Files
scummvm-cursorfix/engines/alg/logic/game_johnnyrock.cpp
2026-02-02 04:50:13 +01:00

1759 lines
47 KiB
C++

/* 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/rect.h"
#include "common/savefile.h"
#include "common/system.h"
#include "graphics/cursorman.h"
#include "alg/graphics.h"
#include "alg/logic/game_johnnyrock.h"
#include "alg/scene.h"
namespace Alg {
GameJohnnyRock::GameJohnnyRock(AlgEngine *vm, const AlgGameDescription *gd) : Game(vm) {
}
GameJohnnyRock::~GameJohnnyRock() {
for (auto item : *_difficultyIcon) {
item->free();
delete item;
}
if (_levelIcon) {
_levelIcon->free();
delete _levelIcon;
}
if (_bulletholeIcon) {
_bulletholeIcon->free();
delete _bulletholeIcon;
}
}
void GameJohnnyRock::init() {
Game::init();
_videoPosX = 11;
_videoPosY = 2;
setupCursorTimer();
if(_vm->useSingleSpeedVideos()) {
loadLibArchive("johnroc.lib");
} else {
loadLibArchive("johnrocd.lib");
}
_sceneInfo->loadScnFile("johnroc.scn");
_startScene = _sceneInfo->getStartScene();
registerScriptFunctions();
verifyScriptFunctions();
_menuzone = new Zone("MainMenu", "GLOBALHIT");
_menuzone->addRect(0x0C, 0xBB, 0x3C, 0xC7, nullptr, 0, "SHOTMENU", "0");
_submenzone = new Zone("SubMenu", "GLOBALHIT");
_submenzone->addRect(0x10, 0x0F, 0x78, 0x34, nullptr, 0, "STARTMENU", "0");
_submenzone->addRect(0x10, 0x8E, 0x8A, 0xAF, nullptr, 0, "CONTMENU", "0");
_submenzone->addRect(0x10, 0x3A, 0x6A, 0x5C, nullptr, 0, "RECTSAVE", "0");
_submenzone->addRect(0x10, 0x64, 0x84, 0x99, nullptr, 0, "RECTLOAD", "0");
_submenzone->addRect(0xD2, 0x8D, 0x12F, 0xB0, nullptr, 0, "EXITMENU", "0");
_submenzone->addRect(0xD0, 0x35, 0x123, 0x51, nullptr, 0, "RECTEASY", "0");
_submenzone->addRect(0xD2, 0x50, 0x125, 0x6B, nullptr, 0, "RECTAVG", "0");
_submenzone->addRect(0xD2, 0x6D, 0x122, 0x86, nullptr, 0, "RECTHARD", "0");
_shotSound = loadSoundFile("blow.8b");
_emptySound = loadSoundFile("empty.8b");
_saveSound = loadSoundFile("saved.8b");
_loadSound = loadSoundFile("loaded.8b");
_skullSound = loadSoundFile("money.8b");
_gun = AlgGraphics::loadScreenCoordAniImage("gun.ani", _palette);
_numbers = AlgGraphics::loadAniImage("numbers.ani", _palette);
_difficultyIcon = AlgGraphics::loadAniImage("diff.ani", _palette);
auto level = AlgGraphics::loadScreenCoordAniImage("level.ani", _palette);
_levelIcon = (*level)[0];
auto hole = AlgGraphics::loadScreenCoordAniImage("hole.ani", _palette);
_bulletholeIcon = (*hole)[0];
_background = AlgGraphics::loadVgaBackground("backgrnd.vga", _palette);
_screen->copyRectToSurface(_background->getPixels(), _background->pitch, 0, 0, _background->w, _background->h);
moveMouse();
}
// FIXME: Need to unregisterScriptFunctions() in destructor to delete all allocated JRScriptFunctionRect and prevent reallocation to fix memory leakage here...
void GameJohnnyRock::registerScriptFunctions() {
#define RECT_HIT_FUNCTION(name, func) _rectHitFuncs[name] = new JRScriptFunctionRect(this, &GameJohnnyRock::func);
RECT_HIT_FUNCTION("DEFAULT", rectNewScene);
RECT_HIT_FUNCTION("NEWSCENE", rectNewScene);
RECT_HIT_FUNCTION("EXITMENU", rectExit);
RECT_HIT_FUNCTION("CONTMENU", rectContinue);
RECT_HIT_FUNCTION("STARTMENU", rectStart);
RECT_HIT_FUNCTION("SHOTMENU", rectShotMenu);
RECT_HIT_FUNCTION("RECTSAVE", rectSave);
RECT_HIT_FUNCTION("RECTLOAD", rectLoad);
RECT_HIT_FUNCTION("RECTEASY", rectEasy);
RECT_HIT_FUNCTION("RECTAVG", rectAverage);
RECT_HIT_FUNCTION("RECTHARD", rectHard);
RECT_HIT_FUNCTION("KILLINNOCENT", rectKillInnocent);
RECT_HIT_FUNCTION("SELCASINO", rectSelectCasino);
RECT_HIT_FUNCTION("SELPOOLH", rectSelectPoolhall);
RECT_HIT_FUNCTION("SELWAREHSE", rectSelectWarehouse);
RECT_HIT_FUNCTION("SELGARAGE", rectSelectGarage);
RECT_HIT_FUNCTION("SELMANSION", rectSelectMansion);
RECT_HIT_FUNCTION("SELAMMO", rectSelectAmmo);
RECT_HIT_FUNCTION("SELOFFICE", rectSelectOffice);
RECT_HIT_FUNCTION("MANBUST", rectShotManBust);
RECT_HIT_FUNCTION("WOMANBUST", rectShotWomanBust);
RECT_HIT_FUNCTION("BLUEVASE", rectShotBlueVase);
RECT_HIT_FUNCTION("CAT", rectShotCat);
RECT_HIT_FUNCTION("INDIAN", rectShotIndian);
RECT_HIT_FUNCTION("PLATE", rectShotPlate);
RECT_HIT_FUNCTION("BLUEDRESSPIC", rectShotBlueDressPic);
RECT_HIT_FUNCTION("MODERNPIC", rectShotModernPic);
RECT_HIT_FUNCTION("MONALISA", rectShotMonaLisa);
RECT_HIT_FUNCTION("GWASHINGTON", rectShotGWashington);
RECT_HIT_FUNCTION("BOYINREDPIC", rectShotBoyInRedPic);
RECT_HIT_FUNCTION("COATOFARMS", rectShotCoatOfArms);
RECT_HIT_FUNCTION("COMBNOA0", rectShotCombinationA0);
RECT_HIT_FUNCTION("COMBNOA1", rectShotCombinationA1);
RECT_HIT_FUNCTION("COMBNOA2", rectShotCombinationA2);
RECT_HIT_FUNCTION("COMBNOA3", rectShotCombinationA3);
RECT_HIT_FUNCTION("COMBNOA4", rectShotCombinationA4);
RECT_HIT_FUNCTION("COMBNOA5", rectShotCombinationA5);
RECT_HIT_FUNCTION("COMBNOB0", rectShotCombinationB0);
RECT_HIT_FUNCTION("COMBNOB1", rectShotCombinationB1);
RECT_HIT_FUNCTION("COMBNOB2", rectShotCombinationB2);
RECT_HIT_FUNCTION("COMBNOB3", rectShotCombinationB3);
RECT_HIT_FUNCTION("COMBNOB4", rectShotCombinationB4);
RECT_HIT_FUNCTION("COMBNOB5", rectShotCombinationB5);
RECT_HIT_FUNCTION("LUCKNO0", rectShotLuckyNumber0);
RECT_HIT_FUNCTION("LUCKNO1", rectShotLuckyNumber1);
RECT_HIT_FUNCTION("LUCKNO2", rectShotLuckyNumber2);
RECT_HIT_FUNCTION("LUCKNO3", rectShotLuckyNumber3);
RECT_HIT_FUNCTION("LUCKNO4", rectShotLuckyNumber4);
RECT_HIT_FUNCTION("LUCKNO5", rectShotLuckyNumber5);
#undef RECT_HIT_FUNCTION
#define PRE_OPS_FUNCTION(name, func) _scenePreOps[name] = new JRScriptFunctionScene(this, &GameJohnnyRock::func);
PRE_OPS_FUNCTION("DRAWRCT", scenePsoDrawRct);
PRE_OPS_FUNCTION("PAUSE", scenePsoPause);
PRE_OPS_FUNCTION("FADEIN", scenePsoFadeIn);
PRE_OPS_FUNCTION("PAUSFI", scenePsoPauseFadeIn);
PRE_OPS_FUNCTION("PREREAD", scenePsoPreRead);
PRE_OPS_FUNCTION("PAUSPR", scenePsoPausePreRead);
PRE_OPS_FUNCTION("DEFAULT", scenePsoDrawRct);
PRE_OPS_FUNCTION("DRAWRCTFDI", scenePsoDrawRctFadeIn);
#undef PRE_OPS_FUNCTION
#define INS_OPS_FUNCTION(name, func) _sceneInsOps[name] = new JRScriptFunctionScene(this, &GameJohnnyRock::func);
INS_OPS_FUNCTION("DEFAULT", sceneIsoDoNothing);
INS_OPS_FUNCTION("PAUSE", sceneIsoPause);
INS_OPS_FUNCTION("SPAUSE", sceneIsoShootpastPause);
INS_OPS_FUNCTION("STARTGAME", sceneIsoStartGame);
INS_OPS_FUNCTION("SHOOTPAST", sceneIsoShootpast);
INS_OPS_FUNCTION("GOTTOCASINO", sceneIsoGotoCasino);
INS_OPS_FUNCTION("GOTTOPOOLH", sceneIsoGotoPoolhall);
INS_OPS_FUNCTION("GOTTOWAREHSE", sceneIsoGotoWarehouse);
INS_OPS_FUNCTION("INWAREHSE2", sceneIsoInWarehouse2);
INS_OPS_FUNCTION("INWAREHSE3", sceneIsoInwarehouse3);
INS_OPS_FUNCTION("GOTOGARAGE", sceneIsoGotoGarage);
INS_OPS_FUNCTION("GOTOMANSION", sceneIsoGotoMansion);
INS_OPS_FUNCTION("INMANSION1", sceneIsoInMansion1);
#undef INS_OPS_FUNCTION
#define NXT_SCN_FUNCTION(name, func) _sceneNxtScn[name] = new JRScriptFunctionScene(this, &GameJohnnyRock::func);
NXT_SCN_FUNCTION("DEFAULT", sceneDefaultNxtscn);
NXT_SCN_FUNCTION("DRAWGUN", sceneDefaultNxtscn);
NXT_SCN_FUNCTION("DIED", sceneNxtscnDied);
NXT_SCN_FUNCTION("BOMBDEAD", sceneNxtscnBombDead);
NXT_SCN_FUNCTION("PIKUNDRTAKR", sceneNxtscnPickUndertaker);
NXT_SCN_FUNCTION("CALLATTRACT", sceneNxtscnCallAttract);
NXT_SCN_FUNCTION("PICKLUCKNO", sceneNxtscnPickLuckyNumber);
NXT_SCN_FUNCTION("PICKMAP", sceneNxtscnPickMap);
NXT_SCN_FUNCTION("PICKCLUE", sceneNxtscnPickClue);
NXT_SCN_FUNCTION("MAPTIMEOUT", sceneNxtscnMapTimeout);
NXT_SCN_FUNCTION("ENTCASINO", sceneNxtscnEnterCasino);
NXT_SCN_FUNCTION("CASINOWHAT?", sceneNxtscnCasinoWhat);
NXT_SCN_FUNCTION("ENTPOOLH", sceneNxtscnEnterPoolhall);
NXT_SCN_FUNCTION("POOLHCLUE", sceneNxtscnPoolhallClue);
NXT_SCN_FUNCTION("ENTWAREHSE", sceneNxtscnEnterWarehouse);
NXT_SCN_FUNCTION("WAREHSECLUE", sceneNxtscnWarehouseClue);
NXT_SCN_FUNCTION("ENTGARAGE", sceneNxtscnEnterGarage);
NXT_SCN_FUNCTION("GARAGECLUE", sceneNxtscnGarageClue);
NXT_SCN_FUNCTION("ENTMANSION", sceneNxtscnEnterMansion);
NXT_SCN_FUNCTION("GIVECLUE", sceneNxtscnGiveClue);
NXT_SCN_FUNCTION("PICKFLOWERMAN", sceneNxtscnPickFlowerMan);
NXT_SCN_FUNCTION("RANDOMSCENE", sceneNxtscnRandomScene);
NXT_SCN_FUNCTION("ENDRANDSCENE", sceneNxtscnEndRandScene);
NXT_SCN_FUNCTION("SCN_KILLINNOCENT", sceneNxtscnKillInnocent);
#undef NXT_SCN_FUNCTION
_zonePtrFb["DEFAULT"] = new JRScriptFunctionPoint(this, &GameJohnnyRock::zoneBullethole);
_sceneShowMsg["DEFAULT"] = new JRScriptFunctionScene(this, &GameJohnnyRock::sceneSmDonothing);
_sceneWepDwn["DEFAULT"] = new JRScriptFunctionScene(this, &GameJohnnyRock::sceneDefaultWepdwn);
_sceneScnScr["DEFAULT"] = new JRScriptFunctionScene(this, &GameJohnnyRock::sceneDefaultScore);
_sceneNxtFrm["DEFAULT"] = new JRScriptFunctionScene(this, &GameJohnnyRock::sceneNxtfrm);
}
void GameJohnnyRock::verifyScriptFunctions() {
auto scenes = _sceneInfo->getScenes();
for (auto scene : *scenes) {
getScriptFunctionScene(PREOP, scene->_preop);
getScriptFunctionScene(SHOWMSG, scene->_scnmsg);
getScriptFunctionScene(INSOP, scene->_insop);
getScriptFunctionScene(WEPDWN, scene->_wepdwn);
getScriptFunctionScene(SCNSCR, scene->_scnscr);
getScriptFunctionScene(NXTFRM, scene->_nxtfrm);
getScriptFunctionScene(NXTSCN, scene->_nxtscn);
for (auto zone : scene->_zones) {
for (auto rect : zone->_rects) {
getScriptFunctionRectHit(rect->_rectHit);
}
}
}
}
JRScriptFunctionPoint GameJohnnyRock::getScriptFunctionZonePtrFb(Common::String name) {
auto it = _zonePtrFb.find(name);
if (it != _zonePtrFb.end()) {
return *it->_value;
} else {
error("GameJohnnyRock::getScriptFunctionZonePtrFb(): Could not find zonePtrFb function: %s", name.c_str());
}
}
JRScriptFunctionRect GameJohnnyRock::getScriptFunctionRectHit(Common::String name) {
auto it = _rectHitFuncs.find(name);
if (it != _rectHitFuncs.end()) {
return *it->_value;
} else {
error("GameJohnnyRock::getScriptFunctionRectHit(): Could not find rectHit function: %s", name.c_str());
}
}
JRScriptFunctionScene GameJohnnyRock::getScriptFunctionScene(SceneFuncType type, Common::String name) {
JRScriptFunctionSceneMap *functionMap;
switch (type) {
case PREOP:
functionMap = &_scenePreOps;
break;
case SHOWMSG:
functionMap = &_sceneShowMsg;
break;
case INSOP:
functionMap = &_sceneInsOps;
break;
case WEPDWN:
functionMap = &_sceneWepDwn;
break;
case SCNSCR:
functionMap = &_sceneScnScr;
break;
case NXTFRM:
functionMap = &_sceneNxtFrm;
break;
case NXTSCN:
functionMap = &_sceneNxtScn;
break;
default:
error("GameJohnnyRock::getScriptFunctionScene(): Unkown scene script type: %u", type);
break;
}
JRScriptFunctionSceneMap::iterator it;
it = functionMap->find(name);
if (it != functionMap->end()) {
return *it->_value;
} else {
error("GameJohnnyRock::getScriptFunctionScene(): Could not find scene type %u function: %s", type, name.c_str());
}
}
void GameJohnnyRock::callScriptFunctionZonePtrFb(Common::String name, Common::Point *point) {
JRScriptFunctionPoint function = getScriptFunctionZonePtrFb(name);
function(point);
}
void GameJohnnyRock::callScriptFunctionRectHit(Common::String name, Rect *rect) {
JRScriptFunctionRect function = getScriptFunctionRectHit(name);
function(rect);
}
void GameJohnnyRock::callScriptFunctionScene(SceneFuncType type, Common::String name, Scene *scene) {
JRScriptFunctionScene function = getScriptFunctionScene(type, name);
function(scene);
}
Common::Error GameJohnnyRock::run() {
init();
newGame();
_curScene = _startScene;
Common::String oldscene;
while (!_vm->shouldQuit()) {
_leftDown = false;
oldscene = _curScene;
_fired = false;
Scene *scene = _sceneInfo->findScene(_curScene);
if (!loadScene(scene)) {
error("GameJohnnyRock::run(): Cannot find scene %s in libfile", scene->_name.c_str());
}
_paletteDirty = true;
_nextFrameTime = getMsTime() + 100;
callScriptFunctionScene(PREOP, scene->_preop, scene);
_currentFrame = getFrame(scene);
while (_currentFrame <= scene->_endFrame && _curScene == oldscene && !_vm->shouldQuit()) {
updateMouse();
// TODO: call scene->messageFunc
callScriptFunctionScene(INSOP, scene->_insop, scene);
_holster = weaponDown();
if (_holster) {
callScriptFunctionScene(WEPDWN, scene->_wepdwn, scene);
}
Common::Point firedCoords;
if (fired(&firedCoords)) {
if (!_holster) {
Rect *hitGlobalRect = checkZone(_menuzone, &firedCoords);
if (hitGlobalRect != nullptr) {
callScriptFunctionRectHit(hitGlobalRect->_rectHit, hitGlobalRect);
} else if (_shots > 0) {
if (!_debug_unlimitedAmmo) {
_shots--;
}
updateStat();
Rect *hitRect = nullptr;
Zone *hitSceneZone = checkZonesV1(scene, hitRect, &firedCoords);
if (hitSceneZone != nullptr) {
callScriptFunctionZonePtrFb(hitSceneZone->_ptrfb, &firedCoords);
callScriptFunctionRectHit(hitRect->_rectHit, hitRect);
} else {
defaultBullethole(&firedCoords);
}
} else {
playSound(_emptySound);
_whichGun = 9;
}
}
}
if (_curScene == oldscene) {
callScriptFunctionScene(NXTFRM, scene->_nxtfrm, scene);
}
displayScore();
moveMouse();
if (_pauseTime > 0) {
_videoDecoder->pauseAudio(true);
} else {
_videoDecoder->pauseAudio(false);
}
if (_videoDecoder->getCurrentFrame() == 0) {
_videoDecoder->getNextFrame();
}
updateScreen();
int32 remainingMillis = _nextFrameTime - getMsTime();
if (remainingMillis < 10) {
if (_videoDecoder->getCurrentFrame() > 0) {
_videoDecoder->getNextFrame();
}
remainingMillis = _nextFrameTime - getMsTime();
_nextFrameTime = getMsTime() + (remainingMillis > 0 ? remainingMillis : 0) + 100;
}
if (remainingMillis > 0) {
if (remainingMillis > 15) {
remainingMillis = 15;
}
g_system->delayMillis(remainingMillis);
}
_currentFrame = getFrame(scene);
}
// frame limit reached or scene changed, prepare for next scene
_hadPause = false;
_pauseTime = 0;
if (_retScene != "") {
_curScene = _retScene;
_retScene = "";
}
if (_subScene != "") {
_retScene = _subScene;
_subScene = "";
}
if (_curScene == oldscene) {
callScriptFunctionScene(NXTSCN, scene->_nxtscn, scene);
}
if (_curScene == "") {
shutdown();
}
}
removeCursorTimer();
return Common::kNoError;
}
bool GameJohnnyRock::fired(Common::Point *point) {
pollEvents();
_fired = false;
if (!_leftDown) {
_buttonDown = false;
return false;
}
if (_leftDown && !_inMenu) {
_leftDown = true;
}
if (_buttonDown) {
if (_thisGameTimer - _machGunTimer > 3) {
_buttonDown = false;
_mgunCnt++;
if (_mgunCnt > 5) {
_mgunCnt = 0;
_leftDown = false;
}
}
return false;
}
_fired = true;
point->x = _mousePos.x;
point->y = _mousePos.y;
_machGunTimer = _thisGameTimer;
_buttonDown = true;
return true;
}
void GameJohnnyRock::newGame() {
_gameMoney = 2000;
_shots = 400;
_score = 0;
_holster = false;
updateStat();
_retScene = "";
_subScene = "";
}
void GameJohnnyRock::resetParams() {
_subScene = "";
_moneyScene = "";
_thisMap = _rnd->getRandomNumber(2);
_clues = 0;
_gotThisNumber = 0;
_gotThisClue = 0;
_thisClue = 0;
_office = 0;
_casino = 0;
_poolHall = 0;
_warehouse = 0;
_garage = 0;
_mansion = 0;
_didContinue = 0;
_thisDifficulty = _difficulty - 1;
_casinoType = _rnd->getRandomNumber(1);
_poolHallType = _rnd->getRandomNumber(2);
_warehouseType = _rnd->getRandomNumber(2);
_garageType = _rnd->getRandomNumber(1);
_mapTimeout = 0;
_ammoAgain = 0;
_combinations[0] = _rnd->getRandomNumber(5);
_combinations[1] = _rnd->getRandomNumber(5);
_combinations[2] = _rnd->getRandomNumber(5);
_combinations[3] = _rnd->getRandomNumber(5);
_whoDidIt = _rnd->getRandomNumber(3);
_inWarehouse = 0;
_officeCount = 0;
_hadGoToMansion = 0;
_randomPlaceBits = 0;
for (int i = 0; i < 5; i++) {
// this assigns places from _randomPlaces
uint16 picked = pickBits(&_randomPlaceBits, 6);
_entranceIndex[i] = picked;
}
_randomPlaceBits = 0;
for (uint8 i = 5; i < 19; i++) {
// this assigns places from _randomPlacesMR
uint16 picked = pickBits(&_randomPlaceBits, 8);
_entranceIndex[i] = picked;
}
_maxRepeat = _thisDifficulty + 4;
_repeatRandomPlace = 0;
_gotTo = 0;
updateStat();
}
void GameJohnnyRock::outShots() {
_shots = 400;
_score = 0;
_holster = false;
updateStat();
}
void GameJohnnyRock::doMenu() {
uint32 startTime = getMsTime();
updateCursor();
_inMenu = true;
moveMouse();
_videoDecoder->pauseAudio(true);
_screen->copyRectToSurface(_background->getBasePtr(_videoPosX, _videoPosY), _background->pitch, _videoPosX, _videoPosY, _videoDecoder->getWidth(), _videoDecoder->getHeight());
showDifficulty(_difficulty, false);
while (_inMenu && !_vm->shouldQuit()) {
Common::Point firedCoords;
if (fired(&firedCoords)) {
Rect *hitMenuRect = checkZone(_submenzone, &firedCoords);
if (hitMenuRect != nullptr) {
callScriptFunctionRectHit(hitMenuRect->_rectHit, hitMenuRect);
}
}
_leftDown = false;
if (_difficulty != _oldDifficulty) {
changeDifficulty(_difficulty);
}
updateScreen();
g_system->delayMillis(15);
}
updateCursor();
_videoDecoder->pauseAudio(false);
if (_hadPause) {
uint32 endTime = getMsTime();
uint32 timeDiff = endTime - startTime;
_pauseTime += timeDiff;
_nextFrameTime += timeDiff;
}
}
void GameJohnnyRock::updateStat() {
if (_score != _oldScore) {
_oldScore = _score;
Common::String buffer = Common::String::format("%05d", _score);
for (int i = 0; i < 5; i++) {
uint8 digit = buffer[i] - '0';
AlgGraphics::drawImage(_screen, (*_numbers)[digit], (i * 7) + 0x7D, 0xBE);
}
}
if (_gameMoney != _oldGameMoney) {
_oldGameMoney = _gameMoney;
Common::String buffer = Common::String::format("%04d", _gameMoney < 0 ? 0 : _gameMoney);
for (int i = 0; i < 4; i++) {
uint8 digit = buffer[i] - '0';
AlgGraphics::drawImage(_screen, (*_numbers)[digit], (i * 7) + 0x43, 0xBE);
}
}
if (_shots != _oldShots) {
_oldShots = _shots;
Common::String buffer = Common::String::format("%04d", _shots);
for (int i = 0; i < 4; i++) {
uint8 digit = buffer[i] - '0';
AlgGraphics::drawImage(_screen, (*_numbers)[digit], (i * 7) + 0x10A, 0xBE);
}
}
AlgGraphics::drawImage(_screen, (*_difficultyIcon)[_difficulty - 1], 0xBA, 0xBE);
}
void GameJohnnyRock::displayScore() {
updateStat();
}
void GameJohnnyRock::showDifficulty(uint8 newDifficulty, bool cursor) {
// reset menu screen
_screen->copyRectToSurface(_background->getBasePtr(_videoPosX, _videoPosY), _background->pitch, _videoPosX, _videoPosY, _videoDecoder->getWidth(), _videoDecoder->getHeight());
AlgGraphics::drawImageCentered(_screen, _levelIcon, _diffPos[newDifficulty][0], _diffPos[newDifficulty][1]);
if (cursor) {
updateCursor();
}
}
void GameJohnnyRock::changeDifficulty(uint8 newDifficulty) {
if (newDifficulty == _oldDifficulty) {
return;
}
showDifficulty(newDifficulty, true);
Game::adjustDifficulty(newDifficulty, _oldDifficulty);
_oldDifficulty = newDifficulty;
_difficulty = newDifficulty;
}
void GameJohnnyRock::updateCursor() {
_oldWhichGun = _whichGun;
}
void GameJohnnyRock::updateMouse() {
if (_oldWhichGun != _whichGun) {
Graphics::Surface *cursor = (*_gun)[_whichGun];
uint16 hotspotX = (cursor->w / 2);
uint16 hotspotY = (cursor->h / 2);
if (debugChannelSet(1, Alg::kAlgDebugGraphics)) {
cursor->drawLine(0, hotspotY, cursor->w, hotspotY, 1);
cursor->drawLine(hotspotX, 0, hotspotX, cursor->h, 1);
}
CursorMan.replaceCursor(cursor->getPixels(), cursor->w, cursor->h, hotspotX, hotspotY, 0);
CursorMan.showMouse(true);
_oldWhichGun = _whichGun;
}
}
void GameJohnnyRock::moveMouse() {
if (_inMenu) {
if (_mousePos.y > 0xB7) {
_mousePos.y = 0xB7;
}
_whichGun = 8;
} else {
if (_mousePos.y > 0xBC) {
_whichGun = 6;
} else if (_whichGun > 5) {
_whichGun = 0;
}
}
updateMouse();
}
bool GameJohnnyRock::weaponDown() {
if (_rightDown && _mousePos.y >= 0xBC && _mousePos.x >= 0x37) {
return true;
}
return false;
}
bool GameJohnnyRock::saveState() {
Common::OutSaveFile *outSaveFile;
Common::String saveFileName = _vm->getSaveStateName(0);
if (!(outSaveFile = g_system->getSavefileManager()->openForSaving(saveFileName))) {
warning("GameJohnnyRock::saveState(): Can't create file '%s', game not saved", saveFileName.c_str());
return false;
}
outSaveFile->writeUint32BE(MKTAG('A', 'L', 'G', 'S')); // header
outSaveFile->writeByte(0); // version, unused for now
outSaveFile->writeUint16LE(_totalDies);
outSaveFile->writeSint16LE(_gameMoney);
outSaveFile->writeUint16LE(_ammoAgain);
outSaveFile->writeUint16LE(_mapTimeout);
outSaveFile->writeByte(_luckyNumber);
outSaveFile->writeByte(_thisMap);
outSaveFile->writeUint16LE(_clues);
outSaveFile->writeUint16LE(_placeBits);
outSaveFile->writeByte(_randomCount);
outSaveFile->writeUint16LE(_doctorBits);
outSaveFile->writeUint16LE(_undertakerBits);
for (int i = 0; i < 4; i++) {
outSaveFile->writeByte(_clueTable[i]);
}
outSaveFile->writeUint16LE(_thisClue);
outSaveFile->writeByte(_gotThisNumber);
outSaveFile->writeByte(_casino);
outSaveFile->writeByte(_poolHall);
outSaveFile->writeByte(_warehouse);
outSaveFile->writeByte(_garage);
outSaveFile->writeByte(_office);
outSaveFile->writeByte(_casinoType);
outSaveFile->writeByte(_poolHallType);
outSaveFile->writeByte(_warehouseType);
outSaveFile->writeByte(_garageType);
outSaveFile->writeByte(_mansion);
outSaveFile->writeByte(_inWarehouse);
outSaveFile->writeByte(_inOffice);
outSaveFile->writeUint16LE(_gotTo);
for (int i = 0; i < 20; i++) {
outSaveFile->writeUint16LE(_entranceIndex[i]);
}
for (int i = 0; i < 10; i++) {
outSaveFile->writeUint16LE(_randomScenesIndex[i]);
}
for (int i = 0; i < 4; i++) {
outSaveFile->writeByte(_combinations[i]);
}
outSaveFile->writeByte(_whoDidIt);
outSaveFile->writeByte(_hadGoToMansion);
outSaveFile->writeUint16LE(_officeCount);
outSaveFile->writeUint16LE(_randomPlaceBits);
outSaveFile->writeByte(_maxRandomCount);
outSaveFile->writeUint16LE(_gotoAfterRandom);
outSaveFile->writeUint16LE(_repeatRandomPlace);
outSaveFile->writeUint16LE(_maxRepeat);
outSaveFile->writeUint16LE(_gotThisClue);
outSaveFile->writeUint16LE(_didContinue);
outSaveFile->writeUint16LE(_thisGameTime);
outSaveFile->writeUint16LE(_shots);
outSaveFile->writeSint32LE(_score);
outSaveFile->writeByte(_holster);
outSaveFile->writeByte(_difficulty);
outSaveFile->writeByte(_thisDifficulty);
outSaveFile->writeString(_moneyScene);
outSaveFile->writeByte(0);
outSaveFile->writeString(_curScene);
outSaveFile->writeByte(0);
outSaveFile->writeString(_subScene);
outSaveFile->writeByte(0);
outSaveFile->writeString(_retScene);
outSaveFile->writeByte(0);
outSaveFile->writeByte(_randomScenesSavestateIndex);
outSaveFile->finalize();
delete outSaveFile;
return true;
}
bool GameJohnnyRock::loadState() {
Common::InSaveFile *inSaveFile;
Common::String saveFileName = _vm->getSaveStateName(0);
if (!(inSaveFile = g_system->getSavefileManager()->openForLoading(saveFileName))) {
debug("GameJohnnyRock::loadState(): Can't load file '%s', game not loaded", saveFileName.c_str());
return false;
}
uint32 header = inSaveFile->readUint32BE();
if (header != MKTAG('A', 'L', 'G', 'S')) {
warning("GameJohnnyRock::loadState(): Unkown save file, header: %s", tag2str(header));
return false;
}
inSaveFile->skip(1); // version, unused for now
_totalDies = inSaveFile->readUint16LE();
_gameMoney = inSaveFile->readSint16LE();
_ammoAgain = inSaveFile->readUint16LE();
_mapTimeout = inSaveFile->readUint16LE();
_luckyNumber = inSaveFile->readByte();
_thisMap = inSaveFile->readByte();
_clues = inSaveFile->readUint16LE();
_placeBits = inSaveFile->readUint16LE();
_randomCount = inSaveFile->readByte();
_doctorBits = inSaveFile->readUint16LE();
_undertakerBits = inSaveFile->readUint16LE();
for (int i = 0; i < 4; i++) {
_clueTable[i] = inSaveFile->readByte();
}
_thisClue = inSaveFile->readUint16LE();
_gotThisNumber = inSaveFile->readByte();
_casino = inSaveFile->readByte();
_poolHall = inSaveFile->readByte();
_warehouse = inSaveFile->readByte();
_garage = inSaveFile->readByte();
_office = inSaveFile->readByte();
_casinoType = inSaveFile->readByte();
_poolHallType = inSaveFile->readByte();
_warehouseType = inSaveFile->readByte();
_garageType = inSaveFile->readByte();
_mansion = inSaveFile->readByte();
_inWarehouse = inSaveFile->readByte();
_inOffice = inSaveFile->readByte();
_gotTo = inSaveFile->readUint16LE();
for (int i = 0; i < 20; i++) {
_entranceIndex[i] = inSaveFile->readUint16LE();
}
for (int i = 0; i < 10; i++) {
_randomScenesIndex[i] = inSaveFile->readUint16LE();
}
for (int i = 0; i < 4; i++) {
_combinations[i] = inSaveFile->readByte();
}
_whoDidIt = inSaveFile->readByte();
_hadGoToMansion = inSaveFile->readByte();
_officeCount = inSaveFile->readUint16LE();
_randomPlaceBits = inSaveFile->readUint16LE();
_maxRandomCount = inSaveFile->readByte();
_gotoAfterRandom = inSaveFile->readUint16LE();
_repeatRandomPlace = inSaveFile->readUint16LE();
_maxRepeat = inSaveFile->readUint16LE();
_gotThisClue = inSaveFile->readUint16LE();
_didContinue = inSaveFile->readUint16LE();
_thisGameTime = inSaveFile->readUint16LE();
_shots = inSaveFile->readUint16LE();
_score = inSaveFile->readSint32LE();
_holster = inSaveFile->readByte();
_difficulty = inSaveFile->readByte();
_thisDifficulty = inSaveFile->readByte();
_moneyScene = inSaveFile->readString();
_curScene = inSaveFile->readString();
_subScene = inSaveFile->readString();
_retScene = inSaveFile->readString();
_randomScenesSavestateIndex = inSaveFile->readByte();
delete inSaveFile;
// find out where _random_scenes should point
uint16 placeIndex = _entranceIndex[_randomScenesSavestateIndex];
if (_randomScenesSavestateIndex < 5) {
_randomScenes = _randomPlaces[placeIndex];
} else {
_randomScenes = _randomPlacesMR[placeIndex];
}
changeDifficulty(_difficulty);
debug("lucky number: %d", (_luckyNumber + 1));
return true;
}
void GameJohnnyRock::doMoneySound() {
playSound(_skullSound);
}
// Misc game functions
Common::String GameJohnnyRock::numToScene(int n) {
switch (n) {
case 1:
return "scene1a";
case 10:
return "scene10a";
case 12:
return "scene12a";
case 14:
return "scene14a";
case 18:
return "scene18a";
case 63:
return "scene63a";
case 71:
return "scene71a";
case 120:
return "scn120a";
case 137:
return "scn137a";
default:
return Common::String::format("scene%d", n);
}
}
uint16 GameJohnnyRock::sceneToNum(Common::String sceneName) {
Common::String temp;
uint16 index = 4;
if (sceneName[index] == 'e') {
index++;
}
while (sceneName[index] != 'a' && sceneName[index] != 'b' && sceneName[index] != 'c' && sceneName[index] != '\0') {
temp += sceneName[index];
index++;
if (index >= sceneName.size()) {
break;
}
}
return atoi(temp.c_str());
}
void GameJohnnyRock::defaultBullethole(Common::Point *point) {
if (point->x >= 14 && point->x <= 306 && point->y >= 5 && point->y <= 169) {
uint16 targetX = point->x - _videoPosX;
uint16 targetY = point->y - _videoPosY;
AlgGraphics::drawImageCentered(_videoDecoder->getVideoFrame(), _bulletholeIcon, targetX, targetY);
updateCursor();
_shotFired = true;
doShot();
}
}
uint16 GameJohnnyRock::pickBits(uint16 *bits, uint8 max) {
// reset bits if full
if (*bits == (0xFFFF >> (16 - max))) {
*bits = 0;
}
uint8 randomNum = _rnd->getRandomNumber(max - 1);
// find first unused bit position
while (*bits & (1 << randomNum)) {
randomNum++;
if (randomNum >= max) {
randomNum = 0;
}
}
*bits |= (1 << randomNum);
return randomNum;
}
uint16 GameJohnnyRock::pickRandomPlace(uint8 place) {
_randomScenesSavestateIndex = place;
uint16 placeIndex = _entranceIndex[place];
if (place < 5) {
_randomScenes = _randomPlaces[placeIndex];
} else {
_randomScenes = _randomPlacesMR[placeIndex];
}
_placeBits = 0;
_randomCount = 0;
memset(&_randomScenesIndex, 0, (10 * sizeof(uint16)));
for (int i = 0; i < (_randomScenes[0] + 4); i++) {
_randomScenesIndex[i] = _randomScenes[i];
}
if (_randomScenes[1] < 0) {
_maxRandomCount = (_thisDifficulty * 2) - _randomScenes[1];
} else {
_maxRandomCount = _randomScenes[1];
}
uint16 index = pickBits(&_placeBits, _randomScenes[0]);
return _randomScenes[index + 4];
}
void GameJohnnyRock::showCombination() {
uint16 offset = (_gotThisClue * 6) + _combinations[_gotThisClue];
_gotThisClue++;
if (_gotThisClue == 4) {
_mansion = 3;
}
_curScene = numToScene(offset + 0xDB);
}
// Script functions: Zone
void GameJohnnyRock::zoneBullethole(Common::Point *point) {
defaultBullethole(point);
}
void GameJohnnyRock::rectShotMenu(Rect *rect) {
doMenu();
}
void GameJohnnyRock::rectSave(Rect *rect) {
if (saveState()) {
doSaveSound();
}
}
void GameJohnnyRock::rectLoad(Rect *rect) {
if (loadState()) {
doLoadSound();
}
}
void GameJohnnyRock::rectContinue(Rect *rect) {
_inMenu = false;
_fired = false;
if (_gameMoney < 0) {
newGame();
_retScene = "";
_subScene = "";
if (_inOffice) {
_curScene = numToScene(_inOffice);
} else {
_curScene = numToScene(_thisMap + 174);
}
_didContinue++;
}
if (_shots <= 0) {
outShots();
_didContinue++;
}
}
void GameJohnnyRock::rectStart(Rect *rect) {
_inMenu = false;
_fired = false;
_thisDifficulty = 0;
Scene *scene = _sceneInfo->findScene(_startScene);
if (scene->_nxtscn == "DRAWGUN") {
callScriptFunctionScene(NXTSCN, "DRAWGUN", scene);
}
_curScene = _startScene;
resetParams();
newGame();
updateStat();
}
void GameJohnnyRock::rectKillInnocent(Rect *rect) {
_inOffice = sceneToNum(_curScene);
if (_inOffice >= 0x13) {
_inOffice = 0;
}
if (!_debug_godMode) {
_gameMoney -= 400;
}
if (_gameMoney < 0) {
_subScene = "scene358";
_retScene = "";
_curScene = "scene151";
} else {
switch (_rnd->getRandomNumber(2)) {
case 0:
_curScene = "scene151";
break;
case 1:
_curScene = "scene152";
break;
case 2:
_curScene = "scene153";
break;
}
}
}
void GameJohnnyRock::rectSelectCasino(Rect *rect) {
_retScene = "";
if (_mansion == 5 && _whoDidIt == 1) {
_repeatRandomPlace = _maxRepeat;
_gotoAfterRandom = 0xF5;
_curScene = numToScene(pickRandomPlace(_maxRepeat + 5));
} else if (_casino == 0) {
if (_gotTo & 1) {
_curScene = "scene19";
} else {
_gotoAfterRandom = 0x13;
_curScene = numToScene(pickRandomPlace(0));
}
} else if (_casino == 1 || _casino == 3) {
_curScene = "scene44";
} else {
_casino = 3;
if (_rnd->getRandomBit()) { // original: (_this_game_time & 1) == 0
_curScene = "scene64";
} else {
_curScene = "scene65";
}
}
}
void GameJohnnyRock::rectSelectPoolhall(Rect *rect) {
_retScene = "";
if (_mansion == 5 && _whoDidIt == 0) {
_repeatRandomPlace = _maxRepeat;
_gotoAfterRandom = 0xF7;
_curScene = numToScene(pickRandomPlace(_maxRepeat + 5));
} else if (_poolHall == 0) {
if (_gotTo & 2) {
_curScene = "scene66";
} else {
_gotoAfterRandom = 0x42;
_curScene = numToScene(pickRandomPlace(1));
}
} else if (_poolHall == 1 || _poolHall == 3) {
_curScene = "scene82";
} else {
_poolHall = 3;
_curScene = "scene89";
}
}
void GameJohnnyRock::rectSelectWarehouse(Rect *rect) {
_retScene = "";
if (_mansion == 5 && _whoDidIt == 2) {
_repeatRandomPlace = _maxRepeat;
_gotoAfterRandom = 0xF9;
_curScene = numToScene(pickRandomPlace(_maxRepeat + 5));
} else if (_warehouse == 0) {
if (_inWarehouse < 2) {
if (_gotTo & 4) {
_curScene = "scene90";
} else {
_inWarehouse = 1;
_gotoAfterRandom = 0x5A;
_curScene = numToScene(pickRandomPlace(2));
}
} else if (_inWarehouse == 2) {
_curScene = "scene93";
} else if (_inWarehouse == 3) {
_curScene = "scene119";
}
} else if (_warehouse == 1 || _warehouse == 3) {
_curScene = "scene122";
} else {
_warehouse = 3;
_curScene = "scene121";
}
}
void GameJohnnyRock::rectSelectGarage(Rect *rect) {
_retScene = "";
if (_mansion == 5 && _whoDidIt == 3) {
_repeatRandomPlace = _maxRepeat;
_gotoAfterRandom = 0xFB;
_curScene = numToScene(pickRandomPlace(_maxRepeat + 5));
} else if (_garage == 0) {
if (_gotTo & 8) {
_curScene = "scene123";
} else {
_gotoAfterRandom = 0x7B;
_curScene = numToScene(pickRandomPlace(3));
}
} else if (_garage == 1 || _garage == 3) {
_curScene = "scene138";
} else {
_garage = 3;
_curScene = "scene139";
}
}
void GameJohnnyRock::rectSelectMansion(Rect *rect) {
_placeBits = 0;
_randomCount = 1;
_retScene = "";
if (_mansion == 1) {
uint16 picked = pickBits(&_placeBits, 5);
_curScene = numToScene(0xB8 + (picked * 2));
} else if (_mansion == 2) {
_curScene = "scene194";
} else if (_mansion == 3) {
_curScene = "scene207";
} else if (_mansion == 4) {
_gotThisNumber = 0;
_curScene = "scene212";
} else if (_mansion == 5) {
_curScene = "scene243";
} else {
if (_garage == 0 || _casino == 0 || _poolHall == 0 || _warehouse == 0) {
_curScene = "scene243";
} else if (_gotTo & 0x10) {
_curScene = "scene180";
} else {
_gotoAfterRandom = 0xB4;
_curScene = numToScene(pickRandomPlace(4));
}
}
}
void GameJohnnyRock::rectSelectAmmo(Rect *rect) {
_retScene = "";
if (_gameMoney >= 100) {
if (!_debug_godMode) {
_gameMoney -= 100;
}
_shots += 200;
_ammoAgain = 0;
doMoneySound();
_curScene = "scene178";
} else {
_ammoAgain++;
if (_ammoAgain >= 2) {
_curScene = "scene243";
} else {
_curScene = "scene179";
}
}
}
void GameJohnnyRock::rectSelectOffice(Rect *rect) {
_retScene = "";
if (!_office) {
_office = 1;
_curScene = "scene168";
} else {
if (_rnd->getRandomBit()) { // original: _this_game_time & 1
_curScene = "scene243";
} else {
_curScene = "scene262";
}
}
}
void GameJohnnyRock::shotClue(uint8 clue) {
if (_clueTable[_gotThisClue] == clue) {
showCombination();
} else {
_gotThisClue = 0;
_curScene = "scene374";
}
}
void GameJohnnyRock::rectShotManBust(Rect *rect) {
shotClue(0);
}
void GameJohnnyRock::rectShotWomanBust(Rect *rect) {
shotClue(1);
}
void GameJohnnyRock::rectShotBlueVase(Rect *rect) {
shotClue(2);
}
void GameJohnnyRock::rectShotCat(Rect *rect) {
shotClue(3);
}
void GameJohnnyRock::rectShotIndian(Rect *rect) {
shotClue(4);
}
void GameJohnnyRock::rectShotPlate(Rect *rect) {
shotClue(5);
}
void GameJohnnyRock::rectShotBlueDressPic(Rect *rect) {
shotClue(6);
}
void GameJohnnyRock::rectShotModernPic(Rect *rect) {
shotClue(7);
}
void GameJohnnyRock::rectShotMonaLisa(Rect *rect) {
shotClue(8);
}
void GameJohnnyRock::rectShotGWashington(Rect *rect) {
shotClue(9);
}
void GameJohnnyRock::rectShotBoyInRedPic(Rect *rect) {
shotClue(10);
}
void GameJohnnyRock::rectShotCoatOfArms(Rect *rect) {
shotClue(11);
}
void GameJohnnyRock::shotCombination(uint8 combination, bool combinationB) {
if (_combinations[_gotThisNumber] == combination) {
_gotThisNumber++;
if (_gotThisNumber >= 4) {
_mansion = 5;
_curScene = numToScene(_whoDidIt + 0xD7);
} else {
if (combinationB) {
_curScene = "scene213";
} else {
_curScene = "scene214";
}
}
} else {
_gotThisNumber = 0;
_curScene = "scene376";
}
}
void GameJohnnyRock::rectShotCombinationA0(Rect *rect) {
shotCombination(0, false);
}
void GameJohnnyRock::rectShotCombinationA1(Rect *rect) {
shotCombination(1, false);
}
void GameJohnnyRock::rectShotCombinationA2(Rect *rect) {
shotCombination(2, false);
}
void GameJohnnyRock::rectShotCombinationA3(Rect *rect) {
shotCombination(3, false);
}
void GameJohnnyRock::rectShotCombinationA4(Rect *rect) {
shotCombination(4, false);
}
void GameJohnnyRock::rectShotCombinationA5(Rect *rect) {
shotCombination(5, false);
}
void GameJohnnyRock::rectShotCombinationB0(Rect *rect) {
shotCombination(0, true);
}
void GameJohnnyRock::rectShotCombinationB1(Rect *rect) {
shotCombination(1, true);
}
void GameJohnnyRock::rectShotCombinationB2(Rect *rect) {
shotCombination(2, true);
}
void GameJohnnyRock::rectShotCombinationB3(Rect *rect) {
shotCombination(3, true);
}
void GameJohnnyRock::rectShotCombinationB4(Rect *rect) {
shotCombination(4, true);
}
void GameJohnnyRock::rectShotCombinationB5(Rect *rect) {
shotCombination(5, true);
}
void GameJohnnyRock::shotLuckyNumber(uint8 number) {
if (_luckyNumber != number || _curScene == _moneyScene) {
return;
}
doMoneySound();
_gameMoney += 100;
_score += 500;
_moneyScene = _curScene;
}
void GameJohnnyRock::rectShotLuckyNumber0(Rect *rect) {
shotLuckyNumber(0);
}
void GameJohnnyRock::rectShotLuckyNumber1(Rect *rect) {
shotLuckyNumber(1);
}
void GameJohnnyRock::rectShotLuckyNumber2(Rect *rect) {
shotLuckyNumber(2);
}
void GameJohnnyRock::rectShotLuckyNumber3(Rect *rect) {
shotLuckyNumber(3);
}
void GameJohnnyRock::rectShotLuckyNumber4(Rect *rect) {
shotLuckyNumber(4);
}
void GameJohnnyRock::rectShotLuckyNumber5(Rect *rect) {
shotLuckyNumber(5);
}
// Script functions: Scene PreOps
// Script functions: Scene Scene InsOps
void GameJohnnyRock::sceneIsoShootpast(Scene *scene) {
if (_fired) {
if (_retScene != "") {
_curScene = _retScene;
_retScene = "";
} else if (_subScene != "") {
_curScene = _subScene;
_subScene = "";
} else {
callScriptFunctionScene(NXTSCN, scene->_nxtscn, scene);
}
}
}
void GameJohnnyRock::sceneIsoShootpastPause(Scene *scene) {
sceneIsoShootpast(scene);
sceneIsoPause(scene);
}
void GameJohnnyRock::sceneIsoGotoCasino(Scene *scene) {
_gotTo |= 1;
sceneIsoShootpast(scene);
}
void GameJohnnyRock::sceneIsoGotoPoolhall(Scene *scene) {
_gotTo |= 2;
sceneIsoShootpast(scene);
}
void GameJohnnyRock::sceneIsoGotoWarehouse(Scene *scene) {
_gotTo |= 4;
}
void GameJohnnyRock::sceneIsoInWarehouse2(Scene *scene) {
_inWarehouse = 2;
sceneIsoShootpast(scene);
}
void GameJohnnyRock::sceneIsoInwarehouse3(Scene *scene) {
_inWarehouse = 3;
sceneIsoShootpast(scene);
}
void GameJohnnyRock::sceneIsoGotoGarage(Scene *scene) {
_gotTo |= 8;
sceneIsoShootpast(scene);
}
void GameJohnnyRock::sceneIsoGotoMansion(Scene *scene) {
_gotTo |= 0x10;
}
void GameJohnnyRock::sceneIsoInMansion1(Scene *scene) {
_mansion = 1;
}
// Script functions: Scene NxtScn
void GameJohnnyRock::sceneNxtscnDied(Scene *scene) {
uint16 sceneNum = sceneToNum(_curScene);
_inOffice = sceneNum;
if (sceneNum >= 0x13) {
_inOffice = 0;
}
_totalDies++;
if (!_debug_godMode) {
_gameMoney -= 400;
}
if (_gameMoney < 0) {
switch (_rnd->getRandomNumber(2)) {
case 0:
_curScene = "scene148";
break;
case 1:
_curScene = "scene149";
break;
case 2:
_curScene = "scene150";
break;
}
} else {
switch (pickBits(&_doctorBits, 8)) {
case 0:
_curScene = "scene140";
break;
case 1:
_curScene = "scene141";
break;
case 2:
_curScene = "scene142";
break;
case 3:
_curScene = "scene143";
break;
case 4:
_curScene = "scene144";
break;
case 5:
_curScene = "scene145";
break;
case 6:
_curScene = "scene146";
break;
case 7:
_curScene = "scene147";
break;
}
}
}
void GameJohnnyRock::sceneNxtscnBombDead(Scene *scene) {
uint16 sceneNum = sceneToNum(_curScene);
_inOffice = sceneNum;
if (sceneNum >= 0x13) {
_inOffice = 0;
}
_totalDies++;
if (!_debug_godMode) {
_gameMoney -= 400;
}
if (_gameMoney < 0) {
switch (_rnd->getRandomNumber(2)) {
case 0:
_curScene = "scene148";
break;
case 1:
_curScene = "scene149";
break;
case 2:
_curScene = "scene150";
break;
}
} else {
_curScene = "scene142";
}
}
void GameJohnnyRock::sceneNxtscnPickUndertaker(Scene *scene) {
switch (pickBits(&_undertakerBits, 3)) {
case 0:
_curScene = "scene154";
break;
case 1:
_curScene = "scene155";
break;
case 2:
_curScene = "scene156";
break;
}
}
void GameJohnnyRock::sceneNxtscnCallAttract(Scene *scene) {
resetParams();
newGame();
_curScene = "scn354aa";
}
void GameJohnnyRock::sceneNxtscnPickLuckyNumber(Scene *scene) {
_luckyNumber = _rnd->getRandomNumber(5);
debug("lucky number: %d", (_luckyNumber + 1));
_curScene = Common::String::format("scene%d", _luckyNumber + 3);
}
void GameJohnnyRock::sceneNxtscnPickMap(Scene *scene) {
Common::String nextScene;
if (_gameMoney < 0) {
switch (_rnd->getRandomNumber(2)) {
case 0:
_curScene = "scene148";
break;
case 1:
_curScene = "scene149";
break;
case 2:
_curScene = "scene150";
break;
}
return;
}
uint16 sceneNum = sceneToNum(_curScene);
if (sceneNum == 18) {
_inOffice = 0;
}
if (_inOffice) {
nextScene = numToScene(_inOffice);
} else if (_officeCount < 10) {
if ((_officeCount % 3) == 0) {
uint16 sceneNume = _officeTable[_officeCount / 3];
nextScene = numToScene(sceneNume);
}
_officeCount++;
} else if (_thisClue == 2 && !_hadGoToMansion) {
if (!_didContinue) {
_thisDifficulty++;
if (_thisDifficulty > 7)
_thisDifficulty = 7;
}
_hadGoToMansion = 1;
if (_poolHall) {
_poolHall = 2;
nextScene = "scene162";
} else if (_casino) {
_casino = 2;
nextScene = "scene163";
} else if (_warehouse) {
_warehouse = 2;
nextScene = "scene165";
}
} else if (_thisClue == 3 && _hadGoToMansion == 1) {
if (_totalDies < 4) {
_thisDifficulty++;
if (_thisDifficulty > 7)
_thisDifficulty = 7;
}
_hadGoToMansion = 2;
if (_poolHall == 1) {
_poolHall = 2;
nextScene = "scene162";
} else if (_casino == 1) {
_casino = 2;
nextScene = "scene163";
} else if (_warehouse == 1) {
_warehouse = 2;
nextScene = "scene165";
}
} else if (_hadGoToMansion == 2 && _garage && _casino && _poolHall && _warehouse) {
if (_totalDies < 5 || _didContinue <= 1) {
_thisDifficulty++;
if (_thisDifficulty > 7)
_thisDifficulty = 7;
}
_hadGoToMansion = 3;
nextScene = "scene166";
}
if (!nextScene.empty()) {
_curScene = nextScene;
} else {
_curScene = numToScene(_thisMap + 174);
}
}
void GameJohnnyRock::sceneNxtscnPickClue(Scene *scene) {
uint16 picked = pickBits(&_clues, 12);
_clueTable[_thisClue] = picked;
_thisClue++;
_curScene = numToScene(picked + 0xC3);
}
void GameJohnnyRock::sceneNxtscnMapTimeout(Scene *scene) {
_mapTimeout++;
if (_mapTimeout < 3) {
_curScene = "scene360";
} else {
_curScene = "scene262";
}
}
void GameJohnnyRock::sceneNxtscnEnterCasino(Scene *scene) {
_placeBits = 0;
_randomCount = 0;
uint16 sceneNum;
if (_casinoType != 0) {
sceneNum = (pickBits(&_placeBits, 12) * 2) + 0x14;
} else {
sceneNum = (pickBits(&_placeBits, 8) * 2) + 0x2D;
}
_curScene = numToScene(sceneNum);
}
void GameJohnnyRock::sceneNxtscnCasinoWhat(Scene *scene) {
_randomCount++;
uint16 maxRandom = ((_thisDifficulty * 3) + 6);
if (_randomCount > maxRandom) {
_casino = 1;
_curScene = "scene63a";
} else {
uint16 sceneNum;
if (_casinoType != 0) {
sceneNum = (pickBits(&_placeBits, 12) * 2) + 0x14;
} else {
sceneNum = (pickBits(&_placeBits, 8) * 2) + 0x2D;
}
_curScene = numToScene(sceneNum);
}
}
void GameJohnnyRock::sceneNxtscnEnterPoolhall(Scene *scene) {
if (_poolHallType == 0) {
_curScene = "scene67";
} else if (_poolHallType == 1) {
_curScene = "scene73";
} else {
_curScene = "scene78";
}
}
void GameJohnnyRock::sceneNxtscnPoolhallClue(Scene *scene) {
_poolHall = 1;
uint16 clue = pickBits(&_clues, 12);
_clueTable[_thisClue] = clue;
_thisClue++;
_curScene = numToScene(clue + 0xC3);
}
void GameJohnnyRock::sceneNxtscnEnterWarehouse(Scene *scene) {
if (_warehouseType == 0) {
_curScene = "scene94";
} else if (_warehouseType == 1) {
_curScene = "scene102";
} else {
_curScene = "scene110";
}
}
void GameJohnnyRock::sceneNxtscnWarehouseClue(Scene *scene) {
_warehouse = 1;
uint16 clue = pickBits(&_clues, 12);
_clueTable[_thisClue] = clue;
_thisClue++;
_curScene = numToScene(clue + 0xC3);
}
void GameJohnnyRock::sceneNxtscnEnterGarage(Scene *scene) {
if (_garageType != 0) {
_curScene = "scene124";
} else {
_curScene = "scene131";
}
}
void GameJohnnyRock::sceneNxtscnGarageClue(Scene *scene) {
_garage = 1;
uint16 clue = pickBits(&_clues, 12);
_clueTable[_thisClue] = clue;
_thisClue++;
_curScene = numToScene(clue + 0xC3);
}
void GameJohnnyRock::sceneNxtscnEnterMansion(Scene *scene) {
_mansion = 1;
_randomCount++;
uint16 maxRandom = ((_thisDifficulty * 2) + 7);
if (_randomCount <= maxRandom) {
uint16 picked = pickBits(&_placeBits, 5);
_curScene = numToScene((picked * 2) + 0xB8);
} else {
_mansion = 2;
_curScene = "scene194";
}
}
void GameJohnnyRock::sceneNxtscnGiveClue(Scene *scene) {
_score += 1000;
_gameMoney += 50;
sceneNxtscnPickMap(scene);
}
void GameJohnnyRock::sceneNxtscnPickFlowerMan(Scene *scene) {
if (_rnd->getRandomBit()) {
_curScene = "scene10a";
} else {
_curScene = "scene12a";
}
}
void GameJohnnyRock::sceneNxtscnRandomScene(Scene *scene) {
_randomCount++;
if (_randomCount <= _maxRandomCount) {
_placeBits = pickBits(&_placeBits, _randomScenes[0]);
_curScene = numToScene(_randomScenes[_placeBits + 4]);
} else {
if (_randomScenes[2] != 0) {
_curScene = numToScene(_randomScenes[2]);
} else if (_repeatRandomPlace > 0) {
_repeatRandomPlace--;
_maxRepeat--;
uint16 picked = pickRandomPlace(_repeatRandomPlace + 5);
_curScene = numToScene(picked);
} else {
_curScene = numToScene(_gotoAfterRandom);
_gotoAfterRandom = 0;
_placeBits = 0;
_randomCount = 1;
}
}
}
void GameJohnnyRock::sceneNxtscnEndRandScene(Scene *scene) {
if (_repeatRandomPlace > 0) {
_repeatRandomPlace--;
_maxRepeat--;
uint16 picked = pickRandomPlace(_repeatRandomPlace + 5);
_curScene = numToScene(picked);
} else {
_curScene = numToScene(_gotoAfterRandom);
_gotoAfterRandom = 0;
_placeBits = 0;
_randomCount = 1;
}
}
void GameJohnnyRock::sceneNxtscnKillInnocent(Scene *scene) {
if (!_debug_godMode) {
_gameMoney -= 400;
}
if (_gameMoney < 0) {
_retScene = "scene358";
_curScene = "scene151";
} else {
switch (_rnd->getRandomNumber(2)) {
case 0:
_curScene = "scene151";
break;
case 1:
_curScene = "scene152";
break;
case 2:
_curScene = "scene153";
break;
}
}
}
// Script functions: WepDwn
void GameJohnnyRock::sceneDefaultWepdwn(Scene *scene) {
_inHolster = 9;
_whichGun = 7;
updateMouse();
}
// Debug methods
void GameJohnnyRock::debugWarpTo(int val) {
// TODO implement
}
// Debugger methods
DebuggerJohnnyRock::DebuggerJohnnyRock(GameJohnnyRock *game) {
_game = game;
registerVar("drawRects", &game->_debug_drawRects);
registerVar("godMode", &game->_debug_godMode);
registerVar("unlimitedAmmo", &game->_debug_unlimitedAmmo);
registerCmd("warpTo", WRAP_METHOD(DebuggerJohnnyRock, cmdWarpTo));
registerCmd("dumpLib", WRAP_METHOD(DebuggerJohnnyRock, cmdDumpLib));
}
bool DebuggerJohnnyRock::cmdWarpTo(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: warp <int>");
return true;
} else {
int val = atoi(argv[1]);
_game->debugWarpTo(val);
return false;
}
}
bool DebuggerJohnnyRock::cmdDumpLib(int argc, const char **argv) {
return _game->debug_dumpLibFile();
}
} // End of namespace Alg