aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sky/compact.cpp2
-rw-r--r--sky/control.cpp11
-rw-r--r--sky/logic.cpp103
-rw-r--r--sky/logic.h47
-rw-r--r--sky/mouse.cpp4
-rw-r--r--sky/sky.cpp188
-rw-r--r--sky/sky.h13
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) {
diff --git a/sky/sky.h b/sky/sky.h
index be0f7fa50d..06657df83f 100644
--- a/sky/sky.h
+++ b/sky/sky.h
@@ -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