diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/wintermute/BGame.cpp | 77 | ||||
-rw-r--r-- | engines/wintermute/BGame.h | 32 | ||||
-rw-r--r-- | engines/wintermute/BRenderSDL.h | 3 | ||||
-rw-r--r-- | engines/wintermute/BScriptHolder.h | 2 | ||||
-rw-r--r-- | engines/wintermute/crc.h | 81 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SXFile.cpp | 720 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SXFile.h | 60 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SXStore.cpp | 508 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SXStore.h | 172 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SXString.cpp | 387 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SXString.h | 58 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SxObject.cpp | 60 | ||||
-rw-r--r-- | engines/wintermute/scriptables/SxObject.h | 44 |
13 files changed, 2141 insertions, 63 deletions
diff --git a/engines/wintermute/BGame.cpp b/engines/wintermute/BGame.cpp index 319e0c5316..a076477b04 100644 --- a/engines/wintermute/BGame.cpp +++ b/engines/wintermute/BGame.cpp @@ -27,43 +27,46 @@ */
#include <time.h>
-#include "dcgf.h"
-#include "BGame.h"
-#include "BFile.h"
-#include "BFileManager.h"
-#include "BFontTT.h"
-#include "BFontStorage.h"
-#include "BImage.h"
-#include "BKeyboardState.h"
-#include "BParser.h"
-#include "BQuickMsg.h"
-#include "BRegistry.h"
-#include "BRenderSDL.h"
-#include "BSound.h"
-#include "BSoundMgr.h"
-#include "BSprite.h"
-#include "BSubFrame.h"
-#include "BSurfaceSDL.h"
-#include "BTransitionMgr.h"
-#include "BViewport.h"
-#include "BStringTable.h"
-#include "BRegion.h"
-#include "crc.h"
-#include "PathUtil.h"
-#include "StringUtil.h"
-#include "UIWindow.h"
-#include "scriptables/ScValue.h"
-#include "scriptables/ScEngine.h"
-#include "scriptables/ScStack.h"
-#include "scriptables/ScScript.h"
-#include "scriptables/SXArray.h"
-#include "scriptables/SXDate.h"
-#include "scriptables/SXString.h"
-#include "scriptables/SXMemBuffer.h"
-#include "scriptables/SxObject.h"
-#include "scriptables/SXFile.h"
-#include "scriptables/SXMath.h"
-#include "scriptables/SXStore.h"
+#include "engines/wintermute/dcgf.h"
+#include "engines/wintermute/BGame.h"
+#include "engines/wintermute/BFader.h"
+#include "engines/wintermute/BFile.h"
+#include "engines/wintermute/BFileManager.h"
+#include "engines/wintermute/BFontTT.h"
+#include "engines/wintermute/BFontStorage.h"
+#include "engines/wintermute/BImage.h"
+#include "engines/wintermute/BKeyboardState.h"
+#include "engines/wintermute/BParser.h"
+#include "engines/wintermute/BQuickMsg.h"
+#include "engines/wintermute/BRegistry.h"
+#include "engines/wintermute/BRenderSDL.h"
+#include "engines/wintermute/BSound.h"
+#include "engines/wintermute/BSoundMgr.h"
+#include "engines/wintermute/BSprite.h"
+#include "engines/wintermute/BSubFrame.h"
+#include "engines/wintermute/BSurfaceSDL.h"
+#include "engines/wintermute/BTransitionMgr.h"
+#include "engines/wintermute/BViewport.h"
+#include "engines/wintermute/BStringTable.h"
+#include "engines/wintermute/BRegion.h"
+#include "engines/wintermute/BSaveThumbHelper.h"
+#include "engines/wintermute/BSurfaceStorage.h"
+#include "engines/wintermute/crc.h"
+#include "engines/wintermute/PathUtil.h"
+#include "engines/wintermute/StringUtil.h"
+#include "engines/wintermute/UIWindow.h"
+#include "engines/wintermute/scriptables/ScValue.h"
+#include "engines/wintermute/scriptables/ScEngine.h"
+#include "engines/wintermute/scriptables/ScStack.h"
+#include "engines/wintermute/scriptables/ScScript.h"
+#include "engines/wintermute/scriptables/SXArray.h"
+#include "engines/wintermute/scriptables/SXDate.h"
+#include "engines/wintermute/scriptables/SXFile.h"
+#include "engines/wintermute/scriptables/SXMemBuffer.h"
+#include "engines/wintermute/scriptables/SxObject.h"
+#include "engines/wintermute/scriptables/SXMath.h"
+#include "engines/wintermute/scriptables/SXStore.h"
+#include "engines/wintermute/scriptables/SXString.h"
#include "common/textconsole.h"
#ifdef __IPHONEOS__
diff --git a/engines/wintermute/BGame.h b/engines/wintermute/BGame.h index 8b74b2d618..208b5b414b 100644 --- a/engines/wintermute/BGame.h +++ b/engines/wintermute/BGame.h @@ -89,10 +89,8 @@ public: uint32 m_LastMiniUpdate;
bool m_MiniUpdateEnabled;
- virtual HRESULT MiniUpdate() {} // <- TODO Unstub
-#if 0
virtual HRESULT MiniUpdate();
-#endif
+
void GetMousePos(POINT *Pos);
RECT m_MouseLockRect;
@@ -103,7 +101,7 @@ public: bool m_SuspendedRendering;
int m_SoundBufferSizeSec;
-#if 0
+
TTextEncoding m_TextEncoding;
bool m_TextRTL;
@@ -116,7 +114,6 @@ public: void DEBUG_DumpClassRegistry();
HRESULT SetWaitCursor(char *Filename);
-
char *m_LocalSaveDir;
bool m_SaveDirChecked;
@@ -152,7 +149,6 @@ public: void SetEngineLogCallback(ENGINE_LOG_CALLBACK Callback = NULL, void *Data = NULL);
ENGINE_LOG_CALLBACK m_EngineLogCallback;
void *m_EngineLogCallbackData;
-#endif
bool m_EditorMode;
bool m_DoNotExpandStrings;
@@ -164,10 +160,9 @@ public: float m_OffsetPercentX;
float m_OffsetPercentY;
CBObject *m_MainObject;
-#if 0
+
HRESULT InitInput(HINSTANCE hInst, HWND hWnd);
HRESULT InitLoop();
-#endif
uint32 m_CurrentTime;
uint32 m_DeltaTime;
CBFont *m_SystemFont;
@@ -178,8 +173,8 @@ public: CBFileManager *m_FileManager;
CBTransitionMgr *m_TransMgr;
CBDebugger *GetDebugMgr();
-//TODO: STUB
- void LOG(HRESULT res, LPCSTR fmt, ...) {}
+
+ void LOG(HRESULT res, LPCSTR fmt, ...);
CBRenderer *m_Renderer;
CBSoundMgr *m_SoundMgr;
@@ -195,7 +190,7 @@ public: void DEBUG_DebugEnable(const char *Filename = NULL);
bool m_DEBUG_DebugMode;
bool m_DEBUG_AbsolutePathWarning;
-#if 0
+
FILE *m_DEBUG_LogFile;
int m_Sequence;
virtual HRESULT LoadFile(const char *Filename);
@@ -203,7 +198,7 @@ public: CBArray<CBQuickMsg *, CBQuickMsg *> m_QuickMessages;
CBArray<CUIWindow *, CUIWindow *> m_Windows;
CBArray<CBViewport *, CBViewport *> m_ViewportStack;
-#endif
+
int m_ViewportSP;
bool m_MouseLeftDown;
bool m_MouseRightDown;
@@ -278,7 +273,7 @@ public: static void AfterLoadFont(void *Font, void *Data);
static void AfterLoadScript(void *script, void *data);
static void InvalidateValues(void *Value, void *Data);
-#if 0
+
HRESULT LoadSettings(char *Filename);
HRESULT ResumeMusic(int Channel);
HRESULT SetMusicStartTime(int Channel, uint32 Time);
@@ -293,7 +288,6 @@ public: int m_MusicCrossfadeChannel1;
int m_MusicCrossfadeChannel2;
HRESULT DisplayWindows(bool InGame = false);
-#endif
CBRegistry *m_Registry;
bool m_UseD3D;
virtual HRESULT Cleanup();
@@ -323,14 +317,12 @@ public: HRESULT UnregisterObject(CBObject *Object);
HRESULT RegisterObject(CBObject *Object);
void QuickMessage(char *Text);
-#if 0
void QuickMessageForm(LPSTR fmt, ...);
HRESULT DisplayQuickMsg();
uint32 m_Fps;
HRESULT UpdateMusicCrossfade();
CBArray<CBObject *, CBObject *> m_RegObjects;
-#endif
public:
virtual HRESULT DisplayContent(bool Update = true, bool DisplayAll = false);
virtual HRESULT DisplayContentSimple();
@@ -338,30 +330,23 @@ public: void ResetMousePos();
int m_SubtitlesSpeed;
void SetInteractive(bool State);
-#if 0
virtual HRESULT WindowLoadHook(CUIWindow *Win, char **Buf, char **Params);
virtual HRESULT WindowScriptMethodHook(CUIWindow *Win, CScScript *Script, CScStack *Stack, char *Name);
-#endif
HRESULT GetCurrentViewportOffset(int *OffsetX = NULL, int *OffsetY = NULL);
HRESULT GetCurrentViewportRect(RECT *Rect, bool *Custom = NULL);
HRESULT PopViewport();
HRESULT PushViewport(CBViewport *Viewport);
HRESULT SetActiveObject(CBObject *Obj);
-#if 0
CBSprite *m_LastCursor;
HRESULT DrawCursor(CBSprite *Cursor);
virtual HRESULT InitAfterLoad();
-#endif
CBSaveThumbHelper *m_CachedThumbnail;
-#if 0
AnsiString GetDataDir();
-#endif
void AddMem(int bytes);
bool m_TouchInterface;
bool m_ConstrainedMemory;
-#if 0
AnsiString GetDeviceType() const;
private:
@@ -392,7 +377,6 @@ protected: public:
void AutoSaveOnExit();
-#endif
};
diff --git a/engines/wintermute/BRenderSDL.h b/engines/wintermute/BRenderSDL.h index 3489881e14..11a969946e 100644 --- a/engines/wintermute/BRenderSDL.h +++ b/engines/wintermute/BRenderSDL.h @@ -32,6 +32,9 @@ #include "BRenderer.h"
#include "SDL.h"
+class SDL_Window;
+class SDL_Renderer;
+
namespace WinterMute {
class CBRenderSDL : public CBRenderer {
diff --git a/engines/wintermute/BScriptHolder.h b/engines/wintermute/BScriptHolder.h index 84a1e73c46..e4a4c0f6f6 100644 --- a/engines/wintermute/BScriptHolder.h +++ b/engines/wintermute/BScriptHolder.h @@ -58,14 +58,12 @@ public: bool m_Ready;
CBArray<CScScript *, CScScript *> m_Scripts;
-#if 0
// scripting interface
virtual CScValue *ScGetProperty(char *Name);
virtual HRESULT ScSetProperty(char *Name, CScValue *Value);
virtual HRESULT ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name);
virtual char *ScToString();
virtual void ScDebuggerDesc(char *Buf, int BufSize);
-#endif
// IWmeObject
public:
virtual bool SendEvent(const char *EventName);
diff --git a/engines/wintermute/crc.h b/engines/wintermute/crc.h new file mode 100644 index 0000000000..578b423de8 --- /dev/null +++ b/engines/wintermute/crc.h @@ -0,0 +1,81 @@ +/**********************************************************************
+ *
+ * Filename: crc.h
+ *
+ * Description: A header file describing the various CRC standards.
+ *
+ * Notes:
+ *
+ *
+ * Copyright (c) 2000 by Michael Barr. This software is placed into
+ * the public domain and may be used for any purpose. However, this
+ * notice must not be changed or removed and no warranty is either
+ * expressed or implied by its publication or distribution.
+ **********************************************************************/
+
+#ifndef _crc_h
+#define _crc_h
+
+#ifndef TRUE
+#define FALSE 0
+#define TRUE !FALSE
+#endif
+
+/*
+ * Select the CRC standard from the list that follows.
+ */
+#define CRC32
+
+
+#if defined(CRC_CCITT)
+
+typedef unsigned short crc;
+
+#define CRC_NAME "CRC-CCITT"
+#define POLYNOMIAL 0x1021
+#define INITIAL_REMAINDER 0xFFFF
+#define FINAL_XOR_VALUE 0x0000
+#define REFLECT_DATA FALSE
+#define REFLECT_REMAINDER FALSE
+#define CHECK_VALUE 0x29B1
+
+#elif defined(CRC16)
+
+typedef unsigned short crc;
+
+#define CRC_NAME "CRC-16"
+#define POLYNOMIAL 0x8005
+#define INITIAL_REMAINDER 0x0000
+#define FINAL_XOR_VALUE 0x0000
+#define REFLECT_DATA TRUE
+#define REFLECT_REMAINDER TRUE
+#define CHECK_VALUE 0xBB3D
+
+#elif defined(CRC32)
+
+typedef unsigned long crc;
+
+#define CRC_NAME "CRC-32"
+#define POLYNOMIAL 0x04C11DB7
+#define INITIAL_REMAINDER 0xFFFFFFFF
+#define FINAL_XOR_VALUE 0xFFFFFFFF
+#define REFLECT_DATA TRUE
+#define REFLECT_REMAINDER TRUE
+#define CHECK_VALUE 0xCBF43926
+
+#else
+
+#error "One of CRC_CCITT, CRC16, or CRC32 must be #define'd."
+
+#endif
+
+void crcInit(void);
+crc crcSlow(unsigned char const message[], int nBytes);
+crc crcFast(unsigned char const message[], int nBytes);
+
+extern "C" crc crc_initialize(void);
+extern "C" crc crc_process_byte(unsigned char byte, crc remainder);
+extern "C" crc crc_finalize(crc remainder);
+
+
+#endif /* _crc_h */
diff --git a/engines/wintermute/scriptables/SXFile.cpp b/engines/wintermute/scriptables/SXFile.cpp new file mode 100644 index 0000000000..7615d3a01f --- /dev/null +++ b/engines/wintermute/scriptables/SXFile.cpp @@ -0,0 +1,720 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "SysClassRegistry.h"
+#include "SysClass.h"
+#include "ScStack.h"
+#include "ScValue.h"
+#include "ScScript.h"
+#include "utils.h"
+#include "BGame.h"
+#include "BFile.h"
+#include "BFileManager.h"
+#include "PlatformSDL.h"
+#include "scriptables/SXFile.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CSXFile, false)
+
+//////////////////////////////////////////////////////////////////////////
+CSXFile::CSXFile(CBGame *inGame, CScStack *Stack): CBScriptable(inGame) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+
+ m_Filename = NULL;
+ if (!Val->IsNULL()) CBUtils::SetString(&m_Filename, Val->GetString());
+
+ m_ReadFile = NULL;
+ m_WriteFile = NULL;
+
+ m_Mode = 0;
+ m_TextMode = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CSXFile::~CSXFile() {
+ Cleanup();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXFile::Cleanup() {
+ delete[] m_Filename;
+ m_Filename = NULL;
+ Close();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CSXFile::Close() {
+ if (m_ReadFile) {
+ Game->m_FileManager->CloseFile(m_ReadFile);
+ m_ReadFile = NULL;
+ }
+ if (m_WriteFile) {
+ fclose(m_WriteFile);
+ m_WriteFile = NULL;
+ }
+ m_Mode = 0;
+ m_TextMode = false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+char *CSXFile::ScToString() {
+ if (m_Filename) return m_Filename;
+ else return "[file object]";
+}
+
+#define FILE_BUFFER_SIZE 32768
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXFile::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ //////////////////////////////////////////////////////////////////////////
+ // SetFilename
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "SetFilename") == 0) {
+ Stack->CorrectParams(1);
+ char *Filename = Stack->Pop()->GetString();
+ Cleanup();
+ CBUtils::SetString(&m_Filename, Filename);
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OpenAsText / OpenAsBinary
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "OpenAsText") == 0 || strcmp(Name, "OpenAsBinary") == 0) {
+ Stack->CorrectParams(1);
+ Close();
+ m_Mode = Stack->Pop()->GetInt(1);
+ if (m_Mode < 1 || m_Mode > 3) {
+ Script->RuntimeError("File.%s: invalid access mode. Setting read mode.", Name);
+ m_Mode = 1;
+ }
+ if (m_Mode == 1) {
+ m_ReadFile = Game->m_FileManager->OpenFile(m_Filename);
+ if (!m_ReadFile) {
+ //Script->RuntimeError("File.%s: Error opening file '%s' for reading.", Name, m_Filename);
+ Close();
+ } else m_TextMode = strcmp(Name, "OpenAsText") == 0;
+ } else {
+ if (strcmp(Name, "OpenAsText") == 0) {
+ if (m_Mode == 2) m_WriteFile = fopen(m_Filename, "w+");
+ else m_WriteFile = fopen(m_Filename, "a+");
+ } else {
+ if (m_Mode == 2) m_WriteFile = fopen(m_Filename, "wb+");
+ else m_WriteFile = fopen(m_Filename, "ab+");
+ }
+
+ if (!m_WriteFile) {
+ //Script->RuntimeError("File.%s: Error opening file '%s' for writing.", Name, m_Filename);
+ Close();
+ } else m_TextMode = strcmp(Name, "OpenAsText") == 0;
+ }
+
+ if (m_ReadFile || m_WriteFile) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Close
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Close") == 0) {
+ Stack->CorrectParams(0);
+ Close();
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetPosition
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetPosition") == 0) {
+ Stack->CorrectParams(1);
+ if (m_Mode == 0) {
+ Script->RuntimeError("File.%s: File is not open", Name);
+ Stack->PushBool(false);
+ } else {
+ int Pos = Stack->Pop()->GetInt();
+ Stack->PushBool(SetPos(Pos));
+ }
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Delete
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Delete") == 0) {
+ Stack->CorrectParams(0);
+ Close();
+ Stack->PushBool(CBPlatform::DeleteFile(m_Filename) != FALSE);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Copy
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Copy") == 0) {
+ Stack->CorrectParams(2);
+ char *Dest = Stack->Pop()->GetString();
+ bool Overwrite = Stack->Pop()->GetBool(true);
+
+ Close();
+ Stack->PushBool(CBPlatform::CopyFile(m_Filename, Dest, !Overwrite) != FALSE);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadLine
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadLine") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open in text mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ uint32 BufSize = FILE_BUFFER_SIZE;
+ byte *Buf = (byte *)malloc(BufSize);
+ uint32 Counter = 0;
+ byte b;
+ bool FoundNewLine = false;
+ HRESULT Ret = E_FAIL;
+ do {
+ Ret = m_ReadFile->Read(&b, 1);
+ if (FAILED(Ret)) break;
+
+ if (Counter > BufSize) {
+ Buf = (byte *)realloc(Buf, BufSize + FILE_BUFFER_SIZE);
+ BufSize += FILE_BUFFER_SIZE;
+ }
+ if (b == '\n') {
+ Buf[Counter] = '\0';
+ FoundNewLine = true;
+ break;
+ } else if (b == 0x0D) continue;
+ else {
+ Buf[Counter] = b;
+ Counter++;
+ }
+ } while (SUCCEEDED(Ret));
+
+ if (Counter > BufSize) {
+ Buf = (byte *)realloc(Buf, BufSize + FILE_BUFFER_SIZE);
+ BufSize += FILE_BUFFER_SIZE;
+ }
+ Buf[Counter] = '\0';
+
+ if (!FoundNewLine && Counter == 0) Stack->PushNULL();
+ else Stack->PushString((char *)Buf);
+
+ free(Buf);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadText
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadText") == 0) {
+ Stack->CorrectParams(1);
+ int TextLen = Stack->Pop()->GetInt();
+
+ if (!m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open in text mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ uint32 BufSize = FILE_BUFFER_SIZE;
+ byte *Buf = (byte *)malloc(BufSize);
+ uint32 Counter = 0;
+ byte b;
+
+ HRESULT Ret = E_FAIL;
+ while (Counter < TextLen) {
+ Ret = m_ReadFile->Read(&b, 1);
+ if (FAILED(Ret)) break;
+
+ if (Counter > BufSize) {
+ Buf = (byte *)realloc(Buf, BufSize + FILE_BUFFER_SIZE);
+ BufSize += FILE_BUFFER_SIZE;
+ }
+ if (b == 0x0D) continue;
+ else {
+ Buf[Counter] = b;
+ Counter++;
+ }
+ }
+
+ if (Counter > BufSize) {
+ Buf = (byte *)realloc(Buf, BufSize + FILE_BUFFER_SIZE);
+ BufSize += FILE_BUFFER_SIZE;
+ }
+ Buf[Counter] = '\0';
+
+ if (TextLen > 0 && Counter == 0) Stack->PushNULL();
+ else Stack->PushString((char *)Buf);
+
+ free(Buf);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteLine / WriteText
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteLine") == 0 || strcmp(Name, "WriteText") == 0) {
+ Stack->CorrectParams(1);
+ char *Line = Stack->Pop()->GetString();
+ if (!m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in text mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ if (strcmp(Name, "WriteLine") == 0)
+ fprintf(m_WriteFile, "%s\n", Line);
+ else
+ fprintf(m_WriteFile, "%s", Line);
+
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////////////
+ // ReadBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadBool") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ bool Val;
+ if (SUCCEEDED(m_ReadFile->Read(&Val, sizeof(bool)))) Stack->PushBool(Val);
+ else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadByte
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadByte") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ byte Val;
+ if (SUCCEEDED(m_ReadFile->Read(&Val, sizeof(byte )))) Stack->PushInt(Val);
+ else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadShort
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadShort") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ short Val;
+ if (SUCCEEDED(m_ReadFile->Read(&Val, sizeof(short)))) Stack->PushInt(65536 + Val);
+ else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadInt / ReadLong
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadInt") == 0 || strcmp(Name, "ReadLong") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ int Val;
+ if (SUCCEEDED(m_ReadFile->Read(&Val, sizeof(int)))) Stack->PushInt(Val);
+ else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadFloat") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ float Val;
+ if (SUCCEEDED(m_ReadFile->Read(&Val, sizeof(float)))) Stack->PushFloat(Val);
+ else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadDouble
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadDouble") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ double Val;
+ if (SUCCEEDED(m_ReadFile->Read(&Val, sizeof(double)))) Stack->PushFloat(Val);
+ else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ReadString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ReadString") == 0) {
+ Stack->CorrectParams(0);
+ if (m_TextMode || !m_ReadFile) {
+ Script->RuntimeError("File.%s: File must be open for reading in binary mode.", Name);
+ Stack->PushNULL();
+ return S_OK;
+ }
+ uint32 Size;
+ if (SUCCEEDED(m_ReadFile->Read(&Size, sizeof(uint32)))) {
+ byte *Str = new byte[Size + 1];
+ if (Str) {
+ if (SUCCEEDED(m_ReadFile->Read(Str, Size))) {
+ Str[Size] = '\0';
+ Stack->PushString((char *)Str);
+ }
+ delete [] Str;
+ } else Stack->PushNULL();
+ } else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteBool") == 0) {
+ Stack->CorrectParams(1);
+ bool Val = Stack->Pop()->GetBool();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ fwrite(&Val, sizeof(Val), 1, m_WriteFile);
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteByte
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteByte") == 0) {
+ Stack->CorrectParams(1);
+ byte Val = Stack->Pop()->GetInt();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ fwrite(&Val, sizeof(Val), 1, m_WriteFile);
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteShort
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteShort") == 0) {
+ Stack->CorrectParams(1);
+ short Val = Stack->Pop()->GetInt();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ fwrite(&Val, sizeof(Val), 1, m_WriteFile);
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteInt / WriteLong
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteInt") == 0 || strcmp(Name, "WriteLong") == 0) {
+ Stack->CorrectParams(1);
+ int Val = Stack->Pop()->GetInt();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ fwrite(&Val, sizeof(Val), 1, m_WriteFile);
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteFloat") == 0) {
+ Stack->CorrectParams(1);
+ float Val = Stack->Pop()->GetFloat();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ fwrite(&Val, sizeof(Val), 1, m_WriteFile);
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteDouble
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteDouble") == 0) {
+ Stack->CorrectParams(1);
+ double Val = Stack->Pop()->GetFloat();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+ fwrite(&Val, sizeof(Val), 1, m_WriteFile);
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WriteString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WriteString") == 0) {
+ Stack->CorrectParams(1);
+ char *Val = Stack->Pop()->GetString();
+
+ if (m_TextMode || !m_WriteFile) {
+ Script->RuntimeError("File.%s: File must be open for writing in binary mode.", Name);
+ Stack->PushBool(false);
+ return S_OK;
+ }
+
+ uint32 Size = strlen(Val);
+ fwrite(&Size, sizeof(Size), 1, m_WriteFile);
+ fwrite(Val, Size, 1, m_WriteFile);
+
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+
+ else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CSXFile::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("file");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Filename (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Filename") == 0) {
+ m_ScValue->SetString(m_Filename);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Position (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Position") == 0) {
+ m_ScValue->SetInt(GetPos());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Length (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Length") == 0) {
+ m_ScValue->SetInt(GetLength());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TextMode (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "TextMode") == 0) {
+ m_ScValue->SetBool(m_TextMode);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccessMode (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccessMode") == 0) {
+ m_ScValue->SetInt(m_Mode);
+ return m_ScValue;
+ }
+
+ else return CBScriptable::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXFile::ScSetProperty(char *Name, CScValue *Value) {
+ /*
+ //////////////////////////////////////////////////////////////////////////
+ // Length
+ //////////////////////////////////////////////////////////////////////////
+ if(strcmp(Name, "Length")==0){
+ int OrigLength = m_Length;
+ m_Length = max(Value->GetInt(0), 0);
+
+ char PropName[20];
+ if(m_Length < OrigLength){
+ for(int i=m_Length; i<OrigLength; i++){
+ sprintf(PropName, "%d", i);
+ m_Values->DeleteProp(PropName);
+ }
+ }
+ return S_OK;
+ }
+ else*/ return CBScriptable::ScSetProperty(Name, Value);
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CSXFile::GetPos() {
+ if (m_Mode == 1 && m_ReadFile) return m_ReadFile->GetPos();
+ else if ((m_Mode == 2 || m_Mode == 3) && m_WriteFile) return ftell(m_WriteFile);
+ else return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CSXFile::SetPos(uint32 Pos, TSeek Origin) {
+ if (m_Mode == 1 && m_ReadFile) return SUCCEEDED(m_ReadFile->Seek(Pos, Origin));
+ else if ((m_Mode == 2 || m_Mode == 3) && m_WriteFile) return fseek(m_WriteFile, Pos, (int)Origin) == 0;
+ else return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CSXFile::GetLength() {
+ if (m_Mode == 1 && m_ReadFile) return m_ReadFile->GetSize();
+ else if ((m_Mode == 2 || m_Mode == 3) && m_WriteFile) {
+ uint32 CurrentPos = ftell(m_WriteFile);
+ fseek(m_WriteFile, 0, SEEK_END);
+ int Ret = ftell(m_WriteFile);
+ fseek(m_WriteFile, CurrentPos, SEEK_SET);
+ return Ret;
+ } else return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXFile::Persist(CBPersistMgr *PersistMgr) {
+
+ CBScriptable::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_Filename));
+ PersistMgr->Transfer(TMEMBER(m_Mode));
+ PersistMgr->Transfer(TMEMBER(m_TextMode));
+
+ uint32 Pos = 0;
+ if (PersistMgr->m_Saving) {
+ Pos = GetPos();
+ PersistMgr->Transfer(TMEMBER(Pos));
+ } else {
+ PersistMgr->Transfer(TMEMBER(Pos));
+
+ // try to re-open file if needed
+ m_WriteFile = NULL;
+ m_ReadFile = NULL;
+
+ if (m_Mode != 0) {
+ // open for reading
+ if (m_Mode == 1) {
+ m_ReadFile = Game->m_FileManager->OpenFile(m_Filename);
+ if (!m_ReadFile) Close();
+ }
+ // open for writing / appending
+ else {
+ if (m_TextMode) {
+ if (m_Mode == 2) m_WriteFile = fopen(m_Filename, "w+");
+ else m_WriteFile = fopen(m_Filename, "a+");
+ } else {
+ if (m_Mode == 2) m_WriteFile = fopen(m_Filename, "wb+");
+ else m_WriteFile = fopen(m_Filename, "ab+");
+ }
+ if (m_WriteFile) Close();
+ }
+ SetPos(Pos);
+ }
+ }
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/scriptables/SXFile.h b/engines/wintermute/scriptables/SXFile.h new file mode 100644 index 0000000000..0ab1acb32c --- /dev/null +++ b/engines/wintermute/scriptables/SXFile.h @@ -0,0 +1,60 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef __WmeSXFile_H__
+#define __WmeSXFile_H__
+
+
+#include "engines/wintermute/BScriptable.h"
+
+namespace WinterMute {
+
+class CBFile;
+
+class CSXFile : public CBScriptable {
+public:
+ DECLARE_PERSISTENT(CSXFile, CBScriptable)
+ CScValue *ScGetProperty(char *Name);
+ HRESULT ScSetProperty(char *Name, CScValue *Value);
+ HRESULT ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name);
+ char *ScToString();
+ CSXFile(CBGame *inGame, CScStack *Stack);
+ virtual ~CSXFile();
+private:
+ CBFile *m_ReadFile;
+ FILE *m_WriteFile;
+ int m_Mode; // 0..none, 1..read, 2..write, 3..append
+ bool m_TextMode;
+ void Close();
+ void Cleanup();
+ uint32 GetPos();
+ uint32 GetLength();
+ bool SetPos(uint32 Pos, TSeek Origin = SEEK_TO_BEGIN);
+ char *m_Filename;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/scriptables/SXStore.cpp b/engines/wintermute/scriptables/SXStore.cpp new file mode 100644 index 0000000000..50c970d41a --- /dev/null +++ b/engines/wintermute/scriptables/SXStore.cpp @@ -0,0 +1,508 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "BGame.h"
+#include "BRegistry.h"
+#include "scriptables/SXStore.h"
+#include "ScValue.h"
+#include "ScScript.h"
+#include "ScStack.h"
+#include "StringUtil.h"
+
+#ifdef __IPHONEOS__
+# include "IOS_StoreKit_interface.h"
+#endif
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CSXStore, false)
+
+//////////////////////////////////////////////////////////////////////////
+CSXStore::CSXStore(CBGame *inGame) : CBObject(inGame) {
+#ifdef __IPHONEOS__
+ StoreKit_SetExternalData((void *)this);
+#endif
+
+ m_EventsEnabled = false;
+ m_LastProductRequestOwner = NULL;
+ m_LastPurchaseOwner = NULL;
+ m_LastRestoreOwner = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CSXStore::~CSXStore() {
+ Cleanup();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::Cleanup() {
+ SetEventsEnabled(NULL, false);
+
+ for (int i = 0; i < m_ValidProducts.GetSize(); i++) {
+ delete m_ValidProducts[i];
+ }
+ m_ValidProducts.RemoveAll();
+
+
+ for (int i = 0; i < m_Transactions.GetSize(); i++) {
+ delete m_Transactions[i];
+ }
+ m_Transactions.RemoveAll();
+
+
+ m_LastProductRequestOwner = m_LastPurchaseOwner = m_LastRestoreOwner = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXStore::ScCallMethod(CScScript *script, CScStack *stack, CScStack *thisStack, char *name) {
+ //////////////////////////////////////////////////////////////////////////
+ // EnableEvents
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "EnableEvents") == 0) {
+ stack->CorrectParams(0);
+ SetEventsEnabled(script, true);
+ stack->PushBool(GetEventsEnabled() == true);
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // DisableEvents
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "DisableEvents") == 0) {
+ stack->CorrectParams(0);
+ SetEventsEnabled(script, false);
+ stack->PushBool(GetEventsEnabled() == false);
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // ValidateProducts
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "ValidateProducts") == 0) {
+ stack->CorrectParams(1);
+ char *prodIdList = stack->Pop()->GetString();
+ m_LastProductRequestOwner = script->m_Owner;
+ ValidateProducts(prodIdList);
+ stack->PushNULL();
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetValidProduct
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetValidProduct") == 0) {
+ stack->CorrectParams(1);
+ int index = stack->Pop()->GetInt();
+ if (index >= 0 && index < m_ValidProducts.GetSize()) {
+ CScValue *prod = stack->GetPushValue();
+ if (prod) {
+ prod->SetProperty("Id", m_ValidProducts[index]->GetId());
+ prod->SetProperty("Name", m_ValidProducts[index]->GetName());
+ prod->SetProperty("Description", m_ValidProducts[index]->GetDesc());
+ prod->SetProperty("Price", m_ValidProducts[index]->GetPrice());
+ }
+ } else
+ stack->PushNULL();
+
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetInvalidProduct
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetInvalidProduct") == 0) {
+ stack->CorrectParams(1);
+ int index = stack->Pop()->GetInt();
+ if (index >= 0 && index < m_InvalidProducts.size())
+ stack->PushString(m_InvalidProducts[index].c_str());
+ else
+ stack->PushNULL();
+
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // GetTransaction
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "GetTransaction") == 0) {
+ stack->CorrectParams(1);
+ int index = stack->Pop()->GetInt();
+ if (index >= 0 && index < m_Transactions.GetSize()) {
+ CScValue *trans = stack->GetPushValue();
+ if (trans) {
+ trans->SetProperty("Id", m_Transactions[index]->GetId());
+ trans->SetProperty("ProductId", m_Transactions[index]->GetProductId());
+ trans->SetProperty("State", m_Transactions[index]->GetState());
+ }
+ } else
+ stack->PushNULL();
+
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Purchase
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Purchase") == 0) {
+ stack->CorrectParams(1);
+ char *prodId = stack->Pop()->GetString();
+ stack->PushBool(Purchase(script, prodId));
+
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // FinishTransaction
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "FinishTransaction") == 0) {
+ stack->CorrectParams(1);
+ char *transId = stack->Pop()->GetString();
+ stack->PushBool(FinishTransaction(script, transId));
+
+ return S_OK;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // RestoreTransactions
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "RestoreTransactions") == 0) {
+ stack->CorrectParams(0);
+ RestoreTransactions(script);
+ stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // UnlockProduct
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "UnlockProduct") == 0) {
+ stack->CorrectParams(1);
+ char *prodId = stack->Pop()->GetString();
+
+ Game->m_Registry->WriteBool("Purchases", prodId, true);
+ Game->m_Registry->SaveValues();
+
+ stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsProductUnlocked
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "IsProductUnlocked") == 0) {
+ stack->CorrectParams(1);
+ char *prodId = stack->Pop()->GetString();
+
+ stack->PushBool(Game->m_Registry->ReadBool("Purchases", prodId, false));
+
+ return S_OK;
+ }
+
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CSXStore::ScGetProperty(char *name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(name, "Type") == 0) {
+ m_ScValue->SetString("store");
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Available (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "Available") == 0) {
+ m_ScValue->SetBool(IsAvailable());
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // EventsEnabled (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "EventsEnabled") == 0) {
+ m_ScValue->SetBool(GetEventsEnabled());
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // NumValidProducts (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumValidProducts") == 0) {
+ m_ScValue->SetInt(m_ValidProducts.GetSize());
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // NumInvalidProducts (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumInvalidProducts") == 0) {
+ m_ScValue->SetInt(m_InvalidProducts.size());
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // NumTransactions (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(name, "NumTransactions") == 0) {
+ m_ScValue->SetInt(m_Transactions.GetSize());
+ return m_ScValue;
+ }
+
+ else return m_ScValue;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXStore::Persist(CBPersistMgr *PersistMgr) {
+ if (!PersistMgr->m_Saving) Cleanup();
+
+ CBObject::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_EventsEnabled));
+ PersistMgr->Transfer(TMEMBER(m_LastProductRequestOwner));
+ PersistMgr->Transfer(TMEMBER(m_LastPurchaseOwner));
+ PersistMgr->Transfer(TMEMBER(m_LastRestoreOwner));
+ PersistMgr->Transfer(TMEMBER(m_InvalidProducts));
+
+ // persist valid products
+ int numProducts;
+ if (PersistMgr->m_Saving) {
+ numProducts = m_ValidProducts.GetSize();
+ PersistMgr->Transfer(TMEMBER(numProducts));
+ for (int i = 0; i < numProducts; i++) m_ValidProducts[i]->Persist(PersistMgr);
+ } else {
+ numProducts = m_ValidProducts.GetSize();
+ PersistMgr->Transfer(TMEMBER(numProducts));
+ for (int i = 0; i < numProducts; i++) {
+ CBStoreProduct *prod = new CBStoreProduct;
+ prod->Persist(PersistMgr);
+ m_ValidProducts.Add(prod);
+ }
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::AfterLoad() {
+ if (m_EventsEnabled) {
+ SetEventsEnabled(NULL, true);
+ }
+#ifdef __IPHONEOS__
+ StoreKit_SetExternalData((void *)this);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::OnObjectDestroyed(CBScriptHolder *obj) {
+ if (m_LastProductRequestOwner == obj) m_LastProductRequestOwner = NULL;
+ if (m_LastPurchaseOwner == obj) m_LastPurchaseOwner = NULL;
+ if (m_LastRestoreOwner == obj) m_LastRestoreOwner = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::SetEventsEnabled(CScScript *script, bool val) {
+ m_EventsEnabled = val;
+
+ if (val) {
+ if (script) m_LastPurchaseOwner = script->m_Owner;
+#ifdef __IPHONEOS__
+ StoreKit_EnableEvents();
+#endif
+ } else {
+ m_LastPurchaseOwner = NULL;
+#ifdef __IPHONEOS__
+ StoreKit_DisableEvents();
+#endif
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::ValidateProducts(const char *prodIdList) {
+#ifdef __IPHONEOS__
+ StoreKit_ValidateProducts(prodIdList);
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CSXStore::IsAvailable() {
+#ifdef __IPHONEOS__
+ return StoreKit_IsStoreAvailable() > 0;
+#else
+ return false;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::ReceiveProductsStart() {
+ for (int i = 0; i < m_ValidProducts.GetSize(); i++) {
+ delete m_ValidProducts[i];
+ }
+ m_ValidProducts.RemoveAll();
+
+ m_InvalidProducts.clear();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::ReceiveProductsEnd() {
+ if (m_LastProductRequestOwner) m_LastProductRequestOwner->ApplyEvent("ProductsValidated");
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::AddValidProduct(const char *id, const char *name, const char *desc, const char *price) {
+ CBStoreProduct *prod = new CBStoreProduct(id, name, desc, price);
+ m_ValidProducts.Add(prod);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::AddInvalidProduct(const char *id) {
+ m_InvalidProducts.push_back(id);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::ReceiveTransactionsStart() {
+ for (int i = 0; i < m_Transactions.GetSize(); i++) {
+ delete m_Transactions[i];
+ }
+ m_Transactions.RemoveAll();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::ReceiveTransactionsEnd() {
+ if (m_LastPurchaseOwner) m_LastPurchaseOwner->ApplyEvent("TransactionsUpdated");
+ else Game->ApplyEvent("TransactionsUpdated");
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::AddTransaction(const char *id, const char *productId, const char *state) {
+ CBStoreTransaction *trans = new CBStoreTransaction(id, productId, state);
+ m_Transactions.Add(trans);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CSXStore::Purchase(CScScript *script, const char *productId) {
+ if (!productId) return false;
+
+#ifdef __IPHONEOS__
+ for (int i = 0; i < m_ValidProducts.GetSize(); i++) {
+ if (strcmp(productId, m_ValidProducts[i]->GetId()) == 0) {
+ m_LastPurchaseOwner = script->m_Owner;
+
+ StoreKit_Purchase(productId);
+ return true;
+ }
+ }
+#endif
+ script->RuntimeError("Store.Purchase() - '%s' is not a valid product id", productId);
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CSXStore::FinishTransaction(CScScript *script, const char *transId) {
+ if (!transId) return false;
+#ifdef __IPHONEOS__
+ for (int i = 0; i < m_Transactions.GetSize(); i++) {
+ if (strcmp(transId, m_Transactions[i]->GetId()) == 0) {
+ if (StoreKit_FinishTransaction(transId) > 0) {
+ SAFE_DELETE(m_Transactions[i]);
+ m_Transactions.RemoveAt(i);
+ return true;
+ } else return false;
+ }
+ }
+#endif
+ script->RuntimeError("Store.FinishTransaction() - '%s' is not a valid transaction id", transId);
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::RestoreTransactions(CScScript *script) {
+ m_LastRestoreOwner = script->m_Owner;
+#ifdef __IPHONEOS__
+ StoreKit_RestoreTransactions();
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSXStore::OnRestoreFinished(bool error) {
+ if (m_LastRestoreOwner) {
+ if (error) m_LastRestoreOwner->ApplyEvent("TransactionsRestoreFailed");
+ else m_LastRestoreOwner->ApplyEvent("TransactionsRestoreFinished");
+ }
+}
+
+
+
+#ifdef __IPHONEOS__
+
+//////////////////////////////////////////////////////////////////////////
+// StoreKit callbacks (called from ObjC)
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_AddValidProductCallback(const char *id, const char *name, const char *desc, const char *price, void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->AddValidProduct(id, name, desc, price);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_AddInvalidProductCallback(const char *id, void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->AddInvalidProduct(id);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_ReceiveProductsStartCallback(void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->ReceiveProductsStart();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_ReceiveProductsEndCallback(void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->ReceiveProductsEnd();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_AddTransactionCallback(const char *id, const char *productId, const char *state, void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->AddTransaction(id, productId, state);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_ReceiveTransactionsStartCallback(void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->ReceiveTransactionsStart();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_ReceiveTransactionsEndCallback(void *data) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->ReceiveTransactionsEnd();
+}
+//////////////////////////////////////////////////////////////////////////
+void StoreKit_RestoreFinishedCallback(void *data, int error) {
+ CSXStore *store = static_cast<CSXStore *>(data);
+ if (store) store->OnRestoreFinished(error > 0);
+}
+
+#endif // __IPHONEOS__
+
+} // end of namespace WinterMute
\ No newline at end of file diff --git a/engines/wintermute/scriptables/SXStore.h b/engines/wintermute/scriptables/SXStore.h new file mode 100644 index 0000000000..f6a13e9eeb --- /dev/null +++ b/engines/wintermute/scriptables/SXStore.h @@ -0,0 +1,172 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef __WmeSXStore_H__
+#define __WmeSXStore_H__
+#include "engines/wintermute/BPersistMgr.h"
+#include "engines/wintermute/utils.h"
+#include "engines/wintermute/BObject.h"
+
+namespace WinterMute {
+
+class CSXStore : public CBObject {
+public:
+
+ //////////////////////////////////////////////////////////////////////////
+ class CBStoreProduct {
+ public:
+ CBStoreProduct() {
+ m_Id = m_Name = m_Desc = m_Price = NULL;
+ }
+
+ CBStoreProduct(const char *id, const char *name, const char *desc, const char *price) {
+ m_Id = m_Name = m_Desc = m_Price = NULL;
+
+ CBUtils::SetString(&m_Id, id);
+ CBUtils::SetString(&m_Name, name);
+ CBUtils::SetString(&m_Desc, desc);
+ CBUtils::SetString(&m_Price, price);
+ }
+
+ ~CBStoreProduct() {
+ delete [] m_Id;
+ delete [] m_Name;
+ delete [] m_Desc;
+ delete [] m_Price;
+ }
+
+ HRESULT Persist(CBPersistMgr *PersistMgr) {
+ PersistMgr->Transfer(TMEMBER(m_Id));
+ PersistMgr->Transfer(TMEMBER(m_Name));
+ PersistMgr->Transfer(TMEMBER(m_Desc));
+ PersistMgr->Transfer(TMEMBER(m_Price));
+ return S_OK;
+ }
+
+ const char *GetId() {
+ return m_Id;
+ }
+ const char *GetName() {
+ return m_Name;
+ }
+ const char *GetDesc() {
+ return m_Desc;
+ }
+ const char *GetPrice() {
+ return m_Price;
+ }
+
+ private:
+ char *m_Id;
+ char *m_Name;
+ char *m_Desc;
+ char *m_Price;
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ class CBStoreTransaction {
+ public:
+ CBStoreTransaction() {
+ m_Id = m_ProductId = m_State = NULL;
+ }
+
+ CBStoreTransaction(const char *id, const char *productId, const char *state) {
+ m_Id = m_ProductId = m_State = NULL;
+
+ CBUtils::SetString(&m_Id, id);
+ CBUtils::SetString(&m_ProductId, productId);
+ CBUtils::SetString(&m_State, state);
+ }
+
+ ~CBStoreTransaction() {
+ delete [] m_Id;
+ delete [] m_ProductId;
+ delete [] m_State;
+ }
+
+ const char *GetId() {
+ return m_Id;
+ }
+ const char *GetProductId() {
+ return m_ProductId;
+ }
+ const char *GetState() {
+ return m_State;
+ }
+
+ private:
+ char *m_Id;
+ char *m_ProductId;
+ char *m_State;
+ };
+
+
+ DECLARE_PERSISTENT(CSXStore, CBObject)
+ CSXStore(CBGame *inGame);
+ virtual ~CSXStore();
+ virtual CScValue *ScGetProperty(char *name);
+ virtual HRESULT ScCallMethod(CScScript *script, CScStack *stack, CScStack *thisStack, char *name);
+
+ void AfterLoad();
+ void OnObjectDestroyed(CBScriptHolder *obj);
+
+ bool IsAvailable();
+ void SetEventsEnabled(CScScript *script, bool val);
+ bool GetEventsEnabled() const {
+ return m_EventsEnabled;
+ }
+ void ValidateProducts(const char *prodIdList);
+
+ void ReceiveTransactionsStart();
+ void ReceiveTransactionsEnd();
+ void AddTransaction(const char *id, const char *productId, const char *state);
+
+ void ReceiveProductsStart();
+ void ReceiveProductsEnd();
+ void AddValidProduct(const char *id, const char *name, const char *desc, const char *price);
+ void AddInvalidProduct(const char *id);
+
+ void OnRestoreFinished(bool error);
+
+private:
+ void Cleanup();
+ bool Purchase(CScScript *script, const char *productId);
+ bool FinishTransaction(CScScript *script, const char *transId);
+ void RestoreTransactions(CScScript *script);
+
+ bool m_EventsEnabled;
+ CBArray<CBStoreProduct *, CBStoreProduct *> m_ValidProducts;
+ AnsiStringArray m_InvalidProducts;
+ CBScriptHolder *m_LastProductRequestOwner;
+ CBScriptHolder *m_LastPurchaseOwner;
+ CBScriptHolder *m_LastRestoreOwner;
+
+ CBArray<CBStoreTransaction *, CBStoreTransaction *> m_Transactions;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/scriptables/SXString.cpp b/engines/wintermute/scriptables/SXString.cpp new file mode 100644 index 0000000000..0283ee4895 --- /dev/null +++ b/engines/wintermute/scriptables/SXString.cpp @@ -0,0 +1,387 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "BGame.h"
+#include "ScStack.h"
+#include "ScValue.h"
+#include "utils.h"
+#include "scriptables/SXString.h"
+#include "scriptables/SXArray.h"
+#include "StringUtil.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CSXString, false)
+
+//////////////////////////////////////////////////////////////////////////
+CSXString::CSXString(CBGame *inGame, CScStack *Stack): CBScriptable(inGame) {
+ _string = NULL;
+ _capacity = 0;
+
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+
+ if (Val->IsInt()) {
+ _capacity = std::max(0, Val->GetInt());
+ if (_capacity > 0) {
+ _string = new char[_capacity];
+ memset(_string, 0, _capacity);
+ }
+ } else {
+ SetStringVal(Val->GetString());
+ }
+
+ if (_capacity == 0) SetStringVal("");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CSXString::~CSXString() {
+ if (_string) delete [] _string;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CSXString::SetStringVal(const char *Val) {
+ int Len = strlen(Val);
+ if (Len >= _capacity) {
+ _capacity = Len + 1;
+ delete[] _string;
+ _string = NULL;
+ _string = new char[_capacity];
+ memset(_string, 0, _capacity);
+ }
+ strcpy(_string, Val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CSXString::ScToString() {
+ if (_string) return _string;
+ else return "[null string]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CSXString::ScSetString(const char *Val) {
+ SetStringVal(Val);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXString::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ //////////////////////////////////////////////////////////////////////////
+ // Substring
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Substring") == 0) {
+ Stack->CorrectParams(2);
+ int start = Stack->Pop()->GetInt();
+ int end = Stack->Pop()->GetInt();
+
+ if (end < start) CBUtils::Swap(&start, &end);
+
+ try {
+ WideString str;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ str = StringUtil::Utf8ToWide(_string);
+ else
+ str = StringUtil::AnsiToWide(_string);
+
+ WideString subStr = str.substr(start, end - start + 1);
+
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ Stack->PushString(StringUtil::WideToUtf8(subStr).c_str());
+ else
+ Stack->PushString(StringUtil::WideToAnsi(subStr).c_str());
+ } catch (std::exception &) {
+ Stack->PushNULL();
+ }
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Substr
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Substr") == 0) {
+ Stack->CorrectParams(2);
+ int start = Stack->Pop()->GetInt();
+
+ CScValue *val = Stack->Pop();
+ int len = val->GetInt();
+
+ if (!val->IsNULL() && len <= 0) {
+ Stack->PushString("");
+ return S_OK;
+ }
+
+ if (val->IsNULL()) len = strlen(_string) - start;
+
+ try {
+ WideString str;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ str = StringUtil::Utf8ToWide(_string);
+ else
+ str = StringUtil::AnsiToWide(_string);
+
+ WideString subStr = str.substr(start, len);
+
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ Stack->PushString(StringUtil::WideToUtf8(subStr).c_str());
+ else
+ Stack->PushString(StringUtil::WideToAnsi(subStr).c_str());
+ } catch (std::exception &) {
+ Stack->PushNULL();
+ }
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToUpperCase
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ToUpperCase") == 0) {
+ Stack->CorrectParams(0);
+
+ WideString str;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ str = StringUtil::Utf8ToWide(_string);
+ else
+ str = StringUtil::AnsiToWide(_string);
+
+ StringUtil::ToUpperCase(str);
+
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ Stack->PushString(StringUtil::WideToUtf8(str).c_str());
+ else
+ Stack->PushString(StringUtil::WideToAnsi(str).c_str());
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToLowerCase
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ToLowerCase") == 0) {
+ Stack->CorrectParams(0);
+
+ WideString str;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ str = StringUtil::Utf8ToWide(_string);
+ else
+ str = StringUtil::AnsiToWide(_string);
+
+ StringUtil::ToLowerCase(str);
+
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ Stack->PushString(StringUtil::WideToUtf8(str).c_str());
+ else
+ Stack->PushString(StringUtil::WideToAnsi(str).c_str());
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IndexOf
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IndexOf") == 0) {
+ Stack->CorrectParams(2);
+
+ char *strToFind = Stack->Pop()->GetString();
+ int index = Stack->Pop()->GetInt();
+
+ WideString str;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ str = StringUtil::Utf8ToWide(_string);
+ else
+ str = StringUtil::AnsiToWide(_string);
+
+ WideString toFind;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ toFind = StringUtil::Utf8ToWide(strToFind);
+ else
+ toFind = StringUtil::AnsiToWide(strToFind);
+
+ int indexOf = StringUtil::IndexOf(str, toFind, index);
+ Stack->PushInt(indexOf);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Split
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Split") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+ char Separators[MAX_PATH] = ",";
+ if (!Val->IsNULL()) strcpy(Separators, Val->GetString());
+
+ CSXArray *Array = new CSXArray(Game);
+ if (!Array) {
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+
+ WideString str;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ str = StringUtil::Utf8ToWide(_string);
+ else
+ str = StringUtil::AnsiToWide(_string);
+
+ WideString delims;
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ delims = StringUtil::Utf8ToWide(Separators);
+ else
+ delims = StringUtil::AnsiToWide(Separators);
+
+ std::vector<WideString> parts;
+
+
+ size_t start, pos;
+ start = 0;
+ do {
+ pos = str.find_first_of(delims, start);
+ if (pos == start) {
+ start = pos + 1;
+ } else if (pos == WideString::npos) {
+ parts.push_back(str.substr(start));
+ break;
+ } else {
+ parts.push_back(str.substr(start, pos - start));
+ start = pos + 1;
+ }
+ start = str.find_first_not_of(delims, start);
+
+ } while (pos != WideString::npos);
+
+ for (std::vector<WideString>::iterator it = parts.begin(); it != parts.end(); ++it) {
+ WideString &part = (*it);
+
+ if (Game->m_TextEncoding == TEXT_UTF8)
+ Val = new CScValue(Game, StringUtil::WideToUtf8(part).c_str());
+ else
+ Val = new CScValue(Game, StringUtil::WideToAnsi(part).c_str());
+
+ Array->Push(Val);
+ delete[] Val;
+ Val = NULL;
+ }
+
+ Stack->PushNative(Array, false);
+ return S_OK;
+ }
+
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CSXString::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("string");
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Length (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Length") == 0) {
+ if (Game->m_TextEncoding == TEXT_UTF8) {
+ WideString wstr = StringUtil::Utf8ToWide(_string);
+ m_ScValue->SetInt(wstr.length());
+ } else
+ m_ScValue->SetInt(strlen(_string));
+
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Capacity
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Capacity") == 0) {
+ m_ScValue->SetInt(_capacity);
+ return m_ScValue;
+ }
+
+ else return m_ScValue;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXString::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Capacity
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Capacity") == 0) {
+ int NewCap = Value->GetInt();
+ if (NewCap < strlen(_string) + 1) Game->LOG(0, "Warning: cannot lower string capacity");
+ else if (NewCap != _capacity) {
+ char *NewStr = new char[NewCap];
+ if (NewStr) {
+ memset(NewStr, 0, NewCap);
+ strcpy(NewStr, _string);
+ delete[] _string;
+ _string = NewStr;
+ _capacity = NewCap;
+ }
+ }
+ return S_OK;
+ }
+
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXString::Persist(CBPersistMgr *PersistMgr) {
+
+ CBScriptable::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(_capacity));
+
+ if (PersistMgr->m_Saving) {
+ if (_capacity > 0) PersistMgr->PutBytes((byte *)_string, _capacity);
+ } else {
+ if (_capacity > 0) {
+ _string = new char[_capacity];
+ PersistMgr->GetBytes((byte *)_string, _capacity);
+ } else _string = NULL;
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CSXString::ScCompare(CBScriptable *Val) {
+ return strcmp(_string, ((CSXString *)Val)->_string);
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/scriptables/SXString.h b/engines/wintermute/scriptables/SXString.h new file mode 100644 index 0000000000..1cd3a7f52c --- /dev/null +++ b/engines/wintermute/scriptables/SXString.h @@ -0,0 +1,58 @@ +/* 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 2
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef __WmeSXString_H__
+#define __WmeSXString_H__
+
+
+#include "engines/wintermute/BScriptable.h"
+
+namespace WinterMute {
+
+class CSXString : public CBScriptable {
+public:
+ virtual int ScCompare(CBScriptable *Val);
+ DECLARE_PERSISTENT(CSXString, CBScriptable)
+ CScValue *ScGetProperty(char *Name);
+ HRESULT ScSetProperty(char *Name, CScValue *Value);
+ HRESULT ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name);
+ void ScSetString(const char *Val);
+ char *ScToString();
+ void SetStringVal(const char *Val);
+
+ CSXString(CBGame *inGame, CScStack *Stack);
+ virtual ~CSXString();
+
+private:
+ char *_string;
+ int _capacity;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/scriptables/SxObject.cpp b/engines/wintermute/scriptables/SxObject.cpp new file mode 100644 index 0000000000..738db08c53 --- /dev/null +++ b/engines/wintermute/scriptables/SxObject.cpp @@ -0,0 +1,60 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "SxObject.h"
+#include "ScValue.h"
+#include "ScStack.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CSXObject, false)
+
+//////////////////////////////////////////////////////////////////////////
+CSXObject::CSXObject(CBGame *inGame, CScStack *Stack): CBObject(inGame) {
+ int NumParams = Stack->Pop()->GetInt(0);
+ for (int i = 0; i < NumParams; i++) {
+ AddScript(Stack->Pop()->GetString());
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CSXObject::~CSXObject() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSXObject::Persist(CBPersistMgr *PersistMgr) {
+ CBObject::Persist(PersistMgr);
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/scriptables/SxObject.h b/engines/wintermute/scriptables/SxObject.h new file mode 100644 index 0000000000..6a355a7288 --- /dev/null +++ b/engines/wintermute/scriptables/SxObject.h @@ -0,0 +1,44 @@ +/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef __WmeSxObject_H__
+#define __WmeSxObject_H__
+
+
+#include "engines/wintermute/BObject.h"
+
+namespace WinterMute {
+
+class CSXObject : public CBObject {
+public:
+ DECLARE_PERSISTENT(CSXObject, CBObject)
+ CSXObject(CBGame *inGame, CScStack *Stack);
+ virtual ~CSXObject();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
|