Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

1
engines/alg/POTFILES Normal file
View File

@@ -0,0 +1 @@
engines/alg/metaengine.cpp

105
engines/alg/alg.cpp Normal file
View File

@@ -0,0 +1,105 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/config-manager.h"
#include "engines/util.h"
#include "alg/alg.h"
#include "alg/detection.h"
#include "alg/game.h"
#include "alg/logic/game_bountyhunter.h"
#include "alg/logic/game_crimepatrol.h"
#include "alg/logic/game_drugwars.h"
#include "alg/logic/game_johnnyrock.h"
#include "alg/logic/game_maddog.h"
#include "alg/logic/game_maddog2.h"
#include "alg/logic/game_spacepirates.h"
namespace Alg {
AlgEngine::AlgEngine(OSystem *syst, const AlgGameDescription *gd)
: Engine(syst), _gameDescription(gd) {
switch (gd->gameType) {
case GType_CRIME_PATROL: {
GameCrimePatrol *game = new GameCrimePatrol(this, gd);
_debugger = new DebuggerCrimePatrol(game);
_game = game;
break;
}
case GType_DRUG_WARS: {
GameDrugWars *game = new GameDrugWars(this, gd);
_debugger = new DebuggerDrugWars(game);
_game = game;
break;
}
case GType_WSJR: {
GameJohnnyRock *game = new GameJohnnyRock(this, gd);
_debugger = new DebuggerJohnnyRock(game);
_game = game;
break;
}
case GType_LAST_BOUNTY_HUNTER: {
GameBountyHunter *game = new GameBountyHunter(this, gd);
_debugger = new DebuggerBountyHunter(game);
_game = game;
break;
}
case GType_MADDOG: {
GameMaddog *game = new GameMaddog(this, gd);
_debugger = new DebuggerMaddog(game);
_game = game;
break;
}
case GType_MADDOG2: {
GameMaddog2 *game = new GameMaddog2(this, gd);
_debugger = new DebuggerMaddog2(game);
_game = game;
break;
}
case GType_SPACE_PIRATES: {
GameSpacePirates *game = new GameSpacePirates(this, gd);
_debugger = new DebuggerSpacePirates(game);
_game = game;
break;
}
}
}
AlgEngine::~AlgEngine() {
delete _game;
}
Common::Error AlgEngine::run() {
initGraphics(320, 200);
setDebugger(_debugger);
if (ConfMan.hasKey("single_speed_videos")) {
_useSingleSpeedVideos = ConfMan.getBool("single_speed_videos");
}
return _game->run();
}
bool AlgEngine::hasFeature(EngineFeature f) const {
return (f == kSupportsReturnToLauncher) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
}
} // End of namespace Alg

65
engines/alg/alg.h Normal file
View File

@@ -0,0 +1,65 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_H
#define ALG_H
#include "engines/advancedDetector.h"
#include "gui/debugger.h"
#include "alg/detection.h"
namespace Alg {
class Game;
class GameBountyHunter;
class GameCrimePatrol;
class GameDrugWars;
class GameJohnnyRock;
class GameMaddog;
class GameMaddog2;
class GameSpacePirates;
enum {
kAlgDebugGeneral = 1,
kAlgDebugGraphics
};
class AlgEngine : public Engine {
public:
AlgEngine(OSystem *syst, const AlgGameDescription *desc);
~AlgEngine();
Common::Error run();
bool hasFeature(EngineFeature f) const;
Common::Platform getPlatform() const;
bool isDemo() const;
bool useSingleSpeedVideos() const { return _useSingleSpeedVideos; };
private:
const AlgGameDescription *_gameDescription;
Game *_game;
GUI::Debugger *_debugger;
bool _useSingleSpeedVideos = false;
};
} // End of namespace Alg
#endif

View File

@@ -0,0 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
add_engine alg "American Laser Games" no

70
engines/alg/detection.cpp Normal file
View File

@@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "base/plugins.h"
#include "engines/advancedDetector.h"
#include "alg/alg.h"
#include "alg/detection.h"
#include "alg/detection_tables.h"
static const PlainGameDescriptor algGames[] = {
{ "maddog", "Mad Dog McCree" },
{ "johnroc", "Who Shot Johnny Rock?" },
{ "spirates", "Space Pirates" },
{ "maddog2", "Mad Dog II: The Lost Gold" },
{ "cpatrol", "Crime Patrol" },
{ "dwars", "Crime Patrol 2: Drug Wars" },
{ "lbhunter", "The Last Bounty Hunter" },
{ nullptr, nullptr }
};
static const DebugChannelDef debugFlagList[] = {
{ Alg::kAlgDebugGeneral, "general", "General" },
{ Alg::kAlgDebugGraphics, "graphics", "Graphics" },
DEBUG_CHANNEL_END
};
class AlgMetaEngineDetection : public AdvancedMetaEngineDetection<Alg::AlgGameDescription> {
public:
AlgMetaEngineDetection() : AdvancedMetaEngineDetection(Alg::gameDescriptions, algGames) {
_guiOptions = GUIO2(GUIO_NOMIDI, GUIO_NOSUBTITLES);
_maxScanDepth = 1;
}
const char *getName() const override {
return "alg";
}
const char *getEngineName() const override {
return "American Laser Games";
}
const char *getOriginalCopyright() const override {
return "Copyright (C) American Laser Games";
}
const DebugChannelDef *getDebugChannels() const override {
return debugFlagList;
}
};
REGISTER_PLUGIN_STATIC(ALG_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, AlgMetaEngineDetection);

51
engines/alg/detection.h Normal file
View File

@@ -0,0 +1,51 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_DETECTION_H
#define ALG_DETECTION_H
#include "engines/advancedDetector.h"
namespace Alg {
enum AlgGameType {
GType_CRIME_PATROL,
GType_DRUG_WARS,
GType_WSJR,
GType_LAST_BOUNTY_HUNTER,
GType_MADDOG,
GType_MADDOG2,
GType_SPACE_PIRATES,
};
struct AlgGameDescription {
AD_GAME_DESCRIPTION_HELPERS(desc);
ADGameDescription desc;
uint8 gameType;
};
#define GAMEOPTION_SINGLE_SPEED_VERSION GUIO_GAMEOPTIONS1
} // End of namespace Alg
#endif // ALG_DETECTION_H

View File

@@ -0,0 +1,172 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace Alg {
static const AlgGameDescription gameDescriptions[] = {
{
// Crime Patrol (v1.00) (DOS)
{
"cpatrol",
"",
AD_ENTRY1s("CPDS.LIB", "43579f72207298f154f6fb2b1a24e193", 303710700),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO1(GAMEOPTION_SINGLE_SPEED_VERSION)
},
GType_CRIME_PATROL,
},
{
// Crime Patrol Demo (DOS)
{
"cpatrol",
"Demo",
AD_ENTRY1s("CP.LIB", "0621e198afb7be96279beec770cd8461", 16859660),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
GUIO0()
},
GType_CRIME_PATROL,
},
{
// Drug Wars (v1.00) (DOS)
{
"dwars",
"",
AD_ENTRY1s("DWDS.LIB", "f00bc0d980eac72b6bbfa691808b62ae", 320739868),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO1(GAMEOPTION_SINGLE_SPEED_VERSION)
},
GType_DRUG_WARS,
},
{
// Drug Wars Demo (DOS)
{
"dwars",
"Demo",
AD_ENTRY1s("DWDEMO.LIB", "1f0cf57c8aeb326c37777c4ad82e7889", 24435449),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
GUIO0()
},
GType_DRUG_WARS,
},
{
// Who Shot Johnny Rock? (v1.00) (DOS)
{
"johnroc",
"",
AD_ENTRY1s("JOHNROCD.LIB", "93c38b5fc7d1ae6e9dccf4f7a1c313a8", 326535618),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO1(GAMEOPTION_SINGLE_SPEED_VERSION)
},
GType_WSJR,
},
{
// The Last Bounty Hunter (v1.00) (DOS)
{
"lbhunter",
"",
AD_ENTRY1s("BHDS.LIB", "6fad52a6a72830ab3373cbe3e0a3a779", 281473503),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
GUIO0()
},
GType_LAST_BOUNTY_HUNTER,
},
{
// The Last Bounty Hunter Demo (DOS)
{
"lbhunter",
"demo",
AD_ENTRY1s("BHDEMO.LIB", "af5fbbd5e18d96225077eb6bf2cac680", 28368775),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE | ADGF_DEMO,
GUIO1(GAMEOPTION_SINGLE_SPEED_VERSION)
},
GType_LAST_BOUNTY_HUNTER,
},
{
// Mad Dog McCree (v1.03a) (DOS)
{
"maddog",
"",
AD_ENTRY1s("MADDOG.LIB", "df27e760531dba600cb3ebc23a2d98d1", 114633310),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO0()
},
GType_MADDOG,
},
{
// Mad Dog II: The Lost Gold (v1.00) (DOS)
{
"maddog2",
"",
AD_ENTRY1s("MADDOG2D.LIB", "1660b1728573481483c50206ad92a0ca", 291119013),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO1(GAMEOPTION_SINGLE_SPEED_VERSION)
},
GType_MADDOG2,
},
{
// Space Pirates (v1.00) (DOS)
{
"spirates",
"",
AD_ENTRY1s("SPDS.LIB", "223d3a339d542905c437a6a63cf6dbd8", 273506701),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
GUIO1(GAMEOPTION_SINGLE_SPEED_VERSION)
},
GType_SPACE_PIRATES,
},
{
// Space Pirates Demo (DOS)
{
"spirates",
"Demo",
AD_ENTRY1s("SP.LIB", "a1a1b7c9ed28ff2484ab8362825c3973", 14556553),
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_DEMO,
GUIO0()
},
GType_SPACE_PIRATES,
},
{ AD_TABLE_END_MARKER, 0 }
};
} // End of namespace Alg

572
engines/alg/game.cpp Normal file
View File

