diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | common/system.h | 8 | ||||
-rw-r--r-- | gui/launcher.cpp | 48 | ||||
-rw-r--r-- | gui/options.cpp | 179 | ||||
-rw-r--r-- | gui/options.h | 17 | ||||
-rw-r--r-- | scumm/actor.cpp | 4 | ||||
-rw-r--r-- | scumm/dialogs.cpp | 53 | ||||
-rw-r--r-- | scumm/dialogs.h | 7 | ||||
-rw-r--r-- | scumm/script_v6.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v6he.cpp | 24 | ||||
-rw-r--r-- | scumm/script_v8.cpp | 3 | ||||
-rw-r--r-- | scumm/scumm.h | 2 | ||||
-rw-r--r-- | scumm/string.cpp | 51 |
13 files changed, 234 insertions, 168 deletions
@@ -30,7 +30,7 @@ MODULE_DIRS := include config.mak # Uncomment this for stricter compile time code verification -# CXXFLAGS+= -Werror +CXXFLAGS+= -Werror CXXFLAGS:= -Wall $(CXXFLAGS) CXXFLAGS+= -O -Wuninitialized diff --git a/common/system.h b/common/system.h index aacc9df032..e35a28889f 100644 --- a/common/system.h +++ b/common/system.h @@ -368,9 +368,12 @@ public: /** * Abstract key code (will be the same for any given key regardless * of modifiers being held at the same time. - * @todo Document which values are to be used for non-ASCII keys - * like F1-F10. * For example, this is the same for both 'A' and Shift-'A'. + * @todo Document which values are to be used for non-ASCII keys + * like F1-F10. For now, let's just say that our primary backend + * is the SDL one, and it uses the values SDL uses... so until + * we fix this, your best bet is to get a copy of SDL_keysym.h + * and look at that, if you want to find out a key code. */ int keycode; /** @@ -378,6 +381,7 @@ public: * This depends on modifiers, i.e. pressing the 'A' key results in * different values here depending on the status of shift, alt and * caps lock. + * For the function keys F1-F9, values of 315-323 are used. */ uint16 ascii; /** diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 0ab29f97c9..53772c67d4 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -86,8 +86,6 @@ class EditGameDialog : public OptionsDialog { public: EditGameDialog(const String &domain, GameSettings target); - void open(); - void close(); virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); protected: @@ -100,6 +98,10 @@ protected: CheckboxWidget *_globalGraphicsOverride; CheckboxWidget *_globalAudioOverride; CheckboxWidget *_globalVolumeOverride; + + virtual void applySettings(); + virtual void loadSettings(); + virtual void saveSettings(); }; EditGameDialog::EditGameDialog(const String &domain, GameSettings target) @@ -203,11 +205,17 @@ EditGameDialog::EditGameDialog(const String &domain, GameSettings target) // Add OK & Cancel buttons addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0); - addButton(_w - (kButtonWidth + 10), _h - 24, "OK", kOKCmd, 0); + addButton(_w - (kButtonWidth + 10), _h - 24, "OK", kSaveCmd, 0); +} + +void EditGameDialog::applySettings() { + // Do *never* apply settings from the EditGameDialog! + // After all, we are editing a game target in the launcher; that target + // can definitely not be the active target, since we are in the launcher. } -void EditGameDialog::open() { - OptionsDialog::open(); +void EditGameDialog::loadSettings() { + OptionsDialog::loadSettings(); int sel, i; bool e; @@ -251,24 +259,22 @@ void EditGameDialog::open() { _platformPopUp->setSelected(sel); } +void EditGameDialog::saveSettings() { + ConfMan.set("description", _descriptionWidget->getLabel(), _domain); -void EditGameDialog::close() { - if (getResult()) { - ConfMan.set("description", _descriptionWidget->getLabel(), _domain); + Common::Language lang = (Common::Language)_langPopUp->getSelectedTag(); + if (lang < 0) + ConfMan.removeKey("language", _domain); + else + ConfMan.set("language", Common::getLanguageCode(lang), _domain); - Common::Language lang = (Common::Language)_langPopUp->getSelectedTag(); - if (lang < 0) - ConfMan.removeKey("language", _domain); - else - ConfMan.set("language", Common::getLanguageCode(lang), _domain); + Common::Platform platform = (Common::Platform)_platformPopUp->getSelectedTag(); + if (platform < 0) + ConfMan.removeKey("platform", _domain); + else + ConfMan.set("platform", Common::getPlatformCode(platform), _domain); - Common::Platform platform = (Common::Platform)_platformPopUp->getSelectedTag(); - if (platform < 0) - ConfMan.removeKey("platform", _domain); - else - ConfMan.set("platform", Common::getPlatformCode(platform), _domain); - } - OptionsDialog::close(); + OptionsDialog::saveSettings(); } void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { @@ -285,7 +291,7 @@ void EditGameDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat setVolumeSettingsState(data != 0); draw(); break; - case kOKCmd: { + case kSaveCmd: { // Write back changes made to config object String newDomain(_domainWidget->getLabel()); if (newDomain != _domain) { diff --git a/gui/options.cpp b/gui/options.cpp index cb42735246..f4ffaf98e5 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -55,6 +55,8 @@ enum { OptionsDialog::OptionsDialog(const String &domain, int x, int y, int w, int h) : Dialog(x, y, w, h), _domain(domain), + _isActiveDomain(domain.isEmpty() || domain == ConfMan.getActiveDomain() || + (ConfMan.getActiveDomain().isEmpty() && domain == Common::ConfigManager::kApplicationDomain)), _enableGraphicSettings(false), _gfxPopUp(0), _fullscreenCheckbox(0), _aspectCheckbox(0), _enableAudioSettings(false), @@ -64,6 +66,7 @@ OptionsDialog::OptionsDialog(const String &domain, int x, int y, int w, int h) _musicVolumeSlider(0), _musicVolumeLabel(0), _sfxVolumeSlider(0), _sfxVolumeLabel(0) { +printf("_isActiveDomain = %d, _domain = %s, active domain = %s\n", _isActiveDomain, _domain.c_str(), ConfMan.getActiveDomain().c_str()); } void OptionsDialog::open() { @@ -71,15 +74,49 @@ void OptionsDialog::open() { // Reset result value setResult(0); + + loadSettings(); +} + +void OptionsDialog::handleScreenChanged() { + loadSettings(); +} + +void OptionsDialog::close() { + if (getResult() == kSaveCmd) { + saveSettings(); + } + + if (_isActiveDomain && (getResult() == kSaveCmd || getResult() == kApplyCmd)) { + applySettings(); + } + + Dialog::close(); +} + +void OptionsDialog::applySettings() { + // Activate changes now + if (_enableGraphicSettings) { + g_system->setFeatureState(OSystem::kFeatureFullscreenMode, _fullscreenCheckbox->getState()); + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, _aspectCheckbox->getState()); + if ((int32)_gfxPopUp->getSelectedTag() >= 0) + g_system->setGraphicsMode(_gfxPopUp->getSelectedTag()); + } +} + +void OptionsDialog::loadSettings() { + bool state; if (_fullscreenCheckbox) { _gfxPopUp->setSelected(0); - _gfxPopUp->setEnabled(false); - if (ConfMan.hasKey("gfx_mode", _domain)) { + if (_isActiveDomain) { + int gfxMode = g_system->getGraphicsMode(); + _gfxPopUp->setSelectedTag(gfxMode); + } else if (ConfMan.hasKey("gfx_mode", _domain)) { const OSystem::GraphicsMode *gm = g_system->getSupportedGraphicsModes(); - String gfxMode = ConfMan.get("gfx_mode", _domain); int gfxCount = 1; + String gfxMode = ConfMan.get("gfx_mode", _domain); while (gm->name) { gfxCount++; @@ -92,10 +129,16 @@ void OptionsDialog::open() { #ifndef _WIN32_WCE // Fullscreen setting - _fullscreenCheckbox->setState(ConfMan.getBool("fullscreen", _domain)); + state = _isActiveDomain ? + g_system->getFeatureState(OSystem::kFeatureFullscreenMode) : + ConfMan.getBool("fullscreen", _domain); + _fullscreenCheckbox->setState(state); // Aspect ratio setting - _aspectCheckbox->setState(ConfMan.getBool("aspect_ratio", _domain)); + state = _isActiveDomain ? + g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection) : + ConfMan.getBool("aspect_ratio", _domain); + _aspectCheckbox->setState(state); #endif } @@ -140,59 +183,55 @@ void OptionsDialog::open() { } } -void OptionsDialog::close() { - if (getResult()) { - if (_fullscreenCheckbox) { - if (_enableGraphicSettings) { - ConfMan.set("fullscreen", _fullscreenCheckbox->getState(), _domain); - ConfMan.set("aspect_ratio", _aspectCheckbox->getState(), _domain); - - if ((int32)_gfxPopUp->getSelectedTag() >= 0) - ConfMan.set("gfx_mode", _gfxPopUp->getSelectedString(), _domain); - } else { - ConfMan.removeKey("fullscreen", _domain); - ConfMan.removeKey("aspect_ratio", _domain); - ConfMan.removeKey("gfx_mode", _domain); - } +void OptionsDialog::saveSettings() { + if (_fullscreenCheckbox) { + if (_enableGraphicSettings) { + ConfMan.set("fullscreen", _fullscreenCheckbox->getState(), _domain); + ConfMan.set("aspect_ratio", _aspectCheckbox->getState(), _domain); + + if ((int32)_gfxPopUp->getSelectedTag() >= 0) + ConfMan.set("gfx_mode", _gfxPopUp->getSelectedString(), _domain); + } else { + ConfMan.removeKey("fullscreen", _domain); + ConfMan.removeKey("aspect_ratio", _domain); + ConfMan.removeKey("gfx_mode", _domain); } + } - if (_masterVolumeSlider) { - if (_enableVolumeSettings) { - ConfMan.set("master_volume", _masterVolumeSlider->getValue(), _domain); - ConfMan.set("music_volume", _musicVolumeSlider->getValue(), _domain); - ConfMan.set("sfx_volume", _sfxVolumeSlider->getValue(), _domain); - } else { - ConfMan.removeKey("master_volume", _domain); - ConfMan.removeKey("music_volume", _domain); - ConfMan.removeKey("sfx_volume", _domain); - } + if (_masterVolumeSlider) { + if (_enableVolumeSettings) { + ConfMan.set("master_volume", _masterVolumeSlider->getValue(), _domain); + ConfMan.set("music_volume", _musicVolumeSlider->getValue(), _domain); + ConfMan.set("sfx_volume", _sfxVolumeSlider->getValue(), _domain); + } else { + ConfMan.removeKey("master_volume", _domain); + ConfMan.removeKey("music_volume", _domain); + ConfMan.removeKey("sfx_volume", _domain); } + } - if (_multiMidiCheckbox) { - if (_enableAudioSettings) { - ConfMan.set("multi_midi", _multiMidiCheckbox->getState(), _domain); - ConfMan.set("native_mt32", _mt32Checkbox->getState(), _domain); - ConfMan.set("subtitles", _subCheckbox->getState(), _domain); - const MidiDriverDescription *md = getAvailableMidiDrivers(); - while (md->name && md->id != (int)_midiPopUp->getSelectedTag()) - md++; - if (md->name) - ConfMan.set("music_driver", md->name, _domain); - else - ConfMan.removeKey("music_driver", _domain); - } else { - ConfMan.removeKey("multi_midi", _domain); - ConfMan.removeKey("native_mt32", _domain); + if (_multiMidiCheckbox) { + if (_enableAudioSettings) { + ConfMan.set("multi_midi", _multiMidiCheckbox->getState(), _domain); + ConfMan.set("native_mt32", _mt32Checkbox->getState(), _domain); + ConfMan.set("subtitles", _subCheckbox->getState(), _domain); + const MidiDriverDescription *md = getAvailableMidiDrivers(); + while (md->name && md->id != (int)_midiPopUp->getSelectedTag()) + md++; + if (md->name) + ConfMan.set("music_driver", md->name, _domain); + else ConfMan.removeKey("music_driver", _domain); - ConfMan.removeKey("subtitles", _domain); - } + } else { + ConfMan.removeKey("multi_midi", _domain); + ConfMan.removeKey("native_mt32", _domain); + ConfMan.removeKey("music_driver", _domain); + ConfMan.removeKey("subtitles", _domain); } - - // Save config file - ConfMan.flushToDisk(); } - Dialog::close(); + // Save config file + ConfMan.flushToDisk(); } void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { @@ -209,10 +248,14 @@ void OptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data _sfxVolumeLabel->setValue(_sfxVolumeSlider->getValue()); _sfxVolumeLabel->draw(); break; - case kOKCmd: - setResult(1); + case kApplyCmd: + case kSaveCmd: + setResult(cmd); close(); break; + case kRevertCmd: + // TODO: Implement this! + break; default: Dialog::handleCommand(sender, cmd, data); } @@ -344,7 +387,7 @@ int OptionsDialog::addVolumeControls(GuiObject *boss, int yoffset) { GlobalOptionsDialog::GlobalOptionsDialog(GameDetector &detector) - : OptionsDialog(Common::ConfigManager::kApplicationDomain, 10, 20, 320 - 2 * 10, 200 - 2 * 20) { + : OptionsDialog(Common::ConfigManager::kApplicationDomain, 10, 10, 320 - 2 * 10, 200 - 2 * 10) { const int vBorder = 5; int yoffset; @@ -388,19 +431,30 @@ GlobalOptionsDialog::GlobalOptionsDialog(GameDetector &detector) tab->setActiveTab(0); // Add OK & Cancel buttons - addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0); - addButton(_w - (kButtonWidth + 10), _h - 24, "OK", kOKCmd, 0); + addButton(10, _h - 24, "Revert", kRevertCmd, 0); + addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "Save", kSaveCmd, 0); + addButton(_w - (kButtonWidth + 10), _h - 24, "Apply", kApplyCmd, 0); // Create file browser dialog _browser = new BrowserDialog("Select directory for savegames"); + + setGraphicSettingsState(true); + setAudioSettingsState(true); + setVolumeSettingsState(true); } GlobalOptionsDialog::~GlobalOptionsDialog() { delete _browser; } -void GlobalOptionsDialog::open() { - OptionsDialog::open(); +void GlobalOptionsDialog::applySettings() { + OptionsDialog::applySettings(); + + // TODO ? +} + +void GlobalOptionsDialog::loadSettings() { + OptionsDialog::loadSettings(); #if !( defined(__DC__) || defined(__GP32__) ) // Set _savePath to the current save path @@ -416,12 +470,11 @@ void GlobalOptionsDialog::open() { #endif } -void GlobalOptionsDialog::close() { - if (getResult()) { - // Savepath - ConfMan.set("savepath", _savePath->getLabel(), _domain); - } - OptionsDialog::close(); +void GlobalOptionsDialog::saveSettings() { + // Savepath + ConfMan.set("savepath", _savePath->getLabel(), _domain); + + OptionsDialog::saveSettings(); } void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { diff --git a/gui/options.h b/gui/options.h index 9f6c6bf852..0196bad21d 100644 --- a/gui/options.h +++ b/gui/options.h @@ -42,15 +42,20 @@ public: void open(); void close(); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + void handleScreenChanged(); enum { - kOKCmd = 'ok ' + kApplyCmd = 'aply', + kSaveCmd = 'save', + kRevertCmd = 'rvrt' }; protected: /** Config domain this dialog is used to edit. */ String _domain; + const bool _isActiveDomain; + int addGraphicControls(GuiObject *boss, int yoffset); int addMIDIControls(GuiObject *boss, int yoffset); int addVolumeControls(GuiObject *boss, int yoffset); @@ -58,6 +63,10 @@ protected: void setGraphicSettingsState(bool enabled); void setAudioSettingsState(bool enabled); void setVolumeSettingsState(bool enabled); + + virtual void applySettings(); + virtual void loadSettings(); + virtual void saveSettings(); private: // @@ -99,13 +108,15 @@ public: GlobalOptionsDialog(GameDetector &detector); ~GlobalOptionsDialog(); - void open(); - void close(); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); protected: BrowserDialog *_browser; StaticTextWidget *_savePath; + + virtual void applySettings(); + virtual void loadSettings(); + virtual void saveSettings(); }; } // End of namespace GUI diff --git a/scumm/actor.cpp b/scumm/actor.cpp index cc21a49577..6523f67916 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -1147,9 +1147,7 @@ int ScummEngine::getActorFromPos(int x, int y) { void ScummEngine::actorTalk() { Actor *a; - _msgPtrToAdd = _charsetBuffer; - _messagePtr = addMessageToStack(_messagePtr); - assert((int)(_msgPtrToAdd - _charsetBuffer) < (int)(sizeof(_charsetBuffer))); + _messagePtr = addMessageToStack(_messagePtr, _charsetBuffer, sizeof(_charsetBuffer)); // FIXME: Workaround for bugs #770039 and #770049 if (_gameId == GID_LOOM || _gameId == GID_LOOM256) { diff --git a/scumm/dialogs.cpp b/scumm/dialogs.cpp index ce7884eb48..a0992ee8c0 100644 --- a/scumm/dialogs.cpp +++ b/scumm/dialogs.cpp @@ -395,10 +395,6 @@ void MainMenuDialog::load() { #pragma mark - enum { - kOKCmd = 'ok ' -}; - -enum { kKeysCmd = 'KEYS' }; @@ -413,12 +409,14 @@ ConfigDialog::ConfigDialog(ScummEngine *scumm) // Add the buttons // #ifdef _WIN32_WCE - addButton(_w - kButtonWidth - 8, _h - 24 - 4, "OK", GUI::OptionsDialog::kOKCmd, 'O'); - addButton(_w - 2 * kButtonWidth - 12, _h - 24 - 4, "Cancel", kCloseCmd, 'C'); - addButton(_w - 3 * kButtonWidth - 16, _h - 24 - 4, "Keys", kKeysCmd, 'K'); + addButton(_w - kButtonWidth - 8, _h - 24 - 4, "Save", GUI::OptionsDialog::kSaveCmd, 'S'); + addButton(_w - 2 * kButtonWidth - 12, _h - 24 - 4, "Apply", GUI::OptionsDialog::kApplyCmd, 'A'); + addButton(_w - 3 * kButtonWidth - 16, _h - 24 - 4, "Revert", GUI::OptionsDialog::kRevertCmd, 'R'); + addButton(_w - 4 * kButtonWidth - 16, _h - 24 - 4, "Keys", kKeysCmd, 'K'); #else - addButton(_w - kButtonWidth-8, _h - 24, "OK", GUI::OptionsDialog::kOKCmd, 'O'); - addButton(_w - 2 * kButtonWidth-12, _h - 24, "Cancel", kCloseCmd, 'C'); + addButton(_w - kButtonWidth - 8, _h - 24, "Save", GUI::OptionsDialog::kSaveCmd, 'S'); + addButton(_w - 2 * kButtonWidth - 12, _h - 24, "Apply", GUI::OptionsDialog::kApplyCmd, 'A'); + addButton(_w - 3 * kButtonWidth - 16, _h - 24, "Revert", GUI::OptionsDialog::kRevertCmd, 'R'); #endif // @@ -446,24 +444,8 @@ ConfigDialog::~ConfigDialog() { #endif } -void ConfigDialog::open() { - GUI_OptionsDialog::open(); - - // update checkboxes, too - subtitlesCheckbox->setState(ConfMan.getBool("subtitles")); -} - -void ConfigDialog::close() { - - if (getResult()) { - // Subtitles - ConfMan.set("subtitles", subtitlesCheckbox->getState(), _domain); - // Sync with current setting - if (_vm->_version >= 7) - _vm->VAR(_vm->VAR_VOICE_MODE) = subtitlesCheckbox->getState(); - } - - GUI_OptionsDialog::close(); +void ConfigDialog::applySettings() { + ConfigDialog::applySettings(); // Sync the engine with the config manager int soundVolumeMaster = ConfMan.getInt("master_volume"); @@ -479,8 +461,25 @@ void ConfigDialog::close() { _vm->_mixer->setVolume(soundVolumeSfx * soundVolumeMaster / 255); _vm->_mixer->setMusicVolume(soundVolumeMusic); + + // Sync with current setting + if (_vm->_version >= 7) + _vm->VAR(_vm->VAR_VOICE_MODE) = ConfMan.getBool("subtitles"); } +void ConfigDialog::loadSettings() { + GUI_OptionsDialog::loadSettings(); + + // Update subtitles checkbox + subtitlesCheckbox->setState(ConfMan.getBool("subtitles")); +} + +void ConfigDialog::saveSettings() { + // Subtitles + ConfMan.set("subtitles", subtitlesCheckbox->getState(), _domain); + + GUI_OptionsDialog::saveSettings(); +} void ConfigDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { diff --git a/scumm/dialogs.h b/scumm/dialogs.h index 54a260b621..2531f17c7a 100644 --- a/scumm/dialogs.h +++ b/scumm/dialogs.h @@ -112,12 +112,15 @@ public: ConfigDialog(ScummEngine *scumm); ~ConfigDialog(); - virtual void open(); - virtual void close(); virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); protected: GUI::CheckboxWidget *subtitlesCheckbox; + + + virtual void applySettings(); + virtual void loadSettings(); + virtual void saveSettings(); }; class InfoDialog : public ScummDialog { diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index b036184701..42f00c92c5 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -2508,8 +2508,8 @@ void ScummEngine_v6::o6_kernelSetFunctions() { const byte *message; byte buf_input[300], buf_output[300]; _messagePtr = getStringAddressVar(VAR_STRING2DRAW); - message = _msgPtrToAdd = buf_input; - addMessageToStack(_messagePtr); + message = buf_input; + addMessageToStack(_messagePtr, buf_input, sizeof(buf_input)); if ((_gameId == GID_DIG) && !(_features & GF_DEMO)) { byte buf_trans[300]; char *t_ptr = (char *)buf_input; diff --git a/scumm/script_v6he.cpp b/scumm/script_v6he.cpp index 9a853d072e..e006b05721 100644 --- a/scumm/script_v6he.cpp +++ b/scumm/script_v6he.cpp @@ -955,9 +955,8 @@ void ScummEngine_v6he::o6_openFile() { int mode, len, slot, l, r; byte filename[100]; - _msgPtrToAdd = filename; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename, sizeof(filename)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; @@ -1003,9 +1002,8 @@ void ScummEngine_v6he::o6_deleteFile() { int len, r; byte filename[100]; - _msgPtrToAdd = filename; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename, sizeof(filename)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; @@ -1022,9 +1020,8 @@ void ScummEngine_v6he::o6_rename() { int len, r1, r2; byte filename[100],filename2[100]; - _msgPtrToAdd = filename; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename, sizeof(filename)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; @@ -1034,9 +1031,8 @@ void ScummEngine_v6he::o6_rename() { break; } - _msgPtrToAdd = filename2; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename2, sizeof(filename2)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; @@ -1344,25 +1340,22 @@ void ScummEngine_v6he::o6_unknownF4() { switch (b) { case 1: - _msgPtrToAdd = filename1; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename1, sizeof(filename1)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; debug(1, "o6_unknownF4(%d, %d, \"%s\")", a, b, _messagePtr); break; case 2: - _msgPtrToAdd = filename1; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename1, sizeof(filename1)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; - _msgPtrToAdd = filename2; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename2, sizeof(filename2)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; @@ -1378,9 +1371,8 @@ void ScummEngine_v6he::o6_unknownF9() { int len, r; byte filename[100]; - _msgPtrToAdd = filename; _messagePtr = _scriptPointer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, filename, sizeof(filename)); len = resStrLen(_scriptPointer); _scriptPointer += len + 1; diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 6096b64cc3..29d49a0213 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -531,8 +531,7 @@ void ScummEngine_v8::decodeParseString(int m, int n) { break; case 5:{ byte buffer[256]; - _msgPtrToAdd = buffer; - addMessageToStack(_messagePtr); + addMessageToStack(_messagePtr, buffer, sizeof(buffer)); enqueueText(buffer, _string[m].xpos, _string[m].ypos, _string[m].color, _string[m].charset, _string[m].center); } break; diff --git a/scumm/scumm.h b/scumm/scumm.h index 34b9183bc3..6a6facc48f 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -1064,7 +1064,7 @@ protected: void CHARSET_1(); void drawString(int a); - const byte *addMessageToStack(const byte *msg); + const byte *addMessageToStack(const byte *msg, byte *dstBuffer, int dstBufferSize); void addIntToStack(int var); void addVerbToStack(int var); void addNameToStack(int var); diff --git a/scumm/string.cpp b/scumm/string.cpp index 88a76c8b01..16115a43fe 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -48,8 +48,7 @@ void ScummEngine::setStringVars(int slot) { void ScummEngine::unkMessage1() { byte buffer[100]; - _msgPtrToAdd = buffer; - _messagePtr = addMessageToStack(_messagePtr); + _messagePtr = addMessageToStack(_messagePtr, buffer, sizeof(buffer)); // if ((_gameId == GID_CMI) && _debugMode) { // In CMI, unkMessage1 is used for printDebug output if ((buffer[0] != 0xFF) && _debugMode) { @@ -78,8 +77,7 @@ void ScummEngine::unkMessage2() { byte buf[100]; const byte *tmp; - _msgPtrToAdd = buf; - tmp = _messagePtr = addMessageToStack(_messagePtr); + tmp = _messagePtr = addMessageToStack(_messagePtr, buf, sizeof(buf)); if (_string[3].color == 0) _string[3].color = 4; @@ -348,8 +346,7 @@ void ScummEngine::drawString(int a) { byte fontHeight = 0; uint color; - _msgPtrToAdd = buf; - _messagePtr = addMessageToStack(_messagePtr); + _messagePtr = addMessageToStack(_messagePtr, buf, sizeof(buf)); _charset->_top = _string[a].ypos + _screenTop; _charset->_startLeft = _charset->_left = _string[a].xpos; @@ -366,18 +363,18 @@ void ScummEngine::drawString(int a) { fontHeight = _charset->getFontHeight(); - _msgPtrToAdd = buf; // trim from the right + byte *tmp = buf; space = NULL; - while (*_msgPtrToAdd) { - if (*_msgPtrToAdd == ' ') { + while (*tmp) { + if (*tmp == ' ') { if (!space) - space = _msgPtrToAdd; + space = tmp; } else { space = NULL; } - _msgPtrToAdd++; + tmp++; } if (space) *space = '\0'; @@ -472,12 +469,16 @@ void ScummEngine::drawString(int a) { } } -const byte *ScummEngine::addMessageToStack(const byte *msg) { +const byte *ScummEngine::addMessageToStack(const byte *msg, byte *dstBuffer, int dstBufferSize) { uint num = 0; uint32 val; byte chr; byte buf[512]; + if (dstBuffer) { + _msgPtrToAdd = dstBuffer; + } + if (msg == NULL) { warning("Bad message in addMessageToStack, ignoring"); return NULL; @@ -563,6 +564,12 @@ const byte *ScummEngine::addMessageToStack(const byte *msg) { } *_msgPtrToAdd = 0; + if (dstBuffer) { + // Check for a buffer overflow + if (_msgPtrToAdd >= dstBuffer + dstBufferSize) + error("addMessageToStack: buffer overflow!"); + } + return msg; } @@ -582,7 +589,7 @@ void ScummEngine::addVerbToStack(int var) { if (num == _verbs[k].verbid && !_verbs[k].type && !_verbs[k].saveid) { const byte *ptr = getResourceAddress(rtVerb, k); ptr = translateTextAndPlaySpeech(ptr); - addMessageToStack(ptr); + addMessageToStack(ptr, 0, 0); break; } } @@ -599,9 +606,9 @@ void ScummEngine::addNameToStack(int var) { if (ptr) { if ((_version == 8) && (ptr[0] == '/')) { translateText(ptr, _transText); - addMessageToStack(_transText); + addMessageToStack(_transText, 0, 0); } else { - addMessageToStack(ptr); + addMessageToStack(ptr, 0, 0); } } } @@ -617,9 +624,9 @@ void ScummEngine::addStringToStack(int var) { if (ptr) { if ((_version == 8) && (ptr[0] == '/')) { translateText(ptr, _transText); - addMessageToStack(_transText); + addMessageToStack(_transText, 0, 0); } else { - addMessageToStack(ptr); + addMessageToStack(ptr, 0, 0); } } } @@ -728,6 +735,7 @@ int indexCompare(const void *p1, const void *p2) { return strcmp(i1->tag, i2->tag); } +// Create an index of the language file. void ScummEngine::loadLanguageBundle() { File file; int32 size; @@ -751,23 +759,16 @@ void ScummEngine::loadLanguageBundle() { file.read(_languageBuffer, size); file.close(); - // Create an index of the language file. - // FIXME: Extend this mechanism to also cover The Dig? - int32 i; char *ptr = _languageBuffer; // Count the number of lines in the language file. - - _languageIndexSize = 0; - - for (;;) { + for (_languageIndexSize = 0; ; _languageIndexSize++) { ptr = strpbrk(ptr, "\n\r"); if (ptr == NULL) break; while (*ptr == '\n' || *ptr == '\r') ptr++; - _languageIndexSize++; } // Fill the language file index. This is just an array of |