diff options
-rw-r--r-- | sky/compact.cpp | 2 | ||||
-rw-r--r-- | sky/control.cpp | 11 | ||||
-rw-r--r-- | sky/logic.cpp | 103 | ||||
-rw-r--r-- | sky/logic.h | 47 | ||||
-rw-r--r-- | sky/mouse.cpp | 4 | ||||
-rw-r--r-- | sky/sky.cpp | 188 | ||||
-rw-r--r-- | sky/sky.h | 13 |
7 files changed, 161 insertions, 207 deletions
diff --git a/sky/compact.cpp b/sky/compact.cpp index 6030a9893e..3b2eee59aa 100644 --- a/sky/compact.cpp +++ b/sky/compact.cpp @@ -288,7 +288,7 @@ uint16 *SkyCompact::getSub(Compact *cpt, uint16 mode) { uint16 *SkyCompact::getGrafixPtr(Compact *cpt) { uint16 *gfxBase = (uint16*)fetchCpt(cpt->grafixProgId); if ((gfxBase == NULL) && cpt->grafixProgPos) { - warning("SkyCompact::getGrafixPtr: got offset for null ptr"); + debug(1, "SkyCompact::getGrafixPtr: got offset for null ptr"); return NULL; } return gfxBase + cpt->grafixProgPos; diff --git a/sky/control.cpp b/sky/control.cpp index b5d51f6ec1..730699ba5b 100644 --- a/sky/control.cpp +++ b/sky/control.cpp @@ -1327,6 +1327,8 @@ uint16 Control::parseSaveData(uint8 *srcBuf) { return RESTORE_FAILED; } } + SkyEngine::_systemVars.systemFlags |= SF_GAME_RESTORED; + LODSW(srcPos, _skySound->_saveSounds[0]); LODSW(srcPos, _skySound->_saveSounds[1]); _skySound->restoreSfx(); @@ -1337,8 +1339,8 @@ uint16 Control::parseSaveData(uint8 *srcBuf) { LODSD(srcPos, mouseType); LODSD(srcPos, palette); - for (cnt = 0; cnt < 838; cnt++) - LODSD(srcPos, Logic::_scriptVariables[cnt]); + _skyLogic->parseSaveData((uint32*)srcPos); + srcPos += NUM_SKY_SCRIPTVARS * sizeof(uint32); for (cnt = 0; cnt < 60; cnt++) LODSD(srcPos, reloadList[cnt]); @@ -1375,11 +1377,6 @@ uint16 Control::parseSaveData(uint8 *srcBuf) { if (srcPos - srcBuf != (int32)size) error("Restore failed! Savegame data = %d bytes. Expected size: %d", srcPos-srcBuf, size); - SkyEngine::_systemVars.systemFlags |= SF_GAME_RESTORED; - if (!SkyEngine::isDemo()) { - _skyLogic->fnLeaveSection(oldSection, 0, 0); - _skyLogic->fnEnterSection(Logic::_scriptVariables[CUR_SECTION], 0, 0); - } _skyDisk->refreshFilesList(reloadList); SkyEngine::_systemVars.currentMusic = (uint16)music; if (!(SkyEngine::_systemVars.systemFlags & SF_MUS_OFF)) diff --git a/sky/logic.cpp b/sky/logic.cpp index 88003d59ee..dd3146936c 100644 --- a/sky/logic.cpp +++ b/sky/logic.cpp @@ -37,10 +37,9 @@ namespace Sky { -uint32 Logic::_scriptVariables[838]; +uint32 Logic::_scriptVariables[NUM_SKY_SCRIPTVARS]; -typedef void (Logic::*LogicTable) (); -static const LogicTable logicTable[] = { +const LogicTable Logic::_logicTable[] = { &Logic::nop, &Logic::logicScript, // 1 script processor &Logic::autoRoute, // 2 Make a route @@ -81,58 +80,71 @@ Logic::Logic(SkyCompact *skyCompact, Screen *skyScreen, Disk *skyDisk, Text *sky initScriptVariables(); } -bool Logic::checkProtection(void) { +void Logic::initScreen0(void) { + fnEnterSection(0, 0, 0); + _skyMusic->startMusic(2); + SkyEngine::_systemVars.currentMusic = 2; +} - if (!_scriptVariables[ENTER_DIGITS]) return false; - if (_scriptVariables[CONSOLE_TYPE] == 5) { // reactor code - _scriptVariables[FS_COMMAND] = 240; - _scriptVariables[ENTER_DIGITS] = 0; - return true; - } else { // copy protection - _scriptVariables[FS_COMMAND] = 337; +void Logic::parseSaveData(uint32 *data) { + if (!SkyEngine::isDemo()) + fnLeaveSection(_scriptVariables[CUR_SECTION], 0, 0); + for (uint16 cnt = 0; cnt < NUM_SKY_SCRIPTVARS; cnt++) + _scriptVariables[cnt] = READ_LE_UINT32(data++); + fnEnterSection(_scriptVariables[CUR_SECTION], 0, 0); +} + +bool Logic::checkProtection(void) { + if (_scriptVariables[ENTER_DIGITS]) { + if (_scriptVariables[CONSOLE_TYPE] == 5) // reactor code + _scriptVariables[FS_COMMAND] = 240; + else // copy protection + _scriptVariables[FS_COMMAND] = 337; _scriptVariables[ENTER_DIGITS] = 0; return true; - } + } else + return false; } void Logic::engine() { - uint16 *logicList = (uint16 *)_skyCompact->fetchCpt(_scriptVariables[LOGIC_LIST_NO]); - //uint16 *logicList = (uint16*)_skyCompact->fetchFromDataList(_scriptVariables[LOGIC_LIST_NO]); - - while (uint16 id = *logicList++) { // 0 means end of list - if (id == 0xffff) { - // Change logic data address - if (*logicList == ID_STD_MENU_LOGIC) - printf("\n\n\nMenu Logic:\n"); - logicList = (uint16 *)_skyCompact->fetchCpt(*logicList); - continue; - } + do { + uint16 *logicList = (uint16 *)_skyCompact->fetchCpt(_scriptVariables[LOGIC_LIST_NO]); + + while (uint16 id = *logicList++) { // 0 means end of list + if (id == 0xffff) { + // Change logic data address + logicList = (uint16 *)_skyCompact->fetchCpt(*logicList); + continue; + } - _scriptVariables[CUR_ID] = id; - _compact = _skyCompact->fetchCpt(id); + _scriptVariables[CUR_ID] = id; + _compact = _skyCompact->fetchCpt(id); - // check the id actually wishes to be processed - if (!(_compact->status & (1 << 6))) - continue; + // check the id actually wishes to be processed + if (!(_compact->status & (1 << 6))) + continue; - // ok, here we process the logic bit system + // ok, here we process the logic bit system - if (_compact->status & (1 << 7)) - _skyGrid->removeObjectFromWalk(_compact); + if (_compact->status & (1 << 7)) + _skyGrid->removeObjectFromWalk(_compact); - Debug::logic(_compact->logic); - (this->*logicTable[_compact->logic]) (); + Debug::logic(_compact->logic); + (this->*_logicTable[_compact->logic]) (); - if (_compact->status & (1 << 7)) - _skyGrid->objectToWalk(_compact); + if (_compact->status & (1 << 7)) + _skyGrid->objectToWalk(_compact); - // a sync sent to the compact is available for one cycle - // only. that cycle has just ended so remove the sync. - // presumably the mega has just reacted to it. - _compact->sync = 0; - if (id == ID_STD_MENU_LOGIC) - printf("\n\n\n"); - } + // a sync sent to the compact is available for one cycle + // only. that cycle has just ended so remove the sync. + // presumably the mega has just reacted to it. + _compact->sync = 0; + } + // usually this loop is run only once, it'll only be run a second time if the game + // script just asked the user to enter a copy protection code. + // this is done to prevent the copy protection screen from flashing up. + // (otherwise it would be visible for 1/50 second) + } while (checkProtection()); } void Logic::nop() {} @@ -808,8 +820,7 @@ uint32 Logic::pop() { return _stack[--_stackPtr]; } -typedef bool (Logic::*McodeTable) (uint32, uint32, uint32); -static McodeTable mcodeTable[] = { +const McodeTable Logic::_mcodeTable[] = { &Logic::fnCacheChip, &Logic::fnCacheFast, &Logic::fnDrawScreen, @@ -1121,7 +1132,7 @@ static const uint32 forwardList5b[] = { }; void Logic::fnExec(uint16 num, uint32 a, uint32 b, uint32 c) { - (this->*mcodeTable[num])(a, b, c); + (this->*_mcodeTable[num])(a, b, c); } void Logic::initScriptVariables() { @@ -1296,7 +1307,7 @@ script: Debug::mcode(mcode, a, b, c); Compact *saveCpt = _compact; - bool ret = (this->*mcodeTable[mcode]) (a, b, c); + bool ret = (this->*_mcodeTable[mcode]) (a, b, c); _compact = saveCpt; if (!ret) diff --git a/sky/logic.h b/sky/logic.h index 269c634eec..13677fb41f 100644 --- a/sky/logic.h +++ b/sky/logic.h @@ -112,6 +112,8 @@ enum scriptVariableOffsets { SC40_LOCKER_5_FLAG = 821 }; +#define NUM_SKY_SCRIPTVARS 838 + class AutoRoute; class Control; class Disk; @@ -123,6 +125,11 @@ class Sound; class Text; class SkyCompact; +class Logic; + +typedef void (Logic::*LogicTable) (); +typedef bool (Logic::*McodeTable) (uint32, uint32, uint32); + class Logic { public: Logic( @@ -134,9 +141,29 @@ public: Mouse *skyMouse, Sound *skySound); void engine(); - bool checkProtection(void); void useControlInstance(Control *control) { _skyControl = control; }; + uint16 mouseScript(uint32 scrNum, Compact *scriptComp); + + static uint32 _scriptVariables[NUM_SKY_SCRIPTVARS]; + Grid *_skyGrid; + + uint16 script(uint16 scriptNo, uint16 offset); + void initScreen0(void); + void parseSaveData(uint32 *data); + +protected: + void push(uint32); + uint32 pop(); + void checkModuleLoaded(uint16 moduleNo); + bool collide(Compact *cpt); + void initScriptVariables(); + void mainAnim(); + void runGetOff(); + void stopAndWait(); + bool checkProtection(void); + + static const LogicTable _logicTable[]; void nop(); void logicScript(); void autoRoute(); @@ -154,9 +181,8 @@ public: void pause(); void waitSync(); void simpleAnim(); - uint16 mouseScript(uint32 scrNum, Compact *scriptComp); - uint16 script(uint16 scriptNo, uint16 offset); + static const McodeTable _mcodeTable[]; bool fnCacheChip(uint32 a, uint32 b, uint32 c); bool fnCacheFast(uint32 a, uint32 b, uint32 c); bool fnDrawScreen(uint32 a, uint32 b, uint32 c); @@ -275,19 +301,6 @@ public: void stdSpeak(Compact *target, uint32 textNum, uint32 animNum, uint32 base); void fnExec(uint16 num, uint32 a, uint32 b, uint32 c); - - static uint32 _scriptVariables[838]; - Grid *_skyGrid; - -protected: - void push(uint32); - uint32 pop(); - void checkModuleLoaded(uint16 moduleNo); - bool collide(Compact *cpt); - void initScriptVariables(); - void mainAnim(); - void runGetOff(); - void stopAndWait(); uint16 *_moduleList[16]; uint32 _stack[20]; @@ -310,6 +323,8 @@ protected: AutoRoute *_skyAutoRoute; Mouse *_skyMouse; Control *_skyControl; + + friend class Debugger; }; } // End of namespace Sky diff --git a/sky/mouse.cpp b/sky/mouse.cpp index cd5bb6a58f..505a80cf4a 100644 --- a/sky/mouse.cpp +++ b/sky/mouse.cpp @@ -221,10 +221,8 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) { while ((*currentList != 0) && (*currentList != 0xFFFF)) { uint16 itemNum = *currentList; Compact *itemData = _skyCompact->fetchCpt(itemNum); - if (itemNum == 0x2E) - printf("menu\n"); currentList++; - if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) { + if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) { if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos) continue; if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos) continue; if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos) continue; diff --git a/sky/sky.cpp b/sky/sky.cpp index 88159220f1..e87b0634d1 100644 --- a/sky/sky.cpp +++ b/sky/sky.cpp @@ -75,8 +75,6 @@ extern bool draw_keyboard; With apologies to the CD32 SteelSky file. */ -#undef WITH_DEBUG_CHEATS - static const GameSettings skySetting = {"sky", "Beneath a Steel Sky", 0 }; @@ -141,57 +139,43 @@ void SkyEngine::initVirgin() { _skyScreen->showScreen(60110); } -void SkyEngine::doCheat(uint8 num) { +void SkyEngine::handleKey(void) { - switch(num) { - case 1: warning("executed cheat: get jammer"); - Logic::_scriptVariables[GOT_JAMMER] = 42; - Logic::_scriptVariables[GOT_SPONSOR] = 69; - break; - case 2: warning("executed cheat: computer room"); - Logic::_scriptVariables[CARD_STATUS] = 2; - Logic::_scriptVariables[CARD_FIX] = 1; - break; - case 3: warning("executed cheat: get to burke"); - Logic::_scriptVariables[KNOWS_PORT] = 42; - break; - case 4: warning("executed cheat: get to reactor section"); - Logic::_scriptVariables[FOREMAN_FRIEND] = 42; - _skyLogic->fnSendSync(8484, 1, 0); // send sync to RAD suit (put in locker) - _skyLogic->fnKillId(ID_ANITA_SPY, 0, 0); // stop anita from getting to you - break; - default: warning("unknown cheat: %d", num); - break; - } -} + if (_keyFlags == OSystem::KBD_CTRL) { + if (_keyPressed == 'f') + _fastMode ^= 1; + else if (_keyPressed == 'g') + _fastMode ^= 2; + else if (_keyPressed == 'd') + _debugger->attach(); + } else { + if (_keyPressed == '`' || _keyPressed == '~' || _keyPressed == '#') + _debugger->attach(); + + if (_keyPressed == 63) + _skyControl->doControlPanel(); -void SkyEngine::handleKey(void) { + if ((_keyPressed == 27) && (!_systemVars.pastIntro)) + _skyControl->restartGame(); - if (_key_pressed == '`' || _key_pressed == '~' || _key_pressed == '#') { - _debugger->attach(); + if (_keyPressed == '.') + _skyMouse->logicClick(); } - - if (_key_pressed == 63) - _skyControl->doControlPanel(); - - if ((_key_pressed == 27) && (!_systemVars.pastIntro)) - _skyControl->restartGame(); -#ifdef WITH_DEBUG_CHEATS - if ((_key_pressed >= '0') && (_key_pressed <= '9')) - doCheat(_key_pressed - '0'); -#endif - if (_key_pressed == '.') - _skyMouse->logicClick(); - _key_pressed = 0; + _keyFlags = _keyPressed = 0; } int SkyEngine::go() { - _sdl_mouse_x = GAME_SCREEN_WIDTH / 2; - _sdl_mouse_y = GAME_SCREEN_HEIGHT / 2; - - bool introSkipped = false; - if (!_quickLaunch) { + _mouseX = GAME_SCREEN_WIDTH / 2; + _mouseY = GAME_SCREEN_HEIGHT / 2; + _keyFlags = _keyPressed = 0; + + uint16 result = 0; + if (ConfMan.hasKey("save_slot") && ConfMan.getInt("save_slot") >= 0) + result = _skyControl->quickXRestore(ConfMan.getInt("save_slot")); + + if (result != GAME_RESTORED) { + bool introSkipped = false; if (_systemVars.gameVersion > 267) {// don't do intro for floppydemos _skyIntro = new Intro(_skyDisk, _skyScreen, _skyMusic, _skySound, _skyText, _mixer, _system); introSkipped = !_skyIntro->doIntro(_floppyIntro); @@ -201,25 +185,20 @@ int SkyEngine::go() { } delete _skyIntro; } - loadBase0(); - } - if (introSkipped) - _skyControl->restartGame(); + _skyLogic->initScreen0(); + + if (introSkipped) + _skyControl->restartGame(); + } _lastSaveTime = _system->getMillis(); while (1) { - if (_debugger->isAttached()) { + if (_debugger->isAttached()) _debugger->onFrame(); - } - - if (_fastMode & 2) - delay(0); - else if (_fastMode & 1) - delay(10); - else - delay(_systemVars.gameSpeed); + + int32 frameTime = (int32)_system->getMillis(); if (_system->getMillis() - _lastSaveTime > 5 * 60 * 1000) { if (_skyControl->loadSaveAllowed()) { @@ -229,19 +208,23 @@ int SkyEngine::go() { _lastSaveTime += 30 * 1000; // try again in 30 secs } _skySound->checkFxQueue(); - _skyMouse->mouseEngine((uint16)_sdl_mouse_x, (uint16)_sdl_mouse_y); - if (_key_pressed) - handleKey(); + _skyMouse->mouseEngine((uint16)_mouseX, (uint16)_mouseY); + handleKey(); _skyLogic->engine(); - if (!_skyLogic->checkProtection()) { // don't let copy prot. screen flash up - _skyScreen->recreate(); - _skyScreen->spriteEngine(); - if (_debugger->showGrid()) { - _skyScreen->showGrid(_skyLogic->_skyGrid->giveGrid(Logic::_scriptVariables[SCREEN])); - _skyScreen->forceRefresh(); - } - _skyScreen->flip(); + _skyScreen->recreate(); + _skyScreen->spriteEngine(); + if (_debugger->showGrid()) { + _skyScreen->showGrid(_skyLogic->_skyGrid->giveGrid(Logic::_scriptVariables[SCREEN])); + _skyScreen->forceRefresh(); } + _skyScreen->flip(); + + if (_fastMode & 2) + delay(0); + else if (_fastMode & 1) + delay(10); + else + delay((frameTime + _systemVars.gameSpeed) - _system->getMillis()); } return 0; @@ -351,19 +334,9 @@ int SkyEngine::init(GameDetector &detector) { } } - uint16 result = 0; - if (ConfMan.hasKey("save_slot") && ConfMan.getInt("save_slot") >= 0) - result = _skyControl->quickXRestore(ConfMan.getInt("save_slot")); - - if (result == GAME_RESTORED) - _quickLaunch = true; - else - _quickLaunch = false; - _skyMusic->setVolume(ConfMan.getInt("music_volume") >> 1); _debugger = new Debugger(_skyLogic, _skyMouse, _skyScreen, _skyCompact); - return 0; } @@ -391,13 +364,6 @@ void SkyEngine::initItemList() { }*/ } -void SkyEngine::loadBase0(void) { - - _skyLogic->fnEnterSection(0, 0, 0); - _skyMusic->startMusic(2); - _systemVars.currentMusic = 2; -} - void SkyEngine::loadFixedItems(void) { _itemList[49] = _skyDisk->loadFile(49); @@ -433,42 +399,27 @@ void SkyEngine::gotTimerTick(void) { _skyScreen->handleTimer(); } -void SkyEngine::delay(uint amount) { +void SkyEngine::delay(int32 amount) { OSystem::Event event; uint32 start = _system->getMillis(); - uint32 cur = start; - _key_pressed = 0; //reset + _keyFlags = _keyPressed = 0; //reset + + if (amount < 0) + amount = 0; do { while (_system->pollEvent(event)) { switch (event.type) { case OSystem::EVENT_KEYDOWN: - if (event.kbd.flags == OSystem::KBD_CTRL) { - if (event.kbd.keycode == 'f') { - _fastMode ^= 1; - break; - } - if (event.kbd.keycode == 'g') { - _fastMode ^= 2; - break; - } - if (event.kbd.keycode == 'd') { - _debugger->attach(); - } - } - - // Make sure backspace works right (this fixes a small issue on OS X) - if (event.kbd.keycode == 8) - _key_pressed = 8; - else - _key_pressed = (byte)event.kbd.ascii; + _keyFlags = event.kbd.flags; + _keyPressed = (byte)event.kbd.ascii; break; case OSystem::EVENT_MOUSEMOVE: if (!(_systemVars.systemFlags & SF_MOUSE_LOCKED)) { - _sdl_mouse_x = event.mouse.x; - _sdl_mouse_y = event.mouse.y; + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; } break; case OSystem::EVENT_LBUTTONDOWN: @@ -485,21 +436,10 @@ void SkyEngine::delay(uint amount) { break; } } + if (amount > 0) + _system->delayMillis((amount > 10) ? 10 : amount); - if (amount == 0) - break; - - { - uint this_delay = 20; -#ifdef _WIN32_WCE - this_delay = 10; -#endif - if (this_delay > amount) - this_delay = amount; - _system->delayMillis(this_delay); - } - cur = _system->getMillis(); - } while (cur < start + amount); + } while (_system->getMillis() < start + amount); } bool SkyEngine::isDemo(void) { @@ -57,11 +57,10 @@ class SkyCompact; class SkyEngine : public Engine { void errorString(const char *buf_input, char *buf_output); protected: - byte _key_pressed; - bool _quickLaunch; // set when starting with -x + byte _keyPressed, _keyFlags; bool _floppyIntro; - int _sdl_mouse_x, _sdl_mouse_y; + int _mouseX, _mouseY; Sound *_skySound; Disk *_skyDisk; @@ -91,15 +90,12 @@ public: protected: byte _fastMode; - void logic_engine(); - void delay(uint amount); + void delay(int32 amount); int go(); - void doCheat(uint8 num); void handleKey(void); uint32 _lastSaveTime; - Text *getText(); int init(GameDetector &detector); void initItemList(); @@ -107,9 +103,6 @@ protected: static void timerHandler(void *ptr); void gotTimerTick(); void loadFixedItems(); - void loadBase0(); - - static int CDECL game_thread_proc(void *param); }; } // End of namespace Sky |