aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEinar Johan Trøan Sømåen2012-03-06 00:29:08 +0100
committerEinar Johan Trøan Sømåen2012-06-02 12:12:18 +0200
commit997c5df43000b7db5b73aa883343d00df92c6cd0 (patch)
tree21793337dcc580ae8d1e7ef5237edde8cd7bc8cf
parentec5f5c739e60ddde701b89fd7484faf867bb347f (diff)
downloadscummvm-rg350-997c5df43000b7db5b73aa883343d00df92c6cd0.tar.gz
scummvm-rg350-997c5df43000b7db5b73aa883343d00df92c6cd0.tar.bz2
scummvm-rg350-997c5df43000b7db5b73aa883343d00df92c6cd0.zip
WINTERMUTE: Add BBase and BParser, and make them compile.
-rw-r--r--engines/wintermute/BBase.cpp173
-rw-r--r--engines/wintermute/BBase.h61
-rw-r--r--engines/wintermute/BDynBuffer.h66
-rw-r--r--engines/wintermute/BGame.h384
-rw-r--r--engines/wintermute/BObject.cpp1122
-rw-r--r--engines/wintermute/BObject.h144
-rw-r--r--engines/wintermute/BParser.cpp435
-rw-r--r--engines/wintermute/BParser.h88
-rw-r--r--engines/wintermute/BPersistMgr.cpp517
-rw-r--r--engines/wintermute/BPersistMgr.h89
-rw-r--r--engines/wintermute/BScriptHolder.h81
-rw-r--r--engines/wintermute/PlatformSDL.h92
-rw-r--r--engines/wintermute/SysClass.cpp203
-rw-r--r--engines/wintermute/SysClass.h101
-rw-r--r--engines/wintermute/SysClassRegistry.cpp287
-rw-r--r--engines/wintermute/SysClassRegistry.h89
-rw-r--r--engines/wintermute/SysInstance.cpp48
-rw-r--r--engines/wintermute/SysInstance.h68
-rw-r--r--engines/wintermute/coll_templ.h372
-rw-r--r--engines/wintermute/dcgf.h62
-rw-r--r--engines/wintermute/dctypes.h181
-rw-r--r--engines/wintermute/module.mk6
-rw-r--r--engines/wintermute/persistent.h89
-rw-r--r--engines/wintermute/wintypes.h117
24 files changed, 4874 insertions, 1 deletions
diff --git a/engines/wintermute/BBase.cpp b/engines/wintermute/BBase.cpp
new file mode 100644
index 0000000000..845543c351
--- /dev/null
+++ b/engines/wintermute/BBase.cpp
@@ -0,0 +1,173 @@
+/* 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
+ */
+
+#include "dcgf.h"
+#include "BBase.h"
+#include "BGame.h"
+#include "BParser.h"
+#include "BDynBuffer.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+CBBase::CBBase(CBGame *GameOwner) {
+ Game = GameOwner;
+ m_Persistable = true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBBase::CBBase() {
+ Game = NULL;
+ m_Persistable = true;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBBase::~CBBase() {
+ m_EditorProps.clear();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *CBBase::GetEditorProp(const char *PropName, const char *InitVal) {
+ m_EditorPropsIter = m_EditorProps.find(PropName);
+ if (m_EditorPropsIter != m_EditorProps.end()) return m_EditorPropsIter->second.c_str();
+ else return InitVal;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBBase::SetEditorProp(const char *PropName, const char *PropValue) {
+ if (PropName == NULL) return E_FAIL;
+
+ if (PropValue == NULL) {
+ m_EditorProps.erase(PropName);
+ } else {
+ m_EditorProps[PropName] = PropValue;
+ }
+ return S_OK;
+}
+
+
+
+TOKEN_DEF_START
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(NAME)
+TOKEN_DEF(VALUE)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBBase::ParseEditorProperty(byte *Buffer, bool Complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(VALUE)
+ TOKEN_TABLE_END
+
+
+ if (!Game->m_EditorMode) return S_OK;
+
+
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (Complete) {
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_EDITOR_PROPERTY) {
+ Game->LOG(0, "'EDITOR_PROPERTY' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = params;
+ }
+
+ char *PropName = NULL;
+ char *PropValue = NULL;
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_NAME:
+ delete[] PropName;
+ PropName = new char[strlen((char *)params) + 1];
+ if (PropName) strcpy(PropName, (char *)params);
+ else cmd = PARSERR_GENERIC;
+ break;
+
+ case TOKEN_VALUE:
+ delete[] PropValue;
+ PropValue = new char[strlen((char *)params) + 1];
+ if (PropValue) strcpy(PropValue, (char *)params);
+ else cmd = PARSERR_GENERIC;
+ break;
+ }
+
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ delete[] PropName;
+ delete[] PropValue;
+ PropName = NULL;
+ PropValue = NULL;
+ Game->LOG(0, "Syntax error in EDITOR_PROPERTY definition");
+ return E_FAIL;
+ }
+ if (cmd == PARSERR_GENERIC || PropName == NULL || PropValue == NULL) {
+ delete[] PropName;
+ delete[] PropValue;
+ PropName = NULL;
+ PropValue = NULL;
+ Game->LOG(0, "Error loading EDITOR_PROPERTY definition");
+ return E_FAIL;
+ }
+
+
+ SetEditorProp(PropName, PropValue);
+
+ delete[] PropName;
+ delete[] PropValue;
+ PropName = NULL;
+ PropValue = NULL;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBBase::SaveAsText(CBDynBuffer *Buffer, int Indent) {
+ m_EditorPropsIter = m_EditorProps.begin();
+ while (m_EditorPropsIter != m_EditorProps.end()) {
+ Buffer->PutTextIndent(Indent, "EDITOR_PROPERTY\n");
+ Buffer->PutTextIndent(Indent, "{\n");
+ Buffer->PutTextIndent(Indent + 2, "NAME=\"%s\"\n", (char *)m_EditorPropsIter->first.c_str());
+ Buffer->PutTextIndent(Indent + 2, "VALUE=\"%s\"\n", m_EditorPropsIter->second.c_str());
+ Buffer->PutTextIndent(Indent, "}\n\n");
+
+ m_EditorPropsIter++;
+ }
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BBase.h b/engines/wintermute/BBase.h
new file mode 100644
index 0000000000..ba228bc572
--- /dev/null
+++ b/engines/wintermute/BBase.h
@@ -0,0 +1,61 @@
+/* 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 WINTERMUTE_BBASE_H
+#define WINTERMUTE_BBASE_H
+
+#include "wintypes.h"
+#include "dctypes.h"
+#include <map>
+#include <string>
+
+namespace WinterMute {
+
+class CBGame;
+class CBDynBuffer;
+
+class CBBase {
+public:
+ bool m_Persistable;
+ HRESULT SetEditorProp(const char *PropName, const char *PropValue);
+ const char *GetEditorProp(const char *PropName, const char *InitVal = NULL);
+ CBBase(TDynamicConstructor, TDynamicConstructor) {};
+ HRESULT ParseEditorProperty(byte *Buffer, bool Complete = true);
+ virtual HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent = 0);
+ CBBase();
+ CBGame *Game;
+ CBBase(CBGame *GameOwner);
+ virtual ~CBBase();
+
+ std::map<std::string, std::string> m_EditorProps;
+ std::map<std::string, std::string>::iterator m_EditorPropsIter;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BDynBuffer.h b/engines/wintermute/BDynBuffer.h
new file mode 100644
index 0000000000..7ef970fcd3
--- /dev/null
+++ b/engines/wintermute/BDynBuffer.h
@@ -0,0 +1,66 @@
+/* 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 WINTERMUTE_BDYNBUFFER_H
+#define WINTERMUTE_BDYNBUFFER_H
+
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBDynBuffer : public CBBase {
+public:
+ bool m_Initialized;
+ void PutText(LPCSTR fmt, ...);
+ void PutTextIndent(int Indent, LPCSTR fmt, ...);
+ uint32 GetDWORD();
+ void PutDWORD(uint32 Val);
+ char *GetString();
+ void PutString(const char *Val);
+ HRESULT GetBytes(byte *Buffer, uint32 Size);
+ HRESULT PutBytes(byte *Buffer, uint32 Size);
+ uint32 GetSize();
+ HRESULT Init(uint32 InitSize = 0);
+ void Cleanup();
+ uint32 m_Size;
+ byte *m_Buffer;
+ CBDynBuffer(CBGame *inGame, uint32 InitSize = 1000, uint32 GrowBy = 1000);
+ virtual ~CBDynBuffer();
+
+private:
+ uint32 m_RealSize;
+ uint32 m_GrowBy;
+ uint32 m_InitSize;
+ uint32 m_Offset;
+ void PutTextForm(const char *format, va_list argptr);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BGame.h b/engines/wintermute/BGame.h
new file mode 100644
index 0000000000..199417ede6
--- /dev/null
+++ b/engines/wintermute/BGame.h
@@ -0,0 +1,384 @@
+/* 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 WINTERMUTE_BGAME_H
+#define WINTERMUTE_BGAME_H
+
+//#include "BDebugger.h"
+//#include "BSaveThumbHelper.h"
+//#include "BFader.h"
+//#include "BRenderer.h"
+//#include "BSurfaceStorage.h"
+#include "engines/wintermute/BObject.h"
+#include "engines/wintermute/persistent.h"
+#include "coll_templ.h"
+
+namespace WinterMute {
+
+typedef void (*ENGINE_LOG_CALLBACK)(char *Text, HRESULT Result, void *Data);
+
+class CBSoundMgr;
+class CBFont;
+class CBFileManager;
+class CBTransitionMgr;
+class CScEngine;
+class CBFontStorage;
+class CBStringTable;
+class CBQuickMsg;
+class CUIWindow;
+class CBViewport;
+class CBRegistry;
+class CSXStore;
+class CSXMath;
+class CBKeyboardState;
+
+#define NUM_MUSIC_CHANNELS 5
+
+class CBGame: public CBObject {
+public:
+ DECLARE_PERSISTENT(CBGame, CBObject)
+#if 0
+ virtual HRESULT OnScriptShutdown(CScScript *Script);
+
+ virtual HRESULT OnActivate(bool Activate, bool RefreshMouse);
+ virtual HRESULT OnMouseLeftDown();
+ virtual HRESULT OnMouseLeftUp();
+ virtual HRESULT OnMouseLeftDblClick();
+ virtual HRESULT OnMouseRightDblClick();
+ virtual HRESULT OnMouseRightDown();
+ virtual HRESULT OnMouseRightUp();
+ virtual HRESULT OnMouseMiddleDown();
+ virtual HRESULT OnMouseMiddleUp();
+ virtual HRESULT OnPaint();
+ virtual HRESULT OnWindowClose();
+
+ bool IsLeftDoubleClick();
+ bool IsRightDoubleClick();
+#endif
+ bool m_AutorunDisabled;
+
+ uint32 m_LastMiniUpdate;
+ bool m_MiniUpdateEnabled;
+
+ virtual HRESULT MiniUpdate() {} // <- TODO Unstub
+#if 0
+ virtual HRESULT MiniUpdate();
+
+ void GetMousePos(POINT *Pos);
+ RECT m_MouseLockRect;
+
+ bool m_ShuttingDown;
+
+ virtual HRESULT DisplayDebugInfo();
+ bool m_DEBUG_ShowFPS;
+
+ bool m_SuspendedRendering;
+ int m_SoundBufferSizeSec;
+
+ TTextEncoding m_TextEncoding;
+ bool m_TextRTL;
+
+ CBSprite *m_LoadingIcon;
+ int m_LoadingIconX;
+ int m_LoadingIconY;
+ int m_LoadingIconPersistent;
+
+ virtual HRESULT ResetContent();
+
+ void DEBUG_DumpClassRegistry();
+ HRESULT SetWaitCursor(char *Filename);
+
+ char *m_LocalSaveDir;
+ bool m_SaveDirChecked;
+
+
+ bool m_IndicatorDisplay;
+ uint32 m_IndicatorColor;
+ int m_IndicatorProgress;
+ int m_IndicatorX;
+ int m_IndicatorY;
+ int m_IndicatorWidth;
+ int m_IndicatorHeight;
+
+ bool m_RichSavedGames;
+ char *m_SavedGameExt;
+
+ char *m_LoadImageName;
+ char *m_SaveImageName;
+ int m_SaveImageX;
+ int m_SaveImageY;
+ int m_LoadImageX;
+ int m_LoadImageY;
+ CBSurface *m_SaveLoadImage;
+
+ HRESULT DisplayIndicator();
+
+ int m_ThumbnailWidth;
+ int m_ThumbnailHeight;
+
+ bool m_ReportTextureFormat;
+ HMODULE m_ResourceModule;
+ void SetResourceModule(HMODULE ResModule);
+
+ void SetEngineLogCallback(ENGINE_LOG_CALLBACK Callback = NULL, void *Data = NULL);
+ ENGINE_LOG_CALLBACK m_EngineLogCallback;
+ void *m_EngineLogCallbackData;
+#endif
+ bool m_EditorMode;
+#if 0
+ bool m_DoNotExpandStrings;
+ void GetOffset(int *OffsetX, int *OffsetY);
+ void SetOffset(int OffsetX, int OffsetY);
+ int GetSequence();
+ int m_OffsetY;
+ int m_OffsetX;
+ float m_OffsetPercentX;
+ float m_OffsetPercentY;
+ CBObject *m_MainObject;
+ HRESULT InitInput(HINSTANCE hInst, HWND hWnd);
+ HRESULT InitLoop();
+ uint32 m_CurrentTime;
+ uint32 m_DeltaTime;
+ CBFont *m_SystemFont;
+ CBFont *m_VideoFont;
+ HRESULT Initialize1();
+ HRESULT Initialize2();
+ HRESULT Initialize3();
+ CBFileManager *m_FileManager;
+ CBTransitionMgr *m_TransMgr;
+ CBDebugger *GetDebugMgr();
+#endif //TODO: STUB
+ void LOG(HRESULT res, LPCSTR fmt, ...) {}
+#if 0
+ CBRenderer *m_Renderer;
+ CBSoundMgr *m_SoundMgr;
+ CScEngine *m_ScEngine;
+ CSXMath *m_MathClass;
+ CSXStore *m_Store;
+ CBSurfaceStorage *m_SurfaceStorage;
+ CBFontStorage *m_FontStorage;
+ CBGame();
+ virtual ~CBGame();
+ void DEBUG_DebugDisable();
+ void DEBUG_DebugEnable(const char *Filename = NULL);
+ bool m_DEBUG_DebugMode;
+ bool m_DEBUG_AbsolutePathWarning;
+ FILE *m_DEBUG_LogFile;
+ int m_Sequence;
+ virtual HRESULT LoadFile(const char *Filename);
+ virtual HRESULT LoadBuffer(byte *Buffer, bool Complete = true);
+ CBArray<CBQuickMsg *, CBQuickMsg *> m_QuickMessages;
+ CBArray<CUIWindow *, CUIWindow *> m_Windows;
+ CBArray<CBViewport *, CBViewport *> m_ViewportStack;
+ int m_ViewportSP;
+ bool m_MouseLeftDown;
+ bool m_MouseRightDown;
+ bool m_MouseMidlleDown;
+ CBStringTable *m_StringTable;
+
+ int m_SettingsResWidth;
+ int m_SettingsResHeight;
+ bool m_SettingsRequireAcceleration;
+ bool m_SettingsAllowWindowed;
+ bool m_SettingsAllowAdvanced;
+ bool m_SettingsAllowAccessTab;
+ bool m_SettingsAllowAboutTab;
+ bool m_SettingsRequireSound;
+ bool m_SettingsAllowDesktopRes;
+ int m_SettingsTLMode;
+ char *m_SettingsGameFile;
+ CBFader *m_Fader;
+ bool m_SuppressScriptErrors;
+
+ virtual HRESULT InvalidateDeviceObjects();
+ virtual HRESULT RestoreDeviceObjects();
+
+ virtual void PublishNatives();
+ virtual HRESULT ExternalCall(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name);
+
+ // 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();
+
+ // compatibility bits
+ bool m_CompatKillMethodThreads;
+
+private:
+ // FPS stuff
+ uint32 m_LastTime;
+ uint32 m_FpsTime;
+ uint32 m_FramesRendered;
+
+public:
+ uint32 m_SurfaceGCCycleTime;
+ bool m_SmartCache;
+ bool m_VideoSubtitles;
+ bool m_Subtitles;
+ uint32 m_MusicStartTime[NUM_MUSIC_CHANNELS];
+ bool m_CompressedSavegames;
+ int m_ScheduledLoadSlot;
+ bool m_Loading;
+ bool m_PersonalizedSave;
+ HRESULT EmptySaveSlot(int Slot);
+ bool IsSaveSlotUsed(int Slot);
+ HRESULT GetSaveSlotDescription(int Slot, char *Buffer);
+ HRESULT GetSaveSlotFilename(int Slot, char *Buffer);
+ void SetWindowTitle();
+ virtual bool HandleMouseWheel(int Delta);
+ bool m_Quitting;
+ virtual HRESULT GetVersion(byte *VerMajor, byte *VerMinor, byte *ExtMajor, byte *ExtMinor);
+ virtual bool HandleKeypress(SDL_Event *event);
+ int m_FreezeLevel;
+ HRESULT Unfreeze();
+ HRESULT Freeze(bool IncludingMusic = true);
+ HRESULT FocusWindow(CUIWindow *Window);
+ bool m_LoadInProgress;
+ CUIWindow *m_FocusedWindow;
+ bool m_EditorForceScripts;
+ static void AfterLoadRegion(void *Region, void *Data);
+ static void AfterLoadSubFrame(void *Subframe, void *Data);
+ static void AfterLoadSound(void *Sound, void *Data);
+ static void AfterLoadFont(void *Font, void *Data);
+ static void AfterLoadScript(void *script, void *data);
+ static void InvalidateValues(void *Value, void *Data);
+ HRESULT LoadSettings(char *Filename);
+ HRESULT ResumeMusic(int Channel);
+ HRESULT SetMusicStartTime(int Channel, uint32 Time);
+ HRESULT PauseMusic(int Channel);
+ HRESULT StopMusic(int Channel);
+ HRESULT PlayMusic(int Channel, char *Filename, bool Looping = true, uint32 LoopStart = 0);
+ CBSound *m_Music[NUM_MUSIC_CHANNELS];
+ bool m_MusicCrossfadeRunning;
+ bool m_MusicCrossfadeSwap;
+ uint32 m_MusicCrossfadeStartTime;
+ uint32 m_MusicCrossfadeLength;
+ int m_MusicCrossfadeChannel1;
+ int m_MusicCrossfadeChannel2;
+ HRESULT DisplayWindows(bool InGame = false);
+ CBRegistry *m_Registry;
+ bool m_UseD3D;
+ virtual HRESULT Cleanup();
+ virtual HRESULT LoadGame(int Slot);
+ virtual HRESULT LoadGame(char *Filename);
+ virtual HRESULT SaveGame(int slot, char *desc, bool quickSave = false);
+ virtual HRESULT ShowCursor();
+ CBSprite *m_CursorNoninteractive;
+ CBObject *m_ActiveObject;
+ CBKeyboardState *m_KeyboardState;
+ bool m_Interactive;
+ TGameState m_State;
+ TGameState m_OrigState;
+ bool m_OrigInteractive;
+ uint32 m_Timer;
+ uint32 m_TimerDelta;
+ uint32 m_TimerLast;
+
+ uint32 m_LiveTimer;
+ uint32 m_LiveTimerDelta;
+ uint32 m_LiveTimerLast;
+
+ CBObject *m_CapturedObject;
+ POINT m_MousePos;
+ bool ValidObject(CBObject *Object);
+ HRESULT UnregisterObject(CBObject *Object);
+ HRESULT RegisterObject(CBObject *Object);
+ void QuickMessage(char *Text);
+ void QuickMessageForm(LPSTR fmt, ...);
+ HRESULT DisplayQuickMsg();
+ uint32 m_Fps;
+ HRESULT UpdateMusicCrossfade();
+
+ CBArray<CBObject *, CBObject *> m_RegObjects;
+
+public:
+ virtual HRESULT DisplayContent(bool Update = true, bool DisplayAll = false);
+ virtual HRESULT DisplayContentSimple();
+ bool m_ForceNonStreamedSounds;
+ void ResetMousePos();
+ int m_SubtitlesSpeed;
+ void SetInteractive(bool State);
+ virtual HRESULT WindowLoadHook(CUIWindow *Win, char **Buf, char **Params);
+ virtual HRESULT WindowScriptMethodHook(CUIWindow *Win, CScScript *Script, CScStack *Stack, char *Name);
+ 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);
+
+ CBSprite *m_LastCursor;
+ HRESULT DrawCursor(CBSprite *Cursor);
+
+ virtual HRESULT InitAfterLoad();
+
+ CBSaveThumbHelper *m_CachedThumbnail;
+
+ AnsiString GetDataDir();
+
+ void AddMem(int bytes);
+
+ bool m_TouchInterface;
+ bool m_ConstrainedMemory;
+ AnsiString GetDeviceType() const;
+
+private:
+ CBDebugger *m_DebugMgr;
+
+ struct LastClickInfo {
+ LastClickInfo() {
+ PosX = PosY = 0;
+ Time = 0;
+ }
+
+ int PosX;
+ int PosY;
+ uint32 Time;
+ };
+
+ LastClickInfo m_LastClick[2];
+ bool IsDoubleClick(int buttonIndex);
+ uint32 m_UsedMem;
+
+
+
+protected:
+ // WME Lite specific
+ bool m_AutoSaveOnExit;
+ int m_AutoSaveSlot;
+ bool m_CursorHidden;
+
+public:
+ void AutoSaveOnExit();
+#endif
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BObject.cpp b/engines/wintermute/BObject.cpp
new file mode 100644
index 0000000000..3bb94046a4
--- /dev/null
+++ b/engines/wintermute/BObject.cpp
@@ -0,0 +1,1122 @@
+/* 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
+ */
+
+#include "dcgf.h"
+#include "BObject.h"
+#include "BParser.h"
+#include "ScValue.h"
+#include "ScStack.h"
+#include "BSound.h"
+#include "BSoundMgr.h"
+#include "BGame.h"
+#include "BStringTable.h"
+#include "BSprite.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBObject, false)
+
+//////////////////////////////////////////////////////////////////////
+CBObject::CBObject(CBGame *inGame): CBScriptHolder(inGame) {
+ m_PosX = m_PosY = 0;
+ m_Movable = true;
+ m_Zoomable = true;
+ m_Registrable = true;
+ m_Shadowable = true;
+ m_Rotatable = false;
+ m_Is3D = false;
+
+ m_AlphaColor = 0;
+ m_Scale = -1;
+ m_RelativeScale = 0;
+
+ m_ScaleX = -1;
+ m_ScaleY = -1;
+
+ m_Ready = true;
+
+ m_SoundEvent = NULL;
+
+ m_ID = Game->GetSequence();
+
+ CBPlatform::SetRectEmpty(&m_Rect);
+ m_RectSet = false;
+
+ m_Cursor = NULL;
+ m_ActiveCursor = NULL;
+ m_SharedCursors = false;
+
+ m_SFX = NULL;
+ m_SFXStart = 0;
+ m_SFXVolume = 100;
+ m_AutoSoundPanning = true;
+
+ m_EditorAlwaysRegister = false;
+ m_EditorSelected = false;
+
+ m_EditorOnly = false;
+
+ m_Rotate = 0.0f;
+ m_RotateValid = false;
+ m_RelativeRotate = 0.0f;
+
+ for (int i = 0; i < 7; i++) m_Caption[i] = NULL;
+ m_SaveState = true;
+
+ m_NonIntMouseEvents = false;
+
+ // sound FX
+ m_SFXType = SFX_NONE;
+ m_SFXParam1 = m_SFXParam2 = m_SFXParam3 = m_SFXParam4 = 0;
+
+ m_BlendMode = BLEND_NORMAL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBObject::~CBObject() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::Cleanup() {
+ if (Game && Game->m_ActiveObject == this) Game->m_ActiveObject = NULL;
+
+ CBScriptHolder::Cleanup();
+ delete[] m_SoundEvent;
+ m_SoundEvent = NULL;
+
+ if (!m_SharedCursors) {
+ delete m_Cursor;
+ delete m_ActiveCursor;
+ m_Cursor = NULL;
+ m_ActiveCursor = NULL;
+ }
+ delete m_SFX;
+ m_SFX = NULL;
+
+ for (int i = 0; i < 7; i++) {
+ delete[] m_Caption[i];
+ m_Caption[i] = NULL;
+ }
+
+ m_SFXType = SFX_NONE;
+ m_SFXParam1 = m_SFXParam2 = m_SFXParam3 = m_SFXParam4 = 0;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBObject::SetCaption(char *Caption, int Case) {
+ if (Case == 0) Case = 1;
+ if (Case < 1 || Case > 7) return;
+
+ delete[] m_Caption[Case - 1];
+ m_Caption[Case - 1] = new char[strlen(Caption) + 1];
+ if (m_Caption[Case - 1]) {
+ strcpy(m_Caption[Case - 1], Caption);
+ Game->m_StringTable->Expand(&m_Caption[Case - 1]);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBObject::GetCaption(int Case) {
+ if (Case == 0) Case = 1;
+ if (Case < 1 || Case > 7 || m_Caption[Case - 1] == NULL) return "";
+ else return m_Caption[Case - 1];
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::Listen(CBScriptHolder *param1, uint32 param2) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // SkipTo
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "SkipTo") == 0) {
+ Stack->CorrectParams(2);
+ m_PosX = Stack->Pop()->GetInt();
+ m_PosY = Stack->Pop()->GetInt();
+ AfterMove();
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Caption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Caption") == 0) {
+ Stack->CorrectParams(1);
+ Stack->PushString(GetCaption(Stack->Pop()->GetInt()));
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetCursor") == 0) {
+ Stack->CorrectParams(1);
+ if (SUCCEEDED(SetCursor(Stack->Pop()->GetString()))) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemoveCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RemoveCursor") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_SharedCursors) {
+ delete m_Cursor;
+ m_Cursor = NULL;
+ } else {
+ m_Cursor = NULL;
+
+ }
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetCursor") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_Cursor || !m_Cursor->m_Filename) Stack->PushNULL();
+ else Stack->PushString(m_Cursor->m_Filename);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetCursorObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetCursorObject") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_Cursor) Stack->PushNULL();
+ else Stack->PushNative(m_Cursor, true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HasCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HasCursor") == 0) {
+ Stack->CorrectParams(0);
+
+ if (m_Cursor) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetCaption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetCaption") == 0) {
+ Stack->CorrectParams(2);
+ SetCaption(Stack->Pop()->GetString(), Stack->Pop()->GetInt());
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadSound
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "LoadSound") == 0) {
+ Stack->CorrectParams(1);
+ char *Filename = Stack->Pop()->GetString();
+ if (SUCCEEDED(PlaySFX(Filename, false, false)))
+ Stack->PushBool(true);
+ else
+ Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlaySound
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PlaySound") == 0) {
+ Stack->CorrectParams(3);
+
+ char *Filename;
+ bool Looping;
+ uint32 LoopStart;
+
+ CScValue *val1 = Stack->Pop();
+ CScValue *val2 = Stack->Pop();
+ CScValue *val3 = Stack->Pop();
+
+ if (val1->m_Type == VAL_BOOL) {
+ Filename = NULL;
+ Looping = val1->GetBool();
+ LoopStart = val2->GetInt();
+ } else {
+ if (val1->IsNULL()) Filename = NULL;
+ else Filename = val1->GetString();
+ Looping = val2->IsNULL() ? false : val2->GetBool();
+ LoopStart = val3->GetInt();
+ }
+
+ if (FAILED(PlaySFX(Filename, Looping, true, NULL, LoopStart))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlaySoundEvent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PlaySoundEvent") == 0) {
+ Stack->CorrectParams(2);
+
+ char *Filename;
+ char *EventName;
+
+ CScValue *val1 = Stack->Pop();
+ CScValue *val2 = Stack->Pop();
+
+ if (val2->IsNULL()) {
+ Filename = NULL;
+ EventName = val1->GetString();
+ } else {
+ Filename = val1->GetString();
+ EventName = val2->GetString();
+ }
+
+ if (FAILED(PlaySFX(Filename, false, true, EventName))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StopSound
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "StopSound") == 0) {
+ Stack->CorrectParams(0);
+
+ if (FAILED(StopSFX())) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PauseSound
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PauseSound") == 0) {
+ Stack->CorrectParams(0);
+
+ if (FAILED(PauseSFX())) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ResumeSound
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ResumeSound") == 0) {
+ Stack->CorrectParams(0);
+
+ if (FAILED(ResumeSFX())) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsSoundPlaying
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsSoundPlaying") == 0) {
+ Stack->CorrectParams(0);
+
+ if (m_SFX && m_SFX->IsPlaying()) Stack->PushBool(true);
+ else Stack->PushBool(false);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetSoundPosition
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetSoundPosition") == 0) {
+ Stack->CorrectParams(1);
+
+ uint32 Time = Stack->Pop()->GetInt();
+ if (FAILED(SetSFXTime(Time))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSoundPosition
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetSoundPosition") == 0) {
+ Stack->CorrectParams(0);
+
+ if (!m_SFX) Stack->PushInt(0);
+ else Stack->PushInt(m_SFX->GetPositionTime());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetSoundVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetSoundVolume") == 0) {
+ Stack->CorrectParams(1);
+
+ int Volume = Stack->Pop()->GetInt();
+ if (FAILED(SetSFXVolume(Volume))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSoundVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetSoundVolume") == 0) {
+ Stack->CorrectParams(0);
+
+ if (!m_SFX) Stack->PushInt(m_SFXVolume);
+ else Stack->PushInt(m_SFX->GetVolume());
+ return S_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundFXNone
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundFXNone") == 0) {
+ Stack->CorrectParams(0);
+ m_SFXType = SFX_NONE;
+ m_SFXParam1 = 0;
+ m_SFXParam2 = 0;
+ m_SFXParam3 = 0;
+ m_SFXParam4 = 0;
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundFXEcho
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundFXEcho") == 0) {
+ Stack->CorrectParams(4);
+ m_SFXType = SFX_ECHO;
+ m_SFXParam1 = (float)Stack->Pop()->GetFloat(0); // Wet/Dry Mix [%] (0-100)
+ m_SFXParam2 = (float)Stack->Pop()->GetFloat(0); // Feedback [%] (0-100)
+ m_SFXParam3 = (float)Stack->Pop()->GetFloat(333.0f); // Left Delay [ms] (1-2000)
+ m_SFXParam4 = (float)Stack->Pop()->GetFloat(333.0f); // Right Delay [ms] (1-2000)
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundFXReverb
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundFXReverb") == 0) {
+ Stack->CorrectParams(4);
+ m_SFXType = SFX_REVERB;
+ m_SFXParam1 = (float)Stack->Pop()->GetFloat(0); // In Gain [dB] (-96 - 0)
+ m_SFXParam2 = (float)Stack->Pop()->GetFloat(0); // Reverb Mix [dB] (-96 - 0)
+ m_SFXParam3 = (float)Stack->Pop()->GetFloat(1000.0f); // Reverb Time [ms] (0.001 - 3000)
+ m_SFXParam4 = (float)Stack->Pop()->GetFloat(0.001f); // HighFreq RT Ratio (0.001 - 0.999)
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ else return CBScriptHolder::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBObject::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("object");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Caption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Caption") == 0) {
+ m_ScValue->SetString(GetCaption(1));
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // X
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "X") == 0) {
+ m_ScValue->SetInt(m_PosX);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Y
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Y") == 0) {
+ m_ScValue->SetInt(m_PosY);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Height (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Height") == 0) {
+ m_ScValue->SetInt(GetHeight());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Ready (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Ready") == 0) {
+ m_ScValue->SetBool(m_Ready);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Movable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Movable") == 0) {
+ m_ScValue->SetBool(m_Movable);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Registrable/Interactive
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Registrable") == 0 || strcmp(Name, "Interactive") == 0) {
+ m_ScValue->SetBool(m_Registrable);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Zoomable/Scalable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Zoomable") == 0 || strcmp(Name, "Scalable") == 0) {
+ m_ScValue->SetBool(m_Zoomable);
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Rotatable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Rotatable") == 0) {
+ m_ScValue->SetBool(m_Rotatable);
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // AlphaColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AlphaColor") == 0) {
+ m_ScValue->SetInt((int)m_AlphaColor);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // BlendMode
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "BlendMode") == 0) {
+ m_ScValue->SetInt((int)m_BlendMode);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Scale
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Scale") == 0) {
+ if (m_Scale < 0) m_ScValue->SetNULL();
+ else m_ScValue->SetFloat((double)m_Scale);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScaleX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScaleX") == 0) {
+ if (m_ScaleX < 0) m_ScValue->SetNULL();
+ else m_ScValue->SetFloat((double)m_ScaleX);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScaleY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScaleY") == 0) {
+ if (m_ScaleY < 0) m_ScValue->SetNULL();
+ else m_ScValue->SetFloat((double)m_ScaleY);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RelativeScale
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RelativeScale") == 0) {
+ m_ScValue->SetFloat((double)m_RelativeScale);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Rotate
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Rotate") == 0) {
+ if (!m_RotateValid) m_ScValue->SetNULL();
+ else m_ScValue->SetFloat((double)m_Rotate);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RelativeRotate
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RelativeRotate") == 0) {
+ m_ScValue->SetFloat((double)m_RelativeRotate);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Colorable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Colorable") == 0) {
+ m_ScValue->SetBool(m_Shadowable);
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // SoundPanning
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundPanning") == 0) {
+ m_ScValue->SetBool(m_AutoSoundPanning);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SaveState
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SaveState") == 0) {
+ m_ScValue->SetBool(m_SaveState);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NonIntMouseEvents
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "NonIntMouseEvents") == 0) {
+ m_ScValue->SetBool(m_NonIntMouseEvents);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccCaption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccCaption") == 0) {
+ m_ScValue->SetNULL();
+ return m_ScValue;
+ }
+
+ else return CBScriptHolder::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Caption
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Caption") == 0) {
+ SetCaption(Value->GetString());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // X
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "X") == 0) {
+ m_PosX = Value->GetInt();
+ AfterMove();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Y
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Y") == 0) {
+ m_PosY = Value->GetInt();
+ AfterMove();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Movable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Movable") == 0) {
+ m_Movable = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Registrable/Interactive
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Registrable") == 0 || strcmp(Name, "Interactive") == 0) {
+ m_Registrable = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Zoomable/Scalable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Zoomable") == 0 || strcmp(Name, "Scalable") == 0) {
+ m_Zoomable = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Rotatable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Rotatable") == 0) {
+ m_Rotatable = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AlphaColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AlphaColor") == 0) {
+ m_AlphaColor = (uint32)Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // BlendMode
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "BlendMode") == 0) {
+ int i = Value->GetInt();
+ if (i < BLEND_NORMAL || i >= NUM_BLEND_MODES) i = BLEND_NORMAL;
+ m_BlendMode = (TSpriteBlendMode)i;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Scale
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Scale") == 0) {
+ if (Value->IsNULL()) m_Scale = -1;
+ else m_Scale = (float)Value->GetFloat();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScaleX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScaleX") == 0) {
+ if (Value->IsNULL()) m_ScaleX = -1;
+ else m_ScaleX = (float)Value->GetFloat();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScaleY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScaleY") == 0) {
+ if (Value->IsNULL()) m_ScaleY = -1;
+ else m_ScaleY = (float)Value->GetFloat();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RelativeScale
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RelativeScale") == 0) {
+ m_RelativeScale = (float)Value->GetFloat();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Rotate
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Rotate") == 0) {
+ if (Value->IsNULL()) {
+ m_Rotate = 0.0f;
+ m_RotateValid = false;
+ } else {
+ m_Rotate = (float)Value->GetFloat();
+ m_RotateValid = true;
+ }
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RelativeRotate
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RelativeRotate") == 0) {
+ m_RelativeRotate = (float)Value->GetFloat();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Colorable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Colorable") == 0) {
+ m_Shadowable = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundPanning
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundPanning") == 0) {
+ m_AutoSoundPanning = Value->GetBool();
+ if (!m_AutoSoundPanning) ResetSoundPan();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SaveState
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SaveState") == 0) {
+ m_SaveState = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NonIntMouseEvents
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "NonIntMouseEvents") == 0) {
+ m_NonIntMouseEvents = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccCaption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccCaption") == 0) {
+ return S_OK;
+ }
+
+ else return CBScriptHolder::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBObject::ScToString() {
+ return "[object]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::ShowCursor() {
+ if (m_Cursor) return Game->DrawCursor(m_Cursor);
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::SaveAsText(CBDynBuffer *Buffer, int Indent) {
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::Persist(CBPersistMgr *PersistMgr) {
+ CBScriptHolder::Persist(PersistMgr);
+
+ for (int i = 0; i < 7; i++) PersistMgr->Transfer(TMEMBER(m_Caption[i]));
+ PersistMgr->Transfer(TMEMBER(m_ActiveCursor));
+ PersistMgr->Transfer(TMEMBER(m_AlphaColor));
+ PersistMgr->Transfer(TMEMBER(m_AutoSoundPanning));
+ PersistMgr->Transfer(TMEMBER(m_Cursor));
+ PersistMgr->Transfer(TMEMBER(m_SharedCursors));
+ PersistMgr->Transfer(TMEMBER(m_EditorAlwaysRegister));
+ PersistMgr->Transfer(TMEMBER(m_EditorOnly));
+ PersistMgr->Transfer(TMEMBER(m_EditorSelected));
+ PersistMgr->Transfer(TMEMBER(m_ID));
+ PersistMgr->Transfer(TMEMBER(m_Is3D));
+ PersistMgr->Transfer(TMEMBER(m_Movable));
+ PersistMgr->Transfer(TMEMBER(m_PosX));
+ PersistMgr->Transfer(TMEMBER(m_PosY));
+ PersistMgr->Transfer(TMEMBER(m_RelativeScale));
+ PersistMgr->Transfer(TMEMBER(m_Rotatable));
+ PersistMgr->Transfer(TMEMBER(m_Scale));
+ PersistMgr->Transfer(TMEMBER(m_SFX));
+ PersistMgr->Transfer(TMEMBER(m_SFXStart));
+ PersistMgr->Transfer(TMEMBER(m_SFXVolume));
+ PersistMgr->Transfer(TMEMBER(m_Ready));
+ PersistMgr->Transfer(TMEMBER(m_Rect));
+ PersistMgr->Transfer(TMEMBER(m_RectSet));
+ PersistMgr->Transfer(TMEMBER(m_Registrable));
+ PersistMgr->Transfer(TMEMBER(m_Shadowable));
+ PersistMgr->Transfer(TMEMBER(m_SoundEvent));
+ PersistMgr->Transfer(TMEMBER(m_Zoomable));
+
+ PersistMgr->Transfer(TMEMBER(m_ScaleX));
+ PersistMgr->Transfer(TMEMBER(m_ScaleY));
+
+ PersistMgr->Transfer(TMEMBER(m_Rotate));
+ PersistMgr->Transfer(TMEMBER(m_RotateValid));
+ PersistMgr->Transfer(TMEMBER(m_RelativeRotate));
+
+ PersistMgr->Transfer(TMEMBER(m_SaveState));
+ PersistMgr->Transfer(TMEMBER(m_NonIntMouseEvents));
+
+ PersistMgr->Transfer(TMEMBER_INT(m_SFXType));
+ PersistMgr->Transfer(TMEMBER(m_SFXParam1));
+ PersistMgr->Transfer(TMEMBER(m_SFXParam2));
+ PersistMgr->Transfer(TMEMBER(m_SFXParam3));
+ PersistMgr->Transfer(TMEMBER(m_SFXParam4));
+
+
+ PersistMgr->Transfer(TMEMBER_INT(m_BlendMode));
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::SetCursor(char *Filename) {
+ if (!m_SharedCursors) {
+ delete m_Cursor;
+ m_Cursor = NULL;
+ }
+
+ m_SharedCursors = false;
+ m_Cursor = new CBSprite(Game);
+ if (!m_Cursor || FAILED(m_Cursor->LoadFile(Filename))) {
+ delete m_Cursor;
+ m_Cursor = NULL;
+ return E_FAIL;
+ } else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::SetActiveCursor(char *Filename) {
+ delete m_ActiveCursor;
+ m_ActiveCursor = new CBSprite(Game);
+ if (!m_ActiveCursor || FAILED(m_ActiveCursor->LoadFile(Filename))) {
+ delete m_ActiveCursor;
+ m_ActiveCursor = NULL;
+ return E_FAIL;
+ } else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBObject::GetHeight() {
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::HandleMouse(TMouseEvent Event, TMouseButton Button) {
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBObject::HandleKeypress(SDL_Event *event) {
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBObject::HandleMouseWheel(int Delta) {
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::PlaySFX(char *Filename, bool Looping, bool PlayNow, char *EventName, uint32 LoopStart) {
+ // just play loaded sound
+ if (Filename == NULL && m_SFX) {
+ if (Game->m_EditorMode || m_SFXStart) {
+ m_SFX->SetVolume(m_SFXVolume);
+ m_SFX->SetPositionTime(m_SFXStart);
+ if (!Game->m_EditorMode) m_SFXStart = 0;
+ }
+ if (PlayNow) {
+ SetSoundEvent(EventName);
+ if (LoopStart) m_SFX->SetLoopStart(LoopStart);
+ return m_SFX->Play(Looping);
+ } else return S_OK;
+ }
+
+ if (Filename == NULL) return E_FAIL;
+
+ // create new sound
+ delete m_SFX;
+
+ m_SFX = new CBSound(Game);
+ if (m_SFX && SUCCEEDED(m_SFX->SetSound(Filename, SOUND_SFX, true))) {
+ m_SFX->SetVolume(m_SFXVolume);
+ if (m_SFXStart) {
+ m_SFX->SetPositionTime(m_SFXStart);
+ m_SFXStart = 0;
+ }
+ m_SFX->ApplyFX(m_SFXType, m_SFXParam1, m_SFXParam2, m_SFXParam3, m_SFXParam4);
+ if (PlayNow) {
+ SetSoundEvent(EventName);
+ if (LoopStart) m_SFX->SetLoopStart(LoopStart);
+ return m_SFX->Play(Looping);
+ } else return S_OK;
+ } else {
+ delete m_SFX;
+ m_SFX = NULL;
+ return E_FAIL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::StopSFX(bool DeleteSound) {
+ if (m_SFX) {
+ m_SFX->Stop();
+ if (DeleteSound) {
+ delete m_SFX;
+ m_SFX = NULL;
+ }
+ return S_OK;
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::PauseSFX() {
+ if (m_SFX) return m_SFX->Pause();
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::ResumeSFX() {
+ if (m_SFX) return m_SFX->Resume();
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::SetSFXTime(uint32 Time) {
+ m_SFXStart = Time;
+ if (m_SFX && m_SFX->IsPlaying()) return m_SFX->SetPositionTime(Time);
+ else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::SetSFXVolume(int Volume) {
+ m_SFXVolume = Volume;
+ if (m_SFX) return m_SFX->SetVolume(Volume);
+ else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::UpdateSounds() {
+ if (m_SoundEvent) {
+ if (m_SFX && !m_SFX->IsPlaying()) {
+ ApplyEvent(m_SoundEvent);
+ SetSoundEvent(NULL);
+ }
+ }
+
+ if (m_SFX) UpdateOneSound(m_SFX);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::UpdateOneSound(CBSound *Sound) {
+ HRESULT Ret = S_OK;
+
+ if (Sound) {
+ if (m_AutoSoundPanning)
+ Ret = Sound->SetPan(Game->m_SoundMgr->PosToPan(m_PosX - Game->m_OffsetX, m_PosY - Game->m_OffsetY));
+
+ Ret = Sound->ApplyFX(m_SFXType, m_SFXParam1, m_SFXParam2, m_SFXParam3, m_SFXParam4);
+ }
+ return Ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::ResetSoundPan() {
+ if (!m_SFX) return S_OK;
+ else {
+ return m_SFX->SetPan(0.0f);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBObject::GetExtendedFlag(char *FlagName) {
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBObject::IsReady() {
+ return m_Ready;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBObject::SetSoundEvent(char *EventName) {
+ delete[] m_SoundEvent;
+ m_SoundEvent = NULL;
+ if (EventName) {
+ m_SoundEvent = new char[strlen(EventName) + 1];
+ if (m_SoundEvent) strcpy(m_SoundEvent, EventName);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBObject::AfterMove() {
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BObject.h b/engines/wintermute/BObject.h
new file mode 100644
index 0000000000..064cc78fc4
--- /dev/null
+++ b/engines/wintermute/BObject.h
@@ -0,0 +1,144 @@
+/* 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 WINTERMUTE_BOBJECT_H
+#define WINTERMUTE_BOBJECT_H
+
+
+#include "SDL.h"
+#include "BScriptHolder.h"
+#include "persistent.h"
+
+namespace WinterMute {
+
+class CBSprite;
+class CBSound;
+class CBSurface;
+class CBScriptHolder;
+class CScValue;
+class CScStack;
+class CScScript;
+class CBObject : public CBScriptHolder {
+public:
+ TSpriteBlendMode m_BlendMode;
+ virtual HRESULT AfterMove();
+ float m_RelativeRotate;
+ bool m_RotateValid;
+ float m_Rotate;
+ void SetSoundEvent(char *EventName);
+ bool m_Rotatable;
+ uint32 m_AlphaColor;
+ float m_Scale;
+ float m_ScaleX;
+ float m_ScaleY;
+ float m_RelativeScale;
+ virtual bool IsReady();
+ virtual bool GetExtendedFlag(char *FlagName);
+ virtual HRESULT ResetSoundPan();
+ virtual HRESULT UpdateSounds();
+ HRESULT UpdateOneSound(CBSound *Sound);
+ bool m_AutoSoundPanning;
+ uint32 m_SFXStart;
+ int m_SFXVolume;
+ HRESULT SetSFXTime(uint32 Time);
+ HRESULT SetSFXVolume(int Volume);
+ HRESULT ResumeSFX();
+ HRESULT PauseSFX();
+ HRESULT StopSFX(bool DeleteSound = true);
+ HRESULT PlaySFX(char *Filename, bool Looping = false, bool PlayNow = true, char *EventName = NULL, uint32 LoopStart = 0);
+ CBSound *m_SFX;
+
+ TSFXType m_SFXType;
+ float m_SFXParam1;
+ float m_SFXParam2;
+ float m_SFXParam3;
+ float m_SFXParam4;
+
+ virtual bool HandleMouseWheel(int Delta);
+ virtual HRESULT HandleMouse(TMouseEvent Event, TMouseButton Button);
+ virtual bool HandleKeypress(SDL_Event *event);
+ virtual int GetHeight();
+ HRESULT SetCursor(char *Filename);
+ HRESULT SetActiveCursor(char *Filename);
+ HRESULT Cleanup();
+ char *GetCaption(int Case = 1);
+ void SetCaption(char *Caption, int Case = 1);
+ bool m_EditorSelected;
+ bool m_EditorAlwaysRegister;
+ bool m_EditorOnly;
+ bool m_Is3D;
+ DECLARE_PERSISTENT(CBObject, CBScriptHolder)
+ virtual HRESULT ShowCursor();
+ CBSprite *m_Cursor;
+ bool m_SharedCursors;
+ CBSprite *m_ActiveCursor;
+ virtual HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent);
+ virtual HRESULT Listen(CBScriptHolder *param1, uint32 param2);
+ bool m_Ready;
+ bool m_Registrable;
+ bool m_Zoomable;
+ bool m_Shadowable;
+ RECT m_Rect;
+ bool m_RectSet;
+ int m_ID;
+ bool m_Movable;
+ CBObject(CBGame *inGame);
+ virtual ~CBObject();
+ char *m_Caption[7];
+ char *m_SoundEvent;
+ int m_PosY;
+ int m_PosX;
+ bool m_SaveState;
+
+ // base
+ virtual HRESULT Update() {
+ return E_FAIL;
+ };
+ virtual HRESULT Display() {
+ return E_FAIL;
+ };
+ virtual HRESULT InvalidateDeviceObjects() {
+ return S_OK;
+ };
+ virtual HRESULT RestoreDeviceObjects() {
+ return S_OK;
+ };
+ bool m_NonIntMouseEvents;
+
+
+public:
+ // 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();
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BParser.cpp b/engines/wintermute/BParser.cpp
new file mode 100644
index 0000000000..de8dd140d2
--- /dev/null
+++ b/engines/wintermute/BParser.cpp
@@ -0,0 +1,435 @@
+/* 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
+ */
+
+#include "dcgf.h"
+#include "BParser.h"
+#include "BGame.h"
+#include "PlatformSDL.h"
+#include "common/str.h"
+
+#define WHITESPACE " \t\n\r"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////
+CBParser::CBParser(CBGame *inGame): CBBase(inGame) {
+ m_WhiteSpace = new char [strlen(WHITESPACE) + 1];
+ strcpy(m_WhiteSpace, WHITESPACE);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBParser::~CBParser() {
+ if (m_WhiteSpace != NULL) delete [] m_WhiteSpace;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+char *CBParser::GetLastOffender() {
+ return m_LastOffender;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+long CBParser::GetObject(char **buf, TokenDesc *tokens, char **name, char **data) {
+ SkipCharacters(buf, m_WhiteSpace);
+
+ // skip comment lines.
+ while (**buf == ';') {
+ *buf = strchr(*buf, '\n');
+ m_ParserLine++;
+ SkipCharacters(buf, m_WhiteSpace);
+ }
+
+ if (! **buf) // at end of file
+ return PARSERR_EOF;
+
+ // find the token.
+ // for now just use brute force. Improve later.
+ while (tokens->id != 0) {
+ if (!scumm_strnicmp(tokens->token, *buf, strlen(tokens->token))) {
+ // here we could be matching PART of a string
+ // we could detect this here or the token list
+ // could just have the longer tokens first in the list
+ break;
+ }
+ ++tokens;
+ }
+ if (tokens->id == 0) {
+ char *p = strchr(*buf, '\n');
+ if (p && p > *buf) {
+ strncpy(m_LastOffender, *buf, MIN(255, p - *buf));
+ } else strcpy(m_LastOffender, "");
+
+ return PARSERR_TOKENNOTFOUND;
+ }
+ // skip the token
+ *buf += strlen(tokens->token);
+ SkipCharacters(buf, m_WhiteSpace);
+
+ // get optional name
+ *name = GetSubText(buf, '\'', '\''); // single quotes
+ SkipCharacters(buf, m_WhiteSpace);
+
+ // get optional data
+ if (**buf == '=') // An assignment rather than a command/object.
+ *data = GetAssignmentText(buf);
+ else
+ *data = GetSubText(buf, '{', '}');
+
+ return tokens->id;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+long CBParser::GetCommand(char **buf, TokenDesc *tokens, char **params) {
+ if (!*buf) return PARSERR_TOKENNOTFOUND;
+ Game->MiniUpdate();
+ char *name;
+ return GetObject(buf, tokens, &name, params);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBParser::SkipCharacters(char **buf, const char *toSkip) {
+ char ch;
+ while ((ch = **buf) != 0) {
+ if (ch == '\n') m_ParserLine++;
+ if (strchr(toSkip, ch) == NULL)
+ return;
+ ++*buf; // skip this character
+ }
+ // we must be at the end of the buffer if we get here
+}
+
+
+//////////////////////////////////////////////////////////////////////
+char *CBParser::GetSubText(char **buf, char open, char close) {
+ if (**buf == 0 || **buf != open)
+ return 0;
+ ++*buf; // skip opening delimiter
+ char *result = *buf;
+
+ // now find the closing delimiter
+ char theChar;
+ long skip = 1;
+
+ if (open == close) // we cant nest identical delimiters
+ open = 0;
+ while ((theChar = **buf) != 0) {
+ if (theChar == open)
+ ++skip;
+ if (theChar == close) {
+ if (--skip == 0) {
+ **buf = 0; // null terminate the result string
+ ++*buf; // move past the closing delimiter
+ break;
+ }
+ }
+ ++*buf; // try next character
+ }
+ return result;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+char *CBParser::GetAssignmentText(char **buf) {
+ ++*buf; // skip the '='
+ SkipCharacters(buf, m_WhiteSpace);
+ char *result = *buf;
+
+
+ if (*result == '"') {
+ result = GetSubText(buf, '"', '"');
+ } else {
+ // now, we need to find the next whitespace to end the data
+ char theChar;
+
+ while ((theChar = **buf) != 0) {
+ if (theChar <= 0x20) // space and control chars
+ break;
+ ++*buf;
+ }
+ **buf = 0; // null terminate it
+ if (theChar) // skip the terminator
+ ++*buf;
+ }
+
+ return result;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+char *CBParser::GetToken(char **buf) {
+ static char token[100];
+ char *b = *buf, * t = token;
+ while (true) {
+ while (*b && (*b == ' ' || *b == '\n' || *b == 13 || *b == 10 || *b == '\t')) b++;
+ if (*b == ';')
+ while (*b && *b != '\n' && *b != 13 && *b != 10) b++;
+ else break;
+ }
+
+ if (*b == '\'') {
+ b++;
+ while (*b && *b != '\'') {
+ *t++ = *b++;
+ }
+ *t++ = 0;
+ if (*b == '\'') b++;
+ } else if (*b == '(' || *b == ')' || *b == '=' || *b == ',' || *b == '[' || *b == ']' ||
+ *b == '%' || *b == ':' || *b == '{' || *b == '}') {
+ *t++ = *b++;
+ *t++ = 0;
+ } else if (*b == '.' && (*(b + 1) < '0' || *(b + 1) > '9')) {
+ *t++ = *b++;
+ *t++ = 0;
+ } else if ((*b >= '0' && *b <= '9') || *b == '.' || *b == '-') {
+ while (*b && ((*b >= '0' && *b <= '9') || *b == '.' || *b == '-')) {
+ *t++ = *b++;
+ }
+ *t++ = 0;
+ } else if ((*b >= 'A' && *b <= 'Z') || (*b >= 'a' && *b <= 'z') || *b == '_') {
+ while (*b && ((*b >= 'A' && *b <= 'Z') || (*b >= 'a' && *b <= 'z') || *b == '_')) {
+ *t++ = *b++;
+ }
+ *t++ = 0;
+ } else if (*b == 0) {
+ *buf = b;
+ return NULL;
+ } else {
+ // Error.
+ return NULL;
+ }
+
+ *buf = b;
+ return token;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+float CBParser::GetTokenFloat(char **buf) {
+ char *t = GetToken(buf);
+ if (!((*t >= '0' && *t <= '9') || *t == '-' || *t == '.')) {
+ // Error situation. We handle this by return 0.
+ return 0.;
+ }
+ float rc = (float)atof(t);
+ return rc;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBParser::GetTokenInt(char **buf) {
+ char *t = GetToken(buf);
+ if (!((*t >= '0' && *t <= '9') || *t == '-')) {
+ // Error situation. We handle this by return 0.
+ return 0;
+ }
+ int rc = atoi(t);
+ return rc;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBParser::SkipToken(char **buf, char *tok, char * /*msg*/) {
+ char *t = GetToken(buf);
+ if (strcmp(t, tok)) return; // Error
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBParser::ScanStr(const char *in, const char *format, ...) {
+ va_list arg;
+ va_start(arg, format);
+
+ int num = 0;
+ in += strspn(in, " \t\n\f");
+
+ while (*format && *in) {
+ if (*format == '%') {
+ format++;
+ switch (*format) {
+ case 'd': {
+ int *a = va_arg(arg, int *);
+ in += strspn(in, " \t\n\f");
+ *a = atoi(in);
+ in += strspn(in, "0123456789+- \t\n\f");
+ num++;
+ break;
+ }
+ case 'D': {
+ int i;
+ int *list = va_arg(arg, int *);
+ int *nr = va_arg(arg, int *);
+ in += strspn(in, " \t\n\f");
+ i = 0;
+ while ((*in >= '0' && *in <= '9') || *in == '+' || *in == '-') {
+ list[i++] = atoi(in);
+ in += strspn(in, "0123456789+-");
+ in += strspn(in, " \t\n\f");
+ if (*in != ',') break;
+ in++;
+ in += strspn(in, " \t\n\f");
+ }
+ *nr = i;
+ num++;
+ break;
+ }
+ case 'b': {
+ bool *a = va_arg(arg, bool *);
+ in += strspn(in, " \t\n\f");
+ const char *in2 = in + strspn(in, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ int l = (int)(in2 - in);
+
+ *a = (bool)(!scumm_strnicmp(in, "yes", l) || !scumm_strnicmp(in, "true", l) || !scumm_strnicmp(in, "on", l) ||
+ !scumm_strnicmp(in, "1", l));
+
+
+ in = in2 + strspn(in2, " \t\n\f");
+ num++;
+ break;
+ }
+ case 'f': {
+ float *a = va_arg(arg, float *);
+ in += strspn(in, " \t\n\f");
+ *a = (float)atof(in);
+ in += strspn(in, "0123456789.eE+- \t\n\f");
+ num++;
+ break;
+ }
+ case 'F': {
+ int i;
+ float *list = va_arg(arg, float *);
+ int *nr = va_arg(arg, int *);
+ in += strspn(in, " \t\n\f");
+ i = 0;
+ while ((*in >= '0' && *in <= '9') || *in == '.' || *in == '+' || *in == '-' || *in == 'e' || *in == 'E') {
+ list[i++] = (float)atof(in);
+ in += strspn(in, "0123456789.eE+-");
+ in += strspn(in, " \t\n\f");
+ if (*in != ',') break;
+ in++;
+ in += strspn(in, " \t\n\f");
+ }
+ *nr = i;
+ num++;
+ break;
+ }
+ case 's': {
+ char *a = va_arg(arg, char *);
+ in += strspn(in, " \t\n\f");
+ if (*in == '\'') {
+ in++;
+ const char *in2 = strchr(in, '\'');
+ if (in2) {
+ strncpy(a, in, (int)(in2 - in));
+ a[(int)(in2 - in)] = 0;
+ in = in2 + 1;
+ } else {
+ strcpy(a, in);
+ in = strchr(in, 0);
+ }
+ } else {
+ const char *in2 = in + strspn(in, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789.");
+ strncpy(a, in, (int)(in2 - in));
+ a[(int)(in2 - in)] = 0;
+ in = in2;
+ }
+ in += strspn(in, " \t\n\f");
+ num++;
+ break;
+ }
+ case 'S': {
+ char *a = va_arg(arg, char *);
+ in += strspn(in, " \t\n\f");
+ if (*in == '\"') {
+ in++;
+ while (*in != '\"') {
+ if (*in == '\\') {
+ in++;
+ switch (*in) {
+ case '\\':
+ *a++ = '\\';
+ break;
+ case 'n':
+ *a++ = '\n';
+ break;
+ case 'r':
+ *a++ = '\r';
+ break;
+ case 't':
+ *a++ = '\t';
+ break;
+ case '"':
+ *a++ = '"';
+ break;
+ default:
+ *a++ = '\\';
+ *a++ = *in;
+ break;
+ } //switch
+ in++;
+ } else {
+ *a++ = *in++;
+ }
+ } //while in string
+ in++;
+ num++;
+ } //if string started
+
+ //terminate string
+ *a = '\0';
+ break;
+ }
+ }
+ if (*format) format++;
+ } else if (*format == ' ') {
+ format++;
+ in += strspn(in, " \t\n\f");
+ } else if (*in == *format) {
+ in++;
+ format++;
+ } else {
+ num = -1;
+ break;
+ }
+ }
+
+ va_end(arg);
+
+ return num;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BParser.h b/engines/wintermute/BParser.h
new file mode 100644
index 0000000000..6e4282c833
--- /dev/null
+++ b/engines/wintermute/BParser.h
@@ -0,0 +1,88 @@
+/* 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 WINTERMUTE_BPARSER_H
+#define WINTERMUTE_BPARSER_H
+
+
+#define TOKEN_DEF_START \
+ enum \
+ { \
+ TOKEN_NONE = 0,
+#define TOKEN_DEF(name) \
+ TOKEN_ ## name,
+#define TOKEN_DEF_END \
+ TOKEN_TOTAL_COUNT \
+ };
+#define TOKEN_TABLE_START(name) \
+ static CBParser::TokenDesc name [] = \
+ {
+#define TOKEN_TABLE(name) \
+ { TOKEN_ ## name, #name },
+#define TOKEN_TABLE_END \
+ { 0, 0 } \
+ };
+
+#define PARSERR_GENERIC -3
+#define PARSERR_EOF -2
+#define PARSERR_TOKENNOTFOUND -1
+
+#include "BBase.h"
+#include "coll_templ.h"
+
+namespace WinterMute {
+
+class CBParser : public CBBase {
+public:
+ struct TokenDesc {
+ long id;
+ const char *token;
+ };
+
+public:
+ int ScanStr(const char *in, const char *format, ...);
+ char *GetLastOffender();
+ void SkipToken(char **buf, char *tok, char *msg = NULL);
+ int GetTokenInt(char **buf);
+ float GetTokenFloat(char **buf);
+ char *GetToken(char **buf);
+ char *GetAssignmentText(char **buf);
+ char *GetSubText(char **buf, char open, char close);
+ void SkipCharacters(char **buf, const char *toSkip);
+ long GetCommand(char **buf, TokenDesc *tokens, char **params);
+ long GetObject(char **buf, TokenDesc *tokens, char **name, char **data);
+ int m_ParserLine;
+ char m_LastOffender[255];
+ CBParser(CBGame *inGame = NULL);
+ virtual ~CBParser();
+ char *m_WhiteSpace;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BPersistMgr.cpp b/engines/wintermute/BPersistMgr.cpp
new file mode 100644
index 0000000000..e4002d9299
--- /dev/null
+++ b/engines/wintermute/BPersistMgr.cpp
@@ -0,0 +1,517 @@
+/* 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
+ */
+
+#include "dcgf.h"
+#include "BFileManager.h"
+#include "BGame.h"
+#include "BPersistMgr.h"
+#include "BSaveThumbHelper.h"
+#include "PlatformSDL.h"
+#include "Vector2.h"
+#include "StringUtil.h"
+#include "BImage.h"
+#include "BSound.h"
+#include "common/str.h"
+
+namespace WinterMute {
+
+#define SAVE_BUFFER_INIT_SIZE 100000
+#define SAVE_BUFFER_GROW_BY 50000
+
+#define SAVE_MAGIC 0x45564153
+#define SAVE_MAGIC_2 0x32564153
+
+//////////////////////////////////////////////////////////////////////////
+CBPersistMgr::CBPersistMgr(CBGame *inGame): CBBase(inGame) {
+ m_Saving = false;
+ m_Buffer = NULL;
+ m_BufferSize = 0;
+ m_Offset = 0;
+
+ m_RichBuffer = NULL;
+ m_RichBufferSize = 0;
+
+ m_SavedDescription = NULL;
+ m_SavedTimestamp = 0;
+ m_SavedVerMajor = m_SavedVerMinor = m_SavedVerBuild = 0;
+ m_SavedExtMajor = m_SavedExtMinor = 0;
+
+ m_ThumbnailDataSize = 0;
+ m_ThumbnailData = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBPersistMgr::~CBPersistMgr() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBPersistMgr::Cleanup() {
+ if (m_Buffer) {
+ if (m_Saving) free(m_Buffer);
+ else delete [] m_Buffer; // allocated by file manager
+ }
+ m_Buffer = NULL;
+
+ m_BufferSize = 0;
+ m_Offset = 0;
+
+ delete[] m_RichBuffer;
+ m_RichBuffer = NULL;
+ m_RichBufferSize = 0;
+
+ m_SavedDescription = NULL; // ref to buffer
+ m_SavedTimestamp = 0;
+ m_SavedVerMajor = m_SavedVerMinor = m_SavedVerBuild = 0;
+ m_SavedExtMajor = m_SavedExtMinor = 0;
+
+ m_ThumbnailDataSize = 0;
+ if (m_ThumbnailData) {
+ delete [] m_ThumbnailData;
+ m_ThumbnailData = NULL;
+ }
+}
+
+// TODO: This is not at all endian-safe
+uint32 makeUint32(byte first, byte second, byte third, byte fourth) {
+ uint32 retVal = first;
+ retVal = retVal & second << 8 & third << 16 & fourth << 24;
+ return retVal;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPersistMgr::InitSave(char *Desc) {
+ if (!Desc) return E_FAIL;
+
+ HRESULT res;
+
+ Cleanup();
+ m_Saving = true;
+
+ m_Buffer = (byte *)malloc(SAVE_BUFFER_INIT_SIZE);
+ if (m_Buffer) {
+ m_BufferSize = SAVE_BUFFER_INIT_SIZE;
+ res = S_OK;
+ } else res = E_FAIL;
+
+
+ if (SUCCEEDED(res)) {
+ // get thumbnails
+ if (!Game->m_CachedThumbnail) {
+ Game->m_CachedThumbnail = new CBSaveThumbHelper(Game);
+ if (FAILED(Game->m_CachedThumbnail->StoreThumbnail(true))) {
+ delete Game->m_CachedThumbnail;
+ Game->m_CachedThumbnail = NULL;
+ }
+ }
+
+
+ uint32 magic = DCGF_MAGIC;
+ PutDWORD(magic);
+
+ magic = SAVE_MAGIC_2;
+ PutDWORD(magic);
+
+ byte VerMajor, VerMinor, ExtMajor, ExtMinor;
+ Game->GetVersion(&VerMajor, &VerMinor, &ExtMajor, &ExtMinor);
+ //uint32 Version = MAKELONG(MAKEWORD(VerMajor, VerMinor), MAKEWORD(ExtMajor, ExtMinor));
+ uint32 Version = makeUint32(VerMajor, VerMinor, ExtMajor, ExtMinor);
+ PutDWORD(Version);
+
+ // new in ver 2
+ PutDWORD((uint32)DCGF_VER_BUILD);
+ PutString(Game->m_Name);
+
+ // thumbnail data size
+ bool ThumbnailOK = false;
+
+ if (Game->m_CachedThumbnail) {
+ if (Game->m_CachedThumbnail->m_Thumbnail) {
+ uint32 Size = 0;
+ byte *Buffer = Game->m_CachedThumbnail->m_Thumbnail->CreateBMPBuffer(&Size);
+
+ PutDWORD(Size);
+ if (Size > 0) PutBytes(Buffer, Size);
+
+ delete [] Buffer;
+ ThumbnailOK = true;
+ }
+ }
+ if (!ThumbnailOK) PutDWORD(0);
+
+ // in any case, destroy the cached thumbnail once used
+ delete Game->m_CachedThumbnail;
+ Game->m_CachedThumbnail = NULL;
+
+ uint32 DataOffset = m_Offset +
+ sizeof(uint32) + // data offset
+ sizeof(uint32) + strlen(Desc) + 1 + // description
+ sizeof(uint32); // timestamp
+
+ PutDWORD(DataOffset);
+ PutString(Desc);
+
+ time_t Timestamp;
+ time(&Timestamp);
+ PutDWORD((uint32)Timestamp);
+ }
+ return res;
+}
+// TODO: Do this properly, this is just a quickfix, that probably doesnt even work.
+// The main point of which is ditching BASS completely.
+byte getLowByte(uint16 word) {
+ uint16 mask = 0xff;
+ return word & mask;
+}
+
+byte getHighByte(uint16 word) {
+ uint16 mask = 0xff << 8;
+ word = word & mask;
+ return word >> 8;
+}
+
+uint16 getLowWord(uint32 dword) {
+ uint32 mask = 0xffff;
+ return dword & mask;
+}
+
+uint16 getHighWord(uint32 dword) {
+ uint32 mask = 0xffff << 16;
+ dword = dword & mask;
+ return dword >> 16;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPersistMgr::InitLoad(char *Filename) {
+ Cleanup();
+
+ m_Saving = false;
+
+ m_Buffer = Game->m_FileManager->ReadWholeFile(Filename, &m_BufferSize);
+ if (m_Buffer) {
+ uint32 Magic;
+ Magic = GetDWORD();
+ if (Magic != DCGF_MAGIC) goto init_fail;
+
+ Magic = GetDWORD();
+
+ if (Magic == SAVE_MAGIC || Magic == SAVE_MAGIC_2) {
+ uint32 Version = GetDWORD();
+ m_SavedVerMajor = getLowByte(getLowWord(Version));
+ m_SavedVerMinor = getHighByte(getLowWord(Version));
+ m_SavedExtMajor = getLowByte(getHighWord(Version));
+ m_SavedExtMinor = getHighByte(getHighWord(Version));
+
+ if (Magic == SAVE_MAGIC_2) {
+ m_SavedVerBuild = (byte )GetDWORD();
+ char *SavedName = GetString();
+ if (SavedName == NULL || scumm_stricmp(SavedName, Game->m_Name) != 0) {
+ Game->LOG(0, "ERROR: Saved game name doesn't match current game");
+ goto init_fail;
+ }
+
+ // load thumbnail
+ m_ThumbnailDataSize = GetDWORD();
+ if (m_ThumbnailDataSize > 0) {
+ m_ThumbnailData = new byte[m_ThumbnailDataSize];
+ if (m_ThumbnailData) {
+ GetBytes(m_ThumbnailData, m_ThumbnailDataSize);
+ } else m_ThumbnailDataSize = 0;
+ }
+ } else m_SavedVerBuild = 35; // last build with ver1 savegames
+
+
+ // if save is newer version than we are, fail
+ if (m_SavedVerMajor > DCGF_VER_MAJOR ||
+ (m_SavedVerMajor == DCGF_VER_MAJOR && m_SavedVerMinor > DCGF_VER_MINOR) ||
+ (m_SavedVerMajor == DCGF_VER_MAJOR && m_SavedVerMinor == DCGF_VER_MINOR && m_SavedVerBuild > DCGF_VER_BUILD)
+ ) {
+ Game->LOG(0, "ERROR: Saved game version is newer than current game");
+ goto init_fail;
+ }
+
+ // if save is older than the minimal version we support
+ if (m_SavedVerMajor < SAVEGAME_VER_MAJOR ||
+ (m_SavedVerMajor == SAVEGAME_VER_MAJOR && m_SavedVerMinor < SAVEGAME_VER_MINOR) ||
+ (m_SavedVerMajor == SAVEGAME_VER_MAJOR && m_SavedVerMinor == SAVEGAME_VER_MINOR && m_SavedVerBuild < SAVEGAME_VER_BUILD)
+ ) {
+ Game->LOG(0, "ERROR: Saved game is too old and cannot be used by this version of game engine");
+ goto init_fail;
+ }
+
+ /*
+ if( m_SavedVerMajor != DCGF_VER_MAJOR || m_SavedVerMinor != DCGF_VER_MINOR)
+ {
+ Game->LOG(0, "ERROR: Saved game is created by other WME version");
+ goto init_fail;
+ }
+ */
+ } else goto init_fail;
+
+
+ uint32 DataOffset = GetDWORD();
+
+ m_SavedDescription = GetString();
+ m_SavedTimestamp = (time_t)GetDWORD();
+
+ m_Offset = DataOffset;
+
+ return S_OK;
+ }
+
+init_fail:
+ Cleanup();
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPersistMgr::SaveFile(char *Filename) {
+ return Game->m_FileManager->SaveFile(Filename, m_Buffer, m_Offset, Game->m_CompressedSavegames, m_RichBuffer, m_RichBufferSize);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPersistMgr::PutBytes(byte *Buffer, uint32 Size) {
+ while (m_Offset + Size > m_BufferSize) {
+ m_BufferSize += SAVE_BUFFER_GROW_BY;
+ m_Buffer = (byte *)realloc(m_Buffer, m_BufferSize);
+ if (!m_Buffer) {
+ Game->LOG(0, "Error reallocating save buffer to %d bytes", m_BufferSize);
+ return E_FAIL;
+ }
+ }
+
+ memcpy(m_Buffer + m_Offset, Buffer, Size);
+ m_Offset += Size;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPersistMgr::GetBytes(byte *Buffer, uint32 Size) {
+ if (m_Offset + Size > m_BufferSize) {
+ Game->LOG(0, "Fatal: Save buffer underflow");
+ return E_FAIL;
+ }
+
+ memcpy(Buffer, m_Buffer + m_Offset, Size);
+ m_Offset += Size;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBPersistMgr::PutDWORD(uint32 Val) {
+ PutBytes((byte *)&Val, sizeof(uint32));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBPersistMgr::GetDWORD() {
+ uint32 ret;
+ GetBytes((byte *)&ret, sizeof(uint32));
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBPersistMgr::PutString(const char *Val) {
+ if (!Val) PutString("(null)");
+ else {
+ PutDWORD(strlen(Val) + 1);
+ PutBytes((byte *)Val, strlen(Val) + 1);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBPersistMgr::GetString() {
+ uint32 len = GetDWORD();
+ char *ret = (char *)(m_Buffer + m_Offset);
+ m_Offset += len;
+
+ if (!strcmp(ret, "(null)")) return NULL;
+ else return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// bool
+HRESULT CBPersistMgr::Transfer(const char *Name, bool *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(bool));
+ else return GetBytes((byte *)Val, sizeof(bool));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// int
+HRESULT CBPersistMgr::Transfer(const char *Name, int *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(int));
+ else return GetBytes((byte *)Val, sizeof(int));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// DWORD
+HRESULT CBPersistMgr::Transfer(const char *Name, uint32 *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(uint32));
+ else return GetBytes((byte *)Val, sizeof(uint32));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// float
+HRESULT CBPersistMgr::Transfer(const char *Name, float *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(float));
+ else return GetBytes((byte *)Val, sizeof(float));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// double
+HRESULT CBPersistMgr::Transfer(const char *Name, double *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(double));
+ else return GetBytes((byte *)Val, sizeof(double));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// char*
+HRESULT CBPersistMgr::Transfer(const char *Name, char **Val) {
+ if (m_Saving) {
+ PutString(*Val);
+ return S_OK;
+ } else {
+ char *str = GetString();
+ if (str) {
+
+ *Val = new char[strlen(str) + 1];
+ strcpy(*Val, str);
+ } else *Val = NULL;
+ return S_OK;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPersistMgr::Transfer(const char *Name, AnsiStringArray &Val) {
+ size_t size;
+
+ if (m_Saving) {
+ size = Val.size();
+ PutBytes((byte *)&size, sizeof(size_t));
+
+ for (AnsiStringArray::iterator it = Val.begin(); it != Val.end(); ++it) {
+ PutString((*it).c_str());
+ }
+ } else {
+ Val.clear();
+ GetBytes((byte *)&size, sizeof(size_t));
+
+ for (size_t i = 0; i < size; i++) {
+ char *str = GetString();
+ if (str) Val.push_back(str);
+ }
+ }
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// BYTE
+HRESULT CBPersistMgr::Transfer(const char *Name, byte *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(byte ));
+ else return GetBytes((byte *)Val, sizeof(byte ));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// RECT
+HRESULT CBPersistMgr::Transfer(const char *Name, RECT *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(RECT));
+ else return GetBytes((byte *)Val, sizeof(RECT));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// POINT
+HRESULT CBPersistMgr::Transfer(const char *Name, POINT *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(POINT));
+ else return GetBytes((byte *)Val, sizeof(POINT));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// Vector2
+HRESULT CBPersistMgr::Transfer(const char *Name, Vector2 *Val) {
+ if (m_Saving) return PutBytes((byte *)Val, sizeof(Vector2));
+ else return GetBytes((byte *)Val, sizeof(Vector2));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// generic pointer
+HRESULT CBPersistMgr::Transfer(const char *Name, void *Val) {
+ int ClassID = -1, InstanceID = -1;
+
+ if (m_Saving) {
+ CSysClassRegistry::GetInstance()->GetPointerID(*(void **)Val, &ClassID, &InstanceID);
+ if (*(void **)Val != NULL && (ClassID == -1 || InstanceID == -1)) {
+ Game->LOG(0, "Warning: invalid instance '%s'", Name);
+ }
+
+ PutDWORD(ClassID);
+ PutDWORD(InstanceID);
+ } else {
+ ClassID = GetDWORD();
+ InstanceID = GetDWORD();
+
+ *(void **)Val = CSysClassRegistry::GetInstance()->IDToPointer(ClassID, InstanceID);
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBPersistMgr::CheckVersion(byte VerMajor, byte VerMinor, byte VerBuild) {
+ if (m_Saving) return true;
+
+ // it's ok if we are same or newer than the saved game
+ if (VerMajor > m_SavedVerMajor ||
+ (VerMajor == m_SavedVerMajor && VerMinor > m_SavedVerMinor) ||
+ (VerMajor == m_SavedVerMajor && VerMinor == m_SavedVerMinor && VerBuild > m_SavedVerBuild)
+ ) return false;
+
+ return true;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BPersistMgr.h b/engines/wintermute/BPersistMgr.h
new file mode 100644
index 0000000000..6a1e42da8a
--- /dev/null
+++ b/engines/wintermute/BPersistMgr.h
@@ -0,0 +1,89 @@
+/* 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 WINTERMUTE_BPERSISTMGR_H
+#define WINTERMUTE_BPERSISTMGR_H
+
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class Vector2;
+
+class CBPersistMgr : public CBBase {
+public:
+ char *m_SavedDescription;
+ time_t m_SavedTimestamp;
+ byte m_SavedVerMajor;
+ byte m_SavedVerMinor;
+ byte m_SavedVerBuild;
+ byte m_SavedExtMajor;
+ byte m_SavedExtMinor;
+ HRESULT SaveFile(char *Filename);
+ uint32 GetDWORD();
+ void PutDWORD(uint32 Val);
+ char *GetString();
+ void PutString(const char *Val);
+ void Cleanup();
+ HRESULT InitLoad(char *Filename);
+ HRESULT InitSave(char *Desc);
+ HRESULT GetBytes(byte *Buffer, uint32 Size);
+ HRESULT PutBytes(byte *Buffer, uint32 Size);
+ uint32 m_Offset;
+ uint32 m_BufferSize;
+ byte *m_Buffer;
+ bool m_Saving;
+
+ uint32 m_RichBufferSize;
+ byte *m_RichBuffer;
+
+ HRESULT Transfer(const char *Name, void *Val);
+ HRESULT Transfer(const char *Name, int *Val);
+ HRESULT Transfer(const char *Name, uint32 *Val);
+ HRESULT Transfer(const char *Name, float *Val);
+ HRESULT Transfer(const char *Name, double *Val);
+ HRESULT Transfer(const char *Name, bool *Val);
+ HRESULT Transfer(const char *Name, byte *Val);
+ HRESULT Transfer(const char *Name, RECT *Val);
+ HRESULT Transfer(const char *Name, POINT *Val);
+ HRESULT Transfer(const char *Name, char **Val);
+ HRESULT Transfer(const char *Name, Vector2 *Val);
+ HRESULT Transfer(const char *Name, AnsiStringArray &Val);
+ CBPersistMgr(CBGame *inGame = NULL);
+ virtual ~CBPersistMgr();
+ bool CheckVersion(byte VerMajor, byte VerMinor, byte VerBuild);
+
+ uint32 m_ThumbnailDataSize;
+ byte *m_ThumbnailData;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BScriptHolder.h b/engines/wintermute/BScriptHolder.h
new file mode 100644
index 0000000000..aaa5176bcf
--- /dev/null
+++ b/engines/wintermute/BScriptHolder.h
@@ -0,0 +1,81 @@
+/* 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 WINTERMUTE_BSCRIPTHOLDER_H
+#define WINTERMUTE_BSCRIPTHOLDER_H
+
+#include "coll_templ.h"
+#include "persistent.h"
+// TODO: Reinclude any of this.
+//#include "BScriptable.h"
+
+namespace WinterMute {
+
+//class CBScriptHolder : public CBScriptable {
+class CBScriptHolder : CBBase {
+public:
+ DECLARE_PERSISTENT(CBScriptHolder, CBBase) // <- TODO, quickfix for compile
+#if 0
+ DECLARE_PERSISTENT(CBScriptHolder, CBScriptable)
+
+ CBScriptHolder(CBGame *inGame);
+ virtual ~CBScriptHolder();
+
+ virtual CScScript *InvokeMethodThread(char *MethodName);
+ virtual void MakeFreezable(bool Freezable);
+ bool CanHandleEvent(char *EventName);
+ virtual bool CanHandleMethod(char *EventMethod);
+ HRESULT Cleanup();
+ HRESULT RemoveScript(CScScript *Script);
+ HRESULT AddScript(char *Filename);
+ virtual HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent);
+ virtual HRESULT Listen(CBScriptHolder *param1, uint32 param2);
+ HRESULT ApplyEvent(const char *EventName, bool Unbreakable = false);
+ void SetFilename(char *Filename);
+ HRESULT ParseProperty(byte *Buffer, bool Complete = true);
+
+ char *m_Filename;
+ bool m_Freezable;
+ bool m_Ready;
+ CBArray<CScScript *, CScScript *> m_Scripts;
+
+ // 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);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/PlatformSDL.h b/engines/wintermute/PlatformSDL.h
new file mode 100644
index 0000000000..029902fab9
--- /dev/null
+++ b/engines/wintermute/PlatformSDL.h
@@ -0,0 +1,92 @@
+/* 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 WINTERMUTE_PLATFORMSDL_H
+#define WINTERMUTE_PLATFORMSDL_H
+
+#include "dctypes.h"
+
+#include "wintypes.h"
+
+union SDL_Event;
+
+namespace WinterMute {
+
+class CBGame;
+
+
+//////////////////////////////////////////////////////////////////////////
+class CBPlatform {
+public:
+ static int Initialize(CBGame *inGame, int argc, char *argv[]);
+ static int MessageLoop();
+ static void HandleEvent(SDL_Event *event);
+
+ static AnsiString GetSystemFontPath();
+ static AnsiString GetPlatformName();
+
+ // Win32 API bindings
+ static HINSTANCE ShellExecute(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd);
+ static void OutputDebugString(LPCSTR lpOutputString);
+ static uint32 GetTime();
+ static BOOL GetCursorPos(LPPOINT lpPoint);
+ static BOOL SetCursorPos(int X, int Y);
+ static BOOL ShowWindow(HWND hWnd, int nCmdShow);
+ static bool DeleteFile(const char *lpFileName);
+ static bool CopyFile(const char *from, const char *to, bool failIfExists);
+ static HWND SetCapture(HWND hWnd);
+ static BOOL ReleaseCapture();
+ static BOOL SetForegroundWindow(HWND hWnd);
+
+ static BOOL SetRectEmpty(LPRECT lprc);
+ static BOOL IsRectEmpty(const LPRECT lprc);
+ static BOOL PtInRect(LPRECT lprc, POINT p);
+ static BOOL SetRect(LPRECT lprc, int left, int top, int right, int bottom);
+ static BOOL IntersectRect(LPRECT lprcDst, const LPRECT lprcSrc1, const LPRECT lprcSrc2);
+ static BOOL UnionRect(LPRECT lprcDst, RECT *lprcSrc1, RECT *lprcSrc2);
+ static BOOL CopyRect(LPRECT lprcDst, RECT *lprcSrc);
+ static BOOL OffsetRect(LPRECT lprc, int dx, int dy);
+ static BOOL EqualRect(LPRECT rect1, LPRECT rect2);
+
+
+ // string functions
+// static int stricmp(const char *str1, const char *str2);
+// static int strnicmp(const char *str1, const char *str2, size_t maxCount);
+ static char *strupr(char *string);
+ static char *strlwr(char *string);
+
+ // sdl event callback
+ static int SDLEventWatcher(void *userdata, SDL_Event *event);
+
+private:
+ static CBGame *Game;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/SysClass.cpp b/engines/wintermute/SysClass.cpp
new file mode 100644
index 0000000000..a673943b57
--- /dev/null
+++ b/engines/wintermute/SysClass.cpp
@@ -0,0 +1,203 @@
+/* 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
+ */
+
+#include "persistent.h"
+#include "SysInstance.h"
+#include "SysClass.h"
+#include "SysClassRegistry.h"
+#include "BGame.h"
+#include "BPersistMgr.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CSysClass::CSysClass(const AnsiString &name, PERSISTBUILD build, PERSISTLOAD load, bool persistent_class) {
+ m_Name = name;
+
+ m_Build = build;
+ m_Load = load;
+ m_Next = NULL;
+ m_SavedID = -1;
+ m_Persistent = persistent_class;
+ m_NumInst = 0;
+
+ CSysClassRegistry::GetInstance()->RegisterClass(this);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CSysClass::~CSysClass() {
+ CSysClassRegistry::GetInstance()->UnregisterClass(this);
+ RemoveAllInstances();
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClass::RemoveAllInstances() {
+ Instances::iterator it;
+ for (it = m_Instances.begin(); it != m_Instances.end(); ++it) {
+ delete(*it);
+ }
+ m_Instances.clear();
+ m_InstanceMap.clear();
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSysInstance *CSysClass::AddInstance(void *instance, int id, int savedId) {
+ CSysInstance *inst = new CSysInstance(instance, id, this);
+ inst->SetSavedID(savedId);
+ m_Instances.insert(inst);
+
+ m_InstanceMap[instance] = inst;
+
+ CSysClassRegistry::GetInstance()->AddInstanceToTable(inst, instance);
+
+ return inst;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClass::RemoveInstance(void *instance) {
+ InstanceMap::iterator mapIt = m_InstanceMap.find(instance);
+ if (mapIt == m_InstanceMap.end()) return false;
+
+ Instances::iterator it = m_Instances.find((*mapIt).second);
+ if (it != m_Instances.end()) {
+ delete(*it);
+ m_Instances.erase(it);
+ }
+
+ m_InstanceMap.erase(mapIt);
+
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CSysClass::GetInstanceID(void *pointer) {
+ InstanceMap::iterator mapIt = m_InstanceMap.find(pointer);
+ if (mapIt == m_InstanceMap.end()) return -1;
+ else return (*mapIt).second->GetID();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void *CSysClass::IDToPointer(int savedID) {
+ //slow
+ Instances::iterator it;
+ for (it = m_Instances.begin(); it != m_Instances.end(); ++it) {
+ if ((*it)->GetSavedID() == savedID) return (*it)->GetInstance();
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CSysClass::GetNumInstances() {
+ return m_Instances.size();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::Dump(FILE *stream) {
+ fprintf(stream, "%03d %c %-20s instances: %d\n", m_ID, m_Persistent ? 'p' : ' ', m_Name.c_str(), GetNumInstances());
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::SaveTable(CBGame *Game, CBPersistMgr *PersistMgr) {
+ PersistMgr->PutString(m_Name.c_str());
+ PersistMgr->PutDWORD(m_ID);
+ PersistMgr->PutDWORD(m_Instances.size());
+
+ Instances::iterator it;
+ for (it = m_Instances.begin(); it != m_Instances.end(); ++it) {
+ PersistMgr->PutDWORD((*it)->GetID());
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::LoadTable(CBGame *Game, CBPersistMgr *PersistMgr) {
+ m_SavedID = PersistMgr->GetDWORD();
+ int numInstances = PersistMgr->GetDWORD();
+
+ for (int i = 0; i < numInstances; i++) {
+ if (m_Persistent) {
+ int instId = PersistMgr->GetDWORD();
+
+ if (i > 0) {
+ Game->LOG(0, "Warning: attempting to load multiple instances of persistent class %s (%d)", m_Name.c_str(), numInstances);
+ continue;
+ }
+
+ Instances::iterator it = m_Instances.begin();
+ if (it != m_Instances.end()) {
+ (*it)->SetSavedID(instId);
+ CSysClassRegistry::GetInstance()->AddInstanceToTable((*it), (*it)->GetInstance());
+ } else Game->LOG(0, "Warning: instance %d of persistent class %s not found", i, m_Name.c_str());
+ }
+ // normal instances, create empty objects
+ else {
+ void *emptyObject = m_Build();
+ AddInstance(emptyObject, CSysClassRegistry::GetInstance()->GetNextID(), PersistMgr->GetDWORD());
+ }
+
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::SaveInstances(CBGame *Game, CBPersistMgr *PersistMgr) {
+ Instances::iterator it;
+ for (it = m_Instances.begin(); it != m_Instances.end(); ++it) {
+ // write instace header
+ PersistMgr->PutDWORD(m_ID);
+ PersistMgr->PutDWORD((*it)->GetID());
+
+ m_Load((*it)->GetInstance(), PersistMgr);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::LoadInstance(void *instance, CBPersistMgr *PersistMgr) {
+ m_Load(instance, PersistMgr);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::ResetSavedIDs() {
+ Instances::iterator it;
+ for (it = m_Instances.begin(); it != m_Instances.end(); ++it) {
+ (*it)->SetSavedID(-1);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClass::InstanceCallback(SYS_INSTANCE_CALLBACK lpCallback, void *lpData) {
+ Instances::iterator it;
+ for (it = m_Instances.begin(); it != m_Instances.end(); ++it) {
+ lpCallback((*it)->GetInstance(), lpData);
+ }
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/SysClass.h b/engines/wintermute/SysClass.h
new file mode 100644
index 0000000000..21d4acd594
--- /dev/null
+++ b/engines/wintermute/SysClass.h
@@ -0,0 +1,101 @@
+/*
+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 __WmeSysClass_H__
+#define __WmeSysClass_H__
+
+#include "persistent.h"
+#include <set>
+#include <map>
+#include "dctypes.h"
+
+namespace WinterMute {
+class CSysInstance;
+class CBGame;
+class CBPersistMgr;
+class CSysClass {
+public:
+ CSysClass(const AnsiString &name, PERSISTBUILD build, PERSISTLOAD load, bool persistent_class);
+ ~CSysClass();
+
+ int GetNumInstances();
+ bool RemoveInstance(void *instance);
+ CSysInstance *AddInstance(void *instance, int id, int savedId = -1);
+ bool RemoveAllInstances();
+
+ int GetInstanceID(void *pointer);
+ void *IDToPointer(int savedID);
+
+ void SetID(int id) {
+ m_ID = id;
+ }
+ int GetID() const {
+ return m_ID;
+ }
+
+ int GetSavedID() const {
+ return m_SavedID;
+ }
+
+ bool IsPersistent() const {
+ return m_Persistent;
+ }
+
+ AnsiString GetName() const {
+ return m_Name;
+ }
+
+ void SaveTable(CBGame *Game, CBPersistMgr *PersistMgr);
+ void LoadTable(CBGame *Game, CBPersistMgr *PersistMgr);
+
+ void SaveInstances(CBGame *Game, CBPersistMgr *PersistMgr);
+ void LoadInstance(void *instance, CBPersistMgr *PersistMgr);
+
+ void InstanceCallback(SYS_INSTANCE_CALLBACK lpCallback, void *lpData);
+
+ void ResetSavedIDs();
+
+ void Dump(FILE *stream);
+
+private:
+ int m_NumInst;
+ bool m_Persistent;
+ CSysClass *m_Next;
+ int m_ID;
+ int m_SavedID;
+ AnsiString m_Name;
+ PERSISTBUILD m_Build;
+ PERSISTLOAD m_Load;
+
+ typedef std::set<CSysInstance *> Instances;
+ Instances m_Instances;
+
+ typedef std::map<void *, CSysInstance *> InstanceMap;
+ InstanceMap m_InstanceMap;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/SysClassRegistry.cpp b/engines/wintermute/SysClassRegistry.cpp
new file mode 100644
index 0000000000..72740a79cf
--- /dev/null
+++ b/engines/wintermute/SysClassRegistry.cpp
@@ -0,0 +1,287 @@
+/* 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
+ */
+
+#include "BGame.h"
+#include "PlatformSDL.h"
+#include "SysInstance.h"
+#include "SysClassRegistry.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CSysClassRegistry::CSysClassRegistry() {
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CSysClassRegistry::~CSysClassRegistry() {
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSysClassRegistry *CSysClassRegistry::GetInstance() {
+ static CSysClassRegistry classReg;
+ return &classReg;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClassRegistry::RegisterClass(CSysClass *classObj) {
+ classObj->SetID(m_Count++);
+ m_Classes.insert(classObj);
+
+ m_NameMap[classObj->GetName()] = classObj;
+ m_IdMap[classObj->GetID()] = classObj;
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClassRegistry::UnregisterClass(CSysClass *classObj) {
+
+ Classes::iterator it = m_Classes.find(classObj);
+ if (it == m_Classes.end()) return false;
+
+ if (classObj->GetNumInstances() != 0) {
+ char str[MAX_PATH];
+ sprintf(str, "Memory leak@class %-20s: %d instance(s) left\n", classObj->GetName().c_str(), classObj->GetNumInstances());
+ CBPlatform::OutputDebugString(str);
+ }
+ m_Classes.erase(it);
+
+ NameMap::iterator mapIt = m_NameMap.find(classObj->GetName());
+ if (mapIt != m_NameMap.end()) m_NameMap.erase(mapIt);
+
+ IdMap::iterator idIt = m_IdMap.find(classObj->GetID());
+ if (idIt != m_IdMap.end()) m_IdMap.erase(idIt);
+
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClassRegistry::RegisterInstance(const char *className, void *instance) {
+ if (m_Disabled) return true;
+
+ NameMap::iterator mapIt = m_NameMap.find(className);
+ if (mapIt == m_NameMap.end()) return false;
+
+ CSysInstance *inst = (*mapIt).second->AddInstance(instance, m_Count++);
+ return (inst != NULL);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClassRegistry::AddInstanceToTable(CSysInstance *instance, void *pointer) {
+ m_InstanceMap[pointer] = instance;
+
+ if (instance->GetSavedID() >= 0)
+ m_SavedInstanceMap[instance->GetSavedID()] = instance;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CSysClassRegistry::GetNextID() {
+ return m_Count++;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClassRegistry::UnregisterInstance(const char *className, void *instance) {
+ NameMap::iterator mapIt = m_NameMap.find(className);
+ if (mapIt == m_NameMap.end()) return false;
+ (*mapIt).second->RemoveInstance(instance);
+
+ InstanceMap::iterator instIt = m_InstanceMap.find(instance);
+ if (instIt != m_InstanceMap.end()) {
+ m_InstanceMap.erase(instIt);
+ return true;
+ } else return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CSysClassRegistry::GetPointerID(void *pointer, int *classID, int *instanceID) {
+ if (pointer == NULL) return true;
+
+ InstanceMap::iterator it = m_InstanceMap.find(pointer);
+ if (it == m_InstanceMap.end()) return false;
+
+
+ CSysInstance *inst = (*it).second;
+ *instanceID = inst->GetID();
+ *classID = inst->GetClass()->GetID();
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void *CSysClassRegistry::IDToPointer(int classID, int instanceID) {
+ SavedInstanceMap::iterator it = m_SavedInstanceMap.find(instanceID);
+ if (it == m_SavedInstanceMap.end()) return NULL;
+ else return (*it).second->GetInstance();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSysClassRegistry::SaveTable(CBGame *Game, CBPersistMgr *PersistMgr, bool quickSave) {
+ PersistMgr->PutDWORD(m_Classes.size());
+
+ int counter = 0;
+
+ Classes::iterator it;
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it) {
+ counter++;
+
+ if (!quickSave) {
+ Game->m_IndicatorProgress = 50.0f / (float)((float)m_Classes.size() / (float)counter);
+ Game->DisplayContent(false);
+ Game->m_Renderer->Flip();
+ }
+
+ (*it)->SaveTable(Game, PersistMgr);
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSysClassRegistry::LoadTable(CBGame *Game, CBPersistMgr *PersistMgr) {
+ Classes::iterator it;
+
+ // reset SavedID of current instances
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it) {
+ (*it)->ResetSavedIDs();
+ }
+
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it) {
+ if ((*it)->IsPersistent()) continue;
+ (*it)->RemoveAllInstances();
+ }
+
+ m_InstanceMap.clear();
+
+
+ int numClasses = PersistMgr->GetDWORD();
+
+ for (int i = 0; i < numClasses; i++) {
+ Game->m_IndicatorProgress = 50.0f / (float)((float)numClasses / (float)i);
+ Game->DisplayContentSimple();
+ Game->m_Renderer->Flip();
+
+ char *className = PersistMgr->GetString();
+ NameMap::iterator mapIt = m_NameMap.find(className);
+ if (mapIt != m_NameMap.end())(*mapIt).second->LoadTable(Game, PersistMgr);
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSysClassRegistry::SaveInstances(CBGame *Game, CBPersistMgr *PersistMgr, bool quickSave) {
+
+ Classes::iterator it;
+
+ // count total instances
+ int numInstances = 0;
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it) {
+ numInstances += (*it)->GetNumInstances();
+ }
+
+ PersistMgr->PutDWORD(numInstances);
+
+ int counter = 0;
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it) {
+ counter++;
+
+ if (!quickSave) {
+ if (counter % 20 == 0) {
+ Game->m_IndicatorProgress = 50 + 50.0f / (float)((float)m_Classes.size() / (float)counter);
+ Game->DisplayContent(false);
+ Game->m_Renderer->Flip();
+ }
+ }
+ Game->MiniUpdate();
+
+ (*it)->SaveInstances(Game, PersistMgr);
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSysClassRegistry::LoadInstances(CBGame *Game, CBPersistMgr *PersistMgr) {
+ // get total instances
+ int numInstances = PersistMgr->GetDWORD();
+
+ for (int i = 0; i < numInstances; i++) {
+ if (i % 20 == 0) {
+ Game->m_IndicatorProgress = 50 + 50.0f / (float)((float)numInstances / (float)i);
+ Game->DisplayContentSimple();
+ Game->m_Renderer->Flip();
+ }
+
+ int classID = PersistMgr->GetDWORD();
+ int instanceID = PersistMgr->GetDWORD();
+ void *instance = IDToPointer(classID, instanceID);
+
+
+ Classes::iterator it;
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it) {
+ if ((*it)->GetSavedID() == classID) {
+ (*it)->LoadInstance(instance, PersistMgr);
+ }
+ }
+ }
+
+ m_SavedInstanceMap.clear();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CSysClassRegistry::EnumInstances(SYS_INSTANCE_CALLBACK lpCallback, const char *className, void *lpData) {
+ NameMap::iterator mapIt = m_NameMap.find(className);
+ if (mapIt == m_NameMap.end()) return E_FAIL;
+
+ (*mapIt).second->InstanceCallback(lpCallback, lpData);
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CSysClassRegistry::DumpClasses(FILE *stream) {
+ Classes::iterator it;
+ for (it = m_Classes.begin(); it != m_Classes.end(); ++it)
+ (*it)->Dump(stream);
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/SysClassRegistry.h b/engines/wintermute/SysClassRegistry.h
new file mode 100644
index 0000000000..1a73f28010
--- /dev/null
+++ b/engines/wintermute/SysClassRegistry.h
@@ -0,0 +1,89 @@
+/* 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 WINTERMUTE_SYSCLASSREGISTRY_H
+#define WINTERMUTE_SYSCLASSREGISTRY_H
+
+#include "wintypes.h"
+#include "dctypes.h"
+#include "persistent.h"
+#include <set>
+#include <map>
+
+namespace WinterMute {
+
+class CBGame;
+class CBPersistMgr;
+class CSysClass;
+class CSysInstance;
+
+class CSysClassRegistry {
+public:
+ static CSysClassRegistry *GetInstance();
+
+ HRESULT EnumInstances(SYS_INSTANCE_CALLBACK lpCallback, const char *className, void *lpData);
+ HRESULT LoadTable(CBGame *Game, CBPersistMgr *PersistMgr);
+ HRESULT SaveTable(CBGame *Game, CBPersistMgr *PersistMgr, bool quickSave);
+ HRESULT LoadInstances(CBGame *Game, CBPersistMgr *PersistMgr);
+ HRESULT SaveInstances(CBGame *Game, CBPersistMgr *PersistMgr, bool quickSave);
+ void *IDToPointer(int classID, int instanceID);
+ bool GetPointerID(void *pointer, int *classID, int *instanceID);
+ bool RegisterClass(CSysClass *classObj);
+ bool UnregisterClass(CSysClass *classObj);
+ bool RegisterInstance(const char *className, void *instance);
+ bool UnregisterInstance(const char *className, void *instance);
+ void DumpClasses(FILE *stream);
+ int GetNextID();
+ void AddInstanceToTable(CSysInstance *instance, void *pointer);
+
+ CSysClassRegistry();
+ virtual ~CSysClassRegistry();
+
+ bool m_Disabled;
+ int m_Count;
+
+ typedef std::set<CSysClass *> Classes;
+ Classes m_Classes;
+
+ typedef std::map<AnsiString, CSysClass *> NameMap;
+ NameMap m_NameMap;
+
+ typedef std::map<int, CSysClass *> IdMap;
+ IdMap m_IdMap;
+
+ typedef std::map<void *, CSysInstance *> InstanceMap;
+ InstanceMap m_InstanceMap;
+
+ typedef std::map<int, CSysInstance *> SavedInstanceMap;
+ SavedInstanceMap m_SavedInstanceMap;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/SysInstance.cpp b/engines/wintermute/SysInstance.cpp
new file mode 100644
index 0000000000..b937136706
--- /dev/null
+++ b/engines/wintermute/SysInstance.cpp
@@ -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 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
+ */
+
+#include "SysInstance.h"
+#include "SysClass.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CSysInstance::CSysInstance(void *Instance, int ID, CSysClass *sysClass) {
+ m_Instance = Instance;
+ m_ID = ID;
+ m_SavedID = -1;
+ m_Class = sysClass;
+
+ m_Used = false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CSysInstance::~CSysInstance() {
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/SysInstance.h b/engines/wintermute/SysInstance.h
new file mode 100644
index 0000000000..0286204c8e
--- /dev/null
+++ b/engines/wintermute/SysInstance.h
@@ -0,0 +1,68 @@
+/* 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 WINTERMUTE_SYSINSTANCE_H
+#define WINTERMUTE_SYSINSTANCE_H
+
+namespace WinterMute {
+
+class CSysClass;
+
+class CSysInstance {
+public:
+ CSysInstance(void *Instance, int ID, CSysClass *sysClass);
+ virtual ~CSysInstance();
+
+ int GetID() const {
+ return m_ID;
+ }
+ int GetSavedID() const {
+ return m_SavedID;
+ }
+ void *GetInstance() const {
+ return m_Instance;
+ }
+ CSysClass *GetClass() const {
+ return m_Class;
+ }
+
+ void SetSavedID(int id) {
+ m_SavedID = id;
+ }
+
+private:
+ bool m_Used;
+ int m_ID;
+ int m_SavedID;
+ void *m_Instance;
+ CSysClass *m_Class;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/coll_templ.h b/engines/wintermute/coll_templ.h
new file mode 100644
index 0000000000..bcd11126a9
--- /dev/null
+++ b/engines/wintermute/coll_templ.h
@@ -0,0 +1,372 @@
+/* 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 WINTERMUTE_COLL_TEMPL_H
+#define WINTERMUTE_COLL_TEMPL_H
+
+
+#include <new>
+#include "BPersistMgr.h"
+
+namespace WinterMute {
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE>
+inline void DCConstructElements(TYPE *pElements, int nCount) {
+ // first do bit-wise zero initialization
+ memset((void *)pElements, 0, nCount * sizeof(TYPE));
+
+ // then call the constructor(s)
+ for (; nCount--; pElements++)
+ ::new((void *)pElements) TYPE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE>
+inline void DCDestructElements(TYPE *pElements, int nCount) {
+ // call the destructor(s)
+ for (; nCount--; pElements++)
+ pElements->~TYPE();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE>
+inline void DCCopyElements(TYPE *pDest, const TYPE *pSrc, int nCount) {
+ // default is element-copy using assignment
+ while (nCount--)
+ *pDest++ = *pSrc++;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+BOOL DCCompareElements(const TYPE *pElement1, const ARG_TYPE *pElement2) {
+ return *pElement1 == *pElement2;
+}
+
+//class CBPersistMgr;
+
+/////////////////////////////////////////////////////////////////////////////
+// CBArray<TYPE, ARG_TYPE>
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+class CBArray {
+public:
+// Construction
+ CBArray();
+
+// Attributes
+ int GetSize() const;
+ int GetUpperBound() const;
+ void SetSize(int nNewSize, int nGrowBy = -1);
+
+// Operations
+ // Clean up
+ void FreeExtra();
+ void RemoveAll();
+ HRESULT Persist(CBPersistMgr *PersistMgr);
+
+ // Accessing elements
+ TYPE GetAt(int nIndex) const;
+ void SetAt(int nIndex, ARG_TYPE newElement);
+ TYPE &ElementAt(int nIndex);
+
+ // Direct Access to the element data (may return NULL)
+ const TYPE *GetData() const;
+ TYPE *GetData();
+
+ // Potentially growing the array
+ void SetAtGrow(int nIndex, ARG_TYPE newElement);
+ int Add(ARG_TYPE newElement);
+ int Append(const CBArray &src);
+ void Copy(const CBArray &src);
+
+ // overloaded operator helpers
+ TYPE operator[](int nIndex) const;
+ TYPE &operator[](int nIndex);
+
+ // Operations that move elements around
+ void InsertAt(int nIndex, ARG_TYPE newElement, int nCount = 1);
+ void RemoveAt(int nIndex, int nCount = 1);
+ void InsertAt(int nStartIndex, CBArray *pNewArray);
+
+// Implementation
+protected:
+ TYPE *m_pData; // the actual array of data
+ int m_nSize; // # of elements (upperBound - 1)
+ int m_nMaxSize; // max allocated
+ int m_nGrowBy; // grow amount
+
+public:
+ ~CBArray();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CBArray<TYPE, ARG_TYPE> inline functions
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+inline int CBArray<TYPE, ARG_TYPE>::GetSize() const {
+ return m_nSize;
+}
+template<class TYPE, class ARG_TYPE>
+inline int CBArray<TYPE, ARG_TYPE>::GetUpperBound() const {
+ return m_nSize - 1;
+}
+template<class TYPE, class ARG_TYPE>
+inline void CBArray<TYPE, ARG_TYPE>::RemoveAll() {
+ SetSize(0, -1);
+}
+template<class TYPE, class ARG_TYPE>
+inline TYPE CBArray<TYPE, ARG_TYPE>::GetAt(int nIndex) const {
+ return m_pData[nIndex];
+}
+template<class TYPE, class ARG_TYPE>
+inline void CBArray<TYPE, ARG_TYPE>::SetAt(int nIndex, ARG_TYPE newElement) {
+ m_pData[nIndex] = newElement;
+}
+template<class TYPE, class ARG_TYPE>
+inline TYPE &CBArray<TYPE, ARG_TYPE>::ElementAt(int nIndex) {
+ return m_pData[nIndex];
+}
+template<class TYPE, class ARG_TYPE>
+inline const TYPE *CBArray<TYPE, ARG_TYPE>::GetData() const {
+ return (const TYPE *)m_pData;
+}
+template<class TYPE, class ARG_TYPE>
+inline TYPE *CBArray<TYPE, ARG_TYPE>::GetData() {
+ return (TYPE *)m_pData;
+}
+template<class TYPE, class ARG_TYPE>
+inline int CBArray<TYPE, ARG_TYPE>::Add(ARG_TYPE newElement) {
+ int nIndex = m_nSize;
+ SetAtGrow(nIndex, newElement);
+ return nIndex;
+}
+template<class TYPE, class ARG_TYPE>
+inline TYPE CBArray<TYPE, ARG_TYPE>::operator[](int nIndex) const {
+ return GetAt(nIndex);
+}
+template<class TYPE, class ARG_TYPE>
+inline TYPE &CBArray<TYPE, ARG_TYPE>::operator[](int nIndex) {
+ return ElementAt(nIndex);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBArray<TYPE, ARG_TYPE> out-of-line functions
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+CBArray<TYPE, ARG_TYPE>::CBArray() {
+ m_pData = NULL;
+ m_nSize = m_nMaxSize = m_nGrowBy = 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+CBArray<TYPE, ARG_TYPE>::~CBArray() {
+ if (m_pData != NULL) {
+ DCDestructElements<TYPE>(m_pData, m_nSize);
+ delete[](byte *)m_pData;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::SetSize(int nNewSize, int nGrowBy) {
+ if (nGrowBy != -1)
+ m_nGrowBy = nGrowBy; // set new size
+
+ if (nNewSize == 0) {
+ // shrink to nothing
+ if (m_pData != NULL) {
+ DCDestructElements<TYPE>(m_pData, m_nSize);
+ delete[](byte *)m_pData;
+ m_pData = NULL;
+ }
+ m_nSize = m_nMaxSize = 0;
+ } else if (m_pData == NULL) {
+ // create one with exact size
+ m_pData = (TYPE *) new byte[nNewSize * sizeof(TYPE)];
+ DCConstructElements<TYPE>(m_pData, nNewSize);
+ m_nSize = m_nMaxSize = nNewSize;
+ } else if (nNewSize <= m_nMaxSize) {
+ // it fits
+ if (nNewSize > m_nSize) {
+ // initialize the new elements
+ DCConstructElements<TYPE>(&m_pData[m_nSize], nNewSize - m_nSize);
+ } else if (m_nSize > nNewSize) {
+ // destroy the old elements
+ DCDestructElements<TYPE>(&m_pData[nNewSize], m_nSize - nNewSize);
+ }
+ m_nSize = nNewSize;
+ } else {
+ // otherwise, grow array
+ int nGrowBy = m_nGrowBy;
+ if (nGrowBy == 0) {
+ // heuristically determine growth when nGrowBy == 0
+ // (this avoids heap fragmentation in many situations)
+ nGrowBy = m_nSize / 8;
+ nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy);
+ }
+ int nNewMax;
+ if (nNewSize < m_nMaxSize + nGrowBy)
+ nNewMax = m_nMaxSize + nGrowBy; // granularity
+ else
+ nNewMax = nNewSize; // no slush
+
+ TYPE *pNewData = (TYPE *) new byte[nNewMax * sizeof(TYPE)];
+
+ // copy new data from old
+ memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
+
+ // construct remaining elements
+ DCConstructElements<TYPE>(&pNewData[m_nSize], nNewSize - m_nSize);
+
+ // get rid of old stuff (note: no destructors called)
+ delete[](byte *)m_pData;
+ m_pData = pNewData;
+ m_nSize = nNewSize;
+ m_nMaxSize = nNewMax;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+int CBArray<TYPE, ARG_TYPE>::Append(const CBArray &src) {
+ int nOldSize = m_nSize;
+ SetSize(m_nSize + src.m_nSize);
+ DCCopyElements<TYPE>(m_pData + nOldSize, src.m_pData, src.m_nSize);
+ return nOldSize;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::Copy(const CBArray &src) {
+ SetSize(src.m_nSize);
+ DCCopyElements<TYPE>(m_pData, src.m_pData, src.m_nSize);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::FreeExtra() {
+ if (m_nSize != m_nMaxSize) {
+ // shrink to desired size
+ TYPE *pNewData = NULL;
+ if (m_nSize != 0) {
+ pNewData = (TYPE *) new byte[m_nSize * sizeof(TYPE)];
+ // copy new data from old
+ memcpy(pNewData, m_pData, m_nSize * sizeof(TYPE));
+ }
+
+ // get rid of old stuff (note: no destructors called)
+ delete[](byte *)m_pData;
+ m_pData = pNewData;
+ m_nMaxSize = m_nSize;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement) {
+ if (nIndex >= m_nSize)
+ SetSize(nIndex + 1, -1);
+ m_pData[nIndex] = newElement;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::InsertAt(int nIndex, ARG_TYPE newElement, int nCount /*=1*/) {
+ if (nIndex >= m_nSize) {
+ // adding after the end of the array
+ SetSize(nIndex + nCount, -1); // grow so nIndex is valid
+ } else {
+ // inserting in the middle of the array
+ int nOldSize = m_nSize;
+ SetSize(m_nSize + nCount, -1); // grow it to new size
+ // destroy intial data before copying over it
+ DCDestructElements<TYPE>(&m_pData[nOldSize], nCount);
+ // shift old data up to fill gap
+ memmove(&m_pData[nIndex + nCount], &m_pData[nIndex],
+ (nOldSize - nIndex) * sizeof(TYPE));
+
+ // re-init slots we copied from
+ DCConstructElements<TYPE>(&m_pData[nIndex], nCount);
+ }
+
+ // insert new value in the gap
+ while (nCount--)
+ m_pData[nIndex++] = newElement;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::RemoveAt(int nIndex, int nCount) {
+ // just remove a range
+ int nMoveCount = m_nSize - (nIndex + nCount);
+ DCDestructElements<TYPE>(&m_pData[nIndex], nCount);
+ if (nMoveCount)
+ memcpy(&m_pData[nIndex], &m_pData[nIndex + nCount],
+ nMoveCount * sizeof(TYPE));
+ m_nSize -= nCount;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+void CBArray<TYPE, ARG_TYPE>::InsertAt(int nStartIndex, CBArray *pNewArray) {
+ if (pNewArray->GetSize() > 0) {
+ InsertAt(nStartIndex, pNewArray->GetAt(0), pNewArray->GetSize());
+ for (int i = 0; i < pNewArray->GetSize(); i++)
+ SetAt(nStartIndex + i, pNewArray->GetAt(i));
+ }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class TYPE, class ARG_TYPE>
+HRESULT CBArray<TYPE, ARG_TYPE>::Persist(CBPersistMgr *PersistMgr) {
+ int i, j;
+ if (PersistMgr->m_Saving) {
+ j = GetSize();
+ PersistMgr->Transfer("ArraySize", &j);
+ for (i = 0; i < j; i++) {
+ ARG_TYPE obj = GetAt(i);
+ PersistMgr->Transfer("", &obj);
+ }
+ } else {
+ SetSize(0, -1);
+ PersistMgr->Transfer("ArraySize", &j);
+ for (i = 0; i < j; i++) {
+ ARG_TYPE obj;
+ PersistMgr->Transfer("", &obj);
+ Add(obj);
+ }
+ }
+ return S_OK;
+}
+
+} // end of namespace WinterMute
+
+#endif // COLL_TEMPL_H
diff --git a/engines/wintermute/dcgf.h b/engines/wintermute/dcgf.h
new file mode 100644
index 0000000000..8fba050f34
--- /dev/null
+++ b/engines/wintermute/dcgf.h
@@ -0,0 +1,62 @@
+/* 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 WINTERMUTE_DCGF_H
+#define WINTERMUTE_DCGF_H
+
+
+//////////////////////////////////////////////////////////////////////////
+#define DCGF_VER_MAJOR 1
+#define DCGF_VER_MINOR 0
+#define DCGF_VER_BUILD 1
+#define DCGF_VER_SUFFIX "beta"
+#define DCGF_VER_BETA true
+
+#define DCGF_NAME "WME Lite"
+#define DCGF_MAGIC 0xDEC0ADDE
+
+// minimal saved game version we support
+#define SAVEGAME_VER_MAJOR 1
+#define SAVEGAME_VER_MINOR 0
+#define SAVEGAME_VER_BUILD 0
+//////////////////////////////////////////////////////////////////////////
+
+#define COMPRESSED_FILE_MAGIC 0x504D435A // ZCMP
+
+#ifdef GetClassName
+#undef GetClassName
+#endif
+
+// macros
+#define RELEASE(obj) if(obj) { obj->Release(); obj = NULL; } else 0
+#define SAFE_DELETE(obj) if(obj) { delete obj; obj = NULL; } else 0
+#define SAFE_DELETE_ARRAY(obj) if(obj) { delete [] obj; obj = NULL; } else 0
+#define DegToRad(_val) (_val*PI*(1.0f/180.0f))
+#define RadToDeg(_val) (_val*(180/PI))
+
+#endif // _DCGF_H_
diff --git a/engines/wintermute/dctypes.h b/engines/wintermute/dctypes.h
new file mode 100644
index 0000000000..0ee5a6bf54
--- /dev/null
+++ b/engines/wintermute/dctypes.h
@@ -0,0 +1,181 @@
+/* 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 WINTERMUTE_DCTYPES_H
+#define WINTERMUTE_DCTYPES_H
+
+#include <string>
+#include <list>
+#include <vector>
+
+namespace WinterMute {
+
+typedef std::string AnsiString;
+typedef std::string Utf8String;
+typedef std::wstring WideString;
+
+
+typedef std::list<WideString> WideStringList;
+typedef std::list<AnsiString> AnsiStringList;
+
+typedef std::vector<WideString> WideStringArray;
+typedef std::vector<AnsiString> AnsiStringArray;
+
+
+enum TGameState {
+ GAME_RUNNING, GAME_FROZEN, GAME_SEMI_FROZEN
+};
+
+
+enum TImageType { IMG_PALETTED8, IMG_TRUECOLOR } ;
+
+
+enum TTextAlign {
+ TAL_LEFT = 0, TAL_RIGHT, TAL_CENTER, NUM_TEXT_ALIGN
+};
+
+
+enum TVerticalAlign {
+ VAL_TOP = 0, VAL_CENTER, VAL_BOTTOM, NUM_VERTICAL_ALIGN
+};
+
+
+enum TDirection {
+ DI_UP = 0, DI_UPRIGHT = 1, DI_RIGHT = 2, DI_DOWNRIGHT = 3, DI_DOWN = 4, DI_DOWNLEFT = 5, DI_LEFT = 6, DI_UPLEFT = 7, NUM_DIRECTIONS = 8, DI_NONE = 9
+};
+
+
+enum TEventType {
+ EVENT_NONE = 0,
+ EVENT_INIT = 1,
+ EVENT_SHUTDOWN = 2,
+ EVENT_LEFT_CLICK = 3,
+ EVENT_RIGHT_CLICK = 4,
+ EVENT_MIDDLE_CLICK = 5,
+ EVENT_LEFT_DBLCLICK = 6,
+ EVENT_PRESS = 7,
+ EVENT_IDLE = 8,
+ EVENT_MOUSE_OVER = 9,
+ EVENT_LEFT_RELEASE = 10,
+ EVENT_RIGHT_RELEASE = 11,
+ EVENT_MIDDLE_RELEASE = 12,
+ NUM_EVENTS
+};
+
+
+enum TUIObjectType {
+ UI_UNKNOWN, UI_BUTTON, UI_WINDOW, UI_STATIC, UI_EDIT, UI_HTML, UI_CUSTOM
+};
+
+
+enum TRendererState {
+ RSTATE_3D, RSTATE_2D, RSTATE_LINES, RSTATE_NONE
+};
+
+
+enum TDynamicConstructor {
+ DYNAMIC_CONSTRUCTOR
+};
+
+enum TSeek {
+ SEEK_TO_BEGIN = SEEK_SET,
+ SEEK_TO_CURRENT = SEEK_CUR,
+ SEEK_TO_END = SEEK_END
+};
+
+enum TSoundType {
+ SOUND_SFX, SOUND_MUSIC, SOUND_SPEECH
+};
+
+enum TVideoMode {
+ VIDEO_WINDOW, VIDEO_FULLSCREEN, VIDEO_ANY
+};
+
+
+enum TVideoPlayback {
+ VID_PLAY_POS = 0,
+ VID_PLAY_STRETCH = 1,
+ VID_PLAY_CENTER = 2
+};
+
+
+enum TMouseEvent {
+ MOUSE_CLICK, MOUSE_RELEASE, MOUSE_DBLCLICK
+};
+
+
+enum TMouseButton {
+ MOUSE_BUTTON_LEFT, MOUSE_BUTTON_RIGHT, MOUSE_BUTTON_MIDDLE
+};
+
+
+enum TTransMgrState{
+ TRANS_MGR_RUNNING, TRANS_MGR_READY
+};
+
+
+enum TTransitionType{
+ TRANSITION_NONE = 0,
+ TRANSITION_FADE_OUT = 1,
+ TRANSITION_FADE_IN = 2,
+ NUM_TRANSITION_TYPES
+};
+
+
+enum TWindowMode {
+ WINDOW_NORMAL, WINDOW_EXCLUSIVE, WINDOW_SYSTEM_EXCLUSIVE
+};
+
+enum TSFXType {
+ SFX_NONE, SFX_ECHO, SFX_REVERB
+};
+
+
+enum TSpriteCacheType {
+ CACHE_ALL, CACHE_HALF
+};
+
+enum TTextEncoding {
+ TEXT_ANSI = 0, TEXT_UTF8 = 1, NUM_TEXT_ENCODINGS
+};
+
+enum TSpriteBlendMode {
+ BLEND_UNKNOWN = -1, BLEND_NORMAL = 0, BLEND_ADDITIVE = 1, BLEND_SUBTRACTIVE = 2, NUM_BLEND_MODES
+};
+
+enum TTTSType {
+ TTS_CAPTION = 0, TTS_TALK, TTS_KEYPRESS
+};
+
+enum TShadowType {
+ SHADOW_NONE = 0, SHADOW_SIMPLE = 1, SHADOW_FLAT = 2, SHADOW_STENCIL = 3
+};
+
+} // end of namespace WinterMute
+
+#endif // DCTYPES_H
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 4096e8d8e6..2eda176c75 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -1,7 +1,11 @@
MODULE := engines/wintermute
MODULE_OBJS := \
+ BBase.o \
+ BParser.o \
detection.o \
+ SysClass.o \
+ SysInstance.o \
wintermute.o
MODULE_DIRS += \
@@ -13,4 +17,4 @@ PLUGIN := 1
endif
# Include common rules
-include $(srcdir)/rules.mk \ No newline at end of file
+include $(srcdir)/rules.mk
diff --git a/engines/wintermute/persistent.h b/engines/wintermute/persistent.h
new file mode 100644
index 0000000000..2e1c9f3214
--- /dev/null
+++ b/engines/wintermute/persistent.h
@@ -0,0 +1,89 @@
+/*
+ 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 WINTERMUTE_PERSISTENT_H
+#define WINTERMUTE_PERSISTENT_H
+
+#include "wintypes.h"
+
+namespace WinterMute {
+
+ class CBPersistMgr;
+
+ // persistence support
+ typedef void *(WINAPI *PERSISTBUILD)(void);
+ typedef HRESULT(WINAPI *PERSISTLOAD)(void *, CBPersistMgr *);
+ typedef void (*SYS_INSTANCE_CALLBACK)(void *Instance, void *Data);
+} // end of namespace WinterMute
+
+#include "SysClass.h"
+#include "SysClassRegistry.h"
+namespace WinterMute {
+
+
+#define DECLARE_PERSISTENT(class_name, parent_class)\
+static const char m_ClassName[];\
+static void* WINAPI PersistBuild(void);\
+virtual const char* GetClassName();\
+static HRESULT WINAPI PersistLoad(void* Instance, CBPersistMgr* PersistMgr);\
+class_name(TDynamicConstructor p1, TDynamicConstructor p2):parent_class(p1, p2){ /*memset(this, 0, sizeof(class_name));*/ };\
+virtual HRESULT Persist(CBPersistMgr* PersistMgr);\
+void* operator new (size_t size);\
+void operator delete(void* p);\
+
+
+#define IMPLEMENT_PERSISTENT(class_name, persistent_class)\
+const char class_name::m_ClassName[] = #class_name;\
+void* class_name::PersistBuild(){\
+return ::new class_name(DYNAMIC_CONSTRUCTOR, DYNAMIC_CONSTRUCTOR);\
+}\
+\
+HRESULT class_name::PersistLoad(void* Instance, CBPersistMgr* PersistMgr){\
+return ((class_name*)Instance)->Persist(PersistMgr);\
+}\
+\
+const char* class_name::GetClassName(){\
+return #class_name;\
+}\
+\
+CSysClass Register##class_name(class_name::m_ClassName, class_name::PersistBuild, class_name::PersistLoad, persistent_class);\
+\
+void* class_name::operator new (size_t size){\
+void* ret = ::operator new(size);\
+CSysClassRegistry::GetInstance()->RegisterInstance(#class_name, ret);\
+return ret;\
+}\
+\
+void class_name::operator delete (void* p){\
+CSysClassRegistry::GetInstance()->UnregisterInstance(#class_name, p);\
+::operator delete(p);\
+}\
+
+#define TMEMBER(member_name) #member_name, &member_name
+#define TMEMBER_INT(member_name) #member_name, (int*)&member_name
+
+} // end of namespace WinterMute
+
+#endif // WINTERMUTE_PERSISTENT_H
diff --git a/engines/wintermute/wintypes.h b/engines/wintermute/wintypes.h
new file mode 100644
index 0000000000..89c1ef6e53
--- /dev/null
+++ b/engines/wintermute/wintypes.h
@@ -0,0 +1,117 @@
+/*
+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 __WmeWintypes_H__
+#define __WmeWintypes_H__
+
+#define FORBIDDEN_SYMBOL_ALLOW_ALL
+#include "common/scummsys.h"
+
+//namespace WinterMute {
+#include <cstdio>
+#include <stdio.h>
+#ifndef __WIN32__
+
+#define WINAPI
+#define CALLBACK
+
+#ifndef __OBJC__
+typedef int BOOL;
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif
+
+#define PI ((float) 3.141592653589793f)
+#define DRGBA(r,g,b,a) ((uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
+
+#define D3DCOLGetB(rgb) ((byte )(rgb))
+#define D3DCOLGetG(rgb) ((byte )(((WORD)(rgb)) >> 8))
+#define D3DCOLGetR(rgb) ((byte )((rgb)>>16))
+#define D3DCOLGetA(rgb) ((byte )((rgb)>>24))
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define CONST const
+
+#define MAX_PATH 512
+
+typedef char CHAR;
+typedef short SHORT;
+typedef int32_t LONG;
+
+typedef uint16 WORD;
+//typedef uint32 QWORD; // HACK for now
+typedef int INT;
+typedef unsigned int UINT;
+
+typedef CHAR *NPSTR, *LPSTR, *PSTR;
+typedef PSTR *PZPSTR;
+typedef const PSTR *PCZPSTR;
+typedef const CHAR *LPCSTR, *PCSTR;
+typedef PCSTR *PZPCSTR;
+
+typedef struct tagRECT {
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+} RECT, *LPRECT;
+
+
+typedef struct tagPOINT {
+ LONG x;
+ LONG y;
+} POINT, *LPPOINT;
+
+
+typedef uint32 HINSTANCE;
+typedef uint32 HMODULE;
+typedef uint32 HWND;
+
+//typedef uint32 HRESULT;
+typedef long HRESULT;
+
+#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
+#define FAILED(hr) (((HRESULT)(hr)) < 0)
+
+#define S_OK ((HRESULT)0)
+//#define S_FALSE ((HRESULT)1)
+#define E_FAIL ((HRESULT)-1)
+
+
+#endif // !__WIN32__
+
+//} // end of namespace WinterMute
+
+#endif // __WmeWintypes_H__