aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--common/system.h8
-rw-r--r--gui/launcher.cpp48
-rw-r--r--gui/options.cpp179
-rw-r--r--gui/options.h17
-rw-r--r--scumm/actor.cpp4
-rw-r--r--scumm/dialogs.cpp53
-rw-r--r--scumm/dialogs.h7
-rw-r--r--scumm/script_v6.cpp4
-rw-r--r--scumm/script_v6he.cpp24
-rw-r--r--scumm/script_v8.cpp3
-rw-r--r--scumm/scumm.h2
-rw-r--r--scumm/string.cpp51
13 files changed, 234 insertions, 168 deletions
diff --git a/Makefile b/Makefile
index b4cd1962d1..b80b0b774c 100644
--- a/Makefile
+++ b/Makefile
@@ -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