[Scummvm-git-logs] scummvm master -> c0eaf1227d983af02bd8acac18101711b0ca7e7b
mduggan
noreply at scummvm.org
Fri Apr 7 12:54:28 UTC 2023
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
c4fc5f9922 TETRAEDGE: Slight cleanups for Game and Application class interfaces
443a14f80e TETRAEDGE: Fixes to get Amerzone as far as main menu.
ba318b8283 TETRAEDGE: Refactor game class to split out Syberia-specific parts
9baaeee37f TETRAEDGE: Starting to add classes needed for Amerzone
0b90939b9f TETRAEDGE: Fix crash in Syberia 1
c0eaf1227d TETRAEDGE: Add more implementation for Amerzone support
Commit: c4fc5f99222290a4ef3b6b3cd2a49567ebc16bb4
https://github.com/scummvm/scummvm/commit/c4fc5f99222290a4ef3b6b3cd2a49567ebc16bb4
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-04-07T21:54:18+09:00
Commit Message:
TETRAEDGE: Slight cleanups for Game and Application class interfaces
Changed paths:
engines/tetraedge/game/application.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/lua_binds.cpp
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 2fcb104ff18..3446496a8b3 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -63,18 +63,13 @@ public:
void showLoadingIcon(bool show);
void saveCorrupted(const Common::String &fname);
- void drawBack();
- void drawFront();
void performRender();
- //void preloadTextrue(); does nothing..
+ //void preloadTextrue(); does nothing
void fade();
void blackFade();
void captureFade();
bool isFading();
- bool onBlackFadeAnimationFinished();
- bool onMainWindowSizeChanged();
- bool onMousePositionChanged(const Common::Point &p);
bool isLockCursor();
bool isLockPad();
@@ -88,8 +83,6 @@ public:
Common::String getHelpText(const Common::String &key);
- const char *inAppUnlockFullVersionID();
-
BonusMenu &bonusMenu() { return _bonusMenu; }
GlobalBonusMenu &globalBonusMenu() { return _globalBonusMenu; }
MainMenu &mainMenu() { return _mainMenu; }
@@ -120,6 +113,15 @@ public:
bool ratioStretched() const { return _ratioStretched; }
private:
+ void drawBack();
+ void drawFront();
+
+ const char *inAppUnlockFullVersionID();
+
+ bool onBlackFadeAnimationFinished();
+ bool onMainWindowSizeChanged();
+ bool onMousePositionChanged(const Common::Point &p);
+
bool _finishedGame;
bool _finishedFremium;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 79a98247426..eb3e22ad9b9 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -52,8 +52,8 @@ _sceneCharacterVisibleFromLoad(false), _isCharacterWalking(false),
_lastCharMoveMousePos(0.0f, 0.0f), _randomSoundFinished(false),
_previousMousePos(-1, -1), _markersVisible(true), _saveRequested(false),
_gameLoadState(0), _luaShowOwnerError(false), _score(0), _warped(false),
-_firstInventory(true), _randomSource("SyberiaGameRandom"), _frameCounter(0),
-_warpFadeFlag(false), _dialogsTold(0), _runModeEnabled(true) {
+_firstInventory(true), _frameCounter(0), _warpFadeFlag(false),
+_dialogsTold(0), _runModeEnabled(true) {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
@@ -1375,11 +1375,13 @@ bool Game::onVideoFinished() {
return false;
}
+/* Unused
void Game::pauseMovie() {
_music.pause();
TeSpriteLayout *sprite = _inGameGui.spriteLayoutChecked("video");
sprite->pause();
}
+*/
bool Game::playMovie(const Common::String &vidPath, const Common::String &musicPath, float volume /* = 1.0f */) {
Application *app = g_engine->getApplication();
@@ -1438,7 +1440,7 @@ void Game::playRandomSound(const Common::String &name) {
if (!_randomSoundFinished) {
_randomSoundTimer.start();
- int r = _randomSource.getRandomNumber(RAND_MAX);
+ int r = g_engine->getRandomNumber(RAND_MAX);
float f = (r + 1 + (r / 100) * -100);
uint64 time = 1000000;
if (f >= 25.0) {
@@ -1454,7 +1456,7 @@ void Game::playRandomSound(const Common::String &name) {
for (auto *snd : sndlist) {
total += snd->_f1;
}
- int r = _randomSource.getRandomNumber(RAND_MAX);
+ int r = g_engine->getRandomNumber(RAND_MAX);
float total2 = 0.0;
uint i = 0;
while (i < sndlist.size() && total2 <= r * 4.656613e-10 * total) {
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index bc2c50857a5..d91d2cb684a 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -83,23 +83,15 @@ public:
//enum EGameScoreID {}; // Not needed?
- bool addAnimToSet(const Common::String &path);
void addArtworkUnlocked(const Common::String &name, bool notify);
void addNoScale2Child(TeLayout *layout);
- void addNoScale2Children();
- void addNoScaleChildren();
void addRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2);
void addToBag(const Common::String &objname);
void addToHand(const Common::String &objname);
void addToScore(int score);
- void attachButtonsLayoutGoto() {}; // does nothing?
- void createButtonsLayoutGoto() {}; // does nothing?
- void deleteButtonsLayoutGoto() {}; // does nothing?
bool changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
- bool changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag);
- void deleteNoScale();
void draw();
void enter(); // will load game if _loadName is set.
// Note: game uses ILayouts here..
@@ -109,9 +101,6 @@ public:
void finishFreemium();
void finishGame();
void initLoadedBackupData();
- void initNoScale();
- void initScene(bool param_1, const Common::String &scenePath);
- bool initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
bool isDocumentOpened();
bool isMouse() { return false; }
bool isMoviePlaying();
@@ -119,39 +108,18 @@ public:
const Common::String ¶m_4, float param_5);
void leave(bool flag);
void loadBackup(const Common::String &path);
- bool loadCharacter(const Common::String &name);
bool loadPlayerCharacter(const Common::String &name);
bool loadScene(const Common::String &name);
// Not in original. Load unlocked artwork from ScummVM config.
void loadUnlockedArtwork();
- bool onAnswered(const Common::String &val);
- bool onCallNumber(Common::String val);
- bool onCharacterAnimationFinished(const Common::String &val);
- bool onCharacterAnimationPlayerFinished(const Common::String &val);
- bool onDialogFinished(const Common::String &val);
- bool onDisplacementFinished();
- bool onDisplacementPlayerFinished();
- bool onFinishedCheckBackup(bool result);
- bool onFinishedLoadingBackup(const Common::String &val);
- bool onFinishedSavingBackup(int something);
- bool onInventoryButtonValidated();
- bool onLockVideoButtonValidated();
- bool onMarkersVisible(TeCheckboxLayout::State state);
- bool onMouseClick(const Common::Point &pt);
- bool onMouseMove();
- bool onSkipVideoButtonValidated();
- bool onVideoFinished();
-
- void pauseMovie();
- void pauseSounds() {}; // does nothing?
+ //void pauseMovie(); // Unused
+ //void pauseSounds() {}; // Unused, does nothing?
bool playMovie(const Common::String &vidPath, const Common::String &musicPath, float volume = 1.0f);
void playRandomSound(const Common::String &name);
void playSound(const Common::String &name, int param_2, float volume);
void removeNoScale2Child(TeLayout *layout);
- void removeNoScale2Children();
- void removeNoScaleChildren();
void resetPreviousMousePos();
void resumeMovie();
void resumeSounds() {}; // does nothing?
@@ -160,7 +128,7 @@ public:
void setCurrentObjectSprite(const Common::String &spritePath);
bool showMarkers(bool val);
bool startAnimation(const Common::String &animName, int loopcount, bool reversed);
- void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {};
+ // void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {}; // Unused.
void stopSound(const Common::String &name);
Common::Error syncGame(Common::Serializer &s); // Basically replaces saveBackup from original..
bool unloadCharacter(const Common::String &character);
@@ -200,7 +168,6 @@ public:
void setPosPlayer(const TeVector3f32 &pos) { _posPlayer = pos; }
TeTimer &walkTimer() { return _walkTimer; }
void setExitZone(const Common::String &zone) { _exitZone = zone; }
- Common::RandomSource &randomSource() { return _randomSource; }
void setLoadName(const Common::String &loadName) { _loadName = loadName; }
bool hasLoadName() const { return !_loadName.empty(); }
bool isArtworkUnlocked(const Common::String &name) const;
@@ -210,6 +177,45 @@ public:
bool runModeEnabled() const { return _runModeEnabled; }
private:
+ bool addAnimToSet(const Common::String &path);
+ void addNoScale2Children();
+ void addNoScaleChildren();
+
+ void attachButtonsLayoutGoto() {}; // does nothing?
+ void createButtonsLayoutGoto() {}; // does nothing?
+ void deleteButtonsLayoutGoto() {}; // does nothing?
+
+ bool changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+
+ void deleteNoScale();
+
+ void initNoScale();
+ void initScene(bool param_1, const Common::String &scenePath);
+ bool initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+
+ bool loadCharacter(const Common::String &name);
+
+ bool onAnswered(const Common::String &val);
+ bool onCallNumber(Common::String val);
+ bool onCharacterAnimationFinished(const Common::String &val);
+ bool onCharacterAnimationPlayerFinished(const Common::String &val);
+ bool onDialogFinished(const Common::String &val);
+ bool onDisplacementFinished();
+ bool onDisplacementPlayerFinished();
+ bool onFinishedCheckBackup(bool result);
+ bool onFinishedLoadingBackup(const Common::String &val);
+ bool onFinishedSavingBackup(int something);
+ bool onInventoryButtonValidated();
+ bool onLockVideoButtonValidated();
+ bool onMarkersVisible(TeCheckboxLayout::State state);
+ bool onMouseClick(const Common::Point &pt);
+ bool onMouseMove();
+ bool onSkipVideoButtonValidated();
+ bool onVideoFinished();
+
+ void removeNoScale2Children();
+ void removeNoScaleChildren();
+
bool _luaShowOwnerError;
bool _running;
bool _entered;
@@ -280,7 +286,6 @@ private:
bool _saveRequested;
bool _randomSoundFinished;
- Common::RandomSource _randomSource;
RandomSound *_randomSound;
TeTimer _randomSoundTimer;
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index d4b129bd863..56c28ac9eff 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -1754,7 +1754,7 @@ static int tolua_ExportedFunctions_SetCharacterLookChar00(lua_State *L) {
}
static uint Random(uint max) {
- return g_engine->getGame()->randomSource().getRandomNumber(max - 1);
+ return g_engine->getRandomNumber(max - 1);
}
static int tolua_ExportedFunctions_Random00(lua_State *L) {
Commit: 443a14f80e4e8a1665918d5cd419a0d0693e0fe8
https://github.com/scummvm/scummvm/commit/443a14f80e4e8a1665918d5cd419a0d0693e0fe8
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-04-07T21:54:18+09:00
Commit Message:
TETRAEDGE: Fixes to get Amerzone as far as main menu.
Changed paths:
engines/tetraedge/detection.cpp
engines/tetraedge/detection_tables.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/inventory_menu.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/te/te_core.cpp
diff --git a/engines/tetraedge/detection.cpp b/engines/tetraedge/detection.cpp
index e72aa1336b2..1e33c369493 100644
--- a/engines/tetraedge/detection.cpp
+++ b/engines/tetraedge/detection.cpp
@@ -54,14 +54,13 @@ DetectedGame TetraedgeMetaEngineDetection::toDetectedGame(const ADDetectedGame &
DetectedGame game = AdvancedMetaEngineDetection::toDetectedGame(adGame);
// The AdvancedDetector model only allows specifying a single supported
- // game language. Both games support multiple languages
- if (game.gameId == "syberia" || game.gameId == "syberia2") {
- for (const Common::Language *language = getGameLanguages(); *language != Common::UNK_LANG; language++) {
- // "ru" only present on syberia 1
- if (game.gameId == "syberia2" && *language == Common::RU_RUS)
- continue;
- game.appendGUIOptions(Common::getGameGUIOptionsDescriptionLanguage(*language));
- }
+ // game language. All games support multiple languages. Only Syberia 1
+ // supports RU.
+ for (const Common::Language *language = getGameLanguages(); *language != Common::UNK_LANG; language++) {
+ // "ru" only present on syberia 1
+ if (game.gameId != "syberia" && *language == Common::RU_RUS)
+ continue;
+ game.appendGUIOptions(Common::getGameGUIOptionsDescriptionLanguage(*language));
}
return game;
diff --git a/engines/tetraedge/detection_tables.h b/engines/tetraedge/detection_tables.h
index e36394c1b69..0ff86557c3a 100644
--- a/engines/tetraedge/detection_tables.h
+++ b/engines/tetraedge/detection_tables.h
@@ -29,6 +29,17 @@ const PlainGameDescriptor GAME_NAMES[] = {
};
const ADGameDescription GAME_DESCRIPTIONS[] = {
+ // Amerzone GOG release
+ {
+ "amerzone",
+ nullptr,
+ AD_ENTRY1s("MacOS/Amerzone", "d:cde4144aeea5a99602ee903554585178", 6380272),
+ Common::UNK_LANG,
+ Common::kPlatformMacintosh,
+ ADGF_UNSTABLE,
+ GUIO0()
+ },
+
// GOG and Steam releases
// Note: Full sum of GOG and Steam are different,
// but size and first 5000 bytes are the same.
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 1f7a0a2515a..3da0e119a23 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -87,6 +87,11 @@ _drawShadows(true) {
// Note: original has an app run timer, but it's never used?
+ if (g_engine->gameType() == TetraedgeEngine::kAmerzone)
+ _defaultCursor = "2D/arrow6.png";
+ else
+ _defaultCursor = "pictures/cursor.png";
+
loadOptions("options.xml");
}
@@ -168,21 +173,23 @@ void Application::create() {
_loc.load(textFileNode);
core->addLoc(&_loc);
- const Common::Path helpMenuPath("menus/help/help_");
- Common::Path helpMenuFilePath;
- i = 0;
- while (i < ARRAYSIZE(allLangs)) {
- helpMenuFilePath = helpMenuPath.append(core->language() + ".xml");
- if (Common::File::exists(helpMenuFilePath))
- break;
- core->language(allLangs[i]);
- i++;
- }
- if (i == ARRAYSIZE(allLangs)) {
- error("Couldn't find menus/help/help_[lang].xml for any language.");
- }
+ if (g_engine->gameType() != TetraedgeEngine::kAmerzone) {
+ const Common::Path helpMenuPath("menus/help/help_");
+ Common::Path helpMenuFilePath;
+ i = 0;
+ while (i < ARRAYSIZE(allLangs)) {
+ helpMenuFilePath = helpMenuPath.append(core->language() + ".xml");
+ if (Common::File::exists(helpMenuFilePath))
+ break;
+ core->language(allLangs[i]);
+ i++;
+ }
+ if (i == ARRAYSIZE(allLangs)) {
+ error("Couldn't find menus/help/help_[lang].xml for any language.");
+ }
- _helpGui.load(helpMenuFilePath);
+ _helpGui.load(helpMenuFilePath);
+ }
// TODO: set TeCore field 0x74 and 0x78 to true here? Do they do anything?");
@@ -229,7 +236,7 @@ void Application::create() {
g_system->showMouse(false);
//mainWindow->setNativeCursorVisible(false);
- _mouseCursorLayout.load("pictures/cursor.png");
+ _mouseCursorLayout.load(_defaultCursor);
_mouseCursorLayout.setAnchor(TeVector3f32(0.3f, 0.1f, 0.0f));
_frontOrientationLayout.addChild(&_mouseCursorLayout);
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 3446496a8b3..7a1bb59ff6a 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -106,6 +106,7 @@ public:
const Common::String &firstWarpPath() { return _firstWarpPath; }
const Common::String &firstZone() { return _firstZone; }
const Common::String &firstScene() { return _firstScene; }
+ const Common::String &defaultCursor() { return _defaultCursor; }
TeLayout &frontLayout() { return _frontLayout; };
TeLayout &frontOrientationLayout() { return _frontOrientationLayout; }
TeLayout &backLayout() { return _backLayout; }
@@ -146,6 +147,7 @@ private:
Common::String _firstWarpPath;
Common::String _firstZone;
Common::String _firstScene;
+ Common::String _defaultCursor;
Common::Array<Common::String> _unrecalAnims;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index eb3e22ad9b9..0e1b50b8e38 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -1265,12 +1265,10 @@ bool Game::onMouseMove() {
if (!_entered)
return false;
- const Common::String DEFAULT_CURSOR("pictures/cursor.png");
-
Application *app = g_engine->getApplication();
if (app->isLockCursor()) {
- app->mouseCursorLayout().load(DEFAULT_CURSOR);
+ app->mouseCursorLayout().load(app->defaultCursor());
return false;
}
@@ -1292,7 +1290,7 @@ bool Game::onMouseMove() {
if (cellphone->isMouseIn(mouseLoc)) {
skipFullSearch = true;
if (!cellbg->visible() && _objectif.isMouseIn(mouseLoc)) {
- app->mouseCursorLayout().load(DEFAULT_CURSOR);
+ app->mouseCursorLayout().load(app->defaultCursor());
return false;
}
}
diff --git a/engines/tetraedge/game/inventory_menu.cpp b/engines/tetraedge/game/inventory_menu.cpp
index 9dd250b5cc1..09d1b63a76c 100644
--- a/engines/tetraedge/game/inventory_menu.cpp
+++ b/engines/tetraedge/game/inventory_menu.cpp
@@ -31,7 +31,7 @@ InventoryMenu::InventoryMenu() {
void InventoryMenu::enter() {
Application *app = g_engine->getApplication();
- app->mouseCursorLayout().load("pictures/cursor.png");
+ app->mouseCursorLayout().load(app->defaultCursor());
_gui.layoutChecked("inventoryMenu")->setVisible(true);
onInventoryButton();
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index 56c28ac9eff..de23497c344 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -78,7 +78,7 @@ static int tolua_ExportedFunctions_LoadObjectMaterials01(lua_State *L) {
static void PlayMovie(const Common::String &vidpath, const Common::String &musicpath) {
Application *app = g_engine->getApplication();
- app->mouseCursorLayout().load("pictures/cursor.png");
+ app->mouseCursorLayout().load(app->defaultCursor());
Game *game = g_engine->getGame();
game->playMovie(vidpath, musicpath);
}
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index 7f4ddf898ef..fa82bba68df 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -68,19 +68,27 @@ void MainMenu::enter() {
app->captureFade();
_entered = true;
- load("menus/mainMenu/mainMenu.lua");
+ const char *luaFile = (g_engine->gameType() == TetraedgeEngine::kAmerzone ? "GUI/MainMenu.lua" : "menus/mainMenu/mainMenu.lua");
+ load(luaFile);
+
+ TeLayout *menuLayout = layoutChecked("menu");
+ appSpriteLayout.addChild(menuLayout);
//
// WORKAROUND: This is set to PanScan ratio 1.0, but with our code
// but that shrinks it down to pillarboxed. Force back to full size.
//
- layoutChecked("background")->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ TeLayout *background;
+ if (layout("background"))
+ background = layoutChecked("background");
+ else
+ background = dynamic_cast<TeLayout *>(menuLayout->child(0));
+ assert(background);
+ background->setRatioMode(TeILayout::RATIO_MODE_NONE);
- TeLayout *menuLayout = layoutChecked("menu");
- appSpriteLayout.addChild(menuLayout);
app->mouseCursorLayout().setVisible(true);
- app->mouseCursorLayout().load("pictures/cursor.png");
+ app->mouseCursorLayout().load(app->defaultCursor());
TeMusic &music = app->music();
if (music.isPlaying()) {
diff --git a/engines/tetraedge/te/te_core.cpp b/engines/tetraedge/te/te_core.cpp
index 99be35c6159..26ffc5ae042 100644
--- a/engines/tetraedge/te/te_core.cpp
+++ b/engines/tetraedge/te/te_core.cpp
@@ -184,7 +184,8 @@ Common::FSNode TeCore::findFile(const Common::Path &path) const {
"DefaultDistributor-Freemium", // iOS Syb 1 paid
"iPhone-iPad/DefaultDistributor", // iOS Syb 1 paid
"Android-iPhone-iPad/iPhone-iPad", // iOS Syb 2
- "PC-MacOSX-Android-iPhone-iPad" // iOS Syb 2
+ "PC-MacOSX-Android-iPhone-iPad", // iOS Syb 2
+ "Full/HD" // Amerzone
};
const Common::Path langs[] = {
Commit: ba318b82839305b6bdcebd110fd713b2fa80f0e5
https://github.com/scummvm/scummvm/commit/ba318b82839305b6bdcebd110fd713b2fa80f0e5
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-04-07T21:54:18+09:00
Commit Message:
TETRAEDGE: Refactor game class to split out Syberia-specific parts
Changed paths:
A engines/tetraedge/game/syberia_game.cpp
A engines/tetraedge/game/syberia_game.h
engines/tetraedge/game/billboard.cpp
engines/tetraedge/game/bonus_menu.cpp
engines/tetraedge/game/documents_browser.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/game_sound.cpp
engines/tetraedge/game/in_game_scene.cpp
engines/tetraedge/game/lua_binds.cpp
engines/tetraedge/game/youki_manager.cpp
engines/tetraedge/module.mk
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/billboard.cpp b/engines/tetraedge/game/billboard.cpp
index 94b36bec1e3..edf113ed5fe 100644
--- a/engines/tetraedge/game/billboard.cpp
+++ b/engines/tetraedge/game/billboard.cpp
@@ -23,7 +23,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/billboard.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/te/te_core.h"
@@ -35,7 +35,7 @@ Billboard::Billboard() : _hasPos2(false) {
bool Billboard::load(const Common::String &path) {
_model = new TeModel();
TeIntrusivePtr<Te3DTexture> texture = Te3DTexture::makeInstance();
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
TeCore *core = g_engine->getCore();
Common::FSNode texnode = core->findFile(game->sceneZonePath().join(path));
texture->load(texnode);
diff --git a/engines/tetraedge/game/bonus_menu.cpp b/engines/tetraedge/game/bonus_menu.cpp
index 10daeb05664..61459b70bb3 100644
--- a/engines/tetraedge/game/bonus_menu.cpp
+++ b/engines/tetraedge/game/bonus_menu.cpp
@@ -24,7 +24,7 @@
#include "common/textconsole.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_input_mgr.h"
@@ -39,6 +39,8 @@ void BonusMenu::enter(const Common::String &scriptName) {
error("BonusMenu::enter: failed to load %s", scriptName.c_str());
Application *app = g_engine->getApplication();
app->frontLayout().addChild(layoutChecked("menu"));
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
buttonLayoutChecked("quitButton")->onMouseClickValidated().add(this, &BonusMenu::onQuitButton);
@@ -65,7 +67,7 @@ void BonusMenu::enter(const Common::String &scriptName) {
if (btn->childCount() <= 4)
error("expected save button to have >4 children");
const Common::String artName = btn->child(4)->name();
- btn->setEnable(g_engine->getGame()->isArtworkUnlocked(artName));
+ btn->setEnable(game->isArtworkUnlocked(artName));
btnNo++;
}
diff --git a/engines/tetraedge/game/documents_browser.cpp b/engines/tetraedge/game/documents_browser.cpp
index 533e928c31a..7921550242e 100644
--- a/engines/tetraedge/game/documents_browser.cpp
+++ b/engines/tetraedge/game/documents_browser.cpp
@@ -23,7 +23,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_lua_thread.h"
#include "tetraedge/te/te_scrolling_layout.h"
@@ -53,20 +53,23 @@ void DocumentsBrowser::hideDocument() {
Game *game = g_engine->getGame();
bool callFn = true;
- Common::Array<Game::YieldedCallback> &yieldedcallbacks = game->yieldedCallbacks();
- for (uint i = 0; i < yieldedcallbacks.size(); i++) {
- if (yieldedcallbacks[i]._luaFnName == "OnDocumentClosed" &&
- yieldedcallbacks[i]._luaParam == docName) {
- yieldedcallbacks.remove_at(i);
- if (yieldedcallbacks[i]._luaThread) {
- yieldedcallbacks[i]._luaThread->resume();
- callFn = false;
+ SyberiaGame *sybgame = dynamic_cast<SyberiaGame *>(game);
+ if (sybgame) {
+ Common::Array<SyberiaGame::YieldedCallback> &yieldedcallbacks = sybgame->yieldedCallbacks();
+ for (uint i = 0; i < yieldedcallbacks.size(); i++) {
+ if (yieldedcallbacks[i]._luaFnName == "OnDocumentClosed" &&
+ yieldedcallbacks[i]._luaParam == docName) {
+ yieldedcallbacks.remove_at(i);
+ if (yieldedcallbacks[i]._luaThread) {
+ yieldedcallbacks[i]._luaThread->resume();
+ callFn = false;
+ }
+ break;
}
- break;
}
+ if (callFn)
+ game->luaScript().execute("OnDocumentClosed", docName);
}
- if (callFn)
- game->luaScript().execute("OnDocumentClosed", docName);
app->fade();
}
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 0e1b50b8e38..7f0ab07c49d 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -46,27 +46,16 @@
namespace Tetraedge {
Game::Game() : _objectsTakenVal(0), _returnToMainMenu(false), _entered(false),
-_enteredFlag2(false), _running(false), _movePlayerCharacterDisabled(false),
-_noScaleLayout(nullptr), _noScaleLayout2(nullptr), _isCharacterIdle(true),
-_sceneCharacterVisibleFromLoad(false), _isCharacterWalking(false),
-_lastCharMoveMousePos(0.0f, 0.0f), _randomSoundFinished(false),
-_previousMousePos(-1, -1), _markersVisible(true), _saveRequested(false),
-_gameLoadState(0), _luaShowOwnerError(false), _score(0), _warped(false),
-_firstInventory(true), _frameCounter(0), _warpFadeFlag(false),
-_dialogsTold(0), _runModeEnabled(true) {
+_running(false), _noScaleLayout2(nullptr), _luaShowOwnerError(false),
+_firstInventory(true), _dialogsTold(0) {
for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
_objectsTakenBits[i] = false;
}
- _randomSound = new RandomSound();
_dialog2.onAnimationDownFinishedSignal().add(this, &Game::onDialogFinished);
_question2.onAnswerSignal().add(this, &Game::onAnswered);
}
Game::~Game() {
- if (_entered) {
- leave(true);
- }
- delete _randomSound;
}
/*static*/ const char *Game::OBJECTS_TAKEN_IDS[5] = {
@@ -77,303 +66,12 @@ Game::~Game() {
"VPoupeeMammouth"
};
-bool Game::addAnimToSet(const Common::String &anim) {
- // Get path to lua script, eg scenes/ValVoralberg/14040/Set14040.lua
- const Common::Path animPath(Common::String("scenes/") + anim + "/");
-
- if (Common::File::exists(animPath)) {
- const Common::StringArray parts = TetraedgeEngine::splitString(anim, '/');
- assert(parts.size() >= 2);
-
- const Common::String layoutName = parts[1];
- const Common::String path = Common::String("scenes/") + parts[0] + "/" + parts[1] + "/Set" + parts[1];
-
- _setAnimGui.load(path + ".lua");
-
- // Note: game makes this here, but never uses it..
- // it seems like a random memory leak??
- // TeSpriteLayout *spritelayout = new TeSpriteLayout();
-
- TeSpriteLayout *spritelayout = findSpriteLayoutByName(_setAnimGui.layoutChecked("root"), layoutName);
-
- _scene.bgGui().layoutChecked("root")->addChild(spritelayout);
- return true;
- }
-
- return false;
-}
-
-/*static*/
-Common::String Game::artworkConfName(const Common::String &name) {
- Common::String configName = Common::String::format("artwork_%s", name.c_str());
- for (uint i = 0; i < configName.size(); i++) {
- if (configName[i] == '/' || configName[i] == '.')
- configName.setChar('_', i);
- }
- return configName;
-}
-
-void Game::addArtworkUnlocked(const Common::String &name, bool notify) {
- const Common::String configName = artworkConfName(name);
- if (_unlockedArtwork.contains(configName))
- return;
- ConfMan.setBool(configName, true);
- ConfMan.flushToDisk();
- _unlockedArtwork[configName] = true;
- if (notify)
- _notifier.push("BONUS!", "Inventory/Objects/VPapierCrayon.png");
-}
-
-bool Game::isArtworkUnlocked(const Common::String &name) const {
- const Common::String configName = artworkConfName(name);
- return _unlockedArtwork.getValOrDefault(configName, false);
-}
-
void Game::addNoScale2Child(TeLayout *layout) {
if (_noScaleLayout2 && layout) {
_noScaleLayout2->addChild(layout);
}
}
-void Game::addNoScale2Children() {
- if (!_noScaleLayout2)
- return;
-
- TeLayout *vidbtn = _inGameGui.layout("videoButtonLayout");
- if (vidbtn)
- _noScaleLayout2->addChild(vidbtn);
-
- TeLayout *bg = _inventory.cellphone()->gui().layout("background");
- if (bg)
- _noScaleLayout2->addChild(bg);
-
- TeButtonLayout *bgbtn = _objectif.gui1().buttonLayout("background");
- if (bgbtn)
- _noScaleLayout2->addChild(bgbtn);
-}
-
-void Game::addNoScaleChildren() {
- if (!_noScaleLayout)
- return;
- TeLayout *inGame = _inGameGui.layout("inGame");
- if (inGame)
- _noScaleLayout->addChild(inGame);
-
- _noScaleLayout->addChild(&_question2);
-
- Application *app = g_engine->getApplication();
- app->frontLayout().addChild(&_dialog2);
-
- _noScaleLayout->addChild(&_inventory);
- _noScaleLayout->addChild(&_inventoryMenu);
- _noScaleLayout->addChild(&_documentsBrowser);
- _noScaleLayout->addChild(&_documentsBrowser.zoomedLayout());
-}
-
-void Game::addRandomSound(const Common::String &name, const Common::String &path, float f1, float volume) {
- if (!_randomSounds.contains(name)) {
- _randomSounds[name] = Common::Array<RandomSound*>();
- }
- RandomSound *randsound = new RandomSound();
- randsound->_path = path;
- randsound->_f1 = f1;
- randsound->_volume = volume;
- randsound->_name = name;
- _randomSounds[name].push_back(randsound);
-}
-
-void Game::addToBag(const Common::String &objid) {
- if (_inventory.objectCount(objid) != 0)
- return;
- _inventory.addObject(objid);
- Common::String imgpath("Inventory/Objects/");
- imgpath += objid;
- imgpath += ".png";
- _notifier.push(_inventory.objectName(objid), imgpath);
- for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
- if (objid == OBJECTS_TAKEN_IDS[i] && !_objectsTakenBits[i]) {
- _objectsTakenBits[i] = true;
- _objectsTakenVal++;
- }
- }
- // Seeems strange as we're already in Game, but that's what original does?
- Game *game = g_engine->getGame();
- game->_score += 10;
- debug("Updated score: %d", game->_score);
-}
-
-void Game::addToHand(const Common::String &objname) {
- _inventory.addObject(objname);
- _inventory.selectedObject(objname);
-}
-
-void Game::addToScore(int score) {
- _score += score;
-}
-
-bool Game::changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
- //debug("Game::changeWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
- Application *app = g_engine->getApplication();
- if (fadeFlag && g_engine->gameType() == TetraedgeEngine::kSyberia) {
- app->blackFade();
- } else {
- app->captureFade();
- }
- // Slight divergence from original.. free after capturing fade so characters don't disappear.
- if (g_engine->gameType() == TetraedgeEngine::kSyberia2)
- _scene.freeGeometry();
-
- _warpZone = zone;
- _warpScene = scene;
- _warpFadeFlag = fadeFlag;
- _warped = true;
- return true;
-}
-
-bool Game::changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
- //debug("Game::changeWarp2(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
- _warped = false;
- _movePlayerCharacterDisabled = false;
- _sceneCharacterVisibleFromLoad = false;
- // TODO? _charMoveMouseEventNo = -1?
- _isCharacterIdle = true;
- _isCharacterWalking = false;
- Common::Path luapath("scenes");
- luapath.joinInPlace(zone);
- luapath.joinInPlace(scene);
- luapath.joinInPlace("Logic");
- luapath.appendInPlace(scene);
- luapath.appendInPlace(".lua");
-
- if (g_engine->getCore()->findFile(luapath).exists()) {
- _luaScript.execute("OnLeave");
- _luaContext.removeGlobal("On");
- _luaContext.removeGlobal("OnEnter");
- _luaContext.removeGlobal("OnWarpObjectHit");
- _luaContext.removeGlobal("OnButtonDown");
- _luaContext.removeGlobal("OnButtonUp");
- _luaContext.removeGlobal("OnFinishedAnim");
- _luaContext.removeGlobal("OnCharacterAnimationFinished");
- _luaContext.removeGlobal("OnCharacterAnimationPlayerFinished");
- _luaContext.removeGlobal("OnDisplacementFinished");
- _luaContext.removeGlobal("OnFreeSoundFinished");
- _luaContext.removeGlobal("OnDocumentClosed");
- _luaContext.removeGlobal("OnSelectedObject");
- _luaContext.removeGlobal("OnDialogFinished");
- _luaContext.removeGlobal("OnAnswered");
- _luaContext.removeGlobal("OnLeave");
- _luaScript.unload();
- }
-
- _forGui.unload();
- _prevSceneName = _currentScene;
- if (!fadeFlag)
- g_engine->getApplication()->fade();
-
- return initWarp(zone, scene, false);
-}
-
-void Game::deleteNoScale() {
- if (_noScaleLayout) {
- removeNoScaleChildren();
- delete _noScaleLayout;
- _noScaleLayout = nullptr;
- }
- if (_noScaleLayout2) {
- removeNoScale2Children();
- delete _noScaleLayout2;
- _noScaleLayout2 = nullptr;
- }
-}
-
-void Game::draw() {
- if (_running) {
- _frameCounter++;
- _scene.draw();
- }
-}
-
-void Game::enter() {
- _enteredFlag2 = true;
- _entered = true;
- _luaShowOwnerError = false;
- _score = 0;
- Application *app = g_engine->getApplication();
- app->visualFade().init();
- // TODO: Original puts this click handler at -10000.. but then it never gets hit?
- Common::SharedPtr<TeCallback1Param<Game, const Common::Point &>> callbackptr(new TeCallback1Param<Game, const Common::Point &>(this, &Game::onMouseClick, 10000.0f));
- g_engine->getInputMgr()->_mouseLUpSignal.push_back(callbackptr);
- _movePlayerCharacterDisabled = false;
- // TODO? Set _charMoveMouseEventNo = -1
- _isCharacterIdle = true;
- _sceneCharacterVisibleFromLoad = false;
- Character::loadSettings("models/ModelsSettings.xml");
- Object3D::loadSettings("objects/ObjectsSettings.xml");
- if (_scene._character) {
- _scene._character->onFinished().remove(this, &Game::onDisplacementPlayerFinished);
- _scene.unloadCharacter(_scene._character->_model->name());
- }
- bool loaded = loadPlayerCharacter("Kate");
- if (!loaded)
- error("[Game::enter] Can't load player character");
-
- _scene._character->_model->setVisible(true);
- _running = true;
- _luaContext.create();
- GameAchievements::registerAchievements(_luaContext);
-
- _luaContext.setGlobal("BUTTON_VALID", 1);
- _luaContext.setGlobal("BUTTON_CANCEL", 2);
- _luaContext.setGlobal("BUTTON_EXTRA1", 4);
- _luaContext.setGlobal("BUTTON_EXTRA2", 8);
- _luaContext.setGlobal("BUTTON_L1", 0x10);
- _luaContext.setGlobal("BUTTON_R1", 0x20);
- _luaContext.setGlobal("BUTTON_START", 0x40);
- _luaContext.setGlobal("BUTTON_UP", 0x80);
- _luaContext.setGlobal("BUTTON_DOWN", 0x100);
- _luaContext.setGlobal("BUTTON_LEFT", 0x200);
- _luaContext.setGlobal("BUTTON_RIGHT", 0x400);
- _luaContext.setGlobal("BUTTON_LS_CLIC", 0x800);
- _luaContext.setGlobal("BUTTON_RS_CLIC", 0x1000);
- _luaContext.setGlobal("BUTTON_BACK", 0x2000);
- _luaContext.setGlobal("BUTTON_SELECT", 0x4000);
- _luaContext.setGlobal("BUTTON_L2", 0x8000);
- _luaContext.setGlobal("BUTTON_R2", 0x10000);
- _luaContext.setGlobal("BUTTON_LS_UP", 0x20000);
- _luaContext.setGlobal("BUTTON_LS_DOWN", 0x40000);
- _luaContext.setGlobal("BUTTON_LS_LEFT", 0x80000);
- _luaContext.setGlobal("BUTTON_LS_RIGHT", 0x100000);
- _luaContext.setGlobal("BUTTON_RS_UP", 0x200000);
- _luaContext.setGlobal("BUTTON_RS_DOWN", 0x400000);
- _luaContext.setGlobal("BUTTON_RS_LEFT", 0x800000);
- _luaContext.setGlobal("BUTTON_RS_RIGHT", 0x1000000);
-
- _gameEnterScript.attachToContext(&_luaContext);
-
- if (!_objectif.gui1().loaded()) {
- _objectif.load();
- }
- _question2.load();
- _dialog2.load();
- _documentsBrowser.load();
- _documentsBrowser.loadZoomed();
- _inventory.load();
-
- _inventory.cellphone()->onCallNumber().add(this, &Game::onCallNumber);
-
- if (hasLoadName()) {
- loadBackup(_loadName);
- } else {
- _gameLoadState = 1;
- onFinishedLoadingBackup("");
- }
- _sceneCharacterVisibleFromLoad = true;
- _scene._character->onFinished().remove(this, &Game::onDisplacementPlayerFinished);
- _scene._character->onFinished().add(this, &Game::onDisplacementPlayerFinished);
- _prevSceneName.clear();
- _notifier.load();
-}
-
/*static*/
TeI3DObject2 *Game::findLayoutByName(TeLayout *parent, const Common::String &name) {
// Seems like this is never used?
@@ -397,336 +95,6 @@ TeSpriteLayout *Game::findSpriteLayoutByName(TeLayout *parent, const Common::Str
return nullptr;
}
-void Game::finishFreemium() {
- Application *app = g_engine->getApplication();
- app->setFinishedGame(true);
- app->setFinishedFremium(true);
-}
-
-void Game::finishGame() {
- Application *app = g_engine->getApplication();
- // FIXME: The original sets this, but then Application::run immediately
- // returns to the menu.. how does the original wait for the credits to end??
- //app->_finishedGame = true;
- _playedTimer.stop();
- /* Game does this but does nothing with result?
- if (app->difficulty() == 2) {
- _playedTimer.getTimeFromStart();
- } */
- app->credits().enter(false);
-}
-
-void Game::initLoadedBackupData() {
- bool warpFlag = true;
- Application *app = g_engine->getApplication();
- Common::String firstWarpPath;
- if (!_loadName.empty()) {
- warpFlag = false;
- Common::InSaveFile *saveFile = g_engine->getSaveFileManager()->openForLoading(_loadName);
- Common::Error result = g_engine->loadGameStream(saveFile);
- if (result.getCode() == Common::kNoError) {
- ExtendedSavegameHeader header;
- if (MetaEngine::readSavegameHeader(saveFile, &header))
- g_engine->setTotalPlayTime(header.playtime);
- }
- } else {
- firstWarpPath = app->firstWarpPath();
- _currentScene = app->firstScene();
- _currentZone = app->firstZone();
- _playedTimer.start();
- _objectsTakenVal = 0;
- for (int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++) {
- _objectsTakenBits[i] = 0;
- }
- _dialogsTold = 0;
- if (_loadName == "NO_OWNER")
- _luaShowOwnerError = true;
- }
- _gameLoadState = 0;
- app->showLoadingIcon(false);
- _loadName.clear();
- initScene(warpFlag, firstWarpPath);
-}
-
-void Game::initNoScale() {
- if (!_noScaleLayout) {
- _noScaleLayout = new TeLayout();
- _noScaleLayout->setName("noScaleLayout");
- _noScaleLayout->setSizeType(TeILayout::RELATIVE_TO_PARENT);
- _noScaleLayout->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
- }
-
- if (!_noScaleLayout2) {
- _noScaleLayout2 = new TeLayout();
- _noScaleLayout2->setName("noScaleLayout2");
- _noScaleLayout2->setSizeType(TeILayout::RELATIVE_TO_PARENT);
- _noScaleLayout2->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
- }
-}
-
-void Game::initScene(bool fade, const Common::String &scenePath) {
- _luaContext.setGlobal("SHOW_OWNER_ERROR", _luaShowOwnerError);
- initWarp(_currentZone, _currentScene, fade);
- loadScene(scenePath);
- if (_scene._character->_model.get() && !_scene.findKate()) {
- _scene.models().push_back(_scene._character->_model);
- }
- _scene._character->_model->setVisible(true);
-}
-
-bool Game::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
- debug("Game::initWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
- _inventoryMenu.unload();
- _inGameGui.unload();
- _movePlayerCharacterDisabled = false;
- _sceneCharacterVisibleFromLoad = true;
-
- if (_scene._character) {
- _scene._character->_model->setVisible(true);
- _scene._character->deleteAllCallback();
- _scene._character->stop();
- _scene._character->setAnimation(_scene._character->characterSettings()._idleAnimFileName, true);
- if (!_scene.findKate()) {
- _scene.models().push_back(_scene._character->_model);
- if (_scene._character->_shadowModel[0]) {
- _scene.models().push_back(_scene._character->_shadowModel[0]);
- _scene.models().push_back(_scene._character->_shadowModel[1]);
- }
- }
- }
-
- _currentZone = zone;
- _currentScene = scene;
-
- _scene.loadBlockers();
- Common::Path scenePath("scenes");
- scenePath.joinInPlace(zone);
- scenePath.joinInPlace(scene);
- _sceneZonePath = scenePath;
-
- TeCore *core = g_engine->getCore();
-
- const Common::FSNode intLuaNode = core->findFile(scenePath.join(Common::String::format("Int%s.lua", scene.c_str())));
- const Common::FSNode logicLuaNode = core->findFile(scenePath.join(Common::String::format("Logic%s.lua", scene.c_str())));
- const Common::FSNode setLuaNode = core->findFile(scenePath.join(Common::String::format("Set%s.lua", scene.c_str())));
- Common::FSNode forLuaNode = core->findFile(scenePath.join(Common::String::format("For%s.lua", scene.c_str())));
- const Common::FSNode markerLuaNode = core->findFile(scenePath.join(Common::String::format("Marker%s.lua", scene.c_str())));
-
- bool intLuaExists = intLuaNode.exists();
- bool logicLuaExists = logicLuaNode.exists();
- bool setLuaExists = setLuaNode.exists();
- bool forLuaExists = forLuaNode.exists();
- if (!forLuaExists) {
- // slight hack.. try an alternate For lua path.
- forLuaNode = core->findFile(scenePath.join("Android-MacOSX").join(Common::String::format("For%s.lua", scene.c_str())));
- forLuaExists = forLuaNode.exists();
- debug("searched for %s", forLuaNode.getName().c_str());
- }
- bool markerLuaExists = markerLuaNode.exists();
-
- if (!intLuaExists && !logicLuaExists && !setLuaExists && !forLuaExists && !markerLuaExists) {
- debug("No lua scripts for scene %s zone %s", scene.c_str(), zone.c_str());
- return false;
- }
-
- for (auto &sound : _gameSounds) {
- sound->setRetain(false);
- }
-
- if (logicLuaExists) {
- _luaContext.addBindings(LuaBinds::LuaOpenBinds);
- _luaScript.attachToContext(&_luaContext);
- _luaScript.load(core->findFile("menus/help/help.lua"));
- _luaScript.execute();
- _luaScript.load(logicLuaNode);
- }
-
- if (_forGui.loaded())
- _forGui.unload();
-
- _scene.reset();
- _scene.bgGui().unload();
- _scene.markerGui().unload();
- _scene.hitObjectGui().unload();
- Common::Path geomPath(Common::String::format("scenes/%s/Geometry%s.bin",
- zone.c_str(), zone.c_str()));
- Common::FSNode geomFile = core->findFile(geomPath);
- if (geomFile.isReadable()) {
- // Syberia 1, load geom bin
- _scene.load(geomFile);
- } else {
- // Syberia 2, load from xml
- _scene.loadXml(zone, scene);
- }
- _scene.loadBackground(setLuaNode);
-
- Application *app = g_engine->getApplication();
- if (forLuaExists) {
- _forGui.load(forLuaNode);
- TeLayout *bg = _forGui.layoutChecked("background");
- bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
- app->frontLayout().addChild(bg);
- // Note: Game also adds cellphone to both frontLayout *and* noScaleLayout2,
- // so we reproduce the broken behavior exactly.
- TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayoutChecked("background");
- app->frontLayout().removeChild(cellbg);
- app->frontLayout().addChild(cellbg);
- _objectif.reattachLayout(&app->frontLayout());
- }
-
- if (intLuaExists) {
- _scene.loadInteractions(intLuaNode);
- TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = _scene.hitObjectGui().buttonLayouts();
- for (auto &entry : blayouts) {
- HitObject *hobj = new HitObject();
- TeButtonLayout *btn = entry._value;
- hobj->_game = this;
- hobj->_button = btn;
- hobj->_name = btn->name();
- btn->onMouseClickValidated().add(hobj, &HitObject::onValidated);
- btn->onButtonChangedToStateDownSignal().add(hobj, &HitObject::onDown);
- btn->onButtonChangedToStateUpSignal().add(hobj, &HitObject::onUp);
- _gameHitObjects.push_back(hobj);
- }
- }
-
- _inventoryMenu.load();
- _inGameGui.load("InGame.lua");
-
- TeButtonLayout *skipbtn = _inGameGui.buttonLayoutChecked("skipVideoButton");
- skipbtn->setVisible(false);
- skipbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
- skipbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
-
- TeButtonLayout *vidbgbtn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
- vidbgbtn->setVisible(false);
- vidbgbtn->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
- vidbgbtn->onMouseClickValidated().add(this, &Game::onLockVideoButtonValidated);
-
- TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
- video->setVisible(false);
- video->_tiledSurfacePtr->_frameAnim.onStop().remove(this, &Game::onVideoFinished);
- video->_tiledSurfacePtr->_frameAnim.onStop().add(this, &Game::onVideoFinished);
-
- TeButtonLayout *invbtn = _inGameGui.buttonLayoutChecked("inventoryButton");
- invbtn->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
- invbtn->onMouseClickValidated().add(this, &Game::onInventoryButtonValidated);
- invbtn->setSizeType(TeILayout::RELATIVE_TO_PARENT);
-
- const TeVector3f32 winSize = app->getMainWindow().size();
- if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
- invbtn->setSize(TeVector3f32(0.12f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.12f, 0.0));
- } else {
- invbtn->setSize(TeVector3f32(0.08f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.08f, 0.0));
- }
-
- TeCheckboxLayout *markersCheckbox = _inGameGui.checkboxLayout("markersVisibleButton");
- markersCheckbox->setState(_markersVisible ? TeCheckboxLayout::CheckboxStateActive : TeCheckboxLayout::CheckboxStateUnactive);
- markersCheckbox->onStateChangedSignal().add(this, &Game::onMarkersVisible);
-
- initNoScale();
- removeNoScale2Children();
- app->frontLayout().removeChild(_noScaleLayout2);
-
- TeLayout *vidLayout = _inGameGui.layout("videoLayout");
- app->frontLayout().removeChild(vidLayout);
- removeNoScaleChildren();
- app->frontLayout().removeChild(_noScaleLayout);
-
- app->frontLayout().addChild(_noScaleLayout);
- addNoScaleChildren();
- app->frontLayout().addChild(vidLayout);
- app->frontLayout().addChild(_noScaleLayout2);
- addNoScale2Children();
- if (!fadeFlag) {
- if (_inventory.selectedObject().size()) {
- _inventory.selectedObject(_inventory.selectedInventoryObject());
- }
- _inventory.setVisible(false);
- _objectif.setVisibleObjectif(false);
- _objectif.setVisibleButtonHelp(true);
- _running = true;
- loadScene("save.xml");
- }
-
- app->backLayout().addChild(_scene.background());
-
- if (markerLuaExists) {
- TeLayout *bg = _scene.markerGui().layout("background");
- app->frontLayout().addChild(bg);
- }
-
- Common::String camname = Common::String("Camera") + scene;
- _scene.setCurrentCamera(camname);
-
- // Special hacks for certain scenes (don't blame me, original does this..)
- if (g_engine->gameType() == TetraedgeEngine::kSyberia) {
- if (scene == "14050") {
- TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
- const TeVector3f32 coords(1200.6f, -1937.5f, 1544.1f);
- curcamera->setPosition(coords);
- } else if (scene == "34610") {
- TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
- const TeVector3f32 coords(-328.243f, 340.303f, -1342.84f);
- curcamera->setPosition(coords);
- const TeQuaternion rot(0.003194f, 0.910923f, -0.009496f, -0.412389f);
- curcamera->setRotation(rot);
- }
-
- //
- // WORKAROUND: Fix the camera in the restored scenes
- //
- if (zone == "ValStreet" && scene == "11100") {
- TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
- cam->setProjMatrixType(3);
- cam->setFov(0.5f);
- } else if (zone == "ValField" && scene == "11170") {
- TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
- cam->setProjMatrixType(3);
- // TODO: Is camera position right? Kate not visible..
- // default values:
- // -494.447998 -79.2976989 1408.5
- // scene entrance and exit
- // -184, -143, 1563
- // -42, -147, 1534
- } else if (zone == "BarRiverSide" && scene == "24020") {
- TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
- cam->setProjMatrixType(3);
- cam->setFov(0.5f);
- }
- }
-
- if (logicLuaExists) {
- _exitZone.clear();
- _luaScript.execute();
- _luaScript.execute("OnEnter", _prevSceneName);
- _luaScript.execute("OnSelectedObject", _inventory.selectedObject());
- }
-
- for (uint i = 0; i < _gameSounds.size(); i++) {
- if (_gameSounds[i]->retain())
- continue;
- _gameSounds[i]->stop();
- _gameSounds[i]->deleteLater();
- _gameSounds.remove_at(i);
- i--;
- }
-
- // Take a copy and clear the global list first, as deleting a sound can cause the
- // next sound to trigger (which might have been deleted already).
- Common::HashMap<Common::String, Common::Array<RandomSound *>> rsounds = _randomSounds;
- _randomSounds.clear();
- for (auto &randsoundlist : rsounds) {
- for (auto *randsound : randsoundlist._value) {
- delete randsound;
- }
- randsoundlist._value.clear();
- }
-
- _scene.initScroll();
- return true;
-}
-
bool Game::isDocumentOpened() {
return _documentsBrowser.gui1().layoutChecked("zoomed")->visible();
}
@@ -787,330 +155,11 @@ bool Game::launchDialog(const Common::String &dname, uint param_2, const Common:
return true;
}
-void Game::leave(bool flag) {
- if (!_enteredFlag2)
- return;
-
- Application *app = g_engine->getApplication();
-
- deleteNoScale();
- _entered = false;
- _running = false;
- _notifier.unload();
- g_engine->getInputMgr()->_mouseLUpSignal.remove(this, &Game::onMouseClick);
- _question2.unload();
- TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
- if (cellbg)
- app->frontLayout().removeChild(cellbg);
- _inventory.cellphone()->leave();
- _dialog2.unload();
- _inventory.unload();
- _documentsBrowser.unload();
- _inventoryMenu.unload();
- _gui1.unload();
- _objectif.unload(); // not done in original, but should be.
- _scene.close();
- _forGui.unload();
- if (_scene._character) {
- _scene._character->deleteAllCallback();
- _scene._character->stop();
- _scene.unloadCharacter(_scene._character->_model->name());
- }
-
- for (auto &sound : _gameSounds) {
- delete sound;
- }
- _gameSounds.clear();
-
- for (auto &randsoundlist : _randomSounds) {
- for (auto *randsound : randsoundlist._value) {
- delete randsound;
- }
- randsoundlist._value.clear();
- }
- _randomSounds.clear();
-
- for (auto *hitobj : _gameHitObjects) {
- delete hitobj;
- }
- _gameHitObjects.clear();
-
- // TODO: clear Game::HitObject tree here?
-
- _luaContext.destroy();
- _running = false;
- _inGameGui.buttonLayoutChecked("skipVideoButton")->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
- _inGameGui.buttonLayoutChecked("videoBackgroundButton")->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
- _inGameGui.spriteLayoutChecked("video")->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onSkipVideoButtonValidated);
- _inGameGui.buttonLayoutChecked("inventoryButton")->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
- _inGameGui.unload();
- _playedTimer.stop();
- _enteredFlag2 = false;
-
- app->lockCursor(false);
- app->lockCursorFromAction(false);
- // TODO: Set some inputmgr flag here?
- Character::animCacheFreeAll();
-}
-
-void Game::loadBackup(const Common::String &path) {
- if (_gameLoadState == 0) {
- _gameLoadState = 1;
- g_engine->getApplication()->showLoadingIcon(true);
- onFinishedLoadingBackup(path);
- }
-}
-
-void Game::loadUnlockedArtwork() {
- Common::ConfigManager::Domain *domain = ConfMan.getActiveDomain();
- for (auto &val : *domain) {
- if (val._key.substr(0, 8) == "artwork_") {
- _unlockedArtwork[val._key] = true;
- }
- }
-}
-
-bool Game::loadCharacter(const Common::String &name) {
- bool result = true;
- Character *character = _scene.character(name);
- if (!character) {
- result = _scene.loadCharacter(name);
- if (result) {
- character = _scene.character(name);
- assert(character);
- character->_onCharacterAnimFinishedSignal.remove(this, &Game::onCharacterAnimationFinished);
- character->_onCharacterAnimFinishedSignal.add(this, &Game::onCharacterAnimationFinished);
- // Syberia 2 uses a simplified callback here.
- // We have made onDisplacementPlayerFinished more like Syberia 1's onDisplacementFinished.
- if (g_engine->gameType() == TetraedgeEngine::kSyberia)
- character->onFinished().add(this, &Game::onDisplacementPlayerFinished);
- else
- character->onFinished().add(this, &Game::onDisplacementFinished);
- }
- }
- return result;
-}
-
-bool Game::loadPlayerCharacter(const Common::String &name) {
- bool result = _scene.loadPlayerCharacter(name);
- if (result) {
- _scene._character->_characterAnimPlayerFinishedSignal.remove(this, &Game::onCharacterAnimationPlayerFinished);
- _scene._character->_characterAnimPlayerFinishedSignal.add(this, &Game::onCharacterAnimationPlayerFinished);
- _scene._character->onFinished().remove(this, &Game::onDisplacementPlayerFinished);
- _scene._character->onFinished().add(this, &Game::onDisplacementPlayerFinished);
- } else {
- debug("failed to load player character %s", name.c_str());
- }
- return result;
-}
-
-bool Game::loadScene(const Common::String &name) {
- TeCore *core = g_engine->getCore();
- _gameEnterScript.load(core->findFile("scenes/OnGameEnter.lua"));
- _gameEnterScript.execute();
- Character *character = _scene._character;
- if (character && character->_model->visible()) {
- _sceneCharacterVisibleFromLoad = true;
- }
- return false;
-}
-
bool Game::onAnswered(const Common::String &val) {
_luaScript.execute("OnAnswered", val);
return false;
}
-bool Game::onCallNumber(Common::String val) {
- _luaScript.execute("OnCallNumber", val);
- return false;
-}
-
-bool Game::onCharacterAnimationFinished(const Common::String &charName) {
- if (!_scene._character)
- return false;
-
- if (g_engine->gameType() == TetraedgeEngine::kSyberia2) {
- Character *character = scene().character(charName);
- if (character) {
- const Common::String curAnimName = character->curAnimName();
- if (curAnimName == character->walkAnim(Character::WalkPart_EndD)
- || curAnimName == character->walkAnim(Character::WalkPart_EndG)) {
- character->updatePosition(1.0);
- character->endMove();
- }
- }
- }
-
- for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
- YieldedCallback &cb = _yieldedCallbacks[i];
- if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == charName) {
- TeLuaThread *lua = cb._luaThread;
- _yieldedCallbacks.remove_at(i);
- if (lua) {
- lua->resume();
- return false;
- }
- break;
- }
- }
- _luaScript.execute("OnCharacterAnimationFinished", charName);
- return false;
-}
-
-bool Game::onCharacterAnimationPlayerFinished(const Common::String &anim) {
- if (_gameLoadState != 0)
- return false;
-
- bool callScripts = true;
- for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
- YieldedCallback &cb = _yieldedCallbacks[i];
- // Yes, even Syberia2 checks for Kate here..
- if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == "Kate") {
- TeLuaThread *lua = cb._luaThread;
- _yieldedCallbacks.remove_at(i);
- if (lua) {
- lua->resume();
- callScripts = false;
- }
- break;
- }
- }
- if (callScripts) {
- if (g_engine->gameType() == TetraedgeEngine::kSyberia)
- _luaScript.execute("OnCharacterAnimationFinished", "Kate");
- else
- _luaScript.execute("OnCharacterAnimationPlayerFinished", anim);
- _luaScript.execute("OnCellCharacterAnimationPlayerFinished", anim);
- }
-
- Character *character = scene()._character;
- assert(character);
- // Note: the above callbacks can change the anim,
- // so we have to fetch this *after* them.
- const Common::String curAnimName = character->curAnimName();
- if (_currentScene == _someSceneName) {
- if (curAnimName == character->walkAnim(Character::WalkPart_Start)
- || curAnimName == character->walkAnim(Character::WalkPart_Loop)
- || curAnimName == character->walkAnim(Character::WalkPart_EndD)
- || curAnimName == character->walkAnim(Character::WalkPart_EndG))
- character->stop();
- } else {
- if (!_sceneCharacterVisibleFromLoad && curAnimName == character->walkAnim(Character::WalkPart_Start)) {
- character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
- return false;
- }
- if (curAnimName == character->walkAnim(Character::WalkPart_EndD)
- || curAnimName == character->walkAnim(Character::WalkPart_EndG)) {
- character->updatePosition(1.0);
- character->endMove();
- // endMove can result in callbacks that change the animation. check again.
- if (character->curAnimName() == character->walkAnim(Character::WalkPart_EndD)
- || character->curAnimName() == character->walkAnim(Character::WalkPart_EndG))
- character->setAnimation(character->characterSettings()._idleAnimFileName, true);
- }
- }
-
- return false;
-}
-
-bool Game::onDialogFinished(const Common::String &val) {
- for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
- YieldedCallback &cb = _yieldedCallbacks[i];
- if (cb._luaFnName == "OnDialogFinished" && cb._luaParam == val) {
- TeLuaThread *lua = cb._luaThread;
- _yieldedCallbacks.remove_at(i);
- if (lua) {
- lua->resume();
- return false;
- }
- break;
- }
- }
-
- _luaScript.execute("OnDialogFinished", val);
- _luaScript.execute("OnCellDialogFinished", val);
- return false;
-}
-
-// This is the Syberia 2 version of this function, not used in Syb 1.
-// Syb 1 uses a function much more like onDisplacementPlayerFinished below.
-bool Game::onDisplacementFinished() {
- TeLuaThread *thread = nullptr;
- for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
- YieldedCallback &cb = _yieldedCallbacks[i];
- if (cb._luaFnName == "OnDisplacementFinished") {
- thread = cb._luaThread;
- _yieldedCallbacks.remove_at(i);
- break;
- }
- }
- if (thread) {
- thread->resume();
- } else {
- _luaScript.execute("OnDisplacementFinished");
- }
- return false;
-}
-
-bool Game::onDisplacementPlayerFinished() {
- _sceneCharacterVisibleFromLoad = true;
- assert(_scene._character);
- _scene._character->stop();
- _scene._character->walkMode("Walk");
- _scene._character->setAnimation(_scene._character->characterSettings()._idleAnimFileName, true);
-
- if (_isCharacterWalking) {
- _isCharacterWalking = false;
- _isCharacterIdle = true;
- } else {
- _isCharacterIdle = false;
- }
-
- TeLuaThread *thread = nullptr;
-
- const char *cbName = (g_engine->gameType() == TetraedgeEngine::kSyberia ?
- "OnDisplacementFinished" : "OnDisplacementPlayerFinished");
-
- for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
- YieldedCallback &cb = _yieldedCallbacks[i];
- if (cb._luaFnName == cbName) {
- thread = cb._luaThread;
- _yieldedCallbacks.remove_at(i);
- break;
- }
- }
- if (thread) {
- thread->resume();
- } else {
- _luaScript.execute(cbName);
- }
- return false;
-}
-
-bool Game::onFinishedCheckBackup(bool result) {
- if (_gameLoadState == 1) {
- _gameLoadState = 0;
- return true;
- }
- return false;
-}
-
-bool Game::onFinishedLoadingBackup(const Common::String &val) {
- if (_gameLoadState == 1) {
- _loadName = val;
- _gameLoadState = 2;
- return true;
- }
- return false;
-}
-
-bool Game::onFinishedSavingBackup(int something) {
- if (something) {
- g_engine->getGame()->_returnToMainMenu = true;
- }
- g_engine->getApplication()->showLoadingIcon(false);
- return true;
-}
bool Game::onInventoryButtonValidated() {
_inventoryMenu.enter();
@@ -1123,119 +172,6 @@ bool Game::onLockVideoButtonValidated() {
return true;
}
-bool Game::onMarkersVisible(TeCheckboxLayout::State state) {
- _markersVisible = (state == TeCheckboxLayout::CheckboxStateActive);
- showMarkers(state == TeCheckboxLayout::CheckboxStateActive);
- return false;
-}
-
-bool Game::onMouseClick(const Common::Point &pt) {
- Application *app = g_engine->getApplication();
-
- if (app->isFading())
- return true;
-
- // In case we capture a click during a video or dialog (shouldn't happen?)
- if (!_scene.currentCamera() || _dialog2.isDialogPlaying() || _question2.isEntered())
- return false;
-
- _posPlayer = TeVector3f32(-1.0f, -1.0f, -1.0f);
- if (_previousMousePos == TeVector2s32(-1, -1)) {
- _previousMousePos = pt;
- } else {
- const TeVector3f32 winSize = app->getMainWindow().size();
- const TeVector2s32 prevMousePos = _previousMousePos;
- _previousMousePos = pt;
- float xdist = (pt.x - prevMousePos._x) / winSize.x();
- float ydist = (pt.y - prevMousePos._y) / winSize.y();
- float sqrdist = xdist * xdist + ydist * ydist;
- if (sqrdist < 0.0001 && (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000.0
- || (_scene._character && _scene._character->walkModeStr() != "Walk"))) {
- return false;
- // Normal walk click
- }
- }
-
- if (!app->frontLayout().isMouseIn(pt))
- return false;
-
- Common::String nearestMeshName = "None";
- TeIntrusivePtr<TeCamera> curCamera = _scene.currentCamera();
- Common::Array<TePickMesh2*> pickMeshes = _scene.clickMeshes();
- TePickMesh2 *nearestMesh = TeFreeMoveZone::findNearestMesh(curCamera, pt, pickMeshes, nullptr, false);
- if (nearestMesh) {
- nearestMeshName = nearestMesh->name();
- debug("Game::onMouseClick: Click near mesh %s", nearestMeshName.c_str());
- _lastCharMoveMousePos = TeVector2s32();
- }
-
- Character *character = _scene._character;
- if (app->isLockCursor() || _movePlayerCharacterDisabled || !character)
- return false;
-
- const Common::String &charAnim = character->curAnimName();
-
- if (charAnim == character->characterSettings()._idleAnimFileName
- || charAnim == character->walkAnim(Character::WalkPart_Start)
- || charAnim == character->walkAnim(Character::WalkPart_Loop)
- || charAnim == character->walkAnim(Character::WalkPart_EndD)
- || charAnim == character->walkAnim(Character::WalkPart_EndG)) {
- _luaScript.execute("On");
- if (!_scene.isObjectBlocking(nearestMeshName) && character->freeMoveZone()) {
- const TeVector3f32 charPos = character->_model->position();
- TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(charPos, pt, 8.0, true);
- if (!curve)
- return false;
-
- _scene.setCurve(curve);
- character->setCurveStartLocation(TeVector3f32());
- if (curve->controlPoints().size() == 1) {
- character->endMove();
- } else {
- if (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000 || !_runModeEnabled) {
- _walkTimer.stop();
- _walkTimer.start();
- character->walkMode("Walk");
- } else {
- // Note: original checks the timer elapsed again here.. why?
- _walkTimer.stop();
- character->walkMode("Jog");
- }
- character->placeOnCurve(curve);
- character->setCurveOffset(0.0);
- if (charAnim != character->walkAnim(Character::WalkPart_Start)) {
- character->setAnimation(character->walkAnim(Character::WalkPart_Start), false);
- }
- character->walkTo(1.0, false);
- _sceneCharacterVisibleFromLoad = false;
- _lastCharMoveMousePos = pt;
- }
- }
- // FIXME: The original never checks for empty/null curve here..
- // but it seems our curve can possibly become null.
- if (_scene.curve() && _scene.curve()->length()) {
- TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
- character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
- character->walkTo(1.0, false);
- _isCharacterWalking = true;
- _posPlayer = lastPoint;
- }
- }
-
- // Note: charAnim above may no longer be valid as anim may have changed.
- if (_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
- _lastCharMoveMousePos = TeVector2s32();
- _movePlayerCharacterDisabled = false;
- _isCharacterIdle = true;
- _isCharacterWalking = false;
- if (nearestMesh) {
- character->stop();
- _luaScript.execute("OnWarpObjectHit", nearestMeshName);
- }
- }
-
- return false;
-}
#ifdef TETRAEDGE_ENABLE_CUSTOM_CURSOR_CHECKS
// Note: None of these cursor files seem to be actually shipped with the game
@@ -1330,46 +266,10 @@ bool Game::onMouseMove() {
bool Game::onSkipVideoButtonValidated() {
TeSpriteLayout *sprite = _inGameGui.spriteLayoutChecked("video");
- TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
sprite->stop();
- btn->setVisible(false);
- return false;
-}
-
-bool Game::onVideoFinished() {
- if (!_inGameGui.loaded()) {
- _music.stop();
- return false;
- }
-
- Application *app = g_engine->getApplication();
-
- app->captureFade();
-
- TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
- Common::String vidPath = video->_tiledSurfacePtr->loadedPath();
- TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
- btn->setVisible(false);
- btn = _inGameGui.buttonLayoutChecked("skipVideoButton");
- btn->setVisible(false);
- video->setVisible(false);
- _music.stop();
- _running = true;
- bool resumed = false;
- for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
- YieldedCallback &cb = _yieldedCallbacks[i];
- if (cb._luaFnName == "OnMovieFinished" && cb._luaParam == vidPath) {
- TeLuaThread *lua = cb._luaThread;
- _yieldedCallbacks.remove_at(i);
- resumed = true;
- if (lua)
- lua->resume();
- break;
- }
- }
- if (!resumed)
- _luaScript.execute("OnMovieFinished", vidPath);
- app->fade();
+ TeButtonLayout *btn = _inGameGui.buttonLayout("videoBackgroundButton");
+ if (btn)
+ btn->setVisible(false);
return false;
}
@@ -1430,50 +330,6 @@ bool Game::playMovie(const Common::String &vidPath, const Common::String &musicP
}
}
-void Game::playRandomSound(const Common::String &name) {
- if (!_randomSounds.contains(name)) {
- warning("Game::playRandomSound: can't find sound list %s", name.c_str());
- return;
- }
-
- if (!_randomSoundFinished) {
- _randomSoundTimer.start();
- int r = g_engine->getRandomNumber(RAND_MAX);
- float f = (r + 1 + (r / 100) * -100);
- uint64 time = 1000000;
- if (f >= 25.0) {
- time = f * 45000.0;
- }
- _randomSoundTimer.setAlarmIn(time);
- _randomSoundTimer.alarmSignal().remove(_randomSound, &RandomSound::onSoundFinished);
- _randomSoundTimer.alarmSignal().add(_randomSound, &RandomSound::onSoundFinished);
- _randomSound->_name = name;
- } else {
- Common::Array<RandomSound *> &sndlist = _randomSounds[name];
- float total = 0.0;
- for (auto *snd : sndlist) {
- total += snd->_f1;
- }
- int r = g_engine->getRandomNumber(RAND_MAX);
- float total2 = 0.0;
- uint i = 0;
- while (i < sndlist.size() && total2 <= r * 4.656613e-10 * total) {
- total2 += sndlist[i]->_f1;
- i++;
- }
- assert(i > 0);
- i--;
- RandomSound *sound = sndlist[i];
- sound->_music.volume(sound->_volume);
- sound->_music.onStopSignal().remove(sound, &RandomSound::onSoundFinished);
- sound->_music.onStopSignal().add(sound, &RandomSound::onSoundFinished);
- sound->_music.load(sound->_path.toString());
- sound->_music.repeat(false);
- sound->_music.play();
- // TODO: set a flag that it's playing?
- }
-}
-
void Game::playSound(const Common::String &name, int repeats, float volume) {
Game *game = g_engine->getGame();
@@ -1525,43 +381,6 @@ void Game::removeNoScale2Child(TeLayout *layout) {
_noScaleLayout2->removeChild(layout);
}
-void Game::removeNoScale2Children() {
- if (!_noScaleLayout2)
- return;
-
- TeLayout *vidbtn = _inGameGui.layout("videoButtonLayout");
- if (vidbtn)
- _noScaleLayout2->removeChild(vidbtn);
-
- TeLayout *bg = _inventory.cellphone()->gui().layout("background");
- if (bg)
- _noScaleLayout2->removeChild(bg);
-
- TeButtonLayout *bgbtn = _objectif.gui1().buttonLayout("background");
- if (bgbtn)
- _noScaleLayout2->removeChild(bgbtn);
-
- TeLayout *notifier = _notifier.gui().layout("notifier");
- if (notifier)
- _noScaleLayout2->removeChild(notifier);
-}
-
-void Game::removeNoScaleChildren() {
- if (!_noScaleLayout)
- return;
- _noScaleLayout->removeChild(&_question2);
- Application *app = g_engine->getApplication();
- app->frontLayout().removeChild(&_dialog2);
- _noScaleLayout->removeChild(&_inventory);
- _noScaleLayout->removeChild(&_inventoryMenu);
- _noScaleLayout->removeChild(&_documentsBrowser);
- _noScaleLayout->removeChild(&_documentsBrowser.zoomedLayout());
-}
-
-void Game::resetPreviousMousePos() {
- _previousMousePos = TeVector2s32(-1, -1);
-}
-
void Game::resumeMovie() {
_music.play();
_inGameGui.spriteLayout("video")->play();
@@ -1674,189 +493,5 @@ Common::Error Game::syncGame(Common::Serializer &s) {
return Common::kNoError;
}
-bool Game::unloadCharacter(const Common::String &charname) {
- Character *c = _scene.character(charname);
- if (!c)
- return false;
-
- for (uint i = 0; i < _scene.models().size(); i++) {
- if (_scene.models()[i] == c->_model) {
- _scene.models().remove_at(i);
- break;
- }
- }
- c->_onCharacterAnimFinishedSignal.remove(this, &Game::onCharacterAnimationFinished);
- c->removeAnim();
- // Syberia 2 uses a simplified callback here.
- // We have made onDisplacementPlayerFinished more like Syberia 1's onDisplacementPlayerFinished.
- if (g_engine->gameType() == TetraedgeEngine::kSyberia)
- c->onFinished().remove(this, &Game::onDisplacementPlayerFinished);
- else
- c->onFinished().remove(this, &Game::onDisplacementFinished);
- _scene.unloadCharacter(charname);
- return true;
-}
-
-bool Game::unloadCharacters() {
- // Loop will update the array, take a copy first.
- Common::Array<Character *> chars = _scene._characters;
- for (Character *c : chars) {
- unloadCharacter(c->_model->name());
- }
- return true;
-}
-
-bool Game::unloadPlayerCharacter(const Common::String &charname) {
- Character *c = _scene.character(charname);
- if (c) {
- c->_onCharacterAnimFinishedSignal.remove(this, &Game::onCharacterAnimationPlayerFinished);
- c->onFinished().remove(this, &Game::onDisplacementPlayerFinished);
- _scene.unloadCharacter(charname);
- }
- return c != nullptr;
-}
-
-void Game::update() {
- if (!_entered)
- return;
-
- TeITextLayout *debugTimeTextLayout = _inGameGui.textLayout("debugTimeText1");
- if (debugTimeTextLayout) {
- warning("TODO: Game::update: Fill out debugTimeTextLayout");
- }
-
- if (!_warped) {
- if (_gameLoadState == 2) {
- initLoadedBackupData();
- return;
- } else if (_gameLoadState != 0) {
- return;
- }
-
- Application *app = g_engine->getApplication();
-
- if (_scene._character) {
- if (!_scene._character->_model->visible())
- app->lockCursor(false);
- }
-
- TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
- if (invbtn)
- invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
-
- Character *player = _scene._character;
- if (player) {
- TeIntrusivePtr<TeModel> model = player->_model;
- bool modelVisible = model->visible();
- if (model->anim())
- player->permanentUpdate();
- if (modelVisible) {
- if (player->needsSomeUpdate()) {
- Game *game = g_engine->getGame();
- game->_sceneCharacterVisibleFromLoad = false;
- TeVector3f32 charPos = player->_model->position();
- const Common::String charName = player->_model->name();
- TeFreeMoveZone *zone = _scene.pathZone(player->freeMoveZoneName());
- if (zone) {
- TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
- zone->setCamera(cam, false);
- player->setFreeMoveZone(zone);
- _scene.setPositionCharacter(charName, player->freeMoveZoneName(), charPos);
- TeIntrusivePtr<TeBezierCurve> curve = zone->curve(model->position(), player->positionCharacter());
- _scene.setCurve(curve);
- player->setCurveStartLocation(TeVector3f32(0, 0, 0));
- player->placeOnCurve(curve);
- player->setCurveOffset(0.0f);
- player->setAnimation(player->walkAnim(Character::WalkPart_Start), false);
- player->walkTo(1.0f, false);
- _isCharacterWalking = true;
- }
- player->setNeedsSomeUpdate(false);
- }
-
- const Common::String &charAnim = _scene._character->curAnimName();
- bool unlockCursor = (charAnim == _scene._character->walkAnim(Character::WalkPart_Start) ||
- charAnim == _scene._character->walkAnim(Character::WalkPart_Loop) ||
- charAnim == _scene._character->walkAnim(Character::WalkPart_EndD) ||
- charAnim == _scene._character->walkAnim(Character::WalkPart_EndG) ||
- charAnim == _scene._character->characterSettings()._idleAnimFileName);
- app->lockCursor(!unlockCursor);
- }
- }
-
- Common::Array<Character *> characters = _scene._characters;
- for (Character *c : characters) {
- if (c->_model->anim())
- c->permanentUpdate();
- }
-
- Common::Point mousePos = g_engine->getInputMgr()->lastMousePos();
- if (_lastUpdateMousePos != mousePos) {
- onMouseMove();
- _lastUpdateMousePos = mousePos;
- }
- if (_saveRequested) {
- _saveRequested = false;
- saveBackup("save.xml");
- }
-
- _luaScript.execute("Update");
- _objectif.update();
- _scene.update();
- } else {
- TeSoundManager *soundmgr = g_engine->getSoundManager();
- // Take a copy in case the active music objects changes as we iterate.
- Common::Array<TeMusic *> musics = soundmgr->musics();
- for (TeMusic *music : musics) {
- const Common::String &chanName = music->channelName();
- if (chanName != "music" && chanName != "sfx" && chanName != "dialog")
- music->stop();
- }
- changeWarp2(_warpZone, _warpScene, _warpFadeFlag);
- }
-}
-
-
-bool Game::HitObject::onChangeWarp() {
- // Seems like this function is never used?
- error("TODO: Implement Game::HitObject::onChangeWarp");
- return false;
-}
-
-bool Game::HitObject::onDown() {
- _game->luaScript().execute("OnButtonDown", _name);
- _game->_isCharacterIdle = true;
- return false;
-}
-
-bool Game::HitObject::onUp() {
- // debug("Game::HitObject mouseup: %s", _name.c_str());
- _game->luaScript().execute("OnButtonUp", _name);
- _game->_isCharacterIdle = true;
- return false;
-}
-
-bool Game::HitObject::onValidated() {
- if (!g_engine->getApplication()->isLockCursor()) {
- _game->luaScript().execute("OnWarpObjectHit", _name);
- _game->_isCharacterIdle = true;
- }
- return false;
-}
-
-bool Game::RandomSound::onSoundFinished() {
- Game *game = g_engine->getGame();
- _music.onStopSignal().remove(this, &RandomSound::onSoundFinished);
- if (game->_randomSoundFinished) {
- game->_randomSoundFinished = false;
- } else {
- game->_randomSoundFinished = true;
- game->_randomSound->_music.onStopSignal().remove(this, &RandomSound::onSoundFinished);
- game->_randomSoundTimer.stop();
- }
- game->playRandomSound(_name);
- return false;
-}
-
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index d91d2cb684a..b8502db1659 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -49,29 +49,7 @@ class TeLuaThread;
class Game {
public:
Game();
- ~Game();
-
- struct HitObject {
- bool onChangeWarp();
- bool onDown();
- bool onUp();
- bool onValidated();
- //byte OnVisible(); empty never used?
-
- Common::String _name;
- Game *_game;
- TeButtonLayout *_button;
- };
-
- class RandomSound {
- public:
- Common::Path _path;
- Common::String _name;
- TeMusic _music;
- float _f1;
- float _volume;
- bool onSoundFinished();
- };
+ virtual ~Game();
struct YieldedCallback {
TeLuaThread *_luaThread;
@@ -81,46 +59,34 @@ public:
// Note: original game long, and int fields.. unused?
};
- //enum EGameScoreID {}; // Not needed?
-
- void addArtworkUnlocked(const Common::String &name, bool notify);
void addNoScale2Child(TeLayout *layout);
- void addRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2);
- void addToBag(const Common::String &objname);
- void addToHand(const Common::String &objname);
- void addToScore(int score);
+ virtual void addToBag(const Common::String &objname) = 0;
- bool changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+ virtual bool changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) = 0;
- void draw();
- void enter(); // will load game if _loadName is set.
+ virtual void draw() = 0;
+ virtual void enter() = 0; // will load game if _loadName is set.
// Note: game uses ILayouts here..
static TeI3DObject2 *findLayoutByName(TeLayout *parent, const Common::String &name);
static TeSpriteLayout *findSpriteLayoutByName(TeLayout *parent, const Common::String &name);
- void finishFreemium();
- void finishGame();
- void initLoadedBackupData();
+ virtual void finishGame() = 0;
+ virtual void initLoadedBackupData() = 0;
bool isDocumentOpened();
bool isMouse() { return false; }
bool isMoviePlaying();
- bool launchDialog(const Common::String ¶m_1, uint param_2, const Common::String ¶m_3,
- const Common::String ¶m_4, float param_5);
- void leave(bool flag);
- void loadBackup(const Common::String &path);
- bool loadPlayerCharacter(const Common::String &name);
- bool loadScene(const Common::String &name);
+ bool launchDialog(const Common::String ¶m_1, uint param_2, const Common::String &charname,
+ const Common::String &animfile, float animblend);
+ virtual void leave(bool flag) = 0;
// Not in original. Load unlocked artwork from ScummVM config.
- void loadUnlockedArtwork();
+ virtual void loadUnlockedArtwork() {};
//void pauseMovie(); // Unused
//void pauseSounds() {}; // Unused, does nothing?
bool playMovie(const Common::String &vidPath, const Common::String &musicPath, float volume = 1.0f);
- void playRandomSound(const Common::String &name);
void playSound(const Common::String &name, int param_2, float volume);
void removeNoScale2Child(TeLayout *layout);
- void resetPreviousMousePos();
void resumeMovie();
void resumeSounds() {}; // does nothing?
void saveBackup(const Common::String &saveName);
@@ -131,10 +97,7 @@ public:
// void startAnimationPart(const Common::String ¶m_1, int param_2, int param_3, int param_4, bool param_5) {}; // Unused.
void stopSound(const Common::String &name);
Common::Error syncGame(Common::Serializer &s); // Basically replaces saveBackup from original..
- bool unloadCharacter(const Common::String &character);
- bool unloadCharacters();
- bool unloadPlayerCharacter(const Common::String &character);
- void update();
+ virtual void update() = 0;
InventoryMenu &inventoryMenu() { return _inventoryMenu; }
Inventory &inventory() { return _inventory; }
@@ -145,14 +108,9 @@ public:
bool _returnToMainMenu;
bool _firstInventory;
- bool _movePlayerCharacterDisabled;
- bool _sceneCharacterVisibleFromLoad;
- bool _isCharacterWalking;
- bool _isCharacterIdle;
const Common::String ¤tZone() const { return _currentZone; }
const Common::String ¤tScene() const { return _currentScene; }
- const Common::Path &sceneZonePath() const { return _sceneZonePath; }
TeLuaScript &luaScript() { return _luaScript; }
TeLuaContext &luaContext() { return _luaContext; }
InGameScene &scene() { return _scene; }
@@ -160,108 +118,45 @@ public:
Question2 &question2() { return _question2; }
TeLuaGUI &forGui() { return _forGui; }
TeLuaGUI &inGameGui() { return _inGameGui; }
- Objectif &objectif() { return _objectif; }
- Common::Array<YieldedCallback> &yieldedCallbacks() { return _yieldedCallbacks; }
- void setSaveRequested() { _saveRequested = true; }
- bool markersVisible() const { return _markersVisible; }
- const TeVector3f32 &posPlayer() const { return _posPlayer; }
- void setPosPlayer(const TeVector3f32 &pos) { _posPlayer = pos; }
- TeTimer &walkTimer() { return _walkTimer; }
- void setExitZone(const Common::String &zone) { _exitZone = zone; }
- void setLoadName(const Common::String &loadName) { _loadName = loadName; }
bool hasLoadName() const { return !_loadName.empty(); }
- bool isArtworkUnlocked(const Common::String &name) const;
- static Common::String artworkConfName(const Common::String &name);
-
- void setRunModeEnabled(bool val) { _runModeEnabled = val; }
- bool runModeEnabled() const { return _runModeEnabled; }
-
-private:
- bool addAnimToSet(const Common::String &path);
- void addNoScale2Children();
- void addNoScaleChildren();
-
- void attachButtonsLayoutGoto() {}; // does nothing?
- void createButtonsLayoutGoto() {}; // does nothing?
- void deleteButtonsLayoutGoto() {}; // does nothing?
-
- bool changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag);
-
- void deleteNoScale();
-
- void initNoScale();
- void initScene(bool param_1, const Common::String &scenePath);
- bool initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
-
- bool loadCharacter(const Common::String &name);
+ void setLoadName(const Common::String &loadName) { _loadName = loadName; }
bool onAnswered(const Common::String &val);
- bool onCallNumber(Common::String val);
- bool onCharacterAnimationFinished(const Common::String &val);
- bool onCharacterAnimationPlayerFinished(const Common::String &val);
- bool onDialogFinished(const Common::String &val);
- bool onDisplacementFinished();
- bool onDisplacementPlayerFinished();
- bool onFinishedCheckBackup(bool result);
- bool onFinishedLoadingBackup(const Common::String &val);
- bool onFinishedSavingBackup(int something);
+ virtual bool onDialogFinished(const Common::String &val) = 0;
+ virtual bool onFinishedLoadingBackup(const Common::String &val) { return false; }
bool onInventoryButtonValidated();
bool onLockVideoButtonValidated();
- bool onMarkersVisible(TeCheckboxLayout::State state);
- bool onMouseClick(const Common::Point &pt);
bool onMouseMove();
bool onSkipVideoButtonValidated();
- bool onVideoFinished();
-
- void removeNoScale2Children();
- void removeNoScaleChildren();
+ virtual bool onVideoFinished() = 0;
+protected:
bool _luaShowOwnerError;
bool _running;
bool _entered;
- bool _enteredFlag2;
- TeLuaGUI _gui1; // TODO: Is this ever used?
+ //TeLuaGUI _gui1; // Never used.
TeLuaGUI _setAnimGui;
TeLuaGUI _forGui;
TeLuaGUI _inGameGui;
Inventory _inventory;
InventoryMenu _inventoryMenu;
- int _score;
-
- int _frameCounter;
InGameScene _scene;
- static char **_objectsTakenIDs;
-
- TeVector2s32 _previousMousePos;
- TeVector2s32 _lastCharMoveMousePos;
-
- Common::String _warpZone;
- Common::String _warpScene;
- bool _warpFadeFlag;
- bool _warped;
+ Common::String _loadName;
- Common::String _currentZone;
Common::String _currentScene;
- Common::String _exitZone;
+ Common::String _currentZone;
Common::String _prevSceneName;
- Common::String _someSceneName;
- Common::Path _sceneZonePath;
-
- Common::String _loadName;
Common::Array<GameSound *> _gameSounds;
- Common::Array<HitObject *> _gameHitObjects;
- // These are static in original, but cleaner to keep here.
- Common::Array<YieldedCallback> _yieldedCallbacks;
-
- Common::HashMap<Common::String, bool> _unlockedArtwork;
- Common::HashMap<Common::String, Common::Array<RandomSound *>> _randomSounds;
- int _gameLoadState;
+ static const int NUM_OBJECTS_TAKEN_IDS = 5;
+ static const char *OBJECTS_TAKEN_IDS[NUM_OBJECTS_TAKEN_IDS];
+ bool _objectsTakenBits[NUM_OBJECTS_TAKEN_IDS];
+ int _objectsTakenVal;
TeTimer _playedTimer;
TeTimer _walkTimer;
@@ -274,30 +169,11 @@ private:
Question2 _question2;
Dialog2 _dialog2;
- Objectif _objectif;
- static const int NUM_OBJECTS_TAKEN_IDS = 5;
- static const char *OBJECTS_TAKEN_IDS[NUM_OBJECTS_TAKEN_IDS];
- bool _objectsTakenBits[NUM_OBJECTS_TAKEN_IDS];
- int _objectsTakenVal;
int _dialogsTold;
- bool _markersVisible;
- bool _saveRequested;
- bool _randomSoundFinished;
-
- RandomSound *_randomSound;
- TeTimer _randomSoundTimer;
-
- TeLayout *_noScaleLayout;
TeLayout *_noScaleLayout2;
- TeVector3f32 _posPlayer;
-
- Common::Point _lastUpdateMousePos;
-
- // Syberia 2 specific data
- bool _runModeEnabled;
};
} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/game_sound.cpp b/engines/tetraedge/game/game_sound.cpp
index b7f45c3cee1..b0b0b6261a5 100644
--- a/engines/tetraedge/game/game_sound.cpp
+++ b/engines/tetraedge/game/game_sound.cpp
@@ -20,7 +20,7 @@
*/
#include "tetraedge/game/game_sound.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/tetraedge.h"
#include "tetraedge/te/te_lua_thread.h"
@@ -31,11 +31,12 @@ GameSound::GameSound() {
}
bool GameSound::onSoundStopped() {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
if (!game->luaContext().isCreated())
return false;
- Common::Array<Game::YieldedCallback> &callbacks = game->yieldedCallbacks();
+ Common::Array<SyberiaGame::YieldedCallback> &callbacks = game->yieldedCallbacks();
for (uint i = 0; i < callbacks.size(); i++) {
if (callbacks[i]._luaFnName == "OnFreeSoundFinished" && callbacks[i]._luaParam == _name) {
TeLuaThread *thread = callbacks[i]._luaThread;
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 32e4b39ec71..23134f6965f 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -26,7 +26,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
#include "tetraedge/game/billboard.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/game/in_game_scene_xml_parser.h"
#include "tetraedge/game/character.h"
@@ -108,7 +108,8 @@ void InGameScene::addAnchorZone(const Common::String &s1, const Common::String &
bool InGameScene::addMarker(const Common::String &markerName, const Common::String &imgPath, float x, float y, const Common::String &locType, const Common::String &markerVal, float anchorX, float anchorY) {
const TeMarker *marker = findMarker(markerName);
if (!marker) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
Application *app = g_engine->getApplication();
TeSpriteLayout *markerSprite = new TeSpriteLayout();
// Note: game checks paths here but seems to just use the original?
@@ -550,7 +551,8 @@ void InGameScene::freeSceneObjects() {
_characters[0]->deleteAllCallback();
}
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->unloadCharacters();
_characters.clear();
@@ -1456,7 +1458,8 @@ void InGameScene::loadInteractions(const Common::FSNode &node) {
void InGameScene::moveCharacterTo(const Common::String &charName, const Common::String &curveName, float curveOffset, float curveEnd) {
Character *c = character(charName);
if (c != nullptr && c != _character) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
if (!game->_movePlayerCharacterDisabled) {
c->setCurveStartLocation(c->characterSettings()._cutSceneCurveDemiPosition);
TeIntrusivePtr<TeBezierCurve> crve = curve(curveName);
@@ -1657,7 +1660,8 @@ void InGameScene::unloadSpriteLayouts() {
}
void InGameScene::update() {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
if (_bgGui.loaded()) {
_bgGui.layoutChecked("background")->setZPosition(0.0f);
}
@@ -1730,7 +1734,7 @@ void InGameScene::update() {
_waitTimeTimer.stop();
bool resumed = false;
for (uint i = 0; i < game->yieldedCallbacks().size(); i++) {
- Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
+ SyberiaGame::YieldedCallback &yc = game->yieldedCallbacks()[i];
if (yc._luaFnName == "OnWaitFinished") {
TeLuaThread *thread = yc._luaThread;
game->yieldedCallbacks().remove_at(i);
@@ -1878,9 +1882,10 @@ void InGameScene::activateMask(const Common::String &name, bool val) {
}
bool InGameScene::AnimObject::onFinished() {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (uint i = 0; i < game->yieldedCallbacks().size(); i++) {
- Game::YieldedCallback &yc = game->yieldedCallbacks()[i];
+ SyberiaGame::YieldedCallback &yc = game->yieldedCallbacks()[i];
if (yc._luaFnName == "OnFinishedAnim" && yc._luaParam == _name) {
TeLuaThread *thread = yc._luaThread;
game->yieldedCallbacks().remove_at(i);
diff --git a/engines/tetraedge/game/lua_binds.cpp b/engines/tetraedge/game/lua_binds.cpp
index de23497c344..ad5f50507ad 100644
--- a/engines/tetraedge/game/lua_binds.cpp
+++ b/engines/tetraedge/game/lua_binds.cpp
@@ -27,6 +27,7 @@
#include "tetraedge/game/game.h"
#include "tetraedge/game/lua_binds.h"
#include "tetraedge/game/object3d.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/to_lua.h"
#include "tetraedge/te/te_core.h"
#include "tetraedge/te/te_lua_thread.h"
@@ -131,11 +132,12 @@ static int tolua_ExportedFunctions_PlayMovieAndWaitForEnd00(lua_State *L) {
Common::String s2(tolua_tostring(L, 2, nullptr));
PlayMovie(s1, s2);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnMovieFinished";
callback._luaParam = s1;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
warning("PlayMovieAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -147,7 +149,8 @@ static int tolua_ExportedFunctions_PlayMovieAndWaitForEnd00(lua_State *L) {
}
static void AddRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2){
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->addRandomSound(s1, s2, f1, f2);
}
@@ -219,7 +222,8 @@ static int tolua_ExportedFunctions_TakeObject00(lua_State *L) {
}
static void TakeObjectInHand(const Common::String &obj) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
// TODO: Set global _lastHitObjectName?? How is it used?
//game->luaContext().setGlobal(_lastHitObjectName, true);
if (!obj.empty())
@@ -391,7 +395,8 @@ static int tolua_ExportedFunctions_AddUnrecalAnim00(lua_State *L) {
}
static void UnlockArtwork(const Common::String &name) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->addArtworkUnlocked(name, true);
Application *app = g_engine->getApplication();
app->saveOptions("options.xml");
@@ -442,7 +447,8 @@ static int tolua_ExportedFunctions_SetCharacterPlayerVisible00(lua_State *L) {
}
static void MoveCharacterPlayerDisabled(bool val) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->_movePlayerCharacterDisabled = val;
}
@@ -714,11 +720,12 @@ int tolua_ExportedFunctions_StartAnimationAndWaitForEnd00(lua_State *L) {
bool b1 = tolua_toboolean(L, 3, false);
StartAnimation(s1, d1, b1);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnFinishedAnim";
callback._luaParam = s1;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
warning("StartAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -732,7 +739,8 @@ int tolua_ExportedFunctions_StartAnimationAndWaitForEnd00(lua_State *L) {
}
static void RequestAutoSave() {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->setSaveRequested();
}
@@ -985,12 +993,13 @@ static int tolua_ExportedFunctions_SetCharacterAnimationAndWaitForEnd00(lua_Stat
double f4 = tolua_tonumber(L, 6, 9999.0);
SetCharacterAnimation(s1, s2, b1, b2, (int)f3, (int)f4);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnCharacterAnimationFinished";
callback._luaParam = s1;
callback._luaParam2 = s2;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1 && cb._luaParam2 == s2)
warning("SetCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -1039,12 +1048,13 @@ static int tolua_ExportedFunctions_BlendCharacterAnimationAndWaitForEnd00(lua_St
bool b2 = tolua_toboolean(L, 5, false);
BlendCharacterAnimation(s1, s2, f1, b1, b2);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnCharacterAnimationFinished";
callback._luaParam = s1;
callback._luaParam2 = s2;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1 && cb._luaParam2 == s2)
warning("BlendCharacterAnimationAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -1341,7 +1351,8 @@ static int tolua_ExportedFunctions_HideBillboard00(lua_State *L) {
}
static void UnlockAchievement(int val) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->addToScore(val);
}
@@ -1394,10 +1405,11 @@ static int tolua_ExportedFunctions_WaitAndWaitForEnd00(lua_State *L) {
double d = tolua_tonumber(L, 1, 0.0);
Wait(d);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnWaitFinished";
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName)
warning("WaitAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -1488,11 +1500,12 @@ static int tolua_ExportedFunctions_LaunchDialogAndWaitForEnd00(lua_State *L) {
float f2 = tolua_tonumber(L, 5, 0.0);
LaunchDialog(s1, f1, s2, s3, f2);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnDialogFinished";
callback._luaParam = s1;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == callback._luaParam)
warning("LaunchDialogAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -1539,7 +1552,8 @@ static int tolua_ExportedFunctions_HideAnswers00(lua_State *L) {
}
static void PushTask(const Common::String &s1, const Common::String &s2) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->objectif().pushObjectif(s1, s2);
}
@@ -1555,7 +1569,8 @@ static int tolua_ExportedFunctions_PushTask00(lua_State *L) {
}
static void DeleteTask(const Common::String &s1, const Common::String &s2) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->objectif().deleteObjectif(s1, s2);
}
@@ -1574,7 +1589,8 @@ static int tolua_ExportedFunctions_DeleteTask00(lua_State *L) {
}
static void SetVisibleButtonHelp(bool val) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->objectif().setVisibleButtonHelp(val);
}
@@ -1609,7 +1625,8 @@ static int tolua_ExportedFunctions_TestFileFlagSystemFlag00(lua_State *L) {
}
static void ExitZone(const Common::String &zone) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->setExitZone(zone);
}
@@ -1915,11 +1932,12 @@ static int tolua_ExportedFunctions_PlaySoundAndWaitForEnd00(lua_State *L) {
double d2 = tolua_tonumber(L, 3, 1.0);
PlaySound(s1, d1, d2);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnFreeSoundFinished";
callback._luaParam = s1;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName && cb._luaParam == s1)
warning("PlaySoundAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -1946,7 +1964,8 @@ static int tolua_ExportedFunctions_StopSound00(lua_State *L) {
}
static void PlayRandomSound(const Common::String &name) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->playRandomSound(name);
}
@@ -2132,7 +2151,8 @@ static int tolua_ExportedFunctions_CurrentCharacterAnimation00(lua_State *L) {
}
static void LoadCharacter(const Common::String &name) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->loadCharacter(name);
}
@@ -2147,7 +2167,8 @@ static int tolua_ExportedFunctions_LoadCharacter00(lua_State *L) {
}
static void UnloadCharacter(const Common::String &name) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->unloadCharacter(name);
}
@@ -2192,10 +2213,11 @@ static int tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00(lua_State *L)
float f2 = tolua_tonumber(L, 4, 0.0);
MoveCharacterTo(s1, s2, f1, f2);
- Game::YieldedCallback callback;
+ SyberiaGame::YieldedCallback callback;
callback._luaThread = TeLuaThread::threadFromState(L);
callback._luaFnName = "OnDisplacementFinished";
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
for (const auto &cb : game->yieldedCallbacks()) {
if (cb._luaFnName == callback._luaFnName)
warning("MoveCharacterToAndWaitForEnd: Reentrency error, your are already in a yielded/sync function call");
@@ -2207,7 +2229,8 @@ static int tolua_ExportedFunctions_MoveCharacterToAndWaitForEnd00(lua_State *L)
}
static void MoveCharacterPlayerTo(float x, float y, float z, bool walkFlag) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
if (game->_movePlayerCharacterDisabled)
return;
@@ -2263,7 +2286,8 @@ static int tolua_ExportedFunctions_MoveCharacterPlayerTo00(lua_State *L) {
}
static void EnableRunMode(bool val) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
game->setRunModeEnabled(val);
}
@@ -2278,7 +2302,8 @@ static int tolua_ExportedFunctions_EnableRunMode00(lua_State *L) {
}
static void SetModelPlayer(const Common::String &name) {
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
Character *character = game->scene()._character;
if (!character) {
diff --git a/engines/tetraedge/game/syberia_game.cpp b/engines/tetraedge/game/syberia_game.cpp
new file mode 100644
index 00000000000..f96c542cf18
--- /dev/null
+++ b/engines/tetraedge/game/syberia_game.cpp
@@ -0,0 +1,1458 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/file.h"
+#include "common/path.h"
+#include "common/str-array.h"
+#include "common/system.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "tetraedge/game/syberia_game.h"
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/character.h"
+#include "tetraedge/game/in_game_scene.h"
+#include "tetraedge/game/game_achievements.h"
+#include "tetraedge/game/lua_binds.h"
+#include "tetraedge/game/object3d.h"
+
+#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_core.h"
+#include "tetraedge/te/te_input_mgr.h"
+#include "tetraedge/te/te_ray_intersection.h"
+#include "tetraedge/te/te_sound_manager.h"
+#include "tetraedge/te/te_variant.h"
+#include "tetraedge/te/te_lua_thread.h"
+
+namespace Tetraedge {
+
+SyberiaGame::SyberiaGame() : Game(),
+_enteredFlag2(false), _movePlayerCharacterDisabled(false),
+_noScaleLayout(nullptr), _isCharacterIdle(true),
+_sceneCharacterVisibleFromLoad(false), _isCharacterWalking(false),
+_lastCharMoveMousePos(0.0f, 0.0f), _randomSoundFinished(false),
+_previousMousePos(-1, -1), _markersVisible(true), _saveRequested(false),
+_gameLoadState(0), _score(0), _warped(false), _frameCounter(0),
+_warpFadeFlag(false), _runModeEnabled(true) {
+ _randomSound = new RandomSound();
+}
+
+SyberiaGame::~SyberiaGame() {
+ if (_entered) {
+ leave(true);
+ }
+ delete _randomSound;
+}
+
+bool SyberiaGame::addAnimToSet(const Common::String &anim) {
+ // Get path to lua script, eg scenes/ValVoralberg/14040/Set14040.lua
+ const Common::Path animPath(Common::String("scenes/") + anim + "/");
+
+ if (Common::File::exists(animPath)) {
+ const Common::StringArray parts = TetraedgeEngine::splitString(anim, '/');
+ assert(parts.size() >= 2);
+
+ const Common::String layoutName = parts[1];
+ const Common::String path = Common::String("scenes/") + parts[0] + "/" + parts[1] + "/Set" + parts[1];
+
+ _setAnimGui.load(path + ".lua");
+
+ // Note: game makes this here, but never uses it..
+ // it seems like a random memory leak??
+ // TeSpriteLayout *spritelayout = new TeSpriteLayout();
+
+ TeSpriteLayout *spritelayout = findSpriteLayoutByName(_setAnimGui.layoutChecked("root"), layoutName);
+
+ _scene.bgGui().layoutChecked("root")->addChild(spritelayout);
+ return true;
+ }
+
+ return false;
+}
+
+/*static*/
+Common::String SyberiaGame::artworkConfName(const Common::String &name) {
+ Common::String configName = Common::String::format("artwork_%s", name.c_str());
+ for (uint i = 0; i < configName.size(); i++) {
+ if (configName[i] == '/' || configName[i] == '.')
+ configName.setChar('_', i);
+ }
+ return configName;
+}
+
+void SyberiaGame::addArtworkUnlocked(const Common::String &name, bool notify) {
+ const Common::String configName = artworkConfName(name);
+ if (_unlockedArtwork.contains(configName))
+ return;
+ ConfMan.setBool(configName, true);
+ ConfMan.flushToDisk();
+ _unlockedArtwork[configName] = true;
+ if (notify)
+ _notifier.push("BONUS!", "Inventory/Objects/VPapierCrayon.png");
+}
+
+bool SyberiaGame::isArtworkUnlocked(const Common::String &name) const {
+ const Common::String configName = artworkConfName(name);
+ return _unlockedArtwork.getValOrDefault(configName, false);
+}
+
+void SyberiaGame::addNoScale2Children() {
+ if (!_noScaleLayout2)
+ return;
+
+ TeLayout *vidbtn = _inGameGui.layout("videoButtonLayout");
+ if (vidbtn)
+ _noScaleLayout2->addChild(vidbtn);
+
+ TeLayout *bg = _inventory.cellphone()->gui().layout("background");
+ if (bg)
+ _noScaleLayout2->addChild(bg);
+
+ TeButtonLayout *bgbtn = _objectif.gui1().buttonLayout("background");
+ if (bgbtn)
+ _noScaleLayout2->addChild(bgbtn);
+}
+
+void SyberiaGame::addNoScaleChildren() {
+ if (!_noScaleLayout)
+ return;
+ TeLayout *inGame = _inGameGui.layout("inGame");
+ if (inGame)
+ _noScaleLayout->addChild(inGame);
+
+ _noScaleLayout->addChild(&_question2);
+
+ Application *app = g_engine->getApplication();
+ app->frontLayout().addChild(&_dialog2);
+
+ _noScaleLayout->addChild(&_inventory);
+ _noScaleLayout->addChild(&_inventoryMenu);
+ _noScaleLayout->addChild(&_documentsBrowser);
+ _noScaleLayout->addChild(&_documentsBrowser.zoomedLayout());
+}
+
+void SyberiaGame::addRandomSound(const Common::String &name, const Common::String &path, float f1, float volume) {
+ if (!_randomSounds.contains(name)) {
+ _randomSounds[name] = Common::Array<RandomSound*>();
+ }
+ RandomSound *randsound = new RandomSound();
+ randsound->_path = path;
+ randsound->_f1 = f1;
+ randsound->_volume = volume;
+ randsound->_name = name;
+ _randomSounds[name].push_back(randsound);
+}
+
+void SyberiaGame::addToBag(const Common::String &objid) {
+ if (_inventory.objectCount(objid) != 0)
+ return;
+ _inventory.addObject(objid);
+ Common::String imgpath("Inventory/Objects/");
+ imgpath += objid;
+ imgpath += ".png";
+ _notifier.push(_inventory.objectName(objid), imgpath);
+ for (int i = 0; i < NUM_OBJECTS_TAKEN_IDS; i++) {
+ if (objid == OBJECTS_TAKEN_IDS[i] && !_objectsTakenBits[i]) {
+ _objectsTakenBits[i] = true;
+ _objectsTakenVal++;
+ }
+ }
+
+ _score += 10;
+ debug("Updated score: %d", _score);
+}
+
+void SyberiaGame::addToHand(const Common::String &objname) {
+ _inventory.addObject(objname);
+ _inventory.selectedObject(objname);
+}
+
+void SyberiaGame::addToScore(int score) {
+ _score += score;
+}
+
+bool SyberiaGame::changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ //debug("Game::changeWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
+ Application *app = g_engine->getApplication();
+ if (fadeFlag && g_engine->gameType() == TetraedgeEngine::kSyberia) {
+ app->blackFade();
+ } else {
+ app->captureFade();
+ }
+ // Slight divergence from original.. free after capturing fade so characters don't disappear.
+ if (g_engine->gameType() == TetraedgeEngine::kSyberia2)
+ _scene.freeGeometry();
+
+ _warpZone = zone;
+ _warpScene = scene;
+ _warpFadeFlag = fadeFlag;
+ _warped = true;
+ return true;
+}
+
+bool SyberiaGame::changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ //debug("Game::changeWarp2(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
+ _warped = false;
+ _movePlayerCharacterDisabled = false;
+ _sceneCharacterVisibleFromLoad = false;
+ // TODO? _charMoveMouseEventNo = -1?
+ _isCharacterIdle = true;
+ _isCharacterWalking = false;
+ Common::Path luapath("scenes");
+ luapath.joinInPlace(zone);
+ luapath.joinInPlace(scene);
+ luapath.joinInPlace("Logic");
+ luapath.appendInPlace(scene);
+ luapath.appendInPlace(".lua");
+
+ if (g_engine->getCore()->findFile(luapath).exists()) {
+ _luaScript.execute("OnLeave");
+ _luaContext.removeGlobal("On");
+ _luaContext.removeGlobal("OnEnter");
+ _luaContext.removeGlobal("OnWarpObjectHit");
+ _luaContext.removeGlobal("OnButtonDown");
+ _luaContext.removeGlobal("OnButtonUp");
+ _luaContext.removeGlobal("OnFinishedAnim");
+ _luaContext.removeGlobal("OnCharacterAnimationFinished");
+ _luaContext.removeGlobal("OnCharacterAnimationPlayerFinished");
+ _luaContext.removeGlobal("OnDisplacementFinished");
+ _luaContext.removeGlobal("OnFreeSoundFinished");
+ _luaContext.removeGlobal("OnDocumentClosed");
+ _luaContext.removeGlobal("OnSelectedObject");
+ _luaContext.removeGlobal("OnDialogFinished");
+ _luaContext.removeGlobal("OnAnswered");
+ _luaContext.removeGlobal("OnLeave");
+ _luaScript.unload();
+ }
+
+ _forGui.unload();
+ _prevSceneName = _currentScene;
+ if (!fadeFlag)
+ g_engine->getApplication()->fade();
+
+ return initWarp(zone, scene, false);
+}
+
+void SyberiaGame::deleteNoScale() {
+ if (_noScaleLayout) {
+ removeNoScaleChildren();
+ delete _noScaleLayout;
+ _noScaleLayout = nullptr;
+ }
+ if (_noScaleLayout2) {
+ removeNoScale2Children();
+ delete _noScaleLayout2;
+ _noScaleLayout2 = nullptr;
+ }
+}
+
+void SyberiaGame::draw() {
+ if (_running) {
+ _frameCounter++;
+ _scene.draw();
+ }
+}
+
+void SyberiaGame::enter() {
+ _enteredFlag2 = true;
+ _entered = true;
+ _luaShowOwnerError = false;
+ _score = 0;
+ Application *app = g_engine->getApplication();
+ app->visualFade().init();
+ // TODO: Original puts this click handler at -10000.. but then it never gets hit?
+ Common::SharedPtr<TeCallback1Param<SyberiaGame, const Common::Point &>> callbackptr(new TeCallback1Param<SyberiaGame, const Common::Point &>(this, &SyberiaGame::onMouseClick, 10000.0f));
+ g_engine->getInputMgr()->_mouseLUpSignal.push_back(callbackptr);
+ _movePlayerCharacterDisabled = false;
+ // TODO? Set _charMoveMouseEventNo = -1
+ _isCharacterIdle = true;
+ _sceneCharacterVisibleFromLoad = false;
+ Character::loadSettings("models/ModelsSettings.xml");
+ Object3D::loadSettings("objects/ObjectsSettings.xml");
+ if (_scene._character) {
+ _scene._character->onFinished().remove(this, &SyberiaGame::onDisplacementPlayerFinished);
+ _scene.unloadCharacter(_scene._character->_model->name());
+ }
+ bool loaded = loadPlayerCharacter("Kate");
+ if (!loaded)
+ error("[Game::enter] Can't load player character");
+
+ _scene._character->_model->setVisible(true);
+ _running = true;
+ _luaContext.create();
+ GameAchievements::registerAchievements(_luaContext);
+
+ _luaContext.setGlobal("BUTTON_VALID", 1);
+ _luaContext.setGlobal("BUTTON_CANCEL", 2);
+ _luaContext.setGlobal("BUTTON_EXTRA1", 4);
+ _luaContext.setGlobal("BUTTON_EXTRA2", 8);
+ _luaContext.setGlobal("BUTTON_L1", 0x10);
+ _luaContext.setGlobal("BUTTON_R1", 0x20);
+ _luaContext.setGlobal("BUTTON_START", 0x40);
+ _luaContext.setGlobal("BUTTON_UP", 0x80);
+ _luaContext.setGlobal("BUTTON_DOWN", 0x100);
+ _luaContext.setGlobal("BUTTON_LEFT", 0x200);
+ _luaContext.setGlobal("BUTTON_RIGHT", 0x400);
+ _luaContext.setGlobal("BUTTON_LS_CLIC", 0x800);
+ _luaContext.setGlobal("BUTTON_RS_CLIC", 0x1000);
+ _luaContext.setGlobal("BUTTON_BACK", 0x2000);
+ _luaContext.setGlobal("BUTTON_SELECT", 0x4000);
+ _luaContext.setGlobal("BUTTON_L2", 0x8000);
+ _luaContext.setGlobal("BUTTON_R2", 0x10000);
+ _luaContext.setGlobal("BUTTON_LS_UP", 0x20000);
+ _luaContext.setGlobal("BUTTON_LS_DOWN", 0x40000);
+ _luaContext.setGlobal("BUTTON_LS_LEFT", 0x80000);
+ _luaContext.setGlobal("BUTTON_LS_RIGHT", 0x100000);
+ _luaContext.setGlobal("BUTTON_RS_UP", 0x200000);
+ _luaContext.setGlobal("BUTTON_RS_DOWN", 0x400000);
+ _luaContext.setGlobal("BUTTON_RS_LEFT", 0x800000);
+ _luaContext.setGlobal("BUTTON_RS_RIGHT", 0x1000000);
+
+ _gameEnterScript.attachToContext(&_luaContext);
+
+ if (!_objectif.gui1().loaded()) {
+ _objectif.load();
+ }
+ _question2.load();
+ _dialog2.load();
+ _documentsBrowser.load();
+ _documentsBrowser.loadZoomed();
+ _inventory.load();
+
+ _inventory.cellphone()->onCallNumber().add(this, &SyberiaGame::onCallNumber);
+
+ if (hasLoadName()) {
+ loadBackup(_loadName);
+ } else {
+ _gameLoadState = 1;
+ onFinishedLoadingBackup("");
+ }
+ _sceneCharacterVisibleFromLoad = true;
+ _scene._character->onFinished().remove(this, &SyberiaGame::onDisplacementPlayerFinished);
+ _scene._character->onFinished().add(this, &SyberiaGame::onDisplacementPlayerFinished);
+ _prevSceneName.clear();
+ _notifier.load();
+}
+
+void SyberiaGame::finishFreemium() {
+ Application *app = g_engine->getApplication();
+ app->setFinishedGame(true);
+ app->setFinishedFremium(true);
+}
+
+void SyberiaGame::finishGame() {
+ Application *app = g_engine->getApplication();
+ // FIXME: The original sets this, but then Application::run immediately
+ // returns to the menu.. how does the original wait for the credits to end??
+ //app->_finishedGame = true;
+ _playedTimer.stop();
+ /* Game does this but does nothing with result?
+ if (app->difficulty() == 2) {
+ _playedTimer.getTimeFromStart();
+ } */
+ app->credits().enter(false);
+}
+
+void SyberiaGame::initLoadedBackupData() {
+ bool warpFlag = true;
+ Application *app = g_engine->getApplication();
+ Common::String firstWarpPath;
+ if (!_loadName.empty()) {
+ warpFlag = false;
+ Common::InSaveFile *saveFile = g_engine->getSaveFileManager()->openForLoading(_loadName);
+ Common::Error result = g_engine->loadGameStream(saveFile);
+ if (result.getCode() == Common::kNoError) {
+ ExtendedSavegameHeader header;
+ if (MetaEngine::readSavegameHeader(saveFile, &header))
+ g_engine->setTotalPlayTime(header.playtime);
+ }
+ } else {
+ firstWarpPath = app->firstWarpPath();
+ _currentScene = app->firstScene();
+ _currentZone = app->firstZone();
+ _playedTimer.start();
+ _objectsTakenVal = 0;
+ for (int i = 0; i < ARRAYSIZE(_objectsTakenBits); i++) {
+ _objectsTakenBits[i] = 0;
+ }
+ _dialogsTold = 0;
+ if (_loadName == "NO_OWNER")
+ _luaShowOwnerError = true;
+ }
+ _gameLoadState = 0;
+ app->showLoadingIcon(false);
+ _loadName.clear();
+ initScene(warpFlag, firstWarpPath);
+}
+
+void SyberiaGame::initNoScale() {
+ if (!_noScaleLayout) {
+ _noScaleLayout = new TeLayout();
+ _noScaleLayout->setName("noScaleLayout");
+ _noScaleLayout->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+ _noScaleLayout->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ }
+
+ if (!_noScaleLayout2) {
+ _noScaleLayout2 = new TeLayout();
+ _noScaleLayout2->setName("noScaleLayout2");
+ _noScaleLayout2->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+ _noScaleLayout2->setSize(TeVector3f32(1.0f, 1.0f, 0.0f));
+ }
+}
+
+void SyberiaGame::initScene(bool fade, const Common::String &scenePath) {
+ _luaContext.setGlobal("SHOW_OWNER_ERROR", _luaShowOwnerError);
+ initWarp(_currentZone, _currentScene, fade);
+ loadScene(scenePath);
+ if (_scene._character->_model.get() && !_scene.findKate()) {
+ _scene.models().push_back(_scene._character->_model);
+ }
+ _scene._character->_model->setVisible(true);
+}
+
+bool SyberiaGame::initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ debug("Game::initWarp(%s, %s, %s)", zone.c_str(), scene.c_str(), fadeFlag ? "true" : "false");
+ _inventoryMenu.unload();
+ _inGameGui.unload();
+ _movePlayerCharacterDisabled = false;
+ _sceneCharacterVisibleFromLoad = true;
+
+ if (_scene._character) {
+ _scene._character->_model->setVisible(true);
+ _scene._character->deleteAllCallback();
+ _scene._character->stop();
+ _scene._character->setAnimation(_scene._character->characterSettings()._idleAnimFileName, true);
+ if (!_scene.findKate()) {
+ _scene.models().push_back(_scene._character->_model);
+ if (_scene._character->_shadowModel[0]) {
+ _scene.models().push_back(_scene._character->_shadowModel[0]);
+ _scene.models().push_back(_scene._character->_shadowModel[1]);
+ }
+ }
+ }
+
+ _currentZone = zone;
+ _currentScene = scene;
+
+ _scene.loadBlockers();
+ Common::Path scenePath("scenes");
+ scenePath.joinInPlace(zone);
+ scenePath.joinInPlace(scene);
+ _sceneZonePath = scenePath;
+
+ TeCore *core = g_engine->getCore();
+
+ const Common::FSNode intLuaNode = core->findFile(scenePath.join(Common::String::format("Int%s.lua", scene.c_str())));
+ const Common::FSNode logicLuaNode = core->findFile(scenePath.join(Common::String::format("Logic%s.lua", scene.c_str())));
+ const Common::FSNode setLuaNode = core->findFile(scenePath.join(Common::String::format("Set%s.lua", scene.c_str())));
+ Common::FSNode forLuaNode = core->findFile(scenePath.join(Common::String::format("For%s.lua", scene.c_str())));
+ const Common::FSNode markerLuaNode = core->findFile(scenePath.join(Common::String::format("Marker%s.lua", scene.c_str())));
+
+ bool intLuaExists = intLuaNode.exists();
+ bool logicLuaExists = logicLuaNode.exists();
+ bool setLuaExists = setLuaNode.exists();
+ bool forLuaExists = forLuaNode.exists();
+ if (!forLuaExists) {
+ // slight hack.. try an alternate For lua path.
+ forLuaNode = core->findFile(scenePath.join("Android-MacOSX").join(Common::String::format("For%s.lua", scene.c_str())));
+ forLuaExists = forLuaNode.exists();
+ debug("searched for %s", forLuaNode.getName().c_str());
+ }
+ bool markerLuaExists = markerLuaNode.exists();
+
+ if (!intLuaExists && !logicLuaExists && !setLuaExists && !forLuaExists && !markerLuaExists) {
+ debug("No lua scripts for scene %s zone %s", scene.c_str(), zone.c_str());
+ return false;
+ }
+
+ for (auto &sound : _gameSounds) {
+ sound->setRetain(false);
+ }
+
+ if (logicLuaExists) {
+ _luaContext.addBindings(LuaBinds::LuaOpenBinds);
+ _luaScript.attachToContext(&_luaContext);
+ _luaScript.load(core->findFile("menus/help/help.lua"));
+ _luaScript.execute();
+ _luaScript.load(logicLuaNode);
+ }
+
+ if (_forGui.loaded())
+ _forGui.unload();
+
+ _scene.reset();
+ _scene.bgGui().unload();
+ _scene.markerGui().unload();
+ _scene.hitObjectGui().unload();
+ Common::Path geomPath(Common::String::format("scenes/%s/Geometry%s.bin",
+ zone.c_str(), zone.c_str()));
+ Common::FSNode geomFile = core->findFile(geomPath);
+ if (geomFile.isReadable()) {
+ // Syberia 1, load geom bin
+ _scene.load(geomFile);
+ } else {
+ // Syberia 2, load from xml
+ _scene.loadXml(zone, scene);
+ }
+ _scene.loadBackground(setLuaNode);
+
+ Application *app = g_engine->getApplication();
+ if (forLuaExists) {
+ _forGui.load(forLuaNode);
+ TeLayout *bg = _forGui.layoutChecked("background");
+ bg->setRatioMode(TeILayout::RATIO_MODE_NONE);
+ app->frontLayout().addChild(bg);
+ // Note: Game also adds cellphone to both frontLayout *and* noScaleLayout2,
+ // so we reproduce the broken behavior exactly.
+ TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayoutChecked("background");
+ app->frontLayout().removeChild(cellbg);
+ app->frontLayout().addChild(cellbg);
+ _objectif.reattachLayout(&app->frontLayout());
+ }
+
+ if (intLuaExists) {
+ _scene.loadInteractions(intLuaNode);
+ TeLuaGUI::StringMap<TeButtonLayout *> &blayouts = _scene.hitObjectGui().buttonLayouts();
+ for (auto &entry : blayouts) {
+ HitObject *hobj = new HitObject();
+ TeButtonLayout *btn = entry._value;
+ hobj->_game = this;
+ hobj->_button = btn;
+ hobj->_name = btn->name();
+ btn->onMouseClickValidated().add(hobj, &HitObject::onValidated);
+ btn->onButtonChangedToStateDownSignal().add(hobj, &HitObject::onDown);
+ btn->onButtonChangedToStateUpSignal().add(hobj, &HitObject::onUp);
+ _gameHitObjects.push_back(hobj);
+ }
+ }
+
+ _inventoryMenu.load();
+ _inGameGui.load("InGame.lua");
+
+ TeButtonLayout *skipbtn = _inGameGui.buttonLayoutChecked("skipVideoButton");
+ skipbtn->setVisible(false);
+ skipbtn->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
+ skipbtn->onMouseClickValidated().add(this, &Game::onSkipVideoButtonValidated);
+
+ TeButtonLayout *vidbgbtn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
+ vidbgbtn->setVisible(false);
+ vidbgbtn->onMouseClickValidated().remove(this, &SyberiaGame::onLockVideoButtonValidated);
+ vidbgbtn->onMouseClickValidated().add(this, &SyberiaGame::onLockVideoButtonValidated);
+
+ TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
+ video->setVisible(false);
+ video->_tiledSurfacePtr->_frameAnim.onStop().remove(this, &Game::onVideoFinished);
+ video->_tiledSurfacePtr->_frameAnim.onStop().add(this, &Game::onVideoFinished);
+
+ TeButtonLayout *invbtn = _inGameGui.buttonLayoutChecked("inventoryButton");
+ invbtn->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
+ invbtn->onMouseClickValidated().add(this, &Game::onInventoryButtonValidated);
+ invbtn->setSizeType(TeILayout::RELATIVE_TO_PARENT);
+
+ const TeVector3f32 winSize = app->getMainWindow().size();
+ if (g_engine->getCore()->fileFlagSystemFlag("definition") == "SD") {
+ invbtn->setSize(TeVector3f32(0.12f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.12f, 0.0));
+ } else {
+ invbtn->setSize(TeVector3f32(0.08f, (4.0f / ((winSize.y() / winSize.x()) * 4.0f)) * 0.08f, 0.0));
+ }
+
+ TeCheckboxLayout *markersCheckbox = _inGameGui.checkboxLayout("markersVisibleButton");
+ markersCheckbox->setState(_markersVisible ? TeCheckboxLayout::CheckboxStateActive : TeCheckboxLayout::CheckboxStateUnactive);
+ markersCheckbox->onStateChangedSignal().add(this, &SyberiaGame::onMarkersVisible);
+
+ initNoScale();
+ removeNoScale2Children();
+ app->frontLayout().removeChild(_noScaleLayout2);
+
+ TeLayout *vidLayout = _inGameGui.layout("videoLayout");
+ app->frontLayout().removeChild(vidLayout);
+ removeNoScaleChildren();
+ app->frontLayout().removeChild(_noScaleLayout);
+
+ app->frontLayout().addChild(_noScaleLayout);
+ addNoScaleChildren();
+ app->frontLayout().addChild(vidLayout);
+ app->frontLayout().addChild(_noScaleLayout2);
+ addNoScale2Children();
+ if (!fadeFlag) {
+ if (_inventory.selectedObject().size()) {
+ _inventory.selectedObject(_inventory.selectedInventoryObject());
+ }
+ _inventory.setVisible(false);
+ _objectif.setVisibleObjectif(false);
+ _objectif.setVisibleButtonHelp(true);
+ _running = true;
+ loadScene("save.xml");
+ }
+
+ app->backLayout().addChild(_scene.background());
+
+ if (markerLuaExists) {
+ TeLayout *bg = _scene.markerGui().layout("background");
+ app->frontLayout().addChild(bg);
+ }
+
+ Common::String camname = Common::String("Camera") + scene;
+ _scene.setCurrentCamera(camname);
+
+ // Special hacks for certain scenes (don't blame me, original does this..)
+ if (g_engine->gameType() == TetraedgeEngine::kSyberia) {
+ if (scene == "14050") {
+ TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
+ const TeVector3f32 coords(1200.6f, -1937.5f, 1544.1f);
+ curcamera->setPosition(coords);
+ } else if (scene == "34610") {
+ TeIntrusivePtr<TeCamera> curcamera = _scene.currentCamera();
+ const TeVector3f32 coords(-328.243f, 340.303f, -1342.84f);
+ curcamera->setPosition(coords);
+ const TeQuaternion rot(0.003194f, 0.910923f, -0.009496f, -0.412389f);
+ curcamera->setRotation(rot);
+ }
+
+ //
+ // WORKAROUND: Fix the camera in the restored scenes
+ //
+ if (zone == "ValStreet" && scene == "11100") {
+ TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
+ cam->setProjMatrixType(3);
+ cam->setFov(0.5f);
+ } else if (zone == "ValField" && scene == "11170") {
+ TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
+ cam->setProjMatrixType(3);
+ // TODO: Is camera position right? Kate not visible..
+ // default values:
+ // -494.447998 -79.2976989 1408.5
+ // scene entrance and exit
+ // -184, -143, 1563
+ // -42, -147, 1534
+ } else if (zone == "BarRiverSide" && scene == "24020") {
+ TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
+ cam->setProjMatrixType(3);
+ cam->setFov(0.5f);
+ }
+ }
+
+ if (logicLuaExists) {
+ _exitZone.clear();
+ _luaScript.execute();
+ _luaScript.execute("OnEnter", _prevSceneName);
+ _luaScript.execute("OnSelectedObject", _inventory.selectedObject());
+ }
+
+ for (uint i = 0; i < _gameSounds.size(); i++) {
+ if (_gameSounds[i]->retain())
+ continue;
+ _gameSounds[i]->stop();
+ _gameSounds[i]->deleteLater();
+ _gameSounds.remove_at(i);
+ i--;
+ }
+
+ // Take a copy and clear the global list first, as deleting a sound can cause the
+ // next sound to trigger (which might have been deleted already).
+ Common::HashMap<Common::String, Common::Array<RandomSound *>> rsounds = _randomSounds;
+ _randomSounds.clear();
+ for (auto &randsoundlist : rsounds) {
+ for (auto *randsound : randsoundlist._value) {
+ delete randsound;
+ }
+ randsoundlist._value.clear();
+ }
+
+ _scene.initScroll();
+ return true;
+}
+
+void SyberiaGame::leave(bool flag) {
+ if (!_enteredFlag2)
+ return;
+
+ Application *app = g_engine->getApplication();
+
+ deleteNoScale();
+ _entered = false;
+ _running = false;
+ _notifier.unload();
+ g_engine->getInputMgr()->_mouseLUpSignal.remove(this, &SyberiaGame::onMouseClick);
+ _question2.unload();
+ TeLayout *cellbg = _inventory.cellphone()->gui().buttonLayout("background");
+ if (cellbg)
+ app->frontLayout().removeChild(cellbg);
+ _inventory.cellphone()->leave();
+ _dialog2.unload();
+ _inventory.unload();
+ _documentsBrowser.unload();
+ _inventoryMenu.unload();
+ _objectif.unload(); // not done in original, but should be.
+ _scene.close();
+ _forGui.unload();
+ if (_scene._character) {
+ _scene._character->deleteAllCallback();
+ _scene._character->stop();
+ _scene.unloadCharacter(_scene._character->_model->name());
+ }
+
+ for (auto &sound : _gameSounds) {
+ delete sound;
+ }
+ _gameSounds.clear();
+
+ for (auto &randsoundlist : _randomSounds) {
+ for (auto *randsound : randsoundlist._value) {
+ delete randsound;
+ }
+ randsoundlist._value.clear();
+ }
+ _randomSounds.clear();
+
+ for (auto *hitobj : _gameHitObjects) {
+ delete hitobj;
+ }
+ _gameHitObjects.clear();
+
+ // TODO: clear SyberiaGame::HitObject tree here?
+
+ _luaContext.destroy();
+ _running = false;
+ _inGameGui.buttonLayoutChecked("skipVideoButton")->onMouseClickValidated().remove(this, &Game::onSkipVideoButtonValidated);
+ _inGameGui.buttonLayoutChecked("videoBackgroundButton")->onMouseClickValidated().remove(this, &Game::onLockVideoButtonValidated);
+ _inGameGui.spriteLayoutChecked("video")->_tiledSurfacePtr->_frameAnim.onFinished().remove(this, &Game::onSkipVideoButtonValidated);
+ _inGameGui.buttonLayoutChecked("inventoryButton")->onMouseClickValidated().remove(this, &Game::onInventoryButtonValidated);
+ _inGameGui.unload();
+ _playedTimer.stop();
+ _enteredFlag2 = false;
+
+ app->lockCursor(false);
+ app->lockCursorFromAction(false);
+ // TODO: Set some inputmgr flag here?
+ Character::animCacheFreeAll();
+}
+
+void SyberiaGame::loadBackup(const Common::String &path) {
+ if (_gameLoadState == 0) {
+ _gameLoadState = 1;
+ g_engine->getApplication()->showLoadingIcon(true);
+ onFinishedLoadingBackup(path);
+ }
+}
+
+void SyberiaGame::loadUnlockedArtwork() {
+ Common::ConfigManager::Domain *domain = ConfMan.getActiveDomain();
+ for (auto &val : *domain) {
+ if (val._key.substr(0, 8) == "artwork_") {
+ _unlockedArtwork[val._key] = true;
+ }
+ }
+}
+
+bool SyberiaGame::loadCharacter(const Common::String &name) {
+ bool result = true;
+ Character *character = _scene.character(name);
+ if (!character) {
+ result = _scene.loadCharacter(name);
+ if (result) {
+ character = _scene.character(name);
+ assert(character);
+ character->_onCharacterAnimFinishedSignal.remove(this, &SyberiaGame::onCharacterAnimationFinished);
+ character->_onCharacterAnimFinishedSignal.add(this, &SyberiaGame::onCharacterAnimationFinished);
+ // Syberia 2 uses a simplified callback here.
+ // We have made onDisplacementPlayerFinished more like Syberia 1's onDisplacementFinished.
+ if (g_engine->gameType() == TetraedgeEngine::kSyberia)
+ character->onFinished().add(this, &SyberiaGame::onDisplacementPlayerFinished);
+ else
+ character->onFinished().add(this, &SyberiaGame::onDisplacementFinished);
+ }
+ }
+ return result;
+}
+
+bool SyberiaGame::loadPlayerCharacter(const Common::String &name) {
+ bool result = _scene.loadPlayerCharacter(name);
+ if (result) {
+ _scene._character->_characterAnimPlayerFinishedSignal.remove(this, &SyberiaGame::onCharacterAnimationPlayerFinished);
+ _scene._character->_characterAnimPlayerFinishedSignal.add(this, &SyberiaGame::onCharacterAnimationPlayerFinished);
+ _scene._character->onFinished().remove(this, &SyberiaGame::onDisplacementPlayerFinished);
+ _scene._character->onFinished().add(this, &SyberiaGame::onDisplacementPlayerFinished);
+ } else {
+ debug("failed to load player character %s", name.c_str());
+ }
+ return result;
+}
+
+bool SyberiaGame::loadScene(const Common::String &name) {
+ TeCore *core = g_engine->getCore();
+ _gameEnterScript.load(core->findFile("scenes/OnGameEnter.lua"));
+ _gameEnterScript.execute();
+ Character *character = _scene._character;
+ if (character && character->_model->visible()) {
+ _sceneCharacterVisibleFromLoad = true;
+ }
+ return false;
+}
+
+bool SyberiaGame::onCallNumber(Common::String val) {
+ _luaScript.execute("OnCallNumber", val);
+ return false;
+}
+
+bool SyberiaGame::onCharacterAnimationFinished(const Common::String &charName) {
+ if (!_scene._character)
+ return false;
+
+ if (g_engine->gameType() == TetraedgeEngine::kSyberia2) {
+ Character *character = scene().character(charName);
+ if (character) {
+ const Common::String curAnimName = character->curAnimName();
+ if (curAnimName == character->walkAnim(Character::WalkPart_EndD)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndG)) {
+ character->updatePosition(1.0);
+ character->endMove();
+ }
+ }
+ }
+
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == charName) {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ if (lua) {
+ lua->resume();
+ return false;
+ }
+ break;
+ }
+ }
+ _luaScript.execute("OnCharacterAnimationFinished", charName);
+ return false;
+}
+
+bool SyberiaGame::onCharacterAnimationPlayerFinished(const Common::String &anim) {
+ if (_gameLoadState != 0)
+ return false;
+
+ bool callScripts = true;
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ // Yes, even Syberia2 checks for Kate here..
+ if (cb._luaFnName == "OnCharacterAnimationFinished" && cb._luaParam == "Kate") {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ if (lua) {
+ lua->resume();
+ callScripts = false;
+ }
+ break;
+ }
+ }
+ if (callScripts) {
+ if (g_engine->gameType() == TetraedgeEngine::kSyberia)
+ _luaScript.execute("OnCharacterAnimationFinished", "Kate");
+ else
+ _luaScript.execute("OnCharacterAnimationPlayerFinished", anim);
+ _luaScript.execute("OnCellCharacterAnimationPlayerFinished", anim);
+ }
+
+ Character *character = scene()._character;
+ assert(character);
+ // Note: the above callbacks can change the anim,
+ // so we have to fetch this *after* them.
+ const Common::String curAnimName = character->curAnimName();
+ if (_currentScene == _someSceneName) {
+ if (curAnimName == character->walkAnim(Character::WalkPart_Start)
+ || curAnimName == character->walkAnim(Character::WalkPart_Loop)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndD)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndG))
+ character->stop();
+ } else {
+ if (!_sceneCharacterVisibleFromLoad && curAnimName == character->walkAnim(Character::WalkPart_Start)) {
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
+ return false;
+ }
+ if (curAnimName == character->walkAnim(Character::WalkPart_EndD)
+ || curAnimName == character->walkAnim(Character::WalkPart_EndG)) {
+ character->updatePosition(1.0);
+ character->endMove();
+ // endMove can result in callbacks that change the animation. check again.
+ if (character->curAnimName() == character->walkAnim(Character::WalkPart_EndD)
+ || character->curAnimName() == character->walkAnim(Character::WalkPart_EndG))
+ character->setAnimation(character->characterSettings()._idleAnimFileName, true);
+ }
+ }
+
+ return false;
+}
+
+bool SyberiaGame::onDialogFinished(const Common::String &val) {
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnDialogFinished" && cb._luaParam == val) {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ if (lua) {
+ lua->resume();
+ return false;
+ }
+ break;
+ }
+ }
+
+ _luaScript.execute("OnDialogFinished", val);
+ _luaScript.execute("OnCellDialogFinished", val);
+ return false;
+}
+
+// This is the Syberia 2 version of this function, not used in Syb 1.
+// Syb 1 uses a function much more like onDisplacementPlayerFinished below.
+bool SyberiaGame::onDisplacementFinished() {
+ TeLuaThread *thread = nullptr;
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnDisplacementFinished") {
+ thread = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ break;
+ }
+ }
+ if (thread) {
+ thread->resume();
+ } else {
+ _luaScript.execute("OnDisplacementFinished");
+ }
+ return false;
+}
+
+bool SyberiaGame::onDisplacementPlayerFinished() {
+ _sceneCharacterVisibleFromLoad = true;
+ assert(_scene._character);
+ _scene._character->stop();
+ _scene._character->walkMode("Walk");
+ _scene._character->setAnimation(_scene._character->characterSettings()._idleAnimFileName, true);
+
+ if (_isCharacterWalking) {
+ _isCharacterWalking = false;
+ _isCharacterIdle = true;
+ } else {
+ _isCharacterIdle = false;
+ }
+
+ TeLuaThread *thread = nullptr;
+
+ const char *cbName = (g_engine->gameType() == TetraedgeEngine::kSyberia ?
+ "OnDisplacementFinished" : "OnDisplacementPlayerFinished");
+
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == cbName) {
+ thread = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ break;
+ }
+ }
+ if (thread) {
+ thread->resume();
+ } else {
+ _luaScript.execute(cbName);
+ }
+ return false;
+}
+
+bool SyberiaGame::onFinishedCheckBackup(bool result) {
+ if (_gameLoadState == 1) {
+ _gameLoadState = 0;
+ return true;
+ }
+ return false;
+}
+
+bool SyberiaGame::onFinishedLoadingBackup(const Common::String &val) {
+ if (_gameLoadState == 1) {
+ _loadName = val;
+ _gameLoadState = 2;
+ return true;
+ }
+ return false;
+}
+
+bool SyberiaGame::onFinishedSavingBackup(int something) {
+ if (something) {
+ g_engine->getGame()->_returnToMainMenu = true;
+ }
+ g_engine->getApplication()->showLoadingIcon(false);
+ return true;
+}
+
+bool SyberiaGame::onMarkersVisible(TeCheckboxLayout::State state) {
+ _markersVisible = (state == TeCheckboxLayout::CheckboxStateActive);
+ showMarkers(state == TeCheckboxLayout::CheckboxStateActive);
+ return false;
+}
+
+bool SyberiaGame::onMouseClick(const Common::Point &pt) {
+ Application *app = g_engine->getApplication();
+
+ if (app->isFading())
+ return true;
+
+ // In case we capture a click during a video or dialog (shouldn't happen?)
+ if (!_scene.currentCamera() || _dialog2.isDialogPlaying() || _question2.isEntered())
+ return false;
+
+ _posPlayer = TeVector3f32(-1.0f, -1.0f, -1.0f);
+ if (_previousMousePos == TeVector2s32(-1, -1)) {
+ _previousMousePos = pt;
+ } else {
+ const TeVector3f32 winSize = app->getMainWindow().size();
+ const TeVector2s32 prevMousePos = _previousMousePos;
+ _previousMousePos = pt;
+ float xdist = (pt.x - prevMousePos._x) / winSize.x();
+ float ydist = (pt.y - prevMousePos._y) / winSize.y();
+ float sqrdist = xdist * xdist + ydist * ydist;
+ if (sqrdist < 0.0001 && (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000.0
+ || (_scene._character && _scene._character->walkModeStr() != "Walk"))) {
+ return false;
+ // Normal walk click
+ }
+ }
+
+ if (!app->frontLayout().isMouseIn(pt))
+ return false;
+
+ Common::String nearestMeshName = "None";
+ TeIntrusivePtr<TeCamera> curCamera = _scene.currentCamera();
+ Common::Array<TePickMesh2*> pickMeshes = _scene.clickMeshes();
+ TePickMesh2 *nearestMesh = TeFreeMoveZone::findNearestMesh(curCamera, pt, pickMeshes, nullptr, false);
+ if (nearestMesh) {
+ nearestMeshName = nearestMesh->name();
+ debug("Game::onMouseClick: Click near mesh %s", nearestMeshName.c_str());
+ _lastCharMoveMousePos = TeVector2s32();
+ }
+
+ Character *character = _scene._character;
+ if (app->isLockCursor() || _movePlayerCharacterDisabled || !character)
+ return false;
+
+ const Common::String &charAnim = character->curAnimName();
+
+ if (charAnim == character->characterSettings()._idleAnimFileName
+ || charAnim == character->walkAnim(Character::WalkPart_Start)
+ || charAnim == character->walkAnim(Character::WalkPart_Loop)
+ || charAnim == character->walkAnim(Character::WalkPart_EndD)
+ || charAnim == character->walkAnim(Character::WalkPart_EndG)) {
+ _luaScript.execute("On");
+ if (!_scene.isObjectBlocking(nearestMeshName) && character->freeMoveZone()) {
+ const TeVector3f32 charPos = character->_model->position();
+ TeIntrusivePtr<TeBezierCurve> curve = character->freeMoveZone()->curve(charPos, pt, 8.0, true);
+ if (!curve)
+ return false;
+
+ _scene.setCurve(curve);
+ character->setCurveStartLocation(TeVector3f32());
+ if (curve->controlPoints().size() == 1) {
+ character->endMove();
+ } else {
+ if (!_walkTimer.running() || _walkTimer.timeElapsed() > 300000 || !_runModeEnabled) {
+ _walkTimer.stop();
+ _walkTimer.start();
+ character->walkMode("Walk");
+ } else {
+ // Note: original checks the timer elapsed again here.. why?
+ _walkTimer.stop();
+ character->walkMode("Jog");
+ }
+ character->placeOnCurve(curve);
+ character->setCurveOffset(0.0);
+ if (charAnim != character->walkAnim(Character::WalkPart_Start)) {
+ character->setAnimation(character->walkAnim(Character::WalkPart_Start), false);
+ }
+ character->walkTo(1.0, false);
+ _sceneCharacterVisibleFromLoad = false;
+ _lastCharMoveMousePos = pt;
+ }
+ }
+ // FIXME: The original never checks for empty/null curve here..
+ // but it seems our curve can possibly become null.
+ if (_scene.curve() && _scene.curve()->length()) {
+ TeVector3f32 lastPoint = _scene.curve()->controlPoints().back();
+ character->setAnimation(character->walkAnim(Character::WalkPart_Loop), true);
+ character->walkTo(1.0, false);
+ _isCharacterWalking = true;
+ _posPlayer = lastPoint;
+ }
+ }
+
+ // Note: charAnim above may no longer be valid as anim may have changed.
+ if (_sceneCharacterVisibleFromLoad || (character->curAnimName() == character->characterSettings()._idleAnimFileName)) {
+ _lastCharMoveMousePos = TeVector2s32();
+ _movePlayerCharacterDisabled = false;
+ _isCharacterIdle = true;
+ _isCharacterWalking = false;
+ if (nearestMesh) {
+ character->stop();
+ _luaScript.execute("OnWarpObjectHit", nearestMeshName);
+ }
+ }
+
+ return false;
+}
+
+bool SyberiaGame::onVideoFinished() {
+ if (!_inGameGui.loaded()) {
+ _music.stop();
+ return false;
+ }
+
+ Application *app = g_engine->getApplication();
+
+ app->captureFade();
+
+ TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
+ Common::String vidPath = video->_tiledSurfacePtr->loadedPath();
+ TeButtonLayout *btn = _inGameGui.buttonLayoutChecked("videoBackgroundButton");
+ btn->setVisible(false);
+ btn = _inGameGui.buttonLayoutChecked("skipVideoButton");
+ btn->setVisible(false);
+ video->setVisible(false);
+ _music.stop();
+ _running = true;
+ bool resumed = false;
+ for (uint i = 0; i < _yieldedCallbacks.size(); i++) {
+ YieldedCallback &cb = _yieldedCallbacks[i];
+ if (cb._luaFnName == "OnMovieFinished" && cb._luaParam == vidPath) {
+ TeLuaThread *lua = cb._luaThread;
+ _yieldedCallbacks.remove_at(i);
+ resumed = true;
+ if (lua)
+ lua->resume();
+ break;
+ }
+ }
+ if (!resumed)
+ _luaScript.execute("OnMovieFinished", vidPath);
+ app->fade();
+ return false;
+}
+
+
+#ifdef TETRAEDGE_ENABLE_CUSTOM_CURSOR_CHECKS
+// Note: None of these cursor files seem to be actually shipped with the game
+// but the logic is reproduced here just in case there's some different
+// version that uses them.
+static const char cursorsTable[][2][80] = {
+ {"H000", "pictures/F000.png"},
+ {"H045", "pictures/F045.png"},
+ {"H090", "pictures/F090.png"},
+ {"H135", "pictures/F135.png"},
+ {"H180", "pictures/F180.png"},
+ {"H225", "pictures/F225.png"},
+ {"H270", "pictures/F270.png"},
+ {"H315", "pictures/F315.png"},
+ {"Main", "pictures/Main.png"},
+ {"Action", "pictures/Action.png"},
+ {"Parler", "pictures/Cursor_Large/Anim_Cursor_Talking.anim"},
+ {"Type01", "pictures/Type01.png"},
+ {"Type02", "pictures/Type02.png"},
+ {"Type03", "pictures/Type03.png"},
+ {"Type04", "pictures/Type04.png"},
+ {"Type05", "pictures/Type05.png"}
+};
+#endif
+
+
+/* Unused
+void SyberiaGame::pauseMovie() {
+ _music.pause();
+ TeSpriteLayout *sprite = _inGameGui.spriteLayoutChecked("video");
+ sprite->pause();
+}
+*/
+
+
+void SyberiaGame::playRandomSound(const Common::String &name) {
+ if (!_randomSounds.contains(name)) {
+ warning("Game::playRandomSound: can't find sound list %s", name.c_str());
+ return;
+ }
+
+ if (!_randomSoundFinished) {
+ _randomSoundTimer.start();
+ int r = g_engine->getRandomNumber(RAND_MAX);
+ float f = (r + 1 + (r / 100) * -100);
+ uint64 time = 1000000;
+ if (f >= 25.0) {
+ time = f * 45000.0;
+ }
+ _randomSoundTimer.setAlarmIn(time);
+ _randomSoundTimer.alarmSignal().remove(_randomSound, &RandomSound::onSoundFinished);
+ _randomSoundTimer.alarmSignal().add(_randomSound, &RandomSound::onSoundFinished);
+ _randomSound->_name = name;
+ } else {
+ Common::Array<RandomSound *> &sndlist = _randomSounds[name];
+ float total = 0.0;
+ for (auto *snd : sndlist) {
+ total += snd->_f1;
+ }
+ int r = g_engine->getRandomNumber(RAND_MAX);
+ float total2 = 0.0;
+ uint i = 0;
+ while (i < sndlist.size() && total2 <= r * 4.656613e-10 * total) {
+ total2 += sndlist[i]->_f1;
+ i++;
+ }
+ assert(i > 0);
+ i--;
+ RandomSound *sound = sndlist[i];
+ sound->_music.volume(sound->_volume);
+ sound->_music.onStopSignal().remove(sound, &RandomSound::onSoundFinished);
+ sound->_music.onStopSignal().add(sound, &RandomSound::onSoundFinished);
+ sound->_music.load(sound->_path.toString());
+ sound->_music.repeat(false);
+ sound->_music.play();
+ // TODO: set a flag that it's playing?
+ }
+}
+
+void SyberiaGame::removeNoScale2Children() {
+ if (!_noScaleLayout2)
+ return;
+
+ TeLayout *vidbtn = _inGameGui.layout("videoButtonLayout");
+ if (vidbtn)
+ _noScaleLayout2->removeChild(vidbtn);
+
+ TeLayout *bg = _inventory.cellphone()->gui().layout("background");
+ if (bg)
+ _noScaleLayout2->removeChild(bg);
+
+ TeButtonLayout *bgbtn = _objectif.gui1().buttonLayout("background");
+ if (bgbtn)
+ _noScaleLayout2->removeChild(bgbtn);
+
+ TeLayout *notifier = _notifier.gui().layout("notifier");
+ if (notifier)
+ _noScaleLayout2->removeChild(notifier);
+}
+
+void SyberiaGame::removeNoScaleChildren() {
+ if (!_noScaleLayout)
+ return;
+ _noScaleLayout->removeChild(&_question2);
+ Application *app = g_engine->getApplication();
+ app->frontLayout().removeChild(&_dialog2);
+ _noScaleLayout->removeChild(&_inventory);
+ _noScaleLayout->removeChild(&_inventoryMenu);
+ _noScaleLayout->removeChild(&_documentsBrowser);
+ _noScaleLayout->removeChild(&_documentsBrowser.zoomedLayout());
+}
+
+void SyberiaGame::resetPreviousMousePos() {
+ _previousMousePos = TeVector2s32(-1, -1);
+}
+
+bool SyberiaGame::unloadCharacter(const Common::String &charname) {
+ Character *c = _scene.character(charname);
+ if (!c)
+ return false;
+
+ for (uint i = 0; i < _scene.models().size(); i++) {
+ if (_scene.models()[i] == c->_model) {
+ _scene.models().remove_at(i);
+ break;
+ }
+ }
+ c->_onCharacterAnimFinishedSignal.remove(this, &SyberiaGame::onCharacterAnimationFinished);
+ c->removeAnim();
+ // Syberia 2 uses a simplified callback here.
+ // We have made onDisplacementPlayerFinished more like Syberia 1's onDisplacementPlayerFinished.
+ if (g_engine->gameType() == TetraedgeEngine::kSyberia)
+ c->onFinished().remove(this, &SyberiaGame::onDisplacementPlayerFinished);
+ else
+ c->onFinished().remove(this, &SyberiaGame::onDisplacementFinished);
+ _scene.unloadCharacter(charname);
+ return true;
+}
+
+bool SyberiaGame::unloadCharacters() {
+ // Loop will update the array, take a copy first.
+ Common::Array<Character *> chars = _scene._characters;
+ for (Character *c : chars) {
+ unloadCharacter(c->_model->name());
+ }
+ return true;
+}
+
+bool SyberiaGame::unloadPlayerCharacter(const Common::String &charname) {
+ Character *c = _scene.character(charname);
+ if (c) {
+ c->_onCharacterAnimFinishedSignal.remove(this, &SyberiaGame::onCharacterAnimationPlayerFinished);
+ c->onFinished().remove(this, &SyberiaGame::onDisplacementPlayerFinished);
+ _scene.unloadCharacter(charname);
+ }
+ return c != nullptr;
+}
+
+void SyberiaGame::update() {
+ if (!_entered)
+ return;
+
+ TeITextLayout *debugTimeTextLayout = _inGameGui.textLayout("debugTimeText1");
+ if (debugTimeTextLayout) {
+ warning("TODO: SyberiaGame::update: Fill out debugTimeTextLayout");
+ }
+
+ if (!_warped) {
+ if (_gameLoadState == 2) {
+ initLoadedBackupData();
+ return;
+ } else if (_gameLoadState != 0) {
+ return;
+ }
+
+ Application *app = g_engine->getApplication();
+
+ if (_scene._character) {
+ if (!_scene._character->_model->visible())
+ app->lockCursor(false);
+ }
+
+ TeButtonLayout *invbtn = _inGameGui.buttonLayout("inventoryButton");
+ if (invbtn)
+ invbtn->setVisible(!app->isLockCursor() && !_dialog2.isDialogPlaying());
+
+ Character *player = _scene._character;
+ if (player) {
+ TeIntrusivePtr<TeModel> model = player->_model;
+ bool modelVisible = model->visible();
+ if (model->anim())
+ player->permanentUpdate();
+ if (modelVisible) {
+ if (player->needsSomeUpdate()) {
+ _sceneCharacterVisibleFromLoad = false;
+ TeVector3f32 charPos = player->_model->position();
+ const Common::String charName = player->_model->name();
+ TeFreeMoveZone *zone = _scene.pathZone(player->freeMoveZoneName());
+ if (zone) {
+ TeIntrusivePtr<TeCamera> cam = _scene.currentCamera();
+ zone->setCamera(cam, false);
+ player->setFreeMoveZone(zone);
+ _scene.setPositionCharacter(charName, player->freeMoveZoneName(), charPos);
+ TeIntrusivePtr<TeBezierCurve> curve = zone->curve(model->position(), player->positionCharacter());
+ _scene.setCurve(curve);
+ player->setCurveStartLocation(TeVector3f32(0, 0, 0));
+ player->placeOnCurve(curve);
+ player->setCurveOffset(0.0f);
+ player->setAnimation(player->walkAnim(Character::WalkPart_Start), false);
+ player->walkTo(1.0f, false);
+ _isCharacterWalking = true;
+ }
+ player->setNeedsSomeUpdate(false);
+ }
+
+ const Common::String &charAnim = _scene._character->curAnimName();
+ bool unlockCursor = (charAnim == _scene._character->walkAnim(Character::WalkPart_Start) ||
+ charAnim == _scene._character->walkAnim(Character::WalkPart_Loop) ||
+ charAnim == _scene._character->walkAnim(Character::WalkPart_EndD) ||
+ charAnim == _scene._character->walkAnim(Character::WalkPart_EndG) ||
+ charAnim == _scene._character->characterSettings()._idleAnimFileName);
+ app->lockCursor(!unlockCursor);
+ }
+ }
+
+ Common::Array<Character *> characters = _scene._characters;
+ for (Character *c : characters) {
+ if (c->_model->anim())
+ c->permanentUpdate();
+ }
+
+ Common::Point mousePos = g_engine->getInputMgr()->lastMousePos();
+ if (_lastUpdateMousePos != mousePos) {
+ onMouseMove();
+ _lastUpdateMousePos = mousePos;
+ }
+ if (_saveRequested) {
+ _saveRequested = false;
+ saveBackup("save.xml");
+ }
+
+ _luaScript.execute("Update");
+ _objectif.update();
+ _scene.update();
+ } else {
+ TeSoundManager *soundmgr = g_engine->getSoundManager();
+ // Take a copy in case the active music objects changes as we iterate.
+ Common::Array<TeMusic *> musics = soundmgr->musics();
+ for (TeMusic *music : musics) {
+ const Common::String &chanName = music->channelName();
+ if (chanName != "music" && chanName != "sfx" && chanName != "dialog")
+ music->stop();
+ }
+ changeWarp2(_warpZone, _warpScene, _warpFadeFlag);
+ }
+}
+
+
+bool SyberiaGame::HitObject::onChangeWarp() {
+ // Seems like this function is never used?
+ error("TODO: Implement SyberiaGame::HitObject::onChangeWarp");
+ return false;
+}
+
+bool SyberiaGame::HitObject::onDown() {
+ _game->luaScript().execute("OnButtonDown", _name);
+ _game->_isCharacterIdle = true;
+ return false;
+}
+
+bool SyberiaGame::HitObject::onUp() {
+ // debug("Game::HitObject mouseup: %s", _name.c_str());
+ _game->luaScript().execute("OnButtonUp", _name);
+ _game->_isCharacterIdle = true;
+ return false;
+}
+
+bool SyberiaGame::HitObject::onValidated() {
+ if (!g_engine->getApplication()->isLockCursor()) {
+ _game->luaScript().execute("OnWarpObjectHit", _name);
+ _game->_isCharacterIdle = true;
+ }
+ return false;
+}
+
+bool SyberiaGame::RandomSound::onSoundFinished() {
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
+ _music.onStopSignal().remove(this, &RandomSound::onSoundFinished);
+ if (game->_randomSoundFinished) {
+ game->_randomSoundFinished = false;
+ } else {
+ game->_randomSoundFinished = true;
+ game->_randomSound->_music.onStopSignal().remove(this, &RandomSound::onSoundFinished);
+ game->_randomSoundTimer.stop();
+ }
+ game->playRandomSound(_name);
+ return false;
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/syberia_game.h b/engines/tetraedge/game/syberia_game.h
new file mode 100644
index 00000000000..8642b0e4dec
--- /dev/null
+++ b/engines/tetraedge/game/syberia_game.h
@@ -0,0 +1,217 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TETRAEDGE_GAME_SYBERIA_GAME_H
+#define TETRAEDGE_GAME_SYBERIA_GAME_H
+
+#include "common/types.h"
+#include "common/serializer.h"
+#include "common/str.h"
+#include "common/random.h"
+
+#include "tetraedge/game/documents_browser.h"
+#include "tetraedge/game/inventory.h"
+#include "tetraedge/game/inventory_menu.h"
+#include "tetraedge/game/in_game_scene.h"
+#include "tetraedge/game/game.h"
+#include "tetraedge/game/notifier.h"
+#include "tetraedge/game/cellphone.h"
+#include "tetraedge/game/game_sound.h"
+#include "tetraedge/game/objectif.h"
+#include "tetraedge/game/question2.h"
+#include "tetraedge/game/dialog2.h"
+#include "tetraedge/te/te_lua_gui.h"
+#include "tetraedge/te/te_music.h"
+#include "tetraedge/te/te_checkbox_layout.h"
+#include "tetraedge/te/te_vector2s32.h"
+
+namespace Tetraedge {
+
+class TeLuaThread;
+
+class SyberiaGame : public Tetraedge::Game {
+public:
+ SyberiaGame();
+ ~SyberiaGame();
+
+ struct HitObject {
+ bool onChangeWarp();
+ bool onDown();
+ bool onUp();
+ bool onValidated();
+ //byte OnVisible(); empty never used?
+
+ Common::String _name;
+ SyberiaGame *_game;
+ TeButtonLayout *_button;
+ };
+
+ class RandomSound {
+ public:
+ Common::Path _path;
+ Common::String _name;
+ TeMusic _music;
+ float _f1;
+ float _volume;
+ bool onSoundFinished();
+ };
+
+ struct YieldedCallback {
+ TeLuaThread *_luaThread;
+ Common::String _luaParam;
+ Common::String _luaParam2;
+ Common::String _luaFnName;
+ // Note: original game long, and int fields.. unused?
+ };
+
+ void addArtworkUnlocked(const Common::String &name, bool notify);
+ void addRandomSound(const Common::String &s1, const Common::String &s2, float f1, float f2);
+ void addToBag(const Common::String &objname) override;
+ void addToHand(const Common::String &objname);
+ void addToScore(int score);
+
+ bool changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) override;
+
+ void draw() override;
+ void enter() override; // will load game if _loadName is set.
+
+ void finishFreemium();
+ void finishGame() override;
+ void initLoadedBackupData() override;
+ void leave(bool flag) override;
+ void loadBackup(const Common::String &path);
+ bool loadCharacter(const Common::String &name);
+ bool loadPlayerCharacter(const Common::String &name);
+ bool loadScene(const Common::String &name);
+
+ // Not in original. Load unlocked artwork from ScummVM config.
+ void loadUnlockedArtwork() override;
+
+ void playRandomSound(const Common::String &name);
+ void resetPreviousMousePos();
+ bool unloadCharacter(const Common::String &character);
+ bool unloadCharacters();
+ bool unloadPlayerCharacter(const Common::String &character);
+ void update() override;
+
+ bool _movePlayerCharacterDisabled;
+ bool _sceneCharacterVisibleFromLoad;
+ bool _isCharacterWalking;
+ bool _isCharacterIdle;
+
+ const Common::Path &sceneZonePath() const { return _sceneZonePath; }
+ Objectif &objectif() { return _objectif; }
+ Common::Array<YieldedCallback> &yieldedCallbacks() { return _yieldedCallbacks; }
+ void setSaveRequested() { _saveRequested = true; }
+ bool markersVisible() const { return _markersVisible; }
+ const TeVector3f32 &posPlayer() const { return _posPlayer; }
+ void setPosPlayer(const TeVector3f32 &pos) { _posPlayer = pos; }
+ TeTimer &walkTimer() { return _walkTimer; }
+ void setExitZone(const Common::String &zone) { _exitZone = zone; }
+ bool isArtworkUnlocked(const Common::String &name) const;
+ static Common::String artworkConfName(const Common::String &name);
+
+ void setRunModeEnabled(bool val) { _runModeEnabled = val; }
+ bool runModeEnabled() const { return _runModeEnabled; }
+
+private:
+ bool addAnimToSet(const Common::String &path);
+ void addNoScale2Children();
+ void addNoScaleChildren();
+
+ void attachButtonsLayoutGoto() {}; // does nothing?
+ void createButtonsLayoutGoto() {}; // does nothing?
+ void deleteButtonsLayoutGoto() {}; // does nothing?
+
+ bool changeWarp2(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+
+ void deleteNoScale();
+
+ void initNoScale();
+ void initScene(bool param_1, const Common::String &scenePath);
+ bool initWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag);
+
+ bool onCallNumber(Common::String val);
+ bool onCharacterAnimationFinished(const Common::String &val);
+ bool onCharacterAnimationPlayerFinished(const Common::String &val);
+ bool onDialogFinished(const Common::String &val) override;
+ bool onDisplacementFinished();
+ bool onDisplacementPlayerFinished();
+ bool onFinishedCheckBackup(bool result);
+ bool onFinishedLoadingBackup(const Common::String &val) override;
+ bool onFinishedSavingBackup(int something);
+ bool onMarkersVisible(TeCheckboxLayout::State state);
+ bool onMouseClick(const Common::Point &pt);
+ bool onVideoFinished() override;
+
+ void removeNoScale2Children();
+ void removeNoScaleChildren();
+
+ bool _enteredFlag2;
+
+ int _score;
+
+ int _frameCounter;
+
+ TeVector2s32 _previousMousePos;
+ TeVector2s32 _lastCharMoveMousePos;
+
+ Common::String _warpZone;
+ Common::String _warpScene;
+ bool _warpFadeFlag;
+ bool _warped;
+
+ Common::String _exitZone;
+ Common::String _someSceneName;
+ Common::Path _sceneZonePath;
+
+ Common::Array<HitObject *> _gameHitObjects;
+ // These are static in original, but cleaner to keep here.
+ Common::Array<YieldedCallback> _yieldedCallbacks;
+
+ Common::HashMap<Common::String, Common::Array<RandomSound *>> _randomSounds;
+
+ Common::HashMap<Common::String, bool> _unlockedArtwork;
+
+ int _gameLoadState;
+
+ Objectif _objectif;
+
+ bool _markersVisible;
+ bool _saveRequested;
+ bool _randomSoundFinished;
+
+ RandomSound *_randomSound;
+ TeTimer _randomSoundTimer;
+
+ TeLayout *_noScaleLayout;
+
+ TeVector3f32 _posPlayer;
+
+ Common::Point _lastUpdateMousePos;
+
+ // Syberia 2 specific data
+ bool _runModeEnabled;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_SYBERIA_GAME_H
diff --git a/engines/tetraedge/game/youki_manager.cpp b/engines/tetraedge/game/youki_manager.cpp
index 12437d59ef2..54d64628be0 100644
--- a/engines/tetraedge/game/youki_manager.cpp
+++ b/engines/tetraedge/game/youki_manager.cpp
@@ -22,7 +22,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/youki_manager.h"
#include "tetraedge/game/character.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
namespace Tetraedge {
@@ -52,7 +52,8 @@ void YoukiManager::update() {
if (g_engine->gameType() != TetraedgeEngine::kSyberia2 || !_followKate)
return;
- Game *game = g_engine->getGame();
+ SyberiaGame *game = dynamic_cast<SyberiaGame *>(g_engine->getGame());
+ assert(game);
Character *youki = game->scene().character("Youki");
if (!youki || !youki->freeMoveZone())
return;
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 008a6c270cd..1e233229e0c 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -41,6 +41,7 @@ MODULE_OBJS := \
game/question2.o \
game/scene_lights_xml_parser.o \
game/splash_screens.o \
+ game/syberia_game.o \
game/upsell_screen.o \
game/youki_manager.o \
te/micropather.o \
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index bbcec02c1d0..9c9b4bc877f 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -31,7 +31,7 @@
#include "engines/dialogs.h"
#include "graphics/palette.h"
-#include "tetraedge/game/game.h"
+#include "tetraedge/game/syberia_game.h"
#include "tetraedge/game/application.h"
#include "tetraedge/game/character.h"
#include "tetraedge/te/te_core.h"
@@ -99,7 +99,7 @@ TeCore *TetraedgeEngine::getCore() {
Game *TetraedgeEngine::getGame() {
if (_game == nullptr)
- _game = new Game();
+ _game = new SyberiaGame();
return _game;
}
Commit: 9baaeee37f17a17a412be2fe3d88eae43070b74b
https://github.com/scummvm/scummvm/commit/9baaeee37f17a17a412be2fe3d88eae43070b74b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-04-07T21:54:18+09:00
Commit Message:
TETRAEDGE: Starting to add classes needed for Amerzone
Changed paths:
A engines/tetraedge/game/amerzone_game.cpp
A engines/tetraedge/game/amerzone_game.h
A engines/tetraedge/te/te_marker.cpp
A engines/tetraedge/te/te_marker.h
A engines/tetraedge/te/te_warp.cpp
A engines/tetraedge/te/te_warp.h
A engines/tetraedge/te/te_warp_marker.cpp
A engines/tetraedge/te/te_warp_marker.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/main_menu.cpp
engines/tetraedge/game/syberia_game.h
engines/tetraedge/module.mk
engines/tetraedge/tetraedge.cpp
diff --git a/engines/tetraedge/game/amerzone_game.cpp b/engines/tetraedge/game/amerzone_game.cpp
new file mode 100644
index 00000000000..cf7e76e9302
--- /dev/null
+++ b/engines/tetraedge/game/amerzone_game.cpp
@@ -0,0 +1,207 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
+#include "tetraedge/game/amerzone_game.h"
+#include "tetraedge/te/te_input_mgr.h"
+
+namespace Tetraedge {
+
+AmerzoneGame::AmerzoneGame() : Tetraedge::Game(), _orientationX(0.0f), _orientationY(0.0f),
+_speedX(0.0f), _speedY(0.0f), _isInDrag(false), _edgeButtonRolloverCount(0),
+_warpX(nullptr), _warpY(nullptr) {
+
+}
+
+void AmerzoneGame::addToBag(const Common::String &objname) {
+ inventory().addObject(objname);
+ // TODO: set this once _puzzleDisjoncteur is created
+ //if (objname == "A_Fil_cuivre_jour")
+ // _puzzleDisjoncteur.addState(2);
+
+ _notifier.push("<section style=\"center\" /><color r=\"0\" g=\"0\" b=\"0\"/><font file=\"Common/Fonts/Arial_r_16.tef\" />" + inventory().objectName(objname), "");
+}
+
+void AmerzoneGame::changeSpeedToMouseDirection() {
+ error("TODO: Implement AmerzoneGame::changeSpeedToMouseDirection");
+}
+
+bool AmerzoneGame::changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) {
+ error("TODO: Implement AmerzoneGame::changeWarp");
+ return false;
+}
+
+void AmerzoneGame::draw() {
+ error("TODO: Implement AmerzoneGame::draw");
+}
+
+void AmerzoneGame::enter() {
+ // TODO:
+ //_puzzleDisjoncteur.setState(5);
+ _inGameGui.load("GUI/InGame.lua");
+
+ error("TODO: Implement AmerzoneGame::enter");
+}
+
+void AmerzoneGame::finishGame() {
+ // Skip the animations of the original.
+ // This is more like OnGameFinishedRotateAnimFinished.
+ leave(true);
+ Application *app = g_engine->getApplication();
+ app->mainMenu().enter();
+}
+
+void AmerzoneGame::initLoadedBackupData() {
+
+}
+
+void AmerzoneGame::leave(bool flag) {
+ error("TODO: Implement AmerzoneGame::leave");
+}
+
+void AmerzoneGame::setAngleX(float angle) {
+ float diff = angle - _orientationX;
+ float distFromMin = _xAngleMin - diff;
+ if (distFromMin < 0)
+ angle += distFromMin;
+ float distFromMax = diff + _xAngleMax;
+ if (distFromMax < 0)
+ angle -= distFromMax;
+
+ diff = angle - _orientationX;
+ _xAngleMin -= diff;
+ _xAngleMax += diff;
+
+ float roundedAngle = (int)(angle / 360.0f) * 360;
+ _orientationX = roundedAngle;
+ if (roundedAngle > 360.0f || roundedAngle < -360.0f)
+ _orientationX = 0;
+}
+
+void AmerzoneGame::setAngleY(float angle) {
+ float diff = angle - _orientationY;
+ float distFromMin = _yAngleMin - diff;
+ if (distFromMin < 0)
+ angle += distFromMin;
+ float distFromMax = diff + _yAngleMax;
+ if (distFromMax < 0)
+ angle -= distFromMax;
+
+ diff = angle - _orientationY;
+ _yAngleMin -= diff;
+ _yAngleMax += diff;
+
+ if (angle < -55.0f)
+ _orientationY = -55.0f;
+ else if (_orientationY > 45.0f)
+ _orientationY = 45.0f;
+}
+
+void AmerzoneGame::speedX(float speed) {
+ _speedX = CLIP(speed, -10000.0f, 10000.0f);
+}
+
+void AmerzoneGame::speedY(float speed) {
+ _speedY = CLIP(speed, -10000.0f, 10000.0f);
+}
+
+void AmerzoneGame::update() {
+ TeInputMgr *inputMgr = g_engine->getInputMgr();
+
+ // TODO:
+ // if (!inputMgr->isLeftDown())
+ // isInDrag(false);
+
+ Application *app = g_engine->getApplication();
+ if (!app->compassLook()) {
+ if (_isInDrag) {
+ TeVector2s32 mousePos = TeVector2s32(inputMgr->lastMousePos());
+ TeVector3f32 offset = TeVector3f32(mousePos - _mouseDragLast);
+ TeMatrix4x4 orientLayoutMatrix = app->frontOrientationLayout().rotation().toTeMatrix();
+ TeVector3f32 rotOffset = orientLayoutMatrix * offset;
+ if (app->inverseLook()) {
+ setAngleX(_orientationX + rotOffset.x() / 2);
+ setAngleY(_orientationY - rotOffset.y() / 2);
+ } else {
+ setAngleX(_orientationX - rotOffset.x() / 2);
+ setAngleY(_orientationY + rotOffset.y() / 2);
+ }
+ _mouseDragLast = inputMgr->lastMousePos();
+ } else {
+ if (_edgeButtonRolloverCount > 0) {
+ changeSpeedToMouseDirection();
+ }
+ float dragtime = (float)(_dragTimer.timeElapsed() / 1000000.0);
+ setAngleX(_orientationX - _speedX * dragtime);
+ setAngleY(_orientationY + _speedY * dragtime);
+ }
+ } else {
+ // Compass stuff happens here in the game, but it's
+ // not fully implemented - the TeCompass class is just
+ // stubs.
+ error("TODO: Implement compass support in AmerzoneGame::update.");
+ }
+
+ if (_warpY) {
+ TeVector2s32 mousePos = TeVector2s32(inputMgr->lastMousePos());
+ TeVector3f32 offset = TeVector3f32(mousePos - _mouseDragStart);
+ if (offset.length() > 20.0f)
+ _warpY->setMouseLeftUpForMakers();
+ }
+
+ TeQuaternion xRot = TeQuaternion::fromAxisAndAngle(TeVector3f32(0, 1, 0), (float)(_orientationX * M_PI) / 180);
+ TeQuaternion yRot = TeQuaternion::fromAxisAndAngle(TeVector3f32(1, 0, 0), (float)(_orientationY * M_PI) / 180);
+
+ if (_warpX)
+ _warpX->rotateCamera(xRot * yRot);
+ if (_warpY)
+ _warpY->rotateCamera(xRot * yRot);
+ if (_warpX)
+ _warpX->update();
+ if (_warpY)
+ _warpY->update();
+
+}
+
+bool AmerzoneGame::onDialogFinished(const Common::String &val) {
+ _luaScript.execute("OnDialogFinished", val);
+ return false;
+}
+
+bool AmerzoneGame::onVideoFinished() {
+ _inGameGui.buttonLayoutChecked("videoBackgroundButton")->setVisible(false);
+ _inGameGui.buttonLayoutChecked("skipVideoButton")->setVisible(false);
+ TeSpriteLayout *video = _inGameGui.spriteLayoutChecked("video");
+ Common::String vidPath = video->_tiledSurfacePtr->loadedPath();
+ video->setVisible(false);
+ _music.stop();
+ // TODO:
+ //Application *app = g_engine->getApplication();
+ //if (app->musicOn()) {
+ // app->music().play();
+ //}
+ _running = true;
+ _luaScript.execute("OnMovieFinished", vidPath);
+ return false;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/game/amerzone_game.h b/engines/tetraedge/game/amerzone_game.h
new file mode 100644
index 00000000000..da2427593e8
--- /dev/null
+++ b/engines/tetraedge/game/amerzone_game.h
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TETRAEDGE_GAME_AMERZONE_GAME_H
+#define TETRAEDGE_GAME_AMERZONE_GAME_H
+
+#include "tetraedge/game/game.h"
+#include "tetraedge/te/te_timer.h"
+#include "tetraedge/te/te_warp.h"
+
+namespace Tetraedge {
+
+/** The main Amerzone Game class. This is known as GameWarp in the original
+ * code, but was renamed to be more descriptive in the ScummVM context */
+class AmerzoneGame : public Tetraedge::Game {
+public:
+ AmerzoneGame();
+
+ ~AmerzoneGame() {}
+
+ virtual void addToBag(const Common::String &objname) override;
+ virtual bool changeWarp(const Common::String &zone, const Common::String &scene, bool fadeFlag) override;
+ virtual void draw() override;
+ virtual void enter() override;
+ virtual void finishGame() override;
+ virtual void initLoadedBackupData() override;
+ virtual void leave(bool flag) override;
+ virtual void update() override;
+ virtual bool onDialogFinished(const Common::String &val) override;
+ virtual bool onVideoFinished() override;
+
+private:
+ void changeSpeedToMouseDirection();
+ void setAngleX(float angle);
+ void setAngleY(float angle);
+ void speedX(float speed);
+ void speedY(float speed);
+
+ TeTimer _dragTimer;
+ float _orientationX;
+ float _orientationY;
+ float _xAngleMin;
+ float _xAngleMax;
+ float _yAngleMin;
+ float _yAngleMax;
+ float _speedX;
+ float _speedY;
+ bool _isInDrag;
+ int _edgeButtonRolloverCount;
+ TeVector2s32 _mouseDragStart;
+ TeVector2s32 _mouseDragLast;
+ /*
+ TeCurveAnim<AmerzoneGame, float> _decelAnimX;
+ TeCurveAnim<AmerzoneGame, float> _decelAnimY;
+ */
+ TeWarp *_warpX;
+ TeWarp *_warpY;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_GAME_AMERZONE_GAME_H
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 3da0e119a23..5f7736396de 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -48,7 +48,7 @@ bool Application::_dontUpdateWhenApplicationPaused = false;
Application::Application() : _finishedGame(false), _finishedFremium(false),
_captureFade(false), _difficulty(1), _created(false), _tutoActivated(false),
-_drawShadows(true) {
+_drawShadows(true), _compassLook(false), _inverseLook(false) {
//
// TODO: Game defaults _ratioStretched to false, but then
// the horizontally scrolling scenes don't scroll properly.
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 7a1bb59ff6a..6b1215db1cb 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -112,6 +112,8 @@ public:
TeLayout &backLayout() { return _backLayout; }
LocFile &loc() { return _loc; }
bool ratioStretched() const { return _ratioStretched; }
+ bool compassLook() const { return _compassLook; }
+ bool inverseLook() const { return _inverseLook; }
private:
void drawBack();
@@ -178,6 +180,8 @@ private:
bool _tutoActivated;
bool _drawShadows;
bool _ratioStretched;
+ bool _compassLook;
+ bool _inverseLook;
int _difficulty;
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index 7f0ab07c49d..cb5ecd5243b 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -28,6 +28,7 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
+#include "tetraedge/game/cellphone.h"
#include "tetraedge/game/character.h"
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/game/game.h"
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index b8502db1659..d3ee0fd04b1 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -32,14 +32,11 @@
#include "tetraedge/game/inventory_menu.h"
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/game/notifier.h"
-#include "tetraedge/game/cellphone.h"
#include "tetraedge/game/game_sound.h"
-#include "tetraedge/game/objectif.h"
#include "tetraedge/game/question2.h"
#include "tetraedge/game/dialog2.h"
#include "tetraedge/te/te_lua_gui.h"
#include "tetraedge/te/te_music.h"
-#include "tetraedge/te/te_checkbox_layout.h"
#include "tetraedge/te/te_vector2s32.h"
namespace Tetraedge {
diff --git a/engines/tetraedge/game/main_menu.cpp b/engines/tetraedge/game/main_menu.cpp
index fa82bba68df..1ef121427b5 100644
--- a/engines/tetraedge/game/main_menu.cpp
+++ b/engines/tetraedge/game/main_menu.cpp
@@ -127,6 +127,11 @@ void MainMenu::enter() {
// TODO: confirmation (menus/confirm/confirmNotSound.lua)
// if TeSoundManager is not valid.
+ // Hide the Facebook button since we don't support it anyway..
+ TeButtonLayout *fbButton = buttonLayout("facebookButton");
+ if (fbButton)
+ fbButton->setVisible(false);
+
_confirmingTuto = false;
TeLayout *panel = layout("panel");
diff --git a/engines/tetraedge/game/syberia_game.h b/engines/tetraedge/game/syberia_game.h
index 8642b0e4dec..f9a7d3e149b 100644
--- a/engines/tetraedge/game/syberia_game.h
+++ b/engines/tetraedge/game/syberia_game.h
@@ -25,23 +25,15 @@
#include "common/types.h"
#include "common/serializer.h"
#include "common/str.h"
-#include "common/random.h"
-#include "tetraedge/game/documents_browser.h"
-#include "tetraedge/game/inventory.h"
-#include "tetraedge/game/inventory_menu.h"
#include "tetraedge/game/in_game_scene.h"
#include "tetraedge/game/game.h"
-#include "tetraedge/game/notifier.h"
#include "tetraedge/game/cellphone.h"
#include "tetraedge/game/game_sound.h"
#include "tetraedge/game/objectif.h"
-#include "tetraedge/game/question2.h"
-#include "tetraedge/game/dialog2.h"
-#include "tetraedge/te/te_lua_gui.h"
-#include "tetraedge/te/te_music.h"
#include "tetraedge/te/te_checkbox_layout.h"
#include "tetraedge/te/te_vector2s32.h"
+#include "tetraedge/te/te_vector3f32.h"
namespace Tetraedge {
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index 1e233229e0c..fdea988313a 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/tetraedge
MODULE_OBJS := \
tetraedge.o \
to_lua.o \
+ game/amerzone_game.o \
game/application.o \
game/billboard.o \
game/bonus_menu.o \
@@ -78,6 +79,7 @@ MODULE_OBJS := \
te/te_lua_gui_lua_callbacks.o \
te/te_lua_script.o \
te/te_lua_thread.o \
+ te/te_marker.o \
te/te_material.o \
te/te_matricies_stack.o \
te/te_matrix4x4.o \
@@ -118,6 +120,8 @@ MODULE_OBJS := \
te/te_vector2s32.o \
te/te_vector3f32.o \
te/te_visual_fade.o \
+ te/te_warp.o \
+ te/te_warp_marker.o \
te/te_xml_parser.o \
te/te_xml_gui.o \
metaengine.o
diff --git a/engines/tetraedge/te/te_marker.cpp b/engines/tetraedge/te/te_marker.cpp
new file mode 100644
index 00000000000..6eb98addb68
--- /dev/null
+++ b/engines/tetraedge/te/te_marker.cpp
@@ -0,0 +1,46 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/te/te_marker.h"
+
+namespace Tetraedge {
+
+TeMarker::TeMarker() : _visible(true), _isActive(false) {
+}
+
+void TeMarker::active(bool val) {
+ _isActive = val;
+ _button.setVisible(!_visible && val);
+}
+
+void TeMarker::update(TeCamera *camera) {
+ if (!_visible)
+ return;
+ error("TODO: Finish TeMarker::update");
+}
+
+void TeMarker::visible(bool vis) {
+ _visible = vis;
+ bool buttonVis = (vis && _isActive);
+ _button.setVisible(buttonVis);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_marker.h b/engines/tetraedge/te/te_marker.h
new file mode 100644
index 00000000000..fbc5cd3e781
--- /dev/null
+++ b/engines/tetraedge/te/te_marker.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TETRAEDGE_TE_TE_MARKER_H
+#define TETRAEDGE_TE_TE_MARKER_H
+
+#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_button_layout.h"
+#include "tetraedge/te/te_vector3f32.h"
+
+namespace Tetraedge {
+
+// Note: Only used in Amerzone
+class TeMarker {
+public:
+ TeMarker();
+
+ void active(bool val);
+ void update(TeCamera *camera);
+ void visible(bool val);
+
+ TeButtonLayout &button() { return _button; }
+private:
+ bool _visible;
+ bool _isActive;
+ TeVector3f32 _loc;
+ // Note: this is a TeSpriteButton in the original, updated
+ // to use the newer ButtonLayout
+ TeButtonLayout _button;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_MARKER_H
diff --git a/engines/tetraedge/te/te_warp.cpp b/engines/tetraedge/te/te_warp.cpp
new file mode 100644
index 00000000000..f6b1ffc5e5c
--- /dev/null
+++ b/engines/tetraedge/te/te_warp.cpp
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/te/te_warp.h"
+
+namespace Tetraedge {
+
+TeWarp::TeWarp() {
+}
+
+void TeWarp::update() {
+ error("TODO: Implement TeWarp::update");
+}
+
+void TeWarp::setMouseLeftUpForMakers() {
+ // TODO:
+ //for (auto &marker : _warpMarkers) {
+ // marker->marker()->sprite()->setEnable(true)
+ //}
+ error("TODO: Implement TeWarp::setMouseLeftUpForMakers");
+}
+
+void TeWarp::rotateCamera(const TeQuaternion &rot) {
+ TeQuaternion normRot = rot;
+ normRot.normalize();
+ _camera.setRotation(normRot);
+}
+
+void TeWarp::setFov(float fov) {
+ _camera.setFov(fov);
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_warp.h b/engines/tetraedge/te/te_warp.h
new file mode 100644
index 00000000000..27291dc57a2
--- /dev/null
+++ b/engines/tetraedge/te/te_warp.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TETRAEDGE_TE_TE_WARP_H
+#define TETRAEDGE_TE_TE_WARP_H
+
+#include "tetraedge/te/te_3d_object2.h"
+#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_quaternion.h"
+#include "tetraedge/te/te_warp_marker.h"
+
+namespace Tetraedge {
+
+// Note: Only used in Amerzone
+class TeWarp : Te3DObject2 {
+public:
+ class AnimData {
+ };
+
+ TeWarp();
+
+ void update();
+ void rotateCamera(const TeQuaternion &rot);
+ void setMarkersOpacity(float opacity);
+ void setMouseLeftUpForMakers();
+ void setFov(float fov);
+
+private:
+ Common::String _warpPath;
+ TeCamera _camera;
+ bool _markersActive;
+
+ Common::Array<TeWarpMarker *> _warpMarkers;
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_WARP_H
diff --git a/engines/tetraedge/te/te_warp_marker.cpp b/engines/tetraedge/te/te_warp_marker.cpp
new file mode 100644
index 00000000000..676663972ba
--- /dev/null
+++ b/engines/tetraedge/te/te_warp_marker.cpp
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/te/te_warp_marker.h"
+
+namespace Tetraedge {
+
+TeWarpMarker::TeWarpMarker() : _marker(nullptr) {
+}
+
+TeWarpMarker::~TeWarpMarker() {
+ if (_marker)
+ _marker->button().onMouseClickValidated().remove(this, &TeWarpMarker::onMarkerButtonValidated);
+}
+
+void TeWarpMarker::marker(TeMarker *marker) {
+ if (_marker)
+ _marker->button().onMouseClickValidated().remove(this, &TeWarpMarker::onMarkerButtonValidated);
+ _marker = marker;
+ if (_marker)
+ _marker->button().onMouseClickValidated().add(this, &TeWarpMarker::onMarkerButtonValidated);
+}
+
+bool TeWarpMarker::onMarkerButtonValidated() {
+ _markerButtonSignal.call(_name);
+ return false;
+}
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_warp_marker.h b/engines/tetraedge/te/te_warp_marker.h
new file mode 100644
index 00000000000..30a643783a3
--- /dev/null
+++ b/engines/tetraedge/te/te_warp_marker.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TETRAEDGE_TE_TE_WARP_MARKER_H
+#define TETRAEDGE_TE_TE_WARP_MARKER_H
+
+#include "common/str.h"
+#include "tetraedge/te/te_marker.h"
+#include "tetraedge/te/te_signal.h"
+
+namespace Tetraedge {
+
+// Note: Only used in Amerzone
+class TeWarpMarker {
+public:
+ TeWarpMarker();
+ ~TeWarpMarker();
+
+ void marker(TeMarker *marker);
+ bool onMarkerButtonValidated();
+
+private:
+ TeMarker *_marker;
+ Common::String _name;
+ TeSignal1Param<const Common::String &> _markerButtonSignal;
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_WARP_MARKER_H
diff --git a/engines/tetraedge/tetraedge.cpp b/engines/tetraedge/tetraedge.cpp
index 9c9b4bc877f..4ba0bce3a84 100644
--- a/engines/tetraedge/tetraedge.cpp
+++ b/engines/tetraedge/tetraedge.cpp
@@ -31,6 +31,7 @@
#include "engines/dialogs.h"
#include "graphics/palette.h"
+#include "tetraedge/game/amerzone_game.h"
#include "tetraedge/game/syberia_game.h"
#include "tetraedge/game/application.h"
#include "tetraedge/game/character.h"
@@ -98,8 +99,12 @@ TeCore *TetraedgeEngine::getCore() {
}
Game *TetraedgeEngine::getGame() {
- if (_game == nullptr)
- _game = new SyberiaGame();
+ if (_game == nullptr) {
+ if (gameType() == kAmerzone)
+ _game = new AmerzoneGame();
+ else
+ _game = new SyberiaGame();
+ }
return _game;
}
Commit: 0b90939b9ffa4795c9b589cf8d63a00d02fba6ae
https://github.com/scummvm/scummvm/commit/0b90939b9ffa4795c9b589cf8d63a00d02fba6ae
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-04-07T21:54:18+09:00
Commit Message:
TETRAEDGE: Fix crash in Syberia 1
Changed paths:
engines/tetraedge/game/in_game_scene.cpp
diff --git a/engines/tetraedge/game/in_game_scene.cpp b/engines/tetraedge/game/in_game_scene.cpp
index 23134f6965f..9c5eb5e5f7e 100644
--- a/engines/tetraedge/game/in_game_scene.cpp
+++ b/engines/tetraedge/game/in_game_scene.cpp
@@ -138,10 +138,11 @@ bool InGameScene::addMarker(const Common::String &markerName, const Common::Stri
float yscale = 1.0f;
// Originally this is only done in Syberia 2, but
- // should be fine to calculate in Syberia 1.
+ // should be fine to calculate in Syberia 1, as long
+ // as the root layout is loaded.
TeLayout *bglayout = _bgGui.layoutChecked("background");
TeSpriteLayout *rootlayout = Game::findSpriteLayoutByName(bglayout, "root");
- if (rootlayout) {
+ if (rootlayout && rootlayout->_tiledSurfacePtr && rootlayout->_tiledSurfacePtr->tiledTexture()) {
TeVector2s32 bgSize = rootlayout->_tiledSurfacePtr->tiledTexture()->totalSize();
xscale = 800.0f / bgSize._x;
yscale = 600.0f / bgSize._y;
Commit: c0eaf1227d983af02bd8acac18101711b0ca7e7b
https://github.com/scummvm/scummvm/commit/c0eaf1227d983af02bd8acac18101711b0ca7e7b
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2023-04-07T21:54:18+09:00
Commit Message:
TETRAEDGE: Add more implementation for Amerzone support
Changed paths:
A engines/tetraedge/te/te_frustum.cpp
A engines/tetraedge/te/te_frustum.h
engines/tetraedge/game/amerzone_game.cpp
engines/tetraedge/game/amerzone_game.h
engines/tetraedge/game/application.cpp
engines/tetraedge/game/application.h
engines/tetraedge/game/dialog2.cpp
engines/tetraedge/game/game.cpp
engines/tetraedge/game/game.h
engines/tetraedge/game/inventory_menu.cpp
engines/tetraedge/game/notifier.cpp
engines/tetraedge/game/syberia_game.cpp
engines/tetraedge/module.mk
engines/tetraedge/te/te_lua_gui.cpp
engines/tetraedge/te/te_marker.cpp
engines/tetraedge/te/te_warp.cpp
engines/tetraedge/te/te_warp.h
engines/tetraedge/te/te_warp_marker.h
diff --git a/engines/tetraedge/game/amerzone_game.cpp b/engines/tetraedge/game/amerzone_game.cpp
index cf7e76e9302..30854c48cb2 100644
--- a/engines/tetraedge/game/amerzone_game.cpp
+++ b/engines/tetraedge/game/amerzone_game.cpp
@@ -22,7 +22,10 @@
#include "tetraedge/tetraedge.h"
#include "tetraedge/game/application.h"
#include "tetraedge/game/amerzone_game.h"
+#include "tetraedge/game/lua_binds.h"
#include "tetraedge/te/te_input_mgr.h"
+#include "tetraedge/te/te_sound_manager.h"
+#include "tetraedge/te/te_warp.h"
namespace Tetraedge {
@@ -55,11 +58,59 @@ void AmerzoneGame::draw() {
}
void AmerzoneGame::enter() {
+ Application *app = g_engine->getApplication();
// TODO:
//_puzzleDisjoncteur.setState(5);
_inGameGui.load("GUI/InGame.lua");
- error("TODO: Implement AmerzoneGame::enter");
+ TeLayout *inGame = _inGameGui.layoutChecked("inGame");
+ // Note:
+ app->frontOrientationLayout().addChild(inGame);
+ _inventoryMenu.load();
+ app->frontOrientationLayout().addChild(&_inventoryMenu);
+
+ TeButtonLayout *invbtn = _inGameGui.buttonLayoutChecked("inventoryButton");
+ invbtn->onMouseClickValidated().add(this, &AmerzoneGame::onInventoryButtonValidated);
+ TeButtonLayout *helpbtn = _inGameGui.buttonLayoutChecked("helpButton");
+ helpbtn->onMouseClickValidated().add(this, &AmerzoneGame::onHelpButtonValidated);
+ if (app->permanentHelp()) {
+ helpbtn->setVisible(false);
+ }
+ TeButtonLayout *skipvidbtn = _inGameGui.buttonLayoutChecked("skipVideoButton");
+ skipvidbtn->setVisible(false);
+ skipvidbtn->onMouseClickValidated().add(this, &AmerzoneGame::onSkipVideoButtonValidated);
+ TeSpriteLayout *vid = _inGameGui.spriteLayoutChecked("video");
+ vid->_tiledSurfacePtr->_frameAnim.onStop().add(this, &Game::onVideoFinished);
+ vid->setVisible(false);
+ _dialog2.load();
+ app->frontOrientationLayout().addChild(&_dialog2);
+ _question2.load();
+
+ TeInputMgr *inputMgr = g_engine->getInputMgr();
+ inputMgr->_mouseMoveSignal.add(this, &AmerzoneGame::onMouseMove);
+ inputMgr->_mouseLUpSignal.add(this, &AmerzoneGame::onMouseLeftUp);
+ inputMgr->_mouseLDownSignal.add(this, &AmerzoneGame::onMouseLeftDown);
+
+ _orientationX = 0;
+ _orientationY = 0;
+ _isInDrag = false;
+ _speedX = 0;
+ _speedY = 0;
+
+ _notifier.load();
+ _warpX = new TeWarp();
+ _warpX->setRotation(app->frontOrientationLayout().rotation());
+ _warpX->init();
+ _warpX->setVisible(true, false);
+ _luaContext.create();
+ _luaScript.attachToContext(&_luaContext);
+
+ warning("TODO: Finish AmerzoneGame::enter");
+
+ _playedTimer.start();
+ _edgeButtonRolloverCount = 0;
+
+ initLoadedBackupData();
}
void AmerzoneGame::finishGame() {
@@ -71,13 +122,38 @@ void AmerzoneGame::finishGame() {
}
void AmerzoneGame::initLoadedBackupData() {
-
+ _luaContext.destroy();
+ _luaContext.create();
+ _luaContext.addBindings(LuaBinds::LuaOpenBinds);
+ //if (!_loadName.empty()) {
+ //}
+ error("TODO: finish AmerzoneGame::initLoadedBackupData");
}
void AmerzoneGame::leave(bool flag) {
error("TODO: Implement AmerzoneGame::leave");
}
+bool AmerzoneGame::onHelpButtonValidated() {
+ g_engine->getSoundManager()->playFreeSound("Sounds/SFX/Clic_prec-suiv.ogg", 1.0f, "sfx");
+
+ bool active = true;
+ TeWarp::debug = TeWarp::debug == false;
+ if (!TeWarp::debug && !g_engine->getApplication()->permanentHelp())
+ active = false;
+
+ _warpY->activeMarkers(active);
+ return false;
+}
+
+bool AmerzoneGame::onMouseLeftUp(const Common::Point &pt) {
+ error("TODO: Implement AmerzoneGame::onMouseLeftUp");
+}
+
+bool AmerzoneGame::onMouseLeftDown(const Common::Point &pt) {
+ error("TODO: Implement AmerzoneGame::onMouseLeftDown");
+}
+
void AmerzoneGame::setAngleX(float angle) {
float diff = angle - _orientationX;
float distFromMin = _xAngleMin - diff;
diff --git a/engines/tetraedge/game/amerzone_game.h b/engines/tetraedge/game/amerzone_game.h
index da2427593e8..e739e6d8c73 100644
--- a/engines/tetraedge/game/amerzone_game.h
+++ b/engines/tetraedge/game/amerzone_game.h
@@ -54,6 +54,10 @@ private:
void speedX(float speed);
void speedY(float speed);
+ bool onHelpButtonValidated();
+ bool onMouseLeftUp(const Common::Point &pt);
+ bool onMouseLeftDown(const Common::Point &pt);
+
TeTimer _dragTimer;
float _orientationX;
float _orientationY;
diff --git a/engines/tetraedge/game/application.cpp b/engines/tetraedge/game/application.cpp
index 5f7736396de..15245e6efde 100644
--- a/engines/tetraedge/game/application.cpp
+++ b/engines/tetraedge/game/application.cpp
@@ -48,7 +48,8 @@ bool Application::_dontUpdateWhenApplicationPaused = false;
Application::Application() : _finishedGame(false), _finishedFremium(false),
_captureFade(false), _difficulty(1), _created(false), _tutoActivated(false),
-_drawShadows(true), _compassLook(false), _inverseLook(false) {
+_drawShadows(true), _compassLook(false), _inverseLook(false),
+_permanentHelp(false) {
//
// TODO: Game defaults _ratioStretched to false, but then
// the horizontally scrolling scenes don't scroll properly.
diff --git a/engines/tetraedge/game/application.h b/engines/tetraedge/game/application.h
index 6b1215db1cb..f24ccd069d0 100644
--- a/engines/tetraedge/game/application.h
+++ b/engines/tetraedge/game/application.h
@@ -114,6 +114,7 @@ public:
bool ratioStretched() const { return _ratioStretched; }
bool compassLook() const { return _compassLook; }
bool inverseLook() const { return _inverseLook; }
+ bool permanentHelp() const { return _permanentHelp; }
private:
void drawBack();
@@ -182,6 +183,7 @@ private:
bool _ratioStretched;
bool _compassLook;
bool _inverseLook;
+ bool _permanentHelp;
int _difficulty;
diff --git a/engines/tetraedge/game/dialog2.cpp b/engines/tetraedge/game/dialog2.cpp
index 04b32693c29..b355096fc7c 100644
--- a/engines/tetraedge/game/dialog2.cpp
+++ b/engines/tetraedge/game/dialog2.cpp
@@ -98,7 +98,8 @@ void Dialog2::load() {
setSize(TeVector3f32(1.0f, 1.0f, usersz.z()));
size(); // refresh size? seems to do nothing with result
_music.repeat(false);
- _gui.load("menus/dialog.lua");
+ const char *luaPath = g_engine->gameType() == TetraedgeEngine::kAmerzone ? "GUI/dialog.lua" : "menus/dialog.lua";
+ _gui.load(luaPath);
size(); // refresh size? seems to do nothing with result
TeButtonLayout *dialogLockBtn = _gui.buttonLayoutChecked("dialogLockButton");
diff --git a/engines/tetraedge/game/game.cpp b/engines/tetraedge/game/game.cpp
index cb5ecd5243b..576577bd23b 100644
--- a/engines/tetraedge/game/game.cpp
+++ b/engines/tetraedge/game/game.cpp
@@ -198,7 +198,7 @@ static const char cursorsTable[][2][80] = {
};
#endif
-bool Game::onMouseMove() {
+bool Game::onMouseMove(const Common::Point &pt) {
if (!_entered)
return false;
diff --git a/engines/tetraedge/game/game.h b/engines/tetraedge/game/game.h
index d3ee0fd04b1..6e187124b98 100644
--- a/engines/tetraedge/game/game.h
+++ b/engines/tetraedge/game/game.h
@@ -123,7 +123,7 @@ public:
virtual bool onFinishedLoadingBackup(const Common::String &val) { return false; }
bool onInventoryButtonValidated();
bool onLockVideoButtonValidated();
- bool onMouseMove();
+ bool onMouseMove(const Common::Point &pt);
bool onSkipVideoButtonValidated();
virtual bool onVideoFinished() = 0;
diff --git a/engines/tetraedge/game/inventory_menu.cpp b/engines/tetraedge/game/inventory_menu.cpp
index 09d1b63a76c..ef7c2182373 100644
--- a/engines/tetraedge/game/inventory_menu.cpp
+++ b/engines/tetraedge/game/inventory_menu.cpp
@@ -56,8 +56,10 @@ void InventoryMenu::load() {
addChild(_gui.layoutChecked("inventoryMenu"));
_gui.buttonLayoutChecked("quitButton")->onMouseClickValidated()
.add(this, &InventoryMenu::onQuitButton);
- _gui.buttonLayoutChecked("quitBackground")->onMouseClickValidated()
- .add(this, &InventoryMenu::onQuitButton);
+ // Quit background is only in Syberia 1 and 2 (not amerzone)
+ TeButtonLayout *quitBackground = _gui.buttonLayout("quitBackground");
+ if (quitBackground)
+ quitBackground->onMouseClickValidated().add(this, &InventoryMenu::onQuitButton);
_gui.buttonLayoutChecked("mainMenuButton")->onMouseClickValidated()
.add(this, &InventoryMenu::onMainMenuButton);
_gui.buttonLayoutChecked("documentsButton")->onMouseClickValidated()
diff --git a/engines/tetraedge/game/notifier.cpp b/engines/tetraedge/game/notifier.cpp
index 32c1fb5da71..0a4f8066e31 100644
--- a/engines/tetraedge/game/notifier.cpp
+++ b/engines/tetraedge/game/notifier.cpp
@@ -76,8 +76,10 @@ void Notifier::launchNextnotifier() {
}
void Notifier::load() {
- _gui.load("menus/Notifier.lua");
- TeLayout *notifierLayout = _gui.layoutChecked("notifier");
+ const char *luaPath = g_engine->gameType() == TetraedgeEngine::kAmerzone ? "GUI/Notify.lua" : "menus/Notifier.lua";
+ _gui.load(luaPath);
+ const char *layoutName = g_engine->gameType() == TetraedgeEngine::kAmerzone ? "notify" : "notifier";
+ TeLayout *notifierLayout = _gui.layoutChecked(layoutName);
Game *game = g_engine->getGame();
game->addNoScale2Child(notifierLayout);
notifierLayout->setVisible(false);
diff --git a/engines/tetraedge/game/syberia_game.cpp b/engines/tetraedge/game/syberia_game.cpp
index f96c542cf18..14dda809a1b 100644
--- a/engines/tetraedge/game/syberia_game.cpp
+++ b/engines/tetraedge/game/syberia_game.cpp
@@ -1387,7 +1387,7 @@ void SyberiaGame::update() {
Common::Point mousePos = g_engine->getInputMgr()->lastMousePos();
if (_lastUpdateMousePos != mousePos) {
- onMouseMove();
+ onMouseMove(mousePos);
_lastUpdateMousePos = mousePos;
}
if (_saveRequested) {
diff --git a/engines/tetraedge/module.mk b/engines/tetraedge/module.mk
index fdea988313a..031499ba56c 100644
--- a/engines/tetraedge/module.mk
+++ b/engines/tetraedge/module.mk
@@ -62,6 +62,7 @@ MODULE_OBJS := \
te/te_font3.o \
te/te_frame_anim.o \
te/te_free_move_zone.o \
+ te/te_frustum.o \
te/te_i_3d_object2.o \
te/te_i_layout.o \
te/te_i_loc.o \
diff --git a/engines/tetraedge/te/te_frustum.cpp b/engines/tetraedge/te/te_frustum.cpp
new file mode 100644
index 00000000000..b5c300caa57
--- /dev/null
+++ b/engines/tetraedge/te/te_frustum.cpp
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tetraedge/te/te_frustum.h"
+
+namespace Tetraedge {
+
+TeFrustum::TeFrustum() {
+}
+
+void TeFrustum::computeNormal(unsigned int val) {
+ error("TODO: implement TeFrustum::computeNormal");
+}
+
+void TeFrustum::extractPlanAdd(const TeMatrix4x4 &matrix, uint dest, uint col) {
+ _m[dest * 4 + 0] = matrix(0, 3) - matrix(0, col);
+ _m[dest * 4 + 1] = matrix(1, 3) - matrix(1, col);
+ _m[dest * 4 + 2] = matrix(2, 3) - matrix(2, col);
+ _m[dest * 4 + 3] = matrix(3, 3) - matrix(3, col);
+}
+
+void TeFrustum::extractPlanSub(const TeMatrix4x4 &matrix, uint dest, uint col) {
+ _m[dest * 4 + 0] = matrix(0, 3) + matrix(0, col);
+ _m[dest * 4 + 1] = matrix(1, 3) + matrix(1, col);
+ _m[dest * 4 + 2] = matrix(2, 3) + matrix(2, col);
+ _m[dest * 4 + 3] = matrix(3, 3) + matrix(3, col);
+}
+
+bool TeFrustum::pointIsIn(const TeVector3f32 &pt) {
+ error("TODO: Implement TeFrustum::pointIsIn");
+}
+
+float TeFrustum::planeLen(int num) const {
+ assert(num >= 0 && num < 6);
+ const float *p = _m + num * 4;
+ float result = (float)sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
+ if (result == 0)
+ result = 1e-08;
+ return result;
+}
+
+bool TeFrustum::sphereIsIn(const TeVector3f32 &vec, float f) {
+ error("TODO: Implement TeFrustum::sphereIsIn");
+}
+
+bool TeFrustum::triangleIsIn(const TeVector3f32 *verts) {
+ for (unsigned int p = 0; p < 6; p++) {
+ bool inside = true;
+ for (unsigned int v = 0; v < 3; v++) {
+ float *pm = _m + p * 4;
+ if(pm[0] * verts[v].x() + pm[1] * verts[v].y() +
+ pm[2] * verts[v].z() + pm[3] >= 0.0)
+ inside = false;
+ }
+ if (!inside)
+ return false;
+ }
+
+ return true;
+}
+
+void TeFrustum::update(TeCamera *camera) {
+ const TeMatrix4x4 camMatrix = camera->worldTransformationMatrix();
+ for (unsigned int plane = 0; plane < 6; plane++) {
+ if (plane % 2)
+ extractPlanAdd(camMatrix, plane / 2, plane);
+ else
+ extractPlanSub(camMatrix, plane / 2, plane);
+ float len = planeLen(plane);
+ float *p = _m + plane * 4;
+ for (int i = 0; i < 4; i++)
+ p[i] /= len;
+ }
+}
+
+
+} // end namespace Tetraedge
diff --git a/engines/tetraedge/te/te_frustum.h b/engines/tetraedge/te/te_frustum.h
new file mode 100644
index 00000000000..dbbc7a9a077
--- /dev/null
+++ b/engines/tetraedge/te/te_frustum.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef TETRAEDGE_TE_TE_FRUSTUM_H
+#define TETRAEDGE_TE_TE_FRUSTUM_H
+
+#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_vector3f32.h"
+#include "tetraedge/te/te_matrix4x4.h"
+
+namespace Tetraedge {
+
+class TeFrustum {
+public:
+ TeFrustum();
+
+ void computeNormal(unsigned int val);
+ void extractPlanAdd(const TeMatrix4x4 &matrix, uint param_2, uint param_3);
+ void extractPlanSub(const TeMatrix4x4 &matrix, uint param_2, uint param_3);
+ bool pointIsIn(const TeVector3f32 &pt);
+ bool sphereIsIn(const TeVector3f32 &vec, float f);
+ bool triangleIsIn(const TeVector3f32 *vertexes);
+ void update(TeCamera *camera);
+
+private:
+ float planeLen(int num) const;
+ float _m[24];
+
+};
+
+} // end namespace Tetraedge
+
+#endif // TETRAEDGE_TE_TE_FRUSTUM_H
diff --git a/engines/tetraedge/te/te_lua_gui.cpp b/engines/tetraedge/te/te_lua_gui.cpp
index d975b165d5b..97d596efc41 100644
--- a/engines/tetraedge/te/te_lua_gui.cpp
+++ b/engines/tetraedge/te/te_lua_gui.cpp
@@ -208,6 +208,9 @@ bool TeLuaGUI::load(const Common::FSNode &node) {
_luaContext.registerCFunction("TeRotationLinearAnimation", rotationLinearAnimationBindings);
_luaContext.registerCFunction("TeScrollingLayout", scrollingLayoutBindings);
_luaContext.registerCFunction("TeExtendedTextLayout", extendedTextLayoutBindings);
+ // TODO: We replaced the video layout from Amerzone with a sprite layout. Probably
+ // works ok?
+ _luaContext.registerCFunction("TeVideoLayout", spriteLayoutBindings);
_luaContext.setInRegistry("__TeLuaGUIThis", this);
_luaScript.attachToContext(&_luaContext);
_luaScript.load(node);
diff --git a/engines/tetraedge/te/te_marker.cpp b/engines/tetraedge/te/te_marker.cpp
index 6eb98addb68..b10c296520a 100644
--- a/engines/tetraedge/te/te_marker.cpp
+++ b/engines/tetraedge/te/te_marker.cpp
@@ -34,7 +34,12 @@ void TeMarker::active(bool val) {
void TeMarker::update(TeCamera *camera) {
if (!_visible)
return;
- error("TODO: Finish TeMarker::update");
+ TeVector3f32 transformLoc = camera->transformCoord(_loc);
+ if (transformLoc.z() < 0) {
+ error("TODO: Finish TeMarker::update");
+ } else {
+ error("TODO: Finish TeMarker::update");
+ }
}
void TeMarker::visible(bool vis) {
diff --git a/engines/tetraedge/te/te_warp.cpp b/engines/tetraedge/te/te_warp.cpp
index f6b1ffc5e5c..1fa3ed159fb 100644
--- a/engines/tetraedge/te/te_warp.cpp
+++ b/engines/tetraedge/te/te_warp.cpp
@@ -19,14 +19,39 @@
*
*/
+#include "tetraedge/tetraedge.h"
+#include "tetraedge/game/application.h"
#include "tetraedge/te/te_warp.h"
+#include "tetraedge/te/te_input_mgr.h"
namespace Tetraedge {
-TeWarp::TeWarp() {
+/*static*/
+bool TeWarp::debug = false;
+
+TeWarp::TeWarp() : _visible1(false) {
+}
+
+void TeWarp::activeMarkers(bool active) {
+ _markersActive = active;
+ for (auto &warpMarker : _warpMarkers)
+ warpMarker->marker()->active(active);
+}
+
+void TeWarp::init() {
+ // This mostly sets up the camera.. maybe nothing to do?
+ warning("TODO: Implement TeWarp::init");
+}
+
+bool TeWarp::onMouseLeftDown(const Common::Point &pt) {
+ error("TODO: Implement TeWarp::onMouseLeftDown");
}
void TeWarp::update() {
+ if (!_visible1 || !_file.isOpen())
+ return;
+ Application *app = g_engine->getApplication();
+ _frustum.update(app->mainWindowCamera());
error("TODO: Implement TeWarp::update");
}
@@ -38,6 +63,22 @@ void TeWarp::setMouseLeftUpForMakers() {
error("TODO: Implement TeWarp::setMouseLeftUpForMakers");
}
+void TeWarp::setVisible(bool v1, bool v2) {
+ if (_visible1 == v1)
+ return;
+
+ _visible1 = v1;
+ TeInputMgr *inputMgr = g_engine->getInputMgr();
+ if (v1) {
+ inputMgr->_mouseLDownSignal.add(this, &TeWarp::onMouseLeftDown);
+ } else {
+ if (v2) {
+ error("TODO: Implement TeWarp::setVisible for v2==true");
+ }
+ inputMgr->_mouseLDownSignal.remove(this, &TeWarp::onMouseLeftDown);
+ }
+}
+
void TeWarp::rotateCamera(const TeQuaternion &rot) {
TeQuaternion normRot = rot;
normRot.normalize();
diff --git a/engines/tetraedge/te/te_warp.h b/engines/tetraedge/te/te_warp.h
index 27291dc57a2..e783f3d67e5 100644
--- a/engines/tetraedge/te/te_warp.h
+++ b/engines/tetraedge/te/te_warp.h
@@ -22,31 +22,45 @@
#ifndef TETRAEDGE_TE_TE_WARP_H
#define TETRAEDGE_TE_TE_WARP_H
+#include "common/file.h"
+
#include "tetraedge/te/te_3d_object2.h"
#include "tetraedge/te/te_camera.h"
+#include "tetraedge/te/te_frustum.h"
#include "tetraedge/te/te_quaternion.h"
#include "tetraedge/te/te_warp_marker.h"
namespace Tetraedge {
// Note: Only used in Amerzone
-class TeWarp : Te3DObject2 {
+class TeWarp : public Te3DObject2 {
public:
class AnimData {
};
TeWarp();
+ void activeMarkers(bool active);
+ void init();
void update();
void rotateCamera(const TeQuaternion &rot);
void setMarkersOpacity(float opacity);
void setMouseLeftUpForMakers();
void setFov(float fov);
+ void setVisible(bool v1, bool v2);
+
+ static bool debug;
private:
+ bool onMouseLeftDown(const Common::Point &pt);
+
+ Common::File _file;
Common::String _warpPath;
TeCamera _camera;
bool _markersActive;
+ bool _visible1;
+
+ TeFrustum _frustum;
Common::Array<TeWarpMarker *> _warpMarkers;
diff --git a/engines/tetraedge/te/te_warp_marker.h b/engines/tetraedge/te/te_warp_marker.h
index 30a643783a3..7bd06540c25 100644
--- a/engines/tetraedge/te/te_warp_marker.h
+++ b/engines/tetraedge/te/te_warp_marker.h
@@ -34,6 +34,7 @@ public:
TeWarpMarker();
~TeWarpMarker();
+ TeMarker *marker() { return _marker; }
void marker(TeMarker *marker);
bool onMarkerButtonValidated();
More information about the Scummvm-git-logs
mailing list