diff options
Diffstat (limited to 'sword1')
-rw-r--r-- | sword1/control.cpp | 840 | ||||
-rw-r--r-- | sword1/control.h | 125 |
2 files changed, 965 insertions, 0 deletions
diff --git a/sword1/control.cpp b/sword1/control.cpp new file mode 100644 index 0000000000..8617c70f8e --- /dev/null +++ b/sword1/control.cpp @@ -0,0 +1,840 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "stdafx.h" +#include "control.h" +#include "common/util.h" +#include "common/file.h" +#include "logic.h" +#include "sworddefs.h" +#include "swordres.h" +#include "resman.h" +#include "objectman.h" +#include "sword1.h" +#include "common/util.h" +#include "mouse.h" + +#define SAVEFILE_WRITE true +#define SAVEFILE_READ false + +enum LangStrings { + STR_PAUSED = 0, + STR_INSERT_CD_A, + STR_INSERT_CD_B, + STR_INCORRECT_CD, + STR_SAVE, + STR_RESTORE, + STR_RESTART, + STR_START, + STR_QUIT, + STR_SPEED, + STR_VOLUME, + STR_TEXT, + STR_DONE, + STR_OK, + STR_CANCEL, + STR_MUSIC, + STR_SPEECH, + STR_FX, + STR_THE_END, + STR_DRIVE_FULL +}; + +enum ButtonIds { + BUTTON_DONE = 1, + BUTTON_MAIN_PANEL, + BUTTON_SAVE_PANEL, + BUTTON_RESTORE_PANEL, + BUTTON_RESTART, + BUTTON_QUIT, + BUTTON_SPEED, + BUTTON_VOLUME, + BUTTON_TEXT, +//- + BUTTON_SCROLL_UP_FAST, + BUTTON_SCROLL_UP_SLOW, + BUTTON_SCROLL_DOWN_SLOW, + BUTTON_SCROLL_DOWN_FAST, + BUTTON_SAVE_SELECT1, + BUTTON_SAVE_SELECT2, + BUTTON_SAVE_SELECT3, + BUTTON_SAVE_SELECT4, + BUTTON_SAVE_SELECT5, + BUTTON_SAVE_SELECT6, + BUTTON_SAVE_SELECT7, + BUTTON_SAVE_SELECT8, + BUTTON_SAVE_RESTORE_OKAY, + BUTTON_SAVE_CANCEL, +}; + +ControlButton::ControlButton(uint16 x, uint16 y, uint32 resId, uint8 id, ResMan *pResMan, uint8 *screenBuf, OSystem *system) { + _x = x; + _y = y; + _id = id; + _resId = resId; + _resMan = pResMan; + _dstBuf = screenBuf + y * SCREEN_WIDTH + x; + _frameIdx = 0; + _resMan->resOpen(_resId); + FrameHeader *tmp = _resMan->fetchFrame(_resMan->fetchRes(_resId), 0); + _width = FROM_LE_16(tmp->width); + _height = FROM_LE_16(tmp->height); + _system = system; +} + +ControlButton::~ControlButton(void) { + _resMan->resClose(_resId); +} + +bool ControlButton::isSaveslot(void) { + return ((_resId >= SR_SLAB1) && (_resId <= SR_SLAB4)); +} + +void ControlButton::draw(void) { + FrameHeader *fHead = _resMan->fetchFrame(_resMan->fetchRes(_resId), _frameIdx); + uint8 *src = (uint8*)fHead + sizeof(FrameHeader); + uint8 *dst = _dstBuf; + for (uint16 cnt = 0; cnt < FROM_LE_16(fHead->height); cnt++) { + for (uint16 cntx = 0; cntx < FROM_LE_16(fHead->width); cntx++) + if (src[cntx]) + dst[cntx] = src[cntx]; + dst += SCREEN_WIDTH; + src += FROM_LE_16(fHead->width); + } + _system->copy_rect(_dstBuf, SCREEN_WIDTH, _x, _y, _width, _height); +} + +bool ControlButton::wasClicked(uint16 mouseX, uint16 mouseY) { + if ((_x <= mouseX) && (_y <= mouseY) && (_x + _width >= mouseX) && (_y + _height >= mouseY)) + return true; + else + return false; +} + +void ControlButton::setSelected(uint8 selected) { + _frameIdx = selected; + draw(); +} + +SwordControl::SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, const char *savePath) { + _resMan = pResMan; + _objMan = pObjMan; + _system = system; + _mouse = pMouse; + strcpy(_savePath, savePath); +} + +uint8 SwordControl::runPanel(void) { + _restoreBuf = NULL; + _lStrings = _languageStrings + MIN(SwordEngine::_systemVars.language, (uint8)BS1_SPANISH) * 20; + _keyPressed = _numButtons = 0; + _screenBuf = (uint8*)malloc(640 * 480); + _font = (uint8*)_resMan->openFetchRes(GAME_FONT); // todo: czech support + _resMan->resOpen(SR_BUTTON); + uint8 *pal = (uint8*)_resMan->openFetchRes(SR_PALETTE); + uint8 *palOut = (uint8*)malloc(256 * 4); + for (uint16 cnt = 1; cnt < 256; cnt++) { + palOut[cnt * 4 + 0] = pal[cnt * 3 + 0] << 2; + palOut[cnt * 4 + 1] = pal[cnt * 3 + 1] << 2; + palOut[cnt * 4 + 2] = pal[cnt * 3 + 2] << 2; + } + palOut[0] = palOut[1] = palOut[2] = palOut[3] = 0; + _resMan->resClose(SR_PALETTE); + _system->set_palette(palOut, 0, 256); + free(palOut); + uint8 mode = 0, newMode = BUTTON_MAIN_PANEL; + bool fullRefresh = false; + _mouse->controlPanel(true); + uint8 retVal = CONTROL_NOTHING_DONE; + + do { + if (newMode) { + mode = newMode; + fullRefresh = true; + destroyButtons(); + memset(_screenBuf, 0, 640 * 480); + } + switch (mode) { + case BUTTON_MAIN_PANEL: + if (fullRefresh) + setupMainPanel(); + break; + case BUTTON_SAVE_PANEL: + if (fullRefresh) + setupSaveRestorePanel(true); + if (_keyPressed) + handleSaveKey(_keyPressed); + break; + case BUTTON_RESTORE_PANEL: + if (fullRefresh) + setupSaveRestorePanel(false); + break; + + } + if (fullRefresh) { + fullRefresh = false; + _system->copy_rect(_screenBuf, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, 480); + } + _system->update_screen(); + delay(1000 / 12); + newMode = getClicks(mode, &retVal); + } while ((newMode != 1) && (retVal == 0)); + _resMan->resClose(SR_BUTTON); + memset(_screenBuf, 0, 640 * 480); + _system->copy_rect(_screenBuf, 640, 0, 0, 640, 480); + free(_screenBuf); + _mouse->controlPanel(false); + return retVal; +} + +uint8 SwordControl::getClicks(uint8 mode, uint8 *retVal) { + if (!_mouseState) + return 0; + if (_mouseState & BS1L_BUTTON_DOWN) + for (uint8 cnt = 0; cnt < _numButtons; cnt++) + if (_buttons[cnt]->wasClicked(_mouseX, _mouseY)) { + _selectedButton = cnt; + _buttons[cnt]->setSelected(1); + } + if (_mouseState & BS1L_BUTTON_UP) { + for (uint8 cnt = 0; cnt < _numButtons; cnt++) + if (_buttons[cnt]->wasClicked(_mouseX, _mouseY)) + if (_selectedButton == cnt) { + // saveslots stay selected after clicking + if (!_buttons[cnt]->isSaveslot()) + _buttons[cnt]->setSelected(0); + _selectedButton = 255; + return handleButtonClick(_buttons[cnt]->_id, mode, retVal); + } + if (_selectedButton < _numButtons) + _buttons[_selectedButton]->setSelected(0); + _selectedButton = 255; + } + return 0; +} + +uint8 SwordControl::handleButtonClick(uint8 id, uint8 mode, uint8 *retVal) { + switch(mode) { + case BUTTON_MAIN_PANEL: + if (id == BUTTON_RESTART) + *retVal |= CONTROL_RESTART_GAME; + else if ((id == BUTTON_RESTORE_PANEL) || (id == BUTTON_SAVE_PANEL) || + (id == BUTTON_DONE)) + return id; + else + return 0; + case BUTTON_SAVE_PANEL: + case BUTTON_RESTORE_PANEL: + if ((id >= BUTTON_SCROLL_UP_FAST) && (id <= BUTTON_SCROLL_DOWN_FAST)) + saveNameScroll(id, mode == BUTTON_SAVE_PANEL); + else if ((id >= BUTTON_SAVE_SELECT1) && (id <= BUTTON_SAVE_SELECT8)) + saveNameSelect(id, mode == BUTTON_SAVE_PANEL); + else if (id == BUTTON_SAVE_RESTORE_OKAY) { + if (mode == BUTTON_SAVE_PANEL) { + if (saveToFile()) // don't go back to main panel if save fails. + return BUTTON_MAIN_PANEL; + } else { + if (restoreFromFile()) { // don't go back to main panel if restore fails. + *retVal |= CONTROL_GAME_RESTORED; + return BUTTON_MAIN_PANEL; + } + } + } else if (id == BUTTON_SAVE_CANCEL) + return BUTTON_MAIN_PANEL; // mode down to main panel + } + return 0; +} + +void SwordControl::deselectSaveslots(void) { + for (uint8 cnt = 0; cnt < 8; cnt++) + _buttons[cnt]->setSelected(0); +} + +void SwordControl::setupMainPanel(void) { + uint32 panelId; + uint8 langCode = MIN(SwordEngine::_systemVars.language, (uint8)BS1_SPANISH); + + if (SwordEngine::_systemVars.deathScreenFlag == 1) + panelId = SR_DEATHPANEL; + else + panelId = SR_PANEL_ENGLISH + langCode; + + FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(panelId), 0); + uint16 panelX = (640 - FROM_LE_16(frameHead->width)) / 2; + uint16 panelY = (400 - FROM_LE_16(frameHead->height)) / 2; + + ControlButton *panel = new ControlButton(panelX, panelY, panelId, 0, _resMan, _screenBuf, _system); + panel->draw(); + delete panel; + _resMan->resClose(panelId); + + if (SwordEngine::_systemVars.deathScreenFlag) + createButtons(_deathButtons, 3); + else + createButtons(_panelButtons, 8); + + if (SwordEngine::_systemVars.deathScreenFlag == 2) // end of game + renderText(_lStrings[STR_THE_END], -480, 188); + + if (SwordEngine::_systemVars.deathScreenFlag == 0) { // normal panel + renderText(_lStrings[STR_SAVE], 180, 188); + renderText(_lStrings[STR_DONE], -460, 332); + renderText(_lStrings[STR_RESTORE], 180, 224); + renderText(_lStrings[STR_RESTART], 180, 260); + renderText(_lStrings[STR_QUIT], 180, 296); + + renderText(_lStrings[STR_SPEED], -460, 188); + renderText(_lStrings[STR_VOLUME], -460, 224); + renderText(_lStrings[STR_TEXT], -460, 260); + } else { + renderText(_lStrings[STR_RESTORE], 285, 224); + if (SwordEngine::_systemVars.deathScreenFlag == 3) // just started game + renderText(_lStrings[STR_START], 285, 260); + else + renderText(_lStrings[STR_RESTART], 285, 260); + renderText(_lStrings[STR_QUIT], 285, 296); + } +} + +void SwordControl::setupSaveRestorePanel(bool saving) { + FrameHeader *savePanel = _resMan->fetchFrame(_resMan->openFetchRes(SR_WINDOW), 0); + uint16 panelX = (640 - FROM_LE_16(savePanel->width)) / 2; + uint16 panelY = (480 - FROM_LE_16(savePanel->height)) / 2; + ControlButton *panel = new ControlButton(panelX, panelY, SR_WINDOW, 0, _resMan, _screenBuf, _system); + panel->draw(); + delete panel; + _resMan->resClose(SR_WINDOW); + createButtons(_saveButtons, 14); + renderText(_lStrings[STR_CANCEL], -(_saveButtons[13].x - 10), _saveButtons[13].y); + if (saving) { + renderText(_lStrings[STR_SAVE], _saveButtons[12].x + 30, _saveButtons[13].y); + } else { + renderText(_lStrings[STR_RESTORE], _saveButtons[12].x + 30, _saveButtons[13].y); + } + readSavegameDescriptions(); + _selectedSavegame = 255; + showSavegameNames(); +} + +bool SwordControl::keyAccepted(uint8 key) { + // this routine needs changes for Czech keys... No idea how to do that, though. + static const char allowedSpecials[] = "éèáàúùäöüÄÖÜß,.:-()?! \"\'"; + if (((key >= 'A') && (key <= 'Z')) || + ((key >= 'a') && (key <= 'z')) || + ((key >= '0') && (key <= '9')) || + strchr(allowedSpecials, key)) + return true; + else + return false; +} + +void SwordControl::handleSaveKey(uint8 key) { + if (_selectedSavegame < 255) { + uint8 len = strlen(_saveNames[_selectedSavegame]); + if ((key == 8) && len) // backspace + _saveNames[_selectedSavegame][len - 1] = '\0'; + else if (keyAccepted(key) && (len < 31)) { + _saveNames[_selectedSavegame][len] = key; + _saveNames[_selectedSavegame][len + 1] = '\0'; + } + showSavegameNames(); + } +} + +bool SwordControl::saveToFile(void) { + if ((_selectedSavegame == 255) || !strlen(_saveNames[_selectedSavegame])) + return false; // no saveslot selected or no name entered + saveGameToFile(_selectedSavegame); + writeSavegameDescriptions(); + return true; +} + +bool SwordControl::restoreFromFile(void) { + if (_selectedSavegame < 255) { + restoreGameFromFile(_selectedSavegame); + return true; + } else + return false; +} + +void SwordControl::readSavegameDescriptions(void) { + SaveFileManager *mgr = _system->get_savefile_manager(); + SaveFile *inf; + inf = mgr->open_savefile("SAVEGAME.INF", _savePath, SAVEFILE_READ); + _saveScrollPos = _saveFiles = 0; + _selectedSavegame = 255; + if (inf && inf->isOpen()) { + uint8 curFileNum = 0; + uint8 ch; + do { + uint8 pos = 0; + do { + ch = inf->readByte(); + if ((ch == 10) || (ch == 255)) + _saveNames[curFileNum][pos] = '\0'; + else + _saveNames[curFileNum][pos] = ch; + pos++; + } while ((ch != 10) && (ch != 255)); + curFileNum++; + } while (ch != 255); + _saveFiles = curFileNum; + for (uint8 cnt = _saveFiles; cnt < 64; cnt++) + _saveNames[cnt][0] = '\0'; + } else + for (uint8 cnt = 0; cnt < 64; cnt++) + _saveNames[cnt][0] = '\0'; + delete inf; + delete mgr; +} + +void SwordControl::writeSavegameDescriptions(void) { + SaveFileManager *mgr = _system->get_savefile_manager(); + SaveFile *outf; + outf = mgr->open_savefile("SAVEGAME.INF", _savePath, SAVEFILE_WRITE); + // if the player accidently clicked the last slot and then deselected it again, + // we'd still have _saveFiles == 64, so get rid of the empty end. + while (strlen(_saveNames[_saveFiles] - 1) == 0) + _saveFiles--; + for (uint8 cnt = 0; cnt < _saveFiles; cnt++) { + outf->write(_saveNames[cnt], strlen(_saveNames[cnt])); + if (cnt < _saveFiles - 1) + outf->writeByte(10); + else + outf->writeByte(255); + } + delete outf; + delete mgr; +} + +void SwordControl::showSavegameNames(void) { + for (uint8 cnt = 0; cnt < 8; cnt++) { + _buttons[cnt]->draw(); + renderText(_saveNames[cnt + _saveScrollPos], _saveButtons[cnt].x + 6, _saveButtons[cnt].y + 2); + } +} + +void SwordControl::saveNameSelect(uint8 id, bool saving) { + deselectSaveslots(); + _buttons[id - BUTTON_SAVE_SELECT1]->setSelected(1); + uint8 num = (id - BUTTON_SAVE_SELECT1) + _saveScrollPos; + if (saving && (_selectedSavegame != 255)) // the player may have entered something, clear it again + strcpy(_saveNames[_selectedSavegame], _oldName); + if (num < _saveFiles) { + _selectedSavegame = num; + strcpy(_oldName, _saveNames[num]); // save for later + } else { + if (!saving) + _buttons[id - BUTTON_SAVE_SELECT1]->setSelected(0); // no save in slot, deselect it + else { + if (_saveFiles <= num) + _saveFiles = num + 1; + _selectedSavegame = num; + _oldName[0] = '\0'; + } + } + showSavegameNames(); +} + +void SwordControl::saveNameScroll(uint8 scroll, bool saving) { + uint16 maxScroll; + if (saving) + maxScroll = 64; + else + maxScroll = _saveFiles; // for loading, we can only scroll as far as there are savegames + if (scroll == BUTTON_SCROLL_UP_FAST) { + if (_saveScrollPos >= 8) + _saveScrollPos -= 8; + else + _saveScrollPos = 0; + } else if (scroll == BUTTON_SCROLL_UP_SLOW) { + if (_saveScrollPos >= 1) + _saveScrollPos--; + } else if (scroll == BUTTON_SCROLL_DOWN_SLOW) { + if (_saveScrollPos < maxScroll - 8) + _saveScrollPos++; + } else if (scroll == BUTTON_SCROLL_DOWN_FAST) { + if (_saveScrollPos < maxScroll - 16) + _saveScrollPos += 8; + else + _saveScrollPos = maxScroll - 8; + } + _selectedSavegame = 255; // deselect savegame + deselectSaveslots(); + showSavegameNames(); +} + +void SwordControl::createButtons(const ButtonInfo *buttons, uint8 num) { + for (uint8 cnt = 0; cnt < num; cnt++) { + _buttons[cnt] = new ControlButton(buttons[cnt].x, buttons[cnt].y, buttons[cnt].resId, buttons[cnt].id, _resMan, _screenBuf, _system); + _buttons[cnt]->draw(); + } + _numButtons = num; +} + +void SwordControl::destroyButtons(void) { + for (uint8 cnt = 0; cnt < _numButtons; cnt++) + delete _buttons[cnt]; + _numButtons = 0; +} + +uint16 SwordControl::getTextWidth(const char *str) { + uint16 width = 0; + while (*str) { + width += FROM_LE_16(_resMan->fetchFrame(_font, *str - 32)->width) - 3; + str++; + } + return width; +} + +void SwordControl::renderText(const char *str, int16 x, uint16 y) { + if (x < 0) // negative x coordinate means rightbound. + x = (-x) - getTextWidth(str); + + uint16 destX = x; + while (*str) { + uint8 *dst = _screenBuf + y * SCREEN_WIDTH + destX; + + FrameHeader *chSpr = _resMan->fetchFrame(_font, *str - 32); + uint8 *sprData = (uint8*)chSpr + sizeof(FrameHeader); + for (uint16 cnty = 0; cnty < FROM_LE_16(chSpr->height); cnty++) { + for (uint16 cntx = 0; cntx < FROM_LE_16(chSpr->width); cntx++) { + if (sprData[cntx]) + dst[cntx] = sprData[cntx]; + } + sprData += FROM_LE_16(chSpr->width); + dst += SCREEN_WIDTH; + } + destX += FROM_LE_16(chSpr->width) - 3; + str++; + } + _system->copy_rect(_screenBuf + y * SCREEN_WIDTH + x, SCREEN_WIDTH, x, y, (destX - x) + 3, 28); +} + +// I can hardly believe this is all it takes for loading and saving... +void SwordControl::saveGameToFile(uint8 slot) { + char fName[15]; + sprintf(fName, "SAVEGAME.%03d", slot); + uint16 liveBuf[TOTAL_SECTIONS]; + SaveFileManager *mgr = _system->get_savefile_manager(); + SaveFile *outf; + outf = mgr->open_savefile(fName, _savePath, SAVEFILE_WRITE); + if (!outf->isOpen()) + error("unable to create file %s", fName); + + _objMan->saveLiveList(liveBuf); + for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++) + outf->writeUint16LE(liveBuf[cnt]); + + BsObject *cpt = _objMan->fetchObject(PLAYER); + SwordLogic::_scriptVars[CHANGE_DIR] = cpt->o_dir; + SwordLogic::_scriptVars[CHANGE_X] = cpt->o_xcoord; + SwordLogic::_scriptVars[CHANGE_Y] = cpt->o_ycoord; + SwordLogic::_scriptVars[CHANGE_STANCE] = STAND; + SwordLogic::_scriptVars[CHANGE_PLACE] = cpt->o_place; + + for (uint16 cnt = 0; cnt < NUM_SCRIPT_VARS; cnt++) + outf->writeUint32LE(SwordLogic::_scriptVars[cnt]); + + uint32 playerSize = (sizeof(BsObject) - 12000) / 4; + uint32 *playerRaw = (uint32*)cpt; + for (uint32 cnt = 0; cnt < playerSize; cnt++) + outf->writeUint32LE(playerRaw[cnt]); + delete outf; + delete mgr; +} + +void SwordControl::restoreGameFromFile(uint8 slot) { + char fName[15]; + sprintf(fName, "SAVEGAME.%03d", slot); + SaveFileManager *mgr = _system->get_savefile_manager(); + SaveFile *inf; + inf = mgr->open_savefile(fName, _savePath, SAVEFILE_READ); + if ((!inf) || (!inf->isOpen())) + error("Unable to open file %s", fName); + + _restoreBuf = (uint8*)malloc( + TOTAL_SECTIONS * 2 + + NUM_SCRIPT_VARS * 4 + + (sizeof(BsObject) - 12000)); + + uint16 *liveBuf = (uint16*)_restoreBuf; + uint32 *scriptBuf = (uint32*)(_restoreBuf + 2 * TOTAL_SECTIONS); + uint32 *playerBuf = (uint32*)(_restoreBuf + 2 * TOTAL_SECTIONS + 4 * NUM_SCRIPT_VARS); + + for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++) + liveBuf[cnt] = inf->readUint16LE(); + + for (uint16 cnt = 0; cnt < NUM_SCRIPT_VARS; cnt++) + scriptBuf[cnt] = inf->readUint32LE(); + + uint32 playerSize = (sizeof(BsObject) - 12000) / 4; + for (uint32 cnt = 0; cnt < playerSize; cnt++) + playerBuf[cnt] = inf->readUint32LE(); + + delete inf; + delete mgr; +} + +void SwordControl::doRestore(void) { + uint8 *bufPos = _restoreBuf; + _objMan->loadLiveList((uint16*)bufPos); + bufPos += TOTAL_SECTIONS * 2; + for (uint16 cnt = 0; cnt < NUM_SCRIPT_VARS; cnt++) { + SwordLogic::_scriptVars[cnt] = *(uint32*)bufPos; + bufPos += 4; + } + uint32 playerSize = (sizeof(BsObject) - 12000) / 4; + uint32 *playerRaw = (uint32*)_objMan->fetchObject(PLAYER); + for (uint32 cnt = 0; cnt < playerSize; cnt++) { + *playerRaw = *(uint32*)bufPos; + playerRaw++; + bufPos += 4; + } + free(_restoreBuf); +} + +void SwordControl::delay(uint32 msecs) { + OSystem::Event event; + + uint32 endTime = _system->get_msecs() + msecs; + _keyPressed = 0; //reset + _mouseState = 0; + + do { + while (_system->poll_event(&event)) { + switch (event.event_code) { + case OSystem::EVENT_KEYDOWN: + + // Make sure backspace works right (this fixes a small issue on OS X) + if (event.kbd.keycode == 8) + _keyPressed = 8; + else + _keyPressed = (byte)event.kbd.ascii; + break; + case OSystem::EVENT_MOUSEMOVE: + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; + break; + case OSystem::EVENT_LBUTTONDOWN: + _mouseState |= BS1L_BUTTON_DOWN; +#ifdef _WIN32_WCE + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; +#endif + break; + case OSystem::EVENT_LBUTTONUP: + _mouseState |= BS1L_BUTTON_UP; + break; + case OSystem::EVENT_QUIT: + _system->quit(); + break; + default: + break; + } + } + _system->delay_msecs(10); + } while (_system->get_msecs() < endTime); +} + +const ButtonInfo SwordControl::_deathButtons[3] = { + {250, 224, SR_BUTTON, BUTTON_RESTORE_PANEL }, + {250, 260, SR_BUTTON, BUTTON_RESTART }, + {250, 296, SR_BUTTON, BUTTON_QUIT } +}; + +const ButtonInfo SwordControl::_panelButtons[8] = { + {145, 188, SR_BUTTON, BUTTON_SAVE_PANEL }, + {145, 224, SR_BUTTON, BUTTON_RESTORE_PANEL }, + {145, 260, SR_BUTTON, BUTTON_RESTART }, + {145, 296, SR_BUTTON, BUTTON_QUIT }, + {475, 188, SR_BUTTON, BUTTON_SPEED }, + {475, 224, SR_BUTTON, BUTTON_VOLUME }, + {475, 260, SR_BUTTON, BUTTON_TEXT }, + {475, 332, SR_BUTTON, BUTTON_DONE } +}; + +const ButtonInfo SwordControl::_saveButtons[16] = { + {114, 32 + 40, SR_SLAB1, BUTTON_SAVE_SELECT1 }, + {114, 68 + 40, SR_SLAB2, BUTTON_SAVE_SELECT2 }, + {114, 104 + 40, SR_SLAB3, BUTTON_SAVE_SELECT3 }, + {114, 140 + 40, SR_SLAB4, BUTTON_SAVE_SELECT4 }, + {114, 176 + 40, SR_SLAB1, BUTTON_SAVE_SELECT5 }, + {114, 212 + 40, SR_SLAB2, BUTTON_SAVE_SELECT6 }, + {114, 248 + 40, SR_SLAB3, BUTTON_SAVE_SELECT7 }, + {114, 284 + 40, SR_SLAB4, BUTTON_SAVE_SELECT8 }, + + {516, 25 + 40, SR_BUTUF, BUTTON_SCROLL_UP_FAST }, + {516, 45 + 40, SR_BUTUS, BUTTON_SCROLL_UP_SLOW }, + {516, 289 + 40, SR_BUTDS, BUTTON_SCROLL_DOWN_SLOW }, + {516, 310 + 40, SR_BUTDF, BUTTON_SCROLL_DOWN_FAST }, + + {125, 338 + 40, SR_BUTTON, BUTTON_SAVE_RESTORE_OKAY}, + {462, 338 + 40, SR_BUTTON, BUTTON_SAVE_CANCEL} +}; + +const char SwordControl::_languageStrings[8 * 20][43] = { + // BS1_ENGLISH: + "PAUSED", + "PLEASE INSERT CD-", + "THEN PRESS A KEY", + "INCORRECT CD", + "Save", + "Restore", + "Restart", + "Start", + "Quit", + "Speed", + "Volume", + "Text", + "Done", + "OK", + "Cancel", + "Music", + "Speech", + "Fx", + "The End", + "DRIVE FULL!", +// BS1_FRENCH: + "PAUSE", + "INS\xC9REZ LE CD-" + "ET APPUYES SUR UNE TOUCHE", + "CD INCORRECT", + "Sauvegarder", + "Recharger", + "Recommencer", + "Commencer", + "Vitesse", + "Volume", + "Texte", + "Termin\xE9", + "OK", + "Annuler", + "Musique", + "Voix", + "Fx", + "Fin", + "DISQUE PLEIN!", +//BS1_GERMAN: + "PAUSE", + "BITTE LEGEN SIE CD-", + "EIN UND DR\xDC CKEN SIE EINE BELIEBIGE TASTE", + "FALSCHE CD", + "Speichern", + "Laden", + "Neues Spiel", + "Start", + "Beenden", + "Geschwindigkeit", + "Lautst\xE4rke", + "Text", + "Fertig", + "OK", + "Abbrechen", + "Musik", + "Sprache", + "Fx", + "Ende", + "DRIVE FULL!", +//BS1_ITALIAN: + "PAUSA", + "INSERITE IL CD-", + "E PREMETE UN TASTO", + "CD ERRATO", + "Salva", + "Ripristina", + "Ricomincia", + "Inizio", + "Velocit\xE0", + "Volume", + "Testo", + "Fatto", + "OK", + "Annula", + "Musica", + "Parlato", + "Fx", + "Fine", + "DISCO PIENO!", +//BS1_SPANISH: + "PAUSA", + "POR FAVOR INTRODUCE EL CD-", + "Y PULSA UNA TECLA", + "CD INCORRECTO", + "Guardar", + "Recuperar", + "Reiniciar", + "Empezar", + "Abandonar", + "Velocidad", + "Volumen", + "Texto", + "Hecho", + "OK", + "Cancelar", + "M\xFAsica", + "Di\xE1logo", + "Fx", + "Fin", + "DISCO LLENO", +// BS1_CZECH: + "\xAC\x41S SE ZASTAVIL", + "VLO\xA6TE DO MECHANIKY CD DISK", + "PAK STISKN\xB7TE LIBOVOLNOU KL\xB5VESU", + "TO NEBUDE TO SPR\xB5VN\x90 CD", + "Ulo\xA7it pozici", + "Nahr\xA0t pozici", + "Za\x9F\xA1t znovu", + "Start", + "Ukon\x9Fit hru", + "Rychlost", + "Hlasitost", + "Titulky", + "Souhlas\xA1m", + "Ano", + "Ne", + "Hudba", + "Mluven, slovo", + "Zvuky", + "Konec", + "Disk pln\xEC", +//BS1_PORTUGESE: + "PAUSA", + "FAVOR INSERIR CD", + "E DIGITAR UMA TECLA", + "CD INCORRETO", + "Salvar", + "Restaurar", + "Reiniciar", + "Iniciar", + "Sair", + "Velocidade", + "Volume", + "Texto", + "Feito", + "OK", + "Cancelar", + "M\xFAsica", + "Voz", + "Efeitos", + "Fim", + "UNIDADE CHEIA!", +}; diff --git a/sword1/control.h b/sword1/control.h new file mode 100644 index 0000000000..4b0a1699b7 --- /dev/null +++ b/sword1/control.h @@ -0,0 +1,125 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef BSCONTROL_H +#define BSCONTROL_H + +#include "scummsys.h" +#include "sworddefs.h" + +class ObjectMan; +class ResMan; +class OSystem; +class SwordMouse; +class SwordEngine; + +#define MAX_BUTTONS 16 + +#define CONTROL_NOTHING_DONE 0 +#define CONTROL_GAME_RESTORED 1 +#define CONTROL_RESTART_GAME 2 + +class ControlButton { +public: + ControlButton(uint16 x, uint16 y, uint32 resId, uint8 id, ResMan *pResMan, uint8 *screenBuf, OSystem *system); + ~ControlButton(void); + void draw(void); + bool wasClicked(uint16 mouseX, uint16 mouseY); + void setSelected(uint8 selected); + bool isSaveslot(void); + uint8 _id; +private: + int _frameIdx; + uint16 _x, _y; + uint16 _width, _height; + uint32 _resId; + ResMan *_resMan; + uint8 *_dstBuf; + OSystem *_system; +}; + +struct ButtonInfo { + uint16 x, y; + uint32 resId, id; +}; + +class SwordControl { +public: + SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, const char *savePath); + ~SwordControl(void); + uint8 runPanel(void); + void doRestore(void); +private: + void initData(void); + void closeData(void); + + void saveGameToFile(uint8 slot); + void restoreGameFromFile(uint8 slot); + void readSavegameDescriptions(void); + void writeSavegameDescriptions(void); + void showSavegameNames(void); + void deselectSaveslots(void); + uint8 *_restoreBuf; + uint8 _saveFiles; + uint8 _saveScrollPos; + uint8 _selectedSavegame; + char _saveNames[64][32]; + char _oldName[32]; + + uint8 getClicks(uint8 mode, uint8 *retVal); + uint8 handleButtonClick(uint8 id, uint8 mode, uint8 *retVal); + + void setupMainPanel(void); + void setupSaveRestorePanel(bool saving); + void saveNameScroll(uint8 scroll, bool saving); + void saveNameSelect(uint8 id, bool saving); + bool saveToFile(void); + bool restoreFromFile(void); + bool keyAccepted(uint8 key); + void handleSaveKey(uint8 key); + + uint16 getTextWidth(const char *str); + void renderText(const char *str, int16 x, uint16 y); + uint8 _numButtons; + uint8 _selectedButton; + void createButtons(const ButtonInfo *buttons, uint8 num); + void destroyButtons(void); + ControlButton *_buttons[MAX_BUTTONS]; + static const ButtonInfo _deathButtons[3], _panelButtons[8], _saveButtons[16]; + static const char _languageStrings[8 * 20][43]; + const char (*_lStrings)[43]; + ObjectMan *_objMan; + ResMan *_resMan; + OSystem *_system; + SwordMouse *_mouse; + SwordEngine *_engine; + char _savePath[256]; + uint8 *_font; + uint32 _fontId; + uint8 *_screenBuf; + uint8 _keyPressed; + void delay(uint32 msecs); + uint16 _mouseX, _mouseY, _mouseState; +}; + + +#endif //BSCONTROL_H + |