aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base/base_game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/wintermute/base/base_game.cpp')
-rw-r--r--engines/wintermute/base/base_game.cpp310
1 files changed, 306 insertions, 4 deletions
diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp
index a06511f3ea..f5caaa8d2e 100644
--- a/engines/wintermute/base/base_game.cpp
+++ b/engines/wintermute/base/base_game.cpp
@@ -48,6 +48,7 @@
#include "engines/wintermute/base/base_surface_storage.h"
#include "engines/wintermute/base/saveload.h"
#include "engines/wintermute/base/save_thumb_helper.h"
+#include "engines/wintermute/base/scriptables/script_ext_array.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script_engine.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
@@ -1259,6 +1260,21 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
return STATUS_OK;
}
+#ifdef ENABLE_FOXTAIL
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] RegistryFlush
+ // Return value is never used
+ // Used at SaveGameSettings() and Game.RegistryFlush()
+ // Called after a series of RegWriteNumber calls
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "RegistryFlush") == 0) {
+ stack->correctParams(0);
+ ConfMan.flushToDisk();
+ stack->pushNULL();
+ return STATUS_OK;
+ }
+#endif
+
//////////////////////////////////////////////////////////////////////////
// RegWriteNumber
//////////////////////////////////////////////////////////////////////////
@@ -1362,13 +1378,54 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
else if (strcmp(name, "GetSaveSlotDescription") == 0) {
stack->correctParams(1);
int slot = stack->pop()->getInt();
- char desc[512];
- desc[0] = '\0';
- SaveLoad::getSaveSlotDescription(slot, desc);
- stack->pushString(desc);
+ Common::String desc = SaveLoad::getSaveSlotDescription(slot);
+ stack->pushString(desc.c_str());
return STATUS_OK;
}
+#ifdef ENABLE_FOXTAIL
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] GetSaveSlotDescriptionTimestamp
+ // Return struct with "Description" and "Timestamp" fields in 1.2.362-
+ // Return array with "Description" and "Timestamp" items in 1.2.527+
+ // Timestamps should be comparable types
+ // Used to sort saved games by timestamps at save.script & load.script
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetSaveSlotDescriptionTimestamp") == 0) {
+ stack->correctParams(1);
+ int slot = stack->pop()->getInt();
+
+ TimeDate time;
+ SaveLoad::getSaveSlotTimestamp(slot, &time);
+ stack->pushInt(time.tm_sec);
+ stack->pushInt(time.tm_min);
+ stack->pushInt(time.tm_hour);
+ stack->pushInt(time.tm_mday);
+ stack->pushInt(time.tm_mon + 1);
+ stack->pushInt(time.tm_year + 1900);
+ stack->pushInt(6);
+ BaseScriptable *date = makeSXDate(_gameRef, stack);
+ stack->pushNative(date, false);
+
+ Common::String desc = SaveLoad::getSaveSlotDescription(slot);
+ stack->pushString(desc.c_str());
+
+ BaseScriptable *obj;
+ if (BaseEngine::instance().isFoxTail(FOXTAIL_1_2_527, FOXTAIL_LATEST_VERSION)) {
+ stack->pushInt(2);
+ obj = makeSXArray(_gameRef, stack);
+ } else {
+ stack->pushInt(0);
+ obj = makeSXObject(_gameRef, stack);
+ obj->scSetProperty("Description", stack->pop());
+ obj->scSetProperty("Timestamp", stack->pop());
+ }
+ stack->pushNative(obj, false);
+
+ return STATUS_OK;
+ }
+#endif
+
//////////////////////////////////////////////////////////////////////////
// EmptySaveSlot
//////////////////////////////////////////////////////////////////////////
@@ -1941,6 +1998,96 @@ bool BaseGame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack
return STATUS_OK;
}
+#ifdef ENABLE_FOXTAIL
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] GetScreenType
+ // Returns 0 on fullscreen and 1 on window
+ // Used to init and update controls at options.script and methods.script
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetScreenType") == 0) {
+ stack->correctParams(0);
+ int type = !g_system->getFeatureState(OSystem::kFeatureFullscreenMode);
+ stack->pushInt(type);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] GetScreenMode
+ // Returns integer to be used as a pixelization mode multiplier
+ // (e.g. it returns 2 for 640x360, 3 for 960x540, etc...)
+ // Used to init and update controls at options.script and methods.script
+ // This implementation always return 2 to fake window size of 2*320 x 2*180
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetScreenMode") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(2);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] GetDesktopDisplayMode
+ // Return struct with "w" and "h" fields in 1.2.362-
+ // Return array with "w" and "h" items in 1.2.527+
+ // Used to init and update controls at options.script and methods.script
+ // w,h of actual desktop size expected to calcucate maximum available size
+ // Available screen modes are calcucated as 2...N, N*320<w and N*180<h
+ // This implementation fakes available size as 2*320 x 2*180 only
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetDesktopDisplayMode") == 0) {
+ stack->correctParams(0);
+ stack->pushInt(2 * 180 + 1);
+ stack->pushInt(2 * 320 + 1);
+
+ BaseScriptable *obj;
+ if (BaseEngine::instance().isFoxTail(FOXTAIL_1_2_527, FOXTAIL_LATEST_VERSION)) {
+ stack->pushInt(2);
+ obj = makeSXArray(_gameRef, stack);
+ } else {
+ stack->pushInt(0);
+ obj = makeSXObject(_gameRef, stack);
+ obj->scSetProperty("w", stack->pop());
+ obj->scSetProperty("h", stack->pop());
+ }
+ stack->pushNative(obj, false);
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] SetScreenTypeMode
+ // This implementation ignores mode, toggles screen type only
+ // Used to change screen type&mode at options.script and methods.script
+ // Return value is never used
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "SetScreenTypeMode") == 0) {
+ stack->correctParams(2);
+ int type = stack->pop()->getInt();
+ stack->pop()->getInt(); //mode is unused
+ g_system->beginGFXTransaction();
+ g_system->setFeatureState(OSystem::kFeatureFullscreenMode, !type);
+ g_system->endGFXTransaction();
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] ChangeWindowGrab
+ // Used at game.script on "Keypress" event on F11
+ // Readme of FoxTail says: "F11 - free the mouse pointer from the window"
+ // This implementation does nothing
+ // Return value is never used
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ChangeWindowGrab") == 0) {
+ stack->correctParams(0);
+ stack->pushNULL();
+
+ return STATUS_OK;
+ }
+#endif
+
//////////////////////////////////////////////////////////////////////////
// ShowStatusLine
//////////////////////////////////////////////////////////////////////////
@@ -2329,6 +2476,123 @@ ScValue *BaseGame::scGetProperty(const Common::String &name) {
return _scValue;
}
+#ifdef ENABLE_FOXTAIL
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] SystemLanguage (RO)
+ // Returns Steam API language name string
+ //////////////////////////////////////////////////////////////////////////
+ else if (name == "SystemLanguage") {
+ switch (Common::parseLanguage(ConfMan.get("language"))) {
+ case Common::CZ_CZE:
+ _scValue->setString("czech");
+ break;
+ case Common::DA_DAN:
+ _scValue->setString("danish");
+ break;
+ case Common::DE_DEU:
+ _scValue->setString("german");
+ break;
+ case Common::ES_ESP:
+ _scValue->setString("spanish");
+ break;
+ case Common::FI_FIN:
+ _scValue->setString("finnish");
+ break;
+ case Common::FR_FRA:
+ _scValue->setString("french");
+ break;
+ case Common::GR_GRE:
+ _scValue->setString("greek");
+ break;
+ case Common::HU_HUN:
+ _scValue->setString("hungarian");
+ break;
+ case Common::IT_ITA:
+ _scValue->setString("italian");
+ break;
+ case Common::JA_JPN:
+ _scValue->setString("japanese");
+ break;
+ case Common::KO_KOR:
+ _scValue->setString("koreana");
+ break;
+ case Common::NB_NOR:
+ _scValue->setString("norwegian");
+ break;
+ case Common::NL_NLD:
+ _scValue->setString("dutch");
+ break;
+ case Common::PT_BRA:
+ _scValue->setString("brazilian");
+ break;
+ case Common::PT_POR:
+ _scValue->setString("portuguese");
+ break;
+ case Common::PL_POL:
+ _scValue->setString("polish");
+ break;
+ case Common::RU_RUS:
+ _scValue->setString("russian");
+ break;
+ case Common::SE_SWE:
+ _scValue->setString("swedish");
+ break;
+ case Common::UA_UKR:
+ _scValue->setString("ukrainian");
+ break;
+ case Common::ZH_CNA:
+ _scValue->setString("schinese");
+ break;
+ case Common::ZH_TWN:
+ _scValue->setString("tchinese");
+ break;
+ default:
+ _scValue->setString("english");
+ break;
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] BuildVersion (RO)
+ // Used to display full game version at options.script in UpdateControls()
+ // Returns FoxTail engine version number as a dotted string
+ //////////////////////////////////////////////////////////////////////////
+ else if (name == "BuildVersion") {
+ if (BaseEngine::instance().getTargetExecutable() == FOXTAIL_1_2_227) {
+ _scValue->setString("1.2.227");
+ } else if (BaseEngine::instance().getTargetExecutable() == FOXTAIL_1_2_230) {
+ _scValue->setString("1.2.230");
+ } else if (BaseEngine::instance().getTargetExecutable() == FOXTAIL_1_2_304) {
+ _scValue->setString("1.2.304");
+ } else if (BaseEngine::instance().getTargetExecutable() == FOXTAIL_1_2_362) {
+ _scValue->setString("1.2.362");
+ } else if (BaseEngine::instance().getTargetExecutable() == FOXTAIL_1_2_527) {
+ _scValue->setString("1.2.527");
+ } else {
+ _scValue->setString("UNKNOWN");
+ }
+ return _scValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] GameVersion (RO)
+ // Used to display full game version at options.script in UpdateControls()
+ // Returns FoxTail version number as a string
+ //////////////////////////////////////////////////////////////////////////
+ else if (name == "GameVersion") {
+ uint32 gameVersion = 0;
+ BaseFileManager *fileManager = BaseEngine::instance().getFileManager();
+ if (fileManager) {
+ gameVersion = fileManager->getPackageVersion("data.dcp");
+ }
+ char tmp[16];
+ sprintf(tmp,"%u",gameVersion);
+ _scValue->setString(tmp);
+ return _scValue;
+ }
+#endif
+
//////////////////////////////////////////////////////////////////////////
// Platform (RO)
//////////////////////////////////////////////////////////////////////////
@@ -2997,6 +3261,44 @@ bool BaseGame::externalCall(ScScript *script, ScStack *stack, ScStack *thisStack
stack->pushBool(val);
}
+#ifdef ENABLE_FOXTAIL
+ //////////////////////////////////////////////////////////////////////////
+ // [FoxTail] Split
+ // Returns array of words of a string, using another as a delimeter
+ // Used to split strings by 1 character delimeter in various scripts
+ // All the delimeters ever used in FoxTail are: " ", "@", "#", "$", "&"
+ // So, this implementation takes 1st char of delimeter string only
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Split") == 0) {
+ stack->correctParams(2);
+ const char *str = stack->pop()->getString();
+ const char sep = stack->pop()->getString()[0];
+ size_t size = strlen(str) + 1;
+
+ // There is no way to makeSXArray() with exactly 1 given element
+ // That's why we are creating empty Array and SXArray::push() later
+ stack->pushInt(0);
+ BaseScriptable *arr = makeSXArray(_gameRef, stack);
+
+ // Iterating string copy, replacing delimeter with '\0' and pushing matches
+ char *copy = new char[size];
+ strcpy(copy, str);
+ char *begin = copy;
+ for (char *it = copy; it < copy + size; it++) {
+ if (*it == sep || *it == '\0') {
+ *it = '\0';
+ stack->pushString(begin);
+ ((SXArray *)arr)->push(stack->pop());
+ begin = it + 1;
+ }
+ }
+
+ stack->pushNative(arr, false);
+
+ delete[] copy;
+ }
+#endif
+
//////////////////////////////////////////////////////////////////////////
// failure
else {