[Scummvm-git-logs] scummvm master -> 92b68a1132eb1272a70c62a266cc1e945eed3ff9
mgerhardy
martin.gerhardy at gmail.com
Tue Nov 3 17:31:44 UTC 2020
This automated email contains information about 26 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f68fbea3b5 TWINE: added return vales to music play methods
6569e84c8c TWINE: init audio cd
55ef559065 TWINE: use better sound type
b89a0ee053 TWINE: fallback to midi if audio cd isn't available
003160bab7 TWINE: missing missing null byte for playername string in savegame
7ba94d71af TWINE: started to implement save/load
8e926838be TWINE: minor cleanup
3257107fad TWINE: refactored menu data
42628c51be TWINE: return the button text - not just the id
2e5d3977c9 TWINE: reduced memory allocations
a41bf7b8ee TWINE: toggle virtual keyboard in player name menu
b2c114d73f TWINE: don't leave on empty name
f5d3e304ec TWINE: added enum for text banks
df8dc9f270 TWINE: replaced magic numbers
7fcf6917db TWINE: hide enum
0a3a634daf TWINE: moved scene text bank id into scene class
f560390f7e TWINE: implement load-savegame menu
d5e0874557 TWINE: reduced visibility
d3c2f7cd91 TWINE: added ScopedEngineFreeze
a7f3a63454 TWINE: reduced scoped + const
d66db9ad12 TWINE: started to implement holomap location loading
688e4a7349 TWINE: replaced magic number
0488fe67c4 TWINE: reduced cyclic complexity
3f6828a7a4 TWINE: allow to activate debug options via console
cf8e7339d0 TWINE: implemented drawText for debug window
92b68a1132 TWINE: cleanup in debug window
Commit: f68fbea3b509bbf4b227f2e512690ebd8478d61c
https://github.com/scummvm/scummvm/commit/f68fbea3b509bbf4b227f2e512690ebd8478d61c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:24:11+01:00
Commit Message:
TWINE: added return vales to music play methods
Changed paths:
engines/twine/music.cpp
engines/twine/music.h
engines/twine/twine.h
diff --git a/engines/twine/music.cpp b/engines/twine/music.cpp
index ab1b8f2541..3c00784655 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/music.cpp
@@ -121,12 +121,12 @@ void Music::musicFadeOut() {
musicVolume(volume);
}
-void Music::playTrackMusicCd(int32 track) {
+bool Music::playTrackMusicCd(int32 track) {
if (!_engine->cfgfile.UseCD) {
- return;
+ return false;
}
AudioCDManager *cdrom = g_system->getAudioCDManager();
- cdrom->play(track, 1, 0, 0);
+ return cdrom->play(track, 1, 0, 0);
}
void Music::stopTrackMusicCd() {
@@ -138,18 +138,18 @@ void Music::stopTrackMusicCd() {
cdrom->stop();
}
-void Music::playTrackMusic(int32 track) {
+bool Music::playTrackMusic(int32 track) {
if (!_engine->cfgfile.Sound) {
- return;
+ return false;
}
if (track == currentMusic) {
- return;
+ return true;
}
currentMusic = track;
stopMusic();
- playTrackMusicCd(track);
+ return playTrackMusicCd(track);
}
void Music::stopTrackMusic() {
@@ -161,13 +161,13 @@ void Music::stopTrackMusic() {
stopTrackMusicCd();
}
-void Music::playMidiMusic(int32 midiIdx, int32 loop) {
+bool Music::playMidiMusic(int32 midiIdx, int32 loop) {
if (!_engine->cfgfile.Sound || _engine->cfgfile.MidiType == MIDIFILE_NONE) {
- return;
+ return false;
}
if (midiIdx == currentMusic) {
- return;
+ return true;
}
stopMusic();
@@ -187,6 +187,7 @@ void Music::playMidiMusic(int32 midiIdx, int32 loop) {
int32 midiSize = HQR::getAllocEntry(&midiPtr, filename, midiIdx);
_midiPlayer.play(midiPtr, midiSize);
+ return true;
}
void Music::stopMidiMusic() {
diff --git a/engines/twine/music.h b/engines/twine/music.h
index 35efac4ea1..e7fb52049d 100644
--- a/engines/twine/music.h
+++ b/engines/twine/music.h
@@ -48,11 +48,11 @@ private:
/** Auxiliar midi pointer to */
uint8 *midiPtr = nullptr;
+ /** Track number of the current playing music */
+ int32 currentMusic = 0;
public:
Music(TwinEEngine *engine);
- /** Track number of the current playing music */
- int32 currentMusic = 0;
/**
* Music volume
@@ -63,21 +63,21 @@ public:
* Play CD music
* @param track track number to play
*/
- void playTrackMusicCd(int32 track);
+ bool playTrackMusicCd(int32 track);
/** Stop CD music */
void stopTrackMusicCd();
/**
* Generic play music, according with settings it plays CD or high quality sounds instead
* @param track track number to play
*/
- void playTrackMusic(int32 track);
+ bool playTrackMusic(int32 track);
/** Generic stop music according with settings */
void stopTrackMusic();
/**
* Play MIDI music
* @param midiIdx music index under mini_mi_win.hqr
*/
- void playMidiMusic(int32 midiIdx, int32 loop = 0);
+ bool playMidiMusic(int32 midiIdx, int32 loop = 0);
/** Stop MIDI music */
void stopMidiMusic();
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index b030001bc1..0cf6d18278 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -209,9 +209,6 @@ public:
* Contains all the data used in the engine to configurated the game in particulary ways. */
ConfigFile cfgfile;
- /** CD Game directory */
- const char *cdDir = "";
-
/** Initialize LBA engine */
void initEngine();
void initMCGA();
Commit: 6569e84c8c2837cce35db50ae4f84cad70bdfcaf
https://github.com/scummvm/scummvm/commit/6569e84c8c2837cce35db50ae4f84cad70bdfcaf
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:24:11+01:00
Commit Message:
TWINE: init audio cd
Changed paths:
engines/twine/music.cpp
diff --git a/engines/twine/music.cpp b/engines/twine/music.cpp
index 3c00784655..cf0c6154f4 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/music.cpp
@@ -204,17 +204,9 @@ bool Music::initCdrom() {
if (!_engine->cfgfile.Sound) {
return false;
}
-#if 0 // TODO: mgerhardy
AudioCDManager* cdrom = g_system->getAudioCDManager();
- if (cdrom->numtracks == NUM_CD_TRACKS) {
- _engine->cdDir = "LBA";
- _engine->cfgfile.UseCD = 1;
- return true;
- }
-#endif
- // not found the right CD
- _engine->cfgfile.UseCD = 0;
- return false;
+ _engine->cfgfile.UseCD = cdrom->open();
+ return _engine->cfgfile.UseCD;
}
void Music::stopMusic() {
Commit: 55ef55906536fd78a6e15a138778aa903a42656d
https://github.com/scummvm/scummvm/commit/55ef55906536fd78a6e15a138778aa903a42656d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:24:55+01:00
Commit Message:
TWINE: use better sound type
Changed paths:
engines/twine/sound.cpp
diff --git a/engines/twine/sound.cpp b/engines/twine/sound.cpp
index 9271c5f273..82a5de14d4 100644
--- a/engines/twine/sound.cpp
+++ b/engines/twine/sound.cpp
@@ -94,7 +94,7 @@ void Sound::playSample(int32 index, int32 frequency, int32 repeat, int32 x, int3
uint8 *sampPtr = _engine->_resources->samplesTable[index];
int32 sampSize = _engine->_resources->samplesSizeTable[index];
- playSample(channelIdx, index, sampPtr, sampSize, repeat, Resources::HQR_SAMPLES_FILE, Audio::Mixer::kPlainSoundType, DisposeAfterUse::NO);
+ playSample(channelIdx, index, sampPtr, sampSize, repeat, Resources::HQR_SAMPLES_FILE, Audio::Mixer::kSFXSoundType, DisposeAfterUse::NO);
}
void Sound::playVoxSample(int32 index) {
Commit: b89a0ee05311939a1da10befbaa73576192657a1
https://github.com/scummvm/scummvm/commit/b89a0ee05311939a1da10befbaa73576192657a1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:24:55+01:00
Commit Message:
TWINE: fallback to midi if audio cd isn't available
Changed paths:
engines/twine/hqr.cpp
engines/twine/music.cpp
engines/twine/music.h
engines/twine/scene.cpp
diff --git a/engines/twine/hqr.cpp b/engines/twine/hqr.cpp
index 2837c0883e..1bac915968 100644
--- a/engines/twine/hqr.cpp
+++ b/engines/twine/hqr.cpp
@@ -196,6 +196,10 @@ int32 numEntries(const char *filename) {
int32 getAllocEntry(uint8 **ptr, const char *filename, int32 index) {
const int32 size = entrySize(filename, index);
+ if (size == 0) {
+ warning("HQR: failed to get entry for index %i from file: %s", index, filename);
+ return 0;
+ }
*ptr = (uint8 *)malloc(size * sizeof(uint8));
if (!*ptr) {
warning("HQR: unable to allocate entry memory");
diff --git a/engines/twine/music.cpp b/engines/twine/music.cpp
index cf0c6154f4..5e58b44cb2 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/music.cpp
@@ -149,7 +149,14 @@ bool Music::playTrackMusic(int32 track) {
currentMusic = track;
stopMusic();
- return playTrackMusicCd(track);
+ if (playTrackMusicCd(track)) {
+ return true;
+ }
+ if (playMidiMusic(track)) {
+ return true;
+ }
+ warning("Failed to play track %i", track);
+ return false;
}
void Music::stopTrackMusic() {
@@ -186,7 +193,11 @@ bool Music::playMidiMusic(int32 midiIdx, int32 loop) {
}
int32 midiSize = HQR::getAllocEntry(&midiPtr, filename, midiIdx);
+ if (midiSize == 0) {
+ return false;
+ }
_midiPlayer.play(midiPtr, midiSize);
+ debug("Play midi music %i from %s", midiIdx, filename);
return true;
}
@@ -212,6 +223,7 @@ bool Music::initCdrom() {
void Music::stopMusic() {
stopTrackMusic();
stopMidiMusic();
+ currentMusic = -1;
}
} // namespace TwinE
diff --git a/engines/twine/music.h b/engines/twine/music.h
index e7fb52049d..e2733686f0 100644
--- a/engines/twine/music.h
+++ b/engines/twine/music.h
@@ -49,8 +49,14 @@ private:
/** Auxiliar midi pointer to */
uint8 *midiPtr = nullptr;
/** Track number of the current playing music */
- int32 currentMusic = 0;
-
+ int32 currentMusic = -1;
+ /**
+ * Play CD music
+ * @param track track number to play
+ */
+ bool playTrackMusicCd(int32 track);
+ /** Stop CD music */
+ void stopTrackMusicCd();
public:
Music(TwinEEngine *engine);
@@ -59,13 +65,7 @@ public:
* @param current volume number
*/
void musicVolume(int32 volume);
- /**
- * Play CD music
- * @param track track number to play
- */
- bool playTrackMusicCd(int32 track);
- /** Stop CD music */
- void stopTrackMusicCd();
+
/**
* Generic play music, according with settings it plays CD or high quality sounds instead
* @param track track number to play
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index 1bf160425d..6a0603bc1a 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -336,7 +336,7 @@ void Scene::changeScene() {
_engine->_renderer->setLightVector(alphaLight, betaLight, 0);
if (sceneMusic != -1) {
- _engine->_music->playMidiMusic(sceneMusic); // TODO this should play midi or cd tracks
+ _engine->_music->playTrackMusic(sceneMusic);
}
}
Commit: 003160bab702a3abcec3bcd743f19f4af58c77ac
https://github.com/scummvm/scummvm/commit/003160bab702a3abcec3bcd743f19f4af58c77ac
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:24:55+01:00
Commit Message:
TWINE: missing missing null byte for playername string in savegame
Changed paths:
engines/twine/gamestate.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 2f58233da7..5f4f5b847f 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -178,20 +178,19 @@ bool GameState::loadGame(Common::InSaveFile *file) {
int playerNameIdx = 0;
do {
const byte c = file->readByte();
+ playerName[playerNameIdx++] = c;
if (c == '\0') {
break;
}
- playerName[playerNameIdx++] = c;
if (playerNameIdx >= ARRAYSIZE(playerName)) {
- warning("Failed to load savegame");
+ warning("Failed to load savegame. Invalid playername.");
return false;
}
} while (true);
- playerName[playerNameIdx] = '\0';
byte numGameFlags = file->readByte();
if (numGameFlags != NUM_GAME_FLAGS) {
- warning("Failed to load gameflags");
+ warning("Failed to load gameflags. Expected %u, but got %u", NUM_GAME_FLAGS, numGameFlags);
return false;
}
file->read(gameFlags, numGameFlags);
@@ -242,6 +241,7 @@ bool GameState::saveGame(Common::OutSaveFile *file) {
file->writeByte(0x03);
file->writeString(playerName);
+ file->writeByte('\0');
file->writeByte(NUM_GAME_FLAGS);
file->write(gameFlags, sizeof(gameFlags));
file->writeByte(_engine->_scene->currentSceneIdx);
Commit: 7ba94d71afc0d8f4a1e37fea2e00782c4159fd95
https://github.com/scummvm/scummvm/commit/7ba94d71afc0d8f4a1e37fea2e00782c4159fd95
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: started to implement save/load
Changed paths:
engines/twine/gamestate.cpp
engines/twine/gamestate.h
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/menuoptions.cpp
engines/twine/menuoptions.h
engines/twine/metaengine.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 5f4f5b847f..ea820a73f4 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -168,7 +168,7 @@ void GameState::initEngineVars() {
_engine->_actor->previousHeroBehaviour = kNormal;
}
-bool GameState::loadGame(Common::InSaveFile *file) {
+bool GameState::loadGame(Common::SeekableReadStream *file) {
if (file == nullptr) {
return false;
}
@@ -235,9 +235,10 @@ bool GameState::loadGame(Common::InSaveFile *file) {
return true;
}
-bool GameState::saveGame(Common::OutSaveFile *file) {
- // TODO: the player name must be handled properly
- Common::strlcpy(playerName, "TwinEngineSave", sizeof(playerName));
+bool GameState::saveGame(Common::WriteStream *file) {
+ if (playerName[0] == '\0') {
+ Common::strlcpy(playerName, "TwinEngineSave", sizeof(playerName));
+ }
file->writeByte(0x03);
file->writeString(playerName);
diff --git a/engines/twine/gamestate.h b/engines/twine/gamestate.h
index 69c988fdcb..fe84dae1c4 100644
--- a/engines/twine/gamestate.h
+++ b/engines/twine/gamestate.h
@@ -139,8 +139,8 @@ public:
void processFoundItem(int32 item);
- bool loadGame(Common::InSaveFile *file);
- bool saveGame(Common::OutSaveFile *file);
+ bool loadGame(Common::SeekableReadStream *file);
+ bool saveGame(Common::WriteStream *file);
void processGameChoices(int32 choiceIdx);
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 1e45794b48..aa14d1bc0f 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -699,7 +699,7 @@ bool Menu::init() {
return HQR::getEntry(plasmaEffectPtr, Resources::HQR_RESS_FILE, RESSHQR_PLASMAEFFECT) > 0;
}
-void Menu::run() {
+EngineState Menu::run() {
_engine->_text->initTextBank(0);
_engine->_music->playTrackMusic(9); // LBA's Theme
@@ -707,31 +707,32 @@ void Menu::run() {
switch (processMenu(MainMenuState)) {
case TextId::kNewGame: {
- _engine->_menuOptions->newGameMenu();
+ if (_engine->_menuOptions->newGameMenu()) {
+ return EngineState::GameLoop;
+ }
break;
}
case TextId::kContinueGame: {
- _engine->_menuOptions->continueGameMenu();
+ if (_engine->_menuOptions->continueGameMenu()) {
+ return EngineState::LoadedGame;
+ }
break;
}
case TextId::kOptions: {
optionsMenu();
break;
}
- case TextId::kQuit: {
- Common::Event event;
- event.type = Common::EVENT_QUIT;
- _engine->_system->getEventManager()->pushEvent(event);
- break;
- }
case kBackground: {
_engine->_screens->loadMenuImage();
break;
}
+ case TextId::kQuit:
case kQuitEngine:
- return;
+ debug("quit the game");
+ return EngineState::QuitGame;
}
_engine->_system->delayMillis(1000 / _engine->cfgfile.Fps);
+ return EngineState::Menu;
}
int32 Menu::giveupMenu() {
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index f39e353a09..e467376e25 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -24,6 +24,7 @@
#define TWINE_MENU_H
#include "twine/actor.h"
+#include "twine/twine.h"
namespace TwinE {
@@ -190,7 +191,7 @@ public:
bool init();
/** Used to run the main menu */
- void run();
+ EngineState run();
/** Used to run the in-game give-up menu */
int32 giveupMenu();
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 3f409e42f9..1d3ce36013 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -21,7 +21,9 @@
*/
#include "twine/menuoptions.h"
+#include "common/error.h"
#include "common/keyboard.h"
+#include "common/str-array.h"
#include "common/system.h"
#include "common/util.h"
#include "twine/flamovies.h"
@@ -282,19 +284,18 @@ bool MenuOptions::enterPlayerName(int32 textIdx) {
return false;
}
-void MenuOptions::newGameMenu() {
- if (enterPlayerName(TextId::kEnterYourName)) {
- _engine->_gameState->initEngineVars();
- newGame();
-
- if (_engine->gameEngineLoop()) {
- showCredits();
- }
+bool MenuOptions::newGameMenu() {
+ if (!enterPlayerName(TextId::kEnterYourName)) {
+ return false;
}
+ _engine->_gameState->initEngineVars();
+ newGame();
+ return true;
}
int MenuOptions::chooseSave(int textIdx) {
- if (!_engine->hasSavedSlots()) {
+ const Common::StringArray& savegames = _engine->getSaveSlots();
+ if (savegames.empty()) {
return -1;
}
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
@@ -311,7 +312,7 @@ int MenuOptions::chooseSave(int textIdx) {
_engine->flip();
if (_engine->shouldQuit()) {
- break;
+ return kQuitEngine;
}
_engine->_system->delayMillis(1);
} while (_engine->_input->toggleAbortAction());
@@ -319,32 +320,13 @@ int MenuOptions::chooseSave(int textIdx) {
return 0;
}
-void MenuOptions::continueGameMenu() {
+bool MenuOptions::continueGameMenu() {
const int slot = chooseSave(TextId::kContinueGame);
if (slot >= 0) {
_engine->_gameState->initEngineVars();
- _engine->loadSaveSlot(slot);
- if (_engine->_scene->newHeroX == -1) {
- _engine->_scene->heroPositionType = ScenePositionType::kNoPosition;
- }
- if (_engine->_gameState->gameChapter == 0 && _engine->_scene->currentSceneIdx == LBA1SceneId::Citadel_Island_Prison) {
- newGame();
- } else {
- _engine->_text->newGameVar5 = 0;
- _engine->_text->textClipSmall();
- _engine->_text->newGameVar4 = 1;
- }
-
- if (_engine->gameEngineLoop()) {
- showCredits();
- }
-
- _engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- do {
- _engine->readKeys();
- _engine->_system->delayMillis(1);
- } while (!_engine->shouldQuit() && !_engine->_input->toggleAbortAction());
+ return _engine->loadGameState(slot).getCode() == Common::kNoError;
}
+ return false;
}
} // namespace TwinE
diff --git a/engines/twine/menuoptions.h b/engines/twine/menuoptions.h
index 78cb7e933e..f7e044eb80 100644
--- a/engines/twine/menuoptions.h
+++ b/engines/twine/menuoptions.h
@@ -40,22 +40,22 @@ private:
void drawSelectableCharacters();
void drawPlayerName(int32 centerx, int32 top, int32 type);
void drawSelectableCharacter(int32 x, int32 y, bool selected);
- void showCredits();
- void newGame();
int chooseSave(int textIdx);
public:
MenuOptions(TwinEEngine *engine) : _engine(engine) {}
+ void showCredits();
bool canShowCredits = false;
char playerName[32] {'\0'};
/** Main menu new game options */
- void newGameMenu();
+ bool newGameMenu();
+ void newGame();
/** Main menu continue game options */
- void continueGameMenu();
+ bool continueGameMenu();
};
} // namespace TwinE
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index 73e2d16609..3393169a51 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -41,10 +41,6 @@ public:
return "TwinE";
}
- bool hasFeature(MetaEngineFeature f) const override {
- return false;
- }
-
bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override {
if (desc) {
TwineGameType gameType = TwineGameType::GType_LBA;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 2ba2925d95..42d3a3d1aa 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -153,7 +153,34 @@ Common::Error TwinEEngine::run() {
_menu->init();
while (!shouldQuit()) {
- _menu->run();
+ readKeys();
+ switch (_state) {
+ case EngineState::QuitGame: {
+ Common::Event event;
+ event.type = Common::EVENT_QUIT;
+ _system->getEventManager()->pushEvent(event);
+ break;
+ }
+ case EngineState::LoadedGame:
+ debug("Loaded game");
+ if (_scene->newHeroX == -1) {
+ _scene->heroPositionType = ScenePositionType::kNoPosition;
+ }
+ _text->newGameVar5 = 0;
+ _text->textClipSmall();
+ _text->newGameVar4 = 1;
+ _state = EngineState::GameLoop;
+ break;
+ case EngineState::GameLoop:
+ if (gameEngineLoop()) {
+ _menuOptions->showCredits();
+ }
+ _state = EngineState::Menu;
+ break;
+ case EngineState::Menu:
+ _state = _menu->run();
+ break;
+ }
}
ConfMan.setInt("CombatAuto", _actor->autoAgressive ? 1 : 0);
@@ -180,34 +207,39 @@ bool TwinEEngine::hasFeature(EngineFeature f) const {
return false;
}
-bool TwinEEngine::hasSavedSlots() {
+Common::StringArray TwinEEngine::getSaveSlots() {
Common::SaveFileManager *saveFileMan = getSaveFileManager();
const Common::String pattern(getMetaEngine().getSavegameFilePattern(_targetName.c_str()));
- return !saveFileMan->listSavefiles(pattern).empty();
+ return saveFileMan->listSavefiles(pattern);
}
void TwinEEngine::wipeSaveSlot(int slot) {
Common::SaveFileManager *saveFileMan = getSaveFileManager();
- const Common::String &saveFile = getMetaEngine().getSavegameFile(slot, _targetName.c_str());
+ const Common::String &saveFile = getSaveStateName(slot);
saveFileMan->removeSavefile(saveFile);
}
-bool TwinEEngine::loadSaveSlot(int slot) {
- Common::SaveFileManager *saveFileMan = getSaveFileManager();
- const Common::String &saveFile = getMetaEngine().getSavegameFile(slot, _targetName.c_str());
- Common::InSaveFile *file = saveFileMan->openForLoading(saveFile);
- return _gameState->loadGame(file);
+bool TwinEEngine::canSaveGameStateCurrently() { return _scene->currentScene != nullptr; }
+
+Common::Error TwinEEngine::loadGameStream(Common::SeekableReadStream *stream) {
+ debug("load game stream");
+ if (!_gameState->loadGame(stream)) {
+ return Common::Error(Common::kReadingFailed);
+ }
+ _state = EngineState::LoadedGame;
+ return Common::Error(Common::kNoError);
}
-bool TwinEEngine::saveSlot(int slot) {
- Common::SaveFileManager *saveFileMan = getSaveFileManager();
- const Common::String &saveFile = getMetaEngine().getSavegameFile(slot, _targetName.c_str());
- Common::OutSaveFile *file = saveFileMan->openForSaving(saveFile);
- return _gameState->saveGame(file);
+Common::Error TwinEEngine::saveGameStream(Common::WriteStream *stream, bool isAutosave) {
+ if (!_gameState->saveGame(stream)) {
+ return Common::Error(Common::kWritingFailed);
+ }
+ return Common::Error(Common::kNoError);
}
void TwinEEngine::autoSave() {
- // TODO:
+ // TODO: scene title, not player name
+ saveGameState(getAutosaveSlot(), _gameState->playerName, true);
}
void TwinEEngine::allocVideoMemory() {
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 0cf6d18278..735f5c661b 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -154,6 +154,13 @@ struct Keyboard;
class Debug;
class DebugScene;
+enum class EngineState {
+ Menu,
+ GameLoop,
+ LoadedGame,
+ QuitGame
+};
+
class TwinEEngine : public Engine {
private:
int32 isTimeFreezed = 0;
@@ -161,6 +168,7 @@ private:
ActorMoveStruct loopMovePtr; // mainLoopVar1
PauseToken _pauseToken;
TwineGameType _gameType;
+ EngineState _state = EngineState::Menu;
public:
TwinEEngine(OSystem *system, Common::Language language, uint32 flagsTwineGameType, TwineGameType gameType);
@@ -169,10 +177,14 @@ public:
Common::Error run() override;
bool hasFeature(EngineFeature f) const override;
+ bool canLoadGameStateCurrently() override { return true; }
+ bool canSaveGameStateCurrently() override;
+
+ Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
+ Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
+
void wipeSaveSlot(int slot);
- bool hasSavedSlots();
- bool loadSaveSlot(int slot);
- bool saveSlot(int slot);
+ Common::StringArray getSaveSlots();
void autoSave();
bool isLBA1() const { return _gameType == TwineGameType::GType_LBA; };
Commit: 8e926838be43817e0c3fe5192e3dfd5f20d4b11c
https://github.com/scummvm/scummvm/commit/8e926838be43817e0c3fe5192e3dfd5f20d4b11c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: minor cleanup
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index aa14d1bc0f..bc6288d052 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -374,7 +374,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
_engine->copyBlockPhys(left, top, right, bottom);
}
-void Menu::drawButton(const int16 *menuSettings, bool hover) {
+void Menu::drawButtons(const int16 *menuSettings, bool hover) {
int16 buttonNumber = menuSettings[MenuSettings_CurrentLoadedButton];
const int32 maxButton = menuSettings[MenuSettings_NumberOfButtons];
int32 topHeight = menuSettings[MenuSettings_ButtonsBoxHeight];
@@ -395,10 +395,8 @@ void Menu::drawButton(const int16 *menuSettings, bool hover) {
localData += MenuSettings_FirstButtonState;
do {
// get menu item settings
- uint8 menuItemId = (uint8)*localData;
- localData += 1;
- uint16 textId = *localData;
- localData += 1;
+ int32 menuItemId = *localData++;
+ int32 textId = *localData++;
if (hover) {
if (currentButton == buttonNumber) {
drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, hover);
@@ -564,12 +562,12 @@ int32 Menu::processMenu(int16 *menuSettings) {
menuSettings[MenuSettings_CurrentLoadedButton] = currentButton;
// draw all buttons
- drawButton(menuSettings, false);
+ drawButtons(menuSettings, false);
buttonsNeedRedraw = false;
}
// draw plasma effect for the current selected button
- drawButton(menuSettings, true);
+ drawButtons(menuSettings, true);
if (_engine->shouldQuit()) {
return kQuitEngine;
}
@@ -773,23 +771,20 @@ int32 Menu::giveupMenu() {
}
void Menu::drawInfoMenu(int16 left, int16 top) {
- int32 boxLeft, boxTop, boxRight, boxBottom;
- int32 newBoxLeft, newBoxLeft2, i;
-
_engine->_interface->resetClip();
drawBox(left, top, left + 450, top + 80);
_engine->_interface->drawSplittedBox(left + 1, top + 1, left + 449, top + 79, 0);
- newBoxLeft2 = left + 9;
+ int32 newBoxLeft2 = left + 9;
_engine->_grid->drawSprite(0, newBoxLeft2, top + 13, _engine->_resources->spriteTable[SPRITEHQR_LIFEPOINTS]);
- boxRight = left + 325;
- newBoxLeft = left + 25;
- boxLeft = _engine->_screens->crossDot(newBoxLeft, boxRight, 50, _engine->_scene->sceneHero->life);
+ int32 boxRight = left + 325;
+ int32 newBoxLeft = left + 25;
+ int32 boxLeft = _engine->_screens->crossDot(newBoxLeft, boxRight, 50, _engine->_scene->sceneHero->life);
- boxTop = top + 10;
- boxBottom = top + 25;
+ int32 boxTop = top + 10;
+ int32 boxBottom = top + 25;
_engine->_interface->drawSplittedBox(newBoxLeft, boxTop, boxLeft, boxBottom, 91);
drawBox(left + 25, top + 10, left + 324, top + 10 + 14);
@@ -821,12 +816,12 @@ void Menu::drawInfoMenu(int16 left, int16 top) {
}
// Clover leaf boxes
- for (i = 0; i < _engine->_gameState->inventoryNumLeafsBox; i++) {
+ for (int32 i = 0; i < _engine->_gameState->inventoryNumLeafsBox; i++) {
_engine->_grid->drawSprite(0, _engine->_screens->crossDot(left + 25, left + 325, 10, i), top + 58, _engine->_resources->spriteTable[SPRITEHQR_CLOVERLEAFBOX]);
}
// Clover leafs
- for (i = 0; i < _engine->_gameState->inventoryNumLeafs; i++) {
+ for (int32 i = 0; i < _engine->_gameState->inventoryNumLeafs; i++) {
_engine->_grid->drawSprite(0, _engine->_screens->crossDot(left + 25, left + 325, 10, i) + 2, top + 60, _engine->_resources->spriteTable[SPRITEHQR_CLOVERLEAF]);
}
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index e467376e25..65ab4d4850 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -120,7 +120,7 @@ private:
* @param data menu settings array
* @param mode flag to know if should draw as a hover button or not
*/
- void drawButton(const int16 *menuSettings, bool hover);
+ void drawButtons(const int16 *menuSettings, bool hover);
/** Used to run the advanced options menu */
int32 advoptionsMenu();
/** Used to run the volume menu */
Commit: 3257107fadf6a39249be5c980aa2ac64ff93ada0
https://github.com/scummvm/scummvm/commit/3257107fadf6a39249be5c980aa2ac64ff93ada0
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: refactored menu data
Changed paths:
engines/twine/gamestate.cpp
engines/twine/gamestate.h
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/twine.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index ea820a73f4..8e01413844 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -55,7 +55,6 @@ GameState::GameState(TwinEEngine *engine) : _engine(engine) {
Common::fill(&holomapFlags[0], &holomapFlags[150], 0);
playerName[0] = 0;
Common::fill(&gameChoices[0], &gameChoices[10], 0);
- Common::fill(&gameChoicesSettings[0], &gameChoicesSettings[18], 0);
}
void GameState::initEngineProjections() {
@@ -411,21 +410,19 @@ void GameState::processFoundItem(int32 item) {
void GameState::processGameChoices(int32 choiceIdx) {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- gameChoicesSettings[MenuSettings_CurrentLoadedButton] = 0; // Current loaded button (button number)
- gameChoicesSettings[MenuSettings_NumberOfButtons] = numChoices; // Num of buttons
- gameChoicesSettings[MenuSettings_ButtonsBoxHeight] = 0; // Buttons box height
- gameChoicesSettings[MenuSettings_HeaderEnd] = _engine->_text->currentTextBank + 3;
+ gameChoicesSettings.reset();
+ gameChoicesSettings.setHeadlineTextId(_engine->_text->currentTextBank + 3);
// filled via script
for (int32 i = 0; i < numChoices; i++) {
- gameChoicesSettings[i * 2 + MenuSettings_FirstButtonState] = 0;
- gameChoicesSettings[i * 2 + MenuSettings_FirstButton] = gameChoices[i];
+ gameChoicesSettings.addButton(gameChoices[i], 0);
}
_engine->_text->drawAskQuestion(choiceIdx);
- _engine->_menu->processMenu(gameChoicesSettings);
- choiceAnswer = gameChoices[gameChoicesSettings[MenuSettings_CurrentLoadedButton]];
+ _engine->_menu->processMenu(&gameChoicesSettings);
+ const int16 activeButton = gameChoicesSettings.getActiveButton();
+ choiceAnswer = gameChoices[activeButton];
// get right VOX entry index
if (_engine->_text->initVoxToPlay(choiceAnswer)) {
diff --git a/engines/twine/gamestate.h b/engines/twine/gamestate.h
index fe84dae1c4..2a6e5f2b03 100644
--- a/engines/twine/gamestate.h
+++ b/engines/twine/gamestate.h
@@ -26,6 +26,7 @@
#include "common/savefile.h"
#include "common/scummsys.h"
#include "twine/actor.h"
+#include "twine/menu.h"
namespace TwinE {
@@ -128,7 +129,7 @@ public:
int32 gameChoices[10]; // inGameMenuData
int32 numChoices = 0; // numOfOptionsInChoice
- int16 gameChoicesSettings[18]; // choiceTab - same structure as menu settings
+ MenuSettings gameChoicesSettings; // choiceTab - same structure as menu settings
int32 choiceAnswer = 0; // inGameMenuAnswer
/** Initialize all engine variables */
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index bc6288d052..35e5befcb2 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -78,152 +78,101 @@ enum _MenuButtonTypes {
#define kBackground 9999
namespace _priv {
-/** Main Menu Settings
-
- Used to create the game main menu. */
-static const int16 MainMenuSettings[] = {
- 0, // Current loaded button (button number)
- 4, // Num of buttons
- 200, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kNewGame, // new game
- 0,
- TextId::kContinueGame, // continue game
- 0,
- TextId::kOptions, // options
- 0,
- TextId::kQuit, // quit
-};
-/** Give Up Menu Settings
-
- Used to create the in-game menu. */
-static const int16 GiveUpMenuSettings[] = {
- 0, // Current loaded button (button number)
- 2, // Num of buttons
- 240, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kContinue, // continue game
- 0,
- TextId::kGiveUp, // quit game
-};
+static MenuSettings createMainMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.setButtonsBoxHeight(200);
+ settings.addButton(TextId::kNewGame);
+ settings.addButton(TextId::kContinueGame);
+ settings.addButton(TextId::kOptions);
+ settings.addButton(TextId::kQuit);
+ return settings;
+}
-/** Give Up Menu Settings
-
- Used to create the in-game menu. This menu have one extra item to save the game */
-static const int16 GiveUpMenuWithSaveSettings[] = {
- 0, // Current loaded button (button number)
- 3, // Num of buttons
- 240, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kContinue, // continue game
- 0,
- TextId::kCreateSaveGame, // save game
- 0,
- TextId::kGiveUp, // quit game
-};
+static MenuSettings createGiveUpMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.setButtonsBoxHeight(240);
+ settings.addButton(TextId::kContinue);
+ settings.addButton(TextId::kGiveUp);
+ return settings;
+}
-/** Options Menu Settings
-
- Used to create the options menu. */
-static const int16 OptionsMenuSettings[] = {
- 0, // Current loaded button (button number)
- 4, // Num of buttons
- 0, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kReturnMenu, // return to previous menu
- 0,
- TextId::kVolumeSettings, // volume settings
- 0,
- TextId::kSaveManage, // save game management
- 0,
- TextId::kAdvanced, // advanced options
-};
+static MenuSettings createGiveUpSaveMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.setButtonsBoxHeight(240);
+ settings.addButton(TextId::kContinue);
+ settings.addButton(TextId::kCreateSaveGame);
+ settings.addButton(TextId::kGiveUp);
+ return settings;
+}
-/** Advanced Options Menu Settings
-
- Used to create the advanced options menu. */
-static const int16 AdvOptionsMenuSettings[] = {
- 0, // Current loaded button (button number)
- 5, // Num of buttons
- 0, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kReturnMenu, // return to main menu
- MenuButtonTypes::kAgressiveMode,
- TextId::kBehaviourAgressiveManual, // aggressive mode (manual|auto)
- MenuButtonTypes::kPolygonDetails,
- TextId::kDetailsPolygonsHigh, // Polygon detail (full|medium|low)
- MenuButtonTypes::kShadowSettings,
- TextId::kDetailsShadowHigh, // Shadows (all|character|no)
- MenuButtonTypes::kSceneryZoom,
- TextId::kScenaryZoomOn, // scenary zoon (on|off)
-};
+static MenuSettings createOptionsMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.addButton(TextId::kReturnMenu);
+ settings.addButton(TextId::kVolumeSettings);
+ settings.addButton(TextId::kSaveManage);
+ settings.addButton(TextId::kAdvanced);
+ return settings;
+}
-/** Save Game Management Menu Settings
-
- Used to create the save game management menu. */
-static const int16 SaveManageMenuSettings[] = {
- 0, // Current loaded button (button number)
- 3, // Num of buttons
- 0, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kReturnMenu, // return to main menu
- 0,
- TextId::kCreateSaveGame, // copy saved game
- 0,
- TextId::kDeleteSaveGame, // delete saved game
-};
+static MenuSettings createAdvancedOptionsMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.addButton(TextId::kReturnMenu);
+ settings.addButton(TextId::kBehaviourAgressiveManual, MenuButtonTypes::kAgressiveMode);
+ settings.addButton(TextId::kDetailsPolygonsHigh, MenuButtonTypes::kPolygonDetails);
+ settings.addButton(TextId::kDetailsShadowHigh, MenuButtonTypes::kShadowSettings);
+ settings.addButton(TextId::kScenaryZoomOn, MenuButtonTypes::kSceneryZoom);
+ return settings;
+}
+
+static MenuSettings createSaveManageMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.addButton(TextId::kReturnMenu);
+ settings.addButton(TextId::kCreateSaveGame);
+ settings.addButton(TextId::kDeleteSaveGame);
+ return settings;
+}
+
+static MenuSettings createVolumeMenu() {
+ MenuSettings settings;
+ settings.reset();
+ settings.addButton(TextId::kReturnMenu);
+ settings.addButton(TextId::kMusicVolume, MenuButtonTypes::kMusicVolume);
+ settings.addButton(TextId::kSoundVolume, MenuButtonTypes::kSoundVolume);
+ settings.addButton(TextId::kCDVolume, MenuButtonTypes::kCDVolume);
+ settings.addButton(TextId::kLineInVolume, MenuButtonTypes::kLineVolume);
+ settings.addButton(TextId::kMasterVolume, MenuButtonTypes::kMasterVolume);
+ settings.addButton(TextId::kSaveSettings);
+ return settings;
+}
-/** Volume Menu Settings
-
- Used to create the volume menu. */
-static const int16 VolumeMenuSettings[] = {
- 0, // Current loaded button (button number)
- 7, // Num of buttons
- 0, // Buttons box height ( is used to calc the height where the first button will appear )
- 0, // unused
- 0,
- TextId::kReturnMenu, // return to main menu
- MenuButtonTypes::kMusicVolume,
- TextId::kMusicVolume, // music volume
- MenuButtonTypes::kSoundVolume,
- TextId::kSoundVolume, // sfx volume
- MenuButtonTypes::kCDVolume,
- TextId::kCDVolume, // cd volume
- MenuButtonTypes::kLineVolume,
- TextId::kLineInVolume, // line-in volume
- MenuButtonTypes::kMasterVolume,
- TextId::kMasterVolume, // master volume
- 0,
- TextId::kSaveSettings, // save parameters
-};
} // namespace _priv
-static int16 *copySettings(const int16 *settings, size_t size) {
- int16 *buf = (int16 *)malloc(size);
+static MenuSettings *copySettings(const MenuSettings settings) {
+ MenuSettings *buf = (MenuSettings *)malloc(sizeof(MenuSettings));
if (buf == nullptr) {
error("Failed to allocate menu state memory");
}
- memcpy(buf, settings, size);
+ *buf = settings;
return buf;
}
Menu::Menu(TwinEEngine *engine) {
_engine = engine;
- OptionsMenuState = copySettings(_priv::OptionsMenuSettings, sizeof(_priv::OptionsMenuSettings));
- GiveUpMenuWithSaveState = copySettings(_priv::GiveUpMenuWithSaveSettings, sizeof(_priv::GiveUpMenuWithSaveSettings));
- VolumeMenuState = copySettings(_priv::VolumeMenuSettings, sizeof(_priv::VolumeMenuSettings));
- SaveManageMenuState = copySettings(_priv::SaveManageMenuSettings, sizeof(_priv::SaveManageMenuSettings));
- GiveUpMenuState = copySettings(_priv::GiveUpMenuSettings, sizeof(_priv::GiveUpMenuSettings));
- MainMenuState = copySettings(_priv::MainMenuSettings, sizeof(_priv::MainMenuSettings));
- AdvOptionsMenuState = copySettings(_priv::AdvOptionsMenuSettings, sizeof(_priv::AdvOptionsMenuSettings));
+ OptionsMenuState = copySettings(_priv::createOptionsMenu());
+ GiveUpMenuWithSaveState = copySettings(_priv::createGiveUpSaveMenu());
+ VolumeMenuState = copySettings(_priv::createVolumeMenu());
+ SaveManageMenuState = copySettings(_priv::createSaveManageMenu());
+ GiveUpMenuState = copySettings(_priv::createGiveUpMenu());
+ MainMenuState = copySettings(_priv::createMainMenu());
+ AdvOptionsMenuState = copySettings(_priv::createAdvancedOptionsMenu());
Common::fill(&behaviourAnimState[0], &behaviourAnimState[4], 0);
Common::fill(&itemAngle[0], &itemAngle[255], 0);
@@ -374,10 +323,10 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
_engine->copyBlockPhys(left, top, right, bottom);
}
-void Menu::drawButtons(const int16 *menuSettings, bool hover) {
- int16 buttonNumber = menuSettings[MenuSettings_CurrentLoadedButton];
- const int32 maxButton = menuSettings[MenuSettings_NumberOfButtons];
- int32 topHeight = menuSettings[MenuSettings_ButtonsBoxHeight];
+void Menu::drawButtons(const MenuSettings *menuSettings, bool hover) {
+ int16 buttonNumber = menuSettings->getActiveButton();
+ const int32 maxButton = menuSettings->getButtonCount();
+ int32 topHeight = menuSettings->getButtonBoxHeight();
if (topHeight == 0) {
topHeight = 35;
@@ -389,35 +338,29 @@ void Menu::drawButtons(const int16 *menuSettings, bool hover) {
return;
}
- uint8 currentButton = 0;
-
- const int16 *localData = menuSettings;
- localData += MenuSettings_FirstButtonState;
- do {
- // get menu item settings
- int32 menuItemId = *localData++;
- int32 textId = *localData++;
+ for (int16 i = 0; i < maxButton; ++i) {
+ const int32 menuItemId = menuSettings->getButtonState(i);
+ const int32 textId = menuSettings->getButtonTextId(i);
if (hover) {
- if (currentButton == buttonNumber) {
+ if (i == buttonNumber) {
drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, hover);
}
} else {
- if (currentButton == buttonNumber) {
+ if (i == buttonNumber) {
drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, true);
} else {
drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, false);
}
}
- currentButton++;
topHeight += 56; // increase button top height
- } while (currentButton < maxButton);
+ }
}
-int32 Menu::processMenu(int16 *menuSettings) {
- int16 currentButton = menuSettings[MenuSettings_CurrentLoadedButton];
+int32 Menu::processMenu(MenuSettings *menuSettings) {
+ int16 currentButton = menuSettings->getActiveButton();
bool buttonsNeedRedraw = true;
- const int32 numEntry = menuSettings[MenuSettings_NumberOfButtons];
+ const int32 numEntry = menuSettings->getButtonCount();
int32 maxButton = numEntry - 1;
_engine->_input->enableKeyMap(uiKeyMapId);
@@ -440,9 +383,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
buttonsNeedRedraw = true;
}
- int16 *menuStatePtr = &menuSettings[MenuSettings_FirstButtonState] + currentButton * 2;
- const int16 id = *menuStatePtr; // get button parameters from settings array
- int16 *textId = menuStatePtr + 1; // to store the changed values
+ const int16 id = menuSettings->getActiveButtonState();
if (menuSettings == AdvOptionsMenuState) {
switch (id) {
case MenuButtonTypes::kAgressiveMode:
@@ -450,9 +391,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->_actor->autoAgressive = !_engine->_actor->autoAgressive;
}
if (_engine->_actor->autoAgressive) {
- *textId = TextId::kBehaviourAgressiveManual;
+ menuSettings->setActiveButtonTextId(TextId::kBehaviourAgressiveManual);
} else {
- *textId = TextId::kBehaviourAgressiveAuto;
+ menuSettings->setActiveButtonTextId(TextId::kBehaviourAgressiveAuto);
}
break;
case MenuButtonTypes::kPolygonDetails:
@@ -464,11 +405,11 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->cfgfile.PolygonDetails %= 3;
}
if (_engine->cfgfile.PolygonDetails == 0) {
- *textId = TextId::kDetailsPolygonsLow;
+ menuSettings->setActiveButtonTextId(TextId::kDetailsPolygonsLow);
} else if (_engine->cfgfile.PolygonDetails == 1) {
- *textId = TextId::kDetailsPolygonsMiddle;
+ menuSettings->setActiveButtonTextId(TextId::kDetailsPolygonsMiddle);
} else {
- *textId = TextId::kDetailsPolygonsHigh;
+ menuSettings->setActiveButtonTextId(TextId::kDetailsPolygonsHigh);
}
break;
case MenuButtonTypes::kShadowSettings:
@@ -480,11 +421,11 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->cfgfile.ShadowMode %= 3;
}
if (_engine->cfgfile.ShadowMode == 0) {
- *textId = TextId::kShadowsDisabled;
+ menuSettings->setActiveButtonTextId(TextId::kShadowsDisabled);
} else if (_engine->cfgfile.ShadowMode == 1) {
- *textId = TextId::kShadowsFigures;
+ menuSettings->setActiveButtonTextId(TextId::kShadowsFigures);
} else {
- *textId = TextId::kDetailsShadowHigh;
+ menuSettings->setActiveButtonTextId(TextId::kDetailsShadowHigh);
}
break;
case MenuButtonTypes::kSceneryZoom:
@@ -492,9 +433,9 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->cfgfile.SceZoom = !_engine->cfgfile.SceZoom;
}
if (_engine->cfgfile.SceZoom) {
- *textId = TextId::kNoScenaryZoom;
+ menuSettings->setActiveButtonTextId(TextId::kNoScenaryZoom);
} else {
- *textId = TextId::kScenaryZoomOn;
+ menuSettings->setActiveButtonTextId(TextId::kScenaryZoomOn);
}
break;
default:
@@ -559,7 +500,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
}
if (buttonsNeedRedraw) {
- menuSettings[MenuSettings_CurrentLoadedButton] = currentButton;
+ menuSettings->setActiveButton(currentButton);
// draw all buttons
drawButtons(menuSettings, false);
@@ -575,8 +516,7 @@ int32 Menu::processMenu(int16 *menuSettings) {
_engine->_system->delayMillis(10);
} while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
- const int buttonTextId = *(menuSettings + MenuSettings_FirstButton + currentButton * 2); // get current browsed button
- return buttonTextId;
+ return menuSettings->getActiveButtonTextId();
}
int32 Menu::advoptionsMenu() {
@@ -737,7 +677,7 @@ int32 Menu::giveupMenu() {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
_engine->_sound->pauseSamples();
- int16 *localMenu;
+ MenuSettings *localMenu;
if (_engine->cfgfile.UseAutoSaving == 1) {
localMenu = GiveUpMenuState;
} else {
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 65ab4d4850..2221055c56 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -92,6 +92,75 @@ enum _TextId {
#define PLASMA_HEIGHT 50
#define kQuitEngine 9998
+class MenuSettings {
+private:
+ int16 _settings[100] {0};
+ int8 _activeButtonIdx = 0;
+public:
+ void reset() {
+ _settings[MenuSettings_NumberOfButtons] = 0;
+ setButtonsBoxHeight(0);
+ setActiveButton(0);
+ }
+
+ // used to calc the height where the first button will appear
+ void setButtonsBoxHeight(int16 height) {
+ _settings[MenuSettings_ButtonsBoxHeight] = height;
+ }
+
+ void setActiveButton(int16 buttonIdx) {
+ _activeButtonIdx = buttonIdx;
+ _settings[MenuSettings_CurrentLoadedButton] = buttonIdx;
+ }
+
+ void setActiveButtonTextId(int16 textIndex) {
+ setButtonTextId(getActiveButton(), textIndex);
+ }
+
+ void setButtonTextId(int16 buttonIdx, int16 textIndex) {
+ _settings[MenuSettings_FirstButton + buttonIdx * 2] = textIndex;
+ }
+
+ int16 getActiveButtonTextId() const {
+ return getButtonTextId(getActiveButton());
+ }
+
+ int16 getActiveButtonState() const {
+ return getButtonState(getActiveButton());
+ }
+
+ int16 getButtonTextId(int buttonIndex) const {
+ return _settings[MenuSettings_FirstButton + buttonIndex * 2];
+ }
+
+ int16 getButtonState(int buttonIndex) const {
+ return _settings[MenuSettings_FirstButtonState + buttonIndex * 2];
+ }
+
+ int16 getActiveButton() const {
+ return _activeButtonIdx;
+ }
+
+ int16 getButtonBoxHeight() const {
+ return _settings[MenuSettings_ButtonsBoxHeight];
+ }
+
+ int16 getButtonCount() const {
+ return _settings[MenuSettings_NumberOfButtons];
+ }
+
+ void setHeadlineTextId(int16 textIndex) {
+ _settings[MenuSettings_HeaderEnd] = textIndex;
+ }
+
+ void addButton(int16 textId, int16 state = 0) {
+ const int16 i = _settings[MenuSettings_NumberOfButtons];
+ _settings[i * 2 + MenuSettings_FirstButtonState] = state;
+ _settings[i * 2 + MenuSettings_FirstButton] = textId;
+ ++_settings[MenuSettings_NumberOfButtons];
+ }
+};
+
class Menu {
private:
TwinEEngine *_engine;
@@ -120,7 +189,7 @@ private:
* @param data menu settings array
* @param mode flag to know if should draw as a hover button or not
*/
- void drawButtons(const int16 *menuSettings, bool hover);
+ void drawButtons(const MenuSettings *menuSettings, bool hover);
/** Used to run the advanced options menu */
int32 advoptionsMenu();
/** Used to run the volume menu */
@@ -141,17 +210,17 @@ private:
*/
void drawMagicItemsBox(int32 left, int32 top, int32 right, int32 bottom, int32 color);
- int16 *GiveUpMenuWithSaveState;
- int16 *VolumeMenuState;
- int16 *SaveManageMenuState;
- int16 *GiveUpMenuState;
- int16 *MainMenuState;
- int16 *AdvOptionsMenuState;
+ MenuSettings *GiveUpMenuWithSaveState;
+ MenuSettings *VolumeMenuState;
+ MenuSettings *SaveManageMenuState;
+ MenuSettings *GiveUpMenuState;
+ MenuSettings *MainMenuState;
+ MenuSettings *AdvOptionsMenuState;
public:
Menu(TwinEEngine *engine);
~Menu();
- int16 *OptionsMenuState;
+ MenuSettings *OptionsMenuState;
int32 currMenuTextIndex = -1;
int32 currMenuTextBank = -1;
@@ -186,7 +255,7 @@ public:
* @param menuSettings menu settings array with the information to build the menu options
* @return pressed menu button identification
*/
- int32 processMenu(int16 *menuSettings);
+ int32 processMenu(MenuSettings *menuSettings);
bool init();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 42d3a3d1aa..ac7ca9904c 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -457,11 +457,11 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (_input->toggleActionIfActive(TwinEActionType::OptionsMenu)) {
freezeTime();
_sound->pauseSamples();
- _menu->OptionsMenuState[MenuSettings_FirstButton] = TextId::kReturnGame;
+ _menu->OptionsMenuState->setButtonTextId(0, TextId::kReturnGame);
_text->initTextBank(0);
_menu->optionsMenu();
_text->initTextBank(_text->currentTextBank + 3);
- _menu->OptionsMenuState[MenuSettings_FirstButton] = TextId::kReturnMenu;
+ _menu->OptionsMenuState->setButtonTextId(0, TextId::kReturnMenu);
// TODO: play music
_sound->resumeSamples();
unfreezeTime();
Commit: 42628c51be119870c2cac8f9ae17d75abada3a04
https://github.com/scummvm/scummvm/commit/42628c51be119870c2cac8f9ae17d75abada3a04
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: return the button text - not just the id
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 35e5befcb2..2c8e4709c5 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -163,6 +163,15 @@ static MenuSettings *copySettings(const MenuSettings settings) {
return buf;
}
+const char *MenuSettings::getButtonText(Text *text, int buttonIndex) const {
+ const int32 textId = getButtonTextId(buttonIndex);
+ static char dialText[256];
+ if (!text->getMenuText(textId, dialText, sizeof(dialText))) {
+ dialText[0] = '\0';
+ }
+ return dialText;
+}
+
Menu::Menu(TwinEEngine *engine) {
_engine = engine;
@@ -256,7 +265,7 @@ void Menu::drawBox(int32 left, int32 top, int32 right, int32 bottom) {
_engine->_interface->drawLine(left + 1, bottom, right, bottom, 73); // bottom line
}
-void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, bool hover) {
+void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, const char *dialText, bool hover) {
const int32 left = width - kMainMenuButtonSpan / 2;
const int32 right = width + kMainMenuButtonSpan / 2;
@@ -315,8 +324,6 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 tex
_engine->_text->setFontColor(15);
_engine->_text->setFontParameters(2, 8);
- char dialText[256];
- _engine->_text->getMenuText(textId, dialText, sizeof(dialText));
const int32 textSize = _engine->_text->getTextSize(dialText);
_engine->_text->drawText(width - (textSize / 2), topheight - 18, dialText);
@@ -340,16 +347,16 @@ void Menu::drawButtons(const MenuSettings *menuSettings, bool hover) {
for (int16 i = 0; i < maxButton; ++i) {
const int32 menuItemId = menuSettings->getButtonState(i);
- const int32 textId = menuSettings->getButtonTextId(i);
+ const char *text = menuSettings->getButtonText(_engine->_text, i);
if (hover) {
if (i == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, hover);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, text, hover);
}
} else {
if (i == buttonNumber) {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, true);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, text, true);
} else {
- drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, textId, false);
+ drawButtonGfx(kMainMenuButtonWidth, topHeight, menuItemId, text, false);
}
}
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 2221055c56..85c58a0d3f 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -96,6 +96,11 @@ class MenuSettings {
private:
int16 _settings[100] {0};
int8 _activeButtonIdx = 0;
+
+ int16 getButtonTextId(int buttonIndex) const {
+ return _settings[MenuSettings_FirstButton + buttonIndex * 2];
+ }
+
public:
void reset() {
_settings[MenuSettings_NumberOfButtons] = 0;
@@ -129,14 +134,12 @@ public:
return getButtonState(getActiveButton());
}
- int16 getButtonTextId(int buttonIndex) const {
- return _settings[MenuSettings_FirstButton + buttonIndex * 2];
- }
-
int16 getButtonState(int buttonIndex) const {
return _settings[MenuSettings_FirstButtonState + buttonIndex * 2];
}
+ const char *getButtonText(Text *text, int buttonIndex) const;
+
int16 getActiveButton() const {
return _activeButtonIdx;
}
@@ -179,10 +182,10 @@ private:
* @param width menu button width
* @param topheight is the height between the top of the screen and the first button
* @param buttonId current button identification from menu settings
- * @param textId
+ * @param dialText
* @param hover flag to know if should draw as a hover button or not
*/
- void drawButtonGfx(int32 width, int32 topheight, int32 buttonId, int32 textId, bool hover);
+ void drawButtonGfx(int32 width, int32 topheight, int32 buttonId, const char *dialText, bool hover);
void plasmaEffectRenderFrame();
/**
* Process the menu button draw
Commit: 2e5d3977c9054c62a2e01029ab8229586b0b7493
https://github.com/scummvm/scummvm/commit/2e5d3977c9054c62a2e01029ab8229586b0b7493
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: reduced memory allocations
Changed paths:
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/twine.cpp
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 2c8e4709c5..e2d30eb4c0 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -81,7 +81,6 @@ namespace _priv {
static MenuSettings createMainMenu() {
MenuSettings settings;
- settings.reset();
settings.setButtonsBoxHeight(200);
settings.addButton(TextId::kNewGame);
settings.addButton(TextId::kContinueGame);
@@ -92,7 +91,6 @@ static MenuSettings createMainMenu() {
static MenuSettings createGiveUpMenu() {
MenuSettings settings;
- settings.reset();
settings.setButtonsBoxHeight(240);
settings.addButton(TextId::kContinue);
settings.addButton(TextId::kGiveUp);
@@ -101,7 +99,6 @@ static MenuSettings createGiveUpMenu() {
static MenuSettings createGiveUpSaveMenu() {
MenuSettings settings;
- settings.reset();
settings.setButtonsBoxHeight(240);
settings.addButton(TextId::kContinue);
settings.addButton(TextId::kCreateSaveGame);
@@ -111,7 +108,6 @@ static MenuSettings createGiveUpSaveMenu() {
static MenuSettings createOptionsMenu() {
MenuSettings settings;
- settings.reset();
settings.addButton(TextId::kReturnMenu);
settings.addButton(TextId::kVolumeSettings);
settings.addButton(TextId::kSaveManage);
@@ -121,7 +117,6 @@ static MenuSettings createOptionsMenu() {
static MenuSettings createAdvancedOptionsMenu() {
MenuSettings settings;
- settings.reset();
settings.addButton(TextId::kReturnMenu);
settings.addButton(TextId::kBehaviourAgressiveManual, MenuButtonTypes::kAgressiveMode);
settings.addButton(TextId::kDetailsPolygonsHigh, MenuButtonTypes::kPolygonDetails);
@@ -132,7 +127,6 @@ static MenuSettings createAdvancedOptionsMenu() {
static MenuSettings createSaveManageMenu() {
MenuSettings settings;
- settings.reset();
settings.addButton(TextId::kReturnMenu);
settings.addButton(TextId::kCreateSaveGame);
settings.addButton(TextId::kDeleteSaveGame);
@@ -141,7 +135,6 @@ static MenuSettings createSaveManageMenu() {
static MenuSettings createVolumeMenu() {
MenuSettings settings;
- settings.reset();
settings.addButton(TextId::kReturnMenu);
settings.addButton(TextId::kMusicVolume, MenuButtonTypes::kMusicVolume);
settings.addButton(TextId::kSoundVolume, MenuButtonTypes::kSoundVolume);
@@ -154,15 +147,6 @@ static MenuSettings createVolumeMenu() {
} // namespace _priv
-static MenuSettings *copySettings(const MenuSettings settings) {
- MenuSettings *buf = (MenuSettings *)malloc(sizeof(MenuSettings));
- if (buf == nullptr) {
- error("Failed to allocate menu state memory");
- }
- *buf = settings;
- return buf;
-}
-
const char *MenuSettings::getButtonText(Text *text, int buttonIndex) const {
const int32 textId = getButtonTextId(buttonIndex);
static char dialText[256];
@@ -175,13 +159,13 @@ const char *MenuSettings::getButtonText(Text *text, int buttonIndex) const {
Menu::Menu(TwinEEngine *engine) {
_engine = engine;
- OptionsMenuState = copySettings(_priv::createOptionsMenu());
- GiveUpMenuWithSaveState = copySettings(_priv::createGiveUpSaveMenu());
- VolumeMenuState = copySettings(_priv::createVolumeMenu());
- SaveManageMenuState = copySettings(_priv::createSaveManageMenu());
- GiveUpMenuState = copySettings(_priv::createGiveUpMenu());
- MainMenuState = copySettings(_priv::createMainMenu());
- AdvOptionsMenuState = copySettings(_priv::createAdvancedOptionsMenu());
+ optionsMenuState = _priv::createOptionsMenu();
+ giveUpMenuWithSaveState = _priv::createGiveUpSaveMenu();
+ volumeMenuState = _priv::createVolumeMenu();
+ saveManageMenuState = _priv::createSaveManageMenu();
+ giveUpMenuState = _priv::createGiveUpMenu();
+ mainMenuState = _priv::createMainMenu();
+ advOptionsMenuState = _priv::createAdvancedOptionsMenu();
Common::fill(&behaviourAnimState[0], &behaviourAnimState[4], 0);
Common::fill(&itemAngle[0], &itemAngle[255], 0);
@@ -190,13 +174,6 @@ Menu::Menu(TwinEEngine *engine) {
Menu::~Menu() {
free(plasmaEffectPtr);
- free(OptionsMenuState);
- free(GiveUpMenuWithSaveState);
- free(VolumeMenuState);
- free(SaveManageMenuState);
- free(GiveUpMenuState);
- free(MainMenuState);
- free(AdvOptionsMenuState);
}
void Menu::plasmaEffectRenderFrame() {
@@ -391,7 +368,7 @@ int32 Menu::processMenu(MenuSettings *menuSettings) {
}
const int16 id = menuSettings->getActiveButtonState();
- if (menuSettings == AdvOptionsMenuState) {
+ if (menuSettings == &advOptionsMenuState) {
switch (id) {
case MenuButtonTypes::kAgressiveMode:
if (_engine->_input->toggleActionIfActive(TwinEActionType::UILeft) || _engine->_input->toggleActionIfActive(TwinEActionType::UIRight)) {
@@ -448,7 +425,7 @@ int32 Menu::processMenu(MenuSettings *menuSettings) {
default:
break;
}
- } else if (menuSettings == VolumeMenuState) {
+ } else if (menuSettings == &volumeMenuState) {
Audio::Mixer *mixer = _engine->_system->getMixer();
switch (id) {
case MenuButtonTypes::kMusicVolume: {
@@ -531,7 +508,7 @@ int32 Menu::advoptionsMenu() {
_engine->flip();
for (;;) {
- switch (processMenu(AdvOptionsMenuState)) {
+ switch (processMenu(&advOptionsMenuState)) {
case TextId::kReturnMenu: {
return 0;
}
@@ -555,7 +532,7 @@ int32 Menu::savemanageMenu() {
_engine->flip();
for (;;) {
- switch (processMenu(SaveManageMenuState)) {
+ switch (processMenu(&saveManageMenuState)) {
case TextId::kReturnMenu:
return 0;
case TextId::kCreateSaveGame:
@@ -580,7 +557,7 @@ int32 Menu::volumeMenu() {
_engine->flip();
for (;;) {
- switch (processMenu(VolumeMenuState)) {
+ switch (processMenu(&volumeMenuState)) {
case TextId::kReturnMenu:
return 0;
case TextId::kSaveSettings:
@@ -602,6 +579,14 @@ int32 Menu::volumeMenu() {
return 0;
}
+void Menu::inGameOptionsMenu() {
+ _engine->_text->initTextBank(0);
+ _engine->_menu->optionsMenuState.setButtonTextId(0, TextId::kReturnGame);
+ _engine->_menu->optionsMenu();
+ _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ optionsMenuState.setButtonTextId(0, TextId::kReturnMenu);
+}
+
int32 Menu::optionsMenu() {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
@@ -610,7 +595,7 @@ int32 Menu::optionsMenu() {
//_engine->_music->playCDtrack(9);
for (;;) {
- switch (processMenu(OptionsMenuState)) {
+ switch (processMenu(&optionsMenuState)) {
case TextId::kReturnGame:
case TextId::kReturnMenu: {
return 0;
@@ -650,7 +635,7 @@ EngineState Menu::run() {
_engine->_music->playTrackMusic(9); // LBA's Theme
_engine->_sound->stopSamples();
- switch (processMenu(MainMenuState)) {
+ switch (processMenu(&mainMenuState)) {
case TextId::kNewGame: {
if (_engine->_menuOptions->newGameMenu()) {
return EngineState::GameLoop;
@@ -686,9 +671,9 @@ int32 Menu::giveupMenu() {
MenuSettings *localMenu;
if (_engine->cfgfile.UseAutoSaving == 1) {
- localMenu = GiveUpMenuState;
+ localMenu = &giveUpMenuState;
} else {
- localMenu = GiveUpMenuWithSaveState;
+ localMenu = &giveUpMenuWithSaveState;
}
int32 menuId;
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 85c58a0d3f..a3bafe631f 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -213,17 +213,17 @@ private:
*/
void drawMagicItemsBox(int32 left, int32 top, int32 right, int32 bottom, int32 color);
- MenuSettings *GiveUpMenuWithSaveState;
- MenuSettings *VolumeMenuState;
- MenuSettings *SaveManageMenuState;
- MenuSettings *GiveUpMenuState;
- MenuSettings *MainMenuState;
- MenuSettings *AdvOptionsMenuState;
+ MenuSettings giveUpMenuWithSaveState;
+ MenuSettings volumeMenuState;
+ MenuSettings saveManageMenuState;
+ MenuSettings giveUpMenuState;
+ MenuSettings mainMenuState;
+ MenuSettings advOptionsMenuState;
+ MenuSettings optionsMenuState;
public:
Menu(TwinEEngine *engine);
~Menu();
- MenuSettings *OptionsMenuState;
int32 currMenuTextIndex = -1;
int32 currMenuTextBank = -1;
@@ -268,6 +268,8 @@ public:
/** Used to run the in-game give-up menu */
int32 giveupMenu();
+ void inGameOptionsMenu();
+
/** Used to run the options menu */
int32 optionsMenu();
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index ac7ca9904c..b56c14afda 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -457,11 +457,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (_input->toggleActionIfActive(TwinEActionType::OptionsMenu)) {
freezeTime();
_sound->pauseSamples();
- _menu->OptionsMenuState->setButtonTextId(0, TextId::kReturnGame);
- _text->initTextBank(0);
- _menu->optionsMenu();
- _text->initTextBank(_text->currentTextBank + 3);
- _menu->OptionsMenuState->setButtonTextId(0, TextId::kReturnMenu);
+ _menu->inGameOptionsMenu();
// TODO: play music
_sound->resumeSamples();
unfreezeTime();
Commit: a41bf7b8eea8108d4befac10cd507551cf6f363b
https://github.com/scummvm/scummvm/commit/a41bf7b8eea8108d4befac10cd507551cf6f363b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: toggle virtual keyboard in player name menu
Changed paths:
engines/twine/menuoptions.cpp
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 1d3ce36013..a4007d3783 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -171,6 +171,25 @@ void MenuOptions::drawPlayerName(int32 centerx, int32 top, int32 type) {
_engine->copyBlockPhys(left, top, right, top + PLASMA_HEIGHT);
}
+/**
+ * @brief Toggle a given @c OSystem::Feature and restore the previous state on destruction
+ */
+class ScopedFeatureState {
+private:
+ OSystem::Feature _feature;
+ bool _changeTo;
+public:
+ ScopedFeatureState(OSystem::Feature feature, bool enable) : _feature(feature), _changeTo(enable) {
+ if (g_system->getFeatureState(feature) != enable) {
+ g_system->setFeatureState(feature, enable);
+ _changeTo = !g_system->getFeatureState(feature);
+ }
+ }
+ ~ScopedFeatureState() {
+ g_system->setFeatureState(_feature, _changeTo);
+ }
+};
+
bool MenuOptions::enterPlayerName(int32 textIdx) {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
@@ -184,6 +203,7 @@ bool MenuOptions::enterPlayerName(int32 textIdx) {
_engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
_engine->flip();
+ ScopedFeatureState scopedVirtualKeyboard(OSystem::kFeatureVirtualKeyboard, true);
for (;;) {
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
Commit: b2c114d73f1166cb7ac1ccb9b612b69756c6cca5
https://github.com/scummvm/scummvm/commit/b2c114d73f1166cb7ac1ccb9b612b69756c6cca5
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: don't leave on empty name
Changed paths:
engines/twine/menuoptions.cpp
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index a4007d3783..c9f4755dfe 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -217,6 +217,9 @@ bool MenuOptions::enterPlayerName(int32 textIdx) {
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter)) {
if (_onScreenKeyboardLeaveViaOkButton) {
if (_onScreenKeyboardX == ONSCREENKEYBOARD_WIDTH - 1 && _onScreenKeyboardY == ONSCREENKEYBOARD_HEIGHT - 1) {
+ if (playerName[0] == '\0') {
+ continue;
+ }
return true;
}
const size_t size = strlen(playerName);
@@ -234,6 +237,10 @@ bool MenuOptions::enterPlayerName(int32 textIdx) {
}
continue;
}
+ if (playerName[0] == '\0') {
+ continue;
+ }
+
return true;
}
if (_engine->_input->toggleActionIfActive(TwinEActionType::UIAbort)) {
Commit: f5d3e304ec81529e88a6102151e24e342ba6cdb5
https://github.com/scummvm/scummvm/commit/f5d3e304ec81529e88a6102151e24e342ba6cdb5
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: added enum for text banks
Changed paths:
engines/twine/text.cpp
engines/twine/text.h
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 57bfe2ac20..c15e25684d 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -133,7 +133,9 @@ void Text::initTextBank(int32 bankIdx) {
// get index according with language
const int32 size = _engine->isLBA1() ? 28 : 30;
- const int32 languageIndex = _engine->cfgfile.LanguageId * size + bankIdx * 2;
+ // the text banks indices are split into index and dialogs - each entry thus consists of two entries in the hqr
+ // every 28 entries starts a new language
+ const int32 languageIndex = _engine->cfgfile.LanguageId * size + (int)bankIdx * 2;
const int32 hqrSize = HQR::getAllocEntry((uint8 **)&dialOrderPtr, Resources::HQR_TEXT_FILE, languageIndex + INDEXOFFSET);
if (hqrSize == 0) {
warning("Failed to initialize text bank %i from file %s", languageIndex, Resources::HQR_TEXT_FILE);
diff --git a/engines/twine/text.h b/engines/twine/text.h
index e66760bd3e..67acb9cc62 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -28,6 +28,25 @@
namespace TwinE {
+// lba1
+enum class TextBankId {
+ None = -1,
+ Options_and_menus = 0,
+ Credits = 1,
+ Inventory_Intro_and_Holomap = 2,
+ Citadel_Island = 3,
+ Principal_Island = 4,
+ White_Leaf_Desert = 5,
+ Proxima_Island = 6,
+ Rebellion_Island = 7,
+ Hamalayi_mountains_southern_range = 8,
+ Hamalayi_mountains_northern_range = 9,
+ Tippet_Island = 10,
+ Brundle_Island = 11,
+ Fortress_Island = 12,
+ Polar_Island = 13
+};
+
class TwinEEngine;
class Text {
private:
Commit: df8dc9f270eacd3b7f7bbf77428b1643da406f98
https://github.com/scummvm/scummvm/commit/df8dc9f270eacd3b7f7bbf77428b1643da406f98
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: replaced magic numbers
Changed paths:
engines/twine/gamestate.cpp
engines/twine/holomap.cpp
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/menuoptions.cpp
engines/twine/script_life_v1.cpp
engines/twine/text.h
engines/twine/twine.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 8e01413844..e28b785910 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -315,7 +315,7 @@ void GameState::processFoundItem(int32 item) {
// process vox play
_engine->_music->stopMusic();
- _engine->_text->initTextBank(2);
+ _engine->_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
_engine->_interface->resetClip();
_engine->_text->initText(item);
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index c2cb8fc921..aa98cad2c2 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -134,7 +134,7 @@ void Holomap::processHolomap() {
drawHolomapTitle(320, 25);
_engine->_renderer->setCameraPosition(320, 190, 128, 1024, 1024);
- _engine->_text->initTextBank(2);
+ _engine->_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
_engine->_text->setFontCrossColor(9);
// TODO
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index e2d30eb4c0..9e062f2211 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -580,7 +580,7 @@ int32 Menu::volumeMenu() {
}
void Menu::inGameOptionsMenu() {
- _engine->_text->initTextBank(0);
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
_engine->_menu->optionsMenuState.setButtonTextId(0, TextId::kReturnGame);
_engine->_menu->optionsMenu();
_engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
@@ -630,7 +630,7 @@ bool Menu::init() {
}
EngineState Menu::run() {
- _engine->_text->initTextBank(0);
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
_engine->_music->playTrackMusic(9); // LBA's Theme
_engine->_sound->stopSamples();
@@ -678,7 +678,7 @@ int32 Menu::giveupMenu() {
int32 menuId;
do {
- _engine->_text->initTextBank(0);
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
menuId = processMenu(localMenu);
switch (menuId) {
case TextId::kContinue:
@@ -855,7 +855,7 @@ void Menu::processBehaviourMenu() {
int32 tmpTextBank = _engine->_text->currentTextBank;
_engine->_text->currentTextBank = -1;
- _engine->_text->initTextBank(0);
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
drawBehaviourMenu(_engine->_scene->sceneHero->angle);
@@ -969,7 +969,7 @@ void Menu::processInventoryMenu() {
drawInventoryItems();
- _engine->_text->initTextBank(2);
+ _engine->_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
int32 bx = 3;
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index a3bafe631f..97f0e3d206 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -25,6 +25,7 @@
#include "twine/actor.h"
#include "twine/twine.h"
+#include "twine/text.h"
namespace TwinE {
@@ -39,55 +40,6 @@ enum MenuSettingsType {
MenuSettings_FirstButton = 5
};
-/** menu text ids */
-namespace TextId {
-enum _TextId {
- kBehaviourNormal = 0,
- kBehaviourSporty = 1,
- kBehaviourAgressiveManual = 2,
- kBehaviourHiding = 3,
- kBehaviourAgressiveAuto = 4,
- kUseProtopack = 5,
- kMusicVolume = 10,
- kSoundVolume = 11,
- kCDVolume = 12,
- kLineInVolume = 13,
- kMasterVolume = 14,
- kReturnGame = 15,
- kSaveSettings = 16,
- kNewGame = 20,
- kContinueGame = 21,
- kQuit = 22,
- kOptions = 23,
- kDelete = 24,
- kReturnMenu = 26,
- kGiveUp = 27,
- kContinue = 28,
- kVolumeSettings = 30,
- kDetailsPolygonsHigh = 31,
- kDetailsShadowHigh = 32,
- //kScenaryZoomOn = 33, // duplicate with 133 - TODO check if this is the same in all languages
- kCreateNewPlayer = 40,
- kCreateSaveGame = 41,
- kEnterYourName = 42,
- kPlayerAlreadyExists = 43,
- kEnterYourNewName = 44,
- kDeleteSaveGame = 45,
- kSaveManage = 46,
- kAdvanced = 47,
- kDelete2 = 48, // difference between 24 and 48?
- kTransferVoices = 49,
- kPleaseWaitWhileVoicesAreSaved = 50,
- kRemoveProtoPack = 105,
- kDetailsPolygonsMiddle = 131,
- kShadowsFigures = 132,
- kScenaryZoomOn = 133,
- kDetailsPolygonsLow = 231,
- kShadowsDisabled = 232,
- kNoScenaryZoom = 233
-};
-}
-
#define PLASMA_WIDTH 320
#define PLASMA_HEIGHT 50
#define kQuitEngine 9998
@@ -226,7 +178,7 @@ public:
~Menu();
int32 currMenuTextIndex = -1;
- int32 currMenuTextBank = -1;
+ int32 currMenuTextBank = TextBankId::None;
char currMenuTextBuffer[256];
int16 itemAngle[255]; // objectRotation
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index c9f4755dfe..4bacb6683c 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -59,7 +59,7 @@ void MenuOptions::newGame() {
_engine->_text->newGameVar4 = 0;
_engine->_text->newGameVar5 = 1;
- _engine->_text->initTextBank(2);
+ _engine->_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
_engine->_text->textClipFull();
_engine->_text->setFontCrossColor(15);
@@ -194,7 +194,7 @@ bool MenuOptions::enterPlayerName(int32 textIdx) {
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
playerName[0] = '\0'; // TODO: read from settings?
- _engine->_text->initTextBank(0);
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
char buffer[256];
_engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
_engine->_text->setFontColor(15);
@@ -329,7 +329,7 @@ int MenuOptions::chooseSave(int textIdx) {
_engine->flip();
do {
// TODO: assemble menu with save slots and make then loadable.
- _engine->_text->initTextBank(0);
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
char buffer[256];
_engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
_engine->_text->setFontColor(15);
diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script_life_v1.cpp
index 2e926c84fc..365c03243e 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script_life_v1.cpp
@@ -1450,7 +1450,7 @@ static int32 lPROJ_3D(TwinEEngine *engine, ScriptContext& ctx) {
engine->_renderer->setCameraAngle(0, 1500, 0, 25, -128, 0, 13000);
engine->_renderer->setLightVector(896, 950, 0);
- engine->_text->initTextBank(1);
+ engine->_text->initTextBank(TextBankId::Credits);
return 0;
}
diff --git a/engines/twine/text.h b/engines/twine/text.h
index 67acb9cc62..ad673adb88 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -28,8 +28,9 @@
namespace TwinE {
-// lba1
-enum class TextBankId {
+// lba
+namespace TextBankId {
+enum _TextBankId {
None = -1,
Options_and_menus = 0,
Credits = 1,
@@ -46,6 +47,56 @@ enum class TextBankId {
Fortress_Island = 12,
Polar_Island = 13
};
+}
+
+/** menu text ids */
+namespace TextId {
+enum _TextId {
+ kBehaviourNormal = 0,
+ kBehaviourSporty = 1,
+ kBehaviourAgressiveManual = 2,
+ kBehaviourHiding = 3,
+ kBehaviourAgressiveAuto = 4,
+ kUseProtopack = 5,
+ kMusicVolume = 10,
+ kSoundVolume = 11,
+ kCDVolume = 12,
+ kLineInVolume = 13,
+ kMasterVolume = 14,
+ kReturnGame = 15,
+ kSaveSettings = 16,
+ kNewGame = 20,
+ kContinueGame = 21,
+ kQuit = 22,
+ kOptions = 23,
+ kDelete = 24,
+ kReturnMenu = 26,
+ kGiveUp = 27,
+ kContinue = 28,
+ kVolumeSettings = 30,
+ kDetailsPolygonsHigh = 31,
+ kDetailsShadowHigh = 32,
+ //kScenaryZoomOn = 33, // duplicate with 133 - TODO check if this is the same in all languages
+ kCreateNewPlayer = 40,
+ kCreateSaveGame = 41,
+ kEnterYourName = 42,
+ kPlayerAlreadyExists = 43,
+ kEnterYourNewName = 44,
+ kDeleteSaveGame = 45,
+ kSaveManage = 46,
+ kAdvanced = 47,
+ kDelete2 = 48, // difference between 24 and 48?
+ kTransferVoices = 49,
+ kPleaseWaitWhileVoicesAreSaved = 50,
+ kRemoveProtoPack = 105,
+ kDetailsPolygonsMiddle = 131,
+ kShadowsFigures = 132,
+ kScenaryZoomOn = 133,
+ kDetailsPolygonsLow = 231,
+ kShadowsDisabled = 232,
+ kNoScenaryZoom = 233
+};
+}
class TwinEEngine;
class Text {
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index b56c14afda..9fb51255c3 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -496,7 +496,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
case kiBookOfBu: {
_screens->fadeToBlack(_screens->paletteRGBA);
_screens->loadImage(RESSHQR_INTROSCREEN1IMG);
- _text->initTextBank(2);
+ _text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
_text->newGameVar4 = 0;
_text->textClipFull();
_text->setFontCrossColor(15);
@@ -552,7 +552,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
unfreezeTime();
_redraw->redrawEngineActions(1);
freezeTime();
- _text->initTextBank(2);
+ _text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
_text->textClipFull();
_text->setFontCrossColor(15);
_text->drawTextFullscreen(162);
Commit: 7fcf6917dbc7a7c4224ded8f29905d137dc86752
https://github.com/scummvm/scummvm/commit/7fcf6917dbc7a7c4224ded8f29905d137dc86752
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: hide enum
Changed paths:
engines/twine/menu.h
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 97f0e3d206..c76865cf00 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -29,23 +29,23 @@
namespace TwinE {
-enum MenuSettingsType {
- // button number
- MenuSettings_CurrentLoadedButton = 0,
- // is used to calc the height where the first button will appear
- MenuSettings_NumberOfButtons = 1,
- MenuSettings_ButtonsBoxHeight = 2,
- MenuSettings_HeaderEnd = 3, // TODO: unknown
- MenuSettings_FirstButtonState = 4,
- MenuSettings_FirstButton = 5
-};
-
#define PLASMA_WIDTH 320
#define PLASMA_HEIGHT 50
#define kQuitEngine 9998
class MenuSettings {
private:
+ enum MenuSettingsType {
+ // button number
+ MenuSettings_CurrentLoadedButton = 0,
+ // is used to calc the height where the first button will appear
+ MenuSettings_NumberOfButtons = 1,
+ MenuSettings_ButtonsBoxHeight = 2,
+ MenuSettings_HeaderEnd = 3, // TODO: unknown
+ MenuSettings_FirstButtonState = 4,
+ MenuSettings_FirstButton = 5
+ };
+
int16 _settings[100] {0};
int8 _activeButtonIdx = 0;
Commit: 0a3a634dafed1562cbc7df75e409a61827b0b7f8
https://github.com/scummvm/scummvm/commit/0a3a634dafed1562cbc7df75e409a61827b0b7f8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: moved scene text bank id into scene class
Changed paths:
engines/twine/gamestate.cpp
engines/twine/holomap.cpp
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/scene.cpp
engines/twine/scene.h
engines/twine/text.cpp
engines/twine/text.h
engines/twine/twine.cpp
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index e28b785910..8ce6d8c644 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -160,7 +160,7 @@ void GameState::initEngineVars() {
gameChapter = 0;
- _engine->_text->currentTextBank = 0;
+ _engine->_scene->sceneTextBank = TextBankId::Options_and_menus;
_engine->_scene->currentlyFollowedActor = 0;
_engine->_actor->heroBehaviour = kNormal;
_engine->_actor->previousHeroAngle = 0;
@@ -401,7 +401,7 @@ void GameState::processFoundItem(int32 item) {
}
initEngineProjections();
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
_engine->_text->stopVox(_engine->_text->currDialTextEntry);
_engine->_scene->sceneHero->animTimerData = tmpAnimTimer;
@@ -411,7 +411,7 @@ void GameState::processGameChoices(int32 choiceIdx) {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
gameChoicesSettings.reset();
- gameChoicesSettings.setHeadlineTextId(_engine->_text->currentTextBank + 3);
+ gameChoicesSettings.setTextBankId(_engine->_scene->sceneTextBank + 3);
// filled via script
for (int32 i = 0; i < numChoices; i++) {
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index aa98cad2c2..7578b8c924 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -145,7 +145,7 @@ void Holomap::processHolomap() {
_engine->_scene->betaLight = betaLightTmp;
_engine->_gameState->initEngineVars();
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
// TODO memcopy reset palette
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 9e062f2211..2e8609b0f2 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -583,7 +583,7 @@ void Menu::inGameOptionsMenu() {
_engine->_text->initTextBank(TextBankId::Options_and_menus);
_engine->_menu->optionsMenuState.setButtonTextId(0, TextId::kReturnGame);
_engine->_menu->optionsMenu();
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
optionsMenuState.setButtonTextId(0, TextId::kReturnMenu);
}
@@ -695,7 +695,7 @@ int32 Menu::giveupMenu() {
default:
warning("Unknown menu button handled: %i", menuId);
}
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
_engine->_system->delayMillis(1000 / _engine->cfgfile.Fps);
} while (menuId != TextId::kGiveUp && menuId != TextId::kContinue);
@@ -852,8 +852,8 @@ void Menu::processBehaviourMenu() {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- int32 tmpTextBank = _engine->_text->currentTextBank;
- _engine->_text->currentTextBank = -1;
+ int32 tmpTextBank = _engine->_scene->sceneTextBank;
+ _engine->_scene->sceneTextBank = TextBankId::None;
_engine->_text->initTextBank(TextBankId::Options_and_menus);
@@ -901,8 +901,8 @@ void Menu::processBehaviourMenu() {
_engine->_actor->setBehaviour(_engine->_actor->heroBehaviour);
_engine->_gameState->initEngineProjections();
- _engine->_text->currentTextBank = tmpTextBank;
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_scene->sceneTextBank = tmpTextBank;
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
}
void Menu::drawMagicItemsBox(int32 left, int32 top, int32 right, int32 bottom, int32 color) { // Rect
@@ -1076,7 +1076,7 @@ void Menu::processInventoryMenu() {
_engine->_gameState->initEngineProjections();
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
}
} // namespace TwinE
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index c76865cf00..2d6c1ba3bd 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -104,8 +104,8 @@ public:
return _settings[MenuSettings_NumberOfButtons];
}
- void setHeadlineTextId(int16 textIndex) {
- _settings[MenuSettings_HeaderEnd] = textIndex;
+ void setTextBankId(int16 textBankIndex) {
+ _settings[MenuSettings_HeaderEnd] = textBankIndex;
}
void addButton(int16 textId, int16 state = 0) {
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index 6a0603bc1a..1f07896ecb 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -97,7 +97,7 @@ bool Scene::loadSceneLBA1() {
Common::MemoryReadStream stream(currentScene, _currentSceneSize);
// load scene ambience properties
- _engine->_text->currentTextBank = stream.readByte();
+ sceneTextBank = stream.readByte();
currentGameOverScene = stream.readByte();
stream.skip(4);
@@ -277,10 +277,10 @@ void Scene::changeScene() {
// TODO: treat holomap trajectories
if (needChangeScene == LBA1SceneId::Citadel_Island_end_sequence_1 || needChangeScene == LBA1SceneId::Citadel_Island_end_sequence_2) {
- _engine->_text->currentTextBank = 10;
+ _engine->_scene->sceneTextBank = TextBankId::Tippet_Island;
}
- _engine->_text->initTextBank(_engine->_text->currentTextBank + 3);
+ _engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
_engine->_grid->initGrid(needChangeScene);
if (heroPositionType == ScenePositionType::kZone) {
diff --git a/engines/twine/scene.h b/engines/twine/scene.h
index 87c940dd9b..9716a66828 100644
--- a/engines/twine/scene.h
+++ b/engines/twine/scene.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/util.h"
#include "twine/actor.h"
+#include "twine/text.h"
namespace TwinE {
@@ -251,6 +252,7 @@ public:
int32 currentSceneIdx = LBA1SceneId::Citadel_Island_Prison;
int32 previousSceneIdx = LBA1SceneId::Citadel_Island_Prison;
+ int32 sceneTextBank = TextBankId::None;
int32 currentGameOverScene = 0;
int32 alphaLight = 0;
int32 betaLight = 0;
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index c15e25684d..488b0733ee 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -31,6 +31,7 @@
#include "twine/renderer.h"
#include "twine/resources.h"
#include "twine/screens.h"
+#include "twine/scene.h"
#include "twine/sound.h"
#include "twine/twine.h"
@@ -717,7 +718,7 @@ void Text::copyText(const char *src, char *dst, int32 size) {
bool Text::getMenuText(int32 index, char *text, uint32 textSize) {
if (index == _engine->_menu->currMenuTextIndex) {
- if (_engine->_menu->currMenuTextBank == currentTextBank) {
+ if (_engine->_menu->currMenuTextBank == _engine->_scene->sceneTextBank) {
Common::strlcpy(text, _engine->_menu->currMenuTextBuffer, textSize);
return true;
}
@@ -737,7 +738,7 @@ bool Text::getMenuText(int32 index, char *text, uint32 textSize) {
copyText(text, _engine->_menu->currMenuTextBuffer, currDialTextSize);
_engine->_menu->currMenuTextIndex = index;
- _engine->_menu->currMenuTextBank = currentTextBank;
+ _engine->_menu->currMenuTextBank = _engine->_scene->sceneTextBank;
return true;
}
diff --git a/engines/twine/text.h b/engines/twine/text.h
index ad673adb88..2da619c1c2 100644
--- a/engines/twine/text.h
+++ b/engines/twine/text.h
@@ -140,7 +140,7 @@ private:
void copyText(const char *src, char *dst, int32 size);
// RECHECK THIS LATER
- int32 currentBankIdx = -1; // textVar1
+ int32 currentBankIdx = TextBankId::None; // textVar1
char textVar2[256] {'\0'};
/** Dialogue text pointer */
@@ -178,9 +178,6 @@ private:
public:
Text(TwinEEngine *engine) : _engine(engine) {}
- /** Current text bank */
- int32 currentTextBank = -1;
-
/** Dialogue text size */
int32 dialTextSize = 0;
/** Pixel size between dialogue text */
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 9fb51255c3..39ee1f05d2 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -506,7 +506,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
cfgfile.FlagDisplayText = tmpFlagDisplayText;
_text->textClipSmall();
_text->newGameVar4 = 1;
- _text->initTextBank(_text->currentTextBank + 3);
+ _text->initTextBank(_scene->sceneTextBank + 3);
_screens->fadeToBlack(_screens->paletteRGBACustom);
_screens->clearScreen();
flip();
@@ -557,7 +557,7 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
_text->setFontCrossColor(15);
_text->drawTextFullscreen(162);
_text->textClipSmall();
- _text->initTextBank(_text->currentTextBank + 3);
+ _text->initTextBank(_scene->sceneTextBank + 3);
break;
}
case kiCloverLeaf:
Commit: f560390f7e22149ffaad0ff37872a9760bc00871
https://github.com/scummvm/scummvm/commit/f560390f7e22149ffaad0ff37872a9760bc00871
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: implement load-savegame menu
also save game loading from launcher is supported now
Changed paths:
engines/twine/gamestate.cpp
engines/twine/menu.cpp
engines/twine/menu.h
engines/twine/menuoptions.cpp
engines/twine/menuoptions.h
engines/twine/metaengine.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 8ce6d8c644..180e63d5ba 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -53,7 +53,7 @@ GameState::GameState(TwinEEngine *engine) : _engine(engine) {
Common::fill(&gameFlags[0], &gameFlags[256], 0);
Common::fill(&inventoryFlags[0], &inventoryFlags[NUM_INVENTORY_ITEMS], 0);
Common::fill(&holomapFlags[0], &holomapFlags[150], 0);
- playerName[0] = 0;
+ playerName[0] = '\0';
Common::fill(&gameChoices[0], &gameChoices[10], 0);
}
@@ -172,6 +172,8 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
return false;
}
+ initEngineVars();
+
file->skip(1); // skip save game id
int playerNameIdx = 0;
@@ -192,7 +194,7 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
warning("Failed to load gameflags. Expected %u, but got %u", NUM_GAME_FLAGS, numGameFlags);
return false;
}
- file->read(gameFlags, numGameFlags);
+ file->read(gameFlags, NUM_GAME_FLAGS);
_engine->_scene->needChangeScene = file->readByte(); // scene index
gameChapter = file->readByte();
@@ -210,21 +212,22 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
_engine->_actor->previousHeroAngle = _engine->_scene->sceneHero->angle;
_engine->_scene->sceneHero->body = file->readByte();
- const byte numHolemapFlags = file->readByte(); // number of holomap locations, always 150
- if (numHolemapFlags != ARRAYSIZE(holomapFlags)) {
- warning("Failed to load holomapflags");
+ const byte numHolomapFlags = file->readByte(); // number of holomap locations, always 150
+ const int32 expectedHolomapFlagsSize = sizeof(holomapFlags);
+ if (numHolomapFlags != expectedHolomapFlagsSize) {
+ warning("Failed to load holomapflags. Got %u, expected %i", numHolomapFlags, expectedHolomapFlagsSize);
return false;
}
- file->read(holomapFlags, numHolemapFlags);
+ file->read(holomapFlags, sizeof(holomapFlags));
inventoryNumGas = file->readByte();
const byte numInventoryFlags = file->readByte(); // number of used inventory items, always 28
if (numInventoryFlags != NUM_INVENTORY_ITEMS) {
- warning("Failed to load inventoryFlags");
+ warning("Failed to load inventoryFlags. Got %u, expected %i", numInventoryFlags, NUM_INVENTORY_ITEMS);
return false;
}
- file->read(inventoryFlags, numInventoryFlags);
+ file->read(inventoryFlags, NUM_INVENTORY_ITEMS);
inventoryNumLeafs = file->readByte();
usingSabre = file->readByte();
@@ -243,7 +246,7 @@ bool GameState::saveGame(Common::WriteStream *file) {
file->writeString(playerName);
file->writeByte('\0');
file->writeByte(NUM_GAME_FLAGS);
- file->write(gameFlags, sizeof(gameFlags));
+ file->write(gameFlags, NUM_GAME_FLAGS);
file->writeByte(_engine->_scene->currentSceneIdx);
file->writeByte(gameChapter);
file->writeByte(_engine->_actor->heroBehaviour);
@@ -259,14 +262,14 @@ bool GameState::saveGame(Common::WriteStream *file) {
file->writeByte(_engine->_scene->sceneHero->body);
// number of holomap locations
- file->writeByte(ARRAYSIZE(holomapFlags));
+ file->writeByte(sizeof(holomapFlags));
file->write(holomapFlags, sizeof(holomapFlags));
file->writeByte(inventoryNumGas);
// number of inventory items
- file->writeByte(ARRAYSIZE(inventoryFlags));
- file->write(inventoryFlags, sizeof(inventoryFlags));
+ file->writeByte(NUM_INVENTORY_ITEMS);
+ file->write(inventoryFlags, NUM_INVENTORY_ITEMS);
file->writeByte(inventoryNumLeafs);
file->writeByte(usingSabre);
diff --git a/engines/twine/menu.cpp b/engines/twine/menu.cpp
index 2e8609b0f2..a56c0a2135 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu.cpp
@@ -147,13 +147,14 @@ static MenuSettings createVolumeMenu() {
} // namespace _priv
-const char *MenuSettings::getButtonText(Text *text, int buttonIndex) const {
- const int32 textId = getButtonTextId(buttonIndex);
- static char dialText[256];
- if (!text->getMenuText(textId, dialText, sizeof(dialText))) {
- dialText[0] = '\0';
+const char *MenuSettings::getButtonText(Text *text, int buttonIndex) {
+ if (_buttonTexts[buttonIndex].empty()) {
+ const int32 textId = getButtonTextId(buttonIndex);
+ char dialText[256] = "";
+ text->getMenuText(textId, dialText, sizeof(dialText));
+ _buttonTexts[buttonIndex] = dialText;
}
- return dialText;
+ return _buttonTexts[buttonIndex].c_str();
}
Menu::Menu(TwinEEngine *engine) {
@@ -307,7 +308,7 @@ void Menu::drawButtonGfx(int32 width, int32 topheight, int32 buttonId, const cha
_engine->copyBlockPhys(left, top, right, bottom);
}
-void Menu::drawButtons(const MenuSettings *menuSettings, bool hover) {
+void Menu::drawButtons(MenuSettings *menuSettings, bool hover) {
int16 buttonNumber = menuSettings->getActiveButton();
const int32 maxButton = menuSettings->getButtonCount();
int32 topHeight = menuSettings->getButtonBoxHeight();
@@ -496,7 +497,6 @@ int32 Menu::processMenu(MenuSettings *menuSettings) {
if (_engine->shouldQuit()) {
return kQuitEngine;
}
- // TODO: update volume settings
_engine->_system->delayMillis(10);
} while (!_engine->_input->toggleActionIfActive(TwinEActionType::UIEnter));
@@ -536,10 +536,10 @@ int32 Menu::savemanageMenu() {
case TextId::kReturnMenu:
return 0;
case TextId::kCreateSaveGame:
- // TODO: implement save game handling and slot rendering
+ _engine->_menuOptions->saveGameMenu();
break;
case TextId::kDeleteSaveGame:
- // TODO: implement save game deletion and slot rendering
+ _engine->_menuOptions->deleteSaveMenu();
break;
case kQuitEngine:
return kQuitEngine;
@@ -688,7 +688,7 @@ int32 Menu::giveupMenu() {
_engine->_sound->stopSamples();
return 1;
case TextId::kCreateSaveGame:
- // TODO: handle save game creation
+ _engine->_menuOptions->saveGameMenu();
break;
case kQuitEngine:
return kQuitEngine;
diff --git a/engines/twine/menu.h b/engines/twine/menu.h
index 2d6c1ba3bd..272ad03af3 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu.h
@@ -29,6 +29,7 @@
namespace TwinE {
+#define MAX_BUTTONS 10
#define PLASMA_WIDTH 320
#define PLASMA_HEIGHT 50
#define kQuitEngine 9998
@@ -46,7 +47,8 @@ private:
MenuSettings_FirstButton = 5
};
- int16 _settings[100] {0};
+ int16 _settings[4 + MAX_BUTTONS * 2] {0};
+ Common::String _buttonTexts[MAX_BUTTONS];
int8 _activeButtonIdx = 0;
int16 getButtonTextId(int buttonIndex) const {
@@ -55,6 +57,9 @@ private:
public:
void reset() {
+ for (int32 i = 0; i < MAX_BUTTONS; ++i) {
+ _buttonTexts[i] = "";
+ }
_settings[MenuSettings_NumberOfButtons] = 0;
setButtonsBoxHeight(0);
setActiveButton(0);
@@ -90,7 +95,7 @@ public:
return _settings[MenuSettings_FirstButtonState + buttonIndex * 2];
}
- const char *getButtonText(Text *text, int buttonIndex) const;
+ const char *getButtonText(Text *text, int buttonIndex);
int16 getActiveButton() const {
return _activeButtonIdx;
@@ -114,6 +119,15 @@ public:
_settings[i * 2 + MenuSettings_FirstButton] = textId;
++_settings[MenuSettings_NumberOfButtons];
}
+
+ void addButton(const char *text, int16 state = 0) {
+ const int16 i = _settings[MenuSettings_NumberOfButtons];
+ _settings[i * 2 + MenuSettings_FirstButtonState] = state;
+ // will return the button index
+ _settings[i * 2 + MenuSettings_FirstButton] = i;
+ _buttonTexts[i] = text;
+ ++_settings[MenuSettings_NumberOfButtons];
+ }
};
class Menu {
@@ -144,7 +158,7 @@ private:
* @param data menu settings array
* @param mode flag to know if should draw as a hover button or not
*/
- void drawButtons(const MenuSettings *menuSettings, bool hover);
+ void drawButtons(MenuSettings *menuSettings, bool hover);
/** Used to run the advanced options menu */
int32 advoptionsMenu();
/** Used to run the volume menu */
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menuoptions.cpp
index 4bacb6683c..7d51ea56c3 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menuoptions.cpp
@@ -26,6 +26,7 @@
#include "common/str-array.h"
#include "common/system.h"
#include "common/util.h"
+#include "savestate.h"
#include "twine/flamovies.h"
#include "twine/gamestate.h"
#include "twine/input.h"
@@ -191,8 +192,6 @@ public:
};
bool MenuOptions::enterPlayerName(int32 textIdx) {
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
playerName[0] = '\0'; // TODO: read from settings?
_engine->_text->initTextBank(TextBankId::Options_and_menus);
char buffer[256];
@@ -312,6 +311,8 @@ bool MenuOptions::enterPlayerName(int32 textIdx) {
}
bool MenuOptions::newGameMenu() {
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
if (!enterPlayerName(TextId::kEnterYourName)) {
return false;
}
@@ -320,38 +321,87 @@ bool MenuOptions::newGameMenu() {
return true;
}
-int MenuOptions::chooseSave(int textIdx) {
- const Common::StringArray& savegames = _engine->getSaveSlots();
- if (savegames.empty()) {
+int MenuOptions::chooseSave(int textIdx, bool showEmptySlots) {
+ const SaveStateList& savegames = _engine->getSaveSlots();
+ if (savegames.empty() && !showEmptySlots) {
return -1;
}
- _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
- _engine->flip();
- do {
- // TODO: assemble menu with save slots and make then loadable.
- _engine->_text->initTextBank(TextBankId::Options_and_menus);
- char buffer[256];
- _engine->_text->getMenuText(textIdx, buffer, sizeof(buffer));
- _engine->_text->setFontColor(15);
- const int halfScreenWidth = (SCREEN_WIDTH / 2);
- _engine->_text->drawText(halfScreenWidth - (_engine->_text->getTextSize(buffer) / 2), 20, buffer);
- _engine->copyBlockPhys(0, 0, SCREEN_WIDTH - 1, 99);
- _engine->flip();
- if (_engine->shouldQuit()) {
- return kQuitEngine;
+ _engine->_text->initTextBank(TextBankId::Options_and_menus);
+
+ MenuSettings saveFiles;
+ saveFiles.addButton(TextId::kReturnMenu);
+
+ const int maxButtons = _engine->getMetaEngine().getMaximumSaveSlot() + 1;
+ for (const SaveStateDescriptor& savegame : savegames) {
+ saveFiles.addButton(savegame.getDescription().encode().c_str(), savegame.getSaveSlot());
+ if (saveFiles.getButtonCount() >= maxButtons) {
+ break;
}
- _engine->_system->delayMillis(1);
- } while (_engine->_input->toggleAbortAction());
+ }
+
+ if (showEmptySlots) {
+ while (saveFiles.getButtonCount() < maxButtons) {
+ saveFiles.addButton("EMPTY");
+ }
+ }
+
+ for (;;) {
+ const int32 id = _engine->_menu->processMenu(&saveFiles);
+ switch (id) {
+ case kQuitEngine:
+ case TextId::kReturnMenu:
+ return -1;
+ default:
+ // the first button is the back button - to subtract that one again to get the real slot index
+ return saveFiles.getButtonState(id);
+ }
+ }
- return 0;
+ return -1;
}
bool MenuOptions::continueGameMenu() {
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
const int slot = chooseSave(TextId::kContinueGame);
if (slot >= 0) {
- _engine->_gameState->initEngineVars();
- return _engine->loadGameState(slot).getCode() == Common::kNoError;
+ debug("Load slot %i", slot);
+ Common::Error state = _engine->loadGameState(slot);
+ if (state.getCode() != Common::kNoError) {
+ error("Failed to load slot %i", slot);
+ return false;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+bool MenuOptions::deleteSaveMenu() {
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
+ const int slot = chooseSave(TextId::kDeleteSaveGame);
+ if (slot >= 0) {
+ _engine->wipeSaveSlot(slot);
+ return true;
+ }
+ return false;
+}
+
+bool MenuOptions::saveGameMenu() {
+ _engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+ _engine->flip();
+ const int slot = chooseSave(TextId::kCreateSaveGame, true);
+ if (slot >= 0) {
+ // TODO: enter description
+ Common::Error state = _engine->saveGameState(slot, "description", false);
+ if (state.getCode() != Common::kNoError) {
+ error("Failed to save slot %i", slot);
+ return false;
+ }
+
+ return true;
}
return false;
}
diff --git a/engines/twine/menuoptions.h b/engines/twine/menuoptions.h
index f7e044eb80..9054eb1309 100644
--- a/engines/twine/menuoptions.h
+++ b/engines/twine/menuoptions.h
@@ -40,7 +40,7 @@ private:
void drawSelectableCharacters();
void drawPlayerName(int32 centerx, int32 top, int32 type);
void drawSelectableCharacter(int32 x, int32 y, bool selected);
- int chooseSave(int textIdx);
+ int chooseSave(int textIdx, bool showEmptySlots = false);
public:
MenuOptions(TwinEEngine *engine) : _engine(engine) {}
@@ -56,6 +56,8 @@ public:
/** Main menu continue game options */
bool continueGameMenu();
+ bool saveGameMenu();
+ bool deleteSaveMenu();
};
} // namespace TwinE
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index 3393169a51..a7bf21fcd6 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -41,6 +41,10 @@ public:
return "TwinE";
}
+ int getMaximumSaveSlot() const override {
+ return 6;
+ }
+
bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override {
if (desc) {
TwineGameType gameType = TwineGameType::GType_LBA;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 39ee1f05d2..058904c952 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -152,6 +152,16 @@ Common::Error TwinEEngine::run() {
_screens->copyScreen(frontVideoBuffer, workVideoBuffer);
_menu->init();
+
+ if (ConfMan.hasKey("save_slot")) {
+ const int saveSlot = ConfMan.getInt("save_slot");
+ if (saveSlot >= 0 && saveSlot <= 999) {
+ Common::Error state = loadGameState(saveSlot);
+ if (state.getCode() != Common::kNoError) {
+ return state;
+ }
+ }
+ }
while (!shouldQuit()) {
readKeys();
switch (_state) {
@@ -207,10 +217,8 @@ bool TwinEEngine::hasFeature(EngineFeature f) const {
return false;
}
-Common::StringArray TwinEEngine::getSaveSlots() {
- Common::SaveFileManager *saveFileMan = getSaveFileManager();
- const Common::String pattern(getMetaEngine().getSavegameFilePattern(_targetName.c_str()));
- return saveFileMan->listSavefiles(pattern);
+SaveStateList TwinEEngine::getSaveSlots() const {
+ return getMetaEngine().listSaves(_targetName.c_str());
}
void TwinEEngine::wipeSaveSlot(int slot) {
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 735f5c661b..071cc99289 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -184,7 +184,7 @@ public:
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
void wipeSaveSlot(int slot);
- Common::StringArray getSaveSlots();
+ SaveStateList getSaveSlots() const;
void autoSave();
bool isLBA1() const { return _gameType == TwineGameType::GType_LBA; };
Commit: d5e0874557b3b2966531d5c0edb80deb2262ddaa
https://github.com/scummvm/scummvm/commit/d5e0874557b3b2966531d5c0edb80deb2262ddaa
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:36+01:00
Commit Message:
TWINE: reduced visibility
Changed paths:
engines/twine/grid.cpp
engines/twine/interface.h
diff --git a/engines/twine/grid.cpp b/engines/twine/grid.cpp
index 53b7735a59..6b549e1472 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/grid.cpp
@@ -573,9 +573,9 @@ void Grid::getBrickPos(int32 x, int32 y, int32 z) {
void Grid::drawColumnGrid(int32 blockIdx, int32 brickBlockIdx, int32 x, int32 y, int32 z) {
const uint8 *blockPtr = getBlockLibrary(blockIdx) + 3 + brickBlockIdx * 4;
- uint8 brickShape = *((const uint8 *)(blockPtr + 0));
- uint8 brickSound = *((const uint8 *)(blockPtr + 1));
- uint16 brickIdx = *((const uint16 *)(blockPtr + 2));
+ const uint8 brickShape = *((const uint8 *)(blockPtr + 0));
+ const uint8 brickSound = *((const uint8 *)(blockPtr + 1));
+ const uint16 brickIdx = *((const uint16 *)(blockPtr + 2));
if (!brickIdx) {
return;
}
diff --git a/engines/twine/interface.h b/engines/twine/interface.h
index b3108194f1..d0e848dba7 100644
--- a/engines/twine/interface.h
+++ b/engines/twine/interface.h
@@ -42,17 +42,17 @@ class Interface {
private:
TwinEEngine *_engine;
int32 checkClipping(int32 x, int32 y);
+ int32 textWindowTopSave = 0;
+ int32 textWindowLeftSave = 0;
+ int32 textWindowRightSave = 0;
+ int32 textWindowBottomSave = 0;
public:
Interface(TwinEEngine *engine);
int32 textWindowTop = 0;
- int32 textWindowTopSave = 0;
int32 textWindowLeft = 0;
- int32 textWindowLeftSave = 0;
int32 textWindowRight = 0;
- int32 textWindowRightSave = 0;
int32 textWindowBottom = 0;
- int32 textWindowBottomSave = 0;
/**
* Draw button line
Commit: d3c2f7cd9132a773d899e51f564092c212099a75
https://github.com/scummvm/scummvm/commit/d3c2f7cd9132a773d899e51f564092c212099a75
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: added ScopedEngineFreeze
Changed paths:
engines/twine/extra.cpp
engines/twine/holomap.cpp
engines/twine/scene.cpp
engines/twine/script_life_v1.cpp
engines/twine/twine.cpp
engines/twine/twine.h
diff --git a/engines/twine/extra.cpp b/engines/twine/extra.cpp
index 7280ff8754..3794a08d45 100644
--- a/engines/twine/extra.cpp
+++ b/engines/twine/extra.cpp
@@ -534,7 +534,6 @@ void Extra::processMagicballBounce(ExtraListStruct *extra, int32 x, int32 y, int
extra->lifeTime = _engine->lbaTime;
}
-/** Process extras */
void Extra::processExtras() {
int32 currentExtraX = 0;
int32 currentExtraY = 0;
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 7578b8c924..f15ee1afcf 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -116,7 +116,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
}
void Holomap::processHolomap() {
- _engine->freezeTime();
+ ScopedEngineFreeze freeze(_engine);
// TODO memcopy palette
@@ -148,8 +148,6 @@ void Holomap::processHolomap() {
_engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
// TODO memcopy reset palette
-
- _engine->unfreezeTime();
}
} // namespace TwinE
diff --git a/engines/twine/scene.cpp b/engines/twine/scene.cpp
index 1f07896ecb..0b93ab2f69 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene.cpp
@@ -464,9 +464,8 @@ void Scene::processActorZones(int32 actorIdx) {
_engine->_grid->useCellingGrid = zone->infoData.CeillingGrid.newGrid;
_engine->_grid->cellingGridIdx = z;
- _engine->freezeTime();
+ ScopedEngineFreeze freeze(_engine);
_engine->_grid->initCellingGrid(_engine->_grid->useCellingGrid);
- _engine->unfreezeTime();
}
}
break;
diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script_life_v1.cpp
index 365c03243e..ef08c1cc15 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script_life_v1.cpp
@@ -1176,9 +1176,8 @@ static int32 lSAY_MESSAGE(TwinEEngine *engine, ScriptContext& ctx) {
engine->_redraw->addOverlay(koText, textEntry, 0, 0, ctx.actorIdx, koFollowActor, 2);
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
engine->_text->initVoxToPlay(textEntry);
- engine->unfreezeTime();
return 0;
}
@@ -1191,9 +1190,8 @@ static int32 lSAY_MESSAGE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
engine->_redraw->addOverlay(koText, textEntry, 0, 0, otherActorIdx, koFollowActor, 2);
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
engine->_text->initVoxToPlay(textEntry);
- engine->unfreezeTime();
return 0;
}
@@ -1228,63 +1226,57 @@ static int32 lGRM_OFF(TwinEEngine *engine, ScriptContext& ctx) {
/*0x52*/
static int32 lFADE_PAL_RED(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
engine->_screens->fadePalRed(engine->_screens->mainPaletteRGBA);
engine->_screens->useAlternatePalette = false;
- engine->unfreezeTime();
return 0;
}
/*0x53*/
static int32 lFADE_ALARM_RED(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->fadePalRed(engine->_screens->paletteRGBA);
engine->_screens->useAlternatePalette = true;
- engine->unfreezeTime();
return 0;
}
/*0x54*/
static int32 lFADE_ALARM_PAL(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->adjustCrossPalette(engine->_screens->paletteRGBA, engine->_screens->mainPaletteRGBA);
engine->_screens->useAlternatePalette = false;
- engine->unfreezeTime();
return 0;
}
/*0x55*/
static int32 lFADE_RED_PAL(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
engine->_screens->fadeRedPal(engine->_screens->mainPaletteRGBA);
engine->_screens->useAlternatePalette = false;
- engine->unfreezeTime();
return 0;
}
/*0x56*/
static int32 lFADE_RED_ALARM(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->fadeRedPal(engine->_screens->paletteRGBA);
engine->_screens->useAlternatePalette = true;
- engine->unfreezeTime();
return 0;
}
/*0x57*/
static int32 lFADE_PAL_ALARM(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_ALARMREDPAL);
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->_screens->adjustCrossPalette(engine->_screens->mainPaletteRGBA, engine->_screens->paletteRGBA);
engine->_screens->useAlternatePalette = true;
- engine->unfreezeTime();
return 0;
}
@@ -1331,14 +1323,13 @@ static int32 lASK_CHOICE_OBJ(TwinEEngine *engine, ScriptContext& ctx) {
/*0x5C*/
static int32 lSET_DARK_PAL(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
HQR::getEntry(engine->_screens->palette, Resources::HQR_RESS_FILE, RESSHQR_DARKPAL);
if (!engine->_screens->lockPalette) {
engine->_screens->convertPalToRGBA(engine->_screens->palette, engine->_screens->paletteRGBA);
engine->setPalette(engine->_screens->paletteRGBA);
}
engine->_screens->useAlternatePalette = true;
- engine->unfreezeTime();
return 0;
}
@@ -1353,7 +1344,7 @@ static int32 lSET_NORMAL_PAL(TwinEEngine *engine, ScriptContext& ctx) {
/*0x5E*/
static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext& ctx) {
- engine->freezeTime();
+ ScopedEngineFreeze scoped(engine);
engine->_screens->fadeToBlack(engine->_screens->paletteRGBA);
engine->_screens->loadImage(25);
engine->_text->textClipFull();
@@ -1374,8 +1365,6 @@ static int32 lMESSAGE_SENDELL(TwinEEngine *engine, ScriptContext& ctx) {
engine->_system->delayMillis(1);
} while (engine->_input->toggleAbortAction());
- engine->unfreezeTime();
-
return 0;
}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 058904c952..b99d32cba1 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -71,6 +71,14 @@
namespace TwinE {
+ScopedEngineFreeze::ScopedEngineFreeze(TwinEEngine* engine) : _engine(engine) {
+ _engine->freezeTime();
+}
+
+ScopedEngineFreeze::~ScopedEngineFreeze() {
+ _engine->unfreezeTime();
+}
+
TwinEEngine::TwinEEngine(OSystem *system, Common::Language language, uint32 flags, TwineGameType gameType)
: Engine(system), _gameType(gameType), _gameLang(language), _gameFlags(flags), _rnd("twine") {
// Add default file directories
@@ -452,10 +460,9 @@ int32 TwinEEngine::runGameEngine() { // mainLoopInteration
if (giveUp == 1) {
unfreezeTime();
_redraw->redrawEngineActions(1);
- freezeTime();
+ ScopedEngineFreeze freeze(this);
autoSave();
quitGame = 0;
- unfreezeTime();
return 0;
}
unfreezeTime();
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 071cc99289..a445a93754 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -161,6 +161,12 @@ enum class EngineState {
QuitGame
};
+struct ScopedEngineFreeze {
+ TwinEEngine* _engine;
+ ScopedEngineFreeze(TwinEEngine* engine);
+ ~ScopedEngineFreeze();
+};
+
class TwinEEngine : public Engine {
private:
int32 isTimeFreezed = 0;
Commit: a7f3a6345402f47f471718854946e0bc2f104917
https://github.com/scummvm/scummvm/commit/a7f3a6345402f47f471718854946e0bc2f104917
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: reduced scoped + const
Changed paths:
engines/twine/movements.cpp
engines/twine/redraw.cpp
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index 740c338930..264d843322 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -87,17 +87,16 @@ int32 Movements::getAngleAndSetTargetActorDistance(int32 x1, int32 z1, int32 x2,
return (256 + ((int32)floor((-1024 * atan2((int64)(z2-z1), (int32)(x2-x1))) / (2*M_PI)))) % 1024;
*/
- int32 newX, newZ, difX, difZ, tmpX, tmpZ, tmpEx, flag, destAngle, startAngle, finalAngle;
+ int32 difZ = z2 - z1;
+ const int32 newZ = difZ * difZ;
- difZ = tmpZ = z2 - z1;
- newZ = tmpZ * tmpZ;
-
- difX = tmpX = x2 - x1;
- newX = tmpX * tmpX;
+ int32 difX = x2 - x1;
+ const int32 newX = difX * difX;
+ int32 flag;
// Exchange X and Z
if (newX < newZ) {
- tmpEx = difX;
+ const int32 tmpEx = difX;
difX = difZ;
difZ = tmpEx;
@@ -112,9 +111,9 @@ int32 Movements::getAngleAndSetTargetActorDistance(int32 x1, int32 z1, int32 x2,
return 0;
}
- destAngle = (difZ << 14) / targetActorDistance;
+ const int32 destAngle = (difZ << 14) / targetActorDistance;
- startAngle = 0;
+ int32 startAngle = 0;
// stopAngle = 0x100;
while (_engine->_renderer->shadeAngleTab3[startAngle] > destAngle) {
@@ -127,13 +126,13 @@ int32 Movements::getAngleAndSetTargetActorDistance(int32 x1, int32 z1, int32 x2,
}
}
- finalAngle = 128 + startAngle;
+ int32 finalAngle = 128 + startAngle;
if (difX <= 0) {
finalAngle = -finalAngle;
}
- if (flag & 1) {
+ if (flag == 1) {
finalAngle = -finalAngle + 0x100;
}
@@ -142,7 +141,7 @@ int32 Movements::getAngleAndSetTargetActorDistance(int32 x1, int32 z1, int32 x2,
int32 Movements::getRealAngle(ActorMoveStruct *movePtr) {
if (movePtr->numOfStep) {
- int32 timePassed = _engine->lbaTime - movePtr->timeOfChange;
+ const int32 timePassed = _engine->lbaTime - movePtr->timeOfChange;
if (timePassed >= movePtr->numOfStep) { // rotation is finished
movePtr->numOfStep = 0;
@@ -161,7 +160,7 @@ int32 Movements::getRealAngle(ActorMoveStruct *movePtr) {
remainingAngle /= movePtr->numOfStep;
remainingAngle += movePtr->from;
- return (remainingAngle);
+ return remainingAngle;
}
return movePtr->to;
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index ba89437f3c..ed8635b9e9 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -439,12 +439,12 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
// Drawing sprite actors
else if (flags == 0x1000) {
- int32 spriteWidth, spriteHeight;
- uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
+ const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
// get actor position on screen
_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
+ int32 spriteWidth, spriteHeight;
_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
// calculate sprite position on screen
@@ -562,9 +562,9 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
// process overlay type
switch (overlay->type) {
case koSprite: {
- int32 spriteWidth, spriteHeight;
- uint8 *spritePtr = _engine->_resources->spriteTable[overlay->info0];
+ const uint8 *spritePtr = _engine->_resources->spriteTable[overlay->info0];
+ int32 spriteWidth, spriteHeight;
_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
const int16 offsetX = *((const int16 *)(_engine->_resources->spriteBoundingBoxPtr + (overlay->info0 * 16)));
@@ -586,8 +586,8 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
char text[10];
snprintf(text, sizeof(text), "%d", overlay->info0);
- int32 textLength = _engine->_text->getTextSize(text);
- int32 textHeight = 48;
+ const int32 textLength = _engine->_text->getTextSize(text);
+ const int32 textHeight = 48;
renderLeft = overlay->x - (textLength / 2);
renderTop = overlay->y - 24;
@@ -606,14 +606,13 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
break;
}
case koNumberRange: {
- char text[10];
-
- int32 range = _engine->_collision->getAverageValue(overlay->info1, overlay->info0, 100, overlay->lifeTime - _engine->lbaTime - 50);
+ const int32 range = _engine->_collision->getAverageValue(overlay->info1, overlay->info0, 100, overlay->lifeTime - _engine->lbaTime - 50);
+ char text[10];
sprintf(text, "%d", range);
- int32 textLength = _engine->_text->getTextSize(text);
- int32 textHeight = 48;
+ const int32 textLength = _engine->_text->getTextSize(text);
+ const int32 textHeight = 48;
renderLeft = overlay->x - (textLength / 2);
renderTop = overlay->y - 24;
@@ -632,7 +631,7 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
break;
}
case koInventoryItem: {
- int32 item = overlay->info0;
+ const int32 item = overlay->info0;
_engine->_interface->drawSplittedBox(10, 10, 69, 69, 0);
_engine->_interface->setClip(10, 10, 69, 69);
@@ -651,11 +650,10 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
case koText: {
char text[256];
-
_engine->_text->getMenuText(overlay->info0, text, sizeof(text));
- int32 textLength = _engine->_text->getTextSize(text);
- int32 textHeight = 48;
+ const int32 textLength = _engine->_text->getTextSize(text);
+ const int32 textHeight = 48;
renderLeft = overlay->x - (textLength / 2);
renderTop = overlay->y - 24;
@@ -725,8 +723,6 @@ void Redraw::redrawEngineActions(int32 bgRedraw) { // fullRedraw
}
void Redraw::drawBubble(int32 actorIdx) {
- int32 spriteWidth, spriteHeight;
- uint8 *spritePtr;
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
// get actor position on screen
@@ -737,7 +733,8 @@ void Redraw::drawBubble(int32 actorIdx) {
bubbleActor = actorIdx;
}
- spritePtr = _engine->_resources->spriteTable[bubbleSpriteIndex];
+ const uint8 *spritePtr = _engine->_resources->spriteTable[bubbleSpriteIndex];
+ int32 spriteWidth, spriteHeight;
_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
// calculate sprite position on screen
Commit: d66db9ad128b8d79048fee07c4f7117a7ea65856
https://github.com/scummvm/scummvm/commit/d66db9ad128b8d79048fee07c4f7117a7ea65856
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: started to implement holomap location loading
Changed paths:
engines/twine/holomap.cpp
engines/twine/holomap.h
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index f15ee1afcf..04412e3dc8 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -21,7 +21,9 @@
*/
#include "twine/holomap.h"
+#include "common/memstream.h"
#include "twine/gamestate.h"
+#include "twine/hqr.h"
#include "twine/interface.h"
#include "twine/renderer.h"
#include "twine/resources.h"
@@ -35,6 +37,30 @@ namespace TwinE {
Holomap::Holomap(TwinEEngine *engine) : _engine(engine) {}
+bool Holomap::loadLocations() {
+ uint8 *locationsPtr;
+ const int32 locationsSize = HQR::getAllocEntry(&locationsPtr, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWINFO);
+ if (locationsSize == 0) {
+ warning("Could not find holomap locations at index %i in %s", RESSHQR_HOLOARROWINFO, Resources::HQR_RESS_FILE);
+ return false;
+ }
+
+ Common::MemoryReadStream stream(locationsPtr, locationsSize);
+ _numLocations = locationsSize / sizeof(Location);
+ if (_numLocations > NUM_LOCATIONS) {
+ warning("Amount of locations (%i) exceeds the maximum of %i", _numLocations, NUM_LOCATIONS);
+ return false;
+ }
+
+ for (int i = 0; i < _numLocations; i++) {
+ _locations[i].x = stream.readUint16LE();
+ _locations[i].y = stream.readUint16LE();
+ _locations[i].z = stream.readUint16LE();
+ _locations[i].textIndex = stream.readUint16LE();
+ }
+ return true;
+}
+
void Holomap::setHolomapPosition(int32 locationIdx) {
assert(locationIdx >= 0 && locationIdx <= ARRAYSIZE(_engine->_gameState->holomapFlags));
_engine->_gameState->holomapFlags[locationIdx] = 0x81;
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index 09c3fd46f5..00d8abe270 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -28,12 +28,24 @@
namespace TwinE {
+#define NUM_LOCATIONS 150
+
class TwinEEngine;
class Holomap {
private:
TwinEEngine *_engine;
+ struct Location {
+ uint16 x = 0;
+ uint16 y = 0;
+ uint16 z = 0;
+ uint16 textIndex = 0;
+ };
+
+ int32 _numLocations = 0;
+ Location _locations[NUM_LOCATIONS];
+
int32 needToLoadHolomapGFX = 0;
uint8 paletteHolomap[NUMOFCOLORS * 3]{0};
@@ -46,6 +58,8 @@ public:
*/
void setHolomapPosition(int32 locationIdx);
+ bool loadLocations();
+
/**
* Clear Holomap location position
* @param locationIdx Scene where position must be cleared
Commit: 688e4a73495833a0c651d76d3a378892dce918a3
https://github.com/scummvm/scummvm/commit/688e4a73495833a0c651d76d3a378892dce918a3
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: replaced magic number
Changed paths:
engines/twine/gamestate.cpp
engines/twine/gamestate.h
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index 180e63d5ba..e4b155abe2 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -212,13 +212,12 @@ bool GameState::loadGame(Common::SeekableReadStream *file) {
_engine->_actor->previousHeroAngle = _engine->_scene->sceneHero->angle;
_engine->_scene->sceneHero->body = file->readByte();
- const byte numHolomapFlags = file->readByte(); // number of holomap locations, always 150
- const int32 expectedHolomapFlagsSize = sizeof(holomapFlags);
- if (numHolomapFlags != expectedHolomapFlagsSize) {
- warning("Failed to load holomapflags. Got %u, expected %i", numHolomapFlags, expectedHolomapFlagsSize);
+ const byte numHolomapFlags = file->readByte(); // number of holomap locations
+ if (numHolomapFlags != NUM_LOCATIONS) {
+ warning("Failed to load holomapflags. Got %u, expected %i", numHolomapFlags, NUM_LOCATIONS);
return false;
}
- file->read(holomapFlags, sizeof(holomapFlags));
+ file->read(holomapFlags, NUM_LOCATIONS);
inventoryNumGas = file->readByte();
@@ -262,8 +261,8 @@ bool GameState::saveGame(Common::WriteStream *file) {
file->writeByte(_engine->_scene->sceneHero->body);
// number of holomap locations
- file->writeByte(sizeof(holomapFlags));
- file->write(holomapFlags, sizeof(holomapFlags));
+ file->writeByte(NUM_LOCATIONS);
+ file->write(holomapFlags, NUM_LOCATIONS);
file->writeByte(inventoryNumGas);
diff --git a/engines/twine/gamestate.h b/engines/twine/gamestate.h
index 2a6e5f2b03..97dbb72d83 100644
--- a/engines/twine/gamestate.h
+++ b/engines/twine/gamestate.h
@@ -27,6 +27,7 @@
#include "common/scummsys.h"
#include "twine/actor.h"
#include "twine/menu.h"
+#include "twine/holomap.h"
namespace TwinE {
@@ -123,7 +124,7 @@ public:
/** Inventory used flags */
uint8 inventoryFlags[NUM_INVENTORY_ITEMS];
- uint8 holomapFlags[150]; // GV14
+ uint8 holomapFlags[NUM_LOCATIONS]; // GV14
char playerName[30];
Commit: 0488fe67c4d658d05ed229a0772403f736e25b39
https://github.com/scummvm/scummvm/commit/0488fe67c4d658d05ed229a0772403f736e25b39
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: reduced cyclic complexity
Changed paths:
engines/twine/animations.cpp
engines/twine/collision.cpp
engines/twine/extra.cpp
engines/twine/gamestate.cpp
diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index bb41cd4a3b..00235bfbb9 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -359,7 +359,7 @@ int32 Animations::getBodyAnimIndex(AnimationTypes animIdx, int32 actorIdx) {
int8 type = *(bodyPtr++);
if (type == -1) {
- currentActorAnimExtraPtr = NULL;
+ currentActorAnimExtraPtr = nullptr;
return -1;
}
@@ -533,15 +533,15 @@ void Animations::processAnimActions(int32 actorIdx) {
case ACTION_THROW_EXTRA_BONUS: {
animPos = stream.readByte();
const int32 yHeight = stream.readSint16LE();
- const int32 var_C = stream.readByte();
+ const int32 sprite = stream.readByte();
const int32 cx = stream.readSint16LE();
const int32 dx = actor->angle + stream.readSint16LE();
const int32 var_24 = stream.readSint16LE();
const int32 var_14 = stream.readByte();
- const int32 var = stream.readByte();
+ const int32 strengthOfHit = stream.readByte();
if (animPos == actor->animPosition) {
- _engine->_extra->addExtraThrow(actorIdx, actor->x, actor->y + yHeight, actor->z, var_C, cx, dx, var_24, var_14, var);
+ _engine->_extra->addExtraThrow(actorIdx, actor->x, actor->y + yHeight, actor->z, sprite, cx, dx, var_24, var_14, strengthOfHit);
}
break;
}
diff --git a/engines/twine/collision.cpp b/engines/twine/collision.cpp
index ec6fa13391..dc122bd38a 100644
--- a/engines/twine/collision.cpp
+++ b/engines/twine/collision.cpp
@@ -184,16 +184,16 @@ void Collision::reajustActorPosition(int32 brickShape) {
if (brickShape >= kStairsTopLeft && brickShape <= kStairsBottomRight) {
switch (brickShape) {
case kStairsTopLeft:
- _engine->_movements->processActorY = brkY + getAverageValue(0, 0x100, 0x200, _engine->_movements->processActorX - brkX);
+ _engine->_movements->processActorY = brkY + getAverageValue(0, 256, 512, _engine->_movements->processActorX - brkX);
break;
case kStairsTopRight:
- _engine->_movements->processActorY = brkY + getAverageValue(0, 0x100, 0x200, _engine->_movements->processActorZ - brkZ);
+ _engine->_movements->processActorY = brkY + getAverageValue(0, 256, 512, _engine->_movements->processActorZ - brkZ);
break;
case kStairsBottomLeft:
- _engine->_movements->processActorY = brkY + getAverageValue(0x100, 0, 0x200, _engine->_movements->processActorZ - brkZ);
+ _engine->_movements->processActorY = brkY + getAverageValue(256, 0, 512, _engine->_movements->processActorZ - brkZ);
break;
case kStairsBottomRight:
- _engine->_movements->processActorY = brkY + getAverageValue(0x100, 0, 0x200, _engine->_movements->processActorX - brkX);
+ _engine->_movements->processActorY = brkY + getAverageValue(256, 0, 512, _engine->_movements->processActorX - brkX);
break;
default:
break;
diff --git a/engines/twine/extra.cpp b/engines/twine/extra.cpp
index 3794a08d45..6a4f5bbbea 100644
--- a/engines/twine/extra.cpp
+++ b/engines/twine/extra.cpp
@@ -196,7 +196,7 @@ void Extra::addExtraSpecial(int32 x, int32 y, int32 z, ExtraSpecialType type) {
extra->z = z;
// same as InitFly
- throwExtra(extra, _engine->getRandomNumber(0x100) + 0x80, _engine->getRandomNumber(0x400), 50, 20);
+ throwExtra(extra, _engine->getRandomNumber(256) + 128, _engine->getRandomNumber(1024), 50, 20);
extra->strengthOfHit = 0;
extra->lifeTime = _engine->lbaTime;
@@ -543,182 +543,203 @@ void Extra::processExtras() {
for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
ExtraListStruct *extra = &extraList[i];
- if (extra->info0 != -1) {
- // process extra life time
- if (extra->type & 0x1) {
- if (extra->actorIdx + extra->lifeTime <= _engine->lbaTime) {
- extra->info0 = -1;
- continue;
- }
- }
- // reset extra
- if (extra->type & 0x800) {
+ if (extra->info0 == -1) {
+ continue;
+ }
+ // process extra life time
+ if (extra->type & 0x1) {
+ if (extra->actorIdx + extra->lifeTime <= _engine->lbaTime) {
extra->info0 = -1;
continue;
}
- //
- if (extra->type & 0x1000) {
- extra->info0 = _engine->_collision->getAverageValue(97, 100, 30, _engine->lbaTime - extra->lifeTime);
- continue;
- }
- // process extra moving
- if (extra->type & 0x2) {
- currentExtraX = extra->x;
- currentExtraY = extra->y;
- currentExtraZ = extra->z;
-
- currentExtraSpeedX = extra->destX * (_engine->lbaTime - extra->lifeTime);
- extra->x = currentExtraSpeedX + extra->lastX;
+ }
+ // reset extra
+ if (extra->type & 0x800) {
+ extra->info0 = -1;
+ continue;
+ }
+ //
+ if (extra->type & 0x1000) {
+ extra->info0 = _engine->_collision->getAverageValue(97, 100, 30, _engine->lbaTime - extra->lifeTime);
+ continue;
+ }
+ // process extra moving
+ if (extra->type & 0x2) {
+ currentExtraX = extra->x;
+ currentExtraY = extra->y;
+ currentExtraZ = extra->z;
- currentExtraSpeedY = extra->destY * (_engine->lbaTime - extra->lifeTime);
- currentExtraSpeedY += extra->lastY;
- extra->y = currentExtraSpeedY - ABS(((extra->angle * (_engine->lbaTime - extra->lifeTime)) * (_engine->lbaTime - extra->lifeTime)) >> 4);
+ currentExtraSpeedX = extra->destX * (_engine->lbaTime - extra->lifeTime);
+ extra->x = currentExtraSpeedX + extra->lastX;
- extra->z = extra->destZ * (_engine->lbaTime - extra->lifeTime) + extra->lastZ;
+ currentExtraSpeedY = extra->destY * (_engine->lbaTime - extra->lifeTime);
+ currentExtraSpeedY += extra->lastY;
+ extra->y = currentExtraSpeedY - ABS(((extra->angle * (_engine->lbaTime - extra->lifeTime)) * (_engine->lbaTime - extra->lifeTime)) >> 4);
- // check if extra is out of scene
- if (extra->y < 0 || extra->x < 0 || extra->x > 0x7E00 || extra->z < 0 || extra->z > 0x7E00) {
- // if extra is Magic Ball
- if (i == _engine->_gameState->magicBallIdx) {
- int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+ extra->z = extra->destZ * (_engine->lbaTime - extra->lifeTime) + extra->lastZ;
- if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
- spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
- }
- if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
- spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
- }
+ // check if extra is out of scene
+ if (extra->y < 0 || extra->x < 0 || extra->x > 0x7E00 || extra->z < 0 || extra->z > 0x7E00) {
+ // if extra is Magic Ball
+ if (i == _engine->_gameState->magicBallIdx) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
- _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
}
-
- // if can take extra on ground
- if (extra->type & 0x20) {
- extra->type &= 0xFFED;
- } else {
- extra->info0 = -1;
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- continue;
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
}
- }
- //
- if (extra->type & 0x4000) {
- if (_engine->lbaTime - extra->lifeTime > 40) {
- extra->type &= 0xBFFF;
+
+ // if can take extra on ground
+ if (extra->type & 0x20) {
+ extra->type &= 0xFFED;
+ } else {
+ extra->info0 = -1;
}
+
continue;
}
- // process actor target hit
- if (extra->type & 0x80) {
- int32 actorIdxAttacked = extra->lifeTime;
- int32 actorIdx = extra->actorIdx;
-
- const ActorStruct *actor = _engine->_scene->getActor(actorIdxAttacked);
- currentExtraX = actor->x;
- currentExtraY = actor->y + 1000;
- currentExtraZ = actor->z;
-
- int32 tmpAngle = _engine->_movements->getAngleAndSetTargetActorDistance(extra->x, extra->z, currentExtraX, currentExtraZ);
- int32 angle = (tmpAngle - extra->angle) & 0x3FF;
-
- if (angle > 400 && angle < 600) {
- if (extra->strengthOfHit) {
- _engine->_actor->hitActor(actorIdx, actorIdxAttacked, extra->strengthOfHit, -1);
- }
-
- if (i == _engine->_gameState->magicBallIdx) {
- _engine->_gameState->magicBallIdx = -1;
- }
-
- extra->info0 = -1;
- continue;
+ }
+ //
+ if (extra->type & 0x4000) {
+ if (_engine->lbaTime - extra->lifeTime > 40) {
+ extra->type &= 0xBFFF;
+ }
+ continue;
+ }
+ // process actor target hit
+ if (extra->type & 0x80) {
+ int32 actorIdxAttacked = extra->lifeTime;
+ int32 actorIdx = extra->actorIdx;
+
+ const ActorStruct *actor = _engine->_scene->getActor(actorIdxAttacked);
+ currentExtraX = actor->x;
+ currentExtraY = actor->y + 1000;
+ currentExtraZ = actor->z;
+
+ int32 tmpAngle = _engine->_movements->getAngleAndSetTargetActorDistance(extra->x, extra->z, currentExtraX, currentExtraZ);
+ int32 angle = (tmpAngle - extra->angle) & 0x3FF;
+
+ if (angle > 400 && angle < 600) {
+ if (extra->strengthOfHit) {
+ _engine->_actor->hitActor(actorIdx, actorIdxAttacked, extra->strengthOfHit, -1);
}
- const int32 angle2 = _engine->_movements->getAngleAndSetTargetActorDistance(extra->y, 0, currentExtraY, _engine->_movements->targetActorDistance);
- int32 pos = _engine->_movements->getRealAngle(&extra->trackActorMove);
- if (!pos) {
- pos = 1;
+ if (i == _engine->_gameState->magicBallIdx) {
+ _engine->_gameState->magicBallIdx = -1;
}
- _engine->_movements->rotateActor(pos, 0, angle2);
- extra->y -= _engine->_renderer->destZ;
+ extra->info0 = -1;
+ continue;
+ }
- _engine->_movements->rotateActor(0, _engine->_renderer->destX, tmpAngle);
- extra->x += _engine->_renderer->destX;
- extra->z += _engine->_renderer->destZ;
+ const int32 angle2 = _engine->_movements->getAngleAndSetTargetActorDistance(extra->y, 0, currentExtraY, _engine->_movements->targetActorDistance);
+ int32 pos = _engine->_movements->getRealAngle(&extra->trackActorMove);
+ if (!pos) {
+ pos = 1;
+ }
- _engine->_movements->setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+ _engine->_movements->rotateActor(pos, 0, angle2);
+ extra->y -= _engine->_renderer->destZ;
- if (actorIdxAttacked == _engine->_collision->checkExtraCollisionWithActors(extra, actorIdx)) {
- if (i == _engine->_gameState->magicBallIdx) {
- _engine->_gameState->magicBallIdx = -1;
- }
+ _engine->_movements->rotateActor(0, _engine->_renderer->destX, tmpAngle);
+ extra->x += _engine->_renderer->destX;
+ extra->z += _engine->_renderer->destZ;
- extra->info0 = -1;
- continue;
+ _engine->_movements->setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+
+ if (actorIdxAttacked == _engine->_collision->checkExtraCollisionWithActors(extra, actorIdx)) {
+ if (i == _engine->_gameState->magicBallIdx) {
+ _engine->_gameState->magicBallIdx = -1;
}
+
+ extra->info0 = -1;
+ continue;
}
- // process magic ball extra aiming for key
- if (extra->type & 0x200) {
- // int32 actorIdxAttacked = extra->lifeTime;
- ExtraListStruct *extraKey = &extraList[extra->actorIdx];
- int32 actorIdx = extra->actorIdx;
+ }
+ // process magic ball extra aiming for key
+ if (extra->type & 0x200) {
+ // int32 actorIdxAttacked = extra->lifeTime;
+ ExtraListStruct *extraKey = &extraList[extra->actorIdx];
+ int32 actorIdx = extra->actorIdx;
- int32 tmpAngle = _engine->_movements->getAngleAndSetTargetActorDistance(extra->x, extra->z, extraKey->x, extraKey->z);
- int32 angle = (tmpAngle - extra->angle) & 0x3FF;
+ int32 tmpAngle = _engine->_movements->getAngleAndSetTargetActorDistance(extra->x, extra->z, extraKey->x, extraKey->z);
+ int32 angle = (tmpAngle - extra->angle) & 0x3FF;
- if (angle > 400 && angle < 600) {
- _engine->_sound->playSample(Samples::ItemFound, 4096, 1, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->y, _engine->_scene->sceneHero->z, 0);
+ if (angle > 400 && angle < 600) {
+ _engine->_sound->playSample(Samples::ItemFound, 4096, 1, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->y, _engine->_scene->sceneHero->z, 0);
- if (extraKey->info1 > 1) {
- _engine->_renderer->projectPositionOnScreen(extraKey->x - _engine->_grid->cameraX, extraKey->y - _engine->_grid->cameraY, extraKey->z - _engine->_grid->cameraZ);
- _engine->_redraw->addOverlay(koNumber, extraKey->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, koNormal, 0, 2);
- }
+ if (extraKey->info1 > 1) {
+ _engine->_renderer->projectPositionOnScreen(extraKey->x - _engine->_grid->cameraX, extraKey->y - _engine->_grid->cameraY, extraKey->z - _engine->_grid->cameraZ);
+ _engine->_redraw->addOverlay(koNumber, extraKey->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, koNormal, 0, 2);
+ }
- _engine->_redraw->addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
+ _engine->_redraw->addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
- _engine->_gameState->inventoryNumKeys += extraKey->info1;
- extraKey->info0 = -1;
+ _engine->_gameState->inventoryNumKeys += extraKey->info1;
+ extraKey->info0 = -1;
- extra->info0 = -1;
- _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, SPRITEHQR_KEY, 0, 8000, 0);
- continue;
- }
- int32 angle2 = _engine->_movements->getAngleAndSetTargetActorDistance(extra->y, 0, extraKey->y, _engine->_movements->targetActorDistance);
- int32 pos = _engine->_movements->getRealAngle(&extra->trackActorMove);
+ extra->info0 = -1;
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, SPRITEHQR_KEY, 0, 8000, 0);
+ continue;
+ }
+ int32 angle2 = _engine->_movements->getAngleAndSetTargetActorDistance(extra->y, 0, extraKey->y, _engine->_movements->targetActorDistance);
+ int32 pos = _engine->_movements->getRealAngle(&extra->trackActorMove);
- if (!pos) {
- pos = 1;
- }
+ if (!pos) {
+ pos = 1;
+ }
- _engine->_movements->rotateActor(pos, 0, angle2);
- extra->y -= _engine->_renderer->destZ;
+ _engine->_movements->rotateActor(pos, 0, angle2);
+ extra->y -= _engine->_renderer->destZ;
- _engine->_movements->rotateActor(0, _engine->_renderer->destX, tmpAngle);
- extra->x += _engine->_renderer->destX;
- extra->z += _engine->_renderer->destZ;
+ _engine->_movements->rotateActor(0, _engine->_renderer->destX, tmpAngle);
+ extra->x += _engine->_renderer->destX;
+ extra->z += _engine->_renderer->destZ;
- _engine->_movements->setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
+ _engine->_movements->setActorAngle(0, extra->destZ, 50, &extra->trackActorMove);
- if (actorIdx == _engine->_collision->checkExtraCollisionWithExtra(extra, _engine->_gameState->magicBallIdx)) {
- _engine->_sound->playSample(Samples::ItemFound, 4096, 1, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->y, _engine->_scene->sceneHero->z, 0);
+ if (actorIdx == _engine->_collision->checkExtraCollisionWithExtra(extra, _engine->_gameState->magicBallIdx)) {
+ _engine->_sound->playSample(Samples::ItemFound, 4096, 1, _engine->_scene->sceneHero->x, _engine->_scene->sceneHero->y, _engine->_scene->sceneHero->z, 0);
- if (extraKey->info1 > 1) {
- _engine->_renderer->projectPositionOnScreen(extraKey->x - _engine->_grid->cameraX, extraKey->y - _engine->_grid->cameraY, extraKey->z - _engine->_grid->cameraZ);
- _engine->_redraw->addOverlay(koNumber, extraKey->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, koNormal, 0, 2);
- }
+ if (extraKey->info1 > 1) {
+ _engine->_renderer->projectPositionOnScreen(extraKey->x - _engine->_grid->cameraX, extraKey->y - _engine->_grid->cameraY, extraKey->z - _engine->_grid->cameraZ);
+ _engine->_redraw->addOverlay(koNumber, extraKey->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, koNormal, 0, 2);
+ }
- _engine->_redraw->addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
+ _engine->_redraw->addOverlay(koSprite, SPRITEHQR_KEY, 10, 30, koNormal, 0, 2);
- _engine->_gameState->inventoryNumKeys += extraKey->info1;
- extraKey->info0 = -1;
+ _engine->_gameState->inventoryNumKeys += extraKey->info1;
+ extraKey->info0 = -1;
- extra->info0 = -1;
- _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, SPRITEHQR_KEY, 0, 8000, 0);
- continue;
+ extra->info0 = -1;
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, SPRITEHQR_KEY, 0, 8000, 0);
+ continue;
+ }
+ if (extraKey->info0 == -1) {
+ int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
+
+ if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
+ spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
+ }
+ if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
+ spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- if (extraKey->info0 == -1) {
+
+ extra->info0 = -1;
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 8000, 0);
+ continue;
+ }
+ }
+ // process extra collision with actors
+ if (extra->type & 0x4) {
+ if (_engine->_collision->checkExtraCollisionWithActors(extra, extra->actorIdx) != -1) {
+ // if extra is Magic Ball
+ if (i == _engine->_gameState->magicBallIdx) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -728,16 +749,40 @@ void Extra::processExtras() {
spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
}
- extra->info0 = -1;
- _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 8000, 0);
- continue;
+ _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
+ }
+
+ extra->info0 = -1;
+ continue;
+ }
+ }
+ // process extra collision with scene ground
+ if (extra->type & 0x8) {
+ int32 process = 0;
+
+ if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->x, extra->y, extra->z)) {
+ // if not touch the ground
+ if (!(extra->type & 0x2000)) {
+ process = 1;
+ }
+ } else {
+ // if touch the ground
+ if (extra->type & 0x2000) {
+ extra->type &= 0xDFFF; // set flag out of ground
}
}
- // process extra collision with actors
- if (extra->type & 0x4) {
- if (_engine->_collision->checkExtraCollisionWithActors(extra, extra->actorIdx) != -1) {
- // if extra is Magic Ball
- if (i == _engine->_gameState->magicBallIdx) {
+
+ if (process) {
+ // show explode cloud
+ if (extra->type & 0x100) {
+ addExtraSpecial(currentExtraX, currentExtraY, currentExtraZ, kExplodeCloud);
+ }
+ // if extra is magic ball
+ if (i == _engine->_gameState->magicBallIdx) {
+ _engine->_sound->playSample(Samples::Hit, _engine->getRandomNumber(300) + 3946, 1, extra->x, extra->y, extra->z);
+
+ // cant bounce with not magic points
+ if (_engine->_gameState->magicBallNumBounce <= 0) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -748,39 +793,14 @@ void Extra::processExtras() {
}
_engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
- }
-
- extra->info0 = -1;
- continue;
- }
- }
- // process extra collision with scene ground
- if (extra->type & 0x8) {
- int32 process = 0;
-
- if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->x, extra->y, extra->z)) {
- // if not touch the ground
- if (!(extra->type & 0x2000)) {
- process = 1;
- }
- } else {
- // if touch the ground
- if (extra->type & 0x2000) {
- extra->type &= 0xDFFF; // set flag out of ground
- }
- }
- if (process) {
- // show explode cloud
- if (extra->type & 0x100) {
- addExtraSpecial(currentExtraX, currentExtraY, currentExtraZ, kExplodeCloud);
+ extra->info0 = -1;
+ continue;
}
- // if extra is magic ball
- if (i == _engine->_gameState->magicBallIdx) {
- _engine->_sound->playSample(Samples::Hit, _engine->getRandomNumber(300) + 3946, 1, extra->x, extra->y, extra->z);
- // cant bounce with not magic points
- if (_engine->_gameState->magicBallNumBounce <= 0) {
+ // if has magic points
+ if (_engine->_gameState->magicBallNumBounce == 1) {
+ if (!_engine->_gameState->magicBallAuxBounce--) {
int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
@@ -795,94 +815,75 @@ void Extra::processExtras() {
extra->info0 = -1;
continue;
}
-
- // if has magic points
- if (_engine->_gameState->magicBallNumBounce == 1) {
- if (!_engine->_gameState->magicBallAuxBounce--) {
- int32 spriteIdx = SPRITEHQR_MAGICBALL_YELLOW_TRANS;
-
- if (extra->info0 == SPRITEHQR_MAGICBALL_GREEN) {
- spriteIdx = SPRITEHQR_MAGICBALL_GREEN_TRANS;
- }
- if (extra->info0 == SPRITEHQR_MAGICBALL_RED) {
- spriteIdx = SPRITEHQR_MAGICBALL_RED_TRANS;
- }
-
- _engine->_gameState->magicBallIdx = addExtra(-1, extra->x, extra->y, extra->z, spriteIdx, 0, 10000, 0);
-
- extra->info0 = -1;
- continue;
- }
- processMagicballBounce(extra, currentExtraX, currentExtraY, currentExtraZ);
- }
- } else {
- extra->info0 = -1;
- continue;
+ processMagicballBounce(extra, currentExtraX, currentExtraY, currentExtraZ);
}
+ } else {
+ extra->info0 = -1;
+ continue;
}
}
- // extra stop moving while collision with bricks
- if (extra->type & 0x10) {
- int32 process = 0;
-
- if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->x, extra->y, extra->z)) {
- // if not touch the ground
- if (!(extra->type & 0x2000)) {
- process = 1;
- }
- } else {
- // if touch the ground
- if (extra->type & 0x2000) {
- extra->type &= 0xDFFF; // set flag out of ground
- }
+ }
+ // extra stop moving while collision with bricks
+ if (extra->type & 0x10) {
+ int32 process = 0;
+
+ if (_engine->_collision->checkExtraCollisionWithBricks(currentExtraX, currentExtraY, currentExtraZ, extra->x, extra->y, extra->z)) {
+ // if not touch the ground
+ if (!(extra->type & 0x2000)) {
+ process = 1;
}
-
- if (process) {
- const int16 *spriteBounds = (const int16 *)(_engine->_resources->spriteBoundingBoxPtr + extra->info0 * 16 + 8);
- extra->y = (_engine->_collision->collisionY << 8) + 0x100 - *(spriteBounds);
- extra->type &= 0xFFED;
- continue;
+ } else {
+ // if touch the ground
+ if (extra->type & 0x2000) {
+ extra->type &= 0xDFFF; // set flag out of ground
}
}
- // get extras on ground
- if ((extra->type & 0x20) && !(extra->type & 0x2)) {
- // if hero touch extra
- if (_engine->_collision->checkExtraCollisionWithActors(extra, -1) == 0) {
- _engine->_sound->playSample(Samples::ItemFound, 4096, 1, extra->x, extra->y, extra->z);
-
- if (extra->info1 > 1 && !_engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
- _engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
- _engine->_redraw->addOverlay(koNumber, extra->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, 158, koNormal, 2);
- }
- _engine->_redraw->addOverlay(koSprite, extra->info0, 10, 30, 0, koNormal, 2);
+ if (process) {
+ const int16 *spriteBounds = (const int16 *)(_engine->_resources->spriteBoundingBoxPtr + extra->info0 * 16 + 8);
+ extra->y = (_engine->_collision->collisionY << 8) + 0x100 - *(spriteBounds);
+ extra->type &= 0xFFED;
+ continue;
+ }
+ }
+ // get extras on ground
+ if ((extra->type & 0x20) && !(extra->type & 0x2)) {
+ // if hero touch extra
+ if (_engine->_collision->checkExtraCollisionWithActors(extra, -1) == 0) {
+ _engine->_sound->playSample(Samples::ItemFound, 4096, 1, extra->x, extra->y, extra->z);
+
+ if (extra->info1 > 1 && !_engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
+ _engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
+ _engine->_redraw->addOverlay(koNumber, extra->info1, _engine->_renderer->projPosX, _engine->_renderer->projPosY, 158, koNormal, 2);
+ }
- if (extra->info0 == SPRITEHQR_KASHES) {
- _engine->_gameState->inventoryNumKashes += extra->info1;
- if (_engine->_gameState->inventoryNumKashes > 999) {
- _engine->_gameState->inventoryNumKashes = 999;
- }
- } else if (extra->info0 == SPRITEHQR_LIFEPOINTS) {
- _engine->_scene->sceneHero->life += extra->info1;
- if (_engine->_scene->sceneHero->life > 50) {
- _engine->_scene->sceneHero->life = 50;
- }
- } else if (extra->info0 == SPRITEHQR_MAGICPOINTS && _engine->_gameState->magicLevelIdx) {
- _engine->_gameState->inventoryMagicPoints += extra->info1 * 2;
- if (_engine->_gameState->inventoryMagicPoints > _engine->_gameState->magicLevelIdx * 20) {
- _engine->_gameState->inventoryMagicPoints = _engine->_gameState->magicLevelIdx * 20;
- }
- } else if (extra->info0 == SPRITEHQR_KEY) {
- _engine->_gameState->inventoryNumKeys += extra->info1;
- } else if (extra->info0 == SPRITEHQR_CLOVERLEAF) {
- _engine->_gameState->inventoryNumLeafs += extra->info1;
- if (_engine->_gameState->inventoryNumLeafs > _engine->_gameState->inventoryNumLeafsBox) {
- _engine->_gameState->inventoryNumLeafs = _engine->_gameState->inventoryNumLeafsBox;
- }
- }
+ _engine->_redraw->addOverlay(koSprite, extra->info0, 10, 30, 0, koNormal, 2);
- extra->info0 = -1;
+ if (extra->info0 == SPRITEHQR_KASHES) {
+ _engine->_gameState->inventoryNumKashes += extra->info1;
+ if (_engine->_gameState->inventoryNumKashes > 999) {
+ _engine->_gameState->inventoryNumKashes = 999;
+ }
+ } else if (extra->info0 == SPRITEHQR_LIFEPOINTS) {
+ _engine->_scene->sceneHero->life += extra->info1;
+ if (_engine->_scene->sceneHero->life > 50) {
+ _engine->_scene->sceneHero->life = 50;
+ }
+ } else if (extra->info0 == SPRITEHQR_MAGICPOINTS && _engine->_gameState->magicLevelIdx) {
+ _engine->_gameState->inventoryMagicPoints += extra->info1 * 2;
+ if (_engine->_gameState->inventoryMagicPoints > _engine->_gameState->magicLevelIdx * 20) {
+ _engine->_gameState->inventoryMagicPoints = _engine->_gameState->magicLevelIdx * 20;
+ }
+ } else if (extra->info0 == SPRITEHQR_KEY) {
+ _engine->_gameState->inventoryNumKeys += extra->info1;
+ } else if (extra->info0 == SPRITEHQR_CLOVERLEAF) {
+ _engine->_gameState->inventoryNumLeafs += extra->info1;
+ if (_engine->_gameState->inventoryNumLeafs > _engine->_gameState->inventoryNumLeafsBox) {
+ _engine->_gameState->inventoryNumLeafs = _engine->_gameState->inventoryNumLeafsBox;
+ }
}
+
+ extra->info0 = -1;
}
}
}
diff --git a/engines/twine/gamestate.cpp b/engines/twine/gamestate.cpp
index e4b155abe2..041b67658a 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/gamestate.cpp
@@ -474,7 +474,7 @@ void GameState::processGameoverAnimation() {
}
const int32 avg = _engine->_collision->getAverageValue(40000, 3200, 500, _engine->lbaTime - startLbaTime);
- const int32 cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 0x64);
+ const int32 cdot = _engine->_screens->crossDot(1, 1024, 100, (_engine->lbaTime - startLbaTime) % 100);
_engine->_interface->blitBox(left, top, right, bottom, (int8 *)_engine->workVideoBuffer.getPixels(), 120, 120, (int8 *)_engine->frontVideoBuffer.getPixels());
_engine->_renderer->setCameraAngle(0, 0, 0, 0, -cdot, 0, avg);
Commit: 3f6828a7a42409cb37fbbbd1633bc2d319181e63
https://github.com/scummvm/scummvm/commit/3f6828a7a42409cb37fbbbd1633bc2d319181e63
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: allow to activate debug options via console
Changed paths:
engines/twine/console.cpp
engines/twine/console.h
diff --git a/engines/twine/console.cpp b/engines/twine/console.cpp
index dd07154124..5275032e30 100644
--- a/engines/twine/console.cpp
+++ b/engines/twine/console.cpp
@@ -24,6 +24,8 @@
#include "twine/twine.h"
#include "twine/gamestate.h"
#include "twine/scene.h"
+#include "twine/debug_scene.h"
+#include "twine/debug_grid.h"
#include "twine/text.h"
namespace TwinE {
@@ -34,11 +36,29 @@ TwinEConsole::TwinEConsole(TwinEEngine *engine) : _engine(engine), GUI::Debugger
registerCmd("change_scene", WRAP_METHOD(TwinEConsole, doChangeScene));
registerCmd("list_menutext", WRAP_METHOD(TwinEConsole, doListMenuText));
registerCmd("toggle_debug", WRAP_METHOD(TwinEConsole, doToggleDebug));
+ registerCmd("toggle_zones", WRAP_METHOD(TwinEConsole, doToggleZoneRendering));
+ registerCmd("toggle_freecamera", WRAP_METHOD(TwinEConsole, doToggleFreeCamera));
+ registerCmd("toggle_scenechanges", WRAP_METHOD(TwinEConsole, doToggleSceneChanges));
}
TwinEConsole::~TwinEConsole() {
}
+bool TwinEConsole::doToggleZoneRendering(int argc, const char **argv) {
+ _engine->_debugScene->showingZones = !_engine->_debugScene->showingZones;
+ return true;
+}
+
+bool TwinEConsole::doToggleFreeCamera(int argc, const char **argv) {
+ _engine->_debugGrid->useFreeCamera = !_engine->_debugGrid->useFreeCamera;
+ return true;
+}
+
+bool TwinEConsole::doToggleSceneChanges(int argc, const char **argv) {
+ _engine->_debugGrid->canChangeScenes = !_engine->_debugGrid->canChangeScenes;
+ return true;
+}
+
bool TwinEConsole::doGiveKey(int argc, const char **argv) {
int amount = 1;
if (argc >= 1) {
diff --git a/engines/twine/console.h b/engines/twine/console.h
index be14df760f..454c1a1dc1 100644
--- a/engines/twine/console.h
+++ b/engines/twine/console.h
@@ -39,6 +39,9 @@ private:
bool doListMenuText(int argc, const char **argv);
bool doToggleDebug(int argc, const char **argv);
bool doGiveKey(int argc, const char **argv);
+ bool doToggleZoneRendering(int argc, const char **argv);
+ bool doToggleFreeCamera(int argc, const char **argv);
+ bool doToggleSceneChanges(int argc, const char **argv);
public:
TwinEConsole(TwinEEngine *engine);
~TwinEConsole() override;
Commit: cf8e7339d01d886556b67b3102fb9018e74f2e80
https://github.com/scummvm/scummvm/commit/cf8e7339d01d886556b67b3102fb9018e74f2e80
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: implemented drawText for debug window
Changed paths:
engines/twine/twine.cpp
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index b99d32cba1..7aab9bf1fd 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -35,6 +35,9 @@
#include "common/translation.h"
#include "engines/metaengine.h"
#include "engines/util.h"
+#include "graphics/colormasks.h"
+#include "graphics/fontman.h"
+#include "graphics/font.h"
#include "graphics/managed_surface.h"
#include "graphics/palette.h"
#include "graphics/pixelformat.h"
@@ -975,24 +978,16 @@ void TwinEEngine::readKeys() {
}
void TwinEEngine::drawText(int32 x, int32 y, const char *string, int32 center) {
-#if 0 // TODO
- SDL_Color white = {0xFF, 0xFF, 0xFF, 0};
- SDL_Color *forecol = &white;
- SDL_Rect rectangle;
- Graphics::ManagedSurface *text = TTF_RenderText_Solid(font, string, *forecol);
-
- if (center) {
- rectangle.x = x - (text->w / 2);
- } else {
- rectangle.x = x;
+ const Graphics::Font *font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
+ if (!font) {
+ return;
}
- rectangle.y = y - 2;
- rectangle.w = text->w;
- rectangle.h = text->h;
-
- SDL_BlitSurface(text, NULL, screenBuffer, &rectangle);
- SDL_FreeSurface(text);
-#endif
+ int width = 100;
+ const Common::String text(string);
+ font->drawString(&frontVideoBuffer, text,
+ x, y, width,
+ frontVideoBuffer.format.RGBToColor(255, 255, 255),
+ center ? Graphics::kTextAlignCenter : Graphics::kTextAlignLeft);
}
} // namespace TwinE
Commit: 92b68a1132eb1272a70c62a266cc1e945eed3ff9
https://github.com/scummvm/scummvm/commit/92b68a1132eb1272a70c62a266cc1e945eed3ff9
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-11-03T18:29:37+01:00
Commit Message:
TWINE: cleanup in debug window
Changed paths:
engines/twine/debug.cpp
engines/twine/debug_scene.cpp
engines/twine/movements.cpp
diff --git a/engines/twine/debug.cpp b/engines/twine/debug.cpp
index 3e6ce4f914..1cf70ec667 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debug.cpp
@@ -392,13 +392,10 @@ void Debug::debugLeftMenu() {
debugAddButton(ZONES_MENU, 205, 244, 350, 264, "Ladder Zones", 215, 249, 7, 87, 119, 0, SHOW_ZONE_LADDER);
}
-int32 Debug::debugProcessButton(int32 X, int32 Y) {
- int32 i;
- int32 j;
-
- for (i = 0; i < numDebugWindows; i++) {
- for (j = 0; j < debugWindows[i].numButtons; j++) {
- if (X > (debugWindows[i].debugButtons[j].left) && X < (debugWindows[i].debugButtons[j].right) && Y > (debugWindows[i].debugButtons[j].top) && Y < (debugWindows[i].debugButtons[j].bottom)) {
+int32 Debug::debugProcessButton(int32 x, int32 y) {
+ for (int32 i = 0; i < numDebugWindows; i++) {
+ for (int32 j = 0; j < debugWindows[i].numButtons; j++) {
+ if (x > (debugWindows[i].debugButtons[j].left) && x < (debugWindows[i].debugButtons[j].right) && y > (debugWindows[i].debugButtons[j].top) && y < (debugWindows[i].debugButtons[j].bottom)) {
return (debugWindows[i].debugButtons[j].type);
}
}
@@ -433,8 +430,9 @@ void Debug::debugProcessWindow() {
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
debugResetButtonsState();
- if (numDebugWindows == 0)
+ if (numDebugWindows == 0) {
debugLeftMenu();
+ }
debugDrawWindows();
do {
diff --git a/engines/twine/debug_scene.cpp b/engines/twine/debug_scene.cpp
index 3a6aa51576..fa5d3ecbb6 100644
--- a/engines/twine/debug_scene.cpp
+++ b/engines/twine/debug_scene.cpp
@@ -39,17 +39,21 @@ void DebugScene::drawBoundingBoxProjectPoints(ScenePoint *pPoint3d, ScenePoint *
pPoint3dProjected->y = _engine->_renderer->projPosY;
pPoint3dProjected->z = _engine->_renderer->projPosZ;
- if (_engine->_redraw->renderLeft > _engine->_renderer->projPosX)
+ if (_engine->_redraw->renderLeft > _engine->_renderer->projPosX) {
_engine->_redraw->renderLeft = _engine->_renderer->projPosX;
+ }
- if (_engine->_redraw->renderRight < _engine->_renderer->projPosX)
+ if (_engine->_redraw->renderRight < _engine->_renderer->projPosX) {
_engine->_redraw->renderRight = _engine->_renderer->projPosX;
+ }
- if (_engine->_redraw->renderTop > _engine->_renderer->projPosY)
+ if (_engine->_redraw->renderTop > _engine->_renderer->projPosY) {
_engine->_redraw->renderTop = _engine->_renderer->projPosY;
+ }
- if (_engine->_redraw->renderBottom < _engine->_renderer->projPosY)
+ if (_engine->_redraw->renderBottom < _engine->_renderer->projPosY) {
_engine->_redraw->renderBottom = _engine->_renderer->projPosY;
+ }
}
int32 DebugScene::checkZoneType(int32 type) {
@@ -123,8 +127,6 @@ void DebugScene::displayZones() {
ScenePoint backTopLeftPoint2D;
ScenePoint backTopRightPoint2D;
- uint8 color;
-
// compute the points in 3D
frontBottomLeftPoint.x = zonePtr->bottomLeft.x - _engine->_grid->cameraX;
@@ -172,7 +174,7 @@ void DebugScene::displayZones() {
// draw all lines
- color = 15 * 3 + zonePtr->type * 16;
+ uint8 color = 15 * 3 + zonePtr->type * 16;
// draw front part
_engine->_interface->drawLine(frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, frontTopLeftPoint2D.x, frontTopLeftPoint2D.y, color);
@@ -198,6 +200,7 @@ void DebugScene::displayZones() {
_engine->_interface->drawLine(backBottomRightPoint2D.x, backBottomRightPoint2D.y, frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, color);
_engine->_interface->drawLine(frontBottomRightPoint2D.x, frontBottomRightPoint2D.y, frontBottomLeftPoint2D.x, frontBottomLeftPoint2D.y, color);
}
+ _engine->flip();
}
} // namespace TwinE
diff --git a/engines/twine/movements.cpp b/engines/twine/movements.cpp
index 264d843322..474f06b5c4 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/movements.cpp
@@ -362,12 +362,12 @@ void Movements::processActorMovements(int32 actorIdx) {
heroMoved = false;
- if (_engine->_input->isActionActive(TwinEActionType::MoveForward)) { // walk forward
+ if (_engine->_input->isActionActive(TwinEActionType::MoveForward)) {
if (!_engine->_scene->currentActorInZone) {
_engine->_animations->initAnim(kForward, 0, 255, actorIdx);
}
heroMoved = true;
- } else if (_engine->_input->isActionActive(TwinEActionType::MoveBackward)) { // walk backward
+ } else if (_engine->_input->isActionActive(TwinEActionType::MoveBackward)) {
_engine->_animations->initAnim(kBackward, 0, 255, actorIdx);
heroMoved = true;
}
More information about the Scummvm-git-logs
mailing list