aboutsummaryrefslogtreecommitdiff
path: root/sky/control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sky/control.cpp')
-rw-r--r--sky/control.cpp472
1 files changed, 141 insertions, 331 deletions
diff --git a/sky/control.cpp b/sky/control.cpp
index 6789afca68..cb87f5c8da 100644
--- a/sky/control.cpp
+++ b/sky/control.cpp
@@ -36,6 +36,7 @@
#include "sky/sound.h"
#include "sky/struc.h"
#include "sky/text.h"
+#include "sky/compact.h"
namespace Sky {
@@ -191,7 +192,7 @@ void ControlStatus::drawToScreen(void) {
_statusText->drawToScreen(WITH_MASK);
}
-Control::Control(SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, OSystem *system) {
+Control::Control(SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system) {
_saveFileMan = saveFileMan;
_skyScreen = screen;
@@ -201,8 +202,8 @@ Control::Control(SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse
_skyMusic = music;
_skyLogic = logic;
_skySound = sound;
+ _skyCompact = skyCompact;
_system = system;
- _memListRoot = NULL;
}
ConResource *Control::createResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, int16 pX, int16 pY, uint32 pText, uint8 pOnClick, uint8 panelType) {
@@ -434,7 +435,7 @@ void Control::doLoadSavePanel(void) {
_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
_system->updateScreen();
_skyScreen->forceRefresh();
- _skyScreen->setPaletteEndian((uint8 *)SkyEngine::fetchCompact(SkyEngine::_systemVars.currentPalette));
+ _skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars.currentPalette));
removePanel();
_skyMouse->spriteMouse(_savedMouse, 0, 0);
_skyText->fnSetFont(_savedCharSet);
@@ -500,7 +501,7 @@ void Control::doControlPanel(void) {
_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
_system->updateScreen();
_skyScreen->forceRefresh();
- _skyScreen->setPaletteEndian((uint8 *)SkyEngine::fetchCompact(SkyEngine::_systemVars.currentPalette));
+ _skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars.currentPalette));
removePanel();
_skyMouse->spriteMouse(_savedMouse, 0, 0);
_skyText->fnSetFont(_savedCharSet);
@@ -1118,7 +1119,6 @@ void Control::doAutoSave(void) {
}
uint16 Control::saveGameToFile(void) {
-
char fName[20];
sprintf(fName,"SKY-VM.%03d", _selectedGame);
@@ -1144,125 +1144,14 @@ uint16 Control::saveGameToFile(void) {
#define STOSD(ptr, val) { *(uint32 *)(ptr) = TO_LE_32(val); (ptr) += 4; }
#define STOSW(ptr, val) { *(uint16 *)(ptr) = TO_LE_16(val); (ptr) += 2; }
-void Control::stosMegaSet(uint8 **destPos, MegaSet *mega) {
- STOSW(*destPos, mega->gridWidth);
- STOSW(*destPos, mega->colOffset);
- STOSW(*destPos, mega->colWidth);
- STOSW(*destPos, mega->lastChr);
- // anims, stands, turnTable
-}
-
-void Control::stosStr(uint8 **destPos, Compact *cpt, uint16 type) {
- uint16 strLen = 0;
- if (type & SAVE_GRAFX) {
- STOSW(*destPos, cpt->grafixProg.ptrType);
- STOSW(*destPos, cpt->grafixProg.ptrTarget);
- STOSW(*destPos, cpt->grafixProg.pos);
- }
-
- if (type & SAVE_TURNP) {
- uint16 *src = cpt->extCompact->turnProg;
- while (src[strLen])
- strLen++;
- strLen++;
- STOSW(*destPos, strLen);
- for (uint16 cnt = 0; cnt < strLen; cnt++) {
- STOSW(*destPos, src[cnt]);
- }
- }
-}
-
-void Control::stosCompact(uint8 **destPos, Compact *cpt) {
- uint16 saveType = 0;
- if (cpt->extCompact) {
- saveType |= SAVE_EXT;
- if (cpt->extCompact->megaSet0) saveType |= SAVE_MEGA0;
- if (cpt->extCompact->megaSet1) saveType |= SAVE_MEGA1;
- if (cpt->extCompact->megaSet2) saveType |= SAVE_MEGA2;
- if (cpt->extCompact->megaSet3) saveType |= SAVE_MEGA3;
- if (cpt->extCompact->turnProg) saveType |= SAVE_TURNP;
- }
- if (cpt->grafixProg.ptrType != PTR_NULL)
- saveType |= SAVE_GRAFX;
-
- STOSW(*destPos, saveType);
-
- stosStr(destPos, cpt, saveType);
-
- STOSW(*destPos, cpt->logic);
- STOSW(*destPos, cpt->status);
- STOSW(*destPos, cpt->sync);
- STOSW(*destPos, cpt->screen);
- STOSW(*destPos, cpt->place);
- // getToTable
- STOSW(*destPos, cpt->xcood);
- STOSW(*destPos, cpt->ycood);
- STOSW(*destPos, cpt->frame);
- STOSW(*destPos, cpt->cursorText);
- STOSW(*destPos, cpt->mouseOn);
- STOSW(*destPos, cpt->mouseOff);
- STOSW(*destPos, cpt->mouseClick);
- STOSW(*destPos, cpt->mouseRelX);
- STOSW(*destPos, cpt->mouseRelY);
- STOSW(*destPos, cpt->mouseSizeX);
- STOSW(*destPos, cpt->mouseSizeY);
- STOSW(*destPos, cpt->actionScript);
- STOSW(*destPos, cpt->upFlag);
- STOSW(*destPos, cpt->downFlag);
- STOSW(*destPos, cpt->getToFlag);
- STOSW(*destPos, cpt->flag);
- STOSW(*destPos, cpt->mood);
- // grafixProg
- STOSW(*destPos, cpt->offset);
- STOSW(*destPos, cpt->mode);
- STOSW(*destPos, cpt->baseSub);
- STOSW(*destPos, cpt->baseSub_off);
- if (cpt->extCompact) {
- STOSW(*destPos, cpt->extCompact->actionSub);
- STOSW(*destPos, cpt->extCompact->actionSub_off);
- STOSW(*destPos, cpt->extCompact->getToSub);
- STOSW(*destPos, cpt->extCompact->getToSub_off);
- STOSW(*destPos, cpt->extCompact->extraSub);
- STOSW(*destPos, cpt->extCompact->extraSub_off);
- STOSW(*destPos, cpt->extCompact->dir);
- STOSW(*destPos, cpt->extCompact->stopScript);
- STOSW(*destPos, cpt->extCompact->miniBump);
- STOSW(*destPos, cpt->extCompact->leaving);
- STOSW(*destPos, cpt->extCompact->atWatch);
- STOSW(*destPos, cpt->extCompact->atWas);
- STOSW(*destPos, cpt->extCompact->alt);
- STOSW(*destPos, cpt->extCompact->request);
- STOSW(*destPos, cpt->extCompact->spWidth_xx);
- STOSW(*destPos, cpt->extCompact->spColour);
- STOSW(*destPos, cpt->extCompact->spTextId);
- STOSW(*destPos, cpt->extCompact->spTime);
- STOSW(*destPos, cpt->extCompact->arAnimIndex);
- // turnProg
- STOSW(*destPos, cpt->extCompact->waitingFor);
- STOSW(*destPos, cpt->extCompact->arTargetX);
- STOSW(*destPos, cpt->extCompact->arTargetY);
- // animScratch
- STOSW(*destPos, cpt->extCompact->megaSet);
-
- if (cpt->extCompact->megaSet0)
- stosMegaSet(destPos, cpt->extCompact->megaSet0);
- if (cpt->extCompact->megaSet1)
- stosMegaSet(destPos, cpt->extCompact->megaSet1);
- if (cpt->extCompact->megaSet2)
- stosMegaSet(destPos, cpt->extCompact->megaSet2);
- if (cpt->extCompact->megaSet3)
- stosMegaSet(destPos, cpt->extCompact->megaSet3);
- }
-}
-
uint32 Control::prepareSaveData(uint8 *destBuf) {
uint32 cnt;
memset(destBuf, 0, 4); // space for data size
uint8 *destPos = destBuf + 4;
STOSD(destPos, SAVE_FILE_REVISION);
-
STOSD(destPos, SkyEngine::_systemVars.gameVersion);
+
STOSW(destPos, _skySound->_saveSounds[0]);
STOSW(destPos, _skySound->_saveSounds[1]);
@@ -1277,19 +1166,12 @@ uint32 Control::prepareSaveData(uint8 *destBuf) {
for (cnt = 0; cnt < 60; cnt++)
STOSD(destPos, loadedFilesList[cnt]);
- for (cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
- stosCompact(&destPos, _saveLoadCpts[cnt]);
-
- for (cnt = 0; cnt < ARRAYSIZE(_saveLoadARs); cnt++)
- for (uint8 elemCnt = 0; elemCnt < 32; elemCnt++) {
- STOSW(destPos, _saveLoadARs[cnt][elemCnt]);
- }
-
- for (cnt = 0; cnt < 3; cnt++)
- STOSW(destPos, SkyCompact::park_table[cnt]);
-
- for (cnt = 0; cnt < 13; cnt++)
- STOSW(destPos, SkyCompact::high_floor_table[cnt]);
+ for (cnt = 0; cnt < _skyCompact->_numSaveIds; cnt++) {
+ uint16 numElems;
+ uint16 *rawCpt = (uint16*)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, NULL, NULL);
+ for (uint16 cnt = 0; cnt < numElems; cnt++)
+ STOSW(destPos, rawCpt[cnt]);
+ }
*(uint32 *)destBuf = TO_LE_32(destPos - destBuf); // save size
return destPos - destBuf;
@@ -1298,163 +1180,143 @@ uint32 Control::prepareSaveData(uint8 *destBuf) {
#undef STOSD
#undef STOSW
-void Control::appendMemList(uint16 *pMem) {
- AllocedMem *newMem = new AllocedMem;
- newMem->mem = pMem;
- newMem->next = _memListRoot;
- _memListRoot = newMem;
-}
-
-void Control::freeMemList(void) {
- AllocedMem *block = _memListRoot;
- AllocedMem *temp;
- while (block) {
- temp = block;
- free(block->mem);
- block = block->next;
- delete temp;
- }
- _memListRoot = NULL;
-}
-
-
#define LODSD(strPtr, val) { val = READ_LE_UINT32(strPtr); (strPtr) += 4; }
#define LODSW(strPtr, val) { val = READ_LE_UINT16(strPtr); (strPtr) += 2; }
-void Control::lodsMegaSet(uint8 **srcPos, MegaSet *mega) {
+void Control::importOldMegaSet(uint8 **srcPos, MegaSet *mega) {
LODSW(*srcPos, mega->gridWidth);
LODSW(*srcPos, mega->colOffset);
LODSW(*srcPos, mega->colWidth);
LODSW(*srcPos, mega->lastChr);
- // anims, stands, turnTable
}
-void Control::lodsCompact(uint8 **srcPos, Compact *cpt) {
-
- uint16 saveType, cnt;
+void Control::importOldCompact(Compact* destCpt, uint8 **srcPos, uint16 numElems, uint16 type, char *name) {
+ uint16 saveType;
LODSW(*srcPos, saveType);
- if ((saveType & (SAVE_EXT | SAVE_TURNP)) && (cpt->extCompact == NULL))
- error("Can't restore! SaveData is SAVE_EXT for Compact");
- if ((saveType & SAVE_MEGA0) && (cpt->extCompact->megaSet0 == NULL))
- error("Can't restore! SaveData is SAVE_MEGA0 for Compact");
- if ((saveType & SAVE_MEGA1) && (cpt->extCompact->megaSet1 == NULL))
- error("Can't restore! SaveData is SAVE_MEGA1 for Compact");
- if ((saveType & SAVE_MEGA2) && (cpt->extCompact->megaSet2 == NULL))
- error("Can't restore! SaveData is SAVE_MEGA2 for Compact");
- if ((saveType & SAVE_MEGA3) && (cpt->extCompact->megaSet3 == NULL))
- error("Can't restore! SaveData is SAVE_MEGA3 for Compact");
-
+ if ((saveType & (SAVE_EXT | SAVE_TURNP)) && (numElems < 54))
+ error("Cpt %s: Savedata doesn't match cpt size (%d)!\n", name, numElems);
+ if ((saveType & SAVE_MEGA0) && (numElems < 54 + 13))
+ error("Cpt %s: Savedata doesn't match cpt size (%d)!\n", name, numElems);
+ if ((saveType & SAVE_MEGA1) && (numElems < 54 + 13 + 13))
+ error("Cpt %s: Savedata doesn't match cpt size (%d)!\n", name, numElems);
+ if ((saveType & SAVE_MEGA2) && (numElems < 54 + 13 + 13 + 13))
+ error("Cpt %s: Savedata doesn't match cpt size (%d)!\n", name, numElems);
+ if ((saveType & SAVE_MEGA3) && (numElems < 54 + 13 + 13 + 13))
+ error("Cpt %s: Savedata doesn't match cpt size (%d)!\n", name, numElems);
if (saveType & SAVE_GRAFX) {
- uint16 tmp;
- LODSW(*srcPos, tmp);
- cpt->grafixProg.ptrType = (uint8)tmp;
- LODSW(*srcPos, cpt->grafixProg.ptrTarget);
- LODSW(*srcPos, cpt->grafixProg.pos);
- } else {
- cpt->grafixProg.ptrType = PTR_NULL;
- cpt->grafixProg.ptrTarget = 0;
- cpt->grafixProg.pos = 0;
+ uint16 type, target, pos;
+ LODSW(*srcPos, type);
+ LODSW(*srcPos, target);
+ LODSW(*srcPos, pos);
+ // convert to new compact system..
+ destCpt->grafixProgPos = pos;
+ if (type == OG_PTR_NULL)
+ destCpt->grafixProgId = 0;
+ else if (type == OG_AUTOROUTE)
+ destCpt->grafixProgId = destCpt->animScratchId;
+ else if (type == OG_COMPACT)
+ destCpt->grafixProgId = target;
+ else if (type == OG_TALKTABLE)
+ destCpt->grafixProgId = TALKTABLE_LIST_ID | target;
+ else if (type == OG_COMPACTELEM)
+ destCpt->grafixProgId = *(uint16*)_skyCompact->getCompactElem(destCpt, target);
+ else
+ error("Illegal GrafixProg type encountered for compact %s", name);
}
-
if (saveType & SAVE_TURNP) {
- uint16 turnLen;
- LODSW(*srcPos, turnLen);
- cpt->extCompact->turnProg = (uint16 *)malloc(turnLen << 1);
- appendMemList(cpt->extCompact->turnProg);
- for (cnt = 0; cnt < turnLen; cnt++)
- LODSW(*srcPos, cpt->extCompact->turnProg[cnt]);
- } else if (cpt->extCompact)
- cpt->extCompact->turnProg = NULL;
-
- LODSW(*srcPos, cpt->logic);
- LODSW(*srcPos, cpt->status);
- LODSW(*srcPos, cpt->sync);
- LODSW(*srcPos, cpt->screen);
- LODSW(*srcPos, cpt->place);
+ // basically impossible to import these. simply set it to end-of-turn and hope the script
+ // will take care of it.
+ destCpt->turnProgId = 0x13B;
+ destCpt->turnProgPos = 1;
+ uint16 turnSkipLen;
+ LODSW(*srcPos, turnSkipLen);
+ *srcPos += 2 * turnSkipLen;
+ } else if (numElems >= 49) {
+ destCpt->turnProgId = 0;
+ destCpt->turnProgPos = 0;
+ }
+ LODSW(*srcPos, destCpt->logic);
+ LODSW(*srcPos, destCpt->status);
+ LODSW(*srcPos, destCpt->sync);
+ LODSW(*srcPos, destCpt->screen);
+ LODSW(*srcPos, destCpt->place);
// getToTable
- LODSW(*srcPos, cpt->xcood);
- LODSW(*srcPos, cpt->ycood);
- LODSW(*srcPos, cpt->frame);
- LODSW(*srcPos, cpt->cursorText);
- LODSW(*srcPos, cpt->mouseOn);
- LODSW(*srcPos, cpt->mouseOff);
- LODSW(*srcPos, cpt->mouseClick);
- LODSW(*srcPos, cpt->mouseRelX);
- LODSW(*srcPos, cpt->mouseRelY);
- LODSW(*srcPos, cpt->mouseSizeX);
- LODSW(*srcPos, cpt->mouseSizeY);
- LODSW(*srcPos, cpt->actionScript);
- LODSW(*srcPos, cpt->upFlag);
- LODSW(*srcPos, cpt->downFlag);
- LODSW(*srcPos, cpt->getToFlag);
- LODSW(*srcPos, cpt->flag);
- LODSW(*srcPos, cpt->mood);
+ LODSW(*srcPos, destCpt->xcood);
+ LODSW(*srcPos, destCpt->ycood);
+ LODSW(*srcPos, destCpt->frame);
+ LODSW(*srcPos, destCpt->cursorText);
+ LODSW(*srcPos, destCpt->mouseOn);
+ LODSW(*srcPos, destCpt->mouseOff);
+ LODSW(*srcPos, destCpt->mouseClick);
+ LODSW(*srcPos, destCpt->mouseRelX);
+ LODSW(*srcPos, destCpt->mouseRelY);
+ LODSW(*srcPos, destCpt->mouseSizeX);
+ LODSW(*srcPos, destCpt->mouseSizeY);
+ LODSW(*srcPos, destCpt->actionScript);
+ LODSW(*srcPos, destCpt->upFlag);
+ LODSW(*srcPos, destCpt->downFlag);
+ LODSW(*srcPos, destCpt->getToFlag);
+ LODSW(*srcPos, destCpt->flag);
+ LODSW(*srcPos, destCpt->mood);
// grafixProg
- LODSW(*srcPos, cpt->offset);
- LODSW(*srcPos, cpt->mode);
- LODSW(*srcPos, cpt->baseSub);
- LODSW(*srcPos, cpt->baseSub_off);
+ LODSW(*srcPos, destCpt->offset);
+ LODSW(*srcPos, destCpt->mode);
+ LODSW(*srcPos, destCpt->baseSub);
+ LODSW(*srcPos, destCpt->baseSub_off);
if (saveType & SAVE_EXT) {
- LODSW(*srcPos, cpt->extCompact->actionSub);
- LODSW(*srcPos, cpt->extCompact->actionSub_off);
- LODSW(*srcPos, cpt->extCompact->getToSub);
- LODSW(*srcPos, cpt->extCompact->getToSub_off);
- LODSW(*srcPos, cpt->extCompact->extraSub);
- LODSW(*srcPos, cpt->extCompact->extraSub_off);
- LODSW(*srcPos, cpt->extCompact->dir);
- LODSW(*srcPos, cpt->extCompact->stopScript);
- LODSW(*srcPos, cpt->extCompact->miniBump);
- LODSW(*srcPos, cpt->extCompact->leaving);
- LODSW(*srcPos, cpt->extCompact->atWatch);
- LODSW(*srcPos, cpt->extCompact->atWas);
- LODSW(*srcPos, cpt->extCompact->alt);
- LODSW(*srcPos, cpt->extCompact->request);
- LODSW(*srcPos, cpt->extCompact->spWidth_xx);
- LODSW(*srcPos, cpt->extCompact->spColour);
- LODSW(*srcPos, cpt->extCompact->spTextId);
- LODSW(*srcPos, cpt->extCompact->spTime);
- LODSW(*srcPos, cpt->extCompact->arAnimIndex);
+ LODSW(*srcPos, destCpt->actionSub);
+ LODSW(*srcPos, destCpt->actionSub_off);
+ LODSW(*srcPos, destCpt->getToSub);
+ LODSW(*srcPos, destCpt->getToSub_off);
+ LODSW(*srcPos, destCpt->extraSub);
+ LODSW(*srcPos, destCpt->extraSub_off);
+ LODSW(*srcPos, destCpt->dir);
+ LODSW(*srcPos, destCpt->stopScript);
+ LODSW(*srcPos, destCpt->miniBump);
+ LODSW(*srcPos, destCpt->leaving);
+ LODSW(*srcPos, destCpt->atWatch);
+ LODSW(*srcPos, destCpt->atWas);
+ LODSW(*srcPos, destCpt->alt);
+ LODSW(*srcPos, destCpt->request);
+ LODSW(*srcPos, destCpt->spWidth_xx);
+ LODSW(*srcPos, destCpt->spColour);
+ LODSW(*srcPos, destCpt->spTextId);
+ LODSW(*srcPos, destCpt->spTime);
+ LODSW(*srcPos, destCpt->arAnimIndex);
// turnProg
- LODSW(*srcPos, cpt->extCompact->waitingFor);
- LODSW(*srcPos, cpt->extCompact->arTargetX);
- LODSW(*srcPos, cpt->extCompact->arTargetY);
+ LODSW(*srcPos, destCpt->waitingFor);
+ LODSW(*srcPos, destCpt->arTargetX);
+ LODSW(*srcPos, destCpt->arTargetY);
// animScratch
- LODSW(*srcPos, cpt->extCompact->megaSet);
-
+ LODSW(*srcPos, destCpt->megaSet);
if (saveType & SAVE_MEGA0)
- lodsMegaSet(srcPos, cpt->extCompact->megaSet0);
+ importOldMegaSet(srcPos, &(destCpt->megaSet0));
if (saveType & SAVE_MEGA1)
- lodsMegaSet(srcPos, cpt->extCompact->megaSet1);
+ importOldMegaSet(srcPos, &(destCpt->megaSet1));
if (saveType & SAVE_MEGA2)
- lodsMegaSet(srcPos, cpt->extCompact->megaSet2);
+ importOldMegaSet(srcPos, &(destCpt->megaSet2));
if (saveType & SAVE_MEGA3)
- lodsMegaSet(srcPos, cpt->extCompact->megaSet3);
+ importOldMegaSet(srcPos, &(destCpt->megaSet3));
}
}
uint16 Control::parseSaveData(uint8 *srcBuf) {
-
uint32 reloadList[60];
uint32 oldSection = Logic::_scriptVariables[CUR_SECTION];
-
uint32 cnt;
uint8 *srcPos = srcBuf;
uint32 size;
uint32 saveRev;
-
+ uint32 gameVersion;
LODSD(srcPos, size);
LODSD(srcPos, saveRev);
if (saveRev > SAVE_FILE_REVISION) {
displayMessage(0, "Unknown save file revision (%d)", saveRev);
return RESTORE_FAILED;
- }
-
- if (saveRev <= OLD_SAVEGAME_TYPE) {
+ } else if (saveRev < OLD_SAVEGAME_TYPE) {
displayMessage(0, "This savegame version is unsupported.");
return RESTORE_FAILED;
}
- uint32 music, mouseType, palette, gameVersion;
-
LODSD(srcPos, gameVersion);
if (gameVersion != SkyEngine::_systemVars.gameVersion) {
if ((!SkyEngine::isCDVersion()) || (gameVersion < 365)) { // cd versions are compatible
@@ -1469,7 +1331,7 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
LODSW(srcPos, _skySound->_saveSounds[1]);
_skySound->restoreSfx();
- freeMemList(); // memory from last restore isn't needed anymore
+ uint32 music, mouseType, palette;
LODSD(srcPos, music);
LODSD(srcPos, _savedCharSet);
LODSD(srcPos, mouseType);
@@ -1481,19 +1343,34 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
for (cnt = 0; cnt < 60; cnt++)
LODSD(srcPos, reloadList[cnt]);
- for (cnt = 0; cnt < ARRAYSIZE(_saveLoadCpts); cnt++)
- lodsCompact(&srcPos, _saveLoadCpts[cnt]);
-
- for (cnt = 0; cnt < ARRAYSIZE(_saveLoadARs); cnt++)
- for (uint8 elemCnt = 0; elemCnt < 32; elemCnt++) {
- LODSW(srcPos, _saveLoadARs[cnt][elemCnt]);
+ if (saveRev == SAVE_FILE_REVISION) {
+ for (cnt = 0; cnt < _skyCompact->_numSaveIds; cnt++) {
+ uint16 numElems;
+ uint16 *rawCpt = (uint16*)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, NULL, NULL);
+ for (uint16 elemCnt = 0; elemCnt < numElems; elemCnt++)
+ LODSW(srcPos, rawCpt[elemCnt]);
}
-
- for (cnt = 0; cnt < 3; cnt++)
- LODSW(srcPos, SkyCompact::park_table[cnt]);
-
- for (cnt = 0; cnt < 13; cnt++)
- LODSW(srcPos, SkyCompact::high_floor_table[cnt]);
+ } else { // import old savegame revision
+ for (cnt = 0; cnt < (uint32)(_skyCompact->_numSaveIds - 2); cnt++) {
+ uint16 numElems;
+ uint16 type;
+ char name[128];
+ uint16 *rawCpt = (uint16*)_skyCompact->fetchCptInfo(_skyCompact->_saveIds[cnt], &numElems, &type, name);
+ if (type == COMPACT) {
+ importOldCompact((Compact*)rawCpt, &srcPos, numElems, type, name);
+ } else if (type == ROUTEBUF) {
+ assert(numElems == 32);
+ for (uint32 elemCnt = 0; elemCnt < numElems; elemCnt++)
+ LODSW(srcPos, rawCpt[elemCnt]);
+ }
+ }
+ uint16 *rawCpt = (uint16*)_skyCompact->fetchCpt(0xBF);
+ for (cnt = 0; cnt < 3; cnt++)
+ LODSW(srcPos, rawCpt[cnt]);
+ rawCpt = (uint16*)_skyCompact->fetchCpt(0xC2);
+ for (cnt = 0; cnt < 13; cnt++)
+ LODSW(srcPos, rawCpt[cnt]);
+ }
if (srcPos - srcBuf != (int32)size)
error("Restore failed! Savegame data = %d bytes. Expected size: %d", srcPos-srcBuf, size);
@@ -1513,11 +1390,8 @@ uint16 Control::parseSaveData(uint8 *srcBuf) {
return GAME_RESTORED;
}
-#undef LODSD
-#undef LODSW
uint16 Control::restoreGameFromFile(bool autoSave) {
-
char fName[20];
if (autoSave) {
if (SkyEngine::isCDVersion())
@@ -1581,7 +1455,7 @@ uint16 Control::quickXRestore(uint16 slot) {
memset(_skyScreen->giveCurrent(), 0, GAME_SCREEN_WIDTH * GAME_SCREEN_HEIGHT);
_skyScreen->showScreen(_skyScreen->giveCurrent());
_skyScreen->forceRefresh();
- _skyScreen->setPaletteEndian((uint8 *)SkyEngine::fetchCompact(SkyEngine::_systemVars.currentPalette));
+ _skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars.currentPalette));
} else {
memset(_screenBuf, 0, FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
@@ -1596,82 +1470,18 @@ uint16 Control::quickXRestore(uint16 slot) {
return result;
}
-uint16 *Control::lz77decode(uint16 *data) {
- uint32 size = READ_LE_UINT32(data);
- data += 2;
- uint16 *outBuf = (uint16*)malloc(size << 1);
- uint32 outPos = 0;
- uint16 lzPos;
- uint16 lzBuf[0x1000];
- memset(lzBuf + 0xF00, 0, 0x200);
- for (lzPos = 0; lzPos < 0xF00; lzPos++)
- lzBuf[lzPos] = TO_LE_16(0xF00 - lzPos);
- lzPos = 0;
- uint32 indic = 0;
- while (outPos < size) {
- if (!(indic >> 16)) {
- indic = READ_LE_UINT16(data) | 0xFFFF0000;
- data++;
- }
- if (indic & 1) {
- lzBuf[lzPos] = outBuf[outPos] = *data;
- outPos++;
- lzPos = (lzPos + 1) & 0xFFF;
- } else {
- uint16 lzFrom = READ_LE_UINT16(data) >> 4;
- uint16 lzLen = (READ_LE_UINT16(data) & 0xF) + 2;
- for (uint16 cnt = 0; cnt < lzLen; cnt++)
- outBuf[outPos + cnt] = lzBuf[(lzPos + cnt) & 0xFFF] = lzBuf[(lzFrom + cnt) & 0xFFF];
-
- outPos += lzLen;
- lzPos = (lzPos + lzLen) & 0xFFF;
- }
- data++;
- indic >>= 1;
- }
- return outBuf;
-}
-
-void Control::applyDiff(uint16 *data, uint16 *diffData, uint16 len) {
- for (uint16 cnt = 0; cnt < len; cnt++) {
- data += READ_LE_UINT16(diffData);
- diffData++;
- *data = *diffData;
- diffData++;
- data++;
- }
-}
-
void Control::restartGame(void) {
if (SkyEngine::_systemVars.gameVersion <= 267)
return; // no restart for floppy demo
- uint16 *resetData = lz77decode((uint16 *)_resetData288);
- switch (SkyEngine::_systemVars.gameVersion) {
- case 303:
- applyDiff(resetData, (uint16*)_resetDiff303, 206);
- break;
- case 331:
- applyDiff(resetData, (uint16*)_resetDiff331, 206);
- break;
- case 348:
- applyDiff(resetData, (uint16*)_resetDiff348, 206);
- break;
- case 365:
- case 368:
- case 372:
- applyDiff(resetData, (uint16*)_resetDiffCd, 214);
- default:
- break;
- }
- // ok, we finally have our savedata
-
+ uint8 *resetData = _skyCompact->createResetData((uint16)SkyEngine::_systemVars.gameVersion);
parseSaveData((uint8*)resetData);
free(resetData);
_skyScreen->forceRefresh();
+
memset(_skyScreen->giveCurrent(), 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
_skyScreen->showScreen(_skyScreen->giveCurrent());
- _skyScreen->setPaletteEndian((uint8 *)SkyEngine::fetchCompact(SkyEngine::_systemVars.currentPalette));
+ _skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars.currentPalette));
_skyMouse->spriteMouse(_savedMouse, 0, 0);
SkyEngine::_systemVars.pastIntro = true;
}