aboutsummaryrefslogtreecommitdiff
path: root/sky/control.cpp
diff options
context:
space:
mode:
authorRobert Göffringmann2003-06-27 02:54:05 +0000
committerRobert Göffringmann2003-06-27 02:54:05 +0000
commit1785e0e30504f4cdaf29a31eec0f58de700ab8b1 (patch)
treed6b77da3587d8e5b1f6578c34ef470e06cef9a55 /sky/control.cpp
parentc10905b975a2bf929b1e053525907663879fdb7f (diff)
downloadscummvm-rg350-1785e0e30504f4cdaf29a31eec0f58de700ab8b1.tar.gz
scummvm-rg350-1785e0e30504f4cdaf29a31eec0f58de700ab8b1.tar.bz2
scummvm-rg350-1785e0e30504f4cdaf29a31eec0f58de700ab8b1.zip
some more loading & saving work (still unfinished)
svn-id: r8663
Diffstat (limited to 'sky/control.cpp')
-rw-r--r--sky/control.cpp312
1 files changed, 303 insertions, 9 deletions
diff --git a/sky/control.cpp b/sky/control.cpp
index 940c109987..7a2e5cc9be 100644
--- a/sky/control.cpp
+++ b/sky/control.cpp
@@ -23,6 +23,7 @@
#include "sky/skydefs.h"
#include "sky/sky.h"
#include "common/file.h"
+#include "common/gameDetector.h"
SkyConResource::SkyConResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen) {
@@ -161,6 +162,8 @@ void SkyControl::initPanel(void) {
memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
uint16 volY = (127 - _skyMusic->giveVolume()) / 4 + 59 - MPNL_Y; // volume slider's Y coordinate
+ uint16 spdY = 12 - (SkyState::_systemVars.gameSpeed / SPEED_MULTIPLY);
+ spdY += MPNL_Y + 93; // speed slider's initial position
_sprites.controlPanel = _skyDisk->loadFile(60500, NULL);
_sprites.button = _skyDisk->loadFile(60501, NULL);
@@ -176,7 +179,7 @@ void SkyControl::initPanel(void) {
//Main control panel: X Y Text OnClick
_controlPanel = createResource(_sprites.controlPanel, 1, 0, 0, 0, 0, DO_NOTHING, MAINPANEL);
_exitButton = createResource( _sprites.button, 3, 0, 16, 125, 50, EXIT, MAINPANEL);
- _slide = createResource( _sprites.slide2, 1, 0, 19, 99, 95, SPEED_SLIDE, MAINPANEL);
+ _slide = createResource( _sprites.slide2, 1, 0, 19,spdY, 95, SPEED_SLIDE, MAINPANEL);
_slide2 = createResource( _sprites.slide2, 1, 0, 19,volY, 14, MUSIC_SLIDE, MAINPANEL);
_slode = createResource( _sprites.slode2, 1, 0, 9, 49, 0, DO_NOTHING, MAINPANEL);
_restorePanButton = createResource( _sprites.button, 3, 0, 58, 19, 51, REST_GAME_PANEL, MAINPANEL);
@@ -187,7 +190,15 @@ void SkyControl::initPanel(void) {
_fxPanButton = createResource( _sprites.button, 3, 0, 58, 99, 86, TOGGLE_FX, MAINPANEL);
else
_fxPanButton = createResource( _sprites.button, 3, 2, 58, 99, 87, TOGGLE_FX, MAINPANEL);
- _musicPanButton = createResource( _sprites.button, 3, 0, 58, 119, 35, TOGGLE_MS, MAINPANEL);
+
+ if (SkyState::isCDVersion()) { // CD Version: Toggle text/speech
+ if (SkyState::_systemVars.systemFlags & SF_ALLOW_TEXT)
+ _musicPanButton = createResource( _sprites.button, 3, 2, 58, 119, 21, TOGGLE_TEXT, MAINPANEL);
+ else
+ _musicPanButton = createResource( _sprites.button, 3, 0, 58, 119, 35, TOGGLE_TEXT, MAINPANEL);
+ } else { // disk version: toggle music on/off
+ _musicPanButton = createResource( _sprites.button, 3, 0, 58, 119, 91, TOGGLE_MS, MAINPANEL);
+ }
_bodge = createResource( _sprites.musicBodge, 2, 1, 98, 115, 0, DO_NOTHING, MAINPANEL);
_yesNo = createResource( _sprites.yesNo, 1, 0, -2, 40, 0, DO_NOTHING, MAINPANEL);
@@ -287,6 +298,8 @@ void SkyControl::doControlPanel(void) {
_skyScreen->setPalette(60510);
drawMainPanel();
+
+ uint16 savedMouse = _skyMouse->giveCurrentMouseType();
_skyMouse->spriteMouse(MOUSE_NORMAL,0,0);
bool quitPanel = false;
@@ -328,6 +341,7 @@ void SkyControl::doControlPanel(void) {
_skyScreen->forceRefresh();
_skyScreen->setPalette((uint8*)SkyState::fetchCompact(SkyState::_systemVars.currentPalette));
removePanel();
+ _skyMouse->spriteMouse(savedMouse, 0, 0);
}
uint16 SkyControl::handleClick(SkyConResource *pButton) {
@@ -373,7 +387,8 @@ uint16 SkyControl::handleClick(SkyConResource *pButton) {
return shiftUp(SLOW);
case SPEED_SLIDE:
- return 0;
+ _mouseClicked = true;
+ return doSpeedSlide();
case MUSIC_SLIDE:
_mouseClicked = true;
@@ -385,6 +400,9 @@ uint16 SkyControl::handleClick(SkyConResource *pButton) {
case TOGGLE_MS:
return 0;
+ case TOGGLE_TEXT:
+ return toggleText(pButton);
+
case EXIT:
animClick(pButton);
return QUIT_PANEL;
@@ -395,6 +413,11 @@ uint16 SkyControl::handleClick(SkyConResource *pButton) {
case QUIT_TO_DOS:
animClick(pButton);
+ if (getYesNo()) {
+ showGameQuitMsg(false);
+ delay(1500);
+ _system->quit();
+ }
return 0;
default:
@@ -402,6 +425,36 @@ uint16 SkyControl::handleClick(SkyConResource *pButton) {
}
}
+bool SkyControl::getYesNo(void) {
+
+ _yesNo->drawToScreen(WITH_MASK);
+ bool retVal; bool quitPanel = false;
+ uint8 mouseType = MOUSE_NORMAL;
+ uint8 wantMouse = MOUSE_NORMAL;
+ while (!quitPanel) {
+ if (mouseType != wantMouse) {
+ mouseType = wantMouse;
+ _skyMouse->spriteMouse(mouseType, 0, 0);
+ }
+ _system->update_screen();
+ delay(50);
+ if ((_mouseY >= 83) && (_mouseY <= 110)) {
+ if ((_mouseX >= 77) && (_mouseX <= 114)) { // over 'yes'
+ wantMouse = MOUSE_CROSS;
+ if (_mouseClicked) {
+ quitPanel = true; retVal = true;
+ }
+ } else if ((_mouseX >= 156) && (_mouseX <= 193)) { // over 'no'
+ wantMouse = MOUSE_CROSS;
+ if (_mouseClicked) {
+ quitPanel = true; retVal = false;
+ }
+ } else wantMouse = MOUSE_NORMAL;
+ } else wantMouse = MOUSE_NORMAL;
+ }
+ return retVal;
+}
+
uint16 SkyControl::doMusicSlide(void) {
int ofsY = _slide2->_y - _mouseY;
@@ -428,6 +481,33 @@ uint16 SkyControl::doMusicSlide(void) {
return 0;
}
+uint16 SkyControl::doSpeedSlide(void) {
+
+ /*int ofsY = _slide->_y - _mouseY;
+ uint16 speedDelay = 12 - (_slide->_y - (MPNL_Y + 93));
+ speedDelay *= SPEED_MULTIPLY;
+ while (_mouseClicked) {
+ delay(50);
+ int newY = ofsY + _mouseY;
+ if (newY < MPNL_Y + 93) newY = MPNL_Y + 93;
+ if (newY > MPNL_Y + 104) newY = MPNL_Y + 104;
+ if (newY != _slide->_y) {
+ _slode->drawToScreen(NO_MASK);
+ _slide->setXY(_slide->_x, (uint16)newY);
+ _slide->drawToScreen(WITH_MASK);
+ _slide2->drawToScreen(WITH_MASK);
+ speedDelay = 12 - (newY - (MPNL_Y + 93));
+ speedDelay *= SPEED_MULTIPLY;
+ }
+ buttonControl(_slide);
+ _text->drawToScreen(WITH_MASK);
+ _system->update_screen();
+ }
+ SkyState::_systemVars.gameSpeed = speedDelay;
+ printf("New delay: %d\n",speedDelay);*/
+ return SPEED_CHANGED;
+}
+
uint16 SkyControl::toggleFx(SkyConResource *pButton) {
SkyState::_systemVars.systemFlags ^= SF_FX_OFF;
@@ -444,6 +524,24 @@ uint16 SkyControl::toggleFx(SkyConResource *pButton) {
return TOGGLED;
}
+uint16 SkyControl::toggleText(SkyConResource *pButton) {
+
+ SkyState::_systemVars.systemFlags ^= SF_ALLOW_SPEECH;
+ if (SkyState::_systemVars.systemFlags & SF_ALLOW_SPEECH) {
+ pButton->_curSprite = 0;
+ pButton->_text = 0x7000 + 35;
+ SkyState::_systemVars.systemFlags &= ~SF_ALLOW_TEXT;
+ } else {
+ pButton->_curSprite = 2;
+ pButton->_text = 0x7000 + 21;
+ SkyState::_systemVars.systemFlags |= SF_ALLOW_TEXT;
+ }
+ pButton->drawToScreen(WITH_MASK);
+ buttonControl(pButton);
+ _system->update_screen();
+ return TOGGLED;
+}
+
uint16 SkyControl::shiftDown(uint8 speed) {
if (speed == SLOW) {
@@ -490,8 +588,6 @@ uint16 SkyControl::saveRestorePanel(bool allowEdit) {
_quitButton->drawToScreen(NO_MASK);
loadSaveDescriptions(saveGameTexts);
- setUpGameSprites(saveGameTexts, textSprites, _firstText);
-
uint16 selectedGame = 0;
bool quitPanel = false;
@@ -499,6 +595,7 @@ uint16 SkyControl::saveRestorePanel(bool allowEdit) {
uint16 clickRes = 0;
while (!quitPanel) {
if (refreshNames) {
+ setUpGameSprites(saveGameTexts, textSprites, _firstText);
showSprites(textSprites);
refreshNames = false;
}
@@ -512,6 +609,7 @@ uint16 SkyControl::saveRestorePanel(bool allowEdit) {
clickRes = CANCEL_PRESSED;
quitPanel = true;
}
+
bool haveButton = false;
for (cnt = 0; cnt < 6; cnt++)
if (lookList[cnt]->isMouseOver(_mouseX, _mouseY)) {
@@ -522,15 +620,15 @@ uint16 SkyControl::saveRestorePanel(bool allowEdit) {
_mouseClicked = false;
clickRes = handleClick(lookList[cnt]);
+
if ((clickRes == CANCEL_PRESSED) || (clickRes == GAME_SAVED) ||
(clickRes == GAME_RESTORED) || (clickRes == NO_DISK_SPACE))
quitPanel = true;
- if (clickRes == SHIFTED) {
- setUpGameSprites(saveGameTexts, textSprites, _firstText);
+ if (clickRes == SHIFTED)
refreshNames = true;
- }
}
}
+
if (_mouseClicked) {
if ((_mouseX >= GAME_NAME_X) && (_mouseX <= GAME_NAME_X + PAN_LINE_WIDTH) &&
(_mouseY >= GAME_NAME_Y) && (_mouseY <= GAME_NAME_Y + PAN_CHAR_HEIGHT * MAX_ON_SCREEN)) {
@@ -539,7 +637,6 @@ uint16 SkyControl::saveRestorePanel(bool allowEdit) {
}
}
if (!haveButton) buttonControl(NULL);
-
}
for (cnt = 0; cnt < MAX_ON_SCREEN; cnt++)
@@ -589,6 +686,7 @@ void SkyControl::loadSaveDescriptions(uint8 *destBuf) {
while ((destPos[nameCnt + 5] = inPos[nameCnt]))
nameCnt++;
destPos += MAX_TEXT_LEN;
+ inPos += nameCnt + 1;
}
free(tmpBuf);
inf->close();
@@ -601,6 +699,162 @@ void SkyControl::loadSaveDescriptions(uint8 *destBuf) {
}
}
+uint16 SkyControl::saveGameToFile(char *fName) {
+
+ File *outf = new File();
+ if (!outf->open(fName, _savePath, File::kFileWriteMode)) {
+ delete outf;
+ return NO_DISK_SPACE;
+ }
+
+ uint8 *saveData = (uint8*)malloc(0x20000);
+ uint32 fSize = prepareSaveData(saveData);
+
+ if (outf->write(saveData, fSize) != fSize) {
+ free(saveData);
+ delete outf;
+ return NO_DISK_SPACE;
+ }
+ outf->close();
+ delete outf;
+ free(saveData);
+ return GAME_SAVED;
+}
+
+#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 SkyControl::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 SkyControl::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;
+ }
+ STOSW(*destPos, 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);
+ }
+}
+
+void SkyControl::stosAR(uint8 **destPos, uint8 *arData) {
+
+ uint16 *data = (uint16*)arData;
+ for (uint8 cnt = 0; cnt < 32; cnt++)
+ STOSW(*destPos, TO_LE_16(data[cnt]));
+}
+
+uint32 SkyControl::prepareSaveData(uint8 *destBuf) {
+
+ uint32 cnt;
+ memset(destBuf, 0, 4); // space for data size
+ uint8 *destPos = destBuf + 4;
+ memcpy(destPos, SAVE_HEADER, sizeof(SAVE_HEADER));
+ destPos += sizeof(SAVE_HEADER);
+ //STOSD(destPos, SkyLogic::_scriptVariables[CUR_SECTION]);
+ STOSD(destPos, _skyMusic->giveCurrentMusic());
+
+ //TODO: save queued sfx
+ STOSD(destPos, _skyText->giveCurrentCharSet());
+ STOSD(destPos, _skyMouse->giveCurrentMouseType());
+ STOSD(destPos, SkyState::_systemVars.currentPalette);
+ for (cnt = 0; cnt < 838; cnt++)
+ STOSD(destPos, SkyLogic::_scriptVariables[cnt]);
+ uint32 *loadedFilesList = _skyDisk->giveLoadedFilesList();
+
+ 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++)
+ stosAR(&destPos, _saveLoadARs[cnt]);
+
+ 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]);
+
+ *(uint32*)destBuf = TO_LE_32(destPos - destBuf); // save size
+ return destPos - destBuf;
+}
+
+#undef STOSD
+#undef STOSW
+
void SkyControl::delay(unsigned int amount) {
OSystem::Event event;
@@ -642,6 +896,8 @@ void SkyControl::delay(unsigned int amount) {
break;
case OSystem::EVENT_QUIT:
+ showGameQuitMsg(false);
+ delay(1500);
_system->quit();
break;
@@ -659,3 +915,41 @@ void SkyControl::delay(unsigned int amount) {
cur = _system->get_msecs();
} while (cur < start + amount);
}
+
+void SkyControl::showGameQuitMsg(bool useScreen) {
+
+ uint8 *textBuf1 = (uint8*)malloc(GAME_SCREEN_WIDTH * 14 + sizeof(dataFileHeader));
+ uint8 *textBuf2 = (uint8*)malloc(GAME_SCREEN_WIDTH * 14 + sizeof(dataFileHeader));
+ char *vText1, *vText2;
+ uint8 *screenData;
+ if (useScreen)
+ screenData = _skyScreen->giveCurrent();
+ else
+ screenData = _screenBuf;
+ switch (SkyState::_systemVars.language) {
+ case DE_DEU: vText1 = VIG_DE1; vText2 = VIG_DE2; break;
+ case FR_FRA: vText1 = VIG_FR1; vText2 = VIG_FR2; break;
+ case IT_ITA: vText1 = VIG_IT1; vText2 = VIG_IT2; break;
+ case PT_BRA: vText1 = VIG_PT1; vText2 = VIG_PT2; break;
+ default: vText1 = VIG_EN1; vText2 = VIG_EN2; break;
+ }
+ _skyText->displayText(vText1, textBuf1, true, 320, 255);
+ _skyText->displayText(vText2, textBuf2, true, 320, 255);
+ uint8 *curLine1 = textBuf1 + sizeof(dataFileHeader);
+ uint8 *curLine2 = textBuf2 + sizeof(dataFileHeader);
+ uint8 *targetLine = screenData + GAME_SCREEN_WIDTH * 80;
+ for (uint8 cnty = 0; cnty < PAN_CHAR_HEIGHT; cnty++) {
+ for (uint16 cntx = 0; cntx < GAME_SCREEN_WIDTH; cntx++) {
+ if (curLine1[cntx])
+ targetLine[cntx] = curLine1[cntx];
+ if (curLine2[cntx])
+ (targetLine + 24 * GAME_SCREEN_WIDTH)[cntx] = curLine2[cntx];
+ }
+ curLine1 += GAME_SCREEN_WIDTH;
+ curLine2 += GAME_SCREEN_WIDTH;
+ targetLine += GAME_SCREEN_WIDTH;
+ }
+ _skyScreen->halvePalette();
+ _skyScreen->showScreen(screenData);
+ free(textBuf1); free(textBuf2);
+}