@@ -0,0 +1,572 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "audio/audiostream.h"
#include "audio/decoders/raw.h"
#include "common/events.h"
#include "common/substream.h"
#include "common/timer.h"
#include "graphics/cursorman.h"
#include "graphics/paletteman.h"
#include "alg/graphics.h"
#include "alg/scene.h"
#include "alg/game.h"
namespace Alg {
Game::Game(AlgEngine *vm) {
_vm = vm;
}
Game::~Game() {
_libFile.close();
_libFileEntries.clear();
delete _rnd;
delete[] _palette;
delete _videoDecoder;
delete _sceneInfo;
if (_background) {
_background->free();
delete _background;
}
if (_screen) {
_screen->free();
delete _screen;
}
for (auto item : *_gun) {
if (item) {
item->free();
delete item;
}
}
for (auto item : *_numbers) {
if (item) {
item->free();
delete item;
}
}
delete _saveSound;
delete _loadSound;
delete _easySound;
delete _avgSound;
delete _hardSound;
delete _skullSound;
delete _shotSound;
delete _emptySound;
}
void Game::init() {
_inMenu = false;
_palette = new uint8[257 * 3]();
// blue for rect display
_palette[5] = 0xFF;
_paletteDirty = true;
_screen = new Graphics::Surface();
_rnd = new Common::RandomSource("alg");
_screen->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
_videoDecoder = new AlgVideoDecoder();
_videoDecoder->setPalette(_palette);
_sceneInfo = new SceneInfo();
}
Common::Error Game::run() {
return Common::kNoError;
}
void Game::shutdown() {
g_system->getMixer()->stopAll();
_vm->quitGame();
}
bool Game::pollEvents() {
Common::Event event;
bool hasEvents = false;
while (g_system->getEventManager()->pollEvent(event)) {
if (event.type == Common::EVENT_MOUSEMOVE) {
_mousePos = event.mouse;
} else if (event.type == Common::EVENT_LBUTTONDOWN) {
_leftDown = true;
_mousePos = event.mouse;
} else if (event.type == Common::EVENT_RBUTTONDOWN) {
_rightDown = true;
_mousePos = event.mouse;
} else if (event.type == Common::EVENT_LBUTTONUP) {
_leftDown = false;
_mousePos = event.mouse;
} else if (event.type == Common::EVENT_RBUTTONUP) {
_rightDown = false;
_mousePos = event.mouse;
}
hasEvents = true;
}
return hasEvents;
}
void Game::loadLibArchive(const Common::Path &path) {
debug("loading lib archive: %s", path.toString().c_str());
if (!_libFile.open(path)) {
error("Game::loadLibArchive(): Can't open library file '%s'", path.toString().c_str());
}
uint16 magicBytes = _libFile.readSint16LE();
uint32 indexOffset = _libFile.readSint32LE();
assert(magicBytes == 1020);
(void)magicBytes;
_libFile.seek(indexOffset);
uint16 indexSize = _libFile.readSint16LE();
assert(indexSize > 0);
(void)indexSize;
while (true) {
uint32 entryOffset = _libFile.readSint32LE();
Common::String entryName = _libFile.readStream(13)->readString();
if (entryName.empty()) {
break;
}
entryName.toLowercase();
_libFileEntries[entryName] = entryOffset;
}
_libFile.seek(0);
_videoDecoder->setInputFile(&_libFile);
}
bool Game::loadScene(Scene *scene) {
Common::String sceneFileName = Common::String::format("%s.mm", scene->_name.c_str());
auto it = _libFileEntries.find(sceneFileName);
if (it != _libFileEntries.end()) {
debug("loaded scene %s", scene->_name.c_str());
_videoDecoder->loadVideoFromStream(it->_value);
return true;
} else {
return false;
}
}
void Game::updateScreen() {
if (!_inMenu) {
Graphics::Surface *frame = _videoDecoder->getVideoFrame();
_screen->copyRectToSurface(frame->getPixels(), frame->pitch, _videoPosX, _videoPosY, frame->w, frame->h);
}
debug_drawZoneRects();
if (_paletteDirty || _videoDecoder->isPaletteDirty()) {
g_system->getPaletteManager()->setPalette(_palette, 0, 256);
_paletteDirty = false;
}
g_system->copyRectToScreen(_screen->getPixels(), _screen->pitch, 0, 0, _screen->w, _screen->h);
g_system->updateScreen();
}
uint32 Game::getMsTime() {
return g_system->getMillis();
}
bool Game::fired(Common::Point *point) {
_fired = false;
pollEvents();
if (_leftDown == true) {
if (_buttonDown) {
return false;
}
_fired = true;
point->x = _mousePos.x;
point->y = _mousePos.y;
_buttonDown = true;
return true;
} else {
_buttonDown = false;
return false;
}
}
Rect *Game::checkZone(Zone *zone, Common::Point *point) {
for (auto &rect : zone->_rects) {
if (point->x >= rect->left &&
point->x <= rect->right &&
point->y >= rect->top &&
point->y <= rect->bottom) {
return rect;
}
}
return nullptr;
}
// This is used by earlier games
Zone *Game::checkZonesV1(Scene *scene, Rect *&hitRect, Common::Point *point) {
for (auto &zone : scene->_zones) {
uint32 startFrame = zone->_startFrame - _videoFrameSkip + 1;
uint32 endFrame = zone->_endFrame + _videoFrameSkip - 1;
if (_currentFrame >= startFrame && _currentFrame <= endFrame) {
hitRect = checkZone(zone, point);
if (hitRect != nullptr) {
return zone;
}
}
}
return nullptr;
}
// This is used by later games
Zone *Game::checkZonesV2(Scene *scene, Rect *&hitRect, Common::Point *point) {
for (auto &zone : scene->_zones) {
uint32 startFrame = zone->_startFrame - (_videoFrameSkip + 1) + ((_difficulty - 1) * _videoFrameSkip);
uint32 endFrame = zone->_endFrame + (_videoFrameSkip - 1) - ((_difficulty - 1) * _videoFrameSkip);
if (_currentFrame >= startFrame && _currentFrame <= endFrame) {
hitRect = checkZone(zone, point);
if (hitRect != nullptr) {
return zone;
}
}
}
return nullptr;
}
// only used by earlier games
void Game::adjustDifficulty(uint8 newDifficulty, uint8 oldDifficulty) {
Common::Array<Scene *> *scenes = _sceneInfo->getScenes();
for (const auto &scene : *scenes) {
if (!(scene->_diff & 0x01)) {
if (scene->_preop == "PAUSE" || scene->_preop == "PAUSFI" || scene->_preop == "PAUSPR") {
scene->_dataParam1 = (scene->_dataParam1 * _pauseDiffScale[newDifficulty - 1]) / _pauseDiffScale[oldDifficulty - 1];
}
}
for (const auto &zone : scene->_zones) {
for (const auto &rect : zone->_rects) {
if (!(scene->_diff & 0x02)) {
int16 cx = (rect->left + rect->right) / 2;
int16 cy = (rect->top + rect->bottom) / 2;
int32 w = (rect->width() * _rectDiffScale[newDifficulty - 1]) / _rectDiffScale[oldDifficulty - 1];
int32 h = (rect->height() * _rectDiffScale[newDifficulty - 1]) / _rectDiffScale[oldDifficulty - 1];
rect->center(cx, cy, w, h);
}
}
}
}
}
uint32 Game::getFrame(Scene *scene) {
if (_videoDecoder->getCurrentFrame() == 0) {
return scene->_startFrame;
}
return scene->_startFrame + (_videoDecoder->getCurrentFrame() * _videoFrameSkip) - _videoFrameSkip;
}
int8 Game::skipToNewScene(Scene *scene) {
if (!_gameInProgress || _sceneSkipped) {
return 0;
}
if (scene->_dataParam2 == -1) {
_sceneSkipped = true;
return -1;
} else if (scene->_dataParam2 > 0) {
uint32 startFrame = scene->_dataParam3;
if (startFrame == 0) {
startFrame = scene->_startFrame + 15;
}
uint32 endFrame = scene->_dataParam4;
if (_currentFrame < endFrame && _currentFrame > startFrame) {
_sceneSkipped = true;
return 1;
}
}
return 0;
}
uint16 Game::randomUnusedInt(uint8 max, uint16 *mask, uint16 exclude) {
if (max == 1) {
return 0;
}
// reset mask if full
uint16 fullMask = 0xFFFF >> (16 - max);
if (*mask == fullMask) {
*mask = 0;
}
uint16 randomNum = 0;
// find an unused random number
while (true) {
randomNum = _rnd->getRandomNumber(max - 1);
// check if bit is already used
uint16 bit = 1 << randomNum;
if (!((*mask & bit) || randomNum == exclude)) {
// set the bit in mask
*mask |= bit;
break;
}
}
return randomNum;
}
// Sound
Audio::SeekableAudioStream *Game::loadSoundFile(const Common::Path &path) {
Common::File *file = new Common::File();
if (!file->open(path)) {
warning("Game::loadSoundFile(): Can't open sound file '%s'", path.toString().c_str());
delete file;
return nullptr;
}
return Audio::makeRawStream(file, 8000, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
}
void Game::playSound(Audio::SeekableAudioStream *stream) {
if (stream != nullptr) {
stream->rewind();
g_system->getMixer()->stopHandle(_sfxAudioHandle);
g_system->getMixer()->playStream(Audio::Mixer::kSFXSoundType, &_sfxAudioHandle, stream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
}
}
void Game::doDiffSound(uint8 difficulty) {
switch (difficulty) {
case 1:
return playSound(_easySound);
case 2:
return playSound(_avgSound);
case 3:
return playSound(_hardSound);
}
}
void Game::doSaveSound() {
playSound(_saveSound);
}
void Game::doLoadSound() {
playSound(_loadSound);
}
void Game::doSkullSound() {
playSound(_skullSound);
}
void Game::doShot() {
playSound(_shotSound);
}
// Timer
static void cursorTimerCallback(void *refCon) {
Game *game = static_cast<Game *>(refCon);
game->runCursorTimer();
}
void Game::setupCursorTimer() {
g_system->getTimerManager()->installTimerProc(&cursorTimerCallback, 1000000 / 50, (void *)this, "cursortimer");
}
void Game::removeCursorTimer() {
g_system->getTimerManager()->removeTimerProc(&cursorTimerCallback);
}
void Game::runCursorTimer() {
_thisGameTimer += 2;
if (_whichGun == 9) {
if (_emptyCount > 0) {
_emptyCount--;
} else {
_whichGun = 0;
}
} else {
if (_shotFired) {
_whichGun++;
if (_whichGun > 5) {
_whichGun = 0;
_shotFired = false;
}
} else {
if (_inHolster > 0) {
_inHolster--;
if (_inHolster == 0 && _whichGun == 7) {
_whichGun = 6;
}
}
}
}
}
// Script functions: Zone
void Game::zoneGlobalHit(Common::Point *point) {
// do nothing
}
// Script functions: RectHit
void Game::rectHitDoNothing(Rect *rect) {
// do nothing
}
void Game::rectNewScene(Rect *rect) {
_score += rect->_score;
if (!rect->_scene.empty()) {
_curScene = rect->_scene;
}
}
void Game::rectEasy(Rect *rect) {
doDiffSound(1);
_difficulty = 1;
}
void Game::rectAverage(Rect *rect) {
doDiffSound(2);
_difficulty = 2;
}
void Game::rectHard(Rect *rect) {
doDiffSound(3);
_difficulty = 3;
}
void Game::rectExit(Rect *rect) {
shutdown();
}
// Script functions: Scene PreOps
void Game::scenePsoDrawRct(Scene *scene) {
}
void Game::scenePsoPause(Scene *scene) {
_hadPause = false;
_pauseTime = 0;
}
void Game::scenePsoDrawRctFadeIn(Scene *scene) {
scenePsoDrawRct(scene);
scenePsoFadeIn(scene);
}
void Game::scenePsoFadeIn(Scene *scene) {
// do nothing
}
void Game::scenePsoPauseFadeIn(Scene *scene) {
scenePsoPause(scene);
scenePsoFadeIn(scene);
}
void Game::scenePsoPreRead(Scene *scene) {
// do nothing
}
void Game::scenePsoPausePreRead(Scene *scene) {
scenePsoPause(scene);
scenePsoPreRead(scene);
}
// Script functions: Scene Scene InsOps
void Game::sceneIsoDoNothing(Scene *scene) {
// do nothing
}
void Game::sceneIsoStartGame(Scene *scene) {
_startScene = scene->_insopParam;
}
void Game::sceneIsoPause(Scene *scene) {
bool checkPause = true;
if (_hadPause) {
checkPause = false;
}
if (_currentFrame > scene->_endFrame) {
checkPause = false;
}
if (scene->_dataParam1 <= 0) {
checkPause = false;
}
if (checkPause) {
uint32 pauseStart = atoi(scene->_insopParam.c_str());
uint32 pauseEnd = atoi(scene->_insopParam.c_str()) + _videoFrameSkip + 1;
if (_currentFrame >= pauseStart && _currentFrame < pauseEnd && !_hadPause) {
uint32 pauseDuration = scene->_dataParam1 * 0x90FF / 1000;
_pauseTime = pauseDuration;
_nextFrameTime += pauseDuration;
_pauseTime += getMsTime();
_hadPause = true;
}
}
if (_pauseTime != 0) {
if (getMsTime() > _pauseTime) {
_pauseTime = 0;
}
}
}
// Script functions: Scene NxtScn
void Game::sceneNxtscnDoNothing(Scene *scene) {
// do nothing
}
void Game::sceneDefaultNxtscn(Scene *scene) {
_curScene = scene->_next;
}
// Script functions: ShowMsg
void Game::sceneSmDonothing(Scene *scene) {
// do nothing
}
// Script functions: ScnScr
void Game::sceneDefaultScore(Scene *scene) {
if (scene->_scnscrParam > 0) {
_score += scene->_scnscrParam;
}
}
// Script functions: ScnNxtFrm
void Game::sceneNxtfrm(Scene *scene) {
}
// debug methods
void Game::debug_drawZoneRects() {
if (_debug_drawRects || debugChannelSet(1, Alg::kAlgDebugGraphics)) {
if (_inMenu) {
for (auto rect : _submenzone->_rects) {
_screen->drawLine(rect->left, rect->top, rect->right, rect->top, 1);
_screen->drawLine(rect->left, rect->top, rect->left, rect->bottom, 1);
_screen->drawLine(rect->right, rect->bottom, rect->right, rect->top, 1);
_screen->drawLine(rect->right, rect->bottom, rect->left, rect->bottom, 1);
}
} else if (_curScene != "") {
Scene *targetScene = _sceneInfo->findScene(_curScene);
for (auto &zone : targetScene->_zones) {
for (auto rect : zone->_rects) {
_screen->drawLine(rect->left, rect->top, rect->right, rect->top, 1);
_screen->drawLine(rect->left, rect->top, rect->left, rect->bottom, 1);
_screen->drawLine(rect->right, rect->bottom, rect->right, rect->top, 1);
_screen->drawLine(rect->right, rect->bottom, rect->left, rect->bottom, 1);
}
}
}
}
}
bool Game::debug_dumpLibFile() {
Common::DumpFile dumpFile;
for (auto &entry : _libFileEntries) {
_libFile.seek(entry._value, SEEK_SET);
uint32 size = _libFile.readUint32LE();
Common::Path dumpFileName(Common::String::format("libDump/%s", entry._key.c_str()));
dumpFile.open(dumpFileName, true);
assert(dumpFile.isOpen());
dumpFile.writeStream(_libFile.readStream(size));
dumpFile.flush();
dumpFile.close();
}
return true;
}
} // End of namespace Alg

186
engines/alg/game.h Normal file
View File

@@ -0,0 +1,186 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_H
#define ALG_GAME_H
#include "common/random.h"
#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "alg/alg.h"
#include "alg/scene.h"
#include "alg/video.h"
namespace Alg {
class Game {
public:
Game(AlgEngine *vm);
virtual ~Game();
virtual void init();
virtual Common::Error run();
bool debug_dumpLibFile();
void runCursorTimer();
bool _debug_drawRects = false;
bool _debug_godMode = false;
bool _debug_unlimitedAmmo = false;
protected:
AlgEngine *_vm;
AlgVideoDecoder *_videoDecoder;
SceneInfo *_sceneInfo;
Common::RandomSource *_rnd;
Common::File _libFile;
Common::HashMap<Common::String, uint32> _libFileEntries;
uint8 *_palette;
bool _paletteDirty;
Graphics::Surface *_background;
Graphics::Surface *_screen;
Common::Array<Graphics::Surface *> *_gun;
Common::Array<Graphics::Surface *> *_numbers;
Audio::SeekableAudioStream *_saveSound = nullptr;
Audio::SeekableAudioStream *_loadSound = nullptr;
Audio::SeekableAudioStream *_easySound = nullptr;
Audio::SeekableAudioStream *_avgSound = nullptr;
Audio::SeekableAudioStream *_hardSound = nullptr;
Audio::SeekableAudioStream *_skullSound = nullptr;
Audio::SeekableAudioStream *_shotSound = nullptr;
Audio::SeekableAudioStream *_emptySound = nullptr;
Audio::SoundHandle _sfxAudioHandle;
Zone *_menuzone;
Zone *_submenzone;
bool _leftDown = false;
bool _rightDown = false;
Common::Point _mousePos;
const uint32 _pauseDiffScale[3] = {0x10000, 0x8000, 0x4000};
const uint32 _rectDiffScale[3] = {0x10000, 0x0C000, 0x8000};
void shutdown();
bool pollEvents();
void loadLibArchive(const Common::Path &path);
Audio::SeekableAudioStream *loadSoundFile(const Common::Path &path);
void playSound(Audio::SeekableAudioStream *stream);
bool loadScene(Scene *scene);
void updateScreen();
uint32 getMsTime();
bool fired(Common::Point *point);
Rect *checkZone(Zone *zone, Common::Point *point);
Zone *checkZonesV1(Scene *scene, Rect *&hitRect, Common::Point *point);
Zone *checkZonesV2(Scene *scene, Rect *&hitRect, Common::Point *point);
uint32 getFrame(Scene *scene);
void adjustDifficulty(uint8 newDifficulty, uint8 oldDifficulty);
int8 skipToNewScene(Scene *scene);
uint16 randomUnusedInt(uint8 max, uint16 *mask, uint16 exclude);
void debug_drawZoneRects();
// Sounds
void doDiffSound(uint8 difficulty);
void doSaveSound();
void doLoadSound();
void doSkullSound();
void doShot();
// Timer
void setupCursorTimer();
void removeCursorTimer();
// Script functions: Zone
void zoneGlobalHit(Common::Point *point);
// Script functions: RectHit
void rectHitDoNothing(Rect *rect);
void rectNewScene(Rect *rect);
void rectExit(Rect *rect);
void rectEasy(Rect *rect);
void rectAverage(Rect *rect);
void rectHard(Rect *rect);
// Script functions: Scene PreOps
void scenePsoDrawRct(Scene *scene);
void scenePsoPause(Scene *scene);
void scenePsoDrawRctFadeIn(Scene *scene);
void scenePsoFadeIn(Scene *scene);
void scenePsoPauseFadeIn(Scene *scene);
void scenePsoPreRead(Scene *scene);
void scenePsoPausePreRead(Scene *scene);
// Script functions: Scene Scene InsOps
void sceneIsoDoNothing(Scene *scene);
void sceneIsoStartGame(Scene *scene);
void sceneIsoPause(Scene *scene);
// Script functions: Scene Scene NxtScn
void sceneNxtscnDoNothing(Scene *scene);
void sceneDefaultNxtscn(Scene *scene);
// Script functions: ShowMsg
void sceneSmDonothing(Scene *scene);
// Script functions: ScnScr
void sceneDefaultScore(Scene *scene);
// Script functions: ScnNxtFrm
void sceneNxtfrm(Scene *scene);
bool _buttonDown = false;
uint8 _difficulty = 1;
uint8 _emptyCount = 0;
bool _fired = false;
uint32 _currentFrame;
bool _gameInProgress = false;
uint32 _thisGameTimer = 0;
bool _hadPause = false;
bool _holster = false;
bool _inMenu = false;
uint8 _inHolster = 0;
int8 _lives = 0;
long int _minF;
long int _maxF;
uint8 _oldWhichGun = 0xFF;
uint8 _oldDifficulty = 1;
int8 _oldLives = 0;
int32 _oldScore = -1;
uint8 _oldShots = 0;
uint32 _pauseTime = 0;
bool _sceneSkipped = false;
int32 _score = 0;
bool _shotFired = false;
uint16 _shots = 0;
uint32 _videoFrameSkip = 3;
uint32 _nextFrameTime = 0;
uint16 _videoPosX;
uint16 _videoPosY;
uint8 _whichGun = 0;
Common::String _curScene;
Common::String _subScene;
Common::String _retScene;
Common::String _lastScene;
Common::String _startScene;
};
} // End of namespace Alg
#endif

179
engines/alg/graphics.cpp Normal file
View File

@@ -0,0 +1,179 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/array.h"
#include "common/debug.h"
#include "common/file.h"
#include "common/path.h"
#include "common/rect.h"
#include "alg/alg.h"
#include "alg/graphics.h"
namespace Alg {
Graphics::Surface *AlgGraphics::loadVgaBackground(const Common::Path &path, uint8 *palette) {
Common::File vgaFile;
if (!vgaFile.open(path)) {
error("AlgGraphics::loadVgaBackground(): Can't open background file '%s'", path.toString().c_str());
}
uint16 width = vgaFile.readUint16LE();
uint16 height = vgaFile.readUint16LE();
uint8 paletteEntries = vgaFile.readByte();
uint8 paletteStart = vgaFile.readByte();
assert(width >= 317 && width <= 320);
assert(height == 200);
assert(paletteStart == 0x10);
for (uint32 i = paletteStart * 3; i < (paletteStart + paletteEntries) * 3U; i += 3) {
palette[i] = vgaFile.readByte();
palette[i + 1] = vgaFile.readByte();
palette[i + 2] = vgaFile.readByte();
}
Graphics::Surface *surface = new Graphics::Surface();
surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
vgaFile.read(surface->getPixels(), width * height);
Common::Rect backgroundRect = Common::Rect(0, 0, width, height);
surface->flipVertical(backgroundRect);
vgaFile.close();
return surface;
}
// for "normal" ani images
Common::Array<Graphics::Surface *> *AlgGraphics::loadAniImage(const Common::Path &path, uint8 *palette) {
Common::Array<Graphics::Surface *> *images = new Common::Array<Graphics::Surface *>();
Common::File aniFile;
if (!aniFile.open(path)) {
error("AlgGraphics::loadAniImage(): Can't open image file '%s'", path.toString().c_str());
}
uint8 paletteEntries = aniFile.readByte();
uint8 paletteStart = aniFile.readByte();
for (uint32 i = paletteStart * 3; i < (paletteStart + paletteEntries) * 3U; i += 3) {
palette[i] = aniFile.readByte();
palette[i + 1] = aniFile.readByte();
palette[i + 2] = aniFile.readByte();
}
uint16 length, width, height;
while (aniFile.pos() < aniFile.size()) {
width = height = 0;
uint64 aniSectionOffset = aniFile.pos();
while (aniFile.pos() < aniFile.size()) {
length = aniFile.readUint16LE();
if (length == 0) {
break;
}
width = length;
height++;
aniFile.skip(2 + length);
}
if (width > 0) {
aniFile.seek(aniSectionOffset, SEEK_SET);
Graphics::Surface *aniImage = new Graphics::Surface();
aniImage->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
for (uint16 y = 0; y < height; y++) {
aniFile.skip(4);
aniFile.read(aniImage->getBasePtr(0, y), width);
}
images->push_back(aniImage);
}
}
aniFile.close();
return images;
}
// for ani images that use relative positioning.
// because these are meant to be drawn directly onto a 320x200 screen, they use relative offsets assuming that resolution.
// as we don't always want to draw directly to screen, we draw to the center of a virtual screen and then copy from a centered subrect.
Common::Array<Graphics::Surface *> *AlgGraphics::loadScreenCoordAniImage(const Common::Path &path, uint8 *palette) {
Common::Array<Graphics::Surface *> *images = new Common::Array<Graphics::Surface *>();
Common::File aniFile;
if (!aniFile.open(path)) {
error("AlgGraphics::loadScreenCoordAniImage(): Can't open image file '%s'", path.toString().c_str());
}
uint8 paletteEntries = aniFile.readByte();
uint8 paletteStart = aniFile.readByte();
for (uint32 i = paletteStart * 3; i < (paletteStart + paletteEntries) * 3U; i += 3) {
palette[i] = aniFile.readByte();
palette[i + 1] = aniFile.readByte();
palette[i + 2] = aniFile.readByte();
}
uint16 length = 0;
int16 offset = 0;
uint32 dest = 0;
uint32 x = 0, y = 0;
while (aniFile.pos() < aniFile.size()) {
Graphics::Surface *renderTarget = new Graphics::Surface();
renderTarget->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
uint32 centerOffset = (renderTarget->w * renderTarget->h / 2) + (renderTarget->w / 2);
while (true) {
length = aniFile.readUint16LE();
if (length == 0) {
break;
}
offset = aniFile.readSint16LE();
dest = centerOffset + offset;
y = dest / renderTarget->w;
x = dest - (y * renderTarget->w);
aniFile.read(renderTarget->getBasePtr(x, y), length);
}
Graphics::Surface *aniImage = new Graphics::Surface();
aniImage->create(96, 96, Graphics::PixelFormat::createFormatCLUT8());
Common::Rect subSectionRect;
subSectionRect.left = (renderTarget->w / 2) - (aniImage->w / 2);
subSectionRect.top = (renderTarget->h / 2) - (aniImage->h / 2);
subSectionRect.right = (renderTarget->w / 2) + (aniImage->w / 2);
subSectionRect.bottom = (renderTarget->h / 2) + (aniImage->h / 2);
aniImage->copyRectToSurface(*renderTarget, 0, 0, subSectionRect);
images->push_back(aniImage);
renderTarget->free();
delete renderTarget;
}
aniFile.close();
return images;
}
void AlgGraphics::drawImage(Graphics::Surface *dst, Graphics::Surface *src, int32 x, int32 y) {
int32 dstX = x;
int32 dstY = y;
Common::Rect subRect = Common::Rect(0, 0, src->w, src->h);
if (dstX < 0) {
subRect.left -= dstX;
dstX = 0;
}
if (dstY < 0) {
subRect.top -= dstY;
dstY = 0;
}
if (dstX + src->w > dst->w) {
subRect.right -= dstX + src->w - dst->w;
}
if (dstY + src->h > dst->h) {
subRect.bottom -= dstY + src->h - dst->h;
}
dst->copyRectToSurfaceWithKey(src->getBasePtr(subRect.left, subRect.top), src->pitch, dstX, dstY, subRect.width(), subRect.height(), 0x00);
}
void AlgGraphics::drawImageCentered(Graphics::Surface *dst, Graphics::Surface *src, int32 x, int32 y) {
int32 dstX = x - (src->w / 2);
int32 dstY = y - (src->h / 2);
drawImage(dst, src, dstX, dstY);
}
} // End of namespace Alg

41
engines/alg/graphics.h Normal file
View File

@@ -0,0 +1,41 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GRAPHICS_H
#define ALG_GRAPHICS_H
#include "common/stream.h"
#include "graphics/surface.h"
namespace Alg {
class AlgGraphics {
public:
static Graphics::Surface *loadVgaBackground(const Common::Path &path, uint8 *palette);
static Common::Array<Graphics::Surface *> *loadAniImage(const Common::Path &path, uint8 *palette);
static Common::Array<Graphics::Surface *> *loadScreenCoordAniImage(const Common::Path &path, uint8 *palette);
static void drawImage(Graphics::Surface *dest, Graphics::Surface *src, int32 x, int32 y);
static void drawImageCentered(Graphics::Surface *dest, Graphics::Surface *src, int32 x, int32 y);
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,287 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_BOUNTYHUNTER_H
#define ALG_GAME_BOUNTYHUNTER_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameBountyHunter> BHScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameBountyHunter> BHScriptFunctionRect;
typedef Common::Functor1Mem<Common::Point *, void, GameJohnnyRock> BHScriptFunctionPoint;
typedef Common::HashMap<Common::String, BHScriptFunctionScene *> BHScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, BHScriptFunctionRect *> BHScriptFunctionRectMap;
typedef Common::HashMap<Common::String, BHScriptFunctionPoint *> BHScriptFunctionPointMap;
class GameBountyHunter : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7
};
public:
GameBountyHunter(AlgEngine *vm, const AlgGameDescription *gd);
~GameBountyHunter() override;
Common::Error run() override;
void debugWarpTo(int val);
private:
void init() override;
void registerScriptFunctions();
void verifyScriptFunctions();
BHScriptFunctionRect getScriptFunctionRectHit(Common::String name);
BHScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
void callScriptFunctionRectHit(Common::String name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene);
BHScriptFunctionRectMap _rectHitFuncs;
BHScriptFunctionSceneMap _scenePreOps;
BHScriptFunctionSceneMap _sceneShowMsg;
BHScriptFunctionSceneMap _sceneInsOps;
BHScriptFunctionSceneMap _sceneWepDwn;
BHScriptFunctionSceneMap _sceneScnScr;
BHScriptFunctionSceneMap _sceneNxtFrm;
BHScriptFunctionSceneMap _sceneNxtScn;
// images
Graphics::Surface *_shotIcon;
Graphics::Surface *_emptyIcon;
Graphics::Surface *_liveIcon;
Graphics::Surface *_deadIcon;
Graphics::Surface *_diffIcon;
Graphics::Surface *_bulletholeIcon;
Graphics::Surface *_playersIcon1;
Graphics::Surface *_playersIcon2;
Graphics::Surface *_textScoreIcon;
Graphics::Surface *_textMenuIcon;
Graphics::Surface *_textBlackBarIcon;
Common::Array<Graphics::Surface *> *_bagsIcons;
Common::Array<Graphics::Surface *> *_shotgun;
// sounds
Audio::SeekableAudioStream *_shotgunSound = nullptr;
// constants
uint16 _randomHarry1[7] = {0x01B9, 0x01B7, 0x01B5, 0x01B3, 0x01AF, 0x01AD, 0};
uint16 _randomHarry2[6] = {0x0194, 0x0190, 0x018E, 0x018C, 0};
uint16 _randomDan1[5] = {0x0173, 0x0171, 0x016F, 0x016D, 0};
uint16 _randomDan1TwoPlayer[6] = {0x0173, 0x0171, 0x016F, 0x016D, 0x016B, 0};
uint16 _randomDan2[7] = {0x0165, 0x0163, 0x0161, 0x015F, 0x015D, 0x015B, 0};
uint16 _randomLoco1[4] = {0xF7, 0xF5, 0xF3, 0};
uint16 _randomLoco2[3] = {0xED, 0xEB, 0};
uint16 _randomKid1[4] = {0xBA, 0xB7, 0xB5, 0};
uint16 _randomKid2[4] = {0xB1, 0xAE, 0xAC, 0};
uint16 *_randomScenes[8] = {_randomHarry1, _randomHarry2, _randomDan1, _randomDan2, _randomLoco1, _randomLoco2, _randomKid1, _randomKid2};
const uint8 _randomScenesPicks[8] = {6, 6, 4, 7, 3, 2, 5, 5};
const uint8 _subLevelOrder[96] = {0, 1, 2, 4, 0, 0, 0, 1, 3, 4, 0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 2, 3, 4, 0,
0, 1, 2, 4, 0, 0, 0, 1, 3, 4, 0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 2, 3, 4, 0,
0, 1, 3, 4, 0, 0, 0, 2, 3, 4, 0, 0, 1, 2, 3, 4, 0, 0, 0, 1, 2, 3, 4, 0,
0, 1, 2, 3, 4, 0, 0, 1, 2, 3, 4, 0, 0, 1, 2, 3, 4, 0, 0, 1, 2, 3, 4, 0};
const uint16 _subLevelSceneIds[20] = {0x01BE, 0x017A, 0x01A2, 0x0198, 0x0183, 0x0178, 0x0167, 0x0159, 0x014B, 0x0147,
0xF1, 0xE1, 0xFF, 0xD8, 0xD0, 0x9B, 0xA8, 0x86, 0xBF, 0x74};
const uint16 _clueLevels[4] = {0x017A, 0x013B, 0xC2, 0x68};
const uint8 _mainLevelMasks[5] = {2, 4, 8, 0x10, 0x80};
const uint8 _gunfightCountDown[15] = {5, 4, 3, 3, 3, 4, 3, 3, 2, 1, 3, 2, 2, 2, 1};
// const uint16 _firstSceneInScenario[4] = {4, 0x36, 0x36, 0x66};
const uint16 _moneyScenes[4] = {0x017D, 0x013C, 0xC3, 0x69};
const uint16 _gunfightScenarios[18] = {0x0116, 0x0118, 0x011B, 0x011D, 0x011F, 0x0121, 0x0123, 0x0125, 0x0127,
0x0129, 0x012B, 0x012D, 0x012F, 0x0131, 0x0133, 0x0135, 0x0137, 0x0139};
const uint16 _innocentScenarios[5] = {0x0110, 0x010F, 0x010C, 0x010B, 0};
const uint16 _deathScenarios[9] = {0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107, 0};
const uint16 _onePlayerOfTwoDead[2] = {0x0109, 0x010A};
const uint16 _allPlayersDead = 0x108;
// gamestate
uint16 _restartScene = 0;
uint8 _numPlayers = 1;
uint8 _player = 0;
uint8 _playerLives[2] = {0, 0};
uint8 _playerGun[2] = {1, 1};
uint8 _playerShots[2] = {0, 0};
uint32 _playerScore[2] = {0, 0};
uint8 _currentLevel = 0;
uint16 _currentSubLevelSceneId = 0;
uint8 _numLevelsDone = 0;
uint8 _levelDoneMask = 0;
uint8 _numSubLevelsDone = 0;
// uint16 _usedScenes = 0;
// int16 _lastPick = -1;
// int16 _initted = 0;
// int16 _sceneCount = 0;
uint16 *_randomSceneList;
uint8 _randomMax = 0;
uint16 _randomMask = 0;
int16 _randomPicked = 0;
uint8 _randomSceneCount = 0;
bool _gunfightInitialized = false;
uint16 _gunfightMask = 0;
int16 _gunfightPicked = 0;
uint8 _gunfightSceneCount = 0;
bool _innocentInitialized = false;
uint16 _innocentMask = 0;
int16 _innocentPicked = 0;
uint8 _innocentSceneCount = 0;
bool _deathInitialized = false;
uint16 _deathMask = 0;
int16 _deathPicked = 0;
uint8 _deathSceneCount = 0;
uint8 _continuesUsed = 0;
bool _wounded = false;
uint16 _mainWounds = 0;
int8 _gunfightCount = 0;
bool _given = false;
uint32 _firstDrawFrame = 0;
uint8 _count = 0;
uint8 _unk_2ADA6 = 0;
// base functions
void newGame();
void doMenu();
void updateCursor();
void updateMouse();
void moveMouse();
void displayLivesLeft(uint8 player);
void displayScores(uint8 player);
void displayShotsLeft(uint8 player);
bool weaponDown();
bool saveState();
bool loadState();
// misc game functions
void setNextScene(uint16 sceneId);
void displayShotFiredImage(Common::Point *point);
void enableVideoFadeIn();
void iconShotgun();
void iconReset();
uint16 beginLevel(uint8 levelNumber);
uint16 pickRandomScene(uint16 *sceneList, uint8 max);
uint16 pickGunfightScene();
uint16 pickInnocentScene();
uint16 pickDeathScene();
uint16 timeForGunfight();
void waitingForShootout(uint32 drawFrame);
void doShotgunSound();
// Script functions: RectHit
void rectShotMenu(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectContinue(Rect *rect);
void rectStart(Rect *rect);
void rectTogglePlayers(Rect *rect);
void rectHitIconJug(Rect *rect);
void rectHitIconLantern(Rect *rect);
void rectHitIconSkull(Rect *rect);
void rectHitIconWheel(Rect *rect);
void rectHitSelectHarry(Rect *rect);
void rectHitSelectDan(Rect *rect);
void rectHitSelectLoco(Rect *rect);
void rectHitSelectKid(Rect *rect);
void rectHitKillMan(Rect *rect);
void rectHitGiveShotgun(Rect *rect);
void rectHitKill3(Rect *rect);
void rectHitCheckShotgun(Rect *rect);
void rectHitCheater(Rect *rect);
// Script functions: Scene PreOps
void scenePsoShootout(Scene *scene);
void scenePsoWoundedMain(Scene *scene);
void scenePsoGunfightSetup(Scene *scene);
void scenePsoLoseALife(Scene *scene);
void scenePsoSetupNdRandom1(Scene *scene);
void scenePsoSetCurrentScene(Scene *scene);
// Script functions: Scene InsOps
void sceneIsoShootout(Scene *scene);
void sceneIsoGivemoney(Scene *scene);
// Script functions: Scene NxtScn
void sceneNxtscnLoseALife(Scene *scene);
void sceneNxtscnContinueGame(Scene *scene);
void sceneNxtscnDidNotContinue(Scene *scene);
void sceneNxtscnKillInnocentMan(Scene *scene);
void sceneNxtscnKillInnocentWoman(Scene *scene);
void sceneNxtscnAfterDie(Scene *scene);
void sceneNxtscnGotoLevelSelect(Scene *scene);
void sceneNxtscnContinueRandom(Scene *scene);
void sceneNxtscnInitRandomHarry1(Scene *scene);
void sceneNxtscnInitRandomHarry2(Scene *scene);
void sceneNxtscnInitRandomDan1(Scene *scene);
void sceneNxtscnInitRandomDan2(Scene *scene);
void sceneNxtscnInitRandomLoco1(Scene *scene);
void sceneNxtscnInitRandomLoco2(Scene *scene);
void sceneNxtscnInitRandomKid1(Scene *scene);
void sceneNxtscnInitRandomKid2(Scene *scene);
void sceneNxtscnNextSubLevel(Scene *scene);
void sceneNxtscnGotoBadGuy(Scene *scene);
void sceneNxtscnAutoSelectLevel(Scene *scene);
void sceneNxtscnSelectScenario(Scene *scene);
void sceneNxtscnFinishScenario(Scene *scene);
void sceneNxtscnGameWon(Scene *scene);
void sceneNxtscnKilledMain(Scene *scene);
void sceneNxtscnWoundedMain(Scene *scene);
void sceneNxtscnEndLevel(Scene *scene);
void sceneNxtscnEndGame(Scene *scene);
void sceneNxtscnDoBreakoutMains(Scene *scene);
void sceneNxtscnDiedRefed(Scene *scene);
void sceneNxtscnGiveShotgun(Scene *scene);
void sceneNxtscnCheck2Players(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
};
class DebuggerBountyHunter : public GUI::Debugger {
public:
DebuggerBountyHunter(GameBountyHunter *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameBountyHunter *_game;
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,279 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_CRIMEPATROL_H
#define ALG_GAME_CRIMEPATROL_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameCrimePatrol> CPScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameCrimePatrol> CPScriptFunctionRect;
typedef Common::HashMap<Common::String, CPScriptFunctionScene *> CPScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, CPScriptFunctionRect *> CPScriptFunctionRectMap;
class GameCrimePatrol : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7
};
public:
GameCrimePatrol(AlgEngine *vm, const AlgGameDescription *gd);
~GameCrimePatrol() override;
void init() override;
void debugWarpTo(int val);
private:
Common::Error run() override;
void registerScriptFunctions();
void verifyScriptFunctions();
CPScriptFunctionRect getScriptFunctionRectHit(Common::String name);
CPScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
void callScriptFunctionRectHit(Common::String name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene);
CPScriptFunctionRectMap _rectHitFuncs;
CPScriptFunctionSceneMap _scenePreOps;
CPScriptFunctionSceneMap _sceneShowMsg;
CPScriptFunctionSceneMap _sceneInsOps;
CPScriptFunctionSceneMap _sceneWepDwn;
CPScriptFunctionSceneMap _sceneScnScr;
CPScriptFunctionSceneMap _sceneNxtFrm;
CPScriptFunctionSceneMap _sceneNxtScn;
// images
Graphics::Surface *_shotIcon;
Graphics::Surface *_emptyIcon;
Graphics::Surface *_liveIcon;
Graphics::Surface *_deadIcon;
Graphics::Surface *_difficultyIcon;
Graphics::Surface *_bulletholeIcon;
// constants
const int16 _scenesLevel0[2] = {0x0191, 0};
const int16 _scenesLevel1[3] = {0x27, 0x01B7, 0};
const int16 _scenesLevel2[4] = {0x33, 0x01C7, 0x01B8, 0};
const int16 _scenesLevel3[3] = {0x48, 0x01C8, 0};
const int16 _scenesLevel4[2] = {0x53, 0};
const int16 _scenesLevel5[2] = {0x60, 0};
const int16 _scenesLevel6[2] = {0x82, 0};
const int16 _scenesLevel7[2] = {0x9B, 0};
const int16 _scenesLevel8[2] = {0xC7, 0};
const int16 _scenesLevel9[2] = {0xB6, 0};
const int16 _scenesLevel10[6] = {0xE0, 0x01BF, 0x01C0, 0x01C1, 0x01C2, 0};
const int16 _scenesLevel11[3] = {0x0136, 0x01C3, 0};
const int16 _scenesLevel12[4] = {0x0119, 0x01C5, 0x0131, 0};
const int16 _scenesLevel13[2] = {0x014C, 0};
const int16 _scenesLevel14[13] = {0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5, 0x01B6, 0};
const int16 _scenesLevel15[5] = {0x3B, 0x3C, 0x3F, 0x41, 0};
const int16 _scenesLevel16[3] = {0x61, 0x65, 0};
const int16 _scenesLevel17[7] = {0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0};
const int16 _scenesLevel18[8] = {0x83, 0x85, 0x87, 0x8A, 0x8C, 0x8F, 0x90, 0};
const int16 _scenesLevel19[7] = {0x9C, 0x9E, 0xA0, 0xA2, 0xA4, 0xA6, 0};
const int16 _scenesLevel20[5] = {0xC8, 0xCA, 0xCC, 0xCE, 0};
const int16 _scenesLevel21[3] = {0xE8, 0xE9, 0};
const int16 _scenesLevel22[11] = {0xF4, 0xF6, 0xF8, 0xFA, 0xFC, 0xFE, 0x0100, 0x0102, 0x0104, 0x0106, 0};
const int16 _scenesLevel23[3] = {0x010E, 0x0113, 0};
const int16 _scenesLevel24[8] = {0x011D, 0x011F, 0x0121, 0x0123, 0x0125, 0x0127, 0x0129, 0};
const int16 _scenesLevel25[6] = {0x013D, 0x013F, 0x0141, 0x0143, 0x0145, 0};
const int16 _scenesLevel26[10] = {0x0157, 0x0159, 0x015B, 0x015D, 0x015F, 0x0161, 0x0163, 0x0165, 0x0167, 0};
const int16 *_levelScenes[27] = {_scenesLevel0, _scenesLevel1, _scenesLevel2, _scenesLevel3, _scenesLevel4, _scenesLevel5, _scenesLevel6,
_scenesLevel7, _scenesLevel8, _scenesLevel9, _scenesLevel10, _scenesLevel11, _scenesLevel12, _scenesLevel13,
_scenesLevel14, _scenesLevel15, _scenesLevel16, _scenesLevel17, _scenesLevel18, _scenesLevel19, _scenesLevel20,
_scenesLevel21, _scenesLevel22, _scenesLevel23, _scenesLevel24, _scenesLevel25, _scenesLevel26};
const int16 _diedScenesStage0[5] = {0x30, 0x31, 0x47, 0x51, 0};
const int16 _diedScenesStage1[7] = {0x5E, 0x5F, 0x7E, 0x7F, 0x98, 0x99, 0};
const int16 _diedScenesStage2[4] = {0xB2, 0xC5, 0xDB, 0};
const int16 _diedScenesStage3[7] = {0x0115, 0x0116, 0x0135, 0x014A, 0x0175, 0x0190, 0};
const int16 _diedScenesStage4[7] = {0x0115, 0x0116, 0x0135, 0x014A, 0x0175, 0x0190, 0};
const int16 *_diedScenesByStage[5] = {_diedScenesStage0, _diedScenesStage1, _diedScenesStage2, _diedScenesStage3, _diedScenesStage4};
const uint16 _deadScenes[5] = {0x32, 0x80, 0xDC, 0x018D, 0x018D};
const uint16 _stageStartScenes[5] = {0x26, 0x52, 0x9A, 0xDF, 0x014C};
const int16 _practiceTargetLeft[5] = {0xE1, 0x45, 0xA8, 0x73, 0xE1};
const int16 _practiceTargetTop[5] = {0x0A, 0x3E, 0x41, 0x6E, 0x6E};
const int16 _practiceTargetRight[5] = {0x0104, 0x6D, 0xCB, 0x95, 0x0104};
const int16 _practiceTargetBottom[5] = {0x3D, 0x79, 0x7B, 0xA1, 0xA1};
// gamestate
uint16 _gotTo[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int8 _stage = 0;
int8 _oldStage = -1;
uint8 _randomSceneCount = 0;
uint8 _randomMax = 0;
uint16 _randomMask = 0;
uint16 _randomPicked = 0;
uint16 _deathMask = 0;
int16 _deathPicked = 0;
uint8 _deathSceneCount = 0;
uint8 _practiceMask = 0;
uint16 _finalStageScene = _stageStartScenes[4];
// base functions
void newGame();
void resetParams();
void doMenu();
void changeDifficulty(uint8 newDifficulty);
void showDifficulty(uint8 newDifficulty, bool updateCursor);
void updateCursor();
void updateMouse();
void moveMouse();
void displayLivesLeft();
void displayScores();
void displayShotsLeft();
bool weaponDown();
bool saveState();
bool loadState();
// misc game functions
void displayShotFiredImage(Common::Point *point);
void enableVideoFadeIn();
uint16 sceneToNumber(Scene *scene);
uint16 pickRandomScene(uint8 index, uint8 max);
uint16 pickDeathScene();
void sceneNxtscnGeneric(uint8 index);
void rectSelectGeneric(uint8 index);
void sceneIsoGotToGeneric(uint8 index, uint16 sceneId);
// Script functions: RectHit
void rectShotMenu(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectContinue(Rect *rect);
void rectStart(Rect *rect);
void rectTargetPractice(Rect *rect);
void rectSelectTargetPractice(Rect *rect);
void rectSelectGangFight(Rect *rect);
void rectSelectWarehouse(Rect *rect);
void rectSelectWestcoastSound(Rect *rect);
void rectSelectDrugDeal(Rect *rect);
void rectSelectCarRing(Rect *rect);
void rectSelectBar(Rect *rect);
void rectSelectBank(Rect *rect);
void rectSelectCrackHouse(Rect *rect);
void rectSelectMethLab(Rect *rect);
void rectSelectAirplane(Rect *rect);
void rectSelectNukeTransport(Rect *rect);
void rectSelectAirport(Rect *rect);
void rectKillInnocentMan(Rect *rect);
// Script functions: Scene PreOps
void scenePsoWarehouseGotTo(Scene *scene);
void scenePsoGangFightGotTo(Scene *scene);
void scenePsoWestcoastSoundGotTo(Scene *scene);
void scenePsoDrugDealGotTo(Scene *scene);
void scenePsoCarRingGotTo(Scene *scene);
void scenePsoBankGotTo(Scene *scene);
void scenePsoCrackHouseGotTo(Scene *scene);
void scenePsoMethLabGotTo(Scene *scene);
void scenePsoAirplaneGotTo(Scene *scene);
void scenePsoAirportGotTo(Scene *scene);
void scenePsoNukeTransportGotTo(Scene *scene);
void scenePsoPowerPlantGotTo(Scene *scene);
// Script functions: Scene NxtScn
void sceneNxtscnGameWon(Scene *scene);
void sceneNxtscnLoseALife(Scene *scene);
void sceneNxtscnDidNotContinue(Scene *scene);
void sceneNxtscnKillInnocentMan(Scene *scene);
void sceneNxtscnKillInnocentWoman(Scene *scene);
void sceneNxtscnAfterDie(Scene *scene);
void sceneNxtscnSelectLanguage1(Scene *scene);
void sceneNxtscnSelectLanguage2(Scene *scene);
void sceneNxtscnSelectRookieScenario(Scene *scene);
void sceneNxtscnSelectUndercoverScenario(Scene *scene);
void sceneNxtscnSelectSwatScenario(Scene *scene);
void sceneNxtscnSelectDeltaScenario(Scene *scene);
void sceneNxtscnInitRandomTargetPractice(Scene *scene);
void sceneNxtscnContinueTargetPractice(Scene *scene);
void sceneNxtscnFinishGangFight(Scene *scene);
void sceneNxtscnFinishWestcoastSound(Scene *scene);
void sceneNxtscnFinishWarehouse(Scene *scene);
void sceneNxtscnInitRandomWarehouse(Scene *scene);
void sceneNxtscnContinueWarehouse(Scene *scene);
void sceneNxtscnFinishDrugDeal(Scene *scene);
void sceneNxtscnInitRandomCarRingLeader(Scene *scene);
void sceneNxtscnContinueCarRingLeader1(Scene *scene);
void sceneNxtscnContinueCarRingLeader2(Scene *scene);
void sceneNxtscnInitRandomCarRing(Scene *scene);
void sceneNxtscnContinueCarRing(Scene *scene);
void sceneNxtscnFinishCarRing(Scene *scene);
void sceneNxtscnFinishBar(Scene *scene);
void sceneNxtscnFinishBank(Scene *scene);
void sceneNxtscnFinishCrackHouse(Scene *scene);
void sceneNxtscnFinishMethLab(Scene *scene);
void sceneNxtscnFinishAirplane(Scene *scene);
void sceneNxtscnFinishAirport(Scene *scene);
void sceneNxtscnFinishNukeTransport(Scene *scene);
void sceneNxtscnInitRandomBar(Scene *scene);
void sceneNxtscnContinueBar(Scene *scene);
void sceneNxtscnInitRandomBank(Scene *scene);
void sceneNxtscnContinueBank(Scene *scene);
void sceneNxtscnInitRandomMethLab(Scene *scene);
void sceneNxtscnContinueMethLab(Scene *scene);
void sceneNxtscnPickRandomRapeller(Scene *scene);
void sceneNxtscnInitRandomAirplane(Scene *scene);
void sceneNxtscnContinueAirplane(Scene *scene);
void sceneNxtscnPickRandomAirplaneFront(Scene *scene);
void sceneNxtscnInitRandomAirport(Scene *scene);
void sceneNxtscnContinueAirport(Scene *scene);
void sceneNxtscnInitRandomNukeTransport(Scene *scene);
void sceneNxtscnContinueNukeTransport(Scene *scene);
void sceneNxtscnInitRandomPowerplant(Scene *scene);
void sceneNxtscnContinuePowerplant(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
void debugDrawPracticeRects();
};
class DebuggerCrimePatrol : public GUI::Debugger {
public:
DebuggerCrimePatrol(GameCrimePatrol *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameCrimePatrol *_game;
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_DRUGWARS_H
#define ALG_GAME_DRUGWARS_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameDrugWars> DWScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameDrugWars> DWScriptFunctionRect;
typedef Common::HashMap<Common::String, DWScriptFunctionScene *> DWScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, DWScriptFunctionRect *> DWScriptFunctionRectMap;
class GameDrugWars : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7
};
public:
GameDrugWars(AlgEngine *vm, const AlgGameDescription *gd);
~GameDrugWars() override;
Common::Error run() override;
void debugWarpTo(int val);
private:
void init() override;
void registerScriptFunctions();
void verifyScriptFunctions();
DWScriptFunctionRect getScriptFunctionRectHit(const Common::String &name);
DWScriptFunctionScene getScriptFunctionScene(SceneFuncType type, const Common::String &name);
void callScriptFunctionRectHit(const Common::String &name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, const Common::String &name, Scene *scene);
DWScriptFunctionRectMap _rectHitFuncs;
DWScriptFunctionSceneMap _scenePreOps;
DWScriptFunctionSceneMap _sceneShowMsg;
DWScriptFunctionSceneMap _sceneInsOps;
DWScriptFunctionSceneMap _sceneWepDwn;
DWScriptFunctionSceneMap _sceneScnScr;
DWScriptFunctionSceneMap _sceneNxtFrm;
DWScriptFunctionSceneMap _sceneNxtScn;
// images
Graphics::Surface *_shotIcon;
Graphics::Surface *_emptyIcon;
Graphics::Surface *_liveIcon;
Graphics::Surface *_deadIcon;
Graphics::Surface *_difficultyIcon;
Graphics::Surface *_bulletholeIcon;
// constants
const int16 _randomScenes0[7] = {0x29, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0};
const int16 _randomScenes1[6] = {0x37, 0x39, 0x3B, 0x3D, 0x3F, 0};
const int16 _randomScenes4[8] = {0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0};
const int16 _randomScenes8[8] = {0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0};
const int16 _randomScenes9[6] = {0xFE, 0x0100, 0x0102, 0x01A3, 0x0105, 0};
const int16 _randomScenes10[8] = {0x0161, 0x0163, 0x0165, 0x0167, 0x016A, 0x016C, 0x016E, 0};
const int16 _randomScenes11[9] = {0x010B, 0x010D, 0x010F, 0x0111, 0x0113, 0x0115, 0x0117, 0x0119, 0};
const int16 _randomScenes12[10] = {0x014C, 0x014E, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015A, 0x015C, 0};
const int16 *_randomScenes[14] = {_randomScenes0, _randomScenes1, nullptr, nullptr, _randomScenes4, nullptr, nullptr, nullptr,
_randomScenes8, _randomScenes9, _randomScenes10, _randomScenes11, _randomScenes12, nullptr};
const uint8 _randomScenesDifficulty[14] = {6, 4, 0, 0, 6, 0, 0, 0, 5, 6, 7, 8, 8, 0};
const uint16 _randomScenesContinue[14] = {0x51, 0x41, 0, 0, 0x01B5, 0, 0, 0, 0xCE, 0x0107, 0x0170, 0x011B, 0x015E, 0};
const int16 _diedScenesStage0[4] = {0x52, 0x53, 0x54, 0};
const int16 _diedScenesStage1[5] = {0x85, 0x86, 0x88, 0x89, 0};
const int16 _diedScenesStage2[3] = {0xEF, 0xF0, 0};
const int16 _diedScenesStage3[3] = {0x0135, 0x0136, 0};
const int16 _diedScenesStage4[3] = {0x0135, 0x0136, 0};
const int16 *_diedScenesByStage[5] = {_diedScenesStage0, _diedScenesStage1, _diedScenesStage2, _diedScenesStage3, _diedScenesStage4};
uint16 _deadScenes[5] = {0x56, 0x8A, 0xF2, 0x0134, 0x0134};
const uint16 _stageStartScenes[5] = {0x51, 0x83, 0xEE, 0x0132, 0x017F};
const uint16 _scenarioStartScenes[14] = {0x27, 0x36, 0x4A, 0x57, 0x9D, 0x8B, 0x74, 0xD8, 0xBF, 0xB8, 0x0160, 0x010A, 0x0137, 0x017F};
// gamestate
uint8 _continues = 0;
uint16 _gotTo[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int8 _gotToIndex = 0;
int8 _stage = 0;
int8 _oldStage = -1;
uint8 _randomSceneCount = 0;
uint8 _randomMax = 0;
uint16 _randomMask = 0;
uint16 _randomPicked = 0;
uint16 _deathMask = 0;
int16 _deathPicked = 0;
uint8 _deathSceneCount = 0;
uint16 _finalStageScene = _stageStartScenes[4];
// base functions
void newGame();
void resetParams();
void doMenu();
void changeDifficulty(uint8 newDifficulty);
void showDifficulty(uint8 newDifficulty, bool updateCursor);
void updateCursor();
void updateMouse();
void moveMouse();
void displayLivesLeft();
void displayScores();
void displayShotsLeft();
bool weaponDown();
bool saveState();
bool loadState();
// misc game functions
void displayShotFiredImage(Common::Point *point);
void enableVideoFadeIn();
uint16 sceneToNumber(Scene *scene);
uint16 pickRandomScene(uint8 index, uint8 max);
uint16 pickDeathScene();
void sceneNxtscnGeneric(uint8 index);
void rectSelectGeneric(uint8 index);
// Script functions: RectHit
void rectShotMenu(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectContinue(Rect *rect);
void rectStart(Rect *rect);
void rectSelectTargetPractice(Rect *rect);
void rectSelectBar(Rect *rect);
void rectSelectCarChase(Rect *rect);
void rectSelectDrugHouse(Rect *rect);
void rectSelectOffice(Rect *rect);
void rectSelectCourt(Rect *rect);
void rectSelectBus(Rect *rect);
void rectSelectDocks(Rect *rect);
void rectSelectHouseBoat(Rect *rect);
void rectSelectParty(Rect *rect);
void rectSelectAirport(Rect *rect);
void rectSelectMansion(Rect *rect);
void rectSelectVillage(Rect *rect);
// Script functions: Scene PreOps
void scenePsoGotTo(Scene *scene);
// Script functions: Scene NxtScn
void sceneNxtscnGameWon(Scene *scene);
void sceneNxtscnLoseALife(Scene *scene);
void sceneNxtscnContinueGame(Scene *scene);
void sceneNxtscnDidNotContinue(Scene *scene);
void sceneNxtscnKillInnocentMan(Scene *scene);
void sceneNxtscnKillInnocentWoman(Scene *scene);
void sceneNxtscnAfterDie(Scene *scene);
void sceneNxtscnInitRandom(Scene *scene);
void sceneNxtscnContinueRandom(Scene *scene);
void sceneNxtscnSelectScenario(Scene *scene);
void sceneNxtscnFinishScenario(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
};
class DebuggerDrugWars : public GUI::Debugger {
public:
DebuggerDrugWars(GameDrugWars *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameDrugWars *_game;
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,285 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_JOHNNYROCK_H
#define ALG_GAME_JOHNNYROCK_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameJohnnyRock> JRScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameJohnnyRock> JRScriptFunctionRect;
typedef Common::Functor1Mem<Common::Point *, void, GameJohnnyRock> JRScriptFunctionPoint;
typedef Common::HashMap<Common::String, JRScriptFunctionScene *> JRScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, JRScriptFunctionRect *> JRScriptFunctionRectMap;
typedef Common::HashMap<Common::String, JRScriptFunctionPoint *> JRScriptFunctionPointMap;
class GameJohnnyRock : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7
};
public:
GameJohnnyRock(AlgEngine *vm, const AlgGameDescription *gd);
~GameJohnnyRock() override;
Common::Error run() override;
void debugWarpTo(int val);
private:
void init() override;
void registerScriptFunctions();
void verifyScriptFunctions();
JRScriptFunctionPoint getScriptFunctionZonePtrFb(Common::String name);
JRScriptFunctionRect getScriptFunctionRectHit(Common::String name);
JRScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
void callScriptFunctionZonePtrFb(Common::String name, Common::Point *point);
void callScriptFunctionRectHit(Common::String name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene);
JRScriptFunctionPointMap _zonePtrFb;
JRScriptFunctionRectMap _rectHitFuncs;
JRScriptFunctionSceneMap _scenePreOps;
JRScriptFunctionSceneMap _sceneShowMsg;
JRScriptFunctionSceneMap _sceneInsOps;
JRScriptFunctionSceneMap _sceneWepDwn;
JRScriptFunctionSceneMap _sceneScnScr;
JRScriptFunctionSceneMap _sceneNxtFrm;
JRScriptFunctionSceneMap _sceneNxtScn;
// images
Common::Array<Graphics::Surface *> *_difficultyIcon;
Graphics::Surface *_levelIcon;
Graphics::Surface *_bulletholeIcon;
// constants
const int16 _randomRooftop[6] = {2, -4, 0x104, 0x1E, 0x100, 0x102};
const int16 _randomTheater[9] = {5, -5, 0x111, 0x1E, 0x107, 0x109, 0x10B, 0x10D, 0x10F};
const int16 _randomAlley[10] = {6, -4, 0, 0x1E, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D};
const int16 _randomFuneralMR[10] = {6, -5, 0x12B, 0x1E, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129};
const int16 _randomBookMR[8] = {4, 5, 0, 0x1E, 0x12E, 0x130, 0x132, 0x134};
const int16 _randomStairway[8] = {4, -3, 0, 0x1E, 0x139, 0x13B, 0x13D, 0x13F};
const int16 _randomHall[8] = {4, -5, 0, 0x1E, 0x141, 0x143, 0x145, 0x146};
const int16 _randomWindows[10] = {6, -3, 0, 0x1E, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E};
const int16 _randomCar[5] = {1, 1, 0, 0, 0x0FE};
const int16 _randomHall1[5] = {1, 1, 0, 0x1E, 0x148};
const int16 _randomElevator[5] = {1, 1, 0, 0, 0x14C};
const int16 _randomBaby[5] = {1, 1, 0, 0, 0x160};
const int16 *_randomPlaces[6] = {_randomWindows, _randomStairway, _randomCar, _randomHall1, _randomElevator, _randomBaby};
const int16 *_randomPlacesMR[8] = {_randomBookMR, _randomFuneralMR, _randomAlley, _randomTheater, _randomHall, _randomWindows, _randomHall1, _randomRooftop};
const int16 _officeTable[5] = {0xA7, 0x9F, 0x9E, 0x0A0, 0x0AD};
const uint16 _diffPos[4][2] = {{0, 0}, {0xCD, 0x35}, {0xD2, 0x53}, {0xD2, 0x6E}};
// gamestate
uint16 _totalDies = 0;
int16 _gameMoney = 0;
int16 _oldGameMoney = 0;
uint16 _ammoAgain = 0;
uint16 _mapTimeout = 0;
uint8 _luckyNumber = 0;
uint8 _thisMap = 0;
uint16 _clues = 0;
uint16 _placeBits = 0;
uint8 _randomCount = 0;
uint16 _doctorBits = 0;
uint16 _undertakerBits = 0;
uint16 _thisClue = 0;
uint8 _gotThisNumber = 0;
uint8 _casino = 0;
uint8 _poolHall = 0;
uint8 _warehouse = 0;
uint8 _garage = 0;
uint8 _office = 0;
uint8 _casinoType = 0;
uint8 _poolHallType = 0;
uint8 _warehouseType = 0;
uint8 _garageType = 0;
uint8 _mansion = 0;
uint8 _inWarehouse = 0;
uint8 _inOffice = 0;
uint16 _gotTo = 0;
uint8 _whoDidIt = 0;
uint8 _hadGoToMansion = 0;
uint16 _officeCount = 0;
uint16 _randomPlaceBits = 0;
uint8 _maxRandomCount = 0;
uint16 _gotoAfterRandom = 0;
uint16 _repeatRandomPlace = 0;
uint16 _maxRepeat = 0;
uint16 _gotThisClue = 0;
uint16 _didContinue = 0;
uint16 _thisGameTime = 0;
uint8 _thisDifficulty = 0;
uint8 _clueTable[4];
uint8 _combinations[4];
uint16 _entranceIndex[20];
const int16 *_randomScenes = nullptr;
uint8 _randomScenesSavestateIndex = 0;
uint16 _randomScenesIndex[10];
Common::String _moneyScene = "";
uint8 _mgunCnt = 0;
uint32 _machGunTimer = 0;
// base functions
bool fired(Common::Point *point);
void newGame();
void resetParams();
void outShots();
void doMenu();
void updateStat();
void displayScore();
void showDifficulty(uint8 newDifficulty, bool updateCursor);
void changeDifficulty(uint8 newDifficulty);
void updateCursor();
void updateMouse();
void moveMouse();
bool weaponDown();
bool saveState();
bool loadState();
void doMoneySound();
// misc game functions
Common::String numToScene(int n);
uint16 sceneToNum(Common::String sceneName);
void defaultBullethole(Common::Point *point);
uint16 pickBits(uint16 *bits, uint8 max);
uint16 pickRandomPlace(uint8 place);
void showCombination();
void shotClue(uint8 clue);
void shotCombination(uint8 combination, bool combinationB);
void shotLuckyNumber(uint8 number);
// Script functions: Zone
void zoneBullethole(Common::Point *point);
// Script functions: RectHit
void rectShotMenu(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectContinue(Rect *rect);
void rectStart(Rect *rect);
void rectKillInnocent(Rect *rect);
void rectSelectCasino(Rect *rect);
void rectSelectPoolhall(Rect *rect);
void rectSelectWarehouse(Rect *rect);
void rectSelectGarage(Rect *rect);
void rectSelectMansion(Rect *rect);
void rectSelectAmmo(Rect *rect);
void rectSelectOffice(Rect *rect);
void rectShotManBust(Rect *rect);
void rectShotWomanBust(Rect *rect);
void rectShotBlueVase(Rect *rect);
void rectShotCat(Rect *rect);
void rectShotIndian(Rect *rect);
void rectShotPlate(Rect *rect);
void rectShotBlueDressPic(Rect *rect);
void rectShotModernPic(Rect *rect);
void rectShotMonaLisa(Rect *rect);
void rectShotGWashington(Rect *rect);
void rectShotBoyInRedPic(Rect *rect);
void rectShotCoatOfArms(Rect *rect);
void rectShotCombinationA0(Rect *rect);
void rectShotCombinationA1(Rect *rect);
void rectShotCombinationA2(Rect *rect);
void rectShotCombinationA3(Rect *rect);
void rectShotCombinationA4(Rect *rect);
void rectShotCombinationA5(Rect *rect);
void rectShotCombinationB0(Rect *rect);
void rectShotCombinationB1(Rect *rect);
void rectShotCombinationB2(Rect *rect);
void rectShotCombinationB3(Rect *rect);
void rectShotCombinationB4(Rect *rect);
void rectShotCombinationB5(Rect *rect);
void rectShotLuckyNumber0(Rect *rect);
void rectShotLuckyNumber1(Rect *rect);
void rectShotLuckyNumber2(Rect *rect);
void rectShotLuckyNumber3(Rect *rect);
void rectShotLuckyNumber4(Rect *rect);
void rectShotLuckyNumber5(Rect *rect);
// Script functions: Scene InsOps
void sceneIsoShootpast(Scene *scene);
void sceneIsoShootpastPause(Scene *scene);
void sceneIsoGotoCasino(Scene *scene);
void sceneIsoGotoPoolhall(Scene *scene);
void sceneIsoGotoWarehouse(Scene *scene);
void sceneIsoInWarehouse2(Scene *scene);
void sceneIsoInwarehouse3(Scene *scene);
void sceneIsoGotoGarage(Scene *scene);
void sceneIsoGotoMansion(Scene *scene);
void sceneIsoInMansion1(Scene *scene);
// Script functions: Scene NxtScn
void sceneNxtscnDied(Scene *scene);
void sceneNxtscnBombDead(Scene *scene);
void sceneNxtscnPickUndertaker(Scene *scene);
void sceneNxtscnCallAttract(Scene *scene);
void sceneNxtscnPickLuckyNumber(Scene *scene);
void sceneNxtscnPickMap(Scene *scene);
void sceneNxtscnPickClue(Scene *scene);
void sceneNxtscnMapTimeout(Scene *scene);
void sceneNxtscnEnterCasino(Scene *scene);
void sceneNxtscnCasinoWhat(Scene *scene);
void sceneNxtscnEnterPoolhall(Scene *scene);
void sceneNxtscnPoolhallClue(Scene *scene);
void sceneNxtscnEnterWarehouse(Scene *scene);
void sceneNxtscnWarehouseClue(Scene *scene);
void sceneNxtscnEnterGarage(Scene *scene);
void sceneNxtscnGarageClue(Scene *scene);
void sceneNxtscnEnterMansion(Scene *scene);
void sceneNxtscnGiveClue(Scene *scene);
void sceneNxtscnPickFlowerMan(Scene *scene);
void sceneNxtscnRandomScene(Scene *scene);
void sceneNxtscnEndRandScene(Scene *scene);
void sceneNxtscnKillInnocent(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
};
class DebuggerJohnnyRock : public GUI::Debugger {
public:
DebuggerJohnnyRock(GameJohnnyRock *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameJohnnyRock *_game;
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,237 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_MADDOG_H
#define ALG_GAME_MADDOG_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameMaddog> MDScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameMaddog> MDScriptFunctionRect;
typedef Common::Functor1Mem<Common::Point *, void, GameMaddog> MDScriptFunctionPoint;
typedef Common::HashMap<Common::String, MDScriptFunctionScene *> MDScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, MDScriptFunctionRect *> MDScriptFunctionRectMap;
typedef Common::HashMap<Common::String, MDScriptFunctionPoint *> MDScriptFunctionPointMap;
class GameMaddog : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7
};
public:
GameMaddog(AlgEngine *vm, const AlgGameDescription *gd);
~GameMaddog() override;
Common::Error run() override;
void debugWarpTo(int val);
private:
void init() override;
void registerScriptFunctions();
void verifyScriptFunctions();
MDScriptFunctionPoint getScriptFunctionZonePtrFb(Common::String name);
MDScriptFunctionRect getScriptFunctionRectHit(Common::String name);
MDScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
void callScriptFunctionZonePtrFb(Common::String name, Common::Point *point);
void callScriptFunctionRectHit(Common::String name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene);
MDScriptFunctionPointMap _zonePtrFb;
MDScriptFunctionRectMap _rectHitFuncs;
MDScriptFunctionSceneMap _scenePreOps;
MDScriptFunctionSceneMap _sceneShowMsg;
MDScriptFunctionSceneMap _sceneInsOps;
MDScriptFunctionSceneMap _sceneWepDwn;
MDScriptFunctionSceneMap _sceneScnScr;
MDScriptFunctionSceneMap _sceneNxtFrm;
MDScriptFunctionSceneMap _sceneNxtScn;
// images
Graphics::Surface *_shotIcon;
Graphics::Surface *_emptyIcon;
Graphics::Surface *_liveIcon;
Graphics::Surface *_deadIcon;
Graphics::Surface *_reloadIcon;
Graphics::Surface *_drawIcon;
Graphics::Surface *_knifeIcon;
Graphics::Surface *_bulletholeIcon;
// constants
const uint16 _fight[3] = {208, 228, 243};
const uint16 _ambush[3] = {192, 193, 192};
const uint16 _hotelScenes[10] = {77, 77, 87, 87, 89, 89, 97, 97, 105, 105};
const uint16 _bottleToss[14] = {171, 171, 174, 174, 175, 175, 178, 178, 179, 179, 182, 182, 183, 183};
const uint16 _diffPos[4][2] = {{0, 0}, {0x4D, 0x43}, {0x4E, 0x66}, {0x4F, 0x80}};
const uint16 _livePos[3][2] = {{0x03, 0x5E}, {0x03, 0x76}, {0x03, 0x8E}};
const uint16 _shotPos[12][2] = {{0x3, 0x5}, {0x0D, 0x5}, {0x17, 0x5}, {0x21, 0x5}, {0x3, 0x21}, {0x0D, 0x21}, {0x17, 0x21}, {0x21, 0x21}, {0x3, 0x3D}, {0x0D, 0x3D}, {0x17, 0x3D}, {0x21, 0x3D}};
// gamestate
uint8 _badMen = 0;
uint8 _badMenBits = 0;
bool _bartenderAlive = false;
uint16 _beenTo = 0;
uint8 _bottles = 0;
uint8 _bottlesMask = 0;
bool _gotClue = false;
uint16 _gotInto = 0;
uint8 _gunTime = 0;
bool _hadSkull = false;
bool _hadLantern = false;
bool _hideOutFront = false;
bool _inShootout = false;
int8 _map0 = 0;
int8 _map1 = 0;
int8 _map2 = 0;
uint8 _mapPos = 0;
uint8 _maxMapPos = 0;
uint8 _peopleKilled = 0;
uint8 _proClue = 0;
uint8 _sheriffCnt = 0; // unused
uint8 _shootOutCnt = 0;
// base functions
void newGame();
void resetParams();
void doMenu();
void updateStat();
void changeDifficulty(uint8 newDifficulty);
void showDifficulty(uint8 newDifficulty, bool updateCursor);
void updateCursor();
void updateMouse();
void moveMouse();
void displayScore();
bool weaponDown();
bool saveState();
bool loadState();
// misc game functions
void defaultBullethole(Common::Point *point);
void die();
uint8 pickRand(uint8 *bits, uint8 max);
uint8 pickBad(uint8 max);
Common::String pickTown();
Common::String pickMap();
Common::String pickSign();
Common::String mapRight();
Common::String mapLeft();
// Script functions: Zone
void zoneBullethole(Common::Point *point);
void zoneSkullhole(Common::Point *point);
// Script functions: RectHit
void rectShotMenu(Rect *rect);
void rectContinue(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectStart(Rect *rect);
void rectStartBottles(Rect *rect);
void rectHideFront(Rect *rect);
void rectHideRear(Rect *rect);
void rectMenuSelect(Rect *rect);
void rectSkull(Rect *rect);
void rectKillMan(Rect *rect);
void rectKillWoman(Rect *rect);
void rectProspSign(Rect *rect);
void rectMineSign(Rect *rect);
void rectMineItem1(Rect *rect);
void rectMineItem2(Rect *rect);
void rectMineItem3(Rect *rect);
void rectMineLantern(Rect *rect);
void rectShotHideout(Rect *rect);
void rectShotRight(Rect *rect);
void rectShotLeft(Rect *rect);
// Script functions: Scene PreOps
void scenePsoShootout(Scene *scene);
void scenePsoMDShootout(Scene *scene);
// Script functions: Scene InsOps
void sceneIsoShootPast(Scene *scene);
void sceneIsoShootPastPause(Scene *scene);
void sceneIsoSkipSaloon(Scene *scene);
void sceneIsoSkipSaloon2(Scene *scene);
void sceneIsoCheckSaloon(Scene *scene);
void sceneIsoIntoStable(Scene *scene);
void sceneIsoIntoOffice(Scene *scene);
void sceneIsoIntoBank(Scene *scene);
void sceneIsoCheckBartender(Scene *scene);
void sceneIsoDidHideout(Scene *scene);
void sceneIsoDidSignPost(Scene *scene);
void sceneIsoDoShootout(Scene *scene);
void sceneIsoMDShootout(Scene *scene);
void sceneIsoShotInto116(Scene *scene);
// Script functions: Scene NxtScn
void sceneDefaultNxtscn(Scene *scene);
void sceneNxtscnPickBottle(Scene *scene);
void sceneNxtscnDied(Scene *scene);
void sceneNxtscnAutoSelect(Scene *scene);
void sceneNxtscnFinishSaloon(Scene *scene);
void sceneNxtscnFinishOffice(Scene *scene);
void sceneNxtscnFinishStable(Scene *scene);
void sceneNxtscnFinishBank(Scene *scene);
void sceneNxtscnPicSaloon(Scene *scene);
void sceneNxtscnKillMan(Scene *scene);
void sceneNxtscnKillWoman(Scene *scene);
void sceneNxtscnBank(Scene *scene);
void sceneNxtscnStable(Scene *scene);
void sceneNxtscnSavProsp(Scene *scene);
void sceneNxtscnPickToss(Scene *scene);
void sceneNxtscnHitToss(Scene *scene);
void sceneNxtscnMissToss(Scene *scene);
void sceneNxtscnPickSign(Scene *scene);
void sceneNxtscnBRockMan(Scene *scene);
void sceneNxtscnLRockMan(Scene *scene);
void sceneNxtscnHotelMen(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
};
class DebuggerMaddog : public GUI::Debugger {
public:
DebuggerMaddog(GameMaddog *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameMaddog *_game;
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_MADDOG2_H
#define ALG_GAME_MADDOG2_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameMaddog2> MD2ScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameMaddog2> MD2ScriptFunctionRect;
typedef Common::Functor1Mem<Common::Point *, void, GameMaddog2> MD2ScriptFunctionPoint;
typedef Common::HashMap<Common::String, MD2ScriptFunctionScene *> MD2ScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, MD2ScriptFunctionRect *> MD2ScriptFunctionRectMap;
typedef Common::HashMap<Common::String, MD2ScriptFunctionPoint *> MD2ScriptFunctionPointMap;
class GameMaddog2 : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7
};
public:
GameMaddog2(AlgEngine *vm, const AlgGameDescription *gd);
~GameMaddog2() override;
Common::Error run() override;
void debugWarpTo(int val);
private:
void init() override;
void registerScriptFunctions();
void verifyScriptFunctions();
MD2ScriptFunctionPoint getScriptFunctionZonePtrFb(Common::String name);
MD2ScriptFunctionRect getScriptFunctionRectHit(Common::String name);
MD2ScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
void callScriptFunctionZonePtrFb(Common::String name, Common::Point *point);
void callScriptFunctionRectHit(Common::String name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene);
MD2ScriptFunctionPointMap _zonePtrFb;
MD2ScriptFunctionRectMap _rectHitFuncs;
MD2ScriptFunctionSceneMap _scenePreOps;
MD2ScriptFunctionSceneMap _sceneShowMsg;
MD2ScriptFunctionSceneMap _sceneInsOps;
MD2ScriptFunctionSceneMap _sceneWepDwn;
MD2ScriptFunctionSceneMap _sceneScnScr;
MD2ScriptFunctionSceneMap _sceneNxtFrm;
MD2ScriptFunctionSceneMap _sceneNxtScn;
// images
Graphics::Surface *_shotIcon;
Graphics::Surface *_emptyIcon;
Graphics::Surface *_liveIcon;
Graphics::Surface *_deadIcon;
Graphics::Surface *_reloadIcon;
Graphics::Surface *_drawIcon;
Graphics::Surface *_knifeIcon;
Graphics::Surface *_bulletholeIcon;
// constants
const int16 _sbClue[3] = {0x67, 0x68, 0x69};
const int16 _bbClue[3] = {0x47, 0x49, 0x48};
const int16 _tpClue[3] = {0x84, 0x85, 0x86};
const int16 _sbScenes[14] = {0x4A, 0x50, 0xB8, 0x55, 0x57, 0x66, 0xBE, 0x94, 0x87, 0x93, 0xCD, 0x95, 0xE3, -1};
const int16 _bbScenes[14] = {0x33, 0x39, 0xB4, 0x41, 0x43, 0x46, 0xA2, 0x8D, 0x87, 0x8F, 0xCD, 0x8E, 0xE3, -1};
const int16 _tpScenes[14] = {0x6A, 0xC3, 0x76, 0x81, 0xAD, 0x83, 0xDC, 0x92, 0x87, 0x90, 0xCD, 0x91, 0xE3, -1};
const int16 _villageScenes[6] = {0x58, 0x5A, 0x5C, 0x5E, 0x60, 0x62};
const int16 _cowboyScenes[7] = {0xCD, 0xCF, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA};
const int16 _farmyardScenes[4] = {0xDC, 0xDE, 0x129, 0xE1};
const int16 _caveScenes[5] = {0xE4, 0xE6, 0xE8, 0xEA, 0xEC};
const int16 _ezShootOuts[5] = {0xAB, 0xBC, 0xC5, 0xC7, 0xCB};
const int16 _shootOuts[6] = {0xAB, 0xBC, 0xC5, 0xC7, 0xC9, 0xCB};
const int16 _ggScenes[3] = {0x87, 0x88, 0x89};
const int16 _dieScenes[6] = {0x96, 0x97, 0x98, 0x9B, 0x9F, 0xA1};
const uint16 _diffPos[3][2] = {{0x0FA, 0x6E}, {0xFA, 0x8E}, {0xFA, 0xAF}};
const uint16 _livePos[3][2] = {{0x81, 0xBE}, {0x70, 0xBE}, {0x5F, 0xBE}};
const uint16 _shotPos[12][2] = {{0x96, 0xBD}, {0x9A, 0xBD}, {0x9E, 0xBD}, {0x0A2, 0xBD}, {0x0A6, 0xBD}, {0x0AA, 0xBD}, {0x0AE, 0xBD}, {0x0B2, 0xBD}, {0x0B6, 0xBD}, {0x0BA, 0xBD}, {0x0BE, 0xBD}, {0x0C2, 0xBD}};
// gamestate
uint16 _dieBits = 0;
uint16 _gotTo = 0;
uint16 _sbGotTo = 0;
uint16 _bbGotTo = 0;
uint16 _tpGotTo = 0;
bool _hadSkull = false;
int16 _thisGuide = 0;
uint16 _doneGuide = 0;
uint16 _shootOutBits = 0;
int16 _lastShootOut = 0;
uint16 _startLives = 3;
bool _wasAShootout = false;
bool _shootoutFromDie = false;
uint16 _whichPadre = 0;
uint16 _whichGatlingGun = 0;
bool _inShootout = false;
uint16 _pickMask = 0;
uint16 _lastPick = 0;
uint16 _placeBits = 0;
uint16 _randomCount = 0;
uint16 _shootOutCnt = 0;
uint16 _totalDies = 0;
// base functions
void newGame();
void resetParams();
void doMenu();
void updateStat();
void changeDifficulty(uint8 newDifficulty);
void showDifficulty(uint8 newDifficulty, bool updateCursor);
void updateCursor();
void updateMouse();
void moveMouse();
void displayScore();
bool weaponDown();
bool saveState();
bool loadState();
// misc game functions
Common::String numToScene(int n);
uint16 sceneToNum(Common::String sceneName);
void defaultBullethole(Common::Point *point);
uint16 die();
uint16 pickBits(uint16 *bits, uint8 max);
uint16 pickShootout();
void nextSB();
void nextBB();
void nextTP();
void ggPickMan();
void genericNext();
void playerWon();
// Script functions: Zone
void zoneBullethole(Common::Point *point);
void zoneSkullhole(Common::Point *point);
// Script functions: RectHit
void rectShotmenu(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectContinue(Rect *rect);
void rectStart(Rect *rect);
void rectSkull(Rect *rect);
void rectKillInnocentMan(Rect *rect);
void rectKillInnocentWoman(Rect *rect);
void rectSelectBeaver(Rect *rect);
void rectSelectBonnie(Rect *rect);
void rectSelectProfessor(Rect *rect);
void rectShotAmmo(Rect *rect);
void rectShotGin(Rect *rect);
void rectShotLantern(Rect *rect);
void rectShootSkull(Rect *rect);
// Script functions: Scene PreOps
void scenePsoShootout(Scene *scene);
void scenePsoMDShootout(Scene *scene);
// Script functions: Scene InsOps
void sceneIsoShootpast(Scene *scene);
void sceneIsoShootpastPause(Scene *scene);
void sceneIsoStagecoach(Scene *scene);
void sceneIsoDifferentPadres(Scene *scene);
void sceneIsoDifferentPadresPause(Scene *scene);
void sceneIsoDontPopNext(Scene *scene);
void sceneIsoGetIntoRock(Scene *scene);
void sceneIsoBenAtCave(Scene *scene);
void sceneIsoSkullAtCave(Scene *scene);
void sceneIsoStartOfTrain(Scene *scene);
void sceneIsoMission(Scene *scene);
void sceneIsoMDShootout(Scene *scene);
void sceneIsoStartOfBoardinghouse(Scene *scene);
void sceneIsoDontContinue(Scene *scene);
void sceneIsoDoShootout(Scene *scene);
// Script functions: Scene NxtScn
void sceneDefaultNxtscn(Scene *scene);
void sceneNxtscnDied(Scene *scene);
void sceneNxtscnKillInnocentMan(Scene *scene);
void sceneNxtscnKillInnocentWoman(Scene *scene);
void sceneNxtscnKillGuide(Scene *scene);
void sceneNxtscnShootSkull(Scene *scene);
void sceneNxtscnCallAttract(Scene *scene);
void sceneNxtscnPickUndertaker(Scene *scene);
void sceneNxtscnChoosePadre(Scene *scene);
void sceneNxtscnSelectGuide(Scene *scene);
void sceneNxtscnSaveBonnie(Scene *scene);
void sceneNxtscnFinishBonnie(Scene *scene);
void sceneNxtscnShowGGClue(Scene *scene);
void sceneNxtscnBBAfterClue(Scene *scene);
void sceneNxtscnAsFarSheGoes(Scene *scene);
void sceneNxtscnSaveBeaver(Scene *scene);
void sceneNxtscnFinishBeaver(Scene *scene);
void sceneNxtscnToGatlingGunSBClue(Scene *scene);
void sceneNxtscnToGuideafterClue(Scene *scene);
void sceneNxtscnToGuideCave(Scene *scene);
void sceneNxtscnInitRandomVillage(Scene *scene);
void sceneNxtscnPickVillageScenes(Scene *scene);
void sceneNxtscnSaveProfessor(Scene *scene);
void sceneNxtscnFinishProfessor(Scene *scene);
void sceneNxtscnToGatlingGunTPClue(Scene *scene);
void sceneNxtscnTPAfterClue(Scene *scene);
void sceneNxtscnFinishGatlingGun1(Scene *scene);
void sceneNxtscnFinishGuyAtGG(Scene *scene);
void sceneNxtscnFinishGatlingGun2(Scene *scene);
void sceneNxtscnHowWeDid(Scene *scene);
void sceneNxtscnPlayerWon(Scene *scene);
void sceneNxtscnBackToNextGuide(Scene *scene);
void sceneNxtscnFinishGenericScene(Scene *scene);
void sceneNxtscnInitRandomCowboys(Scene *scene);
void sceneNxtscnToCowboyScenes(Scene *scene);
void sceneNxtscnInitRandomFarmyard(Scene *scene);
void sceneNxtscnToFarmyardScenes(Scene *scene);
void sceneNxtscnInitRandomCave(Scene *scene);
void sceneNxtscnToCaveScenes(Scene *scene);
void sceneNxtscnPickSkullAtCave(Scene *scene);
void sceneNxtscnDrawGun(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
};
class DebuggerMaddog2 : public GUI::Debugger {
public:
DebuggerMaddog2(GameMaddog2 *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameMaddog2 *_game;
};
} // End of namespace Alg
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,268 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_GAME_SPACEPIRATES_H
#define ALG_GAME_SPACEPIRATES_H
#include "common/hashmap.h"
#include "common/rect.h"
#include "gui/debugger.h"
#include "alg/game.h"
#include "alg/scene.h"
namespace Alg {
typedef Common::Functor1Mem<Scene *, void, GameSpacePirates> SPScriptFunctionScene;
typedef Common::Functor1Mem<Rect *, void, GameSpacePirates> SPScriptFunctionRect;
typedef Common::HashMap<Common::String, SPScriptFunctionScene *> SPScriptFunctionSceneMap;
typedef Common::HashMap<Common::String, SPScriptFunctionRect *> SPScriptFunctionRectMap;
class GameSpacePirates : public Game {
enum SceneFuncType {
PREOP = 1,
SHOWMSG = 2,
INSOP = 3,
WEPDWN = 4,
SCNSCR = 5,
NXTFRM = 6,
NXTSCN = 7,
MISSEDRECTS = 8
};
public:
GameSpacePirates(AlgEngine *vm, const AlgGameDescription *gd);
~GameSpacePirates() override;
Common::Error run() override;
void debugWarpTo(int val);
private:
void init() override;
void registerScriptFunctions();
void verifyScriptFunctions();
SPScriptFunctionRect getScriptFunctionRectHit(Common::String name);
SPScriptFunctionScene getScriptFunctionScene(SceneFuncType type, Common::String name);
void callScriptFunctionRectHit(Common::String name, Rect *rect);
void callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene);
SPScriptFunctionRectMap _rectHitFuncs;
SPScriptFunctionSceneMap _scenePreOps;
SPScriptFunctionSceneMap _sceneShowMsg;
SPScriptFunctionSceneMap _sceneInsOps;
SPScriptFunctionSceneMap _sceneWepDwn;
SPScriptFunctionSceneMap _sceneScnScr;
SPScriptFunctionSceneMap _sceneNxtFrm;
SPScriptFunctionSceneMap _sceneNxtScn;
SPScriptFunctionSceneMap _sceneMissedRects;
// images
Graphics::Surface *_shotIcon;
Graphics::Surface *_emptyIcon;
Graphics::Surface *_deadIcon;
Graphics::Surface *_liveIcon1;
Graphics::Surface *_liveIcon2;
Graphics::Surface *_liveIcon3;
Graphics::Surface *_difficultyIcon;
Graphics::Surface *_bulletholeIcon;
// constants
// gamestate
bool _gameLoaded = false;
int8 _livesLoaded = 0;
uint16 _shotsLoaded = 0;
int32 _scoreLoaded = 0;
uint8 _difficultyLoaded = 0;
bool _nextSceneFound = false;
bool _playerDied = false;
int16 _randomPicked = -1;
uint32 _lastExtraLifeScore = 0;
uint16 _randomScenesValues[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8 _randomScenesUsed[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8 _maxRandom = 0;
uint8 _randomCount = 0;
uint8 _randomCountAsteroids = 0;
uint8 _randomCountMidship = 0;
uint8 _miscRoomsCount = 0;
uint16 _pickedMiscRooms = 0;
uint16 _gotTo = 0;
int8 _currentWorld = 0;
uint16 _worldGotTo[4] = {0, 0, 0, 0};
bool _worldDone[4] = {false, false, false, false};
bool _selectedAWorld = false;
uint16 _selectedWorldStart = 0;
uint16 _sceneBeforeFlyingSkulls = 0;
uint8 _shotGrinReaperCount = 0;
uint16 _clue = 0;
uint8 _shotColor = 0;
uint8 _shotDirection = 0;
uint8 _crystalsShot = 0;
uint8 _crystalState = 0;
uint16 _pickedStartSplitter = 0;
bool _targetPracticeReset = false;
// base functions
void newGame();
void resetParams();
void doMenu();
void changeDifficulty(uint8 newDifficulty);
void showDifficulty(uint8 newDifficulty, bool updateCursor);
void updateCursor();
void updateMouse();
void moveMouse();
void displayLivesLeft();
void displayScores();
void displayShotsLeft();
bool weaponDown();
bool saveState();
bool loadState();
// misc game functions
void playErrorSound();
void displayShotFiredImage();
void displayShotFiredImage(Common::Point *point);
void displayShotLine(uint16 startX, uint16 startY, uint16 endX, uint16 endY);
void displayMultipleShotLines();
void enableVideoFadeIn();
uint16 sceneToNumber(Scene *scene);
uint16 randomUnusedScene(uint8 max);
uint16 randomNumberInRange(uint16 min, uint16 max);
uint16 pickCrystalScene(uint16 scene1, uint16 scene2, uint16 scene3);
// Script functions: RectHit
void rectShotMenu(Rect *rect);
void rectSave(Rect *rect);
void rectLoad(Rect *rect);
void rectContinue(Rect *rect);
void rectStart(Rect *rect);
void rectEasy(Rect *rect);
void rectAverage(Rect *rect);
void rectHard(Rect *rect);
void rectDefault(Rect *rect);
void rectKillInnocentPerson(Rect *rect);
void rectContinueJunkRings(Rect *rect);
void rectShotGrinReaper(Rect *rect);
void rectShowMadDog(Rect *rect);
void rectPottWorldShowCrystal(Rect *rect);
void rectShotLeft(Rect *rect);
void rectShotRight(Rect *rect);
void rectShotGold(Rect *rect);
void rectShotSilver(Rect *rect);
void rectSelectedDuneWorld(Rect *rect);
void rectSelectedJunkWorld(Rect *rect);
void rectSelectedDragonsTeethWorld(Rect *rect);
void rectSelectedVolcanoWorld(Rect *rect);
void rectShotRedDeathGrip(Rect *rect);
void rectShotBlueDeathGrip(Rect *rect);
void rectShotGreenDeathGrip(Rect *rect);
void rectShotYellow(Rect *rect);
void rectShotBlue(Rect *rect);
void rectShotRedCrystal(Rect *rect);
void rectShotBlueCrystal(Rect *rect);
void rectShotGreenCrystal(Rect *rect);
void rectShotBlackDragon1(Rect *rect);
void rectShotBlackDragon2(Rect *rect);
void rectShotBlackDragon3(Rect *rect);
void rectDoFlyingSkull(Rect *rect);
void rectSkipScene(Rect *rect);
void rectHitPirateShip(Rect *rect);
// Script functions: Scene PreOps
void scenePsoFadeInVideo(Scene *scene);
void scenePsoSetGotTo(Scene *scene);
void scenePsoSetGotToNoFadeIn(Scene *scene);
void scenePsoSetWorldGotTo(Scene *scene);
// Script functions: Scene InsOps
void sceneIsoPickAWorld(Scene *scene);
void sceneIsoSetWorldGotTo(Scene *scene);
// Script functions: Scene NxtScn
void sceneNxtscnGotChewedOut(Scene *scene);
void sceneNxtscnRestartFromLast(Scene *scene);
void sceneNxtscnPlayerDied(Scene *scene);
void sceneNxtscnMiscRooms1(Scene *scene);
void sceneNxtscnPickDungeonClue(Scene *scene);
void sceneNxtscnContinueDungeonClue(Scene *scene);
void sceneNxtscnStartMidshipRandomScene(Scene *scene);
void sceneNxtscnContinueMidshipRandomScene(Scene *scene);
void sceneNxtscnShowDeathGripBeamColor(Scene *scene);
void sceneNxtscnSelectAsteroids(Scene *scene);
void sceneNxtscnAsteroidsDone(Scene *scene);
void sceneNxtscnDoFlyingSkulls(Scene *scene);
void sceneNxtscnDidFlyingSkulls(Scene *scene);
void sceneNxtscnShowWhichStartSplitter(Scene *scene);
void sceneNxtscnGotoSelectedWorld(Scene *scene);
void sceneNxtscnStartVolcanoPopup(Scene *scene);
void sceneNxtscnContinueVolcanoPopup(Scene *scene);
void sceneNxtscnGiveFalinaClue(Scene *scene);
void sceneNxtscnCheckFalinaClues(Scene *scene);
void sceneNxtscnSetupFalinaTargetPractice(Scene *scene);
void sceneNxtscnContinueFalinaTargetPractice(Scene *scene);
void sceneNxtscnStartDunePopup(Scene *scene);
void sceneNxtscnContinueDunePopup(Scene *scene);
void sceneNxtscnPottOrPanShoots(Scene *scene);
void sceneNxtscnSetupPottTargetPractice(Scene *scene);
void sceneNxtscnContinuePottTargetPractice(Scene *scene);
void sceneNxtscnStartDragonsTeethPopup(Scene *scene);
void sceneNxtscnContinueDragonsTeethPopup(Scene *scene);
void sceneNxtscnGrinReaperClue(Scene *scene);
void sceneNxtscnStartGrinReaper(Scene *scene);
void sceneNxtscnContinueGrinReaper(Scene *scene);
void sceneNxtscnGrinTargetPractice(Scene *scene);
void sceneNxtscnContinueGrinTargetPractice(Scene *scene);
void sceneNxtscnStartJunkWorld(Scene *scene);
void sceneNxtscnContinueJunkWorld(Scene *scene);
void sceneNxtscnStartJunkRings(Scene *scene);
void sceneNxtscnShowJunkWorldCrystal(Scene *scene);
void sceneNxtscnStartJunkWorldTargetPractice(Scene *scene);
void sceneNxtscnContinueJunkWorldTargetPractice(Scene *scene);
void sceneNxtscnAreAllWorldsDone(Scene *scene);
void sceneNxtscnStartPracticePirateShip(Scene *scene);
void sceneNxtscnMorePracticePirateShip(Scene *scene);
void sceneNxtscnPlayerWon(Scene *scene);
// Script functions: MissedRect
void sceneMissedRectsDefault(Scene *scene);
void sceneMissedRectsMissedPirateShip(Scene *scene);
// Script functions: Scene WepDwn
void sceneDefaultWepdwn(Scene *scene);
// Script functions: Scene ScnScr
void sceneDefaultScnscr(Scene *scene);
};
class DebuggerSpacePirates : public GUI::Debugger {
public:
DebuggerSpacePirates(GameSpacePirates *game);
bool cmdWarpTo(int argc, const char **argv);
bool cmdDumpLib(int argc, const char **argv);
private:
GameSpacePirates *_game;
};
} // End of namespace Alg
#endif

View File

@@ -0,0 +1,82 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/translation.h"
#include "engines/advancedDetector.h"
#include "alg/alg.h"
#include "alg/detection.h"
namespace Alg {
static const ADExtraGuiOptionsMap optionsList[] = {
{
GAMEOPTION_SINGLE_SPEED_VERSION,
{
_s("Use lower quality single speed CD-ROM video"),
_s("These videos are of lower quality, the default version uses double speed CD-ROM videos which are of better quality"),
"single_speed_videos",
false,
0,
0
},
},
AD_EXTRA_GUI_OPTIONS_TERMINATOR
};
Common::Platform AlgEngine::getPlatform() const {
return _gameDescription->desc.platform;
}
bool AlgEngine::isDemo() const {
return (bool)(_gameDescription->desc.flags & ADGF_DEMO);
}
} // namespace Alg
class AlgMetaEngine : public AdvancedMetaEngine<Alg::AlgGameDescription> {
public:
const char *getName() const override {
return "alg";
}
const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override {
return Alg::optionsList;
}
bool hasFeature(MetaEngineFeature f) const override {
return
(f == kSimpleSavesNames);
}
Common::Error createInstance(OSystem *syst, Engine **engine, const Alg::AlgGameDescription *gd) const override;
};
Common::Error AlgMetaEngine::createInstance(OSystem *syst, Engine **engine, const Alg::AlgGameDescription *gd) const {
*engine = new Alg::AlgEngine(syst, gd);
return Common::kNoError;
}
#if PLUGIN_ENABLED_DYNAMIC(ALG)
REGISTER_PLUGIN_DYNAMIC(ALG, PLUGIN_TYPE_ENGINE, AlgMetaEngine);
#else
REGISTER_PLUGIN_STATIC(ALG, PLUGIN_TYPE_ENGINE, AlgMetaEngine);
#endif

30
engines/alg/module.mk Normal file
View File

@@ -0,0 +1,30 @@
MODULE := engines/alg
MODULE_OBJS := \
alg.o \
graphics.o \
game.o \
metaengine.o \
scene.o \
video.o \
logic/game_bountyhunter.o \
logic/game_crimepatrol.o \
logic/game_drugwars.o \
logic/game_johnnyrock.o \
logic/game_maddog.o \
logic/game_maddog2.o \
logic/game_spacepirates.o
MODULE_DIRS += \
engines/alg
# This module can be built as a plugin
ifeq ($(ENABLE_ALG), DYNAMIC_PLUGIN)
PLUGIN := 1
endif
# Include common rules
include $(srcdir)/rules.mk
# Detection objects
DETECT_OBJS += $(MODULE)/detection.o

388
engines/alg/scene.cpp Normal file
View File

@@ -0,0 +1,388 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/debug.h"
#include "common/file.h"
#include "common/tokenizer.h"
#include "alg/scene.h"
namespace Alg {
SceneInfo::SceneInfo() {
}
SceneInfo::~SceneInfo() {
for (auto scene : _scenes) {
delete scene;
}
for (auto zone : _zones) {
delete zone;
}
_scenes.clear();
_zones.clear();
}
void SceneInfo::loadScnFile(const Common::Path &path) {
debug("loading scene script: %s", path.toString().c_str());
if (!_scnFile.open(path)) {
error("SceneInfo::loadScnFile(): Can't open scene file '%s'", path.toString().c_str());
}
bool done = false;
while (_scnFile.pos() < _scnFile.size() && !done) {
Common::String line = _scnFile.readLine();
line.trim();
if (ignoreScriptLine(line)) {
continue;
}
Common::StringTokenizer tokenizer(line, " ");
int8 token = getToken(_mainTokens, tokenizer.nextToken());
uint32 startFrame = 0, endFrame = 0;
Common::String sceneName = nullptr, zoneName = nullptr;
switch (token) {
case 0: // ;
break;
case 1: // ZONE
zoneName = tokenizer.nextToken();
startFrame = atoi(tokenizer.nextToken().c_str());
endFrame = atoi(tokenizer.nextToken().c_str());
parseZone(zoneName, startFrame, endFrame);
break;
case 2: // SCENE
sceneName = tokenizer.nextToken();
startFrame = atoi(tokenizer.nextToken().c_str());
endFrame = atoi(tokenizer.nextToken().c_str());
sceneName.toLowercase();
parseScene(sceneName, startFrame, endFrame);
break;
case 3: // MSG
error("SceneInfo::loadScnFile(): MSG Not implemented: %s", line.c_str());
break;
case 4: // START
_startScene = tokenizer.nextToken();
break;
case 5: // GLOBAL
error("SceneInfo::loadScnFile(): GLOBAL Not implemented: %s", line.c_str());
break;
case 6: // END
done = true;
break;
default:
error("SceneInfo::loadScnFile(): Unknown script section encountered: %s", line.c_str());
break;
}
}
_scnFile.close();
addZonesToScenes();
}
void SceneInfo::parseScene(const Common::String &sceneName, uint32 startFrame, uint32 endFrame) {
Scene *scene = new Scene(sceneName, startFrame, endFrame);
bool done = false;
while (_scnFile.pos() < _scnFile.size() && !done) {
Common::String line = _scnFile.readLine();
line.trim();
if (ignoreScriptLine(line)) {
continue;
}
Common::StringTokenizer tokenizer(line, " ");
int8 token = getToken(_sceneTokens, tokenizer.nextToken());
switch (token) {
case 0: // EOF
case 1: // NEXT
scene->_next = tokenizer.nextToken();
break;
case 2: // ZONES
scene->_zonesStart = tokenizer.nextToken();
scene->_zonesStart2 = tokenizer.nextToken();
scene->_zonesStart3 = tokenizer.nextToken();
break;
case 3: // PREOP
scene->_preop = tokenizer.nextToken();
scene->_preopParam = tokenizer.nextToken();
break;
case 4: // SHOWMSG / SCNMSG
scene->_scnmsg = tokenizer.nextToken();
scene->_scnmsgParam = tokenizer.nextToken();
break;
case 5: // INSOP
scene->_insop = tokenizer.nextToken();
scene->_insopParam = tokenizer.nextToken();
break;
case 6: // WEPDWN
scene->_wepdwn = tokenizer.nextToken();
break;
case 7: // SCNSCR
scene->_scnscr = tokenizer.nextToken();
scene->_scnscrParam = atoi(tokenizer.nextToken().c_str());
break;
case 8: // NXTFRM
scene->_nxtfrm = tokenizer.nextToken();
break;
case 9: // NXTSCN
scene->_nxtscn = tokenizer.nextToken();
// ignore next token if existing
tokenizer.nextToken();
break;
case 10: // DATA
scene->_dataParam1 = atoi(tokenizer.nextToken().c_str());
scene->_dataParam2 = atoi(tokenizer.nextToken().c_str());
scene->_dataParam3 = atoi(tokenizer.nextToken().c_str());
scene->_dataParam4 = atoi(tokenizer.nextToken().c_str());
scene->_dataParam5 = atoi(tokenizer.nextToken().c_str());
scene->_dataParam6 = atoi(tokenizer.nextToken().c_str());
break;
case 11: // DIFF
scene->_diff = atoi(tokenizer.nextToken().c_str());
break;
case 12: // MISSEDRECTS
scene->_missedRects = tokenizer.nextToken();
// ignore next token if existing
tokenizer.nextToken();
break;
case 13: // DIFFICULTY_MOD
scene->_difficultyMod = atoi(tokenizer.nextToken().c_str());
break;
case 14: // ;
done = true;
break;
default:
error("SceneInfo::parseScene(): Unknown scene token found: %s", line.c_str());
break;
}
Common::String nextToken = tokenizer.nextToken();
if (!nextToken.empty()) {
error("SceneInfo::parseScene(): missed token %s in line %s", nextToken.c_str(), line.c_str());
}
}
_scenes.push_back(scene);
}
void SceneInfo::parseZone(const Common::String &zoneName, uint32 startFrame, uint32 endFrame) {
Zone *zone = new Zone(zoneName, startFrame, endFrame);
bool done = false;
while (_scnFile.pos() < _scnFile.size() && !done) {
Common::String line = _scnFile.readLine();
line.trim();
if (ignoreScriptLine(line)) {
continue;
}
Common::StringTokenizer tokenizer(line, " ");
int8 token = getToken(_zoneTokens, tokenizer.nextToken());
Rect *rect = nullptr;
switch (token) {
case 0: // EOF
break;
case 1: // NEXT
zone->_next = tokenizer.nextToken();
break;
case 2: // PTRFB
zone->_ptrfb = tokenizer.nextToken();
break;
case 3: // RECT
{
Common::String temp = tokenizer.nextToken();
if (temp == "MOVING") {
rect = new Rect();
rect->_isMoving = true;
rect->left = atoi(tokenizer.nextToken().c_str());
rect->top = atoi(tokenizer.nextToken().c_str());
rect->right = atoi(tokenizer.nextToken().c_str());
rect->bottom = atoi(tokenizer.nextToken().c_str());
rect->_dest.left = atoi(tokenizer.nextToken().c_str());
rect->_dest.top = atoi(tokenizer.nextToken().c_str());
rect->_dest.right = atoi(tokenizer.nextToken().c_str());
rect->_dest.bottom = atoi(tokenizer.nextToken().c_str());
rect->_scene = tokenizer.nextToken();
rect->_score = atoi(tokenizer.nextToken().c_str());
rect->_rectHit = tokenizer.nextToken();
rect->_unknown = tokenizer.nextToken();
zone->_rects.push_back(rect);
} else {
rect = new Rect();
rect->_isMoving = false;
rect->left = atoi(temp.c_str());
rect->top = atoi(tokenizer.nextToken().c_str());
rect->right = atoi(tokenizer.nextToken().c_str());
rect->bottom = atoi(tokenizer.nextToken().c_str());
rect->_scene = tokenizer.nextToken();
rect->_score = atoi(tokenizer.nextToken().c_str());
rect->_rectHit = tokenizer.nextToken();
rect->_unknown = tokenizer.nextToken();
zone->_rects.push_back(rect);
}
} break;
case 4: // ;
done = true;
break;
default:
error("SceneInfo::parseZone(): Unknown zone token found: %s", line.c_str());
break;
}
Common::String nextToken = tokenizer.nextToken();
if (!nextToken.empty()) {
error("SceneInfo::parseZone(): missed token %s in line %s", nextToken.c_str(), line.c_str());
}
}
_zones.push_back(zone);
}
void SceneInfo::addZonesToScenes() {
for (auto &scene : _scenes) {
if (!scene->_zonesStart.empty()) {
Zone *zone = findZone(scene->_zonesStart);
scene->_zones.push_back(zone);
while (!zone->_next.empty()) {
zone = findZone(zone->_next);
if (zone == nullptr) {
break;
}
scene->_zones.push_back(zone);
}
}
if (!scene->_zonesStart2.empty() && scene->_zonesStart2 != scene->_zonesStart) {
Zone *zone = findZone(scene->_zonesStart2);
scene->_zones.push_back(zone);
while (!zone->_next.empty()) {
zone = findZone(zone->_next);
if (zone == nullptr) {
break;
}
scene->_zones.push_back(zone);
}
}
if (!scene->_zonesStart3.empty() && scene->_zonesStart3 != scene->_zonesStart2) {
Zone *zone = findZone(scene->_zonesStart3);
scene->_zones.push_back(zone);
while (!zone->_next.empty()) {
zone = findZone(zone->_next);
if (zone == nullptr) {
break;
}
scene->_zones.push_back(zone);
}
}
}
}
void SceneInfo::addScene(Scene *scene) {
_scenes.push_back(scene);
}
Zone *SceneInfo::findZone(const Common::String &zoneName) {
for (auto &zone : _zones) {
if (zone->_name.equalsIgnoreCase(zoneName)) {
return zone;
}
}
warning("SceneInfo::findZone(): Cannot find zone %s", zoneName.c_str());
return nullptr;
}
Scene *SceneInfo::findScene(const Common::String &sceneName) {
for (auto &scene : _scenes) {
if (scene->_name.equalsIgnoreCase(sceneName)) {
return scene;
}
}
error("SceneInfo::findScene(): Cannot find scene %s", sceneName.c_str());
}
int8 SceneInfo::getToken(const TokenEntry *tokenList, const Common::String &token) {
for (int i = 0; tokenList[i].name != nullptr; i++) {
if (token == tokenList[i].name) {
return tokenList[i].value;
}
}
return -1;
}
bool SceneInfo::ignoreScriptLine(const Common::String &line) {
if (line.empty()) {
return true; // empty line
} else if (line.hasPrefix("//")) {
return true; // comment
} else if (line.hasPrefix("*")) {
return true; // doc comment
} else if (line.hasPrefix("NXET")) {
return true; // typo in Maddog2
} else if (line.hasPrefix("DATA$")) {
return true; // typo in DrugWars
} else if (line.hasPrefix("NUMBER_OF_")) {
return true; // unnecessary numbers
}
return false;
}
Scene::Scene(const Common::String &name, uint32 startFrame, uint32 endFrame) {
_preop = "DEFAULT";
_insop = "DEFAULT";
_scnmsg = "DEFAULT";
_wepdwn = "DEFAULT";
_scnscr = "DEFAULT";
_nxtfrm = "DEFAULT";
_nxtscn = "DEFAULT";
_missedRects = "DEFAULT";
_missedRects = "DEFAULT";
_scnscrParam = 0;
_dataParam1 = 0;
_dataParam2 = 0;
_dataParam3 = 0;
_dataParam4 = 0;
_dataParam5 = "";
_name = name;
_startFrame = startFrame;
_endFrame = endFrame;
_diff = 0;
_difficultyMod = 0;
}
Zone::Zone(const Common::String &name, const Common::String &ptrfb) {
_name = name;
_ptrfb = ptrfb;
}
Zone::Zone(const Common::String &name, uint32 startFrame, uint32 endFrame) {
_name = name;
_startFrame = startFrame;
_endFrame = endFrame;
}
Zone::~Zone() {
for (auto rect : _rects) {
delete rect;
}
}
void Zone::addRect(int16 left, int16 top, int16 right, int16 bottom, const Common::String &scene, uint32 score, const Common::String &rectHit, const Common::String &unknown) {
Rect *rect = new Rect();
rect->left = left;
rect->top = top;
rect->right = right;
rect->bottom = bottom;
rect->_scene = scene;
rect->_score = score;
rect->_rectHit = rectHit;
rect->_unknown = unknown;
_rects.push_back(rect);
}
} // End of namespace Alg

163
engines/alg/scene.h Normal file
View File

@@ -0,0 +1,163 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_SCENE_H
#define ALG_SCENE_H
#include "common/array.h"
#include "common/file.h"
#include "common/path.h"
#include "common/rect.h"
#include "common/str.h"
namespace Alg {
struct TokenEntry {
const char *name;
uint8 value;
};
const TokenEntry _mainTokens[] = {
{"ZONE", 1},
{"SCENE", 2},
{"MSG", 3},
{"START", 4},
{"GLOBAL", 5},
{"END", 6},
{nullptr, 0}};
const TokenEntry _zoneTokens[] = {
{"NEXT", 1},
{"PTRFB", 2},
{"RECT", 3},
{";", 4},
{nullptr, 0}};
const TokenEntry _sceneTokens[] = {
{"NEXT", 1},
{"ZONES", 2},
{"PREOP", 3},
{"SHOWMSG", 4},
{"SCNMSG", 4},
{"INSOP", 5},
{"WEPDWN", 6},
{"SCNSCR", 7},
{"NXTFRM", 8},
{"NXTSCN", 9},
{"DATA", 10},
{"DIFF", 11},
{"MISSEDRECTS", 12},
{"DIFFICULTY_MOD", 13},
{";", 14},
{nullptr, 0}};
class Rect : public Common::Rect {
public:
Common::String _scene;
uint32 _score;
Common::String _rectHit;
Common::String _unknown;
bool _isMoving = false;
Common::Rect _dest;
void center(int16 cx, int16 cy, int16 w, int16 h) {
right = cx + (w / 2);
left = cx - (w / 2);
top = cy - (h / 2);
bottom = cy + (h / 2);
}
};
class Zone {
public:
Zone(const Common::String &name, uint32 startFrame, uint32 endFrame);
Zone(const Common::String &name, const Common::String &ptrfb);
~Zone();
Common::String _name;
uint32 _startFrame = 0;
uint32 _endFrame = 0;
Common::String _ptrfb;
Common::Array<Rect *> _rects;
Common::String _next;
void addRect(int16 left, int16 top, int16 right, int16 bottom, const Common::String &scene, uint32 score, const Common::String &rectHit, const Common::String &unknown);
};
class Scene {
public:
Scene(const Common::String &name, uint32 startFrame, uint32 endFrame);
~Scene() = default;
Common::String _name;
uint32 _startFrame;
uint32 _endFrame;
Common::String _next;
Common::String _zonesStart;
Common::String _zonesStart2;
Common::String _zonesStart3;
Common::String _preop;
Common::String _preopParam;
Common::String _insop;
Common::String _insopParam;
Common::String _scnmsg;
Common::String _scnmsgParam;
Common::String _wepdwn;
Common::String _scnscr;
int32 _scnscrParam;
Common::String _nxtfrm;
Common::String _nxtscn;
int32 _dataParam1;
int32 _dataParam2;
int32 _dataParam3;
int32 _dataParam4;
Common::String _dataParam5;
Common::String _dataParam6;
uint32 _diff;
Common::String _missedRects;
uint32 _difficultyMod;
Common::Array<Zone *> _zones;
};
class SceneInfo {
public:
SceneInfo();
~SceneInfo();
void loadScnFile(const Common::Path &path);
Common::String getStartScene() { return _startScene; }
Common::Array<Scene *> *getScenes() { return &_scenes; }
Scene *findScene(const Common::String &sceneName);
void addScene(Scene *scene);
private:
Common::File _scnFile;
Common::String _startScene;
Common::Array<Scene *> _scenes;
Common::Array<Zone *> _zones;
void parseScene(const Common::String &sceneName, uint32 startFrame, uint32 endFrame);
void parseZone(const Common::String &zoneName, uint32 startFrame, uint32 endFrame);
void addZonesToScenes();
Zone *findZone(const Common::String &zoneName);
int8 getToken(const TokenEntry *tokenList, const Common::String &token);
bool ignoreScriptLine(const Common::String &line);
};
} // End of namespace Alg
#endif

309
engines/alg/video.cpp Normal file
View File

@@ -0,0 +1,309 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/textconsole.h"
#include "graphics/surface.h"
#include "audio/decoders/raw.h"
#include "alg/video.h"
namespace Alg {
AlgVideoDecoder::AlgVideoDecoder() {
_frame = nullptr;
_audioStream = nullptr;
}
AlgVideoDecoder::~AlgVideoDecoder() {
if (_frame) {
_frame->free();
delete _frame;
}
delete _audioStream;
}
void AlgVideoDecoder::loadVideoFromStream(uint32 offset) {
_input->seek(offset);
_size = _input->readUint32LE();
_currentFrame = 0;
uint16 chunkType = _input->readUint16LE();
uint32 chunkSize = _input->readUint32LE();
_numChunks = _input->readUint16LE();
_frameRate = _input->readUint16LE();
_videoMode = _input->readUint16LE();
_width = _input->readUint16LE();
_height = _input->readUint16LE();
uint16 typeRaw = _input->readUint16LE();
uint16 typeInter = _input->readUint16LE();
uint16 typeIntraHh = _input->readUint16LE();
uint16 typeInterHh = _input->readUint16LE();
uint16 typeIntraHhv = _input->readUint16LE();
uint16 typeInterHhv = _input->readUint16LE();
(void)chunkType;
(void)typeRaw;
(void)typeInter;
(void)typeIntraHh;
(void)typeInterHh;
(void)typeIntraHhv;
(void)typeInterHhv;
if (chunkSize == 0x18) {
_audioType = _input->readUint16LE();
}
assert(chunkType == 0x00);
assert(chunkSize == 0x16 || chunkSize == 0x18);
assert(_frameRate == 10);
assert(_videoMode == 0x13);
assert(typeRaw == 0x02);
assert(typeInter == 0x05);
assert(typeIntraHh == 0x0c);
assert(typeInterHh == 0x0d);
assert(typeIntraHhv == 0x0e);
assert(typeInterHhv == 0x0f);
_currentChunk = 0;
_bytesLeft = _size - chunkSize - 6;
if (_frame) {
_frame->free();
delete _frame;
}
delete _audioStream;
_frame = new Graphics::Surface();
_frame->create(_width, _height, Graphics::PixelFormat::createFormatCLUT8());
_audioStream = makePacketizedRawStream(8000, Audio::FLAG_UNSIGNED);
g_system->getMixer()->stopHandle(_audioHandle);
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
}
void AlgVideoDecoder::skipNumberOfFrames(uint32 num) {
uint32 videoFramesSkipped = 0;
while (videoFramesSkipped < num && _bytesLeft > 0) {
uint16 chunkType = _input->readUint16LE();
uint32 chunkSize = _input->readUint32LE();
_currentChunk++;
switch (chunkType) {
case MKTAG16(0x00, 0x08):
case MKTAG16(0x00, 0x0c):
case MKTAG16(0x00, 0x0e):
case MKTAG16(0x00, 0x05):
case MKTAG16(0x00, 0x0d):
case MKTAG16(0x00, 0x0f):
case MKTAG16(0x00, 0x02):
videoFramesSkipped++;
_currentFrame++;
break;
}
_input->skip(chunkSize);
_bytesLeft -= chunkSize + 6;
}
// find next keyframe
bool nextKeyframeFound = false;
while (!nextKeyframeFound && _bytesLeft > 0) {
uint16 chunkType = _input->readUint16LE();
uint32 chunkSize = _input->readUint32LE();
_currentChunk++;
switch (chunkType) {
case MKTAG16(0x00, 0x08):
case MKTAG16(0x00, 0x0c):
case MKTAG16(0x00, 0x0e):
nextKeyframeFound = true;
_input->seek(-6, SEEK_CUR);
break;
case MKTAG16(0x00, 0x05):
case MKTAG16(0x00, 0x0d):
case MKTAG16(0x00, 0x0f):
case MKTAG16(0x00, 0x02):
_input->skip(chunkSize);
_bytesLeft -= chunkSize + 6;
videoFramesSkipped++;
_currentFrame++;
break;
default:
_input->skip(chunkSize);
_bytesLeft -= chunkSize + 6;
}
}
}
void AlgVideoDecoder::readNextChunk() {
uint16 chunkType = _input->readUint16LE();
uint32 chunkSize = _input->readUint32LE();
_currentChunk++;
switch (chunkType) {
case MKTAG16(0x00, 0x00):
error("AlgVideoDecoder::readNextChunk(): got repeated header chunk");
break;
case MKTAG16(0x00, 0x30):
updatePalette(chunkSize, false);
break;
case MKTAG16(0x00, 0x31):
updatePalette(chunkSize, true);
break;
case MKTAG16(0x00, 0x15):
readAudioData(chunkSize, 8000);
break;
case MKTAG16(0x00, 0x16):
readAudioData(chunkSize, 11000);
break;
case MKTAG16(0x00, 0x08):
decodeIntraFrame(chunkSize, 0, 0);
_gotVideoFrame = true;
break;
case MKTAG16(0x00, 0x0c):
decodeIntraFrame(chunkSize, 1, 0);
_gotVideoFrame = true;
break;
case MKTAG16(0x00, 0x0e):
decodeIntraFrame(chunkSize, 1, 1);
_gotVideoFrame = true;
break;
case MKTAG16(0x00, 0x05):
decodeInterFrame(chunkSize, 0, 0);
_gotVideoFrame = true;
break;
case MKTAG16(0x00, 0x0d):
decodeInterFrame(chunkSize, 1, 0);
_gotVideoFrame = true;
break;
case MKTAG16(0x00, 0x0f):
decodeInterFrame(chunkSize, 1, 1);
_gotVideoFrame = true;
break;
case MKTAG16(0x00, 0x02):
warning("AlgVideoDecoder::readNextChunk(): raw video not supported");
_input->skip(chunkSize);
break;
default:
error("AlgVideoDecoder::readNextChunk(): Unknown chunk encountered: %d", chunkType);
}
_bytesLeft -= chunkSize + 6;
}
void AlgVideoDecoder::getNextFrame() {
_paletteDirty = false;
_gotVideoFrame = false;
while (!_gotVideoFrame && _bytesLeft > 0) {
readNextChunk();
}
_currentFrame++;
}
void AlgVideoDecoder::decodeIntraFrame(uint32 size, uint8 hh, uint8 hv) {
uint16 x = 0, y = 0;
int32 bytesRemaining = size;
int32 runLength = 0;
uint8 readByte, color = 0;
while (bytesRemaining > 0) {
readByte = _input->readByte();
if (readByte & 0x80) {
runLength = 1;
color = readByte;
bytesRemaining--;
} else {
runLength = (readByte & 0x7F) + 2;
color = _input->readByte();
bytesRemaining -= 2;
}
if (color > 0) {
memset(_frame->getBasePtr(x, y), color, runLength * (1 + hh));
if (hv) {
memset(_frame->getBasePtr(x, y + 1), color, runLength * (1 + hh));
}
}
x += runLength + (hh * runLength);
if (x >= _width) {
x = 0;
y += 1 + hv;
}
}
assert(bytesRemaining == 0);
(void)bytesRemaining;
}
void AlgVideoDecoder::decodeInterFrame(uint32 size, uint8 hh, uint8 hv) {
uint32 bytesRead = 0;
uint16 length = 0, x = 0, y = 0, replacementBytesLeft = 0;
replacementBytesLeft = _input->readUint16LE();
bytesRead += 2;
if (replacementBytesLeft == 0) {
_input->skip(size - 2);
return;
}
Common::SeekableReadStream *replacement = _input->readStream(replacementBytesLeft);
bytesRead += replacementBytesLeft;
while (replacementBytesLeft > 1) {
length = replacement->readByte();
x = replacement->readByte() + ((length & 0x80) << 1);
length &= 0x7F;
replacementBytesLeft -= 2;
if (length == 0) {
y += x;
continue;
}
for (uint32 i = 0; i < length; i++) {
uint8 replaceArray = replacement->readByte();
for (uint8 j = 0x80; j > 0; j = j >> 1) {
if (replaceArray & j) {
uint8 color = _input->readByte();
bytesRead++;
memset(_frame->getBasePtr(x, y), color, (1 + hh));
if (hv) {
memset(_frame->getBasePtr(x, y + 1), color, (1 + hh));
}
}
x += 1 + hh;
}
}
y += 1 + hv;
}
delete replacement;
assert(bytesRead == size);
(void)bytesRead;
}
void AlgVideoDecoder::updatePalette(uint32 size, bool partial) {
_paletteDirty = true;
uint32 bytesRead = 0;
uint16 start = 0, count = 256;
if (partial) {
start = _input->readUint16LE();
count = _input->readUint16LE();
bytesRead += 4;
}
uint16 paletteIndex = start * 3;
for (uint16 i = 0; i < count; i++) {
uint8 r = _input->readByte() * 4;
uint8 g = _input->readByte() * 4;
uint8 b = _input->readByte() * 4;
_palette[paletteIndex++] = r;
_palette[paletteIndex++] = g;
_palette[paletteIndex++] = b;
bytesRead += 3;
}
assert(bytesRead == size);
(void)bytesRead;
}
void AlgVideoDecoder::readAudioData(uint32 size, uint16 rate) {
assert(_audioType == 21);
(void)_audioType;
_audioStream->queuePacket(_input->readStream(size));
}
} // End of namespace Alg

78
engines/alg/video.h Normal file
View File

@@ -0,0 +1,78 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ALG_VIDEO_H
#define ALG_VIDEO_H
#include "audio/audiostream.h"
#include "audio/mixer.h"
#include "common/file.h"
namespace Alg {
class AlgVideoDecoder {
public:
AlgVideoDecoder();
~AlgVideoDecoder();
void getNextFrame();
void loadVideoFromStream(uint32 offset);
void skipNumberOfFrames(uint32 num);
void setInputFile(Common::File *input) { _input = input; }
bool isFinished() const { return _bytesLeft == 0; }
Graphics::Surface *getVideoFrame() const { return _frame; }
void setPalette(uint8 *palette) { _palette = palette; }
bool isPaletteDirty() const { return _paletteDirty; }
void pauseAudio(bool pause) const { g_system->getMixer()->pauseHandle(_audioHandle, pause); }
uint16 getWidth() const { return _width; }
uint16 getHeight() const { return _height; }
uint32 getCurrentFrame() const { return _currentFrame; }
private:
Common::File *_input;
Graphics::Surface *_frame;
Audio::PacketizedAudioStream *_audioStream;
Audio::SoundHandle _audioHandle;
uint8 *_palette;
bool _paletteDirty;
bool _gotVideoFrame;
uint32 _currentFrame;
uint32 _size;
uint32 _bytesLeft;
uint16 _currentChunk;
uint16 _numChunks = 0;
uint16 _frameRate = 0;
uint16 _videoMode = 0;
uint16 _width = 0;
uint16 _height = 0;
uint16 _audioType = 0;
void readNextChunk();
void decodeIntraFrame(uint32 size, uint8 hh, uint8 hv);
void decodeInterFrame(uint32 size, uint8 hh, uint8 hv);
void updatePalette(uint32 size, bool partial);
void readAudioData(uint32 size, uint16 rate);
};
} // End of namespace Alg
#endif