From 1e9d51c28a67837fee2249ab9f38a6657dce6f9f Mon Sep 17 00:00:00 2001 From: AndywinXp Date: Sat, 18 Jun 2022 20:38:48 +0200 Subject: [PATCH] SCUMM: COMI: Implement the original main menu Every functionality has been implemented (audio options, text options, saving and loading). The only thing currently missing from the menu is the thumbnail handling. --- engines/scumm/imuse_digi/dimuse_cmds.cpp | 3 +- engines/scumm/imuse_digi/dimuse_engine.cpp | 75 +++++++++++++++++----- engines/scumm/imuse_digi/dimuse_engine.h | 3 + engines/scumm/input.cpp | 31 ++++++--- engines/scumm/saveload.cpp | 61 ++++++++++++++++++ engines/scumm/script_v8.cpp | 53 +++++++++++---- engines/scumm/scumm.cpp | 30 ++++++++- engines/scumm/scumm.h | 5 ++ engines/scumm/vars.cpp | 3 + 9 files changed, 224 insertions(+), 40 deletions(-) diff --git a/engines/scumm/imuse_digi/dimuse_cmds.cpp b/engines/scumm/imuse_digi/dimuse_cmds.cpp index 8da2bd45219..034b1d31b6a 100644 --- a/engines/scumm/imuse_digi/dimuse_cmds.cpp +++ b/engines/scumm/imuse_digi/dimuse_cmds.cpp @@ -49,8 +49,7 @@ int IMuseDigital::cmdsHandleCmd(int cmd, uint8 *ptr, int a, int b, int c, int d, case 4: return cmdsResume(); case 7: - _groupsHandler->setGroupVol(a, b); - break; + return _groupsHandler->setGroupVol(a, b); case 8: cmdsStartSound(a, b); break; diff --git a/engines/scumm/imuse_digi/dimuse_engine.cpp b/engines/scumm/imuse_digi/dimuse_engine.cpp index d59dad6264e..533b9673dc6 100644 --- a/engines/scumm/imuse_digi/dimuse_engine.cpp +++ b/engines/scumm/imuse_digi/dimuse_engine.cpp @@ -315,6 +315,12 @@ void IMuseDigital::saveLoadEarly(Common::Serializer &s) { _curMusicCue = 0; } else { diMUSESaveLoad(s); + + if (s.isLoading() && _vm->isUsingOriginalGUI()) { + diMUSESetMusicGroupVol(diMUSEGetMusicGroupVol()); + diMUSESetVoiceGroupVol(diMUSEGetVoiceGroupVol()); + diMUSESetSFXGroupVol(diMUSEGetSFXGroupVol()); + } } } @@ -359,21 +365,23 @@ void IMuseDigital::diMUSEHeartbeat() { waveOutCallback(); - // Update volumes + if (!_vm->isUsingOriginalGUI()) { + // Update volumes - if (_curMixerMusicVolume != _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)) { - _curMixerMusicVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); - diMUSESetMusicGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2, 0, 127)); - } + if (_curMixerMusicVolume != _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType)) { + _curMixerMusicVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType); + diMUSESetMusicGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2, 0, 127)); + } - if (_curMixerSpeechVolume != _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType)) { - _curMixerSpeechVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType); - diMUSESetVoiceGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2, 0, 127)); - } + if (_curMixerSpeechVolume != _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType)) { + _curMixerSpeechVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType); + diMUSESetVoiceGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2, 0, 127)); + } - if (_curMixerSFXVolume != _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType)) { - _curMixerSFXVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType); - diMUSESetSFXGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2, 0, 127)); + if (_curMixerSFXVolume != _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType)) { + _curMixerSFXVolume = _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType); + diMUSESetSFXGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2, 0, 127)); + } } // Handle fades and triggers @@ -659,6 +667,7 @@ void IMuseDigital::parseScriptCmds(int cmd, int soundId, int sub_cmd, int d, int int b = soundId; int c = sub_cmd; int id; + int volume = b; switch (cmd) { case 0x1000: // SetState @@ -678,15 +687,27 @@ void IMuseDigital::parseScriptCmds(int cmd, int soundId, int sub_cmd, int d, int break; case 0x2000: // SetGroupSfxVolume - diMUSESetSFXGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2, 0, 127)); + if (!_vm->isUsingOriginalGUI()) { + volume = CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2, 0, 127); + } + + diMUSESetSFXGroupVol(volume); break; case 0x2001: // SetGroupVoiceVolume - diMUSESetVoiceGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2, 0, 127)); + if (!_vm->isUsingOriginalGUI()) { + volume = CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2, 0, 127); + } + + diMUSESetVoiceGroupVol(volume); break; case 0x2002: // SetGroupMusicVolume - diMUSESetMusicGroupVol(CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2, 0, 127)); + if (!_vm->isUsingOriginalGUI()) { + volume = CLIP(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2, 0, 127); + } + + diMUSESetMusicGroupVol(volume); break; case 10: // StopAllSounds case 12: // SetParam @@ -813,6 +834,30 @@ int IMuseDigital::diMUSELipSync(int soundId, int syncId, int msPos, int32 &width return waveLipSync(soundId, syncId, msPos, width, height); } +int IMuseDigital::diMUSEGetMusicGroupVol() { + if (_vm->isUsingOriginalGUI()) { + return diMUSESetGroupVol(DIMUSE_GROUP_MUSIC, -1); + } + + return _mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2; +} + +int IMuseDigital::diMUSEGetSFXGroupVol() { + if (_vm->isUsingOriginalGUI()) { + return diMUSESetGroupVol(DIMUSE_GROUP_SFX, -1); + } + + return _mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2; +} + +int IMuseDigital::diMUSEGetVoiceGroupVol() { + if (_vm->isUsingOriginalGUI()) { + return diMUSESetGroupVol(DIMUSE_GROUP_SPEECH, -1); + } + + return _mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2; +} + int IMuseDigital::diMUSESetMusicGroupVol(int volume) { debug(5, "IMuseDigital::diMUSESetMusicGroupVol(): %d", volume); if (_isEarlyDiMUSE) diff --git a/engines/scumm/imuse_digi/dimuse_engine.h b/engines/scumm/imuse_digi/dimuse_engine.h index 23e6931537a..36247ce7717 100644 --- a/engines/scumm/imuse_digi/dimuse_engine.h +++ b/engines/scumm/imuse_digi/dimuse_engine.h @@ -373,6 +373,9 @@ public: void diMUSEQueryStream(int soundId, int32 &bufSize, int32 &criticalSize, int32 &freeSpace, int &paused); int diMUSEFeedStream(int soundId, uint8 *srcBuf, int32 sizeToFeed, int paused); int diMUSELipSync(int soundId, int syncId, int msPos, int32 &width, int32 &height); + int diMUSEGetMusicGroupVol(); + int diMUSEGetSFXGroupVol(); + int diMUSEGetVoiceGroupVol(); int diMUSESetMusicGroupVol(int volume); int diMUSESetSFXGroupVol(int volume); int diMUSESetVoiceGroupVol(int volume); diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 6330fe04a1c..788c957876c 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -377,13 +377,25 @@ void ScummEngine::processInput() { #ifdef ENABLE_SCUMM_7_8 void ScummEngine_v8::processKeyboard(Common::KeyState lastKeyHit) { - // F1 (the trigger for the original save/load dialog) is mapped to F5 + // F1 (the trigger for the original save/load dialog) is mapped to F5, + // unless we chose to use the original GUI if (!(_game.features & GF_DEMO) && lastKeyHit.keycode == Common::KEYCODE_F1 && lastKeyHit.hasFlags(0)) { - lastKeyHit = Common::KeyState(Common::KEYCODE_F5, 319); + if (isUsingOriginalGUI()) { + lastKeyHit = Common::KeyState(Common::KEYCODE_F1, 315); + } else { + lastKeyHit = Common::KeyState(Common::KEYCODE_F5, 319); + } + } - // Alt-F5 should bring up the original save/load dialog, so map it to F1. - if (!(_game.features & GF_DEMO) && lastKeyHit.keycode == Common::KEYCODE_F5 && lastKeyHit.hasFlags(Common::KBD_ALT)) { + // If we are using the original GUI, remap F5 to F1 + if (isUsingOriginalGUI() && !(_game.features & GF_DEMO) && lastKeyHit.keycode == Common::KEYCODE_F5 && lastKeyHit.hasFlags(0)) { + lastKeyHit = Common::KeyState(Common::KEYCODE_F1, 315); + } + + // Alt-F5 should bring up the original save/load dialog, so map it to F1, + // again, unless we chose to use the original GUI + if (!isUsingOriginalGUI() && !(_game.features & GF_DEMO) && lastKeyHit.keycode == Common::KEYCODE_F5 && lastKeyHit.hasFlags(Common::KBD_ALT)) { lastKeyHit = Common::KeyState(Common::KEYCODE_F1, 315); } @@ -668,9 +680,8 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) { // Map arrow keys to number keys in the SEGA version of MI to support // scrolling to conversation choices. See bug report #2013 for details. _mouseAndKeyboardStat = lastKeyHit.keycode - Common::KEYCODE_UP + 54; - } else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) { - // Map arrow keys to number keys in the PCEngine version of Loom to support - // the menu screen. + } else if (isUsingOriginalGUI() || (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine)) { + // Map arrow keys to number keys in games which use the original menu screen. switch (lastKeyHit.keycode) { case Common::KEYCODE_UP: _mouseAndKeyboardStat = 328; @@ -697,7 +708,11 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) { } } else { - _mouseAndKeyboardStat = lastKeyHit.ascii; + // Map the DEL key when using the original GUI; used when writing the savegame name. + if (isUsingOriginalGUI() && lastKeyHit.keycode == Common::KEYCODE_DELETE) + _mouseAndKeyboardStat = 339; + else + _mouseAndKeyboardStat = lastKeyHit.ascii; } } diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 47bd5f5d887..274794620f1 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -156,6 +156,54 @@ void ScummEngine::requestLoad(int slot) { _saveLoadFlag = 2; // 2 for load } +void ScummEngine::copyHeapSaveGameToFile(int slot, const char *saveName) { + Common::String fileName; + SaveGameHeader hdr; + bool saveFailed = false; + uint32 heapFileSize; + + Common::SeekableReadStream *heapSaveFile = openSaveFileForReading(1, true, fileName); + hdr.type = heapSaveFile->readUint32BE(); + hdr.size = heapSaveFile->readUint32LE(); + hdr.ver = heapSaveFile->readUint32LE(); + heapSaveFile->read(hdr.name, sizeof(hdr.name)); + Common::strlcpy(hdr.name, saveName, sizeof(hdr.name)); + + heapFileSize = (uint32)heapSaveFile->size(); + if (heapSaveFile->err() || hdr.type != MKTAG('S','C','V','M')) { + saveFailed = true; + } else { + Common::WriteStream *saveFile = openSaveFileForWriting(slot, false, fileName); + if (!saveFile) { + saveFailed = true; + } else { + saveFile->writeUint32BE(hdr.type); + saveFile->writeUint32LE(hdr.size); + saveFile->writeUint32LE(hdr.ver); + saveFile->write(hdr.name, sizeof(hdr.name)); + + heapSaveFile->seek(sizeof(hdr), SEEK_SET); + while (!heapSaveFile->eos()) { + byte b = heapSaveFile->readByte(); + saveFile->writeByte(b); + } + + saveFile->finalize(); + if (saveFile->err()) + saveFailed = true; + + delete saveFile; + } + } + + if (saveFailed) + debug(1, "State save as '%s' FAILED", fileName.c_str()); + else + debug(1, "State saved as '%s'", fileName.c_str()); + + +} + Common::SeekableReadStream *ScummEngine::openSaveFileForReading(int slot, bool compat, Common::String &fileName) { fileName = makeSavegameName(slot, compat); return _saveFileMan->openForLoading(fileName); @@ -1653,6 +1701,19 @@ void ScummEngine_v7::saveLoadWithSerializer(Common::Serializer &s) { // WORKAROUND bug #3483: Reset the default charset color to a sane value. _string[0]._default.charset = 1; } + + // The original Save/Load screen for COMI saves a heap savegame when it is entered + // and the same heap savegame is restored when it is exited, so let's refresh these + // variables so that they are not lost. The original doesn't do this as it appears + // to handle these temporary heap savegames a little differently, but this should + // suffice... + if (isUsingOriginalGUI() && _game.version == 8) { + if (ConfMan.hasKey("original_gui_saveload_page", _targetName)) + VAR(VAR_SAVELOAD_PAGE) = ConfMan.getInt("original_gui_saveload_page"); + + if (ConfMan.hasKey("original_gui_object_labels", _targetName)) + VAR(VAR_OBJECT_LABEL_FLAG) = ConfMan.getInt("original_gui_object_labels"); + } } #endif diff --git a/engines/scumm/script_v8.cpp b/engines/scumm/script_v8.cpp index a46b40dcf2b..d200d5cf6ba 100644 --- a/engines/scumm/script_v8.cpp +++ b/engines/scumm/script_v8.cpp @@ -289,7 +289,7 @@ void ScummEngine_v8::writeVar(uint var, int value) { if (!(var & 0xF0000000)) { assertRange(0, var, _numVariables - 1, "variable (writing)"); - if (var == VAR_CHARINC) { + if (!isUsingOriginalGUI() && var == VAR_CHARINC) { // Did the user override the talkspeed manually? Then use that. // Otherwise, use the value specified by the game script. // Note: To determine whether there was a user override, we only @@ -1120,9 +1120,11 @@ void ScummEngine_v8::o8_kernelSetFunctions() { break; } case 26: { // saveGameWrite - // FIXME: This doesn't work - char *address = (char *)getStringAddress(args[2]); - debug(0, "o8_kernelSetFunctions: saveGame(%d, %s)", args[1], address); + char *saveName = (char *)getStringAddress(args[2]); + debug(0, "o8_kernelSetFunctions: saveGame(%d, %s)", args[1], saveName); + if (isUsingOriginalGUI()) { + copyHeapSaveGameToFile(args[1], saveName); + } break; } case 27: // saveGameRead @@ -1148,6 +1150,24 @@ void ScummEngine_v8::o8_kernelSetFunctions() { int idx = args[1]; int value = args[2]; const char *str = (const char *)getStringAddress(idx); + if (isUsingOriginalGUI()) { + if (!strcmp(str, "SFX Volume")) + ConfMan.setInt("sfx_volume", value * 2); + else if (!strcmp(str, "Voice Volume")) + ConfMan.setInt("speech_volume", value * 2); + else if (!strcmp(str, "Music Volume")) + ConfMan.setInt("music_volume", value * 2); + else if (!strcmp(str, "Text Status")) + ConfMan.setInt("original_gui_text_status", value); + else if (!strcmp(str, "Text Speed")) + ConfMan.setInt("original_gui_text_speed", value); + else if (!strcmp(str, "Object Names")) + ConfMan.setInt("original_gui_object_labels", value); + else if (!strcmp(str, "Saveload Page")) + ConfMan.setInt("original_gui_saveload_page", value); + + ConfMan.flushToDisk(); + } debugC(DEBUG_GENERAL,"o8_kernelSetFunctions: writeRegistryValue(%s, %d)", str, value); } @@ -1156,10 +1176,14 @@ void ScummEngine_v8::o8_kernelSetFunctions() { debug(0, "o8_kernelSetFunctions: paletteSetIntensity(%d, %d)", args[1], args[2]); break; case 34: // queryQuit - if (ConfMan.getBool("confirm_exit")) + if (isUsingOriginalGUI()) { confirmExitDialog(); - else - quitGame(); + } else { + if (ConfMan.getBool("confirm_exit")) + confirmExitDialog(); + else + quitGame(); + } break; case 108: // buildPaletteShadow setShadowPalette(args[1], args[2], args[3], args[4], args[5], args[6]); @@ -1234,13 +1258,13 @@ void ScummEngine_v8::o8_kernelGetFunctions() { } break; case 0xDD: // getGroupSfxVol - push(_mixer->getVolumeForSoundType(Audio::Mixer::kSFXSoundType) / 2); + push(_imuseDigital->diMUSEGetSFXGroupVol()); break; case 0xDE: // getGroupVoiceVol - push(_mixer->getVolumeForSoundType(Audio::Mixer::kSpeechSoundType) / 2); + push(_imuseDigital->diMUSEGetVoiceGroupVol()); break; case 0xDF: // getGroupMusicVol - push(_mixer->getVolumeForSoundType(Audio::Mixer::kMusicSoundType) / 2); + push(_imuseDigital->diMUSEGetMusicGroupVol()); break; case 0xE0: // readRegistryValue { @@ -1253,13 +1277,16 @@ void ScummEngine_v8::o8_kernelGetFunctions() { else if (!strcmp(str, "Music Volume")) push(ConfMan.getInt("music_volume") / 2); else if (!strcmp(str, "Text Status")) - push(ConfMan.getBool("subtitles")); + push(isUsingOriginalGUI() ? ConfMan.getInt("original_gui_text_status") : ConfMan.getBool("subtitles")); + else if (!strcmp(str, "Text Speed")) + push(ConfMan.getInt("original_gui_text_speed")); else if (!strcmp(str, "Object Names")) - push(ConfMan.getBool("object_labels")); + push(isUsingOriginalGUI() ? ConfMan.getInt("original_gui_object_labels") : ConfMan.getBool("object_labels")); else if (!strcmp(str, "Saveload Page")) - push(14); + push(ConfMan.getInt("original_gui_saveload_page")); else // Use defaults push(-1); + debugC(DEBUG_GENERAL,"o8_kernelGetFunctions: readRegistryValue(%s)", str); } break; diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 2f0f0444f95..386fd5963ca 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -2059,6 +2059,25 @@ void ScummEngine::setupMusic(int midi, const Common::String &macInstrumentFile) } void ScummEngine::syncSoundSettings() { + if (isUsingOriginalGUI() && _game.version == 8) { + _voiceMode = ConfMan.getInt("original_gui_text_status"); + + if (VAR_VOICE_MODE != 0xFF) + VAR(VAR_VOICE_MODE) = _voiceMode; + + if (ConfMan.hasKey("original_gui_text_speed", _targetName)) { + _defaultTalkDelay = ConfMan.getInt("original_gui_text_speed"); + + // In the original GUI the talk delay is represented as text speed, + // so we have to invert the value: + // - 9 is the highest text speed possible; + // - 0 is the lowest text speed possible. + if (VAR_CHARINC != 0xFF) + VAR(VAR_CHARINC) = 9 - _defaultTalkDelay; + } + return; + } + Engine::syncSoundSettings(); // Sync the engine with the config manager @@ -2534,7 +2553,7 @@ void ScummEngine::scummLoop_handleSaveLoad() { bool success; Common::U32String errMsg; - if (_game.version == 8 && _saveTemporaryState) + if (_game.version == 8 && (_saveTemporaryState || isUsingOriginalGUI())) VAR(VAR_GAME_LOADED) = 0; Common::String filename; @@ -2553,7 +2572,7 @@ void ScummEngine::scummLoop_handleSaveLoad() { if (!success) errMsg = _("Failed to load saved game from file:\n\n%s"); - if (success && _saveTemporaryState && VAR_GAME_LOADED != 0xFF) + if (success && (_saveTemporaryState || isUsingOriginalGUI()) && VAR_GAME_LOADED != 0xFF) VAR(VAR_GAME_LOADED) = (_game.version == 8) ? 1 : 203; } @@ -2945,6 +2964,13 @@ void ScummEngine::restart() { runBootscript(); } +bool ScummEngine::isUsingOriginalGUI() { + if (_game.version == 8) + return _useOriginalGUI; + + return false; +} + void ScummEngine::runBootscript() { int args[NUM_SCRIPT_LOCAL]; memset(args, 0, sizeof(args)); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 671f5a8b217..0d92b0586a2 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -386,6 +386,7 @@ public: ResourceManager *_res = nullptr; bool _enableEnhancements = false; + bool _useOriginalGUI = true; bool _enableAudioOverride = false; protected: @@ -482,6 +483,7 @@ protected: public: void pauseGame(); void restart(); + bool isUsingOriginalGUI(); protected: Dialog *_pauseDialog = nullptr; @@ -619,6 +621,7 @@ protected: void loadResource(Common::Serializer &ser, ResType type, ResId idx); void loadResourceOLD(Common::Serializer &ser, ResType type, ResId idx); // "Obsolete" + void copyHeapSaveGameToFile(int slot, const char *saveName); virtual Common::SeekableReadStream *openSaveFileForReading(int slot, bool compat, Common::String &fileName); virtual Common::WriteStream *openSaveFileForWriting(int slot, bool compat, Common::String &fileName); @@ -1443,6 +1446,8 @@ public: byte VAR_RIGHTBTN_HOLD = 0xFF; // V6/V72HE/V7/V8 byte VAR_SAVELOAD_SCRIPT = 0xFF; // V6/V7 (not HE) byte VAR_SAVELOAD_SCRIPT2 = 0xFF; // V6/V7 (not HE) + byte VAR_SAVELOAD_PAGE = 0xFF; // V8 + byte VAR_OBJECT_LABEL_FLAG = 0xFF; // V8 // V6/V7 specific variables (FT & Sam & Max specific) byte VAR_CHARSET_MASK = 0xFF; diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index e6244610bf7..66fca7a50ae 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -558,6 +558,9 @@ void ScummEngine_v8::setupScummVars() { VAR_KEYPRESS = 132; VAR_BLAST_ABOVE_TEXT = 133; VAR_SYNC = 134; + + VAR_SAVELOAD_PAGE = 175; + VAR_OBJECT_LABEL_FLAG = 176; } #endif