aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute
diff options
context:
space:
mode:
authorEinar Johan Trøan Sømåen2012-03-06 03:09:12 +0100
committerEinar Johan Trøan Sømåen2012-06-02 12:12:22 +0200
commitb602b511607ac7bae911a5306bbe8301fdad4708 (patch)
tree9d58ffb57d434d8330e22c059239f7f0b1849487 /engines/wintermute
parent72a44cdc7b2040037a97f00c0c218b7f6bd9cd31 (diff)
downloadscummvm-rg350-b602b511607ac7bae911a5306bbe8301fdad4708.tar.gz
scummvm-rg350-b602b511607ac7bae911a5306bbe8301fdad4708.tar.bz2
scummvm-rg350-b602b511607ac7bae911a5306bbe8301fdad4708.zip
WINTERMUTE: Add the files for the rest of the B-classes.
Diffstat (limited to 'engines/wintermute')
-rw-r--r--engines/wintermute/BActiveRect.cpp107
-rw-r--r--engines/wintermute/BActiveRect.h59
-rw-r--r--engines/wintermute/BDebugger.cpp49
-rw-r--r--engines/wintermute/BDebugger.h55
-rw-r--r--engines/wintermute/BDiskFile.cpp214
-rw-r--r--engines/wintermute/BDiskFile.h59
-rw-r--r--engines/wintermute/BDynBuffer.cpp192
-rw-r--r--engines/wintermute/BEvent.cpp197
-rw-r--r--engines/wintermute/BEvent.h56
-rw-r--r--engines/wintermute/BFader.cpp175
-rw-r--r--engines/wintermute/BFader.h62
-rw-r--r--engines/wintermute/BFile.cpp69
-rw-r--r--engines/wintermute/BFile.h65
-rw-r--r--engines/wintermute/BFileEntry.cpp50
-rw-r--r--engines/wintermute/BFileEntry.h57
-rw-r--r--engines/wintermute/BFileManager.cpp743
-rw-r--r--engines/wintermute/BFileManager.h81
-rw-r--r--engines/wintermute/BFont.cpp206
-rw-r--r--engines/wintermute/BFont.h61
-rw-r--r--engines/wintermute/BFontBitmap.cpp532
-rw-r--r--engines/wintermute/BFontBitmap.h72
-rw-r--r--engines/wintermute/BFontStorage.cpp155
-rw-r--r--engines/wintermute/BFontStorage.h66
-rw-r--r--engines/wintermute/BFontTT.cpp853
-rw-r--r--engines/wintermute/BFontTT.h188
-rw-r--r--engines/wintermute/BFrame.cpp707
-rw-r--r--engines/wintermute/BFrame.h73
-rw-r--r--engines/wintermute/BGame.cpp4462
-rw-r--r--engines/wintermute/BGame.h20
-rw-r--r--engines/wintermute/BImage.cpp117
-rw-r--r--engines/wintermute/BImage.h62
-rw-r--r--engines/wintermute/BKeyboardState.cpp243
-rw-r--r--engines/wintermute/BKeyboardState.h71
-rw-r--r--engines/wintermute/BPackage.cpp102
-rw-r--r--engines/wintermute/BPackage.h57
-rw-r--r--engines/wintermute/BPkgFile.cpp228
-rw-r--r--engines/wintermute/BPkgFile.h61
-rw-r--r--engines/wintermute/BPoint.cpp64
-rw-r--r--engines/wintermute/BPoint.h50
-rw-r--r--engines/wintermute/BQuickMsg.cpp54
-rw-r--r--engines/wintermute/BQuickMsg.h48
-rw-r--r--engines/wintermute/BRegion.cpp508
-rw-r--r--engines/wintermute/BRegion.h68
-rw-r--r--engines/wintermute/BRegistry.cpp227
-rw-r--r--engines/wintermute/BRegistry.h76
-rw-r--r--engines/wintermute/BRenderSDL.cpp408
-rw-r--r--engines/wintermute/BRenderSDL.h95
-rw-r--r--engines/wintermute/BRenderer.cpp259
-rw-r--r--engines/wintermute/BRenderer.h124
-rw-r--r--engines/wintermute/BResourceFile.cpp103
-rw-r--r--engines/wintermute/BResourceFile.h50
-rw-r--r--engines/wintermute/BResources.cpp2830
-rw-r--r--engines/wintermute/BResources.h41
-rw-r--r--engines/wintermute/BSaveThumbFile.cpp146
-rw-r--r--engines/wintermute/BSaveThumbFile.h51
-rw-r--r--engines/wintermute/BSaveThumbHelper.cpp79
-rw-r--r--engines/wintermute/BSaveThumbHelper.h50
-rw-r--r--engines/wintermute/BScriptHolder.cpp470
-rw-r--r--engines/wintermute/BSound.cpp266
-rw-r--r--engines/wintermute/BSound.h85
-rw-r--r--engines/wintermute/BSoundBuffer.cpp384
-rw-r--r--engines/wintermute/BSoundBuffer.h95
-rw-r--r--engines/wintermute/BSoundMgr.cpp330
-rw-r--r--engines/wintermute/BSoundMgr.h70
-rw-r--r--engines/wintermute/BSprite.cpp753
-rw-r--r--engines/wintermute/BSprite.h90
-rw-r--r--engines/wintermute/BStringTable.cpp229
-rw-r--r--engines/wintermute/BStringTable.h55
-rw-r--r--engines/wintermute/BSubFrame.cpp588
-rw-r--r--engines/wintermute/BSubFrame.h85
-rw-r--r--engines/wintermute/BSurface.cpp196
-rw-r--r--engines/wintermute/BSurface.h93
-rw-r--r--engines/wintermute/BSurfaceSDL.cpp402
-rw-r--r--engines/wintermute/BSurfaceSDL.h79
-rw-r--r--engines/wintermute/BSurfaceStorage.cpp192
-rw-r--r--engines/wintermute/BSurfaceStorage.h58
-rw-r--r--engines/wintermute/BTransitionMgr.cpp126
-rw-r--r--engines/wintermute/BTransitionMgr.h54
-rw-r--r--engines/wintermute/BViewport.cpp98
-rw-r--r--engines/wintermute/BViewport.h55
-rw-r--r--engines/wintermute/PathUtil.cpp196
-rw-r--r--engines/wintermute/PathUtil.h56
-rw-r--r--engines/wintermute/StringUtil.cpp49
-rw-r--r--engines/wintermute/StringUtil.h53
-rw-r--r--engines/wintermute/SysClass.h49
-rw-r--r--engines/wintermute/module.mk1
-rw-r--r--engines/wintermute/persistent.h1
-rw-r--r--engines/wintermute/utils.cpp49
-rw-r--r--engines/wintermute/utils.h55
89 files changed, 21140 insertions, 179 deletions
diff --git a/engines/wintermute/BActiveRect.cpp b/engines/wintermute/BActiveRect.cpp
new file mode 100644
index 0000000000..5827cb8d61
--- /dev/null
+++ b/engines/wintermute/BActiveRect.cpp
@@ -0,0 +1,107 @@
+/* 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 "BActiveRect.h"
+#include "BGame.h"
+#include "BRegion.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+CBActiveRect::CBActiveRect(CBGame *inGame): CBBase(inGame) {
+ CBPlatform::SetRectEmpty(&m_Rect);
+ m_Owner = NULL;
+ m_Frame = NULL;
+ m_Region = NULL;
+ m_ZoomX = 100;
+ m_ZoomY = 100;
+ m_OffsetX = m_OffsetY = 0;
+ ClipRect();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBActiveRect::CBActiveRect(CBGame *inGame, CBObject *Owner, CBSubFrame *Frame, int X, int Y, int Width, int Height, float ZoomX, float ZoomY, bool Precise): CBBase(inGame) {
+ m_Owner = Owner;
+ m_Frame = Frame;
+ CBPlatform::SetRect(&m_Rect, X, Y, X + Width, Y + Height);
+ m_ZoomX = ZoomX;
+ m_ZoomY = ZoomY;
+ m_Precise = Precise;
+ m_Region = NULL;
+ m_OffsetX = m_OffsetY = 0;
+ ClipRect();
+}
+
+//////////////////////////////////////////////////////////////////////
+CBActiveRect::CBActiveRect(CBGame *inGame, CBObject *Owner, CBRegion *Region, int OffsetX, int OffsetY): CBBase(inGame) {
+ m_Owner = Owner;
+ m_Region = Region;
+ CBPlatform::CopyRect(&m_Rect, &Region->m_Rect);
+ CBPlatform::OffsetRect(&m_Rect, -OffsetX, -OffsetY);
+ m_ZoomX = 100;
+ m_ZoomY = 100;
+ m_Precise = true;
+ m_Frame = NULL;
+ ClipRect();
+ m_OffsetX = OffsetX;
+ m_OffsetY = OffsetY;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBActiveRect::~CBActiveRect() {
+ m_Owner = NULL;
+ m_Frame = NULL;
+ m_Region = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBActiveRect::ClipRect() {
+ RECT rc;
+ bool CustomViewport;
+ Game->GetCurrentViewportRect(&rc, &CustomViewport);
+ CBRenderer *Rend = Game->m_Renderer;
+
+ if (!CustomViewport) {
+ rc.left -= Rend->m_DrawOffsetX;
+ rc.right -= Rend->m_DrawOffsetX;
+ rc.top -= Rend->m_DrawOffsetY;
+ rc.bottom -= Rend->m_DrawOffsetY;
+ }
+
+ if (rc.left > m_Rect.left) m_OffsetX = rc.left - m_Rect.left;
+ if (rc.top > m_Rect.top) m_OffsetY = rc.top - m_Rect.top;
+
+ CBPlatform::IntersectRect(&m_Rect, &m_Rect, &rc);
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BActiveRect.h b/engines/wintermute/BActiveRect.h
new file mode 100644
index 0000000000..ee9bb8aea1
--- /dev/null
+++ b/engines/wintermute/BActiveRect.h
@@ -0,0 +1,59 @@
+/* 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_BACTIVERECT_H
+#define WINTERMUTE_BACTIVERECT_H
+
+#include "BBase.h"
+
+namespace WinterMute {
+class CBRegion;
+class CBSubFrame;
+class CBObject;
+class CBActiveRect: CBBase {
+public:
+ void ClipRect();
+ bool m_Precise;
+ float m_ZoomX;
+ float m_ZoomY;
+ CBSubFrame *m_Frame;
+ CBObject *m_Owner;
+ CBRegion *m_Region;
+ int m_OffsetX;
+ int m_OffsetY;
+ RECT m_Rect;
+ CBActiveRect(CBGame *inGameOwner = NULL);
+ CBActiveRect(CBGame *inGameOwner, CBObject *Owner, CBSubFrame *Frame, int X, int Y, int Width, int Height, float ZoomX = 100, float ZoomY = 100, bool Precise = true);
+ CBActiveRect(CBGame *inGame, CBObject *Owner, CBRegion *Region, int OffsetX, int OffsetY);
+ virtual ~CBActiveRect();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BDebugger.cpp b/engines/wintermute/BDebugger.cpp
index 8e5faa8db1..13eae9fd18 100644
--- a/engines/wintermute/BDebugger.cpp
+++ b/engines/wintermute/BDebugger.cpp
@@ -1,27 +1,30 @@
+/* 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 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.
-*/
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
#include "BDebugger.h"
diff --git a/engines/wintermute/BDebugger.h b/engines/wintermute/BDebugger.h
index 28b37cee4f..21a7d308a9 100644
--- a/engines/wintermute/BDebugger.h
+++ b/engines/wintermute/BDebugger.h
@@ -1,30 +1,33 @@
+/* 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 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 __WmeBDebugger_H__
-#define __WmeBDebugger_H__
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_BDEBUGGER_H
+#define WINTERMUTE_BDEBUGGER_H
#include "BBase.h"
diff --git a/engines/wintermute/BDiskFile.cpp b/engines/wintermute/BDiskFile.cpp
new file mode 100644
index 0000000000..ea7a24a0a9
--- /dev/null
+++ b/engines/wintermute/BDiskFile.cpp
@@ -0,0 +1,214 @@
+/* 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 "BGame.h"
+#include "wintypes.h"
+#include "BPkgFile.h"
+#include "BDiskFile.h"
+#include "common/stream.h"
+#include "BFileManager.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBDiskFile::CBDiskFile(CBGame *inGame): CBFile(inGame) {
+ m_File = NULL;
+ m_Data = NULL;
+ m_Compressed = false;
+ m_PrefixSize = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBDiskFile::~CBDiskFile() {
+ Close();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDiskFile::Open(Common::String Filename) {
+ Close();
+
+ char FullPath[MAX_PATH];
+
+ for (int i = 0; i < Game->m_FileManager->m_SinglePaths.GetSize(); i++) {
+ sprintf(FullPath, "%s%s", Game->m_FileManager->m_SinglePaths[i], Filename.c_str());
+ CorrectSlashes(FullPath);
+
+ m_File = Common::createFileStream(FullPath);
+ if (m_File != NULL)
+ break;
+ }
+
+ // if we didn't find it in search paths, try to open directly
+ if (!m_File) {
+ strcpy(FullPath, Filename.c_str());
+ CorrectSlashes(FullPath);
+ m_File = Common::createFileStream(FullPath);
+ }
+
+ if (m_File) {
+ uint32 magic1, magic2;
+ magic1 = m_File->readUint32LE();
+ magic2 = m_File->readUint32LE();
+
+ if (magic1 == DCGF_MAGIC && magic2 == COMPRESSED_FILE_MAGIC) m_Compressed = true;
+
+ if (m_Compressed) {
+ uint32 DataOffset, CompSize, UncompSize;
+ DataOffset = m_File->readUint32LE();
+ CompSize = m_File->readUint32LE();
+ UncompSize = m_File->readUint32LE();
+
+ byte *CompBuffer = new byte[CompSize];
+ if (!CompBuffer) {
+ Game->LOG(0, "Error allocating memory for compressed file '%s'", Filename.c_str());
+ Close();
+ return E_FAIL;
+ }
+
+ m_Data = new byte[UncompSize];
+ if (!m_Data) {
+ Game->LOG(0, "Error allocating buffer for file '%s'", Filename.c_str());
+ delete [] CompBuffer;
+ Close();
+ return E_FAIL;
+ }
+ m_File->seek(DataOffset + m_PrefixSize, SEEK_SET);
+ m_File->read(CompBuffer, CompSize);
+
+ if (uncompress(m_Data, (uLongf *)&UncompSize, CompBuffer, CompSize) != Z_OK) {
+ Game->LOG(0, "Error uncompressing file '%s'", Filename.c_str());
+ delete [] CompBuffer;
+ Close();
+ return E_FAIL;
+ }
+
+ delete [] CompBuffer;
+ m_Size = UncompSize;
+ m_Pos = 0;
+ delete m_File;
+ m_File = NULL;
+ } else {
+ m_Pos = 0;
+ m_File->seek(0, SEEK_END);
+ m_Size = m_File->pos() - m_PrefixSize;
+ m_File->seek(m_PrefixSize,SEEK_SET);
+ }
+
+ return S_OK;
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDiskFile::Close() {
+ if (m_File) {
+ delete m_File;
+ }
+ m_File = NULL;
+ m_Pos = 0;
+ m_Size = 0;
+
+ delete[] m_Data;
+ m_Data = NULL;
+
+ m_Compressed = false;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDiskFile::Read(void *Buffer, uint32 Size) {
+ if (m_Compressed) {
+ memcpy(Buffer, m_Data + m_Pos, Size);
+ m_Pos += Size;
+ return S_OK;
+ } else {
+
+ if (m_File) {
+ size_t count = m_File->read(Buffer, Size);
+ m_Pos += count;
+ return S_OK;
+ } else return E_FAIL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDiskFile::Seek(uint32 Pos, TSeek Origin) {
+ if (m_Compressed) {
+ uint32 NewPos = 0;
+
+ switch (Origin) {
+ case SEEK_TO_BEGIN:
+ NewPos = Pos;
+ break;
+ case SEEK_TO_END:
+ NewPos = m_Size + Pos;
+ break;
+ case SEEK_TO_CURRENT:
+ NewPos = m_Pos + Pos;
+ break;
+ }
+
+ if (NewPos < 0 || NewPos > m_Size) return E_FAIL;
+ else m_Pos = NewPos;
+ return S_OK;
+ } else {
+ if (!m_File) return E_FAIL;
+ int ret = 1;
+
+ switch (Origin) {
+ case SEEK_TO_BEGIN:
+ ret = m_File->seek(m_PrefixSize + Pos, SEEK_SET);
+ break;
+ case SEEK_TO_END:
+ ret = m_File->seek(Pos, SEEK_END);
+ break;
+ case SEEK_TO_CURRENT:
+ ret = m_File->seek(Pos, SEEK_CUR);
+ break;
+ }
+ if (ret == 0) {
+ m_Pos = m_File->pos() - m_PrefixSize;
+ return S_OK;
+ } else return E_FAIL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBDiskFile::CorrectSlashes(char *fileName) {
+ for (size_t i = 0; i < strlen(fileName); i++) {
+ if (fileName[i] == '\\') fileName[i] = '/';
+ }
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BDiskFile.h b/engines/wintermute/BDiskFile.h
new file mode 100644
index 0000000000..7cb4a889aa
--- /dev/null
+++ b/engines/wintermute/BDiskFile.h
@@ -0,0 +1,59 @@
+/* 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_BDISKFILE_H
+#define WINTERMUTE_BDISKFILE_H
+
+
+#include "BFile.h"
+
+namespace Common {
+ class SeekableReadStream;
+}
+
+namespace WinterMute {
+
+class CBDiskFile : public CBFile {
+public:
+ CBDiskFile(CBGame *inGame);
+ virtual ~CBDiskFile();
+ virtual HRESULT Seek(uint32 Pos, TSeek Origin = SEEK_TO_BEGIN);
+ virtual HRESULT Read(void *Buffer, uint32 Size);
+ virtual HRESULT Close();
+ virtual HRESULT Open(Common::String Filename);
+private:
+ void CorrectSlashes(char *fileName);
+ Common::SeekableReadStream *m_File;
+ byte *m_Data;
+ bool m_Compressed;
+ uint32 m_PrefixSize;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BDynBuffer.cpp b/engines/wintermute/BDynBuffer.cpp
new file mode 100644
index 0000000000..3fe99faeb1
--- /dev/null
+++ b/engines/wintermute/BDynBuffer.cpp
@@ -0,0 +1,192 @@
+/* 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 "BDynBuffer.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBDynBuffer::CBDynBuffer(CBGame *inGame, uint32 InitSize, uint32 GrowBy): CBBase(inGame) {
+ m_Buffer = NULL;
+ m_Size = 0;
+ m_RealSize = 0;
+
+ m_Offset = 0;
+ m_InitSize = InitSize;
+ m_GrowBy = GrowBy;
+
+ m_Initialized = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBDynBuffer::~CBDynBuffer() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBDynBuffer::Cleanup() {
+ if (m_Buffer) free(m_Buffer);
+ m_Buffer = NULL;
+ m_Size = 0;
+ m_RealSize = 0;
+ m_Offset = 0;
+ m_Initialized = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBDynBuffer::GetSize() {
+ return m_Size;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDynBuffer::Init(uint32 InitSize) {
+ Cleanup();
+
+ if (InitSize == 0) InitSize = m_InitSize;
+
+ m_Buffer = (byte *)malloc(InitSize);
+ if (!m_Buffer) {
+ Game->LOG(0, "CBDynBuffer::Init - Error allocating %d bytes", InitSize);
+ return E_FAIL;
+ }
+
+ m_RealSize = InitSize;
+ m_Initialized = true;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDynBuffer::PutBytes(byte *Buffer, uint32 Size) {
+ if (!m_Initialized) Init();
+
+ while (m_Offset + Size > m_RealSize) {
+ m_RealSize += m_GrowBy;
+ m_Buffer = (byte *)realloc(m_Buffer, m_RealSize);
+ if (!m_Buffer) {
+ Game->LOG(0, "CBDynBuffer::PutBytes - Error reallocating buffer to %d bytes", m_RealSize);
+ return E_FAIL;
+ }
+ }
+
+ memcpy(m_Buffer + m_Offset, Buffer, Size);
+ m_Offset += Size;
+ m_Size += Size;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBDynBuffer::GetBytes(byte *Buffer, uint32 Size) {
+ if (!m_Initialized) Init();
+
+ if (m_Offset + Size > m_Size) {
+ Game->LOG(0, "CBDynBuffer::GetBytes - Buffer underflow");
+ return E_FAIL;
+ }
+
+ memcpy(Buffer, m_Buffer + m_Offset, Size);
+ m_Offset += Size;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBDynBuffer::PutDWORD(uint32 Val) {
+ PutBytes((byte *)&Val, sizeof(uint32));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBDynBuffer::GetDWORD() {
+ uint32 ret;
+ GetBytes((byte *)&ret, sizeof(uint32));
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBDynBuffer::PutString(const char *Val) {
+ if (!Val) PutString("(null)");
+ else {
+ PutDWORD(strlen(Val) + 1);
+ PutBytes((byte *)Val, strlen(Val) + 1);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBDynBuffer::GetString() {
+ uint32 len = GetDWORD();
+ char *ret = (char *)(m_Buffer + m_Offset);
+ m_Offset += len;
+
+ if (!strcmp(ret, "(null)")) return NULL;
+ else return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBDynBuffer::PutText(LPCSTR fmt, ...) {
+ va_list va;
+
+ va_start(va, fmt);
+ PutTextForm(fmt, va);
+ va_end(va);
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBDynBuffer::PutTextIndent(int Indent, LPCSTR fmt, ...) {
+ va_list va;
+
+ PutText("%*s", Indent, "");
+
+ va_start(va, fmt);
+ PutTextForm(fmt, va);
+ va_end(va);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBDynBuffer::PutTextForm(const char *format, va_list argptr) {
+ char buff[32768];
+ vsprintf(buff, format, argptr);
+ PutBytes((byte *)buff, strlen(buff));
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BEvent.cpp b/engines/wintermute/BEvent.cpp
new file mode 100644
index 0000000000..fbeddacb39
--- /dev/null
+++ b/engines/wintermute/BEvent.cpp
@@ -0,0 +1,197 @@
+/* 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 "BFileManager.h"
+#include "BEvent.h"
+#include "BParser.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CBEvent, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBEvent::CBEvent(CBGame *inGame): CBBase(inGame) {
+ m_Type = EVENT_NONE;
+ m_Script = NULL;
+ m_Name = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBEvent::CBEvent(CBGame *inGame, TEventType Type, char *Script): CBBase(inGame) {
+ m_Type = Type;
+ m_Script = new char [strlen(Script) + 1];
+ if (m_Script) strcpy(m_Script, Script);
+ m_Name = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBEvent::~CBEvent() {
+ delete[] m_Script;
+ m_Script = NULL;
+ delete[] m_Name;
+ m_Name = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *CBEvent::GetEventName(TEventType Type) {
+ switch (Type) {
+ case EVENT_INIT:
+ return "INIT";
+ case EVENT_SHUTDOWN:
+ return "SHUTDOWN";
+ case EVENT_LEFT_CLICK:
+ return "LEFT_CLICK";
+ case EVENT_RIGHT_CLICK:
+ return "RIGHT_CLICK";
+ case EVENT_MIDDLE_CLICK:
+ return "MIDDLE_CLICK";
+ case EVENT_LEFT_DBLCLICK:
+ return "LEFT_DBLCLICK";
+ case EVENT_PRESS:
+ return "PRESS";
+ case EVENT_IDLE:
+ return "IDLE";
+ case EVENT_MOUSE_OVER:
+ return "MOUSE_OVER";
+ case EVENT_LEFT_RELEASE:
+ return "LEFT_RELEASE";
+ case EVENT_RIGHT_RELEASE:
+ return "RIGHT_RELEASE";
+ case EVENT_MIDDLE_RELEASE:
+ return "MIDDLE_RELEASE";
+
+ default:
+ return "NONE";
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBEvent::SetScript(char *Script) {
+ if (m_Script) delete [] m_Script;
+
+ m_Script = new char [strlen(Script) + 1];
+ if (m_Script) strcpy(m_Script, Script);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBEvent::SetName(char *Name) {
+ if (m_Name) delete [] m_Name;
+
+ m_Name = new char [strlen(Name) + 1];
+ if (m_Name) strcpy(m_Name, Name);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBEvent::LoadFile(char *Filename) {
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer == NULL) {
+ Game->LOG(0, "CBEvent::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret;
+
+ if (FAILED(ret = LoadBuffer(Buffer, true))) Game->LOG(0, "Error parsing EVENT file '%s'", Filename);
+
+ delete [] Buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(EVENT)
+TOKEN_DEF(NAME)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBEvent::LoadBuffer(byte *Buffer, bool Complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(EVENT)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (Complete) {
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_EVENT) {
+ Game->LOG(0, "'EVENT' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = params;
+ }
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_NAME:
+ SetName((char *)params);
+ break;
+
+ case TOKEN_SCRIPT:
+ SetScript((char *)params);
+ break;
+ }
+
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in EVENT definition");
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBEvent::Persist(CBPersistMgr *PersistMgr) {
+
+ PersistMgr->Transfer(TMEMBER(Game));
+
+ PersistMgr->Transfer(TMEMBER(m_Script));
+ PersistMgr->Transfer(TMEMBER(m_Name));
+ PersistMgr->Transfer(TMEMBER_INT(m_Type));
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BEvent.h b/engines/wintermute/BEvent.h
new file mode 100644
index 0000000000..006e10706e
--- /dev/null
+++ b/engines/wintermute/BEvent.h
@@ -0,0 +1,56 @@
+/* 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_BEVENT_H
+#define WINTERMUTE_BEVENT_H
+
+
+#include "BBase.h"
+#include "dctypes.h" // Added by ClassView
+
+namespace WinterMute {
+
+class CBEvent : public CBBase {
+public:
+ DECLARE_PERSISTENT(CBEvent, CBBase)
+ void SetScript(char *Script);
+ void SetName(char *Name);
+ static const char *GetEventName(TEventType Type);
+ char *m_Script;
+ char *m_Name;
+ TEventType m_Type;
+ CBEvent(CBGame *inGame);
+ CBEvent(CBGame *inGame, TEventType Type, char *Script);
+ virtual ~CBEvent();
+ HRESULT LoadFile(char *Filename);
+ HRESULT LoadBuffer(byte *Buffer, bool Complete = true);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFader.cpp b/engines/wintermute/BFader.cpp
new file mode 100644
index 0000000000..f64023a08d
--- /dev/null
+++ b/engines/wintermute/BFader.cpp
@@ -0,0 +1,175 @@
+/* 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 "BFader.h"
+#include "BGame.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CBFader, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBFader::CBFader(CBGame *inGame): CBObject(inGame) {
+ m_Active = false;
+ m_Red = m_Green = m_Blue = 0;
+ m_CurrentAlpha = 0x00;
+ m_SourceAlpha = 0;
+ m_TargetAlpha = 0;
+ m_Duration = 1000;
+ m_StartTime = 0;
+ m_System = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFader::~CBFader() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFader::Update() {
+ if (!m_Active) return S_OK;
+
+ int AlphaDelta = m_TargetAlpha - m_SourceAlpha;
+
+ uint32 time;
+
+ if (m_System) time = CBPlatform::GetTime() - m_StartTime;
+ else time = Game->m_Timer - m_StartTime;
+
+ if (time >= m_Duration) m_CurrentAlpha = m_TargetAlpha;
+ else {
+ m_CurrentAlpha = m_SourceAlpha + (float)time / (float)m_Duration * AlphaDelta;
+ }
+ m_CurrentAlpha = MIN(255, std::max(m_CurrentAlpha, (byte )0));
+
+ m_Ready = time >= m_Duration;
+ if (m_Ready && m_CurrentAlpha == 0x00) m_Active = false;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFader::Display() {
+ if (!m_Active) return S_OK;
+
+ if (m_CurrentAlpha > 0x00) return Game->m_Renderer->FadeToColor(DRGBA(m_Red, m_Green, m_Blue, m_CurrentAlpha));
+ else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFader::Deactivate() {
+ m_Active = false;
+ m_Ready = true;
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFader::FadeIn(uint32 SourceColor, uint32 Duration, bool System) {
+ m_Ready = false;
+ m_Active = true;
+
+ m_Red = D3DCOLGetR(SourceColor);
+ m_Green = D3DCOLGetG(SourceColor);
+ m_Blue = D3DCOLGetB(SourceColor);
+
+ m_SourceAlpha = D3DCOLGetA(SourceColor);
+ m_TargetAlpha = 0;
+
+ m_Duration = Duration;
+ m_System = System;
+
+ if (m_System) m_StartTime = CBPlatform::GetTime();
+ else m_StartTime = Game->m_Timer;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFader::FadeOut(uint32 TargetColor, uint32 Duration, bool System) {
+ m_Ready = false;
+ m_Active = true;
+
+ m_Red = D3DCOLGetR(TargetColor);
+ m_Green = D3DCOLGetG(TargetColor);
+ m_Blue = D3DCOLGetB(TargetColor);
+
+ //m_SourceAlpha = 0;
+ m_SourceAlpha = m_CurrentAlpha;
+ m_TargetAlpha = D3DCOLGetA(TargetColor);
+
+ m_Duration = Duration;
+ m_System = System;
+
+ if (m_System) m_StartTime = CBPlatform::GetTime();
+ else m_StartTime = Game->m_Timer;
+
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBFader::GetCurrentColor() {
+ return DRGBA(m_Red, m_Green, m_Blue, m_CurrentAlpha);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFader::Persist(CBPersistMgr *PersistMgr) {
+ CBObject::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_Active));
+ PersistMgr->Transfer(TMEMBER(m_Blue));
+ PersistMgr->Transfer(TMEMBER(m_CurrentAlpha));
+ PersistMgr->Transfer(TMEMBER(m_Duration));
+ PersistMgr->Transfer(TMEMBER(m_Green));
+ PersistMgr->Transfer(TMEMBER(m_Red));
+ PersistMgr->Transfer(TMEMBER(m_SourceAlpha));
+ PersistMgr->Transfer(TMEMBER(m_StartTime));
+ PersistMgr->Transfer(TMEMBER(m_TargetAlpha));
+ PersistMgr->Transfer(TMEMBER(m_System));
+
+ if (m_System && !PersistMgr->m_Saving) m_StartTime = 0;
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFader.h b/engines/wintermute/BFader.h
new file mode 100644
index 0000000000..44ce256826
--- /dev/null
+++ b/engines/wintermute/BFader.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_BFADER_H
+#define WINTERMUTE_BFADER_H
+
+
+#include "BObject.h"
+
+namespace WinterMute {
+
+class CBFader : public CBObject {
+public:
+ bool m_System;
+ uint32 GetCurrentColor();
+ HRESULT FadeOut(uint32 TargetColor, uint32 Duration, bool System = false);
+ HRESULT FadeIn(uint32 SourceColor, uint32 Duration, bool System = false);
+ HRESULT Deactivate();
+ HRESULT Display();
+ HRESULT Update();
+ DECLARE_PERSISTENT(CBFader, CBObject)
+ CBFader(CBGame *inGame);
+ virtual ~CBFader();
+ bool m_Active;
+ byte m_Red;
+ byte m_Green;
+ byte m_Blue;
+ byte m_CurrentAlpha;
+ byte m_TargetAlpha;
+ byte m_SourceAlpha;
+ uint32 m_Duration;
+ uint32 m_StartTime;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFile.cpp b/engines/wintermute/BFile.cpp
new file mode 100644
index 0000000000..f4d7da2c70
--- /dev/null
+++ b/engines/wintermute/BFile.cpp
@@ -0,0 +1,69 @@
+/* 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 "BFile.h"
+#include "common/memstream.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFile::CBFile(CBGame *inGame): CBBase(inGame) {
+ m_Pos = 0;
+ m_Size = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFile::~CBFile() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBFile::IsEOF() {
+ return m_Pos == m_Size;
+}
+
+Common::SeekableReadStream *CBFile::getMemStream() {
+ uint32 oldPos = GetPos();
+ Seek(0);
+ byte *data = new byte[GetSize()];
+ Read(data, GetSize());
+ Seek(oldPos);
+ Common::MemoryReadStream *memStream = new Common::MemoryReadStream(data, GetSize(), DisposeAfterUse::YES);
+ return memStream;
+}
+
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFile.h b/engines/wintermute/BFile.h
new file mode 100644
index 0000000000..db6a29d903
--- /dev/null
+++ b/engines/wintermute/BFile.h
@@ -0,0 +1,65 @@
+/* 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_BFILE_H
+#define WINTERMUTE_BFILE_H
+
+
+#include "BBase.h"
+#include "common/str.h"
+
+namespace Common {
+ class SeekableReadStream;
+}
+
+namespace WinterMute {
+
+class CBFile : public CBBase {
+public:
+ uint32 m_Pos;
+ uint32 m_Size;
+ virtual uint32 GetSize() {
+ return m_Size;
+ };
+ virtual uint32 GetPos() {
+ return m_Pos;
+ };
+ virtual HRESULT Seek(uint32 Pos, TSeek Origin = SEEK_TO_BEGIN) = 0;
+ virtual HRESULT Read(void *Buffer, uint32 Size) = 0;
+ virtual HRESULT Close() = 0;
+ virtual HRESULT Open(Common::String Filename) = 0;
+ virtual bool IsEOF();
+ CBFile(CBGame *inGame);
+ virtual ~CBFile();
+ // Temporary solution to allow usage in ScummVM-code:
+ virtual Common::SeekableReadStream *getMemStream();
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFileEntry.cpp b/engines/wintermute/BFileEntry.cpp
new file mode 100644
index 0000000000..18a15e37f9
--- /dev/null
+++ b/engines/wintermute/BFileEntry.cpp
@@ -0,0 +1,50 @@
+/* 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 "BFileEntry.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBFileEntry::CBFileEntry(CBGame *inGame): CBBase(inGame) {
+ m_Package = NULL;
+ m_Length = m_CompressedLength = m_Offset = m_Flags = 0;
+ m_Filename = "";
+
+ m_TimeDate1 = m_TimeDate2 = 0;
+
+ m_JournalTime = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFileEntry::~CBFileEntry() {
+ m_Package = NULL; // ref only
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFileEntry.h b/engines/wintermute/BFileEntry.h
new file mode 100644
index 0000000000..cfad80926c
--- /dev/null
+++ b/engines/wintermute/BFileEntry.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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_BFILEENTRY_H
+#define WINTERMUTE_BFILEENTRY_H
+
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBPackage;
+
+class CBFileEntry : public CBBase {
+public:
+ uint32 m_TimeDate2;
+ uint32 m_TimeDate1;
+ uint32 m_Flags;
+ uint32 m_JournalTime;
+ std::string m_Filename;
+ uint32 m_CompressedLength;
+ uint32 m_Length;
+ uint32 m_Offset;
+ CBPackage *m_Package;
+ CBFileEntry(CBGame *inGame);
+ virtual ~CBFileEntry();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFileManager.cpp b/engines/wintermute/BFileManager.cpp
new file mode 100644
index 0000000000..d679321598
--- /dev/null
+++ b/engines/wintermute/BFileManager.cpp
@@ -0,0 +1,743 @@
+/* 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 "StringUtil.h"
+#include "PathUtil.h"
+#include "BDiskFile.h"
+#include "BResourceFile.h"
+#include "BSaveThumbFile.h"
+#include "BFileEntry.h"
+#include "BPkgFile.h"
+#include "BPackage.h"
+#include "BRegistry.h"
+#include "BGame.h"
+#include "dcpackage.h"
+#include "utils.h"
+#include "PlatformSDL.h"
+#include "common/str.h"
+#include "common/textconsole.h"
+#include <boost/filesystem.hpp>
+
+#ifdef __WIN32__
+# include <direct.h>
+#else
+# include <unistd.h>
+#endif
+
+#ifdef __APPLE__
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+
+
+#if _DEBUG
+#pragma comment(lib, "zlib_d.lib")
+#else
+#pragma comment(lib, "zlib.lib")
+#endif
+
+
+extern "C"
+{
+#include "zlib.h"
+}
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+CBFileManager::CBFileManager(CBGame *inGame): CBBase(inGame) {
+ m_BasePath = NULL;
+
+ InitPaths();
+ RegisterPackages();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBFileManager::~CBFileManager() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::Cleanup() {
+ int i;
+
+ // delete registered paths
+ for (i = 0; i < m_SinglePaths.GetSize(); i++)
+ delete [] m_SinglePaths[i];
+ m_SinglePaths.RemoveAll();
+
+ for (i = 0; i < m_PackagePaths.GetSize(); i++)
+ delete [] m_PackagePaths[i];
+ m_PackagePaths.RemoveAll();
+
+
+ // delete file entries
+ m_FilesIter = m_Files.begin();
+ while (m_FilesIter != m_Files.end()) {
+ delete m_FilesIter->second;
+ m_FilesIter++;
+ }
+ m_Files.clear();
+
+ // close open files
+ for (i = 0; i < m_OpenFiles.GetSize(); i++) {
+ m_OpenFiles[i]->Close();
+ delete m_OpenFiles[i];
+ }
+ m_OpenFiles.RemoveAll();
+
+
+ // delete packages
+ for (i = 0; i < m_Packages.GetSize(); i++)
+ delete m_Packages[i];
+ m_Packages.RemoveAll();
+
+ delete[] m_BasePath;
+ m_BasePath = NULL;
+
+ return S_OK;
+}
+
+
+
+#define MAX_FILE_SIZE 10000000
+//////////////////////////////////////////////////////////////////////
+byte *CBFileManager::ReadWholeFile(const char *Filename, uint32 *Size, bool MustExist) {
+
+ byte *buffer = NULL;
+
+ CBFile *File = OpenFile(Filename);
+ if (!File) {
+ if (MustExist) Game->LOG(0, "Error opening file '%s'", Filename);
+ return NULL;
+ }
+
+ /*
+ if(File->GetSize()>MAX_FILE_SIZE){
+ Game->LOG(0, "File '%s' exceeds the maximum size limit (%d bytes)", Filename, MAX_FILE_SIZE);
+ CloseFile(File);
+ return NULL;
+ }
+ */
+
+
+ buffer = new byte[File->GetSize() + 1];
+ if (buffer == NULL) {
+ Game->LOG(0, "Error allocating buffer for file '%s' (%d bytes)", Filename, File->GetSize() + 1);
+ CloseFile(File);
+ return NULL;
+ }
+
+ if (FAILED(File->Read(buffer, File->GetSize()))) {
+ Game->LOG(0, "Error reading file '%s'", Filename);
+ CloseFile(File);
+ delete [] buffer;
+ return NULL;
+ };
+
+ buffer[File->GetSize()] = '\0';
+ if (Size != NULL) *Size = File->GetSize();
+ CloseFile(File);
+
+ return buffer;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::SaveFile(char *Filename, byte *Buffer, uint32 BufferSize, bool Compressed, byte *PrefixBuffer, uint32 PrefixSize) {
+ RestoreCurrentDir();
+
+ CBUtils::CreatePath(Filename, false);
+
+ FILE *f = fopen(Filename, "wb");
+ if (!f) {
+ Game->LOG(0, "Error opening file '%s' for writing.", Filename);
+ return E_FAIL;
+ }
+
+ if (PrefixBuffer && PrefixSize) {
+ fwrite(PrefixBuffer, PrefixSize, 1, f);
+ }
+
+ if (Compressed) {
+ uint32 CompSize = BufferSize + (BufferSize / 100) + 12; // 1% extra space
+ byte *CompBuffer = new byte[CompSize];
+ if (!CompBuffer) {
+ Game->LOG(0, "Error allocating compression buffer while saving '%s'", Filename);
+ Compressed = false;
+ } else {
+ if (compress(CompBuffer, (uLongf *)&CompSize, Buffer, BufferSize) == Z_OK) {
+ uint32 magic = DCGF_MAGIC;
+ fwrite(&magic, sizeof(uint32), 1, f);
+ magic = COMPRESSED_FILE_MAGIC;
+ fwrite(&magic, sizeof(uint32), 1, f);
+
+ uint32 DataOffset = 5 * sizeof(uint32);
+ fwrite(&DataOffset, sizeof(uint32), 1, f);
+
+ fwrite(&CompSize, sizeof(uint32), 1, f);
+ fwrite(&BufferSize, sizeof(uint32), 1, f);
+
+ fwrite(CompBuffer, CompSize, 1, f);
+ } else {
+ Game->LOG(0, "Error compressing data while saving '%s'", Filename);
+ Compressed = false;
+ }
+
+ delete [] CompBuffer;
+ }
+ }
+
+ if (!Compressed) fwrite(Buffer, BufferSize, 1, f);
+
+ fclose(f);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::RequestCD(int CD, char *PackageFile, char *Filename) {
+ // unmount all non-local packages
+ for (int i = 0; i < m_Packages.GetSize(); i++) {
+ if (m_Packages[i]->m_CD > 0) m_Packages[i]->Close();
+ }
+
+
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::AddPath(TPathType Type, const char *Path) {
+ if (Path == NULL || strlen(Path) < 1) return E_FAIL;
+
+ bool slashed = (Path[strlen(Path) - 1] == '\\' || Path[strlen(Path) - 1] == '/');
+
+ char *buffer = new char [strlen(Path) + 1 + (slashed ? 0 : 1)];
+ if (buffer == NULL) return E_FAIL;
+
+ strcpy(buffer, Path);
+ if (!slashed) strcat(buffer, "\\");
+ //CBPlatform::strlwr(buffer);
+
+ switch (Type) {
+ case PATH_SINGLE:
+ m_SinglePaths.Add(buffer);
+ break;
+ case PATH_PACKAGE:
+ m_PackagePaths.Add(buffer);
+ break;
+ }
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::ReloadPaths() {
+ // delete registered paths
+ for (int i = 0; i < m_SinglePaths.GetSize(); i++)
+ delete [] m_SinglePaths[i];
+ m_SinglePaths.RemoveAll();
+
+ for (int i = 0; i < m_PackagePaths.GetSize(); i++)
+ delete [] m_PackagePaths[i];
+ m_PackagePaths.RemoveAll();
+
+ return InitPaths();
+}
+
+
+#define TEMP_BUFFER_SIZE 32768
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::InitPaths() {
+ RestoreCurrentDir();
+
+ AnsiString pathList;
+ int numPaths;
+
+ // single files paths
+ pathList = Game->m_Registry->ReadString("Resource", "CustomPaths", "");
+ numPaths = CBUtils::StrNumEntries(pathList.c_str(), ';');
+
+ for (int i = 0; i < numPaths; i++) {
+ char *path = CBUtils::StrEntry(i, pathList.c_str(), ';');
+ if (path && strlen(path) > 0) {
+ AddPath(PATH_SINGLE, path);
+ }
+ delete[] path;
+ path = NULL;
+ }
+ AddPath(PATH_SINGLE, ".\\");
+
+
+ // package files paths
+ AddPath(PATH_PACKAGE, "./");
+
+#ifdef __APPLE__
+ // search .app path and Resources dir in the bundle
+ CFURLRef appUrlRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
+ const char *pathPtr = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding());
+
+#ifdef __IPHONE__
+ AddPath(PATH_PACKAGE, pathPtr);
+ AddPath(PATH_SINGLE, pathPtr);
+#else
+ char bundlePath[MAX_PATH];
+
+ sprintf(bundlePath, "%s/../", pathPtr);
+ AddPath(PATH_PACKAGE, bundlePath);
+ AddPath(PATH_SINGLE, bundlePath);
+
+ sprintf(bundlePath, "%s/Contents/Resources/", pathPtr);
+ AddPath(PATH_PACKAGE, bundlePath);
+ AddPath(PATH_SINGLE, bundlePath);
+
+
+ CFRelease(appUrlRef);
+ CFRelease(macPath);
+#endif
+#endif
+
+
+ pathList = Game->m_Registry->ReadString("Resource", "PackagePaths", "");
+ numPaths = CBUtils::StrNumEntries(pathList.c_str(), ';');
+
+ for (int i = 0; i < numPaths; i++) {
+ char *path = CBUtils::StrEntry(i, pathList.c_str(), ';');
+ if (path && strlen(path) > 0) {
+ AddPath(PATH_PACKAGE, path);
+ }
+ delete[] path;
+ path = NULL;
+ }
+ AddPath(PATH_PACKAGE, "data");
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::RegisterPackages() {
+ RestoreCurrentDir();
+
+ Game->LOG(0, "Scanning packages...");
+ warning("Scanning packages");
+
+ AnsiString extension = AnsiString(".") + AnsiString(PACKAGE_EXTENSION);
+
+ for (int i = 0; i < m_PackagePaths.GetSize(); i++) {
+ boost::filesystem::path absPath = boost::filesystem::system_complete(m_PackagePaths[i]);
+
+ //Game->LOG(0, "Scanning: %s", absPath.string().c_str());
+ //printf("Scanning: %s\n", absPath.string().c_str());
+
+ if (!exists(absPath)) continue;
+
+ // scan files
+ boost::filesystem::directory_iterator endIter;
+ for (boost::filesystem::directory_iterator dit(absPath); dit != endIter; ++dit) {
+ if (!is_directory((*dit).status())) {
+ AnsiString fileName = (*dit).path().string();
+
+ if (!IsValidPackage(fileName)) continue;
+
+ warning("%s", fileName.c_str());
+ //printf("%s\n", fileName.c_str());
+ if (!StringUtil::CompareNoCase(extension, PathUtil::GetExtension(fileName))) continue;
+ warning("Registered");
+ RegisterPackage(absPath.string().c_str(), dit->path().filename().string().c_str());
+ }
+ }
+ }
+
+
+ Game->LOG(0, " Registered %d files in %d package(s)", m_Files.size(), m_Packages.GetSize());
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::RegisterPackage(const char *Path, const char *Name, bool SearchSignature) {
+ char Filename[MAX_PATH];
+ sprintf(Filename, "%s%s", Path, Name);
+
+ FILE *f = fopen(Filename, "rb");
+ if (!f) {
+ Game->LOG(0, " Error opening package file '%s'. Ignoring.", Filename);
+ return S_OK;
+ }
+
+ uint32 AbosulteOffset = 0;
+ bool BoundToExe = false;
+
+ if (SearchSignature) {
+ uint32 Offset;
+ if (!FindPackageSignature(f, &Offset)) {
+ fclose(f);
+ return S_OK;
+ } else {
+ fseek(f, Offset, SEEK_SET);
+ AbosulteOffset = Offset;
+ BoundToExe = true;
+ }
+ }
+
+ TPackageHeader hdr;
+ fread(&hdr, sizeof(TPackageHeader), 1, f);
+ if (hdr.Magic1 != PACKAGE_MAGIC_1 || hdr.Magic2 != PACKAGE_MAGIC_2 || hdr.PackageVersion > PACKAGE_VERSION) {
+ Game->LOG(0, " Invalid header in package file '%s'. Ignoring.", Filename);
+ fclose(f);
+ return S_OK;
+ }
+
+ if (hdr.PackageVersion != PACKAGE_VERSION) {
+ Game->LOG(0, " Warning: package file '%s' is outdated.", Filename);
+ }
+
+ // new in v2
+ if (hdr.PackageVersion == PACKAGE_VERSION) {
+ uint32 DirOffset;
+ fread(&DirOffset, sizeof(uint32), 1, f);
+ DirOffset += AbosulteOffset;
+ fseek(f, DirOffset, SEEK_SET);
+ }
+
+ for (int i = 0; i < hdr.NumDirs; i++) {
+ CBPackage *pkg = new CBPackage(Game);
+ if (!pkg) return E_FAIL;
+
+ pkg->m_BoundToExe = BoundToExe;
+
+ // read package info
+ byte NameLength;
+ fread(&NameLength, sizeof(byte ), 1, f);
+ pkg->m_Name = new char[NameLength];
+ fread(pkg->m_Name, NameLength, 1, f);
+ fread(&pkg->m_CD, sizeof(byte ), 1, f);
+ pkg->m_Priority = hdr.Priority;
+
+ if (!hdr.MasterIndex) pkg->m_CD = 0; // override CD to fixed disk
+ m_Packages.Add(pkg);
+
+
+ // read file entries
+ uint32 NumFiles;
+ fread(&NumFiles, sizeof(uint32), 1, f);
+
+ for (int j = 0; j < NumFiles; j++) {
+ char *Name;
+ uint32 Offset, Length, CompLength, Flags, TimeDate1, TimeDate2;
+
+ fread(&NameLength, sizeof(byte ), 1, f);
+ Name = new char[NameLength];
+ fread(Name, NameLength, 1, f);
+
+ // v2 - xor name
+ if (hdr.PackageVersion == PACKAGE_VERSION) {
+ for (int k = 0; k < NameLength; k++) {
+ ((byte *)Name)[k] ^= 'D';
+ }
+ }
+
+ // some old version of ProjectMan writes invalid directory entries
+ // so at least prevent strupr from corrupting memory
+ Name[NameLength - 1] = '\0';
+
+
+ CBPlatform::strupr(Name);
+
+ fread(&Offset, sizeof(uint32), 1, f);
+ Offset += AbosulteOffset;
+ fread(&Length, sizeof(uint32), 1, f);
+ fread(&CompLength, sizeof(uint32), 1, f);
+ fread(&Flags, sizeof(uint32), 1, f);
+
+ if (hdr.PackageVersion == PACKAGE_VERSION) {
+ fread(&TimeDate1, sizeof(uint32), 1, f);
+ fread(&TimeDate2, sizeof(uint32), 1, f);
+ }
+
+ m_FilesIter = m_Files.find(Name);
+ if (m_FilesIter == m_Files.end()) {
+ CBFileEntry *file = new CBFileEntry(Game);
+ file->m_Package = pkg;
+ file->m_Offset = Offset;
+ file->m_Length = Length;
+ file->m_CompressedLength = CompLength;
+ file->m_Flags = Flags;
+
+ m_Files[Name] = file;
+ } else {
+ // current package has lower CD number or higher priority, than the registered
+ if (pkg->m_CD < m_FilesIter->second->m_Package->m_CD || pkg->m_Priority > m_FilesIter->second->m_Package->m_Priority) {
+ m_FilesIter->second->m_Package = pkg;
+ m_FilesIter->second->m_Offset = Offset;
+ m_FilesIter->second->m_Length = Length;
+ m_FilesIter->second->m_CompressedLength = CompLength;
+ m_FilesIter->second->m_Flags = Flags;
+ }
+ }
+ delete [] Name;
+ }
+ }
+
+
+ fclose(f);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBFileManager::IsValidPackage(const AnsiString &fileName) const {
+ AnsiString plainName = PathUtil::GetFileNameWithoutExtension(fileName);
+
+ // check for device-type specific packages
+ if (StringUtil::StartsWith(plainName, "xdevice_", true)) {
+ return StringUtil::CompareNoCase(plainName, "xdevice_" + Game->GetDeviceType());
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+FILE *CBFileManager::OpenPackage(char *Name) {
+ RestoreCurrentDir();
+
+ FILE *ret = NULL;
+ char Filename[MAX_PATH];
+
+ for (int i = 0; i < m_PackagePaths.GetSize(); i++) {
+ sprintf(Filename, "%s%s.%s", m_PackagePaths[i], Name, PACKAGE_EXTENSION);
+ ret = fopen(Filename, "rb");
+ if (ret != NULL) return ret;
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+FILE *CBFileManager::OpenSingleFile(char *Name) {
+ RestoreCurrentDir();
+
+ FILE *ret = NULL;
+ char Filename[MAX_PATH];
+
+ for (int i = 0; i < m_SinglePaths.GetSize(); i++) {
+ sprintf(Filename, "%s%s", m_SinglePaths[i], Name);
+ ret = fopen(Filename, "rb");
+ if (ret != NULL) return ret;
+ }
+
+ // didn't find in search paths, try to open directly
+ return fopen(Name, "rb");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBFileManager::GetFullPath(char *Filename, char *Fullname) {
+ RestoreCurrentDir();
+
+ FILE *f = NULL;
+ bool found = false;
+
+ for (int i = 0; i < m_SinglePaths.GetSize(); i++) {
+ sprintf(Fullname, "%s%s", m_SinglePaths[i], Filename);
+ f = fopen(Fullname, "rb");
+ if (f) {
+ fclose(f);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ f = fopen(Filename, "rb");
+ if (f) {
+ fclose(f);
+ found = true;
+ strcpy(Fullname, Filename);
+ }
+ }
+
+ return found;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFileEntry *CBFileManager::GetPackageEntry(const char *Filename) {
+ char *upc_name = new char[strlen(Filename) + 1];
+ strcpy(upc_name, Filename);
+ CBPlatform::strupr(upc_name);
+
+ CBFileEntry *ret = NULL;
+ m_FilesIter = m_Files.find(upc_name);
+ if (m_FilesIter != m_Files.end()) ret = m_FilesIter->second;
+
+ delete [] upc_name;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFile *CBFileManager::OpenFile(const char *Filename, bool AbsPathWarning) {
+ if (strcmp(Filename, "") == 0) return NULL;
+ //Game->LOG(0, "open file: %s", Filename);
+#ifdef __WIN32__
+ if (Game->m_DEBUG_DebugMode && Game->m_DEBUG_AbsolutePathWarning && AbsPathWarning) {
+ char Drive[_MAX_DRIVE];
+ _splitpath(Filename, Drive, NULL, NULL, NULL);
+ if (Drive[0] != '\0') {
+ Game->LOG(0, "WARNING: Referencing absolute path '%s'. The game will NOT work on another computer.", Filename);
+ }
+ }
+#endif
+
+ CBFile *File = OpenFileRaw(Filename);
+ if (File) m_OpenFiles.Add(File);
+ return File;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::CloseFile(CBFile *File) {
+ for (int i = 0; i < m_OpenFiles.GetSize(); i++) {
+ if (m_OpenFiles[i] == File) {
+ m_OpenFiles[i]->Close();
+ delete m_OpenFiles[i];
+ m_OpenFiles.RemoveAt(i);
+ return S_OK;
+ }
+ }
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFile *CBFileManager::OpenFileRaw(const char *Filename) {
+ RestoreCurrentDir();
+
+ if (scumm_strnicmp(Filename, "savegame:", 9) == 0) {
+ CBSaveThumbFile *SaveThumbFile = new CBSaveThumbFile(Game);
+ if (SUCCEEDED(SaveThumbFile->Open(Filename))) return SaveThumbFile;
+ else {
+ delete SaveThumbFile;
+ return NULL;
+ }
+ }
+
+ CBDiskFile *DiskFile = new CBDiskFile(Game);
+ if (SUCCEEDED(DiskFile->Open(Filename))) return DiskFile;
+
+ delete DiskFile;
+
+ CBPkgFile *PkgFile = new CBPkgFile(Game);
+ if (SUCCEEDED(PkgFile->Open(Filename))) return PkgFile;
+
+ delete PkgFile;
+
+ CBResourceFile *ResFile = new CBResourceFile(Game);
+ if (SUCCEEDED(ResFile->Open(Filename))) return ResFile;
+
+ delete ResFile;
+
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::RestoreCurrentDir() {
+ if (!m_BasePath) return S_OK;
+ else {
+ if (!chdir(m_BasePath)) return S_OK;
+ else return E_FAIL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFileManager::SetBasePath(char *Path) {
+ Cleanup();
+
+ if (Path) {
+ m_BasePath = new char[strlen(Path) + 1];
+ strcpy(m_BasePath, Path);
+ }
+
+ InitPaths();
+ RegisterPackages();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBFileManager::FindPackageSignature(FILE *f, uint32 *Offset) {
+ byte buf[32768];
+
+ byte Signature[8];
+ ((uint32 *)Signature)[0] = PACKAGE_MAGIC_1;
+ ((uint32 *)Signature)[1] = PACKAGE_MAGIC_2;
+
+ fseek(f, 0, SEEK_END);
+ uint32 FileSize = ftell(f);
+
+ int StartPos = 1024 * 1024;
+
+ int BytesRead = StartPos;
+
+ while (BytesRead < FileSize - 16) {
+ int ToRead = MIN(32768, FileSize - BytesRead);
+ fseek(f, StartPos, SEEK_SET);
+ int ActuallyRead = fread(buf, 1, ToRead, f);
+ if (ActuallyRead != ToRead) return false;
+
+ for (int i = 0; i < ToRead - 8; i++)
+ if (!memcmp(buf + i, Signature, 8)) {
+ *Offset = StartPos + i;
+ return true;
+ }
+
+ BytesRead = BytesRead + ToRead - 16;
+ StartPos = StartPos + ToRead - 16;
+
+ }
+ return false;
+
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFileManager.h b/engines/wintermute/BFileManager.h
new file mode 100644
index 0000000000..e585841a4a
--- /dev/null
+++ b/engines/wintermute/BFileManager.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_BFILEMANAGER_H
+#define WINTERMUTE_BFILEMANAGER_H
+
+
+#include <map>
+#include "coll_templ.h"
+#include "BFileEntry.h"
+#include "common/archive.h"
+
+namespace WinterMute {
+class CBFile;
+class CBFileManager: CBBase {
+public:
+ bool FindPackageSignature(FILE *f, uint32 *Offset);
+ HRESULT Cleanup();
+ HRESULT SetBasePath(char *Path);
+ HRESULT RestoreCurrentDir();
+ char *m_BasePath;
+ bool GetFullPath(char *Filename, char *Fullname);
+ CBFile *OpenFileRaw(const char *Filename);
+ HRESULT CloseFile(CBFile *File);
+ CBFile *OpenFile(const char *Filename, bool AbsPathWarning = true);
+ CBFileEntry *GetPackageEntry(const char *Filename);
+ FILE *OpenSingleFile(char *Name);
+ FILE *OpenPackage(char *Name);
+ HRESULT RegisterPackages();
+ HRESULT InitPaths();
+ HRESULT ReloadPaths();
+ typedef enum {
+ PATH_PACKAGE, PATH_SINGLE
+ } TPathType;
+ HRESULT AddPath(TPathType Type, const char *Path);
+ HRESULT RequestCD(int CD, char *PackageFile, char *Filename);
+ HRESULT SaveFile(char *Filename, byte *Buffer, uint32 BufferSize, bool Compressed = false, byte *PrefixBuffer = NULL, uint32 PrefixSize = 0);
+ byte *ReadWholeFile(const char *Filename, uint32 *Size = NULL, bool MustExist = true);
+ CBFileManager(CBGame *inGame = NULL);
+ virtual ~CBFileManager();
+ CBArray<char *, char *> m_SinglePaths;
+ CBArray<char *, char *> m_PackagePaths;
+ CBArray<CBPackage *, CBPackage *> m_Packages;
+ CBArray<CBFile *, CBFile *> m_OpenFiles;
+
+ std::map<std::string, CBFileEntry *> m_Files;
+private:
+ HRESULT RegisterPackage(const char *Path, const char *Name, bool SearchSignature = false);
+ std::map<std::string, CBFileEntry *>::iterator m_FilesIter;
+ bool IsValidPackage(const AnsiString &fileName) const;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFont.cpp b/engines/wintermute/BFont.cpp
new file mode 100644
index 0000000000..93d870875d
--- /dev/null
+++ b/engines/wintermute/BFont.cpp
@@ -0,0 +1,206 @@
+/* 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 "BFont.h"
+#include "BFontBitmap.h"
+#include "BParser.h"
+#include "BFileManager.h"
+#include "BFontTT.h"
+#include "BGame.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CBFont, false)
+
+//////////////////////////////////////////////////////////////////////
+CBFont::CBFont(CBGame *inGame): CBObject(inGame) {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBFont::~CBFont() {
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBFont::DrawText(byte *text, int x, int y, int width, TTextAlign align, int max_height, int MaxLenght) {
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBFont::GetTextHeight(byte *text, int width) {
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBFont::GetTextWidth(byte *text, int MaxLenght) {
+ return 0;
+}
+
+/*
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFont::LoadFile(char * Filename)
+{
+ BYTE* Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if(Buffer==NULL){
+ Game->LOG(0, "CBFont::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret;
+
+ m_Filename = new char [strlen(Filename)+1];
+ strcpy(m_Filename, Filename);
+
+ if(FAILED(ret = LoadBuffer(Buffer))) Game->LOG(0, "Error parsing FONT file '%s'", Filename);
+
+ delete [] Buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+ TOKEN_DEF (FONT)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFont::LoadBuffer(byte * Buffer)
+{
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE (FONT)
+ TOKEN_TABLE_END
+
+ char* params;
+ int cmd;
+ CBParser parser(Game);
+
+ if(parser.GetCommand ((char**)&Buffer, commands, (char**)&params)!=TOKEN_FONT){
+ Game->LOG(0, "'FONT' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = (byte *)params;
+
+ while ((cmd = parser.GetCommand ((char**)&Buffer, commands, (char**)&params)) > 0)
+ {
+ switch (cmd)
+ {
+ case TOKEN_IMAGE:
+ surface_file = (char*)params;
+ break;
+
+ case TOKEN_TRANSPARENT:
+ parser.ScanStr(params, "%d,%d,%d", &r, &g, &b);
+ custom_trans = true;
+ break;
+ }
+
+
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND){
+ Game->LOG(0, "Syntax error in FONT definition");
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+*/
+
+//////////////////////////////////////////////////////////////////////////
+int CBFont::GetLetterHeight() {
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFont::Persist(CBPersistMgr *PersistMgr) {
+
+ CBObject::Persist(PersistMgr);
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFont *CBFont::CreateFromFile(CBGame *Game, char *Filename) {
+ if (IsTrueType(Game, Filename)) {
+ CBFontTT *Font = new CBFontTT(Game);
+ if (Font) {
+ if (FAILED(Font->LoadFile(Filename))) {
+ delete Font;
+ return NULL;
+ }
+ }
+ return Font;
+ } else {
+ CBFontBitmap *Font = new CBFontBitmap(Game);
+ if (Font) {
+ if (FAILED(Font->LoadFile(Filename))) {
+ delete Font;
+ return NULL;
+ }
+ }
+ return Font;
+ }
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(FONT)
+TOKEN_DEF(TTFONT)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+bool CBFont::IsTrueType(CBGame *Game, char *Filename) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(TTFONT)
+ TOKEN_TABLE_END
+
+
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer == NULL) return false;
+
+ byte *WorkBuffer = Buffer;
+
+ char *params;
+ CBParser parser(Game);
+
+ bool Ret = false;
+ if (parser.GetCommand((char **)&WorkBuffer, commands, (char **)&params) == TOKEN_TTFONT)
+ Ret = true;
+
+ delete [] Buffer;
+ return Ret;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFont.h b/engines/wintermute/BFont.h
new file mode 100644
index 0000000000..5ffba7ace4
--- /dev/null
+++ b/engines/wintermute/BFont.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_BFONT_H
+#define WINTERMUTE_BFONT_H
+
+#include "BObject.h"
+
+#define NUM_CHARACTERS 256
+
+namespace WinterMute {
+
+class CBFont: public CBObject {
+public:
+ DECLARE_PERSISTENT(CBFont, CBObject)
+ virtual int GetTextWidth(byte *text, int MaxLenght = -1);
+ virtual int GetTextHeight(byte *text, int width);
+ virtual void DrawText(byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int MaxLenght = -1);
+ virtual int GetLetterHeight();
+
+ virtual void InitLoop() {};
+
+ CBFont(CBGame *inGame);
+ virtual ~CBFont();
+
+ static CBFont *CreateFromFile(CBGame *Game, char *Filename);
+
+private:
+ //HRESULT LoadBuffer(byte * Buffer);
+ //HRESULT LoadFile(char* Filename);
+ static bool IsTrueType(CBGame *Game, char *Filename);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFontBitmap.cpp b/engines/wintermute/BFontBitmap.cpp
new file mode 100644
index 0000000000..e7a1466ed0
--- /dev/null
+++ b/engines/wintermute/BFontBitmap.cpp
@@ -0,0 +1,532 @@
+/* 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 "BFontBitmap.h"
+#include "StringUtil.h"
+#include "BParser.h"
+#include "BFrame.h"
+#include "BSurface.h"
+#include "BGame.h"
+#include "BSubFrame.h"
+#include "BFrame.h"
+#include "BSprite.h"
+#include "BFileManager.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CBFontBitmap, false)
+
+//////////////////////////////////////////////////////////////////////
+CBFontBitmap::CBFontBitmap(CBGame *inGame): CBFont(inGame) {
+ m_Subframe = NULL;
+ m_Sprite = NULL;
+ m_WidthsFrame = 0;
+ memset(m_Widths, 0, NUM_CHARACTERS);
+ m_TileWidth = m_TileHeight = m_NumColumns = 0;
+ m_FontextFix = false;
+ m_Freezable = false;
+ m_WholeCell = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBFontBitmap::~CBFontBitmap() {
+ SAFE_DELETE(m_Subframe);
+ SAFE_DELETE(m_Sprite);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBFontBitmap::DrawText(byte *text, int x, int y, int width, TTextAlign align, int max_height, int MaxLenght) {
+ TextHeightDraw(text, x, y, width, align, true, max_height, MaxLenght);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBFontBitmap::GetTextHeight(byte *text, int width) {
+ return TextHeightDraw(text, 0, 0, width, TAL_LEFT, false);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBFontBitmap::GetTextWidth(byte *text, int MaxLength) {
+ AnsiString str;
+
+ if (Game->m_TextEncoding == TEXT_UTF8) {
+ WideString wstr = StringUtil::Utf8ToWide(Utf8String((char *)text));
+ str = StringUtil::WideToAnsi(wstr);
+ } else {
+ str = AnsiString((char *)text);
+ }
+
+ if (MaxLength >= 0 && str.length() > MaxLength) str = str.substr(0, MaxLength);
+
+ int TextWidth = 0;
+ for (size_t i = 0; i < str.length(); i++) {
+ TextWidth += GetCharWidth(str[i]);
+ }
+
+ return TextWidth;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+int CBFontBitmap::TextHeightDraw(byte *text, int x, int y, int width, TTextAlign align, bool draw, int max_height, int MaxLenght) {
+ if (MaxLenght == 0) return 0;
+
+ if (text == NULL || text[0] == '\0') return m_TileHeight;
+
+
+
+ AnsiString str;
+
+ if (Game->m_TextEncoding == TEXT_UTF8) {
+ WideString wstr = StringUtil::Utf8ToWide(Utf8String((char *)text));
+ str = StringUtil::WideToAnsi(wstr);
+ } else {
+ str = AnsiString((char *)text);
+ }
+ if (str.empty()) return 0;
+
+ int LineLength = 0;
+ int RealLength = 0;
+ int NumLines = 0;
+
+ int i;
+
+ int index = -1;
+ int start = 0;
+ int end = 0;
+ int last_end = 0;
+
+ bool done = false;
+ bool new_line = false;
+ bool long_line = false;
+
+ if (draw) Game->m_Renderer->StartSpriteBatch();
+
+ while (!done) {
+ if (max_height > 0 && (NumLines + 1)*m_TileHeight > max_height) {
+ if (draw) Game->m_Renderer->EndSpriteBatch();
+ return NumLines * m_TileHeight;
+ }
+
+ index++;
+
+ if (str[index] == ' ' && (max_height < 0 || max_height / m_TileHeight > 1)) {
+ end = index - 1;
+ RealLength = LineLength;
+ }
+
+ if (str[index] == '\n') {
+ end = index - 1;
+ RealLength = LineLength;
+ new_line = true;
+ }
+
+ if (LineLength + GetCharWidth(str[index]) > width && last_end == end) {
+ end = index - 1;
+ RealLength = LineLength;
+ new_line = true;
+ long_line = true;
+ }
+
+ if (str[index + 1] == '\0' || (MaxLenght >= 0 && index == MaxLenght - 1)) {
+ done = true;
+ if (!new_line) {
+ end = index;
+ LineLength += GetCharWidth(str[index]);
+ RealLength = LineLength;
+ }
+ } else LineLength += GetCharWidth(str[index]);
+
+ if ((LineLength > width) || done || new_line) {
+ if (end < 0) done = true;
+ int StartX;
+ switch (align) {
+ case TAL_CENTER:
+ StartX = x + (width - RealLength) / 2;
+ break;
+ case TAL_RIGHT:
+ StartX = x + width - RealLength;
+ break;
+ case TAL_LEFT:
+ StartX = x;
+ break;
+ }
+ for (i = start; i < end + 1; i++) {
+ if (draw) DrawChar(str[i], StartX, y);
+ StartX += GetCharWidth(str[i]);
+ }
+ y += m_TileHeight;
+ last_end = end;
+ if (long_line) end--;
+ start = end + 2;
+ index = end + 1;
+ LineLength = 0;
+ new_line = false;
+ long_line = false;
+ NumLines++;
+ }
+ }
+
+ if (draw) Game->m_Renderer->EndSpriteBatch();
+
+ return NumLines * m_TileHeight;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBFontBitmap::DrawChar(byte c, int x, int y) {
+ if (m_FontextFix) c--;
+
+ int row, col;
+
+ row = c / m_NumColumns;
+ col = c % m_NumColumns;
+
+ RECT rect;
+ /* l t r b */
+ int TileWidth;
+ if (m_WholeCell) TileWidth = m_TileWidth;
+ else TileWidth = m_Widths[c];
+
+ CBPlatform::SetRect(&rect, col * m_TileWidth, row * m_TileHeight, col * m_TileWidth + TileWidth, (row + 1)*m_TileHeight);
+ bool Handled = false;
+ if (m_Sprite) {
+ m_Sprite->GetCurrentFrame();
+ if (m_Sprite->m_CurrentFrame >= 0 && m_Sprite->m_CurrentFrame < m_Sprite->m_Frames.GetSize() && m_Sprite->m_Frames[m_Sprite->m_CurrentFrame]) {
+ if (m_Sprite->m_Frames[m_Sprite->m_CurrentFrame]->m_Subframes.GetSize() > 0) {
+ m_Sprite->m_Frames[m_Sprite->m_CurrentFrame]->m_Subframes[0]->m_Surface->DisplayTrans(x, y, rect);
+ }
+ Handled = true;
+ }
+ }
+ if (!Handled && m_Subframe) m_Subframe->m_Surface->DisplayTrans(x, y, rect);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFontBitmap::LoadFile(char *Filename) {
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer == NULL) {
+ Game->LOG(0, "CBFontBitmap::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret;
+
+ m_Filename = new char [strlen(Filename) + 1];
+ strcpy(m_Filename, Filename);
+
+ if (FAILED(ret = LoadBuffer(Buffer))) Game->LOG(0, "Error parsing FONT file '%s'", Filename);
+
+ delete [] Buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(FONTEXT_FIX)
+TOKEN_DEF(FONT)
+TOKEN_DEF(IMAGE)
+TOKEN_DEF(TRANSPARENT)
+TOKEN_DEF(COLUMNS)
+TOKEN_DEF(TILE_WIDTH)
+TOKEN_DEF(TILE_HEIGHT)
+TOKEN_DEF(DEFAULT_WIDTH)
+TOKEN_DEF(WIDTHS)
+TOKEN_DEF(AUTO_WIDTH)
+TOKEN_DEF(SPACE_WIDTH)
+TOKEN_DEF(EXPAND_WIDTH)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(SPRITE)
+TOKEN_DEF(WIDTHS_FRAME)
+TOKEN_DEF(PAINT_WHOLE_CELL)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFontBitmap::LoadBuffer(byte *Buffer) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(FONTEXT_FIX)
+ TOKEN_TABLE(FONT)
+ TOKEN_TABLE(IMAGE)
+ TOKEN_TABLE(TRANSPARENT)
+ TOKEN_TABLE(COLUMNS)
+ TOKEN_TABLE(TILE_WIDTH)
+ TOKEN_TABLE(TILE_HEIGHT)
+ TOKEN_TABLE(DEFAULT_WIDTH)
+ TOKEN_TABLE(WIDTHS)
+ TOKEN_TABLE(AUTO_WIDTH)
+ TOKEN_TABLE(SPACE_WIDTH)
+ TOKEN_TABLE(EXPAND_WIDTH)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(SPRITE)
+ TOKEN_TABLE(WIDTHS_FRAME)
+ TOKEN_TABLE(PAINT_WHOLE_CELL)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_FONT) {
+ Game->LOG(0, "'FONT' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = (byte *)params;
+
+ int widths[300];
+ int num = 0, default_width = 8;
+ int last_width = 0;
+ int i;
+ int r = 255, g = 255, b = 255;
+ bool custom_trans = false;
+ char *surface_file = NULL;
+ char *sprite_file = NULL;
+
+ bool AutoWidth = false;
+ int SpaceWidth = 0;
+ int ExpandWidth = 0;
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+
+ switch (cmd) {
+ case TOKEN_IMAGE:
+ surface_file = (char *)params;
+ break;
+
+ case TOKEN_SPRITE:
+ sprite_file = (char *)params;
+ break;
+
+ case TOKEN_TRANSPARENT:
+ parser.ScanStr(params, "%d,%d,%d", &r, &g, &b);
+ custom_trans = true;
+ break;
+
+ case TOKEN_WIDTHS:
+ parser.ScanStr(params, "%D", widths, &num);
+ for (i = 0; last_width < NUM_CHARACTERS, num > 0; last_width++, num--, i++) {
+ m_Widths[last_width] = (byte )widths[i];
+ }
+ break;
+
+ case TOKEN_DEFAULT_WIDTH:
+ parser.ScanStr(params, "%d", &default_width);
+ break;
+
+ case TOKEN_WIDTHS_FRAME:
+ parser.ScanStr(params, "%d", &m_WidthsFrame);
+ break;
+
+ case TOKEN_COLUMNS:
+ parser.ScanStr(params, "%d", &m_NumColumns);
+ break;
+
+ case TOKEN_TILE_WIDTH:
+ parser.ScanStr(params, "%d", &m_TileWidth);
+ break;
+
+ case TOKEN_TILE_HEIGHT:
+ parser.ScanStr(params, "%d", &m_TileHeight);
+ break;
+
+ case TOKEN_AUTO_WIDTH:
+ parser.ScanStr(params, "%b", &AutoWidth);
+ break;
+
+ case TOKEN_FONTEXT_FIX:
+ parser.ScanStr(params, "%b", &m_FontextFix);
+ break;
+
+ case TOKEN_PAINT_WHOLE_CELL:
+ parser.ScanStr(params, "%b", &m_WholeCell);
+ break;
+
+ case TOKEN_SPACE_WIDTH:
+ parser.ScanStr(params, "%d", &SpaceWidth);
+ break;
+
+ case TOKEN_EXPAND_WIDTH:
+ parser.ScanStr(params, "%d", &ExpandWidth);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ ParseEditorProperty((byte *)params, false);
+ break;
+ }
+
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in FONT definition");
+ return E_FAIL;
+ }
+
+ if (sprite_file != NULL) {
+ SAFE_DELETE(m_Sprite);
+ m_Sprite = new CBSprite(Game, this);
+ if (!m_Sprite || FAILED(m_Sprite->LoadFile(sprite_file))) SAFE_DELETE(m_Sprite);
+ }
+
+ if (surface_file != NULL && !m_Sprite) {
+ m_Subframe = new CBSubFrame(Game);
+ if (custom_trans) m_Subframe->SetSurface(surface_file, false, r, g, b);
+ else m_Subframe->SetSurface(surface_file);
+ }
+
+
+ if (((m_Subframe == NULL || m_Subframe->m_Surface == NULL) && m_Sprite == NULL) || m_NumColumns == 0 || m_TileWidth == 0 || m_TileHeight == 0) {
+ Game->LOG(0, "Incomplete font definition");
+ return E_FAIL;
+ }
+
+ if (AutoWidth) {
+ // calculate characters width
+ GetWidths();
+
+ // do we need to modify widths?
+ if (ExpandWidth != 0) {
+ for (i = 0; i < NUM_CHARACTERS; i++) {
+ int NewWidth = (int)m_Widths[i] + ExpandWidth;
+ if (NewWidth < 0) NewWidth = 0;
+
+ m_Widths[i] = (byte )NewWidth;
+ }
+ }
+
+ // handle space character
+ char SpaceChar = ' ';
+ if (m_FontextFix) SpaceChar--;
+
+ if (SpaceWidth != 0) m_Widths[SpaceChar] = SpaceWidth;
+ else {
+ if (m_Widths[SpaceChar] == ExpandWidth || m_Widths[SpaceChar] == 0) {
+ m_Widths[SpaceChar] = (m_Widths['m'] + m_Widths['i']) / 2;
+ }
+ }
+ } else {
+ for (i = last_width; i < NUM_CHARACTERS; i++) m_Widths[i] = default_width;
+ }
+
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontBitmap::Persist(CBPersistMgr *PersistMgr) {
+
+ CBFont::Persist(PersistMgr);
+ PersistMgr->Transfer(TMEMBER(m_NumColumns));
+
+ PersistMgr->Transfer(TMEMBER(m_Subframe));
+ PersistMgr->Transfer(TMEMBER(m_TileHeight));
+ PersistMgr->Transfer(TMEMBER(m_TileWidth));
+ PersistMgr->Transfer(TMEMBER(m_Sprite));
+ PersistMgr->Transfer(TMEMBER(m_WidthsFrame));
+
+ if (PersistMgr->m_Saving)
+ PersistMgr->PutBytes(m_Widths, sizeof(m_Widths));
+ else
+ PersistMgr->GetBytes(m_Widths, sizeof(m_Widths));
+
+
+ PersistMgr->Transfer(TMEMBER(m_FontextFix));
+ PersistMgr->Transfer(TMEMBER(m_WholeCell));
+
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBFontBitmap::GetCharWidth(byte Index) {
+ if (m_FontextFix) Index--;
+ return m_Widths[Index];
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontBitmap::GetWidths() {
+ CBSurface *surf = NULL;
+
+ if (m_Sprite) {
+ if (m_WidthsFrame >= 0 && m_WidthsFrame < m_Sprite->m_Frames.GetSize()) {
+ if (m_Sprite->m_Frames[m_WidthsFrame] && m_Sprite->m_Frames[m_WidthsFrame]->m_Subframes.GetSize() > 0) {
+ surf = m_Sprite->m_Frames[m_WidthsFrame]->m_Subframes[0]->m_Surface;
+ }
+ }
+ }
+ if (surf == NULL && m_Subframe) surf = m_Subframe->m_Surface;
+ if (!surf || FAILED(surf->StartPixelOp())) return E_FAIL;
+
+
+ for (int i = 0; i < NUM_CHARACTERS; i++) {
+ int xxx = (i % m_NumColumns) * m_TileWidth;
+ int yyy = (i / m_NumColumns) * m_TileHeight;
+
+
+ int min_col = -1;
+ for (int row = 0; row < m_TileHeight; row++) {
+ for (int col = m_TileWidth - 1; col >= min_col + 1; col--) {
+ if (xxx + col < 0 || xxx + col >= surf->GetWidth() || yyy + row < 0 || yyy + row >= surf->GetHeight()) continue;
+ if (!surf->IsTransparentAtLite(xxx + col, yyy + row)) {
+ //min_col = col;
+ min_col = std::max(col, min_col);
+ break;
+ }
+ }
+ if (min_col == m_TileWidth - 1) break;
+ }
+
+ m_Widths[i] = min_col + 1;
+ }
+ surf->EndPixelOp();
+ /*
+ Game->LOG(0, "----- %s ------", m_Filename);
+ for(int j=0; j<16; j++)
+ {
+ Game->LOG(0, "%02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d %02d", m_Widths[j*16+0], m_Widths[j*16+1], m_Widths[j*16+2], m_Widths[j*16+3], m_Widths[j*16+4], m_Widths[j*16+5], m_Widths[j*16+6], m_Widths[j*16+7], m_Widths[j*16+8], m_Widths[j*16+9], m_Widths[j*16+10], m_Widths[j*16+11], m_Widths[j*16+12], m_Widths[j*16+13], m_Widths[j*16+14], m_Widths[j*16+15]);
+ }
+ */
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CBFontBitmap::GetLetterHeight() {
+ return m_TileHeight;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFontBitmap.h b/engines/wintermute/BFontBitmap.h
new file mode 100644
index 0000000000..c56c192e63
--- /dev/null
+++ b/engines/wintermute/BFontBitmap.h
@@ -0,0 +1,72 @@
+/* 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_BFONTBITMAP_H
+#define WINTERMUTE_BFONTBITMAP_H
+
+
+#include "BFont.h"
+
+namespace WinterMute {
+class CBSubFrame;
+class CBFontBitmap : public CBFont {
+public:
+ DECLARE_PERSISTENT(CBFontBitmap, CBFont)
+ HRESULT LoadBuffer(byte *Buffer);
+ HRESULT LoadFile(char *Filename);
+ virtual int GetTextWidth(byte *text, int MaxLength = -1);
+ virtual int GetTextHeight(byte *text, int width);
+ virtual void DrawText(byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int MaxLenght = -1);
+ virtual int GetLetterHeight();
+
+ CBFontBitmap(CBGame *inGame);
+ virtual ~CBFontBitmap();
+
+
+ HRESULT GetWidths();
+ CBSprite *m_Sprite;
+ int m_WidthsFrame;
+ bool m_FontextFix;
+ int m_NumColumns;
+ int m_TileHeight;
+ int m_TileWidth;
+ byte m_Widths[NUM_CHARACTERS];
+ CBSubFrame *m_Subframe;
+ bool m_WholeCell;
+
+private:
+ int GetCharWidth(byte Index);
+ void DrawChar(byte c, int x, int y);
+
+ int TextHeightDraw(byte *text, int x, int y, int width, TTextAlign align, bool draw, int max_height = -1, int MaxLenght = -1);
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFontStorage.cpp b/engines/wintermute/BFontStorage.cpp
new file mode 100644
index 0000000000..cb14714550
--- /dev/null
+++ b/engines/wintermute/BFontStorage.cpp
@@ -0,0 +1,155 @@
+/* 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 "BFontStorage.h"
+#include "BGame.h"
+#include "BFont.h"
+#include "PlatformSDL.h"
+#include "common/str.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CBFontStorage, true)
+
+//////////////////////////////////////////////////////////////////////////
+CBFontStorage::CBFontStorage(CBGame *inGame): CBBase(inGame) {
+ m_FTLibrary = NULL;
+ InitFreeType();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBFontStorage::~CBFontStorage() {
+ Cleanup(true);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontStorage::InitFreeType() {
+ FT_Error error = FT_Init_FreeType(&m_FTLibrary);
+ if (error) {
+ Game->LOG(0, "Error initializing FreeType library.");
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontStorage::Cleanup(bool Warn) {
+ int i;
+
+ for (i = 0; i < m_Fonts.GetSize(); i++) {
+ if (Warn) Game->LOG(0, "Removing orphan font '%s'", m_Fonts[i]->m_Filename);
+ delete m_Fonts[i];
+ }
+ m_Fonts.RemoveAll();
+
+
+ if (m_FTLibrary) FT_Done_FreeType(m_FTLibrary);
+
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontStorage::InitLoop() {
+ for (int i = 0; i < m_Fonts.GetSize(); i++) {
+ m_Fonts[i]->InitLoop();
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBFont *CBFontStorage::AddFont(char *Filename) {
+ if (!Filename) return NULL;
+
+ for (int i = 0; i < m_Fonts.GetSize(); i++) {
+ if (scumm_stricmp(m_Fonts[i]->m_Filename, Filename) == 0) {
+ m_Fonts[i]->m_RefCount++;
+ return m_Fonts[i];
+ }
+ }
+
+ /*
+ CBFont* font = new CBFont(Game);
+ if(!font) return NULL;
+
+ if(FAILED(font->LoadFile(Filename))){
+ delete font;
+ return NULL;
+ }
+ else {
+ font->m_RefCount = 1;
+ m_Fonts.Add(font);
+ return font;
+ }
+ */
+ CBFont *font = CBFont::CreateFromFile(Game, Filename);
+ if (font) {
+ font->m_RefCount = 1;
+ m_Fonts.Add(font);
+ }
+ return font;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontStorage::RemoveFont(CBFont *Font) {
+ if (!Font) return E_FAIL;
+
+ for (int i = 0; i < m_Fonts.GetSize(); i++) {
+ if (m_Fonts[i] == Font) {
+ m_Fonts[i]->m_RefCount--;
+ if (m_Fonts[i]->m_RefCount <= 0) {
+ delete m_Fonts[i];
+ m_Fonts.RemoveAt(i);
+ }
+ break;
+ }
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontStorage::Persist(CBPersistMgr *PersistMgr) {
+
+ if (!PersistMgr->m_Saving) Cleanup(false);
+
+ PersistMgr->Transfer(TMEMBER(Game));
+ m_Fonts.Persist(PersistMgr);
+
+ if (!PersistMgr->m_Saving) InitFreeType();
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFontStorage.h b/engines/wintermute/BFontStorage.h
new file mode 100644
index 0000000000..6dc2273022
--- /dev/null
+++ b/engines/wintermute/BFontStorage.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_BFONTSTORAGE_H
+#define WINTERMUTE_BFONTSTORAGE_H
+
+
+#include "BBase.h"
+#include "persistent.h"
+#include "coll_templ.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+namespace WinterMute {
+
+class CBFont;
+
+class CBFontStorage : public CBBase {
+public:
+ DECLARE_PERSISTENT(CBFontStorage, CBBase)
+ HRESULT Cleanup(bool Warn = false);
+ HRESULT RemoveFont(CBFont *Font);
+ CBFont *AddFont(char *Filename);
+ CBFontStorage(CBGame *inGame);
+ virtual ~CBFontStorage();
+ CBArray<CBFont *, CBFont *> m_Fonts;
+ HRESULT InitLoop();
+
+ FT_Library GetFTLibrary() const {
+ return m_FTLibrary;
+ }
+
+private:
+ void InitFreeType();
+ FT_Library m_FTLibrary;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFontTT.cpp b/engines/wintermute/BFontTT.cpp
new file mode 100644
index 0000000000..a1ca6577fa
--- /dev/null
+++ b/engines/wintermute/BFontTT.cpp
@@ -0,0 +1,853 @@
+/* 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 <ft2build.h>
+#include FT_FREETYPE_H
+#include "dcgf.h"
+#include "BFile.h"
+#include "BFontTT.h"
+#include "FontGlyphCache.h"
+#include "PathUtil.h"
+#include "StringUtil.h"
+#include "MathUtil.h"
+#include "BRenderSDL.h"
+#include "BSurfaceSDL.h"
+#include "BParser.h"
+#include "BGame.h"
+#include "BFileManager.h"
+#include "utils.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBFontTT, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBFontTT::CBFontTT(CBGame *inGame): CBFont(inGame) {
+ m_FontHeight = 12;
+ m_IsBold = m_IsItalic = m_IsUnderline = m_IsStriked = false;
+
+ m_FontFile = NULL;
+
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) m_CachedTexts[i] = NULL;
+
+
+ m_FTFace = NULL;
+ m_FTStream = NULL;
+
+ m_GlyphCache = NULL;
+
+ m_Ascender = m_Descender = m_LineHeight = m_PointSize = m_UnderlinePos = 0;
+ m_HorDpi = m_VertDpi = 0;
+ m_MaxCharWidth = m_MaxCharHeight = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBFontTT::~CBFontTT(void) {
+ ClearCache();
+
+ for (int i = 0; i < m_Layers.GetSize(); i++) {
+ delete m_Layers[i];
+ }
+ m_Layers.RemoveAll();
+
+ delete[] m_FontFile;
+ m_FontFile = NULL;
+
+ delete m_GlyphCache;
+ m_GlyphCache = NULL;
+
+ if (m_FTFace) {
+ FT_Done_Face(m_FTFace);
+ m_FTFace = NULL;
+ }
+ delete[] m_FTStream;
+ m_FTStream = NULL;
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::ClearCache() {
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ if (m_CachedTexts[i]) delete m_CachedTexts[i];
+ m_CachedTexts[i] = NULL;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::InitLoop() {
+ // we need more aggressive cache management on iOS not to waste too much memory on fonts
+ if (Game->m_ConstrainedMemory) {
+ // purge all cached images not used in the last frame
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ if (m_CachedTexts[i] == NULL) continue;
+
+ if (!m_CachedTexts[i]->m_Marked) {
+ delete m_CachedTexts[i];
+ m_CachedTexts[i] = NULL;
+ } else m_CachedTexts[i]->m_Marked = false;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CBFontTT::GetTextWidth(byte *Text, int MaxLength) {
+ WideString text;
+
+ if (Game->m_TextEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
+ else text = StringUtil::AnsiToWide((char *)Text);
+
+ if (MaxLength >= 0 && text.length() > MaxLength) text = text.substr(0, MaxLength);
+
+ int textWidth, textHeight;
+ MeasureText(text, -1, -1, textWidth, textHeight);
+
+ return textWidth;
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CBFontTT::GetTextHeight(byte *Text, int Width) {
+ WideString text;
+
+ if (Game->m_TextEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
+ else text = StringUtil::AnsiToWide((char *)Text);
+
+
+ int textWidth, textHeight;
+ MeasureText(text, Width, -1, textWidth, textHeight);
+
+ return textHeight;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::DrawText(byte *Text, int X, int Y, int Width, TTextAlign Align, int MaxHeight, int MaxLength) {
+ if (Text == NULL || strcmp((char *)Text, "") == 0) return;
+
+ WideString text;
+
+ if (Game->m_TextEncoding == TEXT_UTF8) text = StringUtil::Utf8ToWide((char *)Text);
+ else text = StringUtil::AnsiToWide((char *)Text);
+
+ if (MaxLength >= 0 && text.length() > MaxLength) text = text.substr(0, MaxLength);
+
+ CBRenderSDL *m_Renderer = (CBRenderSDL *)Game->m_Renderer;
+
+ // find cached surface, if exists
+ int MinPriority = INT_MAX;
+ int MinIndex = -1;
+ CBSurface *Surface = NULL;
+ int textOffset = 0;
+
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) {
+ if (m_CachedTexts[i] == NULL) {
+ MinPriority = 0;
+ MinIndex = i;
+ } else {
+ if (m_CachedTexts[i]->m_Text == text && m_CachedTexts[i]->m_Align == Align && m_CachedTexts[i]->m_Width == Width && m_CachedTexts[i]->m_MaxHeight == MaxHeight && m_CachedTexts[i]->m_MaxLength == MaxLength) {
+ Surface = m_CachedTexts[i]->m_Surface;
+ textOffset = m_CachedTexts[i]->m_TextOffset;
+ m_CachedTexts[i]->m_Priority++;
+ m_CachedTexts[i]->m_Marked = true;
+ break;
+ } else {
+ if (m_CachedTexts[i]->m_Priority < MinPriority) {
+ MinPriority = m_CachedTexts[i]->m_Priority;
+ MinIndex = i;
+ }
+ }
+ }
+ }
+
+ // not found, create one
+ if (!Surface) {
+ Surface = RenderTextToTexture(text, Width, Align, MaxHeight, textOffset);
+ if (Surface) {
+ // write surface to cache
+ if (m_CachedTexts[MinIndex] != NULL) delete m_CachedTexts[MinIndex];
+ m_CachedTexts[MinIndex] = new CBCachedTTFontText;
+
+ m_CachedTexts[MinIndex]->m_Surface = Surface;
+ m_CachedTexts[MinIndex]->m_Align = Align;
+ m_CachedTexts[MinIndex]->m_Width = Width;
+ m_CachedTexts[MinIndex]->m_MaxHeight = MaxHeight;
+ m_CachedTexts[MinIndex]->m_MaxLength = MaxLength;
+ m_CachedTexts[MinIndex]->m_Priority = 1;
+ m_CachedTexts[MinIndex]->m_Text = text;
+ m_CachedTexts[MinIndex]->m_TextOffset = textOffset;
+ m_CachedTexts[MinIndex]->m_Marked = true;
+ }
+ }
+
+
+ // and paint it
+ if (Surface) {
+ RECT rc;
+ CBPlatform::SetRect(&rc, 0, 0, Surface->GetWidth(), Surface->GetHeight());
+ for (int i = 0; i < m_Layers.GetSize(); i++) {
+ uint32 Color = m_Layers[i]->m_Color;
+ uint32 OrigForceAlpha = m_Renderer->m_ForceAlphaColor;
+ if (m_Renderer->m_ForceAlphaColor != 0) {
+ Color = DRGBA(D3DCOLGetR(Color), D3DCOLGetG(Color), D3DCOLGetB(Color), D3DCOLGetA(m_Renderer->m_ForceAlphaColor));
+ m_Renderer->m_ForceAlphaColor = 0;
+ }
+ Surface->DisplayTransOffset(X, Y - textOffset, rc, Color, BLEND_NORMAL, false, false, m_Layers[i]->m_OffsetX, m_Layers[i]->m_OffsetY);
+
+ m_Renderer->m_ForceAlphaColor = OrigForceAlpha;
+ }
+ }
+
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBSurface *CBFontTT::RenderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) {
+ TextLineList lines;
+ WrapText(text, width, maxHeight, lines);
+
+
+ TextLineList::iterator it;
+
+ int textHeight = lines.size() * (m_MaxCharHeight + m_Ascender);
+ SDL_Surface *surface = SDL_CreateRGBSurface(0, width, textHeight, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
+
+ SDL_LockSurface(surface);
+
+ int posY = (int)GetLineHeight() - (int)m_Descender;
+
+ for (it = lines.begin(); it != lines.end(); ++it) {
+ TextLine *line = (*it);
+ int posX = 0;
+
+ switch (align) {
+ case TAL_CENTER:
+ posX += (width - line->GetWidth()) / 2;
+ break;
+
+ case TAL_RIGHT:
+ posX += width - line->GetWidth();
+ break;
+ }
+
+
+ textOffset = 0;
+ for (size_t i = 0; i < line->GetText().length(); i++) {
+ wchar_t ch = line->GetText()[i];
+
+ GlyphInfo *glyph = m_GlyphCache->GetGlyph(ch);
+ if (!glyph) continue;
+
+ textOffset = std::max(textOffset, glyph->GetBearingY());
+ }
+
+
+ int origPosX = posX;
+
+ wchar_t prevChar = L'\0';
+ for (size_t i = 0; i < line->GetText().length(); i++) {
+ wchar_t ch = line->GetText()[i];
+
+ GlyphInfo *glyph = m_GlyphCache->GetGlyph(ch);
+ if (!glyph) continue;
+
+ float kerning = 0;
+ if (prevChar != L'\0') kerning = GetKerning(prevChar, ch);
+ posX += (int)kerning;
+
+
+ if (glyph->GetBearingY() > 0) {
+ int i = 10;
+ }
+
+ SDL_Rect rect;
+ rect.x = posX + glyph->GetBearingX();
+ rect.y = posY - glyph->GetBearingY() + textOffset;
+ rect.w = glyph->GetImage()->w;
+ rect.h = glyph->GetImage()->h;
+
+ BlitSurface(glyph->GetImage(), surface, &rect);
+
+ prevChar = ch;
+ posX += (int)(glyph->GetAdvanceX());
+ posY += (int)(glyph->GetAdvanceY());
+ }
+
+ if (m_IsUnderline) {
+ for (int i = origPosX; i < origPosX + line->GetWidth(); i++) {
+ Uint8 *buf = (Uint8 *)surface->pixels + (int)(m_UnderlinePos + m_Ascender) * surface->pitch;
+ Uint32 *buf32 = (Uint32 *)buf;
+
+ buf32[i] = SDL_MapRGBA(surface->format, 255, 255, 255, 255);
+ }
+ }
+
+ SDL_UnlockSurface(surface);
+
+ delete line;
+ line = NULL;
+ posY += GetLineHeight();
+ }
+
+ CBSurfaceSDL *wmeSurface = new CBSurfaceSDL(Game);
+ if (SUCCEEDED(wmeSurface->CreateFromSDLSurface(surface))) {
+ SDL_FreeSurface(surface);
+ return wmeSurface;
+ } else {
+ SDL_FreeSurface(surface);
+ delete wmeSurface;
+ return NULL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::BlitSurface(SDL_Surface *src, SDL_Surface *target, SDL_Rect *targetRect) {
+ //SDL_BlitSurface(src, NULL, target, targetRect);
+
+ for (int y = 0; y < src->h; y++) {
+ if (targetRect->y + y < 0 || targetRect->y + y >= target->h) continue;
+
+
+ Uint8 *srcBuf = (Uint8 *)src->pixels + y * src->pitch;
+ Uint8 *tgtBuf = (Uint8 *)target->pixels + (y + targetRect->y) * target->pitch;
+
+ Uint32 *srcBuf32 = (Uint32 *)srcBuf;
+ Uint32 *tgtBuf32 = (Uint32 *)tgtBuf;
+
+ for (int x = 0; x < src->w; x++) {
+ if (targetRect->x + x < 0 || targetRect->x + x >= target->w) continue;
+
+ tgtBuf32[x + targetRect->x] = srcBuf32[x];
+ }
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+int CBFontTT::GetLetterHeight() {
+ return GetLineHeight();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFontTT::LoadFile(char *Filename) {
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer == NULL) {
+ Game->LOG(0, "CBFontTT::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret;
+
+ m_Filename = new char [strlen(Filename) + 1];
+ strcpy(m_Filename, Filename);
+
+ if (FAILED(ret = LoadBuffer(Buffer))) Game->LOG(0, "Error parsing TTFONT file '%s'", Filename);
+
+ delete [] Buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(TTFONT)
+TOKEN_DEF(SIZE)
+TOKEN_DEF(FACE)
+TOKEN_DEF(FILENAME)
+TOKEN_DEF(BOLD)
+TOKEN_DEF(ITALIC)
+TOKEN_DEF(UNDERLINE)
+TOKEN_DEF(STRIKE)
+TOKEN_DEF(CHARSET)
+TOKEN_DEF(COLOR)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(LAYER)
+TOKEN_DEF(OFFSET_X)
+TOKEN_DEF(OFFSET_Y)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFontTT::LoadBuffer(byte *Buffer) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(TTFONT)
+ TOKEN_TABLE(SIZE)
+ TOKEN_TABLE(FACE)
+ TOKEN_TABLE(FILENAME)
+ TOKEN_TABLE(BOLD)
+ TOKEN_TABLE(ITALIC)
+ TOKEN_TABLE(UNDERLINE)
+ TOKEN_TABLE(STRIKE)
+ TOKEN_TABLE(CHARSET)
+ TOKEN_TABLE(COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(LAYER)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_TTFONT) {
+ Game->LOG(0, "'TTFONT' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = (byte *)params;
+
+ uint32 BaseColor = 0x00000000;
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_SIZE:
+ parser.ScanStr(params, "%d", &m_FontHeight);
+ break;
+
+ case TOKEN_FACE:
+ // we don't need this anymore
+ break;
+
+ case TOKEN_FILENAME:
+ CBUtils::SetString(&m_FontFile, params);
+ break;
+
+ case TOKEN_BOLD:
+ parser.ScanStr(params, "%b", &m_IsBold);
+ break;
+
+ case TOKEN_ITALIC:
+ parser.ScanStr(params, "%b", &m_IsItalic);
+ break;
+
+ case TOKEN_UNDERLINE:
+ parser.ScanStr(params, "%b", &m_IsUnderline);
+ break;
+
+ case TOKEN_STRIKE:
+ parser.ScanStr(params, "%b", &m_IsStriked);
+ break;
+
+ case TOKEN_CHARSET:
+ // we don't need this anymore
+ break;
+
+ case TOKEN_COLOR: {
+ int r, g, b;
+ parser.ScanStr(params, "%d,%d,%d", &r, &g, &b);
+ BaseColor = DRGBA(r, g, b, D3DCOLGetA(BaseColor));
+ }
+ break;
+
+ case TOKEN_ALPHA: {
+ int a;
+ parser.ScanStr(params, "%d", &a);
+ BaseColor = DRGBA(D3DCOLGetR(BaseColor), D3DCOLGetG(BaseColor), D3DCOLGetB(BaseColor), a);
+ }
+ break;
+
+ case TOKEN_LAYER: {
+ CBTTFontLayer *Layer = new CBTTFontLayer;
+ if (Layer && SUCCEEDED(ParseLayer(Layer, (byte *)params))) m_Layers.Add(Layer);
+ else {
+ delete Layer;
+ Layer = NULL;
+ cmd = PARSERR_TOKENNOTFOUND;
+ }
+ }
+ break;
+
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in TTFONT definition");
+ return E_FAIL;
+ }
+
+ // create at least one layer
+ if (m_Layers.GetSize() == 0) {
+ CBTTFontLayer *Layer = new CBTTFontLayer;
+ Layer->m_Color = BaseColor;
+ m_Layers.Add(Layer);
+ }
+
+ if (!m_FontFile) CBUtils::SetString(&m_FontFile, "arial.ttf");
+
+ return InitFont();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontTT::ParseLayer(CBTTFontLayer *Layer, byte *Buffer) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(OFFSET_X)
+ TOKEN_TABLE(OFFSET_Y)
+ TOKEN_TABLE(COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ CBParser parser(Game);
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_OFFSET_X:
+ parser.ScanStr(params, "%d", &Layer->m_OffsetX);
+ break;
+
+ case TOKEN_OFFSET_Y:
+ parser.ScanStr(params, "%d", &Layer->m_OffsetY);
+ break;
+
+ case TOKEN_COLOR: {
+ int r, g, b;
+ parser.ScanStr(params, "%d,%d,%d", &r, &g, &b);
+ Layer->m_Color = DRGBA(r, g, b, D3DCOLGetA(Layer->m_Color));
+ }
+ break;
+
+ case TOKEN_ALPHA: {
+ int a;
+ parser.ScanStr(params, "%d", &a);
+ Layer->m_Color = DRGBA(D3DCOLGetR(Layer->m_Color), D3DCOLGetG(Layer->m_Color), D3DCOLGetB(Layer->m_Color), a);
+ }
+ break;
+ }
+ }
+ if (cmd != PARSERR_EOF) return E_FAIL;
+ else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontTT::Persist(CBPersistMgr *PersistMgr) {
+ CBFont::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_IsBold));
+ PersistMgr->Transfer(TMEMBER(m_IsItalic));
+ PersistMgr->Transfer(TMEMBER(m_IsUnderline));
+ PersistMgr->Transfer(TMEMBER(m_IsStriked));
+ PersistMgr->Transfer(TMEMBER(m_FontHeight));
+ PersistMgr->Transfer(TMEMBER(m_FontFile));
+
+
+ // persist layers
+ int NumLayers;
+ if (PersistMgr->m_Saving) {
+ NumLayers = m_Layers.GetSize();
+ PersistMgr->Transfer(TMEMBER(NumLayers));
+ for (int i = 0; i < NumLayers; i++) m_Layers[i]->Persist(PersistMgr);
+ } else {
+ NumLayers = m_Layers.GetSize();
+ PersistMgr->Transfer(TMEMBER(NumLayers));
+ for (int i = 0; i < NumLayers; i++) {
+ CBTTFontLayer *Layer = new CBTTFontLayer;
+ Layer->Persist(PersistMgr);
+ m_Layers.Add(Layer);
+ }
+ }
+
+ if (!PersistMgr->m_Saving) {
+ for (int i = 0; i < NUM_CACHED_TEXTS; i++) m_CachedTexts[i] = NULL;
+ m_GlyphCache = NULL;
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::AfterLoad() {
+ InitFont();
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFontTT::InitFont() {
+ if (!m_FontFile) return E_FAIL;
+
+ CBFile *file = Game->m_FileManager->OpenFile(m_FontFile);
+ if (!file) {
+ // the requested font file is not in wme file space; try loading a system font
+ AnsiString fontFileName = PathUtil::Combine(CBPlatform::GetSystemFontPath(), PathUtil::GetFileName(m_FontFile));
+ file = Game->m_FileManager->OpenFile((char *)fontFileName.c_str(), false);
+
+ if (!file) {
+ Game->LOG(0, "Error loading TrueType font '%s'", m_FontFile);
+ return E_FAIL;
+ }
+ }
+
+ FT_Error error;
+
+ float vertDpi = 96.0;
+ float horDpi = 96.0;
+
+
+ m_FTStream = (FT_Stream)new byte[sizeof(*m_FTStream)];
+ memset(m_FTStream, 0, sizeof(*m_FTStream));
+
+ m_FTStream->read = CBFontTT::FTReadSeekProc;
+ m_FTStream->close = CBFontTT::FTCloseProc;
+ m_FTStream->descriptor.pointer = file;
+ m_FTStream->size = file->GetSize();
+
+ FT_Open_Args args;
+ args.flags = FT_OPEN_STREAM;
+ args.stream = m_FTStream;
+
+ error = FT_Open_Face(Game->m_FontStorage->GetFTLibrary(), &args, 0, &m_FTFace);
+ if (error) {
+ SAFE_DELETE_ARRAY(m_FTStream);
+ Game->m_FileManager->CloseFile(file);
+ return E_FAIL;
+ }
+
+ error = FT_Set_Char_Size(m_FTFace, 0, (FT_F26Dot6)(m_FontHeight * 64), (FT_UInt)horDpi, (FT_UInt)vertDpi);
+ if (error) {
+ FT_Done_Face(m_FTFace);
+ m_FTFace = NULL;
+ return E_FAIL;
+ }
+
+ // http://en.wikipedia.org/wiki/Em_(typography)
+ float pixelsPerEm = (m_FontHeight / 72.f) * vertDpi; // Size in inches * dpi
+ float EmsPerUnit = 1.0f / m_FTFace->units_per_EM;
+ float pixelsPerUnit = pixelsPerEm * EmsPerUnit;
+
+ // bounding box in pixels
+ float xMin = m_FTFace->bbox.xMin * pixelsPerUnit;
+ float xMax = m_FTFace->bbox.xMax * pixelsPerUnit;
+ float yMin = m_FTFace->bbox.yMin * pixelsPerUnit;
+ float yMax = m_FTFace->bbox.yMax * pixelsPerUnit;
+
+ // metrics in pixels
+ m_Ascender = m_FTFace->ascender * pixelsPerUnit;
+ m_Descender = - m_FTFace->descender * pixelsPerUnit;
+ m_LineHeight = MathUtil::RoundUp(m_FTFace->height * pixelsPerUnit) + 2;
+ m_UnderlinePos = - m_FTFace->underline_position * pixelsPerUnit;
+
+ // max character size (used for texture grid)
+ m_MaxCharWidth = (size_t)MathUtil::RoundUp(xMax - xMin);
+ m_MaxCharHeight = (size_t)MathUtil::RoundUp(yMax - yMin);
+
+ m_GlyphCache = new FontGlyphCache();
+ m_GlyphCache->Initialize();
+
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// I/O bridge between FreeType and WME file system
+//////////////////////////////////////////////////////////////////////////
+unsigned long CBFontTT::FTReadSeekProc(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
+ CBFile *f = static_cast<CBFile *>(stream->descriptor.pointer);
+ if (!f) return 0;
+
+ f->Seek(offset, SEEK_TO_BEGIN);
+ if (count) {
+ uint32 oldPos = f->GetPos();
+ f->Read(buffer, count);
+ return f->GetPos() - oldPos;
+ } else return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::FTCloseProc(FT_Stream stream) {
+ CBFile *f = static_cast<CBFile *>(stream->descriptor.pointer);
+ if (!f) return;
+
+ CBGame *Game = f->Game;
+
+ Game->m_FileManager->CloseFile(f);
+ stream->descriptor.pointer = NULL;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::WrapText(const WideString &text, int maxWidth, int maxHeight, TextLineList &lines) {
+ int currWidth = 0;
+ wchar_t prevChar = L'\0';
+ int prevSpaceIndex = -1;
+ int prevSpaceWidth = 0;
+ int lineStartIndex = 0;
+
+ PrepareGlyphs(text);
+
+ for (size_t i = 0; i < text.length(); i++) {
+ wchar_t ch = text[i];
+
+ if (ch == L' ') {
+ prevSpaceIndex = i;
+ prevSpaceWidth = currWidth;
+ }
+
+ int charWidth = 0;
+
+ if (ch != L'\n') {
+ GlyphInfo *glyphInfo = GetGlyphCache()->GetGlyph(ch);
+ if (!glyphInfo) continue;
+
+ float kerning = 0;
+ if (prevChar != L'\0') kerning = GetKerning(prevChar, ch);
+ prevChar = ch;
+
+ charWidth = (int)(glyphInfo->GetAdvanceX() + kerning);
+ }
+
+ bool lineTooLong = maxWidth >= 0 && currWidth + charWidth > maxWidth;
+ bool breakOnSpace = false;
+
+ // we can't fit even a single character
+ if (lineTooLong && currWidth == 0) break;
+
+
+ if (ch == L'\n' || i == text.length() - 1 || lineTooLong) {
+ int breakPoint, breakWidth;
+
+ if (prevSpaceIndex >= 0 && lineTooLong) {
+ breakPoint = prevSpaceIndex;
+ breakWidth = prevSpaceWidth;
+ breakOnSpace = true;
+ } else {
+ breakPoint = i;
+ breakWidth = currWidth;
+
+ breakOnSpace = (ch == L'\n');
+
+ // we're at the end
+ if (i == text.length() - 1) {
+ breakPoint++;
+ breakWidth += charWidth;
+ }
+ }
+
+ if (maxHeight >= 0 && (lines.size() + 1) * GetLineHeight() > maxHeight) break;
+
+ WideString line = text.substr(lineStartIndex, breakPoint - lineStartIndex);
+ lines.push_back(new TextLine(line, breakWidth));
+
+ currWidth = 0;
+ prevChar = L'\0';
+ prevSpaceIndex = -1;
+
+ if (breakOnSpace) breakPoint++;
+
+ lineStartIndex = breakPoint;
+ i = breakPoint - 1;
+
+ continue;
+ }
+
+ //if (ch == L' ' && currLine.empty()) continue;
+ currWidth += charWidth;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::MeasureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight) {
+ TextLineList lines;
+ WrapText(text, maxWidth, maxHeight, lines);
+
+ textHeight = (int)(lines.size() * GetLineHeight());
+ textWidth = 0;
+
+ TextLineList::iterator it;
+ for (it = lines.begin(); it != lines.end(); ++it) {
+ TextLine *line = (*it);
+ textWidth = std::max(textWidth, line->GetWidth());
+ SAFE_DELETE(line);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+float CBFontTT::GetKerning(wchar_t leftChar, wchar_t rightChar) {
+ GlyphInfo *infoLeft = m_GlyphCache->GetGlyph(leftChar);
+ GlyphInfo *infoRight = m_GlyphCache->GetGlyph(rightChar);
+
+ if (!infoLeft || !infoRight) return 0;
+
+ FT_Vector delta;
+ FT_Error error = FT_Get_Kerning(m_FTFace, infoLeft->GetGlyphIndex(), infoRight->GetGlyphIndex(), ft_kerning_unfitted, &delta);
+ if (error) return 0;
+
+ return delta.x * (1.0f / 64.0f);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::PrepareGlyphs(const WideString &text) {
+ // make sure we have all the glyphs we need
+ for (size_t i = 0; i < text.length(); i++) {
+ wchar_t ch = text[i];
+ if (!m_GlyphCache->HasGlyph(ch)) CacheGlyph(ch);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBFontTT::CacheGlyph(wchar_t ch) {
+ FT_UInt glyphIndex = FT_Get_Char_Index(m_FTFace, ch);
+ if (!glyphIndex) return;
+
+ FT_Error error = FT_Load_Glyph(m_FTFace, glyphIndex, FT_LOAD_DEFAULT);
+ if (error) return;
+
+ error = FT_Render_Glyph(m_FTFace->glyph, FT_RENDER_MODE_NORMAL);
+ if (error) return;
+
+ byte *pixels = m_FTFace->glyph->bitmap.buffer;
+ size_t stride = m_FTFace->glyph->bitmap.pitch;
+
+
+ // convert from monochrome to grayscale if needed
+ byte *tempBuffer = NULL;
+ if (pixels != NULL && m_FTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
+ tempBuffer = new byte[m_FTFace->glyph->bitmap.width * m_FTFace->glyph->bitmap.rows];
+ for (int j = 0; j < m_FTFace->glyph->bitmap.rows; j++) {
+ int rowOffset = stride * j;
+ for (int i = 0; i < m_FTFace->glyph->bitmap.width; i++) {
+ int byteOffset = i / 8;
+ int bitOffset = 7 - (i % 8);
+ byte bit = (pixels[rowOffset + byteOffset] & (1 << bitOffset)) >> bitOffset;
+ tempBuffer[m_FTFace->glyph->bitmap.width * j + i] = 255 * bit;
+ }
+ }
+
+ pixels = tempBuffer;
+ stride = m_FTFace->glyph->bitmap.width;
+ }
+
+ // add glyph to cache
+ m_GlyphCache->AddGlyph(ch, glyphIndex, m_FTFace->glyph, m_FTFace->glyph->bitmap.width, m_FTFace->glyph->bitmap.rows, pixels, stride);
+
+ if (tempBuffer) delete [] tempBuffer;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFontTT.h b/engines/wintermute/BFontTT.h
new file mode 100644
index 0000000000..6fbb019a27
--- /dev/null
+++ b/engines/wintermute/BFontTT.h
@@ -0,0 +1,188 @@
+/* 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_BFONTTT_H
+#define WINTERMUTE_BFONTTT_H
+
+#include "BFontStorage.h"
+#include "BFont.h"
+#include "BSurface.h"
+
+#define NUM_CACHED_TEXTS 30
+class SDL_Surface;
+namespace WinterMute {
+
+class FontGlyphCache;
+
+class CBFontTT : public CBFont {
+private:
+ //////////////////////////////////////////////////////////////////////////
+ class CBCachedTTFontText {
+ public:
+ WideString m_Text;
+ int m_Width;
+ TTextAlign m_Align;
+ int m_MaxHeight;
+ int m_MaxLength;
+ CBSurface *m_Surface;
+ int m_Priority;
+ int m_TextOffset;
+ bool m_Marked;
+
+ CBCachedTTFontText() {
+ m_Text = L"";
+ m_Width = m_MaxHeight = m_MaxLength = -1;
+ m_Align = TAL_LEFT;
+ m_Surface = NULL;
+ m_Priority = -1;
+ m_TextOffset = 0;
+ m_Marked = false;
+ }
+
+ virtual ~CBCachedTTFontText() {
+ if (m_Surface) delete m_Surface;
+ }
+ };
+
+public:
+ //////////////////////////////////////////////////////////////////////////
+ class CBTTFontLayer {
+ public:
+ CBTTFontLayer() {
+ m_OffsetX = m_OffsetY = 0;
+ m_Color = 0x00000000;
+ }
+
+ HRESULT Persist(CBPersistMgr *PersistMgr) {
+ PersistMgr->Transfer(TMEMBER(m_OffsetX));
+ PersistMgr->Transfer(TMEMBER(m_OffsetY));
+ PersistMgr->Transfer(TMEMBER(m_Color));
+ return S_OK;
+ }
+
+ int m_OffsetX;
+ int m_OffsetY;
+ uint32 m_Color;
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ class TextLine {
+ public:
+ TextLine(const WideString &text, int width) {
+ m_Text = text;
+ m_Width = width;
+ }
+
+ const WideString &GetText() const {
+ return m_Text;
+ }
+ int GetWidth() const {
+ return m_Width;
+ }
+ private:
+ WideString m_Text;
+ int m_Width;
+ };
+ typedef std::list<TextLine *> TextLineList;
+
+
+public:
+ DECLARE_PERSISTENT(CBFontTT, CBFont)
+ CBFontTT(CBGame *inGame);
+ virtual ~CBFontTT(void);
+
+ virtual int GetTextWidth(byte *text, int MaxLenght = -1);
+ virtual int GetTextHeight(byte *text, int width);
+ virtual void DrawText(byte *text, int x, int y, int width, TTextAlign align = TAL_LEFT, int max_height = -1, int MaxLenght = -1);
+ virtual int GetLetterHeight();
+
+ HRESULT LoadBuffer(byte *Buffer);
+ HRESULT LoadFile(char *Filename);
+
+ static unsigned long FTReadSeekProc(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count);
+ static void FTCloseProc(FT_Stream stream);
+
+ FontGlyphCache *GetGlyphCache() {
+ return m_GlyphCache;
+ }
+
+ float GetLineHeight() const {
+ return m_LineHeight;
+ }
+
+ void AfterLoad();
+ void InitLoop();
+
+private:
+ HRESULT ParseLayer(CBTTFontLayer *Layer, byte *Buffer);
+
+ void WrapText(const WideString &text, int maxWidth, int maxHeight, TextLineList &lines);
+ void MeasureText(const WideString &text, int maxWidth, int maxHeight, int &textWidth, int &textHeight);
+ float GetKerning(wchar_t leftChar, wchar_t rightChar);
+ void PrepareGlyphs(const WideString &text);
+ void CacheGlyph(wchar_t ch);
+
+ CBSurface *RenderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset);
+ void BlitSurface(SDL_Surface *src, SDL_Surface *target, SDL_Rect *targetRect);
+
+
+ CBCachedTTFontText *m_CachedTexts[NUM_CACHED_TEXTS];
+
+ HRESULT InitFont();
+ FT_Stream m_FTStream;
+ FT_Face m_FTFace;
+
+ FontGlyphCache *m_GlyphCache;
+
+ float m_Ascender;
+ float m_Descender;
+ float m_LineHeight;
+ float m_UnderlinePos;
+ float m_PointSize;
+ float m_VertDpi;
+ float m_HorDpi;
+
+ size_t m_MaxCharWidth;
+ size_t m_MaxCharHeight;
+
+public:
+ bool m_IsBold;
+ bool m_IsItalic;
+ bool m_IsUnderline;
+ bool m_IsStriked;
+ int m_FontHeight;
+ char *m_FontFile;
+
+ CBArray<CBTTFontLayer *, CBTTFontLayer *> m_Layers;
+ void ClearCache();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BFrame.cpp b/engines/wintermute/BFrame.cpp
new file mode 100644
index 0000000000..4d8d557a2a
--- /dev/null
+++ b/engines/wintermute/BFrame.cpp
@@ -0,0 +1,707 @@
+/* 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 "BFrame.h"
+#include "BGame.h"
+#include "BDynBuffer.h"
+#include "ScValue.h"
+#include "BSoundMgr.h"
+#include "BSound.h"
+#include "BSubFrame.h"
+#include "ScScript.h"
+#include "ScStack.h"
+#include "PlatformSDL.h"
+#include "common/str.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBFrame, false)
+
+//////////////////////////////////////////////////////////////////////
+CBFrame::CBFrame(CBGame *inGame): CBScriptable(inGame, true) {
+ m_Delay = 0;
+ m_MoveX = m_MoveY = 0;
+
+ m_Sound = NULL;
+ m_KillSound = false;
+
+ m_EditorExpanded = false;
+ m_Keyframe = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBFrame::~CBFrame() {
+ delete m_Sound;
+ m_Sound = NULL;
+
+ int i;
+
+ for (i = 0; i < m_Subframes.GetSize(); i++) delete m_Subframes[i];
+ m_Subframes.RemoveAll();
+
+ for (i = 0; i < m_ApplyEvent.GetSize(); i++) {
+ SAFE_DELETE_ARRAY(m_ApplyEvent[i]);
+ }
+ m_ApplyEvent.RemoveAll();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::Draw(int X, int Y, CBObject *Register, float ZoomX, float ZoomY, bool Precise, uint32 Alpha, bool AllFrames, float Rotate, TSpriteBlendMode BlendMode) {
+ HRESULT res;
+
+ for (int i = 0; i < m_Subframes.GetSize(); i++) {
+ res = m_Subframes[i]->Draw(X, Y, Register, ZoomX, ZoomY, Precise, Alpha, Rotate, BlendMode);
+ if (FAILED(res)) return res;
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::OneTimeDisplay(CBObject *Owner, bool Muted) {
+ if (m_Sound && !Muted) {
+ if (Owner) Owner->UpdateOneSound(m_Sound);
+ m_Sound->Play();
+ /*
+ if(Game->m_State==GAME_FROZEN)
+ {
+ m_Sound->Pause(true);
+ }
+ */
+ }
+ if (Owner) {
+ for (int i = 0; i < m_ApplyEvent.GetSize(); i++) {
+ Owner->ApplyEvent(m_ApplyEvent[i]);
+ }
+ }
+ return S_OK;
+}
+
+
+
+TOKEN_DEF_START
+TOKEN_DEF(DELAY)
+TOKEN_DEF(IMAGE)
+TOKEN_DEF(TRANSPARENT)
+TOKEN_DEF(RECT)
+TOKEN_DEF(HOTSPOT)
+TOKEN_DEF(2D_ONLY)
+TOKEN_DEF(3D_ONLY)
+TOKEN_DEF(MIRROR_X)
+TOKEN_DEF(MIRROR_Y)
+TOKEN_DEF(MOVE)
+TOKEN_DEF(ALPHA_COLOR)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(SUBFRAME)
+TOKEN_DEF(SOUND)
+TOKEN_DEF(KEYFRAME)
+TOKEN_DEF(DECORATION)
+TOKEN_DEF(APPLY_EVENT)
+TOKEN_DEF(EDITOR_SELECTED)
+TOKEN_DEF(EDITOR_EXPANDED)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(KILL_SOUND)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::LoadBuffer(byte *Buffer, int LifeTime, bool KeepLoaded) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(DELAY)
+ TOKEN_TABLE(IMAGE)
+ TOKEN_TABLE(TRANSPARENT)
+ TOKEN_TABLE(RECT)
+ TOKEN_TABLE(HOTSPOT)
+ TOKEN_TABLE(2D_ONLY)
+ TOKEN_TABLE(3D_ONLY)
+ TOKEN_TABLE(MIRROR_X)
+ TOKEN_TABLE(MIRROR_Y)
+ TOKEN_TABLE(MOVE)
+ TOKEN_TABLE(ALPHA_COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(SUBFRAME)
+ TOKEN_TABLE(SOUND)
+ TOKEN_TABLE(KEYFRAME)
+ TOKEN_TABLE(DECORATION)
+ TOKEN_TABLE(APPLY_EVENT)
+ TOKEN_TABLE(EDITOR_SELECTED)
+ TOKEN_TABLE(EDITOR_EXPANDED)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(KILL_SOUND)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ CBParser parser(Game);
+ RECT rect;
+ int r = 255, g = 255, b = 255;
+ int ar = 255, ag = 255, ab = 255, alpha = 255;
+ int HotspotX = 0, HotspotY = 0;
+ bool custom_trans = false;
+ bool editor_selected = false;
+ bool Is2DOnly = false;
+ bool Is3DOnly = false;
+ bool Decoration = false;
+ bool MirrorX = false;
+ bool MirrorY = false;
+ CBPlatform::SetRectEmpty(&rect);
+ char *surface_file = NULL;
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, &params)) > 0) {
+ switch (cmd) {
+ case TOKEN_DELAY:
+ parser.ScanStr(params, "%d", &m_Delay);
+ break;
+
+ case TOKEN_IMAGE:
+ surface_file = params;
+ break;
+
+ case TOKEN_TRANSPARENT:
+ parser.ScanStr(params, "%d,%d,%d", &r, &g, &b);
+ custom_trans = true;
+ break;
+
+ case TOKEN_RECT:
+ parser.ScanStr(params, "%d,%d,%d,%d", &rect.left, &rect.top, &rect.right, &rect.bottom);
+ break;
+
+ case TOKEN_HOTSPOT:
+ parser.ScanStr(params, "%d,%d", &HotspotX, &HotspotY);
+ break;
+
+ case TOKEN_MOVE:
+ parser.ScanStr(params, "%d,%d", &m_MoveX, &m_MoveY);
+ break;
+
+ case TOKEN_2D_ONLY:
+ parser.ScanStr(params, "%b", &Is2DOnly);
+ break;
+
+ case TOKEN_3D_ONLY:
+ parser.ScanStr(params, "%b", &Is3DOnly);
+ break;
+
+ case TOKEN_MIRROR_X:
+ parser.ScanStr(params, "%b", &MirrorX);
+ break;
+
+ case TOKEN_MIRROR_Y:
+ parser.ScanStr(params, "%b", &MirrorY);
+ break;
+
+ case TOKEN_ALPHA_COLOR:
+ parser.ScanStr(params, "%d,%d,%d", &ar, &ag, &ab);
+ break;
+
+ case TOKEN_ALPHA:
+ parser.ScanStr(params, "%d", &alpha);
+ break;
+
+ case TOKEN_EDITOR_SELECTED:
+ parser.ScanStr(params, "%b", &editor_selected);
+ break;
+
+ case TOKEN_EDITOR_EXPANDED:
+ parser.ScanStr(params, "%b", &m_EditorExpanded);
+ break;
+
+ case TOKEN_KILL_SOUND:
+ parser.ScanStr(params, "%b", &m_KillSound);
+ break;
+
+ case TOKEN_SUBFRAME: {
+ CBSubFrame *subframe = new CBSubFrame(Game);
+ if (!subframe || FAILED(subframe->LoadBuffer((byte *)params, LifeTime, KeepLoaded))) {
+ delete subframe;
+ cmd = PARSERR_GENERIC;
+ } else m_Subframes.Add(subframe);
+ }
+ break;
+
+ case TOKEN_SOUND: {
+ if (m_Sound) {
+ delete m_Sound;
+ m_Sound = NULL;
+ }
+ m_Sound = new CBSound(Game);
+ if (!m_Sound || FAILED(m_Sound->SetSound(params, SOUND_SFX, false))) {
+ if (Game->m_SoundMgr->m_SoundAvailable) Game->LOG(0, "Error loading sound '%s'.", params);
+ delete m_Sound;
+ m_Sound = NULL;
+ }
+ }
+ break;
+
+ case TOKEN_APPLY_EVENT: {
+ char *Event = new char[strlen(params) + 1];
+ strcpy(Event, params);
+ m_ApplyEvent.Add(Event);
+ }
+ break;
+
+ case TOKEN_KEYFRAME:
+ parser.ScanStr(params, "%b", &m_Keyframe);
+ break;
+
+ case TOKEN_DECORATION:
+ parser.ScanStr(params, "%b", &Decoration);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ ParseEditorProperty((byte *)params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in FRAME definition");
+ return E_FAIL;
+ }
+
+ if (cmd == PARSERR_GENERIC) {
+ Game->LOG(0, "Error loading FRAME definition");
+ return E_FAIL;
+ }
+
+
+ CBSubFrame *sub = new CBSubFrame(Game);
+ if (surface_file != NULL) {
+ if (custom_trans) sub->SetSurface(surface_file, false, r, g, b, LifeTime, KeepLoaded);
+ else sub->SetSurface(surface_file, true, 0, 0, 0, LifeTime, KeepLoaded);
+
+ if (!sub->m_Surface) {
+ delete sub;
+ Game->LOG(0, "Error loading SUBFRAME");
+ return E_FAIL;
+ }
+
+ sub->m_Alpha = DRGBA(ar, ag, ab, alpha);
+ if (custom_trans) sub->m_Transparent = DRGBA(r, g, b, 0xFF);
+ }
+
+ if (CBPlatform::IsRectEmpty(&rect)) sub->SetDefaultRect();
+ else sub->m_Rect = rect;
+
+ sub->m_HotspotX = HotspotX;
+ sub->m_HotspotY = HotspotY;
+ sub->m_2DOnly = Is2DOnly;
+ sub->m_3DOnly = Is3DOnly;
+ sub->m_Decoration = Decoration;
+ sub->m_MirrorX = MirrorX;
+ sub->m_MirrorY = MirrorY;
+
+
+ sub->m_EditorSelected = editor_selected;
+ m_Subframes.InsertAt(0, sub);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBFrame::GetBoundingRect(LPRECT Rect, int X, int Y, float ScaleX, float ScaleY) {
+ if (!Rect) return false;
+ CBPlatform::SetRectEmpty(Rect);
+
+ RECT SubRect;
+
+ for (int i = 0; i < m_Subframes.GetSize(); i++) {
+ m_Subframes[i]->GetBoundingRect(&SubRect, X, Y, ScaleX, ScaleY);
+ CBPlatform::UnionRect(Rect, Rect, &SubRect);
+ }
+ return true;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::SaveAsText(CBDynBuffer *Buffer, int Indent) {
+ Buffer->PutTextIndent(Indent, "FRAME {\n");
+ Buffer->PutTextIndent(Indent + 2, "DELAY = %d\n", m_Delay);
+
+ if (m_MoveX != 0 || m_MoveY != 0)
+ Buffer->PutTextIndent(Indent + 2, "MOVE {%d, %d}\n", m_MoveX, m_MoveY);
+
+ if (m_Sound && m_Sound->m_SoundFilename)
+ Buffer->PutTextIndent(Indent + 2, "SOUND=\"%s\"\n", m_Sound->m_SoundFilename);
+
+ Buffer->PutTextIndent(Indent + 2, "KEYFRAME=%s\n", m_Keyframe ? "TRUE" : "FALSE");
+
+ if (m_KillSound)
+ Buffer->PutTextIndent(Indent + 2, "KILL_SOUND=%s\n", m_KillSound ? "TRUE" : "FALSE");
+
+ if (m_EditorExpanded)
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_EXPANDED=%s\n", m_EditorExpanded ? "TRUE" : "FALSE");
+
+ if (m_Subframes.GetSize() > 0) m_Subframes[0]->SaveAsText(Buffer, Indent, false);
+
+ int i;
+ for (i = 1; i < m_Subframes.GetSize(); i++) {
+ m_Subframes[i]->SaveAsText(Buffer, Indent + 2);
+ }
+
+ for (i = 0; i < m_ApplyEvent.GetSize(); i++) {
+ Buffer->PutTextIndent(Indent + 2, "APPLY_EVENT=\"%s\"\n", m_ApplyEvent[i]);
+ }
+
+ CBBase::SaveAsText(Buffer, Indent + 2);
+
+
+ Buffer->PutTextIndent(Indent, "}\n\n");
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::Persist(CBPersistMgr *PersistMgr) {
+ CBScriptable::Persist(PersistMgr);
+
+ m_ApplyEvent.Persist(PersistMgr);
+ PersistMgr->Transfer(TMEMBER(m_Delay));
+ PersistMgr->Transfer(TMEMBER(m_EditorExpanded));
+ PersistMgr->Transfer(TMEMBER(m_Keyframe));
+ PersistMgr->Transfer(TMEMBER(m_KillSound));
+ PersistMgr->Transfer(TMEMBER(m_MoveX));
+ PersistMgr->Transfer(TMEMBER(m_MoveY));
+ PersistMgr->Transfer(TMEMBER(m_Sound));
+ m_Subframes.Persist(PersistMgr);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSound
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "GetSound") == 0) {
+ Stack->CorrectParams(0);
+
+ if (m_Sound && m_Sound->m_SoundFilename) Stack->PushString(m_Sound->m_SoundFilename);
+ else Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetSound
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "SetSound") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+ delete m_Sound;
+ m_Sound = NULL;
+
+ if (!Val->IsNULL()) {
+ m_Sound = new CBSound(Game);
+ if (!m_Sound || FAILED(m_Sound->SetSound(Val->GetString(), SOUND_SFX, false))) {
+ Stack->PushBool(false);
+ delete m_Sound;
+ m_Sound = NULL;
+ } else Stack->PushBool(true);
+ } else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSubframe
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "GetSubframe") == 0) {
+ Stack->CorrectParams(1);
+ int Index = Stack->Pop()->GetInt(-1);
+ if (Index < 0 || Index >= m_Subframes.GetSize()) {
+ Script->RuntimeError("Frame.GetSubframe: Subframe index %d is out of range.", Index);
+ Stack->PushNULL();
+ } else Stack->PushNative(m_Subframes[Index], true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteSubframe
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DeleteSubframe") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+ if (Val->IsInt()) {
+ int Index = Val->GetInt(-1);
+ if (Index < 0 || Index >= m_Subframes.GetSize()) {
+ Script->RuntimeError("Frame.DeleteSubframe: Subframe index %d is out of range.", Index);
+ }
+ } else {
+ CBSubFrame *Sub = (CBSubFrame *)Val->GetNative();
+ for (int i = 0; i < m_Subframes.GetSize(); i++) {
+ if (m_Subframes[i] == Sub) {
+ delete m_Subframes[i];
+ m_Subframes.RemoveAt(i);
+ break;
+ }
+ }
+ }
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddSubframe
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AddSubframe") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+ char *Filename = NULL;
+ if (!Val->IsNULL()) Filename = Val->GetString();
+
+ CBSubFrame *Sub = new CBSubFrame(Game);
+ if (Filename != NULL) {
+ Sub->SetSurface(Filename);
+ Sub->SetDefaultRect();
+ }
+ m_Subframes.Add(Sub);
+
+ Stack->PushNative(Sub, true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InsertSubframe
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "InsertSubframe") == 0) {
+ Stack->CorrectParams(2);
+ int Index = Stack->Pop()->GetInt();
+ if (Index < 0) Index = 0;
+
+ CScValue *Val = Stack->Pop();
+ char *Filename = NULL;
+ if (!Val->IsNULL()) Filename = Val->GetString();
+
+ CBSubFrame *Sub = new CBSubFrame(Game);
+ if (Filename != NULL) {
+ Sub->SetSurface(Filename);
+ }
+
+ if (Index >= m_Subframes.GetSize()) m_Subframes.Add(Sub);
+ else m_Subframes.InsertAt(Index, Sub);
+
+ Stack->PushNative(Sub, true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetEvent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetSubframe") == 0) {
+ Stack->CorrectParams(1);
+ int Index = Stack->Pop()->GetInt(-1);
+ if (Index < 0 || Index >= m_ApplyEvent.GetSize()) {
+ Script->RuntimeError("Frame.GetEvent: Event index %d is out of range.", Index);
+ Stack->PushNULL();
+ } else Stack->PushString(m_ApplyEvent[Index]);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddEvent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AddEvent") == 0) {
+ Stack->CorrectParams(1);
+ char *Event = Stack->Pop()->GetString();
+ for (int i = 0; i < m_ApplyEvent.GetSize(); i++) {
+ if (scumm_stricmp(m_ApplyEvent[i], Event) == 0) {
+ Stack->PushNULL();
+ return S_OK;
+ }
+ }
+ m_ApplyEvent.Add(Event);
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteEvent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DeleteEvent") == 0) {
+ Stack->CorrectParams(1);
+ char *Event = Stack->Pop()->GetString();
+ for (int i = 0; i < m_ApplyEvent.GetSize(); i++) {
+ if (scumm_stricmp(m_ApplyEvent[i], Event) == 0) {
+ delete [] m_ApplyEvent[i];
+ m_ApplyEvent.RemoveAt(i);
+ break;
+ }
+ }
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ else {
+ if (m_Subframes.GetSize() == 1) return m_Subframes[0]->ScCallMethod(Script, Stack, ThisStack, Name);
+ else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBFrame::ScGetProperty(char *Name) {
+ if (!m_ScValue) m_ScValue = new CScValue(Game);
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("frame");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Delay
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Delay") == 0) {
+ m_ScValue->SetInt(m_Delay);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Keyframe
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Keyframe") == 0) {
+ m_ScValue->SetBool(m_Keyframe);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // KillSounds
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "KillSounds") == 0) {
+ m_ScValue->SetBool(m_KillSound);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MoveX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MoveX") == 0) {
+ m_ScValue->SetInt(m_MoveX);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MoveY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MoveY") == 0) {
+ m_ScValue->SetInt(m_MoveY);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumSubframes (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "NumSubframes") == 0) {
+ m_ScValue->SetInt(m_Subframes.GetSize());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumEvents (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "NumEvents") == 0) {
+ m_ScValue->SetInt(m_ApplyEvent.GetSize());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ else {
+ if (m_Subframes.GetSize() == 1) return m_Subframes[0]->ScGetProperty(Name);
+ else return CBScriptable::ScGetProperty(Name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBFrame::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Delay
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Delay") == 0) {
+ m_Delay = std::max(0, Value->GetInt());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Keyframe
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Keyframe") == 0) {
+ m_Keyframe = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // KillSounds
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "KillSounds") == 0) {
+ m_KillSound = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MoveX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MoveX") == 0) {
+ m_MoveX = Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MoveY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MoveY") == 0) {
+ m_MoveY = Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ else {
+ if (m_Subframes.GetSize() == 1) return m_Subframes[0]->ScSetProperty(Name, Value);
+ else return CBScriptable::ScSetProperty(Name, Value);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBFrame::ScToString() {
+ return "[frame]";
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BFrame.h b/engines/wintermute/BFrame.h
new file mode 100644
index 0000000000..9538305dd6
--- /dev/null
+++ b/engines/wintermute/BFrame.h
@@ -0,0 +1,73 @@
+/* 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_BFRAME_H
+#define WINTERMUTE_BFRAME_H
+
+#include "BScriptable.h"
+#include "coll_templ.h"
+
+namespace WinterMute {
+class CBSound;
+class CBSubFrame;
+class CBObject;
+class CScScript;
+class CScStack;
+class CBFrame: public CBScriptable {
+public:
+ bool m_KillSound;
+ bool m_Keyframe;
+ HRESULT OneTimeDisplay(CBObject *Owner, bool Muted = false);
+ DECLARE_PERSISTENT(CBFrame, CBScriptable)
+ CBSound *m_Sound;
+ bool m_EditorExpanded;
+ bool GetBoundingRect(LPRECT Rect, int X, int Y, float ScaleX = 100, float ScaleY = 100);
+ HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent);
+ int m_MoveY;
+ int m_MoveX;
+ uint32 m_Delay;
+ CBArray<CBSubFrame *, CBSubFrame *> m_Subframes;
+ HRESULT Draw(int X, int Y, CBObject *Register = NULL, float ZoomX = 100, float ZoomY = 100, bool Precise = true, uint32 Alpha = 0xFFFFFFFF, bool AllFrames = false, float Rotate = 0.0f, TSpriteBlendMode BlendMode = BLEND_NORMAL);
+ HRESULT LoadBuffer(byte *Buffer, int LifeTime, bool KeepLoaded);
+
+ CBFrame(CBGame *inGame);
+ virtual ~CBFrame();
+
+ CBArray<char *, char *> m_ApplyEvent;
+
+ // 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/BGame.cpp b/engines/wintermute/BGame.cpp
new file mode 100644
index 0000000000..2c58641c33
--- /dev/null
+++ b/engines/wintermute/BGame.cpp
@@ -0,0 +1,4462 @@
+/* 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 "BGame.h"
+#include "BFile.h"
+#include "BRegistry.h"
+#include "BRenderSDL.h"
+#include "BSurfaceSDL.h"
+#include "BQuickMsg.h"
+#include "scriptables/SXString.h"
+#include "scriptables/SXDate.h"
+#include "scriptables/SXArray.h"
+#include "SxObject.h"
+#include "scriptables/SXMemBuffer.h"
+#include "SXFile.h"
+#include "SXMath.h"
+#include "SXStore.h"
+#include "PathUtil.h"
+#include <time.h>
+#include "crc.h"
+#include "StringUtil.h"
+#include "BParser.h"
+#include "BImage.h"
+#include "BTransitionMgr.h"
+#include "BKeyboardState.h"
+#include "UIWindow.h"
+#include "ScValue.h"
+#include "BSoundMgr.h"
+#include "BSound.h"
+#include "BSubFrame.h"
+#include "BViewport.h"
+#include "BFontStorage.h"
+#include "BFontTT.h"
+#include "ScEngine.h"
+#include "BStringTable.h"
+#include "ScScript.h"
+#include "BRegion.h"
+#include "BSprite.h"
+#include "BFileManager.h"
+#include "ScStack.h"
+#include "common/textconsole.h"
+
+#ifdef __IPHONEOS__
+# include "ios_utils.h"
+#endif
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+IMPLEMENT_PERSISTENT(CBGame, true)
+
+
+//////////////////////////////////////////////////////////////////////
+CBGame::CBGame(): CBObject(this) {
+ m_ShuttingDown = false;
+
+ m_State = GAME_RUNNING;
+ m_OrigState = GAME_RUNNING;
+ m_FreezeLevel = 0;
+
+ m_Interactive = true;
+ m_OrigInteractive = false;
+
+ m_SurfaceStorage = NULL;
+ m_FontStorage = NULL;
+ m_Renderer = NULL;
+ m_SoundMgr = NULL;
+ m_FileManager = NULL;
+ m_TransMgr = NULL;
+ m_DebugMgr = NULL;
+ m_ScEngine = NULL;
+ m_KeyboardState = NULL;
+
+ m_MathClass = NULL;
+
+ m_DEBUG_LogFile = NULL;
+ m_DEBUG_DebugMode = false;
+ m_DEBUG_AbsolutePathWarning = true;
+ m_DEBUG_ShowFPS = false;
+
+ m_SystemFont = NULL;
+ m_VideoFont = NULL;
+
+ m_MainObject = NULL;
+ m_ActiveObject = NULL;
+
+ m_Fader = NULL;
+
+ m_OffsetX = m_OffsetY = 0;
+ m_OffsetPercentX = m_OffsetPercentY = 0.0f;
+
+ m_Subtitles = true;
+ m_VideoSubtitles = true;
+
+ m_Timer = 0;
+ m_TimerDelta = 0;
+ m_TimerLast = 0;
+
+ m_LiveTimer = 0;
+ m_LiveTimerDelta = 0;
+ m_LiveTimerLast = 0;
+
+ m_Sequence = 0;
+
+ m_MousePos.x = m_MousePos.y = 0;
+ m_MouseLeftDown = m_MouseRightDown = m_MouseMidlleDown = false;
+ m_CapturedObject = NULL;
+
+ // FPS counters
+ m_LastTime = m_FpsTime = m_DeltaTime = m_FramesRendered = m_Fps = 0;
+
+ m_CursorNoninteractive = NULL;
+
+ m_UseD3D = false;
+
+ srand((unsigned)time(NULL));
+
+ m_Registry = new CBRegistry(this);
+ m_StringTable = new CBStringTable(this);
+
+ for (int i = 0; i < NUM_MUSIC_CHANNELS; i++) {
+ m_Music[i] = NULL;
+ m_MusicStartTime[i] = 0;
+ }
+
+ m_SettingsResWidth = 800;
+ m_SettingsResHeight = 600;
+ m_SettingsRequireAcceleration = false;
+ m_SettingsRequireSound = false;
+ m_SettingsTLMode = 0;
+ m_SettingsAllowWindowed = true;
+ m_SettingsGameFile = NULL;
+ m_SettingsAllowAdvanced = false;
+ m_SettingsAllowAccessTab = true;
+ m_SettingsAllowAboutTab = true;
+ m_SettingsAllowDesktopRes = false;
+
+ m_EditorForceScripts = false;
+ m_EditorAlwaysRegister = false;
+
+ m_FocusedWindow = NULL;
+
+ m_LoadInProgress = false;
+
+ m_Quitting = false;
+ m_Loading = false;
+ m_ScheduledLoadSlot = -1;
+
+ m_PersonalizedSave = false;
+ m_CompressedSavegames = true;
+
+ m_EditorMode = false;
+ m_DoNotExpandStrings = false;
+
+ m_EngineLogCallback = NULL;
+ m_EngineLogCallbackData = NULL;
+
+ m_SmartCache = false;
+ m_SurfaceGCCycleTime = 10000;
+
+ m_ReportTextureFormat = false;
+
+ m_ViewportSP = -1;
+
+ m_SubtitlesSpeed = 70;
+
+ m_ResourceModule = NULL;
+
+ m_ForceNonStreamedSounds = false;
+
+ m_ThumbnailWidth = m_ThumbnailHeight = 0;
+
+ m_IndicatorDisplay = false;
+ m_IndicatorColor = DRGBA(255, 0, 0, 128);
+ m_IndicatorProgress = 0;
+ m_IndicatorX = -1;
+ m_IndicatorY = -1;
+ m_IndicatorWidth = -1;
+ m_IndicatorHeight = 8;
+ m_RichSavedGames = false;
+ m_SavedGameExt = NULL;
+ CBUtils::SetString(&m_SavedGameExt, "dsv");
+
+ m_MusicCrossfadeRunning = false;
+ m_MusicCrossfadeStartTime = 0;
+ m_MusicCrossfadeLength = 0;
+ m_MusicCrossfadeChannel1 = -1;
+ m_MusicCrossfadeChannel2 = -1;
+ m_MusicCrossfadeSwap = false;
+
+ m_LoadImageName = NULL;
+ m_SaveImageName = NULL;
+ m_SaveLoadImage = NULL;
+
+ m_SaveImageX = m_SaveImageY = 0;
+ m_LoadImageX = m_LoadImageY = 0;
+
+ m_LocalSaveDir = NULL;
+ CBUtils::SetString(&m_LocalSaveDir, "saves");
+ m_SaveDirChecked = false;
+
+ m_LoadingIcon = NULL;
+ m_LoadingIconX = m_LoadingIconY = 0;
+ m_LoadingIconPersistent = false;
+
+ m_TextEncoding = TEXT_ANSI;
+ m_TextRTL = false;
+
+ m_SoundBufferSizeSec = 3;
+ m_SuspendedRendering = false;
+
+ m_LastCursor = NULL;
+
+
+ CBPlatform::SetRectEmpty(&m_MouseLockRect);
+
+ m_SuppressScriptErrors = false;
+ m_LastMiniUpdate = 0;
+ m_MiniUpdateEnabled = false;
+
+ m_CachedThumbnail = NULL;
+
+ m_AutorunDisabled = false;
+
+ // compatibility bits
+ m_CompatKillMethodThreads = false;
+
+ m_UsedMem = 0;
+
+
+ m_AutoSaveOnExit = true;
+ m_AutoSaveSlot = 999;
+ m_CursorHidden = false;
+
+#ifdef __IPHONEOS__
+ m_TouchInterface = true;
+ m_ConstrainedMemory = true; // TODO differentiate old and new iOS devices
+#else
+ m_TouchInterface = false;
+ m_ConstrainedMemory = false;
+#endif
+
+ m_Store = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBGame::~CBGame() {
+ m_ShuttingDown = true;
+
+ LOG(0, "");
+ LOG(0, "Shutting down...");
+
+ GetDebugMgr()->OnGameShutdown();
+
+ m_Registry->WriteBool("System", "LastRun", true);
+
+ Cleanup();
+
+ delete[] m_LocalSaveDir;
+ delete[] m_SettingsGameFile;
+ delete[] m_SavedGameExt;
+
+ delete m_CachedThumbnail;
+
+ delete m_SaveLoadImage;
+ delete m_MathClass;
+
+ delete m_TransMgr;
+ delete m_ScEngine;
+ delete m_FontStorage;
+ delete m_SurfaceStorage;
+ delete m_SoundMgr;
+ delete m_DebugMgr;
+ //SAFE_DELETE(m_KeyboardState);
+
+ delete m_Renderer;
+ delete m_FileManager;
+ delete m_Registry;
+ delete m_StringTable;
+
+ m_LocalSaveDir = NULL;
+ m_SettingsGameFile = NULL;
+ m_SavedGameExt = NULL;
+
+ m_CachedThumbnail = NULL;
+
+ m_SaveLoadImage = NULL;
+ m_MathClass = NULL;
+
+ m_TransMgr = NULL;
+ m_ScEngine = NULL;
+ m_FontStorage = NULL;
+ m_SurfaceStorage = NULL;
+ m_SoundMgr = NULL;
+ m_DebugMgr = NULL;
+
+ m_Renderer = NULL;
+ m_FileManager = NULL;
+ m_Registry = NULL;
+ m_StringTable = NULL;
+
+ DEBUG_DebugDisable();
+ CBPlatform::OutputDebugString("--- shutting down normally ---\n");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Cleanup() {
+ int i;
+
+ delete m_LoadingIcon;
+ m_LoadingIcon = NULL;
+
+ m_EngineLogCallback = NULL;
+ m_EngineLogCallbackData = NULL;
+
+ for (i = 0; i < NUM_MUSIC_CHANNELS; i++) {
+ delete m_Music[i];
+ m_Music[i] = NULL;
+ m_MusicStartTime[i] = 0;
+ }
+
+ UnregisterObject(m_Store);
+ m_Store = NULL;
+
+ UnregisterObject(m_Fader);
+ m_Fader = NULL;
+
+ for (i = 0; i < m_RegObjects.GetSize(); i++) {
+ delete m_RegObjects[i];
+ m_RegObjects[i] = NULL;
+ }
+ m_RegObjects.RemoveAll();
+
+ m_Windows.RemoveAll(); // refs only
+ m_FocusedWindow = NULL; // ref only
+
+ delete[] m_SaveImageName;
+ delete[] m_LoadImageName;
+ m_SaveImageName = NULL;
+ m_LoadImageName = NULL;
+
+ delete m_CursorNoninteractive;
+ delete m_Cursor;
+ delete m_ActiveCursor;
+ m_CursorNoninteractive = NULL;
+ m_Cursor = NULL;
+ m_ActiveCursor = NULL;
+
+ delete m_ScValue;
+ delete m_SFX;
+ m_ScValue = NULL;
+ m_SFX = NULL;
+
+ for (i = 0; i < m_Scripts.GetSize(); i++) {
+ m_Scripts[i]->m_Owner = NULL;
+ m_Scripts[i]->Finish();
+ }
+ m_Scripts.RemoveAll();
+
+ m_FontStorage->RemoveFont(m_SystemFont);
+ m_SystemFont = NULL;
+
+ m_FontStorage->RemoveFont(m_VideoFont);
+ m_VideoFont = NULL;
+
+ for (i = 0; i < m_QuickMessages.GetSize(); i++) delete m_QuickMessages[i];
+ m_QuickMessages.RemoveAll();
+
+ m_ViewportStack.RemoveAll();
+ m_ViewportSP = -1;
+
+ delete[] m_Name;
+ delete[] m_Filename;
+ m_Name = NULL;
+ m_Filename = NULL;
+ for (int i = 0; i < 7; i++) {
+ delete[] m_Caption[i];
+ m_Caption[i] = NULL;
+ }
+
+ m_LastCursor = NULL;
+
+ delete m_KeyboardState;
+ m_KeyboardState = NULL;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Initialize1() {
+ m_SurfaceStorage = new CBSurfaceStorage(this);
+ if (m_SurfaceStorage == NULL) goto init_fail;
+
+ m_FontStorage = new CBFontStorage(this);
+ if (m_FontStorage == NULL) goto init_fail;
+
+ m_FileManager = new CBFileManager(this);
+ if (m_FileManager == NULL) goto init_fail;
+
+ m_SoundMgr = new CBSoundMgr(this);
+ if (m_SoundMgr == NULL) goto init_fail;
+
+ m_DebugMgr = new CBDebugger(this);
+ if (m_DebugMgr == NULL) goto init_fail;
+
+ m_MathClass = new CSXMath(this);
+ if (m_MathClass == NULL) goto init_fail;
+
+ m_ScEngine = new CScEngine(this);
+ if (m_ScEngine == NULL) goto init_fail;
+
+ m_TransMgr = new CBTransitionMgr(this);
+ if (m_TransMgr == NULL) goto init_fail;
+
+ m_KeyboardState = new CBKeyboardState(this);
+ if (m_KeyboardState == NULL) goto init_fail;
+
+ m_Fader = new CBFader(this);
+ if (m_Fader == NULL) goto init_fail;
+ RegisterObject(m_Fader);
+
+ m_Store = new CSXStore(this);
+ if (m_Store == NULL) goto init_fail;
+ RegisterObject(m_Store);
+
+ return S_OK;
+
+init_fail:
+ if (m_MathClass) delete m_MathClass;
+ if (m_Store) delete m_Store;
+ if (m_KeyboardState) delete m_KeyboardState;
+ if (m_TransMgr) delete m_TransMgr;
+ if (m_DebugMgr) delete m_DebugMgr;
+ if (m_SurfaceStorage) delete m_SurfaceStorage;
+ if (m_FontStorage) delete m_FontStorage;
+ if (m_SoundMgr) delete m_SoundMgr;
+ if (m_FileManager) delete m_FileManager;
+ if (m_ScEngine) delete m_ScEngine;
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Initialize2() { // we know whether we are going to be accelerated
+ m_Renderer = new CBRenderSDL(this);
+ if (m_Renderer == NULL) goto init_fail;
+
+ return S_OK;
+
+init_fail:
+ if (m_Renderer) delete m_Renderer;
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Initialize3() { // renderer is initialized
+ m_PosX = m_Renderer->m_Width / 2;
+ m_PosY = m_Renderer->m_Height / 2;
+
+ if (m_IndicatorY == -1) m_IndicatorY = m_Renderer->m_Height - m_IndicatorHeight;
+ if (m_IndicatorX == -1) m_IndicatorX = 0;
+ if (m_IndicatorWidth == -1) m_IndicatorWidth = m_Renderer->m_Width;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBGame::DEBUG_DebugEnable(const char *Filename) {
+ m_DEBUG_DebugMode = true;
+
+#ifndef __IPHONEOS__
+ if (Filename)m_DEBUG_LogFile = fopen(Filename, "a+");
+ else m_DEBUG_LogFile = fopen("./zz_debug.log", "a+");
+
+ if (!m_DEBUG_LogFile) {
+ AnsiString safeLogFileName = PathUtil::GetSafeLogFileName();
+ m_DEBUG_LogFile = fopen(safeLogFileName.c_str(), "a+");
+ }
+
+ if (m_DEBUG_LogFile != NULL) fprintf(m_DEBUG_LogFile, "\n");
+#endif
+
+ time_t timeNow;
+ time(&timeNow);
+ struct tm *tm = localtime(&timeNow);
+
+#ifdef _DEBUG
+ LOG(0, "********** DEBUG LOG OPENED %02d-%02d-%04d (Debug Build) *******************", tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
+#else
+ LOG(0, "********** DEBUG LOG OPENED %02d-%02d-%04d (Release Build) *****************", tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
+#endif
+
+ LOG(0, "%s ver %d.%d.%d%s, Compiled on " __DATE__ ", " __TIME__, DCGF_NAME, DCGF_VER_MAJOR, DCGF_VER_MINOR, DCGF_VER_BUILD, DCGF_VER_SUFFIX);
+ //LOG(0, "Extensions: %s ver %d.%02d", EXT_NAME, EXT_VER_MAJOR, EXT_VER_MINOR);
+
+ AnsiString platform = CBPlatform::GetPlatformName();
+ LOG(0, "Platform: %s", platform.c_str());
+ LOG(0, "");
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBGame::DEBUG_DebugDisable() {
+ if (m_DEBUG_LogFile != NULL) {
+ LOG(0, "********** DEBUG LOG CLOSED ********************************************");
+ fclose(m_DEBUG_LogFile);
+ m_DEBUG_LogFile = NULL;
+ }
+ m_DEBUG_DebugMode = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBGame::LOG(HRESULT res, LPCSTR fmt, ...) {
+#ifndef __IPHONEOS__
+ if (!m_DEBUG_DebugMode) return;
+#endif
+ time_t timeNow;
+ time(&timeNow);
+ struct tm *tm = localtime(&timeNow);
+
+ char buff[512];
+ va_list va;
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+#ifdef __IPHONEOS__
+ printf("%02d:%02d:%02d: %s\n", tm->tm_hour, tm->tm_min, tm->tm_sec, buff);
+ fflush(stdout);
+#else
+ if (m_DEBUG_LogFile == NULL) return;
+
+ // redirect to an engine's own callback
+ if (m_EngineLogCallback) {
+ m_EngineLogCallback(buff, res, m_EngineLogCallbackData);
+ }
+ if (m_DebugMgr) m_DebugMgr->OnLog(res, buff);
+
+ warning("%02d:%02d: %s\n", tm->tm_hour, tm->tm_min, buff);
+ fprintf(m_DEBUG_LogFile, "%02d:%02d: %s\n", tm->tm_hour, tm->tm_min, buff);
+ fflush(m_DEBUG_LogFile);
+#endif
+
+ //QuickMessage(buff);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::SetEngineLogCallback(ENGINE_LOG_CALLBACK Callback, void *Data) {
+ m_EngineLogCallback = Callback;
+ m_EngineLogCallbackData = Data;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBGame::InitLoop() {
+ m_ViewportSP = -1;
+
+ m_CurrentTime = CBPlatform::GetTime();
+
+ GetDebugMgr()->OnGameTick();
+ m_Renderer->InitLoop();
+ m_SoundMgr->InitLoop();
+ UpdateMusicCrossfade();
+
+ m_SurfaceStorage->InitLoop();
+ m_FontStorage->InitLoop();
+
+
+ //m_ActiveObject = NULL;
+
+ // count FPS
+ m_DeltaTime = m_CurrentTime - m_LastTime;
+ m_LastTime = m_CurrentTime;
+ m_FpsTime += m_DeltaTime;
+
+ m_LiveTimerDelta = m_LiveTimer - m_LiveTimerLast;
+ m_LiveTimerLast = m_LiveTimer;
+ m_LiveTimer += MIN(1000, m_DeltaTime);
+
+ if (m_State != GAME_FROZEN) {
+ m_TimerDelta = m_Timer - m_TimerLast;
+ m_TimerLast = m_Timer;
+ m_Timer += MIN(1000, m_DeltaTime);
+ } else m_TimerDelta = 0;
+
+ m_FramesRendered++;
+ if (m_FpsTime > 1000) {
+ m_Fps = m_FramesRendered;
+ m_FramesRendered = 0;
+ m_FpsTime = 0;
+ }
+ //Game->LOG(0, "%d", m_Fps);
+
+ GetMousePos(&m_MousePos);
+
+ m_FocusedWindow = NULL;
+ for (int i = m_Windows.GetSize() - 1; i >= 0; i--) {
+ if (m_Windows[i]->m_Visible) {
+ m_FocusedWindow = m_Windows[i];
+ break;
+ }
+ }
+
+ UpdateSounds();
+
+ if (m_Fader) m_Fader->Update();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBGame::InitInput(HINSTANCE hInst, HWND hWnd) {
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBGame::GetSequence() {
+ return ++m_Sequence;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::SetOffset(int OffsetX, int OffsetY) {
+ m_OffsetX = OffsetX;
+ m_OffsetY = OffsetY;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::GetOffset(int *OffsetX, int *OffsetY) {
+ if (OffsetX != NULL) *OffsetX = m_OffsetX;
+ if (OffsetY != NULL) *OffsetY = m_OffsetY;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::LoadFile(const char *Filename) {
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer == NULL) {
+ Game->LOG(0, "CBGame::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret;
+
+ m_Filename = new char [strlen(Filename) + 1];
+ strcpy(m_Filename, Filename);
+
+ if (FAILED(ret = LoadBuffer(Buffer, true))) Game->LOG(0, "Error parsing GAME file '%s'", Filename);
+
+
+ delete [] Buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(GAME)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(SYSTEM_FONT)
+TOKEN_DEF(VIDEO_FONT)
+TOKEN_DEF(EVENTS)
+TOKEN_DEF(CURSOR)
+TOKEN_DEF(ACTIVE_CURSOR)
+TOKEN_DEF(NONINTERACTIVE_CURSOR)
+TOKEN_DEF(STRING_TABLE)
+TOKEN_DEF(RESOLUTION)
+TOKEN_DEF(SETTINGS)
+TOKEN_DEF(REQUIRE_3D_ACCELERATION)
+TOKEN_DEF(REQUIRE_SOUND)
+TOKEN_DEF(HWTL_MODE)
+TOKEN_DEF(ALLOW_WINDOWED_MODE)
+TOKEN_DEF(ALLOW_ACCESSIBILITY_TAB)
+TOKEN_DEF(ALLOW_ABOUT_TAB)
+TOKEN_DEF(ALLOW_ADVANCED)
+TOKEN_DEF(ALLOW_DESKTOP_RES)
+TOKEN_DEF(REGISTRY_PATH)
+TOKEN_DEF(PERSONAL_SAVEGAMES)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(SUBTITLES_SPEED)
+TOKEN_DEF(SUBTITLES)
+TOKEN_DEF(VIDEO_SUBTITLES)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF(THUMBNAIL_WIDTH)
+TOKEN_DEF(THUMBNAIL_HEIGHT)
+TOKEN_DEF(INDICATOR_X)
+TOKEN_DEF(INDICATOR_Y)
+TOKEN_DEF(INDICATOR_WIDTH)
+TOKEN_DEF(INDICATOR_HEIGHT)
+TOKEN_DEF(INDICATOR_COLOR)
+TOKEN_DEF(SAVE_IMAGE_X)
+TOKEN_DEF(SAVE_IMAGE_Y)
+TOKEN_DEF(SAVE_IMAGE)
+TOKEN_DEF(LOAD_IMAGE_X)
+TOKEN_DEF(LOAD_IMAGE_Y)
+TOKEN_DEF(LOAD_IMAGE)
+TOKEN_DEF(LOCAL_SAVE_DIR)
+TOKEN_DEF(RICH_SAVED_GAMES)
+TOKEN_DEF(SAVED_GAME_EXT)
+TOKEN_DEF(GUID)
+TOKEN_DEF(COMPAT_KILL_METHOD_THREADS)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::LoadBuffer(byte *Buffer, bool Complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(GAME)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(SYSTEM_FONT)
+ TOKEN_TABLE(VIDEO_FONT)
+ TOKEN_TABLE(EVENTS)
+ TOKEN_TABLE(CURSOR)
+ TOKEN_TABLE(ACTIVE_CURSOR)
+ TOKEN_TABLE(NONINTERACTIVE_CURSOR)
+ TOKEN_TABLE(PERSONAL_SAVEGAMES)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(SUBTITLES_SPEED)
+ TOKEN_TABLE(SUBTITLES)
+ TOKEN_TABLE(VIDEO_SUBTITLES)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE(THUMBNAIL_WIDTH)
+ TOKEN_TABLE(THUMBNAIL_HEIGHT)
+ TOKEN_TABLE(INDICATOR_X)
+ TOKEN_TABLE(INDICATOR_Y)
+ TOKEN_TABLE(INDICATOR_WIDTH)
+ TOKEN_TABLE(INDICATOR_HEIGHT)
+ TOKEN_TABLE(INDICATOR_COLOR)
+ TOKEN_TABLE(SAVE_IMAGE_X)
+ TOKEN_TABLE(SAVE_IMAGE_Y)
+ TOKEN_TABLE(SAVE_IMAGE)
+ TOKEN_TABLE(LOAD_IMAGE_X)
+ TOKEN_TABLE(LOAD_IMAGE_Y)
+ TOKEN_TABLE(LOAD_IMAGE)
+ TOKEN_TABLE(LOCAL_SAVE_DIR)
+ TOKEN_TABLE(COMPAT_KILL_METHOD_THREADS)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (Complete) {
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_GAME) {
+ Game->LOG(0, "'GAME' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = params;
+ }
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (FAILED(LoadFile((char *)params))) cmd = PARSERR_GENERIC;
+ break;
+
+ case TOKEN_NAME:
+ SetName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ SetCaption((char *)params);
+ break;
+
+ case TOKEN_SYSTEM_FONT:
+ if (m_SystemFont) m_FontStorage->RemoveFont(m_SystemFont);
+ m_SystemFont = NULL;
+
+ m_SystemFont = Game->m_FontStorage->AddFont((char *)params);
+ break;
+
+ case TOKEN_VIDEO_FONT:
+ if (m_VideoFont) m_FontStorage->RemoveFont(m_VideoFont);
+ m_VideoFont = NULL;
+
+ m_VideoFont = Game->m_FontStorage->AddFont((char *)params);
+ break;
+
+
+ case TOKEN_CURSOR:
+ delete m_Cursor;
+ m_Cursor = new CBSprite(Game);
+ if (!m_Cursor || FAILED(m_Cursor->LoadFile((char *)params))) {
+ delete m_Cursor;
+ m_Cursor = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_ACTIVE_CURSOR:
+ delete m_ActiveCursor;
+ m_ActiveCursor = NULL;
+ m_ActiveCursor = new CBSprite(Game);
+ if (!m_ActiveCursor || FAILED(m_ActiveCursor->LoadFile((char *)params))) {
+ delete m_ActiveCursor;
+ m_ActiveCursor = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_NONINTERACTIVE_CURSOR:
+ delete m_CursorNoninteractive;
+ m_CursorNoninteractive = new CBSprite(Game);
+ if (!m_CursorNoninteractive || FAILED(m_CursorNoninteractive->LoadFile((char *)params))) {
+ delete m_CursorNoninteractive;
+ m_CursorNoninteractive = NULL;
+ cmd = PARSERR_GENERIC;
+ }
+ break;
+
+ case TOKEN_SCRIPT:
+ AddScript((char *)params);
+ break;
+
+ case TOKEN_PERSONAL_SAVEGAMES:
+ parser.ScanStr((char *)params, "%b", &m_PersonalizedSave);
+ break;
+
+ case TOKEN_SUBTITLES:
+ parser.ScanStr((char *)params, "%b", &m_Subtitles);
+ break;
+
+ case TOKEN_SUBTITLES_SPEED:
+ parser.ScanStr((char *)params, "%d", &m_SubtitlesSpeed);
+ break;
+
+ case TOKEN_VIDEO_SUBTITLES:
+ parser.ScanStr((char *)params, "%b", &m_VideoSubtitles);
+ break;
+
+ case TOKEN_PROPERTY:
+ ParseProperty(params, false);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ ParseEditorProperty(params, false);
+ break;
+
+ case TOKEN_THUMBNAIL_WIDTH:
+ parser.ScanStr((char *)params, "%d", &m_ThumbnailWidth);
+ break;
+
+ case TOKEN_THUMBNAIL_HEIGHT:
+ parser.ScanStr((char *)params, "%d", &m_ThumbnailHeight);
+ break;
+
+ case TOKEN_INDICATOR_X:
+ parser.ScanStr((char *)params, "%d", &m_IndicatorX);
+ break;
+
+ case TOKEN_INDICATOR_Y:
+ parser.ScanStr((char *)params, "%d", &m_IndicatorY);
+ break;
+
+ case TOKEN_INDICATOR_COLOR: {
+ int r, g, b, a;
+ parser.ScanStr((char *)params, "%d,%d,%d,%d", &r, &g, &b, &a);
+ m_IndicatorColor = DRGBA(r, g, b, a);
+ }
+ break;
+
+ case TOKEN_INDICATOR_WIDTH:
+ parser.ScanStr((char *)params, "%d", &m_IndicatorWidth);
+ break;
+
+ case TOKEN_INDICATOR_HEIGHT:
+ parser.ScanStr((char *)params, "%d", &m_IndicatorHeight);
+ break;
+
+ case TOKEN_SAVE_IMAGE:
+ CBUtils::SetString(&m_SaveImageName, (char *)params);
+ break;
+
+ case TOKEN_SAVE_IMAGE_X:
+ parser.ScanStr((char *)params, "%d", &m_SaveImageX);
+ break;
+
+ case TOKEN_SAVE_IMAGE_Y:
+ parser.ScanStr((char *)params, "%d", &m_SaveImageY);
+ break;
+
+ case TOKEN_LOAD_IMAGE:
+ CBUtils::SetString(&m_LoadImageName, (char *)params);
+ break;
+
+ case TOKEN_LOAD_IMAGE_X:
+ parser.ScanStr((char *)params, "%d", &m_LoadImageX);
+ break;
+
+ case TOKEN_LOAD_IMAGE_Y:
+ parser.ScanStr((char *)params, "%d", &m_LoadImageY);
+ break;
+
+ case TOKEN_LOCAL_SAVE_DIR:
+ CBUtils::SetString(&m_LocalSaveDir, (char *)params);
+ break;
+
+ case TOKEN_COMPAT_KILL_METHOD_THREADS:
+ parser.ScanStr((char *)params, "%b", &m_CompatKillMethodThreads);
+ break;
+ }
+ }
+
+ if (!m_SystemFont) m_SystemFont = Game->m_FontStorage->AddFont("system_font.fnt");
+
+
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in GAME definition");
+ return E_FAIL;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ Game->LOG(0, "Error loading GAME definition");
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ //////////////////////////////////////////////////////////////////////////
+ // LOG
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "LOG") == 0) {
+ Stack->CorrectParams(1);
+ LOG(0, Stack->Pop()->GetString());
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Caption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Caption") == 0) {
+ HRESULT res = CBObject::ScCallMethod(Script, Stack, ThisStack, Name);
+ SetWindowTitle();
+ return res;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Msg
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Msg") == 0) {
+ Stack->CorrectParams(1);
+ QuickMessage(Stack->Pop()->GetString());
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RunScript
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RunScript") == 0) {
+ Game->LOG(0, "**Warning** The 'RunScript' method is now obsolete. Use 'AttachScript' instead (same syntax)");
+ Stack->CorrectParams(1);
+ if (FAILED(AddScript(Stack->Pop()->GetString())))
+ Stack->PushBool(false);
+ else
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadStringTable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "LoadStringTable") == 0) {
+ Stack->CorrectParams(2);
+ char *Filename = Stack->Pop()->GetString();
+ CScValue *Val = Stack->Pop();
+
+ bool ClearOld;
+ if (Val->IsNULL()) ClearOld = true;
+ else ClearOld = Val->GetBool();
+
+ if (FAILED(m_StringTable->LoadFile(Filename, ClearOld)))
+ Stack->PushBool(false);
+ else
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ValidObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ValidObject") == 0) {
+ Stack->CorrectParams(1);
+ CBScriptable *obj = Stack->Pop()->GetNative();
+ if (ValidObject((CBObject *) obj)) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Reset
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Reset") == 0) {
+ Stack->CorrectParams(0);
+ ResetContent();
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // UnloadObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "UnloadObject") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *val = Stack->Pop();
+ CBObject *obj = (CBObject *)val->GetNative();
+ UnregisterObject(obj);
+ if (val->GetType() == VAL_VARIABLE_REF) val->SetNULL();
+
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadWindow
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "LoadWindow") == 0) {
+ Stack->CorrectParams(1);
+ CUIWindow *win = new CUIWindow(Game);
+ if (win && SUCCEEDED(win->LoadFile(Stack->Pop()->GetString()))) {
+ m_Windows.Add(win);
+ RegisterObject(win);
+ Stack->PushNative(win, true);
+ } else {
+ delete win;
+ win = NULL;
+ Stack->PushNULL();
+ }
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ExpandString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ExpandString") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *val = Stack->Pop();
+ char *str = new char[strlen(val->GetString()) + 1];
+ strcpy(str, val->GetString());
+ m_StringTable->Expand(&str);
+ Stack->PushString(str);
+ delete [] str;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlayMusic / PlayMusicChannel
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PlayMusic") == 0 || strcmp(Name, "PlayMusicChannel") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "PlayMusic") == 0) Stack->CorrectParams(3);
+ else {
+ Stack->CorrectParams(4);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ char *Filename = Stack->Pop()->GetString();
+ CScValue *ValLooping = Stack->Pop();
+ bool Looping = ValLooping->IsNULL() ? true : ValLooping->GetBool();
+
+ CScValue *ValLoopStart = Stack->Pop();
+ uint32 LoopStart = (uint32)(ValLoopStart->IsNULL() ? 0 : ValLoopStart->GetInt());
+
+
+ if (FAILED(PlayMusic(Channel, Filename, Looping, LoopStart))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StopMusic / StopMusicChannel
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "StopMusic") == 0 || strcmp(Name, "StopMusicChannel") == 0) {
+ int Channel = 0;
+
+ if (strcmp(Name, "StopMusic") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ if (FAILED(StopMusic(Channel))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PauseMusic / PauseMusicChannel
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PauseMusic") == 0 || strcmp(Name, "PauseMusicChannel") == 0) {
+ int Channel = 0;
+
+ if (strcmp(Name, "PauseMusic") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ if (FAILED(PauseMusic(Channel))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ResumeMusic / ResumeMusicChannel
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ResumeMusic") == 0 || strcmp(Name, "ResumeMusicChannel") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "ResumeMusic") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ if (FAILED(ResumeMusic(Channel))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetMusic / GetMusicChannel
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetMusic") == 0 || strcmp(Name, "GetMusicChannel") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "GetMusic") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+ if (Channel < 0 || Channel >= NUM_MUSIC_CHANNELS) Stack->PushNULL();
+ else {
+ if (!m_Music[Channel] || !m_Music[Channel]->m_SoundFilename) Stack->PushNULL();
+ else Stack->PushString(m_Music[Channel]->m_SoundFilename);
+ }
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetMusicPosition / SetMusicChannelPosition
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetMusicPosition") == 0 || strcmp(Name, "SetMusicChannelPosition") == 0 || strcmp(Name, "SetMusicPositionChannel") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "SetMusicPosition") == 0) Stack->CorrectParams(1);
+ else {
+ Stack->CorrectParams(2);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ uint32 Time = Stack->Pop()->GetInt();
+
+ if (FAILED(SetMusicStartTime(Channel, Time))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetMusicPosition / GetMusicChannelPosition
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetMusicPosition") == 0 || strcmp(Name, "GetMusicChannelPosition") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "GetMusicPosition") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ if (Channel < 0 || Channel >= NUM_MUSIC_CHANNELS || !m_Music[Channel]) Stack->PushInt(0);
+ else Stack->PushInt(m_Music[Channel]->GetPositionTime());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsMusicPlaying / IsMusicChannelPlaying
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsMusicPlaying") == 0 || strcmp(Name, "IsMusicChannelPlaying") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "IsMusicPlaying") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ if (Channel < 0 || Channel >= NUM_MUSIC_CHANNELS || !m_Music[Channel]) Stack->PushBool(false);
+ else Stack->PushBool(m_Music[Channel]->IsPlaying());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetMusicVolume / SetMusicChannelVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetMusicVolume") == 0 || strcmp(Name, "SetMusicChannelVolume") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "SetMusicVolume") == 0) Stack->CorrectParams(1);
+ else {
+ Stack->CorrectParams(2);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ int Volume = Stack->Pop()->GetInt();
+ if (Channel < 0 || Channel >= NUM_MUSIC_CHANNELS || !m_Music[Channel]) Stack->PushBool(false);
+ else {
+ if (FAILED(m_Music[Channel]->SetVolume(Volume))) Stack->PushBool(false);
+ else Stack->PushBool(true);
+ }
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetMusicVolume / GetMusicChannelVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetMusicVolume") == 0 || strcmp(Name, "GetMusicChannelVolume") == 0) {
+ int Channel = 0;
+ if (strcmp(Name, "GetMusicVolume") == 0) Stack->CorrectParams(0);
+ else {
+ Stack->CorrectParams(1);
+ Channel = Stack->Pop()->GetInt();
+ }
+
+ if (Channel < 0 || Channel >= NUM_MUSIC_CHANNELS || !m_Music[Channel]) Stack->PushInt(0);
+ else Stack->PushInt(m_Music[Channel]->GetVolume());
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MusicCrossfade
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MusicCrossfade") == 0) {
+ Stack->CorrectParams(4);
+ int Channel1 = Stack->Pop()->GetInt(0);
+ int Channel2 = Stack->Pop()->GetInt(0);
+ uint32 FadeLength = (uint32)Stack->Pop()->GetInt(0);
+ bool Swap = Stack->Pop()->GetBool(true);
+
+ if (m_MusicCrossfadeRunning) {
+ Script->RuntimeError("Game.MusicCrossfade: Music crossfade is already in progress.");
+ Stack->PushBool(false);
+ return S_OK;
+ }
+
+ m_MusicCrossfadeStartTime = m_LiveTimer;
+ m_MusicCrossfadeChannel1 = Channel1;
+ m_MusicCrossfadeChannel2 = Channel2;
+ m_MusicCrossfadeLength = FadeLength;
+ m_MusicCrossfadeSwap = Swap;
+
+ m_MusicCrossfadeRunning = true;
+
+ Stack->PushBool(true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSoundLength
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetSoundLength") == 0) {
+ Stack->CorrectParams(1);
+
+ int Length = 0;
+ char *Filename = Stack->Pop()->GetString();
+
+ CBSound *Sound = new CBSound(Game);
+ if (Sound && SUCCEEDED(Sound->SetSound(Filename, SOUND_MUSIC, true))) {
+ Length = Sound->GetLength();
+ delete Sound;
+ Sound = NULL;
+ }
+ Stack->PushInt(Length);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetMousePos
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetMousePos") == 0) {
+ Stack->CorrectParams(2);
+ int x = Stack->Pop()->GetInt();
+ int y = Stack->Pop()->GetInt();
+ x = std::max(x, 0);
+ x = std::min(x, m_Renderer->m_Width);
+ y = std::max(y, 0);
+ y = std::min(y, m_Renderer->m_Height);
+ POINT p;
+ p.x = x + m_Renderer->m_DrawOffsetX;
+ p.y = y + m_Renderer->m_DrawOffsetY;
+
+ CBPlatform::SetCursorPos(p.x, p.y);
+
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LockMouseRect
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "LockMouseRect") == 0) {
+ Stack->CorrectParams(4);
+ int left = Stack->Pop()->GetInt();
+ int top = Stack->Pop()->GetInt();
+ int right = Stack->Pop()->GetInt();
+ int bottom = Stack->Pop()->GetInt();
+
+ if (right < left) CBUtils::Swap(&left, &right);
+ if (bottom < top) CBUtils::Swap(&top, &bottom);
+
+ CBPlatform::SetRect(&m_MouseLockRect, left, top, right, bottom);
+
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlayVideo
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PlayVideo") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PlayTheora
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PlayTheora") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // QuitGame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "QuitGame") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushNULL();
+ m_Quitting = true;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RegWriteNumber
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RegWriteNumber") == 0) {
+ Stack->CorrectParams(2);
+ char *Key = Stack->Pop()->GetString();
+ int Val = Stack->Pop()->GetInt();
+ m_Registry->WriteInt("PrivateSettings", Key, Val);
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RegReadNumber
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RegReadNumber") == 0) {
+ Stack->CorrectParams(2);
+ char *Key = Stack->Pop()->GetString();
+ int InitVal = Stack->Pop()->GetInt();
+ Stack->PushInt(m_Registry->ReadInt("PrivateSettings", Key, InitVal));
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RegWriteString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RegWriteString") == 0) {
+ Stack->CorrectParams(2);
+ char *Key = Stack->Pop()->GetString();
+ char *Val = Stack->Pop()->GetString();
+ m_Registry->WriteString("PrivateSettings", Key, Val);
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RegReadString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RegReadString") == 0) {
+ Stack->CorrectParams(2);
+ char *Key = Stack->Pop()->GetString();
+ char *InitVal = Stack->Pop()->GetString();
+ AnsiString val = m_Registry->ReadString("PrivateSettings", Key, InitVal);
+ Stack->PushString((char *)val.c_str());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SaveGame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SaveGame") == 0) {
+ Stack->CorrectParams(3);
+ int Slot = Stack->Pop()->GetInt();
+ char *xdesc = Stack->Pop()->GetString();
+ bool quick = Stack->Pop()->GetBool(false);
+
+ char *Desc = new char[strlen(xdesc) + 1];
+ strcpy(Desc, xdesc);
+ Stack->PushBool(true);
+ if (FAILED(SaveGame(Slot, Desc, quick))) {
+ Stack->Pop();
+ Stack->PushBool(false);
+ }
+ delete [] Desc;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // LoadGame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "LoadGame") == 0) {
+ Stack->CorrectParams(1);
+ m_ScheduledLoadSlot = Stack->Pop()->GetInt();
+ m_Loading = true;
+ Stack->PushBool(false);
+ Script->Sleep(0);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsSaveSlotUsed
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsSaveSlotUsed") == 0) {
+ Stack->CorrectParams(1);
+ int Slot = Stack->Pop()->GetInt();
+ Stack->PushBool(IsSaveSlotUsed(Slot));
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSaveSlotDescription
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetSaveSlotDescription") == 0) {
+ Stack->CorrectParams(1);
+ int Slot = Stack->Pop()->GetInt();
+ char Desc[512];
+ Desc[0] = '\0';
+ GetSaveSlotDescription(Slot, Desc);
+ Stack->PushString(Desc);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // EmptySaveSlot
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "EmptySaveSlot") == 0) {
+ Stack->CorrectParams(1);
+ int Slot = Stack->Pop()->GetInt();
+ EmptySaveSlot(Slot);
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetGlobalSFXVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetGlobalSFXVolume") == 0) {
+ Stack->CorrectParams(1);
+ Game->m_SoundMgr->SetVolumePercent(SOUND_SFX, (byte )Stack->Pop()->GetInt());
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetGlobalSpeechVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetGlobalSpeechVolume") == 0) {
+ Stack->CorrectParams(1);
+ Game->m_SoundMgr->SetVolumePercent(SOUND_SPEECH, (byte )Stack->Pop()->GetInt());
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetGlobalMusicVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetGlobalMusicVolume") == 0) {
+ Stack->CorrectParams(1);
+ Game->m_SoundMgr->SetVolumePercent(SOUND_MUSIC, (byte )Stack->Pop()->GetInt());
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetGlobalMasterVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetGlobalMasterVolume") == 0) {
+ Stack->CorrectParams(1);
+ Game->m_SoundMgr->SetMasterVolumePercent((byte )Stack->Pop()->GetInt());
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetGlobalSFXVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetGlobalSFXVolume") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushInt(m_SoundMgr->GetVolumePercent(SOUND_SFX));
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetGlobalSpeechVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetGlobalSpeechVolume") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushInt(m_SoundMgr->GetVolumePercent(SOUND_SPEECH));
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetGlobalMusicVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetGlobalMusicVolume") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushInt(m_SoundMgr->GetVolumePercent(SOUND_MUSIC));
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetGlobalMasterVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetGlobalMasterVolume") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushInt(m_SoundMgr->GetMasterVolumePercent());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetActiveCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetActiveCursor") == 0) {
+ Stack->CorrectParams(1);
+ if (SUCCEEDED(SetActiveCursor(Stack->Pop()->GetString()))) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetActiveCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetActiveCursor") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_ActiveCursor || !m_ActiveCursor->m_Filename) Stack->PushNULL();
+ else Stack->PushString(m_ActiveCursor->m_Filename);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetActiveCursorObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetActiveCursorObject") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_ActiveCursor) Stack->PushNULL();
+ else Stack->PushNative(m_ActiveCursor, true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemoveActiveCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RemoveActiveCursor") == 0) {
+ Stack->CorrectParams(0);
+ delete m_ActiveCursor;
+ m_ActiveCursor = NULL;
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HasActiveCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HasActiveCursor") == 0) {
+ Stack->CorrectParams(0);
+
+ if (m_ActiveCursor) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // FileExists
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "FileExists") == 0) {
+ Stack->CorrectParams(1);
+ char *Filename = Stack->Pop()->GetString();
+
+ CBFile *File = m_FileManager->OpenFile(Filename, false);
+ if (!File) Stack->PushBool(false);
+ else {
+ m_FileManager->CloseFile(File);
+ Stack->PushBool(true);
+ }
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // FadeOut / FadeOutAsync / SystemFadeOut / SystemFadeOutAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "FadeOut") == 0 || strcmp(Name, "FadeOutAsync") == 0 || strcmp(Name, "SystemFadeOut") == 0 || strcmp(Name, "SystemFadeOutAsync") == 0) {
+ Stack->CorrectParams(5);
+ uint32 Duration = Stack->Pop()->GetInt(500);
+ byte Red = Stack->Pop()->GetInt(0);
+ byte Green = Stack->Pop()->GetInt(0);
+ byte Blue = Stack->Pop()->GetInt(0);
+ byte Alpha = Stack->Pop()->GetInt(0xFF);
+
+ bool System = (strcmp(Name, "SystemFadeOut") == 0 || strcmp(Name, "SystemFadeOutAsync") == 0);
+
+ m_Fader->FadeOut(DRGBA(Red, Green, Blue, Alpha), Duration, System);
+ if (strcmp(Name, "FadeOutAsync") != 0 && strcmp(Name, "SystemFadeOutAsync") != 0) Script->WaitFor(m_Fader);
+
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // FadeIn / FadeInAsync / SystemFadeIn / SystemFadeInAsync
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "FadeIn") == 0 || strcmp(Name, "FadeInAsync") == 0 || strcmp(Name, "SystemFadeIn") == 0 || strcmp(Name, "SystemFadeInAsync") == 0) {
+ Stack->CorrectParams(5);
+ uint32 Duration = Stack->Pop()->GetInt(500);
+ byte Red = Stack->Pop()->GetInt(0);
+ byte Green = Stack->Pop()->GetInt(0);
+ byte Blue = Stack->Pop()->GetInt(0);
+ byte Alpha = Stack->Pop()->GetInt(0xFF);
+
+ bool System = (strcmp(Name, "SystemFadeIn") == 0 || strcmp(Name, "SystemFadeInAsync") == 0);
+
+ m_Fader->FadeIn(DRGBA(Red, Green, Blue, Alpha), Duration, System);
+ if (strcmp(Name, "FadeInAsync") != 0 && strcmp(Name, "SystemFadeInAsync") != 0) Script->WaitFor(m_Fader);
+
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetFadeColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetFadeColor") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushInt(m_Fader->GetCurrentColor());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Screenshot
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Screenshot") == 0) {
+ Stack->CorrectParams(1);
+ char Filename[MAX_PATH];
+
+ CScValue *Val = Stack->Pop();
+
+ int FileNum = 0;
+ while (true) {
+ sprintf(Filename, "%s%03d.bmp", Val->IsNULL() ? m_Name : Val->GetString(), FileNum);
+ FILE *f = fopen(Filename, "rb");
+ if (!f) break;
+ else fclose(f);
+ FileNum++;
+ }
+
+ bool ret = false;
+ CBImage *Image = Game->m_Renderer->TakeScreenshot();
+ if (Image) {
+ ret = SUCCEEDED(Image->SaveBMPFile(Filename));
+ delete Image;
+ } else ret = false;
+
+ Stack->PushBool(ret);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScreenshotEx
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScreenshotEx") == 0) {
+ Stack->CorrectParams(3);
+ char *Filename = Stack->Pop()->GetString();
+ int SizeX = Stack->Pop()->GetInt(m_Renderer->m_Width);
+ int SizeY = Stack->Pop()->GetInt(m_Renderer->m_Height);
+
+ bool ret = false;
+ CBImage *Image = Game->m_Renderer->TakeScreenshot();
+ if (Image) {
+ ret = SUCCEEDED(Image->Resize(SizeX, SizeY));
+ if (ret) ret = SUCCEEDED(Image->SaveBMPFile(Filename));
+ delete Image;
+ } else ret = false;
+
+ Stack->PushBool(ret);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CreateWindow
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CreateWindow") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+
+ CUIWindow *Win = new CUIWindow(Game);
+ m_Windows.Add(Win);
+ RegisterObject(Win);
+ if (!Val->IsNULL()) Win->SetName(Val->GetString());
+ Stack->PushNative(Win, true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteWindow
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DeleteWindow") == 0) {
+ Stack->CorrectParams(1);
+ CBObject *Obj = (CBObject *)Stack->Pop()->GetNative();
+ for (int i = 0; i < m_Windows.GetSize(); i++) {
+ if (m_Windows[i] == Obj) {
+ UnregisterObject(m_Windows[i]);
+ Stack->PushBool(true);
+ return S_OK;
+ }
+ }
+ Stack->PushBool(false);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // OpenDocument
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "OpenDocument") == 0) {
+#ifdef __WIN32__
+ Stack->CorrectParams(1);
+ if (!m_Renderer->m_Windowed) CBPlatform::ShowWindow(m_Renderer->m_Window, SW_MINIMIZE);
+ HINSTANCE i = CBPlatform::ShellExecute(m_Renderer->m_Window, "open", Stack->Pop()->GetString(), NULL, NULL, SW_MAXIMIZE);
+ Stack->PushBool((int)i > 32);
+#else
+ Stack->CorrectParams(0);
+ Stack->PushNULL();
+#endif
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DEBUG_DumpClassRegistry
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DEBUG_DumpClassRegistry") == 0) {
+ Stack->CorrectParams(0);
+ DEBUG_DumpClassRegistry();
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetLoadingScreen
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetLoadingScreen") == 0) {
+ Stack->CorrectParams(3);
+ CScValue *Val = Stack->Pop();
+ m_LoadImageX = Stack->Pop()->GetInt();
+ m_LoadImageY = Stack->Pop()->GetInt();
+
+ if (Val->IsNULL()) {
+ delete[] m_LoadImageName;
+ m_LoadImageName = NULL;
+ } else {
+ CBUtils::SetString(&m_LoadImageName, Val->GetString());
+ }
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetSavingScreen
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetSavingScreen") == 0) {
+ Stack->CorrectParams(3);
+ CScValue *Val = Stack->Pop();
+ m_SaveImageX = Stack->Pop()->GetInt();
+ m_SaveImageY = Stack->Pop()->GetInt();
+
+ if (Val->IsNULL()) {
+ delete[] m_SaveImageName;
+ m_SaveImageName = NULL;
+ } else {
+ CBUtils::SetString(&m_SaveImageName, Val->GetString());
+ }
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetWaitCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetWaitCursor") == 0) {
+ Stack->CorrectParams(1);
+ if (SUCCEEDED(SetWaitCursor(Stack->Pop()->GetString()))) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemoveWaitCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RemoveWaitCursor") == 0) {
+ Stack->CorrectParams(0);
+ delete m_CursorNoninteractive;
+ m_CursorNoninteractive = NULL;
+
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetWaitCursor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetWaitCursor") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_CursorNoninteractive || !m_CursorNoninteractive->m_Filename) Stack->PushNULL();
+ else Stack->PushString(m_CursorNoninteractive->m_Filename);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetWaitCursorObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetWaitCursorObject") == 0) {
+ Stack->CorrectParams(0);
+ if (!m_CursorNoninteractive) Stack->PushNULL();
+ else Stack->PushNative(m_CursorNoninteractive, true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ClearScriptCache
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ClearScriptCache") == 0) {
+ Stack->CorrectParams(0);
+ Stack->PushBool(SUCCEEDED(m_ScEngine->EmptyScriptCache()));
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DisplayLoadingIcon
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DisplayLoadingIcon") == 0) {
+ Stack->CorrectParams(4);
+
+ char *Filename = Stack->Pop()->GetString();
+ m_LoadingIconX = Stack->Pop()->GetInt();
+ m_LoadingIconY = Stack->Pop()->GetInt();
+ m_LoadingIconPersistent = Stack->Pop()->GetBool();
+
+ delete m_LoadingIcon;
+ m_LoadingIcon = new CBSprite(this);
+ if (!m_LoadingIcon || FAILED(m_LoadingIcon->LoadFile(Filename))) {
+ delete m_LoadingIcon;
+ m_LoadingIcon = NULL;
+ } else {
+ DisplayContent(false, true);
+ Game->m_Renderer->Flip();
+ Game->m_Renderer->InitLoop();
+ }
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HideLoadingIcon
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HideLoadingIcon") == 0) {
+ Stack->CorrectParams(0);
+ delete m_LoadingIcon;
+ m_LoadingIcon = NULL;
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DumpTextureStats
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DumpTextureStats") == 0) {
+ Stack->CorrectParams(1);
+ char *Filename = Stack->Pop()->GetString();
+
+ m_Renderer->DumpData(Filename);
+
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccOutputText
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccOutputText") == 0) {
+ Stack->CorrectParams(2);
+ char *Str = Stack->Pop()->GetString();
+ int Type = Stack->Pop()->GetInt();
+ // do nothing
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // StoreSaveThumbnail
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "StoreSaveThumbnail") == 0) {
+ Stack->CorrectParams(0);
+ delete m_CachedThumbnail;
+ m_CachedThumbnail = new CBSaveThumbHelper(this);
+ if (FAILED(m_CachedThumbnail->StoreThumbnail())) {
+ delete m_CachedThumbnail;
+ m_CachedThumbnail = NULL;
+ Stack->PushBool(false);
+ } else Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteSaveThumbnail
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DeleteSaveThumbnail") == 0) {
+ Stack->CorrectParams(0);
+ delete m_CachedThumbnail;
+ m_CachedThumbnail = NULL;
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetFileChecksum
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetFileChecksum") == 0) {
+ Stack->CorrectParams(2);
+ char *Filename = Stack->Pop()->GetString();
+ bool AsHex = Stack->Pop()->GetBool(false);
+
+ CBFile *File = m_FileManager->OpenFile(Filename, false);
+ if (File) {
+ crc remainder = crc_initialize();
+ byte Buf[1024];
+ int BytesRead = 0;
+
+ while (BytesRead < File->GetSize()) {
+ int BufSize = MIN(1024, File->GetSize() - BytesRead);
+ BytesRead += BufSize;
+
+ File->Read(Buf, BufSize);
+ for (int i = 0; i < BufSize; i++) {
+ remainder = crc_process_byte(Buf[i], remainder);
+ }
+ }
+ crc checksum = crc_finalize(remainder);
+
+ if (AsHex) {
+ char Hex[100];
+ sprintf(Hex, "%x", checksum);
+ Stack->PushString(Hex);
+ } else
+ Stack->PushInt(checksum);
+
+ m_FileManager->CloseFile(File);
+ File = NULL;
+ } else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // EnableScriptProfiling
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "EnableScriptProfiling") == 0) {
+ Stack->CorrectParams(0);
+ m_ScEngine->EnableProfiling();
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DisableScriptProfiling
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DisableScriptProfiling") == 0) {
+ Stack->CorrectParams(0);
+ m_ScEngine->DisableProfiling();
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ShowStatusLine
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ShowStatusLine") == 0) {
+ Stack->CorrectParams(0);
+#ifdef __IPHONEOS__
+ IOS_ShowStatusLine(TRUE);
+#endif
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HideStatusLine
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HideStatusLine") == 0) {
+ Stack->CorrectParams(0);
+#ifdef __IPHONEOS__
+ IOS_ShowStatusLine(FALSE);
+#endif
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ else return CBObject::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBGame::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("game");
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Name") == 0) {
+ m_ScValue->SetString(m_Name);
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // Hwnd (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Hwnd") == 0) {
+ m_ScValue->SetInt((int)m_Renderer->m_Window);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CurrentTime (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CurrentTime") == 0) {
+ m_ScValue->SetInt((int)m_Timer);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WindowsTime (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WindowsTime") == 0) {
+ m_ScValue->SetInt((int)CBPlatform::GetTime());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WindowedMode (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WindowedMode") == 0) {
+ m_ScValue->SetBool(m_Renderer->m_Windowed);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MouseX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MouseX") == 0) {
+ m_ScValue->SetInt(m_MousePos.x);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MouseY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MouseY") == 0) {
+ m_ScValue->SetInt(m_MousePos.y);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MainObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MainObject") == 0) {
+ m_ScValue->SetNative(m_MainObject, true);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ActiveObject (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ActiveObject") == 0) {
+ m_ScValue->SetNative(m_ActiveObject, true);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScreenWidth (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScreenWidth") == 0) {
+ m_ScValue->SetInt(m_Renderer->m_Width);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ScreenHeight (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ScreenHeight") == 0) {
+ m_ScValue->SetInt(m_Renderer->m_Height);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Interactive
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Interactive") == 0) {
+ m_ScValue->SetBool(m_Interactive);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DebugMode (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DebugMode") == 0) {
+ m_ScValue->SetBool(m_DEBUG_DebugMode);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundAvailable (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundAvailable") == 0) {
+ m_ScValue->SetBool(m_SoundMgr->m_SoundAvailable);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SFXVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SFXVolume") == 0) {
+ Game->LOG(0, "**Warning** The SFXVolume attribute is obsolete");
+ m_ScValue->SetInt(m_SoundMgr->GetVolumePercent(SOUND_SFX));
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SpeechVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SpeechVolume") == 0) {
+ Game->LOG(0, "**Warning** The SpeechVolume attribute is obsolete");
+ m_ScValue->SetInt(m_SoundMgr->GetVolumePercent(SOUND_SPEECH));
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MusicVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MusicVolume") == 0) {
+ Game->LOG(0, "**Warning** The MusicVolume attribute is obsolete");
+ m_ScValue->SetInt(m_SoundMgr->GetVolumePercent(SOUND_MUSIC));
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MasterVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MasterVolume") == 0) {
+ Game->LOG(0, "**Warning** The MasterVolume attribute is obsolete");
+ m_ScValue->SetInt(m_SoundMgr->GetMasterVolumePercent());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Keyboard (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Keyboard") == 0) {
+ if (m_KeyboardState) m_ScValue->SetNative(m_KeyboardState, true);
+ else m_ScValue->SetNULL();
+
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Subtitles
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Subtitles") == 0) {
+ m_ScValue->SetBool(m_Subtitles);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesSpeed
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SubtitlesSpeed") == 0) {
+ m_ScValue->SetInt(m_SubtitlesSpeed);
+ return m_ScValue;
+ }
+ //////////////////////////////////////////////////////////////////////////
+ // VideoSubtitles
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "VideoSubtitles") == 0) {
+ m_ScValue->SetBool(m_VideoSubtitles);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // FPS (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "FPS") == 0) {
+ m_ScValue->SetInt(m_Fps);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AcceleratedMode / Accelerated (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AcceleratedMode") == 0 || strcmp(Name, "Accelerated") == 0) {
+ m_ScValue->SetBool(m_UseD3D);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TextEncoding
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "TextEncoding") == 0) {
+ m_ScValue->SetInt(m_TextEncoding);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TextRTL
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "TextRTL") == 0) {
+ m_ScValue->SetBool(m_TextRTL);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundBufferSize
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundBufferSize") == 0) {
+ m_ScValue->SetInt(m_SoundBufferSizeSec);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SuspendedRendering
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SuspendedRendering") == 0) {
+ m_ScValue->SetBool(m_SuspendedRendering);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SuppressScriptErrors
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SuppressScriptErrors") == 0) {
+ m_ScValue->SetBool(m_SuppressScriptErrors);
+ return m_ScValue;
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Frozen
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Frozen") == 0) {
+ m_ScValue->SetBool(m_State == GAME_FROZEN);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccTTSEnabled
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccTTSEnabled") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccTTSTalk
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccTTSTalk") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccTTSCaptions
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccTTSCaptions") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccTTSKeypress
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccTTSKeypress") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccKeyboardEnabled
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccKeyboardEnabled") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccKeyboardCursorSkip
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccKeyboardCursorSkip") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AccKeyboardPause
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AccKeyboardPause") == 0) {
+ m_ScValue->SetBool(false);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutorunDisabled
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AutorunDisabled") == 0) {
+ m_ScValue->SetBool(m_AutorunDisabled);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SaveDirectory (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SaveDirectory") == 0) {
+ AnsiString dataDir = GetDataDir();
+ m_ScValue->SetString((char *)dataDir.c_str());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutoSaveOnExit
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AutoSaveOnExit") == 0) {
+ m_ScValue->SetBool(m_AutoSaveOnExit);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutoSaveSlot
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AutoSaveSlot") == 0) {
+ m_ScValue->SetInt(m_AutoSaveSlot);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CursorHidden
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CursorHidden") == 0) {
+ m_ScValue->SetBool(m_CursorHidden);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Platform (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Platform") == 0) {
+ m_ScValue->SetString(CBPlatform::GetPlatformName().c_str());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeviceType (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DeviceType") == 0) {
+ m_ScValue->SetString(GetDeviceType().c_str());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MostRecentSaveSlot (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MostRecentSaveSlot") == 0) {
+ m_ScValue->SetInt(m_Registry->ReadInt("System", "MostRecentSaveSlot", -1));
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Store (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Store") == 0) {
+ if (m_Store) m_ScValue->SetNative(m_Store, true);
+ else m_ScValue->SetNULL();
+
+ return m_ScValue;
+ }
+
+ else return CBObject::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Name") == 0) {
+ SetName(Value->GetString());
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MouseX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MouseX") == 0) {
+ m_MousePos.x = Value->GetInt();
+ ResetMousePos();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MouseY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MouseY") == 0) {
+ m_MousePos.y = Value->GetInt();
+ ResetMousePos();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Caption
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Name") == 0) {
+ HRESULT res = CBObject::ScSetProperty(Name, Value);
+ SetWindowTitle();
+ return res;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MainObject
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MainObject") == 0) {
+ CBScriptable *obj = Value->GetNative();
+ if (obj == NULL || ValidObject((CBObject *)obj)) m_MainObject = (CBObject *)obj;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Interactive
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Interactive") == 0) {
+ SetInteractive(Value->GetBool());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SFXVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SFXVolume") == 0) {
+ Game->LOG(0, "**Warning** The SFXVolume attribute is obsolete");
+ Game->m_SoundMgr->SetVolumePercent(SOUND_SFX, (byte )Value->GetInt());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SpeechVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SpeechVolume") == 0) {
+ Game->LOG(0, "**Warning** The SpeechVolume attribute is obsolete");
+ Game->m_SoundMgr->SetVolumePercent(SOUND_SPEECH, (byte )Value->GetInt());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MusicVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MusicVolume") == 0) {
+ Game->LOG(0, "**Warning** The MusicVolume attribute is obsolete");
+ Game->m_SoundMgr->SetVolumePercent(SOUND_MUSIC, (byte )Value->GetInt());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MasterVolume
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MasterVolume") == 0) {
+ Game->LOG(0, "**Warning** The MasterVolume attribute is obsolete");
+ Game->m_SoundMgr->SetMasterVolumePercent((byte )Value->GetInt());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Subtitles
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Subtitles") == 0) {
+ m_Subtitles = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SubtitlesSpeed
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SubtitlesSpeed") == 0) {
+ m_SubtitlesSpeed = Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // VideoSubtitles
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "VideoSubtitles") == 0) {
+ m_VideoSubtitles = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TextEncoding
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "TextEncoding") == 0) {
+ int Enc = Value->GetInt();
+ if (Enc < 0) Enc = 0;
+ if (Enc >= NUM_TEXT_ENCODINGS) Enc = NUM_TEXT_ENCODINGS - 1;
+ m_TextEncoding = (TTextEncoding)Enc;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TextRTL
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "TextRTL") == 0) {
+ m_TextRTL = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SoundBufferSize
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SoundBufferSize") == 0) {
+ m_SoundBufferSizeSec = Value->GetInt();
+ m_SoundBufferSizeSec = std::max(3, m_SoundBufferSizeSec);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SuspendedRendering
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SuspendedRendering") == 0) {
+ m_SuspendedRendering = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SuppressScriptErrors
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SuppressScriptErrors") == 0) {
+ m_SuppressScriptErrors = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutorunDisabled
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AutorunDisabled") == 0) {
+ m_AutorunDisabled = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutoSaveOnExit
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AutoSaveOnExit") == 0) {
+ m_AutoSaveOnExit = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AutoSaveSlot
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AutoSaveSlot") == 0) {
+ m_AutoSaveSlot = Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CursorHidden
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CursorHidden") == 0) {
+ m_CursorHidden = Value->GetBool();
+ return S_OK;
+ }
+
+ else return CBObject::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBGame::ScToString() {
+ return "[game object]";
+}
+
+
+
+#define QUICK_MSG_DURATION 3000
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DisplayQuickMsg() {
+ if (m_QuickMessages.GetSize() == 0 || !m_SystemFont) return S_OK;
+
+ int i;
+
+ // update
+ for (i = 0; i < m_QuickMessages.GetSize(); i++) {
+ if (m_CurrentTime - m_QuickMessages[i]->m_StartTime >= QUICK_MSG_DURATION) {
+ delete m_QuickMessages[i];
+ m_QuickMessages.RemoveAt(i);
+ i--;
+ }
+ }
+
+ int PosY = 20;
+
+ // display
+ for (i = 0; i < m_QuickMessages.GetSize(); i++) {
+ m_SystemFont->DrawText((byte *)m_QuickMessages[i]->GetText(), 0, PosY, m_Renderer->m_Width);
+ PosY += m_SystemFont->GetTextHeight((byte *)m_QuickMessages[i]->GetText(), m_Renderer->m_Width);
+ }
+ return S_OK;
+}
+
+
+#define MAX_QUICK_MSG 5
+//////////////////////////////////////////////////////////////////////////
+void CBGame::QuickMessage(char *Text) {
+ if (m_QuickMessages.GetSize() >= MAX_QUICK_MSG) {
+ delete m_QuickMessages[0];
+ m_QuickMessages.RemoveAt(0);
+ }
+ m_QuickMessages.Add(new CBQuickMsg(Game, Text));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::QuickMessageForm(LPSTR fmt, ...) {
+ char buff[256];
+ va_list va;
+
+ va_start(va, fmt);
+ vsprintf(buff, fmt, va);
+ va_end(va);
+
+ QuickMessage(buff);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::RegisterObject(CBObject *Object) {
+ m_RegObjects.Add(Object);
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::UnregisterObject(CBObject *Object) {
+ if (!Object) return S_OK;
+
+ int i;
+
+ // is it a window?
+ for (i = 0; i < m_Windows.GetSize(); i++) {
+ if ((CBObject *)m_Windows[i] == Object) {
+ m_Windows.RemoveAt(i);
+
+ // get new focused window
+ if (m_FocusedWindow == Object) m_FocusedWindow = NULL;
+
+ break;
+ }
+ }
+
+ // is it active object?
+ if (m_ActiveObject == Object) m_ActiveObject = NULL;
+
+ // is it main object?
+ if (m_MainObject == Object) m_MainObject = NULL;
+
+ if (m_Store) m_Store->OnObjectDestroyed(Object);
+
+ // destroy object
+ for (i = 0; i < m_RegObjects.GetSize(); i++) {
+ if (m_RegObjects[i] == Object) {
+ m_RegObjects.RemoveAt(i);
+ if (!m_LoadInProgress) CSysClassRegistry::GetInstance()->EnumInstances(InvalidateValues, "CScValue", (void *)Object);
+ delete Object;
+ return S_OK;
+ }
+ }
+
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::InvalidateValues(void *Value, void *Data) {
+ CScValue *val = (CScValue *)Value;
+ if (val->IsNative() && val->GetNative() == Data) {
+ if (!val->m_Persistent && ((CBScriptable *)Data)->m_RefCount == 1) {
+ ((CBScriptable *)Data)->m_RefCount++;
+ }
+ val->SetNative(NULL);
+ val->SetNULL();
+ }
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::ValidObject(CBObject *Object) {
+ if (!Object) return false;
+ if (Object == this) return true;
+
+ for (int i = 0; i < m_RegObjects.GetSize(); i++) {
+ if (m_RegObjects[i] == Object) return true;
+ }
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::PublishNatives() {
+ if (!m_ScEngine || !m_ScEngine->m_CompilerAvailable) return;
+
+ m_ScEngine->ExtDefineFunction("LOG");
+ m_ScEngine->ExtDefineFunction("String");
+ m_ScEngine->ExtDefineFunction("MemBuffer");
+ m_ScEngine->ExtDefineFunction("File");
+ m_ScEngine->ExtDefineFunction("Date");
+ m_ScEngine->ExtDefineFunction("Array");
+ m_ScEngine->ExtDefineFunction("TcpClient");
+ m_ScEngine->ExtDefineFunction("Object");
+ //m_ScEngine->ExtDefineFunction("Game");
+ m_ScEngine->ExtDefineFunction("Sleep");
+ m_ScEngine->ExtDefineFunction("WaitFor");
+ m_ScEngine->ExtDefineFunction("Random");
+ m_ScEngine->ExtDefineFunction("SetScriptTimeSlice");
+ m_ScEngine->ExtDefineFunction("MakeRGBA");
+ m_ScEngine->ExtDefineFunction("MakeRGB");
+ m_ScEngine->ExtDefineFunction("MakeHSL");
+ m_ScEngine->ExtDefineFunction("RGB");
+ m_ScEngine->ExtDefineFunction("GetRValue");
+ m_ScEngine->ExtDefineFunction("GetGValue");
+ m_ScEngine->ExtDefineFunction("GetBValue");
+ m_ScEngine->ExtDefineFunction("GetAValue");
+ m_ScEngine->ExtDefineFunction("GetHValue");
+ m_ScEngine->ExtDefineFunction("GetSValue");
+ m_ScEngine->ExtDefineFunction("GetLValue");
+ m_ScEngine->ExtDefineFunction("Debug");
+
+ m_ScEngine->ExtDefineFunction("ToString");
+ m_ScEngine->ExtDefineFunction("ToInt");
+ m_ScEngine->ExtDefineFunction("ToBool");
+ m_ScEngine->ExtDefineFunction("ToFloat");
+
+ m_ScEngine->ExtDefineVariable("Game");
+ m_ScEngine->ExtDefineVariable("Math");
+ m_ScEngine->ExtDefineVariable("Directory");
+ m_ScEngine->ExtDefineVariable("self");
+ m_ScEngine->ExtDefineVariable("this");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::ExternalCall(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ CScValue *this_obj;
+
+ //////////////////////////////////////////////////////////////////////////
+ // LOG
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "LOG") == 0) {
+ Stack->CorrectParams(1);
+ Game->LOG(0, "sc: %s", Stack->Pop()->GetString());
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // String
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "String") == 0) {
+ this_obj = ThisStack->GetTop();
+
+ this_obj->SetNative(new CSXString(Game, Stack));
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MemBuffer
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MemBuffer") == 0) {
+ this_obj = ThisStack->GetTop();
+
+ this_obj->SetNative(new CSXMemBuffer(Game, Stack));
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // File
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "File") == 0) {
+ this_obj = ThisStack->GetTop();
+
+ this_obj->SetNative(new CSXFile(Game, Stack));
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Date
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Date") == 0) {
+ this_obj = ThisStack->GetTop();
+
+ this_obj->SetNative(new CSXDate(Game, Stack));
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Array
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Array") == 0) {
+ this_obj = ThisStack->GetTop();
+
+ this_obj->SetNative(new CSXArray(Game, Stack));
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Object
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Object") == 0) {
+ this_obj = ThisStack->GetTop();
+
+ this_obj->SetNative(new CSXObject(Game, Stack));
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Sleep
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Sleep") == 0) {
+ Stack->CorrectParams(1);
+
+ Script->Sleep((uint32)Stack->Pop()->GetInt());
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // WaitFor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "WaitFor") == 0) {
+ Stack->CorrectParams(1);
+
+ CBScriptable *obj = Stack->Pop()->GetNative();
+ if (ValidObject((CBObject *)obj)) Script->WaitForExclusive((CBObject *)obj);
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Random
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Random") == 0) {
+ Stack->CorrectParams(2);
+
+ int from = Stack->Pop()->GetInt();
+ int to = Stack->Pop()->GetInt();
+
+ Stack->PushInt(CBUtils::RandomInt(from, to));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetScriptTimeSlice
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetScriptTimeSlice") == 0) {
+ Stack->CorrectParams(1);
+
+ Script->m_TimeSlice = (uint32)Stack->Pop()->GetInt();
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MakeRGBA / MakeRGB / RGB
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MakeRGBA") == 0 || strcmp(Name, "MakeRGB") == 0 || strcmp(Name, "RGB") == 0) {
+ Stack->CorrectParams(4);
+ int r = Stack->Pop()->GetInt();
+ int g = Stack->Pop()->GetInt();
+ int b = Stack->Pop()->GetInt();
+ int a;
+ CScValue *val = Stack->Pop();
+ if (val->IsNULL()) a = 255;
+ else a = val->GetInt();
+
+ Stack->PushInt(DRGBA(r, g, b, a));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MakeHSL
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MakeHSL") == 0) {
+ Stack->CorrectParams(3);
+ int h = Stack->Pop()->GetInt();
+ int s = Stack->Pop()->GetInt();
+ int l = Stack->Pop()->GetInt();
+
+ Stack->PushInt(CBUtils::HSLtoRGB(h, s, l));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetRValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetRValue") == 0) {
+ Stack->CorrectParams(1);
+
+ uint32 rgba = (uint32)Stack->Pop()->GetInt();
+ Stack->PushInt(D3DCOLGetR(rgba));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetGValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetGValue") == 0) {
+ Stack->CorrectParams(1);
+
+ uint32 rgba = (uint32)Stack->Pop()->GetInt();
+ Stack->PushInt(D3DCOLGetG(rgba));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetBValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetBValue") == 0) {
+ Stack->CorrectParams(1);
+
+ uint32 rgba = (uint32)Stack->Pop()->GetInt();
+ Stack->PushInt(D3DCOLGetB(rgba));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetAValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetAValue") == 0) {
+ Stack->CorrectParams(1);
+
+ uint32 rgba = (uint32)Stack->Pop()->GetInt();
+ Stack->PushInt(D3DCOLGetA(rgba));
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetHValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetHValue") == 0) {
+ Stack->CorrectParams(1);
+ uint32 rgb = (uint32)Stack->Pop()->GetInt();
+
+ byte H, S, L;
+ CBUtils::RGBtoHSL(rgb, &H, &S, &L);
+ Stack->PushInt(H);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetSValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetSValue") == 0) {
+ Stack->CorrectParams(1);
+ uint32 rgb = (uint32)Stack->Pop()->GetInt();
+
+ byte H, S, L;
+ CBUtils::RGBtoHSL(rgb, &H, &S, &L);
+ Stack->PushInt(S);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetLValue
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetLValue") == 0) {
+ Stack->CorrectParams(1);
+ uint32 rgb = (uint32)Stack->Pop()->GetInt();
+
+ byte H, S, L;
+ CBUtils::RGBtoHSL(rgb, &H, &S, &L);
+ Stack->PushInt(L);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Debug
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Debug") == 0) {
+ Stack->CorrectParams(0);
+
+ if (Game->GetDebugMgr()->m_Enabled) {
+ Game->GetDebugMgr()->OnScriptHitBreakpoint(Script);
+ Script->Sleep(0);
+ }
+ Stack->PushNULL();
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToString
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ToString") == 0) {
+ Stack->CorrectParams(1);
+ char *Str = Stack->Pop()->GetString();
+ char *Str2 = new char[strlen(Str) + 1];
+ strcpy(Str2, Str);
+ Stack->PushString(Str2);
+ delete [] Str2;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToInt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ToInt") == 0) {
+ Stack->CorrectParams(1);
+ int Val = Stack->Pop()->GetInt();
+ Stack->PushInt(Val);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToFloat
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ToFloat") == 0) {
+ Stack->CorrectParams(1);
+ double Val = Stack->Pop()->GetFloat();
+ Stack->PushFloat(Val);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ToBool
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ToBool") == 0) {
+ Stack->CorrectParams(1);
+ bool Val = Stack->Pop()->GetBool();
+ Stack->PushBool(Val);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // failure
+ else {
+ Script->RuntimeError("Call to undefined function '%s'. Ignored.", Name);
+ Stack->CorrectParams(0);
+ Stack->PushNULL();
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::ShowCursor() {
+ if (m_CursorHidden) return S_OK;
+
+ if (!m_Interactive && Game->m_State == GAME_RUNNING) {
+ if (m_CursorNoninteractive) return DrawCursor(m_CursorNoninteractive);
+ } else {
+ if (m_ActiveObject && !FAILED(m_ActiveObject->ShowCursor())) return S_OK;
+ else {
+ if (m_ActiveObject && m_ActiveCursor && m_ActiveObject->GetExtendedFlag("usable")) return DrawCursor(m_ActiveCursor);
+ else if (m_Cursor) return DrawCursor(m_Cursor);
+ }
+ }
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::SaveGame(int slot, char *desc, bool quickSave) {
+ char Filename[MAX_PATH + 1];
+ GetSaveSlotFilename(slot, Filename);
+
+ LOG(0, "Saving game '%s'...", Filename);
+
+ Game->ApplyEvent("BeforeSave", true);
+
+ HRESULT ret;
+
+ m_IndicatorDisplay = true;
+ m_IndicatorProgress = 0;
+ CBPersistMgr *pm = new CBPersistMgr(Game);
+ if (FAILED(ret = pm->InitSave(desc))) goto save_finish;
+
+ if (!quickSave) {
+ delete m_SaveLoadImage;
+ m_SaveLoadImage = NULL;
+ if (m_SaveImageName) {
+ m_SaveLoadImage = new CBSurfaceSDL(this);
+
+ if (!m_SaveLoadImage || FAILED(m_SaveLoadImage->Create(m_SaveImageName, true, 0, 0, 0))) {
+ delete m_SaveLoadImage;
+ m_SaveLoadImage = NULL;
+ }
+ }
+ }
+
+ if (FAILED(ret = CSysClassRegistry::GetInstance()->SaveTable(Game, pm, quickSave))) goto save_finish;
+ if (FAILED(ret = CSysClassRegistry::GetInstance()->SaveInstances(Game, pm, quickSave))) goto save_finish;
+ if (FAILED(ret = pm->SaveFile(Filename))) goto save_finish;
+
+ m_Registry->WriteInt("System", "MostRecentSaveSlot", slot);
+
+save_finish:
+ delete pm;
+ m_IndicatorDisplay = false;
+
+ delete m_SaveLoadImage;
+ m_SaveLoadImage = NULL;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::LoadGame(int Slot) {
+ //Game->LOG(0, "Load start %d", CBUtils::GetUsedMemMB());
+
+ m_Loading = false;
+ m_ScheduledLoadSlot = -1;
+
+ char Filename[MAX_PATH + 1];
+ GetSaveSlotFilename(Slot, Filename);
+
+ return LoadGame(Filename);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::LoadGame(char *Filename) {
+ LOG(0, "Loading game '%s'...", Filename);
+ GetDebugMgr()->OnGameShutdown();
+
+ HRESULT ret;
+
+ delete m_SaveLoadImage;
+ m_SaveLoadImage = NULL;
+ if (m_LoadImageName) {
+ m_SaveLoadImage = new CBSurfaceSDL(this);
+
+ if (!m_SaveLoadImage || FAILED(m_SaveLoadImage->Create(m_LoadImageName, true, 0, 0, 0))) {
+ delete m_SaveLoadImage;
+ m_SaveLoadImage = NULL;
+ }
+ }
+
+
+ m_LoadInProgress = true;
+ m_IndicatorDisplay = true;
+ m_IndicatorProgress = 0;
+ CBPersistMgr *pm = new CBPersistMgr(Game);
+ m_DEBUG_AbsolutePathWarning = false;
+ if (FAILED(ret = pm->InitLoad(Filename))) goto load_finish;
+
+ //if(FAILED(ret = Cleanup())) goto load_finish;
+ if (FAILED(ret = CSysClassRegistry::GetInstance()->LoadTable(Game, pm))) goto load_finish;
+ if (FAILED(ret = CSysClassRegistry::GetInstance()->LoadInstances(Game, pm))) goto load_finish;
+
+ // data initialization after load
+ InitAfterLoad();
+
+ Game->ApplyEvent("AfterLoad", true);
+
+ DisplayContent(true, false);
+ //m_Renderer->Flip();
+
+ GetDebugMgr()->OnGameInit();
+
+load_finish:
+ m_DEBUG_AbsolutePathWarning = true;
+
+ m_IndicatorDisplay = false;
+ delete pm;
+ m_LoadInProgress = false;
+
+ delete m_SaveLoadImage;
+ m_SaveLoadImage = NULL;
+
+ //Game->LOG(0, "Load end %d", CBUtils::GetUsedMemMB());
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::InitAfterLoad() {
+ CSysClassRegistry::GetInstance()->EnumInstances(AfterLoadRegion, "CBRegion", NULL);
+ CSysClassRegistry::GetInstance()->EnumInstances(AfterLoadSubFrame, "CBSubFrame", NULL);
+ CSysClassRegistry::GetInstance()->EnumInstances(AfterLoadSound, "CBSound", NULL);
+ CSysClassRegistry::GetInstance()->EnumInstances(AfterLoadFont, "CBFontTT", NULL);
+ CSysClassRegistry::GetInstance()->EnumInstances(AfterLoadScript, "CScScript", NULL);
+
+ m_ScEngine->RefreshScriptBreakpoints();
+ if (m_Store) m_Store->AfterLoad();
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AfterLoadRegion(void *Region, void *Data) {
+ ((CBRegion *)Region)->CreateRegion();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AfterLoadSubFrame(void *Subframe, void *Data) {
+ ((CBSubFrame *)Subframe)->SetSurfaceSimple();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AfterLoadSound(void *Sound, void *Data) {
+ ((CBSound *)Sound)->SetSoundSimple();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AfterLoadFont(void *Font, void *Data) {
+ ((CBFontTT *)Font)->AfterLoad();
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AfterLoadScript(void *script, void *data) {
+ ((CScScript *)script)->AfterLoad();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DisplayWindows(bool InGame) {
+ HRESULT res;
+
+ int i;
+
+ // did we lose focus? focus topmost window
+ if (m_FocusedWindow == NULL || !m_FocusedWindow->m_Visible || m_FocusedWindow->m_Disable) {
+ m_FocusedWindow = NULL;
+ for (i = m_Windows.GetSize() - 1; i >= 0; i--) {
+ if (m_Windows[i]->m_Visible && !m_Windows[i]->m_Disable) {
+ m_FocusedWindow = m_Windows[i];
+ break;
+ }
+ }
+ }
+
+ // display all windows
+ for (i = 0; i < m_Windows.GetSize(); i++) {
+ if (m_Windows[i]->m_Visible && m_Windows[i]->m_InGame == InGame) {
+
+ res = m_Windows[i]->Display();
+ if (FAILED(res)) return res;
+ }
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::PlayMusic(int Channel, char *Filename, bool Looping, uint32 LoopStart) {
+ if (Channel >= NUM_MUSIC_CHANNELS) {
+ Game->LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", Channel, NUM_MUSIC_CHANNELS);
+ return E_FAIL;
+ }
+
+ delete m_Music[Channel];
+ m_Music[Channel] = NULL;
+
+ m_Music[Channel] = new CBSound(Game);
+ if (m_Music[Channel] && SUCCEEDED(m_Music[Channel]->SetSound(Filename, SOUND_MUSIC, true))) {
+ if (m_MusicStartTime[Channel]) {
+ m_Music[Channel]->SetPositionTime(m_MusicStartTime[Channel]);
+ m_MusicStartTime[Channel] = 0;
+ }
+ if (LoopStart) m_Music[Channel]->SetLoopStart(LoopStart);
+ return m_Music[Channel]->Play(Looping);
+ } else {
+ delete m_Music[Channel];
+ m_Music[Channel] = NULL;
+ return E_FAIL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::StopMusic(int Channel) {
+ if (Channel >= NUM_MUSIC_CHANNELS) {
+ Game->LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", Channel, NUM_MUSIC_CHANNELS);
+ return E_FAIL;
+ }
+
+ if (m_Music[Channel]) {
+ m_Music[Channel]->Stop();
+ delete m_Music[Channel];
+ m_Music[Channel] = NULL;
+ return S_OK;
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::PauseMusic(int Channel) {
+ if (Channel >= NUM_MUSIC_CHANNELS) {
+ Game->LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", Channel, NUM_MUSIC_CHANNELS);
+ return E_FAIL;
+ }
+
+ if (m_Music[Channel]) return m_Music[Channel]->Pause();
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::ResumeMusic(int Channel) {
+ if (Channel >= NUM_MUSIC_CHANNELS) {
+ Game->LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", Channel, NUM_MUSIC_CHANNELS);
+ return E_FAIL;
+ }
+
+ if (m_Music[Channel]) return m_Music[Channel]->Resume();
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::SetMusicStartTime(int Channel, uint32 Time) {
+
+ if (Channel >= NUM_MUSIC_CHANNELS) {
+ Game->LOG(0, "**Error** Attempting to use music channel %d (max num channels: %d)", Channel, NUM_MUSIC_CHANNELS);
+ return E_FAIL;
+ }
+
+ m_MusicStartTime[Channel] = Time;
+ if (m_Music[Channel] && m_Music[Channel]->IsPlaying()) return m_Music[Channel]->SetPositionTime(Time);
+ else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::LoadSettings(char *Filename) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(SETTINGS)
+ TOKEN_TABLE(GAME)
+ TOKEN_TABLE(STRING_TABLE)
+ TOKEN_TABLE(RESOLUTION)
+ TOKEN_TABLE(REQUIRE_3D_ACCELERATION)
+ TOKEN_TABLE(REQUIRE_SOUND)
+ TOKEN_TABLE(HWTL_MODE)
+ TOKEN_TABLE(ALLOW_WINDOWED_MODE)
+ TOKEN_TABLE(ALLOW_ACCESSIBILITY_TAB)
+ TOKEN_TABLE(ALLOW_ABOUT_TAB)
+ TOKEN_TABLE(ALLOW_ADVANCED)
+ TOKEN_TABLE(ALLOW_DESKTOP_RES)
+ TOKEN_TABLE(REGISTRY_PATH)
+ TOKEN_TABLE(RICH_SAVED_GAMES)
+ TOKEN_TABLE(SAVED_GAME_EXT)
+ TOKEN_TABLE(GUID)
+ TOKEN_TABLE_END
+
+
+ byte *OrigBuffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (OrigBuffer == NULL) {
+ Game->LOG(0, "CBGame::LoadSettings failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret = S_OK;
+
+ byte *Buffer = OrigBuffer;
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_SETTINGS) {
+ Game->LOG(0, "'SETTINGS' keyword expected in game settings file.");
+ return E_FAIL;
+ }
+ Buffer = params;
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_GAME:
+ SAFE_DELETE_ARRAY(m_SettingsGameFile);
+ m_SettingsGameFile = new char[strlen((char *)params) + 1];
+ if (m_SettingsGameFile) strcpy(m_SettingsGameFile, (char *)params);
+ break;
+
+ case TOKEN_STRING_TABLE:
+ if (FAILED(m_StringTable->LoadFile((char *)params))) cmd = PARSERR_GENERIC;
+ break;
+
+ case TOKEN_RESOLUTION:
+ parser.ScanStr((char *)params, "%d,%d", &m_SettingsResWidth, &m_SettingsResHeight);
+ break;
+
+ case TOKEN_REQUIRE_3D_ACCELERATION:
+ parser.ScanStr((char *)params, "%b", &m_SettingsRequireAcceleration);
+ break;
+
+ case TOKEN_REQUIRE_SOUND:
+ parser.ScanStr((char *)params, "%b", &m_SettingsRequireSound);
+ break;
+
+ case TOKEN_HWTL_MODE:
+ parser.ScanStr((char *)params, "%d", &m_SettingsTLMode);
+ break;
+
+ case TOKEN_ALLOW_WINDOWED_MODE:
+ parser.ScanStr((char *)params, "%b", &m_SettingsAllowWindowed);
+ break;
+
+ case TOKEN_ALLOW_DESKTOP_RES:
+ parser.ScanStr((char *)params, "%b", &m_SettingsAllowDesktopRes);
+ break;
+
+ case TOKEN_ALLOW_ADVANCED:
+ parser.ScanStr((char *)params, "%b", &m_SettingsAllowAdvanced);
+ break;
+
+ case TOKEN_ALLOW_ACCESSIBILITY_TAB:
+ parser.ScanStr((char *)params, "%b", &m_SettingsAllowAccessTab);
+ break;
+
+ case TOKEN_ALLOW_ABOUT_TAB:
+ parser.ScanStr((char *)params, "%b", &m_SettingsAllowAboutTab);
+ break;
+
+ case TOKEN_REGISTRY_PATH:
+ m_Registry->SetBasePath((char *)params);
+ break;
+
+ case TOKEN_RICH_SAVED_GAMES:
+ parser.ScanStr((char *)params, "%b", &m_RichSavedGames);
+ break;
+
+ case TOKEN_SAVED_GAME_EXT:
+ CBUtils::SetString(&m_SavedGameExt, (char *)params);
+ break;
+
+ case TOKEN_GUID:
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in game settings '%s'", Filename);
+ ret = E_FAIL;
+ }
+ if (cmd == PARSERR_GENERIC) {
+ Game->LOG(0, "Error loading game settings '%s'", Filename);
+ ret = E_FAIL;
+ }
+
+ m_SettingsAllowWindowed = m_Registry->ReadBool("Debug", "AllowWindowed", m_SettingsAllowWindowed);
+ m_CompressedSavegames = m_Registry->ReadBool("Debug", "CompressedSavegames", m_CompressedSavegames);
+ //m_CompressedSavegames = false;
+
+ delete [] OrigBuffer;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Persist(CBPersistMgr *PersistMgr) {
+ if (!PersistMgr->m_Saving) Cleanup();
+
+ CBObject::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_ActiveObject));
+ PersistMgr->Transfer(TMEMBER(m_CapturedObject));
+ PersistMgr->Transfer(TMEMBER(m_CursorNoninteractive));
+ PersistMgr->Transfer(TMEMBER(m_DoNotExpandStrings));
+ PersistMgr->Transfer(TMEMBER(m_EditorMode));
+ PersistMgr->Transfer(TMEMBER(m_Fader));
+ PersistMgr->Transfer(TMEMBER(m_FreezeLevel));
+ PersistMgr->Transfer(TMEMBER(m_FocusedWindow));
+ PersistMgr->Transfer(TMEMBER(m_FontStorage));
+ PersistMgr->Transfer(TMEMBER(m_Interactive));
+ PersistMgr->Transfer(TMEMBER(m_KeyboardState));
+ PersistMgr->Transfer(TMEMBER(m_LastTime));
+ PersistMgr->Transfer(TMEMBER(m_MainObject));
+ for (int i = 0; i < NUM_MUSIC_CHANNELS; i++) {
+ PersistMgr->Transfer(TMEMBER(m_Music[i]));
+ PersistMgr->Transfer(TMEMBER(m_MusicStartTime[i]));
+ }
+
+ PersistMgr->Transfer(TMEMBER(m_OffsetX));
+ PersistMgr->Transfer(TMEMBER(m_OffsetY));
+ PersistMgr->Transfer(TMEMBER(m_OffsetPercentX));
+ PersistMgr->Transfer(TMEMBER(m_OffsetPercentY));
+
+ PersistMgr->Transfer(TMEMBER(m_OrigInteractive));
+ PersistMgr->Transfer(TMEMBER_INT(m_OrigState));
+ PersistMgr->Transfer(TMEMBER(m_PersonalizedSave));
+ PersistMgr->Transfer(TMEMBER(m_Quitting));
+
+ m_RegObjects.Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_ScEngine));
+ //PersistMgr->Transfer(TMEMBER(m_SoundMgr));
+ PersistMgr->Transfer(TMEMBER_INT(m_State));
+ //PersistMgr->Transfer(TMEMBER(m_SurfaceStorage));
+ PersistMgr->Transfer(TMEMBER(m_Subtitles));
+ PersistMgr->Transfer(TMEMBER(m_SubtitlesSpeed));
+ PersistMgr->Transfer(TMEMBER(m_SystemFont));
+ PersistMgr->Transfer(TMEMBER(m_VideoFont));
+ PersistMgr->Transfer(TMEMBER(m_VideoSubtitles));
+
+ PersistMgr->Transfer(TMEMBER(m_Timer));
+ PersistMgr->Transfer(TMEMBER(m_TimerDelta));
+ PersistMgr->Transfer(TMEMBER(m_TimerLast));
+
+ PersistMgr->Transfer(TMEMBER(m_LiveTimer));
+ PersistMgr->Transfer(TMEMBER(m_LiveTimerDelta));
+ PersistMgr->Transfer(TMEMBER(m_LiveTimerLast));
+
+ PersistMgr->Transfer(TMEMBER(m_MusicCrossfadeRunning));
+ PersistMgr->Transfer(TMEMBER(m_MusicCrossfadeStartTime));
+ PersistMgr->Transfer(TMEMBER(m_MusicCrossfadeLength));
+ PersistMgr->Transfer(TMEMBER(m_MusicCrossfadeChannel1));
+ PersistMgr->Transfer(TMEMBER(m_MusicCrossfadeChannel2));
+ PersistMgr->Transfer(TMEMBER(m_MusicCrossfadeSwap));
+
+ PersistMgr->Transfer(TMEMBER(m_LoadImageName));
+ PersistMgr->Transfer(TMEMBER(m_SaveImageName));
+ PersistMgr->Transfer(TMEMBER(m_SaveImageX));
+ PersistMgr->Transfer(TMEMBER(m_SaveImageY));
+ PersistMgr->Transfer(TMEMBER(m_LoadImageX));
+ PersistMgr->Transfer(TMEMBER(m_LoadImageY));
+
+ PersistMgr->Transfer(TMEMBER_INT(m_TextEncoding));
+ PersistMgr->Transfer(TMEMBER(m_TextRTL));
+
+ PersistMgr->Transfer(TMEMBER(m_SoundBufferSizeSec));
+ PersistMgr->Transfer(TMEMBER(m_SuspendedRendering));
+
+ PersistMgr->Transfer(TMEMBER(m_MouseLockRect));
+
+ m_Windows.Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_SuppressScriptErrors));
+ PersistMgr->Transfer(TMEMBER(m_AutorunDisabled));
+
+ PersistMgr->Transfer(TMEMBER(m_AutoSaveOnExit));
+ PersistMgr->Transfer(TMEMBER(m_AutoSaveSlot));
+ PersistMgr->Transfer(TMEMBER(m_CursorHidden));
+
+ if (PersistMgr->CheckVersion(1, 0, 1))
+ PersistMgr->Transfer(TMEMBER(m_Store));
+ else
+ m_Store = NULL;
+
+ if (!PersistMgr->m_Saving) m_Quitting = false;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::FocusWindow(CUIWindow *Window) {
+ CUIWindow *Prev = m_FocusedWindow;
+
+ int i;
+ for (i = 0; i < m_Windows.GetSize(); i++) {
+ if (m_Windows[i] == Window) {
+ if (i < m_Windows.GetSize() - 1) {
+ m_Windows.RemoveAt(i);
+ m_Windows.Add(Window);
+
+ Game->m_FocusedWindow = Window;
+ }
+
+ if (Window->m_Mode == WINDOW_NORMAL && Prev != Window && Game->ValidObject(Prev) && (Prev->m_Mode == WINDOW_EXCLUSIVE || Prev->m_Mode == WINDOW_SYSTEM_EXCLUSIVE))
+ return FocusWindow(Prev);
+ else return S_OK;
+ }
+ }
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Freeze(bool IncludingMusic) {
+ if (m_FreezeLevel == 0) {
+ m_ScEngine->PauseAll();
+ m_SoundMgr->PauseAll(IncludingMusic);
+ m_OrigState = m_State;
+ m_OrigInteractive = m_Interactive;
+ m_Interactive = true;
+ }
+ m_State = GAME_FROZEN;
+ m_FreezeLevel++;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::Unfreeze() {
+ if (m_FreezeLevel == 0) return S_OK;
+
+ m_FreezeLevel--;
+ if (m_FreezeLevel == 0) {
+ m_State = m_OrigState;
+ m_Interactive = m_OrigInteractive;
+ m_ScEngine->ResumeAll();
+ m_SoundMgr->ResumeAll();
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::HandleKeypress(SDL_Event *event) {
+#ifdef __WIN32__
+ // handle Alt+F4 on windows
+ if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_F4 && (event->key.keysym.mod == KMOD_LALT || event->key.keysym.mod == KMOD_RALT)) {
+ OnWindowClose();
+ return true;
+ }
+#endif
+
+ if (event->type == SDL_KEYDOWN && event->key.keysym.sym == SDLK_RETURN && (event->key.keysym.mod == KMOD_LALT || event->key.keysym.mod == KMOD_RALT)) {
+ m_Renderer->SwitchFullscreen();
+ return true;
+ }
+
+
+
+ m_KeyboardState->ReadKey(event);
+
+ if (m_FocusedWindow) {
+ if (!Game->m_FocusedWindow->HandleKeypress(event)) {
+ if (event->type != SDL_TEXTINPUT) {
+ if (Game->m_FocusedWindow->CanHandleEvent("Keypress"))
+ Game->m_FocusedWindow->ApplyEvent("Keypress");
+ else
+ ApplyEvent("Keypress");
+ }
+ }
+ return true;
+ } else if (event->type != SDL_TEXTINPUT) {
+ ApplyEvent("Keypress");
+ return true;
+ } else return true;
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::HandleMouseWheel(int Delta) {
+ bool Handled = false;
+ if (m_FocusedWindow) {
+ Handled = Game->m_FocusedWindow->HandleMouseWheel(Delta);
+
+ if (!Handled) {
+ if (Delta < 0 && Game->m_FocusedWindow->CanHandleEvent("MouseWheelDown")) {
+ Game->m_FocusedWindow->ApplyEvent("MouseWheelDown");
+ Handled = true;
+ } else if (Game->m_FocusedWindow->CanHandleEvent("MouseWheelUp")) {
+ Game->m_FocusedWindow->ApplyEvent("MouseWheelUp");
+ Handled = true;
+ }
+
+ }
+ }
+
+ if (!Handled) {
+ if (Delta < 0) {
+ ApplyEvent("MouseWheelDown");
+ } else {
+ ApplyEvent("MouseWheelUp");
+ }
+ }
+
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::GetVersion(byte *VerMajor, byte *VerMinor, byte *ExtMajor, byte *ExtMinor) {
+ if (VerMajor) *VerMajor = DCGF_VER_MAJOR;
+ if (VerMinor) *VerMinor = DCGF_VER_MINOR;
+
+ if (ExtMajor) *ExtMajor = 0;
+ if (ExtMinor) *ExtMinor = 0;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::SetWindowTitle() {
+ if (m_Renderer) {
+ char Title[512];
+ strcpy(Title, m_Caption[0]);
+ if (Title[0] != '\0') strcat(Title, " - ");
+ strcat(Title, "WME Lite");
+
+
+ Utf8String title;
+ if (m_TextEncoding == TEXT_UTF8) {
+ title = Utf8String(Title);
+ } else {
+ WideString wstr = StringUtil::AnsiToWide(Title);
+ title = StringUtil::WideToUtf8(wstr);
+ }
+
+ CBRenderSDL *renderer = static_cast<CBRenderSDL *>(m_Renderer);
+ SDL_SetWindowTitle(renderer->GetSdlWindow(), title.c_str());
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::GetSaveSlotFilename(int Slot, char *Buffer) {
+ AnsiString dataDir = GetDataDir();
+ sprintf(Buffer, "%s/save%03d.%s", dataDir.c_str(), Slot, m_SavedGameExt);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString CBGame::GetDataDir() {
+ AnsiString userDir = PathUtil::GetUserDirectory();
+#ifdef __IPHONEOS__
+ return userDir;
+#else
+ AnsiString baseDir = m_Registry->GetBasePath();
+ return PathUtil::Combine(userDir, baseDir);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::GetSaveSlotDescription(int Slot, char *Buffer) {
+ Buffer[0] = '\0';
+
+ char Filename[MAX_PATH + 1];
+ GetSaveSlotFilename(Slot, Filename);
+ CBPersistMgr *pm = new CBPersistMgr(Game);
+ if (!pm) return E_FAIL;
+
+ m_DEBUG_AbsolutePathWarning = false;
+ if (FAILED(pm->InitLoad(Filename))) {
+ m_DEBUG_AbsolutePathWarning = true;
+ delete pm;
+ return E_FAIL;
+ }
+
+ m_DEBUG_AbsolutePathWarning = true;
+ strcpy(Buffer, pm->m_SavedDescription);
+ delete pm;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::IsSaveSlotUsed(int Slot) {
+ char Filename[MAX_PATH + 1];
+ GetSaveSlotFilename(Slot, Filename);
+
+ CBFile *File = m_FileManager->OpenFile(Filename, false);
+ if (!File) return false;
+
+ m_FileManager->CloseFile(File);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::EmptySaveSlot(int Slot) {
+ char Filename[MAX_PATH + 1];
+ GetSaveSlotFilename(Slot, Filename);
+
+ CBPlatform::DeleteFile(Filename);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::SetActiveObject(CBObject *Obj) {
+ // not-active when game is frozen
+ if (Obj && !Game->m_Interactive && !Obj->m_NonIntMouseEvents) {
+ Obj = NULL;
+ }
+
+ if (Obj == m_ActiveObject) return S_OK;
+
+ if (m_ActiveObject) m_ActiveObject->ApplyEvent("MouseLeave");
+ //if(ValidObject(m_ActiveObject)) m_ActiveObject->ApplyEvent("MouseLeave");
+ m_ActiveObject = Obj;
+ if (m_ActiveObject) {
+ m_ActiveObject->ApplyEvent("MouseEntry");
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::PushViewport(CBViewport *Viewport) {
+ m_ViewportSP++;
+ if (m_ViewportSP >= m_ViewportStack.GetSize()) m_ViewportStack.Add(Viewport);
+ else m_ViewportStack[m_ViewportSP] = Viewport;
+
+ m_Renderer->SetViewport(Viewport->GetRect());
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::PopViewport() {
+ m_ViewportSP--;
+ if (m_ViewportSP < -1) Game->LOG(0, "Fatal: Viewport stack underflow!");
+
+ if (m_ViewportSP >= 0 && m_ViewportSP < m_ViewportStack.GetSize()) m_Renderer->SetViewport(m_ViewportStack[m_ViewportSP]->GetRect());
+ else m_Renderer->SetViewport(m_Renderer->m_DrawOffsetX,
+ m_Renderer->m_DrawOffsetY,
+ m_Renderer->m_Width + m_Renderer->m_DrawOffsetX,
+ m_Renderer->m_Height + m_Renderer->m_DrawOffsetY);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::GetCurrentViewportRect(RECT *Rect, bool *Custom) {
+ if (Rect == NULL) return E_FAIL;
+ else {
+ if (m_ViewportSP >= 0) {
+ CBPlatform::CopyRect(Rect, m_ViewportStack[m_ViewportSP]->GetRect());
+ if (Custom) *Custom = true;
+ } else {
+ CBPlatform::SetRect(Rect, m_Renderer->m_DrawOffsetX,
+ m_Renderer->m_DrawOffsetY,
+ m_Renderer->m_Width + m_Renderer->m_DrawOffsetX,
+ m_Renderer->m_Height + m_Renderer->m_DrawOffsetY);
+ if (Custom) *Custom = false;
+ }
+
+ return S_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::GetCurrentViewportOffset(int *OffsetX, int *OffsetY) {
+ if (m_ViewportSP >= 0) {
+ if (OffsetX) *OffsetX = m_ViewportStack[m_ViewportSP]->m_OffsetX;
+ if (OffsetY) *OffsetY = m_ViewportStack[m_ViewportSP]->m_OffsetY;
+ } else {
+ if (OffsetX) *OffsetX = 0;
+ if (OffsetY) *OffsetY = 0;
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::WindowLoadHook(CUIWindow *Win, char **Buf, char **Params) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::WindowScriptMethodHook(CUIWindow *Win, CScScript *Script, CScStack *Stack, char *Name) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::SetInteractive(bool State) {
+ m_Interactive = State;
+ if (m_TransMgr) m_TransMgr->m_OrigInteractive = State;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::ResetMousePos() {
+ POINT p;
+ p.x = m_MousePos.x + m_Renderer->m_DrawOffsetX;
+ p.y = m_MousePos.y + m_Renderer->m_DrawOffsetY;
+
+ CBPlatform::SetCursorPos(p.x, p.y);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::SetResourceModule(HMODULE ResModule) {
+ m_ResourceModule = ResModule;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DisplayContent(bool Update, bool DisplayAll) {
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DisplayContentSimple() {
+ // fill black
+ m_Renderer->Fill(0, 0, 0);
+ if (m_IndicatorDisplay) DisplayIndicator();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DisplayIndicator() {
+ if (m_SaveLoadImage) {
+ RECT rc;
+ CBPlatform::SetRect(&rc, 0, 0, m_SaveLoadImage->GetWidth(), m_SaveLoadImage->GetHeight());
+ if (m_LoadInProgress) m_SaveLoadImage->DisplayTrans(m_LoadImageX, m_LoadImageY, rc);
+ else m_SaveLoadImage->DisplayTrans(m_SaveImageX, m_SaveImageY, rc);
+ }
+
+ if (!m_IndicatorDisplay && m_IndicatorWidth <= 0 || m_IndicatorHeight <= 0) return S_OK;
+ m_Renderer->SetupLines();
+ for (int i = 0; i < m_IndicatorHeight; i++)
+ m_Renderer->DrawLine(m_IndicatorX, m_IndicatorY + i, m_IndicatorX + (int)(m_IndicatorWidth * (float)((float)m_IndicatorProgress / 100.0f)), m_IndicatorY + i, m_IndicatorColor);
+
+ m_Renderer->Setup2D();
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::UpdateMusicCrossfade() {
+ byte GlobMusicVol = m_SoundMgr->GetVolumePercent(SOUND_MUSIC);
+
+ if (!m_MusicCrossfadeRunning) return S_OK;
+ if (m_State == GAME_FROZEN) return S_OK;
+
+ if (m_MusicCrossfadeChannel1 < 0 || m_MusicCrossfadeChannel1 >= NUM_MUSIC_CHANNELS || !m_Music[m_MusicCrossfadeChannel1]) {
+ m_MusicCrossfadeRunning = false;
+ return S_OK;
+ }
+ if (m_MusicCrossfadeChannel2 < 0 || m_MusicCrossfadeChannel2 >= NUM_MUSIC_CHANNELS || !m_Music[m_MusicCrossfadeChannel2]) {
+ m_MusicCrossfadeRunning = false;
+ return S_OK;
+ }
+
+ if (!m_Music[m_MusicCrossfadeChannel1]->IsPlaying()) m_Music[m_MusicCrossfadeChannel1]->Play();
+ if (!m_Music[m_MusicCrossfadeChannel2]->IsPlaying()) m_Music[m_MusicCrossfadeChannel2]->Play();
+
+ uint32 CurrentTime = Game->m_LiveTimer - m_MusicCrossfadeStartTime;
+
+ if (CurrentTime >= m_MusicCrossfadeLength) {
+ m_MusicCrossfadeRunning = false;
+ //m_Music[m_MusicCrossfadeChannel2]->SetVolume(GlobMusicVol);
+ m_Music[m_MusicCrossfadeChannel2]->SetVolume(100);
+
+ m_Music[m_MusicCrossfadeChannel1]->Stop();
+ //m_Music[m_MusicCrossfadeChannel1]->SetVolume(GlobMusicVol);
+ m_Music[m_MusicCrossfadeChannel1]->SetVolume(100);
+
+
+ if (m_MusicCrossfadeSwap) {
+ // swap channels
+ CBSound *Dummy = m_Music[m_MusicCrossfadeChannel1];
+ int DummyInt = m_MusicStartTime[m_MusicCrossfadeChannel1];
+
+ m_Music[m_MusicCrossfadeChannel1] = m_Music[m_MusicCrossfadeChannel2];
+ m_MusicStartTime[m_MusicCrossfadeChannel1] = m_MusicStartTime[m_MusicCrossfadeChannel2];
+
+ m_Music[m_MusicCrossfadeChannel2] = Dummy;
+ m_MusicStartTime[m_MusicCrossfadeChannel2] = DummyInt;
+ }
+ } else {
+ //m_Music[m_MusicCrossfadeChannel1]->SetVolume(GlobMusicVol - (float)CurrentTime / (float)m_MusicCrossfadeLength * GlobMusicVol);
+ //m_Music[m_MusicCrossfadeChannel2]->SetVolume((float)CurrentTime / (float)m_MusicCrossfadeLength * GlobMusicVol);
+ m_Music[m_MusicCrossfadeChannel1]->SetVolume(100 - (float)CurrentTime / (float)m_MusicCrossfadeLength * 100);
+ m_Music[m_MusicCrossfadeChannel2]->SetVolume((float)CurrentTime / (float)m_MusicCrossfadeLength * 100);
+
+ //Game->QuickMessageForm("%d %d", m_Music[m_MusicCrossfadeChannel1]->GetVolume(), m_Music[m_MusicCrossfadeChannel2]->GetVolume());
+ }
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::ResetContent() {
+ m_ScEngine->ClearGlobals();
+ //m_Timer = 0;
+ //m_LiveTimer = 0;
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::DEBUG_DumpClassRegistry() {
+ FILE *f = fopen("./zz_class_reg_dump.log", "wt");
+
+ CSysClassRegistry::GetInstance()->DumpClasses(f);
+
+ fclose(f);
+ Game->QuickMessage("Classes dump completed.");
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::InvalidateDeviceObjects() {
+ for (int i = 0; i < m_RegObjects.GetSize(); i++) {
+ m_RegObjects[i]->InvalidateDeviceObjects();
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::RestoreDeviceObjects() {
+ for (int i = 0; i < m_RegObjects.GetSize(); i++) {
+ m_RegObjects[i]->RestoreDeviceObjects();
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::SetWaitCursor(char *Filename) {
+ delete m_CursorNoninteractive;
+ m_CursorNoninteractive = NULL;
+
+ m_CursorNoninteractive = new CBSprite(Game);
+ if (!m_CursorNoninteractive || FAILED(m_CursorNoninteractive->LoadFile(Filename))) {
+ delete m_CursorNoninteractive;
+ m_CursorNoninteractive = NULL;
+ return E_FAIL;
+ } else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DrawCursor(CBSprite *Cursor) {
+ if (!Cursor) return E_FAIL;
+ if (Cursor != m_LastCursor) {
+ Cursor->Reset();
+ m_LastCursor = Cursor;
+ }
+ return Cursor->Draw(m_MousePos.x, m_MousePos.y);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnActivate(bool Activate, bool RefreshMouse) {
+ if (m_ShuttingDown || !m_Renderer) return S_OK;
+
+ m_Renderer->m_Active = Activate;
+
+ if (RefreshMouse) {
+ POINT p;
+ GetMousePos(&p);
+ SetActiveObject(m_Renderer->GetObjectAt(p.x, p.y));
+ }
+
+ if (Activate) m_SoundMgr->ResumeAll();
+ else m_SoundMgr->PauseAll();
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseLeftDown() {
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_CLICK, MOUSE_BUTTON_LEFT);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("LeftClick"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("LeftClick");
+ }
+ }
+
+ if (m_ActiveObject != NULL) m_CapturedObject = m_ActiveObject;
+ m_MouseLeftDown = true;
+ CBPlatform::SetCapture(m_Renderer->m_Window);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseLeftUp() {
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_RELEASE, MOUSE_BUTTON_LEFT);
+
+ CBPlatform::ReleaseCapture();
+ m_CapturedObject = NULL;
+ m_MouseLeftDown = false;
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("LeftRelease"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("LeftRelease");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseLeftDblClick() {
+ if (m_State == GAME_RUNNING && !m_Interactive) return S_OK;
+
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_DBLCLICK, MOUSE_BUTTON_LEFT);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("LeftDoubleClick"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("LeftDoubleClick");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseRightDblClick() {
+ if (m_State == GAME_RUNNING && !m_Interactive) return S_OK;
+
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_DBLCLICK, MOUSE_BUTTON_RIGHT);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("RightDoubleClick"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("RightDoubleClick");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseRightDown() {
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_CLICK, MOUSE_BUTTON_RIGHT);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("RightClick"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("RightClick");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseRightUp() {
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_RELEASE, MOUSE_BUTTON_RIGHT);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("RightRelease"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("RightRelease");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseMiddleDown() {
+ if (m_State == GAME_RUNNING && !m_Interactive) return S_OK;
+
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_CLICK, MOUSE_BUTTON_MIDDLE);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("MiddleClick"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("MiddleClick");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnMouseMiddleUp() {
+ if (m_ActiveObject) m_ActiveObject->HandleMouse(MOUSE_RELEASE, MOUSE_BUTTON_MIDDLE);
+
+ bool Handled = m_State == GAME_RUNNING && SUCCEEDED(ApplyEvent("MiddleRelease"));
+ if (!Handled) {
+ if (m_ActiveObject != NULL) {
+ m_ActiveObject->ApplyEvent("MiddleRelease");
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnPaint() {
+ if (m_Renderer && m_Renderer->m_Windowed && m_Renderer->m_Ready) {
+ m_Renderer->InitLoop();
+ DisplayContent(false, true);
+ DisplayDebugInfo();
+ m_Renderer->WindowedBlt();
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnWindowClose() {
+ if (CanHandleEvent("QuitGame")) {
+ if (m_State != GAME_FROZEN) Game->ApplyEvent("QuitGame");
+ return S_OK;
+ } else return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::DisplayDebugInfo() {
+ char str[100];
+
+ if (m_DEBUG_ShowFPS) {
+ sprintf(str, "FPS: %d", Game->m_Fps);
+ m_SystemFont->DrawText((byte *)str, 0, 0, 100, TAL_LEFT);
+ }
+
+ if (Game->m_DEBUG_DebugMode) {
+ if (!Game->m_Renderer->m_Windowed)
+ sprintf(str, "Mode: %dx%dx%d", m_Renderer->m_Width, m_Renderer->m_Height, m_Renderer->m_BPP);
+ else
+ sprintf(str, "Mode: %dx%d windowed", m_Renderer->m_Width, m_Renderer->m_Height);
+
+ strcat(str, " (");
+ strcat(str, m_Renderer->GetName());
+ strcat(str, ")");
+ m_SystemFont->DrawText((byte *)str, 0, 0, m_Renderer->m_Width, TAL_RIGHT);
+
+ m_Renderer->DisplayDebugInfo();
+
+ int ScrTotal, ScrRunning, ScrWaiting, ScrPersistent;
+ ScrTotal = m_ScEngine->GetNumScripts(&ScrRunning, &ScrWaiting, &ScrPersistent);
+ sprintf(str, "Running scripts: %d (r:%d w:%d p:%d)", ScrTotal, ScrRunning, ScrWaiting, ScrPersistent);
+ m_SystemFont->DrawText((byte *)str, 0, 70, m_Renderer->m_Width, TAL_RIGHT);
+
+
+ sprintf(str, "Timer: %d", m_Timer);
+ Game->m_SystemFont->DrawText((byte *)str, 0, 130, m_Renderer->m_Width, TAL_RIGHT);
+
+ if (m_ActiveObject != NULL) m_SystemFont->DrawText((byte *)m_ActiveObject->m_Name, 0, 150, m_Renderer->m_Width, TAL_RIGHT);
+
+ sprintf(str, "GfxMem: %dMB", m_UsedMem / (1024 * 1024));
+ m_SystemFont->DrawText((byte *)str, 0, 170, m_Renderer->m_Width, TAL_RIGHT);
+
+ }
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBDebugger *CBGame::GetDebugMgr() {
+ if (!m_DebugMgr) m_DebugMgr = new CBDebugger(this);
+ return m_DebugMgr;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::GetMousePos(POINT *Pos) {
+ CBPlatform::GetCursorPos(Pos);
+
+ Pos->x -= m_Renderer->m_DrawOffsetX;
+ Pos->y -= m_Renderer->m_DrawOffsetY;
+
+ /*
+ // Windows can squish maximized window if it's larger than desktop
+ // so we need to modify mouse position appropriately (tnx mRax)
+ if(m_Renderer->m_Windowed && ::IsZoomed(m_Renderer->m_Window))
+ {
+ RECT rc;
+ ::GetClientRect(m_Renderer->m_Window, &rc);
+ Pos->x *= Game->m_Renderer->m_RealWidth;
+ Pos->x /= (rc.right - rc.left);
+ Pos->y *= Game->m_Renderer->m_RealHeight;
+ Pos->y /= (rc.bottom - rc.top);
+ }
+ */
+
+ if (m_MouseLockRect.left != 0 && m_MouseLockRect.right != 0 && m_MouseLockRect.top != 0 && m_MouseLockRect.bottom != 0) {
+ if (!CBPlatform::PtInRect(&m_MouseLockRect, *Pos)) {
+ Pos->x = std::max(m_MouseLockRect.left, Pos->x);
+ Pos->y = std::max(m_MouseLockRect.top, Pos->y);
+
+ Pos->x = std::min(m_MouseLockRect.right, Pos->x);
+ Pos->y = std::min(m_MouseLockRect.bottom, Pos->y);
+
+ POINT NewPos = *Pos;
+
+ NewPos.x += m_Renderer->m_DrawOffsetX;
+ NewPos.y += m_Renderer->m_DrawOffsetY;
+
+ CBPlatform::SetCursorPos(NewPos.x, NewPos.y);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::MiniUpdate() {
+ if (!m_MiniUpdateEnabled) return S_OK;
+
+ if (CBPlatform::GetTime() - m_LastMiniUpdate > 200) {
+ if (m_SoundMgr) m_SoundMgr->InitLoop();
+ m_LastMiniUpdate = CBPlatform::GetTime();
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBGame::OnScriptShutdown(CScScript *Script) {
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::IsLeftDoubleClick() {
+ return IsDoubleClick(0);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::IsRightDoubleClick() {
+ return IsDoubleClick(1);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBGame::IsDoubleClick(int buttonIndex) {
+ uint32 maxDoubleCLickTime = 500;
+ int maxMoveX = 4;
+ int maxMoveY = 4;
+
+#if __WIN32__
+ maxDoubleCLickTime = GetDoubleClickTime();
+ maxMoveX = GetSystemMetrics(SM_CXDOUBLECLK);
+ maxMoveY = GetSystemMetrics(SM_CYDOUBLECLK);
+#elif __IPHONEOS__
+ maxMoveX = 16;
+ maxMoveY = 16;
+#endif
+
+ POINT pos;
+ CBPlatform::GetCursorPos(&pos);
+
+ int moveX = abs(pos.x - m_LastClick[buttonIndex].PosX);
+ int moveY = abs(pos.y - m_LastClick[buttonIndex].PosY);
+
+
+ if (m_LastClick[buttonIndex].Time == 0 || CBPlatform::GetTime() - m_LastClick[buttonIndex].Time > maxDoubleCLickTime || moveX > maxMoveX || moveY > maxMoveY) {
+ m_LastClick[buttonIndex].Time = CBPlatform::GetTime();
+ m_LastClick[buttonIndex].PosX = pos.x;
+ m_LastClick[buttonIndex].PosY = pos.y;
+ return false;
+ } else {
+ m_LastClick[buttonIndex].Time = 0;
+ return true;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AutoSaveOnExit() {
+ m_SoundMgr->SaveSettings();
+ m_Registry->SaveValues();
+
+ if (!m_AutoSaveOnExit) return;
+ if (m_State == GAME_FROZEN) return;
+
+ SaveGame(m_AutoSaveSlot, "autosave", true);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBGame::AddMem(int bytes) {
+ m_UsedMem += bytes;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString CBGame::GetDeviceType() const {
+#ifdef __IPHONEOS__
+ char devType[128];
+ IOS_GetDeviceType(devType);
+ return AnsiString(devType);
+#else
+ return "computer";
+#endif
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BGame.h b/engines/wintermute/BGame.h
index a61ba1270d..b3df2b3046 100644
--- a/engines/wintermute/BGame.h
+++ b/engines/wintermute/BGame.h
@@ -29,10 +29,10 @@
#ifndef WINTERMUTE_BGAME_H
#define WINTERMUTE_BGAME_H
-#include "BDebugger.h"
+#include "engines/wintermute/BDebugger.h"
//#include "BSaveThumbHelper.h"
//#include "BFader.h"
-//#include "BRenderer.h"
+#include "engines/wintermute/BRenderer.h"
//#include "BSurfaceStorage.h"
#include "engines/wintermute/BObject.h"
#include "engines/wintermute/persistent.h"
@@ -53,7 +53,9 @@ class CBStringTable;
class CBQuickMsg;
class CUIWindow;
class CBViewport;
+class CBRenderer;
class CBRegistry;
+class CBSurfaceStorage;
class CSXStore;
class CSXMath;
class CBKeyboardState;
@@ -63,7 +65,7 @@ class CBKeyboardState;
class CBGame: public CBObject {
public:
DECLARE_PERSISTENT(CBGame, CBObject)
-#if 0
+
virtual HRESULT OnScriptShutdown(CScScript *Script);
virtual HRESULT OnActivate(bool Activate, bool RefreshMouse);
@@ -80,7 +82,7 @@ public:
bool IsLeftDoubleClick();
bool IsRightDoubleClick();
-#endif
+
bool m_AutorunDisabled;
uint32 m_LastMiniUpdate;
@@ -175,7 +177,7 @@ public:
#endif //TODO: STUB
CBDebugger *GetDebugMgr();
void LOG(HRESULT res, LPCSTR fmt, ...) {}
-#if 0
+
CBRenderer *m_Renderer;
CBSoundMgr *m_SoundMgr;
CScEngine *m_ScEngine;
@@ -184,6 +186,7 @@ public:
CBSurfaceStorage *m_SurfaceStorage;
CBFontStorage *m_FontStorage;
CBGame();
+#if 0
virtual ~CBGame();
void DEBUG_DebugDisable();
void DEBUG_DebugEnable(const char *Filename = NULL);
@@ -216,19 +219,17 @@ public:
char *m_SettingsGameFile;
CBFader *m_Fader;
bool m_SuppressScriptErrors;
-#if 0
+
virtual HRESULT InvalidateDeviceObjects();
virtual HRESULT RestoreDeviceObjects();
-#endif
+
virtual void PublishNatives();
virtual HRESULT ExternalCall(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name);
-#if 0
// scripting interface
virtual CScValue *ScGetProperty(char *Name);
virtual HRESULT ScSetProperty(char *Name, CScValue *Value);
virtual HRESULT ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name);
virtual char *ScToString();
-
// compatibility bits
bool m_CompatKillMethodThreads;
@@ -248,6 +249,7 @@ public:
int m_ScheduledLoadSlot;
bool m_Loading;
bool m_PersonalizedSave;
+#if 0
HRESULT EmptySaveSlot(int Slot);
bool IsSaveSlotUsed(int Slot);
HRESULT GetSaveSlotDescription(int Slot, char *Buffer);
diff --git a/engines/wintermute/BImage.cpp b/engines/wintermute/BImage.cpp
new file mode 100644
index 0000000000..6f0d0235aa
--- /dev/null
+++ b/engines/wintermute/BImage.cpp
@@ -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.
+*/
+
+#include "dcgf.h"
+#include "BImage.h"
+//#include "FreeImage.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+CBImage::CBImage(CBGame *inGame, FIBITMAP *bitmap): CBBase(inGame) {
+#if 0
+ m_Bitmap = bitmap;
+#endif
+ m_Bitmap = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBImage::~CBImage() {
+#if 0
+ if (m_Bitmap) FreeImage_Unload(m_Bitmap);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBImage::SaveBMPFile(char *Filename) {
+#if 0
+ if (!m_Bitmap) return E_FAIL;
+
+ if (FreeImage_Save(FIF_BMP, m_Bitmap, Filename)) return S_OK;
+ else return E_FAIL;
+#endif
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBImage::Resize(int NewWidth, int NewHeight) {
+#if 0
+ if (!m_Bitmap) return E_FAIL;
+
+ if (NewWidth == 0) NewWidth = FreeImage_GetWidth(m_Bitmap);
+ if (NewHeight == 0) NewHeight = FreeImage_GetHeight(m_Bitmap);
+
+
+ FIBITMAP *newImg = FreeImage_Rescale(m_Bitmap, NewWidth, NewHeight, FILTER_BILINEAR);
+ if (newImg) {
+ FreeImage_Unload(m_Bitmap);
+ m_Bitmap = newImg;
+ return S_OK;
+ } else return E_FAIL;
+#endif
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+byte *CBImage::CreateBMPBuffer(uint32 *BufferSize) {
+ if (!m_Bitmap) return NULL;
+#if 0
+ FIMEMORY *fiMem = FreeImage_OpenMemory();
+ FreeImage_SaveToMemory(FIF_PNG, m_Bitmap, fiMem);
+ uint32 size;
+ byte *data;
+ FreeImage_AcquireMemory(fiMem, &data, &size);
+
+
+ byte *Buffer = new byte[size];
+ memcpy(Buffer, data, size);
+
+ FreeImage_CloseMemory(fiMem);
+
+ if (BufferSize) *BufferSize = size;
+
+ return Buffer;
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBImage::CopyFrom(CBImage *OrigImage, int NewWidth, int NewHeight) {
+#if 0
+ if (m_Bitmap) FreeImage_Unload(m_Bitmap);
+
+ if (NewWidth == 0) NewWidth = FreeImage_GetWidth(OrigImage->GetBitmap());
+ if (NewHeight == 0) NewHeight = FreeImage_GetHeight(OrigImage->GetBitmap());
+
+ m_Bitmap = FreeImage_Rescale(OrigImage->GetBitmap(), NewWidth, NewHeight, FILTER_BILINEAR);
+#endif
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BImage.h b/engines/wintermute/BImage.h
new file mode 100644
index 0000000000..a738fb418b
--- /dev/null
+++ b/engines/wintermute/BImage.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_BIMAGE_H
+#define WINTERMUTE_BIMAGE_H
+
+
+//#include "FreeImage.h"
+#include "BBase.h"
+#include "common/endian.h"
+
+struct FIBITMAP;
+
+namespace WinterMute {
+
+class CBImage: CBBase {
+
+public:
+ CBImage(CBGame *inGame, FIBITMAP *bitmap = NULL);
+ ~CBImage();
+
+
+ byte *CreateBMPBuffer(uint32 *BufferSize = NULL);
+ HRESULT Resize(int NewWidth, int NewHeight);
+ HRESULT SaveBMPFile(char *Filename);
+ HRESULT CopyFrom(CBImage *OrigImage, int NewWidth = 0, int NewHeight = 0);
+
+ FIBITMAP *GetBitmap() const {
+ return m_Bitmap;
+ }
+private:
+ FIBITMAP *m_Bitmap;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BKeyboardState.cpp b/engines/wintermute/BKeyboardState.cpp
new file mode 100644
index 0000000000..7e89d9827c
--- /dev/null
+++ b/engines/wintermute/BKeyboardState.cpp
@@ -0,0 +1,243 @@
+/* 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 "BKeyboardState.h"
+#include "ScValue.h"
+#include "ScStack.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBKeyboardState, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBKeyboardState::CBKeyboardState(CBGame *inGame): CBScriptable(inGame) {
+ m_CurrentPrintable = false;
+ m_CurrentCharCode = 0;
+ m_CurrentKeyData = 0;
+
+ m_CurrentShift = false;
+ m_CurrentAlt = false;
+ m_CurrentControl = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBKeyboardState::~CBKeyboardState() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBKeyboardState::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ //////////////////////////////////////////////////////////////////////////
+ // IsKeyDown
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "IsKeyDown") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *val = Stack->Pop();
+ int vKey;
+
+ if (val->m_Type == VAL_STRING && strlen(val->GetString()) > 0) {
+ char *str = val->GetString();
+ if (str[0] >= 'A' && str[0] <= 'Z') str[0] += ('a' - 'A');
+ vKey = (int)str[0];
+ } else vKey = val->GetInt();
+
+ Uint8 *state = SDL_GetKeyboardState(NULL);
+ SDL_Scancode scanCode = SDL_GetScancodeFromKey(VKeyToKeyCode(vKey));
+ bool isDown = state[scanCode] > 0;
+
+ Stack->PushBool(isDown);
+ return S_OK;
+ }
+
+ else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBKeyboardState::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("keyboard");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Key
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Key") == 0) {
+ if (m_CurrentPrintable) {
+ char key[2];
+ key[0] = (char)m_CurrentCharCode;
+ key[1] = '\0';
+ m_ScValue->SetString(key);
+ } else m_ScValue->SetString("");
+
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Printable
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Printable") == 0) {
+ m_ScValue->SetBool(m_CurrentPrintable);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // KeyCode
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "KeyCode") == 0) {
+ m_ScValue->SetInt(m_CurrentCharCode);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsShift
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsShift") == 0) {
+ m_ScValue->SetBool(m_CurrentShift);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsAlt
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsAlt") == 0) {
+ m_ScValue->SetBool(m_CurrentAlt);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsControl
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsControl") == 0) {
+ m_ScValue->SetBool(m_CurrentControl);
+ return m_ScValue;
+ }
+
+ else return CBScriptable::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBKeyboardState::ScSetProperty(char *Name, CScValue *Value) {
+ /*
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if(strcmp(Name, "Name")==0){
+ SetName(Value->GetString());
+ if(m_Renderer) SetWindowText(m_Renderer->m_Window, m_Name);
+ return S_OK;
+ }
+
+ else*/ return CBScriptable::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBKeyboardState::ScToString() {
+ return "[keyboard state]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBKeyboardState::ReadKey(SDL_Event *event) {
+ m_CurrentPrintable = (event->type == SDL_TEXTINPUT);
+ m_CurrentCharCode = KeyCodeToVKey(event);
+ //m_CurrentKeyData = KeyData;
+
+ m_CurrentControl = IsControlDown();
+ m_CurrentAlt = IsAltDown();
+ m_CurrentShift = IsShiftDown();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBKeyboardState::Persist(CBPersistMgr *PersistMgr) {
+ //if(!PersistMgr->m_Saving) Cleanup();
+ CBScriptable::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_CurrentAlt));
+ PersistMgr->Transfer(TMEMBER(m_CurrentCharCode));
+ PersistMgr->Transfer(TMEMBER(m_CurrentControl));
+ PersistMgr->Transfer(TMEMBER(m_CurrentKeyData));
+ PersistMgr->Transfer(TMEMBER(m_CurrentPrintable));
+ PersistMgr->Transfer(TMEMBER(m_CurrentShift));
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBKeyboardState::IsShiftDown() {
+ int mod = SDL_GetModState();
+ return (mod & KMOD_LSHIFT) || (mod & KMOD_RSHIFT);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBKeyboardState::IsControlDown() {
+ int mod = SDL_GetModState();
+ return (mod & KMOD_LCTRL) || (mod & KMOD_RCTRL);
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBKeyboardState::IsAltDown() {
+ int mod = SDL_GetModState();
+ return (mod & KMOD_LALT) || (mod & KMOD_RALT);
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBKeyboardState::KeyCodeToVKey(SDL_Event *event) {
+ if (event->type != SDL_KEYDOWN) return 0;
+
+ switch (event->key.keysym.sym) {
+ case SDLK_KP_ENTER:
+ return SDLK_RETURN;
+ default:
+ return event->key.keysym.sym;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+SDL_Keycode CBKeyboardState::VKeyToKeyCode(uint32 vkey) {
+ // todo
+ return (SDL_Keycode)vkey;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BKeyboardState.h b/engines/wintermute/BKeyboardState.h
new file mode 100644
index 0000000000..f5ea56f055
--- /dev/null
+++ b/engines/wintermute/BKeyboardState.h
@@ -0,0 +1,71 @@
+/* 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_BKEYBOARD_STATE_H
+#define WINTERMUTE_BKEYBOARD_STATE_H
+
+
+#include "BBase.h"
+#include "BScriptable.h"
+#include <SDL.h>
+
+namespace WinterMute {
+
+class CBKeyboardState : public CBScriptable {
+public:
+ uint32 m_CurrentKeyData;
+ uint32 m_CurrentCharCode;
+ bool m_CurrentPrintable;
+
+ bool m_CurrentShift;
+ bool m_CurrentAlt;
+ bool m_CurrentControl;
+
+ DECLARE_PERSISTENT(CBKeyboardState, CBScriptable)
+ CBKeyboardState(CBGame *inGame);
+ virtual ~CBKeyboardState();
+ HRESULT ReadKey(SDL_Event *event);
+
+ static bool IsShiftDown();
+ static bool IsControlDown();
+ static bool IsAltDown();
+
+ // 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();
+
+private:
+ uint32 KeyCodeToVKey(SDL_Event *event);
+ SDL_Keycode VKeyToKeyCode(uint32 vkey);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BPackage.cpp b/engines/wintermute/BPackage.cpp
new file mode 100644
index 0000000000..d5ae12fa84
--- /dev/null
+++ b/engines/wintermute/BPackage.cpp
@@ -0,0 +1,102 @@
+/* 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 "BPackage.h"
+#include "BGame.h"
+#include "BFileManager.h"
+
+namespace WinterMute {
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+CBPackage::CBPackage(CBGame *inGame): CBBase(inGame) {
+ m_File = NULL;
+ m_Name = NULL;
+ m_CD = 0;
+ m_Priority = 0;
+ m_BoundToExe = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBPackage::~CBPackage() {
+ if (m_Name) delete [] m_Name;
+ CloseFilePointer(m_File);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPackage::Open() {
+ if (m_File) return S_OK;
+ else {
+ m_File = GetFilePointer();
+ return m_File ? S_OK : E_FAIL;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPackage::Close() {
+ if (m_File) fclose(m_File);
+ m_File = NULL;
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPackage::Read(FILE *file, uint32 offset, byte *buffer, uint32 size) {
+ HRESULT ret;
+ if (FAILED(ret = Open())) return ret;
+ else {
+ if (fseek(file, offset, SEEK_SET)) return E_FAIL;
+ if (fread(buffer, size, 1, file) != 1) return E_FAIL;
+ else return S_OK;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+FILE *CBPackage::GetFilePointer() {
+ FILE *file = Game->m_FileManager->OpenPackage(m_Name);
+ if (!file) {
+ Game->m_FileManager->RequestCD(m_CD, m_Name, "");
+ file = Game->m_FileManager->OpenPackage(m_Name);
+ }
+ return file;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBPackage::CloseFilePointer(FILE*& file) {
+ if (file) fclose(file);
+ file = NULL;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BPackage.h b/engines/wintermute/BPackage.h
new file mode 100644
index 0000000000..54f2e04a6c
--- /dev/null
+++ b/engines/wintermute/BPackage.h
@@ -0,0 +1,57 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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_BPACKAGE_H
+#define WINTERMUTE_BPACKAGE_H
+
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBPackage : public CBBase {
+public:
+ FILE *GetFilePointer();
+ void CloseFilePointer(FILE*& file);
+
+ bool m_BoundToExe;
+ byte m_Priority;
+ HRESULT Read(FILE *file, uint32 offset, byte *buffer, uint32 size);
+ HRESULT Close();
+ HRESULT Open();
+ char *m_Name;
+ int m_CD;
+ FILE *m_File;
+ CBPackage(CBGame *inGame);
+ virtual ~CBPackage();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BPkgFile.cpp b/engines/wintermute/BPkgFile.cpp
new file mode 100644
index 0000000000..1210d90e24
--- /dev/null
+++ b/engines/wintermute/BPkgFile.cpp
@@ -0,0 +1,228 @@
+/* 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 "BPackage.h"
+#include "BPkgFile.h"
+#include "BGame.h"
+#include "BFileManager.h"
+
+#if _DEBUG
+#pragma comment(lib, "zlib_d.lib")
+#else
+#pragma comment(lib, "zlib.lib")
+#endif
+
+
+extern "C" {
+#include "zlib.h"
+}
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBPkgFile::CBPkgFile(CBGame *inGame): CBFile(inGame) {
+ m_FileEntry = NULL;
+ m_File = NULL;
+ m_Compressed = false;
+
+ m_Stream.zalloc = (alloc_func)0;
+ m_Stream.zfree = (free_func)0;
+ m_Stream.opaque = (voidpf)0;
+
+ m_InflateInit = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBPkgFile::~CBPkgFile() {
+ Close();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPkgFile::Open(Common::String Filename) {
+ Close();
+
+ char fileName[MAX_PATH];
+ strcpy(fileName, Filename.c_str());
+
+ // correct slashes
+ for (int i = 0; i < strlen(fileName); i++) {
+ if (fileName[i] == '/') fileName[i] = '\\';
+ }
+
+ m_FileEntry = Game->m_FileManager->GetPackageEntry(fileName);
+ if (!m_FileEntry) return E_FAIL;
+
+ m_File = m_FileEntry->m_Package->GetFilePointer();
+ if (!m_File) return E_FAIL;
+
+
+ m_Compressed = (m_FileEntry->m_CompressedLength != 0);
+ m_Size = m_FileEntry->m_Length;
+
+ SeekToPos(0);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPkgFile::Close() {
+ if (m_FileEntry) {
+ m_FileEntry->m_Package->CloseFilePointer(m_File);
+ m_FileEntry = NULL;
+ }
+ m_File = NULL;
+
+ m_Pos = 0;
+ m_Size = 0;
+
+ if (m_InflateInit) inflateEnd(&m_Stream);
+ m_InflateInit = false;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPkgFile::Read(void *Buffer, uint32 Size) {
+ if (!m_FileEntry) return E_FAIL;
+
+ HRESULT ret = S_OK;
+
+ if (m_Pos + Size > m_Size) {
+ Size = m_Size - m_Pos;
+ if (Size == 0) return E_FAIL;
+ }
+
+ if (m_Compressed) {
+ uint32 InitOut = m_Stream.total_out;
+
+ m_Stream.avail_out = Size;
+ m_Stream.next_out = (byte *)Buffer;
+
+ while (m_Stream.total_out - InitOut < Size && m_Stream.total_in < m_FileEntry->m_CompressedLength) {
+ // needs to read more data?
+ if (m_Stream.avail_in == 0) {
+ m_Stream.avail_in = MIN(COMPRESSED_BUFFER_SIZE, m_FileEntry->m_CompressedLength - m_Stream.total_in);
+ m_FileEntry->m_Package->Read(m_File, m_FileEntry->m_Offset + m_Stream.total_in, m_CompBuffer, m_Stream.avail_in);
+ m_Stream.next_in = m_CompBuffer;
+ }
+
+ int res = inflate(&m_Stream, Z_SYNC_FLUSH);
+ if (res != Z_OK && res != Z_STREAM_END) {
+ Game->LOG(0, "zlib error: %d", res);
+ ret = E_FAIL;
+ break;
+ }
+ }
+
+
+ } else {
+ ret = m_FileEntry->m_Package->Read(m_File, m_FileEntry->m_Offset + m_Pos, (byte *)Buffer, Size);
+ }
+
+ m_Pos += Size;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPkgFile::Seek(uint32 Pos, TSeek Origin) {
+ if (!m_FileEntry) return E_FAIL;
+
+ uint32 NewPos = 0;
+
+ switch (Origin) {
+ case SEEK_TO_BEGIN:
+ NewPos = Pos;
+ break;
+ case SEEK_TO_END:
+ NewPos = m_Size + Pos;
+ break;
+ case SEEK_TO_CURRENT:
+ NewPos = m_Pos + Pos;
+ break;
+ }
+
+ if (NewPos < 0 || NewPos > m_Size) return E_FAIL;
+
+ return SeekToPos(NewPos);
+}
+
+
+#define STREAM_BUFFER_SIZE 4096
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPkgFile::SeekToPos(uint32 NewPos) {
+ HRESULT ret = S_OK;
+
+ // seek compressed stream to NewPos
+ if (m_Compressed) {
+ byte StreamBuffer[STREAM_BUFFER_SIZE];
+ if (m_InflateInit) inflateEnd(&m_Stream);
+ m_InflateInit = false;
+
+ m_Stream.avail_in = 0;
+ m_Stream.next_in = m_CompBuffer;
+ m_Stream.avail_out = MIN(STREAM_BUFFER_SIZE, NewPos);
+ m_Stream.next_out = StreamBuffer;
+ inflateInit(&m_Stream);
+ m_InflateInit = true;
+
+ while (m_Stream.total_out < NewPos && m_Stream.total_in < m_FileEntry->m_CompressedLength) {
+ // needs to read more data?
+ if (m_Stream.avail_in == 0) {
+ m_Stream.avail_in = MIN(COMPRESSED_BUFFER_SIZE, m_FileEntry->m_CompressedLength - m_Stream.total_in);
+ m_FileEntry->m_Package->Read(m_File, m_FileEntry->m_Offset + m_Stream.total_in, m_CompBuffer, m_Stream.avail_in);
+ m_Stream.next_in = m_CompBuffer;
+ }
+
+ // needs more space?
+ if (m_Stream.avail_out == 0) {
+ m_Stream.next_out = StreamBuffer;
+ m_Stream.avail_out = MIN(STREAM_BUFFER_SIZE, NewPos - m_Stream.total_out);
+ }
+
+ // stream on!
+ int res = inflate(&m_Stream, Z_SYNC_FLUSH);
+ if (res != Z_OK && res != Z_STREAM_END) {
+ ret = E_FAIL;
+ break;
+ }
+ }
+
+ }
+
+ m_Pos = NewPos;
+ return ret;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BPkgFile.h b/engines/wintermute/BPkgFile.h
new file mode 100644
index 0000000000..a00c954860
--- /dev/null
+++ b/engines/wintermute/BPkgFile.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_BPKGFILE_H
+#define WINTERMUTE_BPKGFILE_H
+
+
+#include "BFile.h"
+#include "BFileEntry.h"
+#include <zlib.h> // Added by ClassView
+
+#define COMPRESSED_BUFFER_SIZE 4096
+
+namespace WinterMute {
+
+class CBPkgFile : public CBFile {
+public:
+ CBPkgFile(CBGame *inGame);
+ virtual ~CBPkgFile();
+ virtual HRESULT Seek(uint32 Pos, TSeek Origin = SEEK_TO_BEGIN);
+ virtual HRESULT Read(void *Buffer, uint32 Size);
+ virtual HRESULT Close();
+ virtual HRESULT Open(Common::String Filename);
+private:
+ bool m_InflateInit;
+ HRESULT SeekToPos(uint32 NewPos);
+ bool m_Compressed;
+ CBFileEntry *m_FileEntry;
+ z_stream m_Stream;
+ byte m_CompBuffer[COMPRESSED_BUFFER_SIZE];
+ FILE *m_File;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BPoint.cpp b/engines/wintermute/BPoint.cpp
new file mode 100644
index 0000000000..331e9252f4
--- /dev/null
+++ b/engines/wintermute/BPoint.cpp
@@ -0,0 +1,64 @@
+/* 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 "BPoint.h"
+#include "BPersistMgr.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBPoint, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBPoint::CBPoint() {
+ x = y = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBPoint::~CBPoint() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBPoint::CBPoint(int initX, int initY) {
+ x = initX;
+ y = initY;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBPoint::Persist(CBPersistMgr *PersistMgr) {
+
+ PersistMgr->Transfer(TMEMBER(x));
+ PersistMgr->Transfer(TMEMBER(y));
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BPoint.h b/engines/wintermute/BPoint.h
new file mode 100644
index 0000000000..6cd17653d9
--- /dev/null
+++ b/engines/wintermute/BPoint.h
@@ -0,0 +1,50 @@
+/* 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_BPOINT_H
+#define WINTERMUTE_BPOINT_H
+
+#include "persistent.h"
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBPoint: public CBBase {
+public:
+ DECLARE_PERSISTENT(CBPoint, CBBase)
+ CBPoint();
+ CBPoint(int initX, int initY);
+ int y;
+ int x;
+ virtual ~CBPoint();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BQuickMsg.cpp b/engines/wintermute/BQuickMsg.cpp
new file mode 100644
index 0000000000..0f8c54f030
--- /dev/null
+++ b/engines/wintermute/BQuickMsg.cpp
@@ -0,0 +1,54 @@
+/* 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 "BQuickMsg.h"
+#include "BGame.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBQuickMsg::CBQuickMsg(CBGame *inGame, char *Text): CBBase(inGame) {
+ m_Text = new char [strlen(Text) + 1];
+ if (m_Text) strcpy(m_Text, Text);
+ m_StartTime = Game->m_CurrentTime;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBQuickMsg::~CBQuickMsg() {
+ if (m_Text) delete [] m_Text;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBQuickMsg::GetText() {
+ return m_Text;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BQuickMsg.h b/engines/wintermute/BQuickMsg.h
new file mode 100644
index 0000000000..67bb8cf8bf
--- /dev/null
+++ b/engines/wintermute/BQuickMsg.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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_BQUICKMSG_H
+#define WINTERMUTE_BQUICKMSG_H
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBQuickMsg : public CBBase {
+public:
+ char *GetText();
+ uint32 m_StartTime;
+ char *m_Text;
+ CBQuickMsg(CBGame *inGame, char *Text);
+ virtual ~CBQuickMsg();
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BRegion.cpp b/engines/wintermute/BRegion.cpp
new file mode 100644
index 0000000000..309d44edab
--- /dev/null
+++ b/engines/wintermute/BRegion.cpp
@@ -0,0 +1,508 @@
+/* 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 "BRegion.h"
+#include "BParser.h"
+#include "BDynBuffer.h"
+#include "ScValue.h"
+#include "BGame.h"
+#include "ScScript.h"
+#include "ScStack.h"
+#include "BFileManager.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBRegion, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBRegion::CBRegion(CBGame *inGame): CBObject(inGame) {
+ m_Active = true;
+ m_EditorSelectedPoint = -1;
+ m_LastMimicScale = -1;
+ m_LastMimicX = m_LastMimicY = INT_MIN;
+
+ CBPlatform::SetRectEmpty(&m_Rect);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBRegion::~CBRegion() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegion::Cleanup() {
+ for (int i = 0; i < m_Points.GetSize(); i++) delete m_Points[i];
+ m_Points.RemoveAll();
+
+ CBPlatform::SetRectEmpty(&m_Rect);
+ m_EditorSelectedPoint = -1;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegion::CreateRegion() {
+ return SUCCEEDED(GetBoundingRect(&m_Rect));
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegion::PointInRegion(int X, int Y) {
+ if (m_Points.GetSize() < 3) return false;
+
+ POINT pt;
+ pt.x = X;
+ pt.y = Y;
+
+ RECT rect;
+ rect.left = X - 1;
+ rect.right = X + 2;
+ rect.top = Y - 1;
+ rect.bottom = Y + 2;
+
+ if (CBPlatform::PtInRect(&m_Rect, pt)) return PtInPolygon(X, Y);
+ else return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::LoadFile(char *Filename) {
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer == NULL) {
+ Game->LOG(0, "CBRegion::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ HRESULT ret;
+
+ m_Filename = new char [strlen(Filename) + 1];
+ strcpy(m_Filename, Filename);
+
+ if (FAILED(ret = LoadBuffer(Buffer, true))) Game->LOG(0, "Error parsing REGION file '%s'", Filename);
+
+
+ delete [] Buffer;
+
+ return ret;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(REGION)
+TOKEN_DEF(TEMPLATE)
+TOKEN_DEF(NAME)
+TOKEN_DEF(ACTIVE)
+TOKEN_DEF(POINT)
+TOKEN_DEF(CAPTION)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(EDITOR_SELECTED_POINT)
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::LoadBuffer(byte *Buffer, bool Complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(REGION)
+ TOKEN_TABLE(TEMPLATE)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(ACTIVE)
+ TOKEN_TABLE(POINT)
+ TOKEN_TABLE(CAPTION)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(EDITOR_SELECTED_POINT)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (Complete) {
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_REGION) {
+ Game->LOG(0, "'REGION' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = params;
+ }
+
+ int i;
+
+ for (i = 0; i < m_Points.GetSize(); i++) delete m_Points[i];
+ m_Points.RemoveAll();
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_TEMPLATE:
+ if (FAILED(LoadFile((char *)params))) cmd = PARSERR_GENERIC;
+ break;
+
+ case TOKEN_NAME:
+ SetName((char *)params);
+ break;
+
+ case TOKEN_CAPTION:
+ SetCaption((char *)params);
+ break;
+
+ case TOKEN_ACTIVE:
+ parser.ScanStr((char *)params, "%b", &m_Active);
+ break;
+
+ case TOKEN_POINT: {
+ int x, y;
+ parser.ScanStr((char *)params, "%d,%d", &x, &y);
+ m_Points.Add(new CBPoint(x, y));
+ }
+ break;
+
+ case TOKEN_SCRIPT:
+ AddScript((char *)params);
+ break;
+
+ case TOKEN_EDITOR_SELECTED_POINT:
+ parser.ScanStr((char *)params, "%d", &m_EditorSelectedPoint);
+ break;
+
+ case TOKEN_PROPERTY:
+ ParseProperty(params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in REGION definition");
+ return E_FAIL;
+ }
+
+ CreateRegion();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddPoint
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "AddPoint") == 0) {
+ Stack->CorrectParams(2);
+ int X = Stack->Pop()->GetInt();
+ int Y = Stack->Pop()->GetInt();
+
+ m_Points.Add(new CBPoint(X, Y));
+ CreateRegion();
+
+ Stack->PushBool(true);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InsertPoint
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "InsertPoint") == 0) {
+ Stack->CorrectParams(3);
+ int Index = Stack->Pop()->GetInt();
+ int X = Stack->Pop()->GetInt();
+ int Y = Stack->Pop()->GetInt();
+
+ if (Index >= 0 && Index < m_Points.GetSize()) {
+ m_Points.InsertAt(Index, new CBPoint(X, Y));
+ CreateRegion();
+
+ Stack->PushBool(true);
+ } else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetPoint
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetPoint") == 0) {
+ Stack->CorrectParams(3);
+ int Index = Stack->Pop()->GetInt();
+ int X = Stack->Pop()->GetInt();
+ int Y = Stack->Pop()->GetInt();
+
+ if (Index >= 0 && Index < m_Points.GetSize()) {
+ m_Points[Index]->x = X;
+ m_Points[Index]->y = Y;
+ CreateRegion();
+
+ Stack->PushBool(true);
+ } else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // RemovePoint
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "RemovePoint") == 0) {
+ Stack->CorrectParams(1);
+ int Index = Stack->Pop()->GetInt();
+
+ if (Index >= 0 && Index < m_Points.GetSize()) {
+ delete m_Points[Index];
+ m_Points[Index] = NULL;
+
+ m_Points.RemoveAt(Index);
+ CreateRegion();
+
+ Stack->PushBool(true);
+ } else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetPoint
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "GetPoint") == 0) {
+ Stack->CorrectParams(1);
+ int Index = Stack->Pop()->GetInt();
+
+ if (Index >= 0 && Index < m_Points.GetSize()) {
+ CScValue *Val = Stack->GetPushValue();
+ if (Val) {
+ Val->SetProperty("X", m_Points[Index]->x);
+ Val->SetProperty("Y", m_Points[Index]->y);
+ }
+ } else Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ else return CBObject::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBRegion::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("region");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Name") == 0) {
+ m_ScValue->SetString(m_Name);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Active") == 0) {
+ m_ScValue->SetBool(m_Active);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumPoints
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "NumPoints") == 0) {
+ m_ScValue->SetInt(m_Points.GetSize());
+ return m_ScValue;
+ }
+
+ else return CBObject::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Name") == 0) {
+ SetName(Value->GetString());
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Active
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Active") == 0) {
+ m_Active = Value->GetBool();
+ return S_OK;
+ }
+
+ else return CBObject::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBRegion::ScToString() {
+ return "[region]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::SaveAsText(CBDynBuffer *Buffer, int Indent, char *NameOverride) {
+ if (!NameOverride) Buffer->PutTextIndent(Indent, "REGION {\n");
+ else Buffer->PutTextIndent(Indent, "%s {\n", NameOverride);
+
+ Buffer->PutTextIndent(Indent + 2, "NAME=\"%s\"\n", m_Name);
+ Buffer->PutTextIndent(Indent + 2, "CAPTION=\"%s\"\n", GetCaption());
+ Buffer->PutTextIndent(Indent + 2, "ACTIVE=%s\n", m_Active ? "TRUE" : "FALSE");
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_SELECTED_POINT=%d\n", m_EditorSelectedPoint);
+
+ int i;
+
+ for (i = 0; i < m_Scripts.GetSize(); i++) {
+ Buffer->PutTextIndent(Indent + 2, "SCRIPT=\"%s\"\n", m_Scripts[i]->m_Filename);
+ }
+
+ for (i = 0; i < m_Points.GetSize(); i++) {
+ Buffer->PutTextIndent(Indent + 2, "POINT {%d,%d}\n", m_Points[i]->x, m_Points[i]->y);
+ }
+
+ if (m_ScProp) m_ScProp->SaveAsText(Buffer, Indent + 2);
+
+ Buffer->PutTextIndent(Indent, "}\n\n");
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::Persist(CBPersistMgr *PersistMgr) {
+
+ CBObject::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_Active));
+ PersistMgr->Transfer(TMEMBER(m_EditorSelectedPoint));
+ PersistMgr->Transfer(TMEMBER(m_LastMimicScale));
+ PersistMgr->Transfer(TMEMBER(m_LastMimicX));
+ PersistMgr->Transfer(TMEMBER(m_LastMimicY));
+ m_Points.Persist(PersistMgr);
+
+ return S_OK;
+}
+
+
+typedef struct {
+ double x, y;
+} dPoint;
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegion::PtInPolygon(int X, int Y) {
+ if (m_Points.GetSize() < 3) return false;
+
+ int counter = 0;
+ int i;
+ double xinters;
+ dPoint p, p1, p2;
+
+ p.x = (double)X;
+ p.y = (double)Y;
+
+ p1.x = (double)m_Points[0]->x;
+ p1.y = (double)m_Points[0]->y;
+
+ for (i = 1; i <= m_Points.GetSize(); i++) {
+ p2.x = (double)m_Points[i % m_Points.GetSize()]->x;
+ p2.y = (double)m_Points[i % m_Points.GetSize()]->y;
+
+ if (p.y > std::min(p1.y, p2.y)) {
+ if (p.y <= std::max(p1.y, p2.y)) {
+ if (p.x <= std::max(p1.x, p2.x)) {
+ if (p1.y != p2.y) {
+ xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
+ if (p1.x == p2.x || p.x <= xinters)
+ counter++;
+ }
+ }
+ }
+ }
+ p1 = p2;
+ }
+
+ if (counter % 2 == 0)
+ return false;
+ else
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::GetBoundingRect(RECT *Rect) {
+ if (m_Points.GetSize() == 0) CBPlatform::SetRectEmpty(Rect);
+ else {
+ int MinX = INT_MAX, MinY = INT_MAX, MaxX = INT_MIN, MaxY = INT_MIN;
+
+ for (int i = 0; i < m_Points.GetSize(); i++) {
+ MinX = std::min(MinX, m_Points[i]->x);
+ MinY = std::min(MinY, m_Points[i]->y);
+
+ MaxX = std::max(MaxX, m_Points[i]->x);
+ MaxY = std::max(MaxY, m_Points[i]->y);
+ }
+ CBPlatform::SetRect(Rect, MinX, MinY, MaxX, MaxY);
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRegion::Mimic(CBRegion *Region, float Scale, int X, int Y) {
+ if (Scale == m_LastMimicScale && X == m_LastMimicX && Y == m_LastMimicY) return S_OK;
+
+ Cleanup();
+
+ for (int i = 0; i < Region->m_Points.GetSize(); i++) {
+ int x, y;
+
+ x = (int)((float)Region->m_Points[i]->x * Scale / 100.0f);
+ y = (int)((float)Region->m_Points[i]->y * Scale / 100.0f);
+
+ m_Points.Add(new CBPoint(x + X, y + Y));
+ }
+
+ m_LastMimicScale = Scale;
+ m_LastMimicX = X;
+ m_LastMimicY = Y;
+
+ return CreateRegion() ? S_OK : E_FAIL;
+}
+
+} // end of namespace WinterMute \ No newline at end of file
diff --git a/engines/wintermute/BRegion.h b/engines/wintermute/BRegion.h
new file mode 100644
index 0000000000..94202ea8dd
--- /dev/null
+++ b/engines/wintermute/BRegion.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_BREGION_H
+#define WINTERMUTE_BREGION_H
+
+#include "BPoint.h"
+#include "BObject.h"
+
+namespace WinterMute {
+
+class CBRegion : public CBObject {
+public:
+ float m_LastMimicScale;
+ int m_LastMimicX;
+ int m_LastMimicY;
+ void Cleanup();
+ HRESULT Mimic(CBRegion *Region, float Scale = 100.0f, int X = 0, int Y = 0);
+ HRESULT GetBoundingRect(RECT *Rect);
+ bool PtInPolygon(int X, int Y);
+ DECLARE_PERSISTENT(CBRegion, CBObject)
+ bool m_Active;
+ int m_EditorSelectedPoint;
+ CBRegion(CBGame *inGame);
+ virtual ~CBRegion();
+ bool PointInRegion(int X, int Y);
+ bool CreateRegion();
+ HRESULT LoadFile(char *Filename);
+ HRESULT LoadBuffer(byte *Buffer, bool Complete = true);
+ RECT m_Rect;
+ CBArray<CBPoint *, CBPoint *> m_Points;
+ virtual HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent, char *NameOverride = NULL);
+
+ // 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/BRegistry.cpp b/engines/wintermute/BRegistry.cpp
new file mode 100644
index 0000000000..4d7b1b6d37
--- /dev/null
+++ b/engines/wintermute/BRegistry.cpp
@@ -0,0 +1,227 @@
+/* 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 <fstream>
+#include "BGame.h"
+#include "BRegistry.h"
+#include "PathUtil.h"
+#include "StringUtil.h"
+#include "tinyxml.h"
+#include "utils.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBRegistry::CBRegistry(CBGame *inGame): CBBase(inGame) {
+ m_IniName = NULL;
+
+ SetIniName("./wme.ini");
+ LoadValues(true);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBRegistry::~CBRegistry() {
+ SaveValues();
+ delete[] m_IniName;
+ m_IniName = NULL;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString CBRegistry::ReadString(const AnsiString &subKey, const AnsiString &key, const AnsiString &init) {
+ AnsiString ret = "";
+
+#ifdef __WIN32__
+ // check ini file first (so what we can use project files on windows)
+ char buffer[32768];
+ GetPrivateProfileString(subKey.c_str(), key.c_str(), init.c_str(), buffer, 32768, m_IniName);
+ ret = AnsiString(buffer);
+
+ if (buffer != init) return ret;
+#endif
+
+ bool found = false;
+ ret = GetValue(m_LocalValues, subKey, key, found);
+ if (!found) ret = GetValue(m_Values, subKey, key, found);
+ if (!found) ret = init;
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegistry::WriteString(const AnsiString &subKey, const AnsiString &key, const AnsiString &value) {
+ m_Values[subKey][key] = value;
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBRegistry::ReadInt(const AnsiString &subKey, const AnsiString &key, int init) {
+#ifdef __WIN32__
+ int ret = GetPrivateProfileInt(subKey.c_str(), key.c_str(), init, m_IniName);
+ if (ret != init) return ret;
+#endif
+
+ AnsiString val = ReadString(subKey, key, "");
+ if (val.empty()) return init;
+ else return atoi(val.c_str());
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegistry::WriteInt(const AnsiString &subKey, const AnsiString &key, int value) {
+ WriteString(subKey, key, StringUtil::ToString(value));
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegistry::ReadBool(const AnsiString &subKey, const AnsiString &key, bool init) {
+ return (ReadInt(subKey, key, (int)init) != 0);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRegistry::WriteBool(const AnsiString &subKey, const AnsiString &key, bool value) {
+ return WriteInt(subKey, key, (int)value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegistry::SetIniName(char *Name) {
+ delete[] m_IniName;
+ m_IniName = NULL;
+
+ if (strchr(Name, '\\') == NULL && strchr(Name, '/') == NULL) {
+ m_IniName = new char [strlen(Name) + 3];
+ sprintf(m_IniName, "./%s", Name);
+ } else {
+ m_IniName = new char [strlen(Name) + 1];
+ strcpy(m_IniName, Name);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBRegistry::GetIniName() {
+ return m_IniName;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegistry::LoadValues(bool local) {
+ if (local) LoadXml("settings.xml", m_LocalValues);
+ else LoadXml(PathUtil::Combine(Game->GetDataDir(), "settings.xml"), m_Values);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegistry::SaveValues() {
+ SaveXml(PathUtil::Combine(Game->GetDataDir(), "settings.xml"), m_Values);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegistry::SetBasePath(const char *basePath) {
+ m_BasePath = PathUtil::GetFileNameWithoutExtension(basePath);
+
+ LoadValues(false);
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString CBRegistry::GetValue(PathValueMap &values, const AnsiString path, const AnsiString &key, bool &found) {
+ found = false;
+ PathValueMap::iterator it = values.find(path);
+ if (it == values.end()) return "";
+
+ KeyValuePair pairs = (*it).second;
+ KeyValuePair::iterator keyIt = pairs.find(key);
+ if (keyIt == pairs.end()) return "";
+ else {
+ found = true;
+ return (*keyIt).second;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegistry::LoadXml(const AnsiString fileName, PathValueMap &values) {
+ TiXmlDocument doc(fileName);
+ if (!doc.LoadFile()) return;
+
+ TiXmlElement *rootElem = doc.RootElement();
+ if (!rootElem || rootElem->ValueStr() != "Settings") return;
+
+ for (TiXmlElement *pathElem = rootElem->FirstChildElement(); pathElem != NULL; pathElem = pathElem->NextSiblingElement()) {
+ for (TiXmlElement *keyElem = pathElem->FirstChildElement(); keyElem != NULL; keyElem = keyElem->NextSiblingElement()) {
+ values[pathElem->ValueStr()][keyElem->ValueStr()] = keyElem->GetText();
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBRegistry::SaveXml(const AnsiString fileName, PathValueMap &values) {
+ CBUtils::CreatePath(fileName.c_str());
+
+ TiXmlDocument doc;
+ doc.LinkEndChild(new TiXmlDeclaration("1.0", "utf-8", ""));
+
+ TiXmlElement *root = new TiXmlElement("Settings");
+ doc.LinkEndChild(root);
+
+ PathValueMap::iterator pathIt;
+ for (pathIt = m_Values.begin(); pathIt != m_Values.end(); ++pathIt) {
+ TiXmlElement *pathElem = new TiXmlElement((*pathIt).first);
+ root->LinkEndChild(pathElem);
+
+
+ KeyValuePair pairs = (*pathIt).second;
+ KeyValuePair::iterator keyIt;
+ for (keyIt = pairs.begin(); keyIt != pairs.end(); ++keyIt) {
+ TiXmlElement *keyElem = new TiXmlElement((*keyIt).first);
+ pathElem->LinkEndChild(keyElem);
+
+ keyElem->LinkEndChild(new TiXmlText((*keyIt).second));
+ }
+ }
+
+
+ TiXmlPrinter printer;
+ doc.Accept(&printer);
+
+ std::ofstream stream;
+ stream.open(fileName.c_str());
+
+ if (!stream.is_open()) return;
+ else {
+ stream << printer.Str();
+ stream.close();
+ }
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BRegistry.h b/engines/wintermute/BRegistry.h
new file mode 100644
index 0000000000..48b88fd663
--- /dev/null
+++ b/engines/wintermute/BRegistry.h
@@ -0,0 +1,76 @@
+/* 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_BREGISTRY_H
+#define WINTERMUTE_BREGISTRY_H
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBRegistry : public CBBase {
+public:
+ void SetIniName(char *Name);
+ char *GetIniName();
+ bool WriteBool(const AnsiString &subKey, const AnsiString &key, bool Value);
+ bool ReadBool(const AnsiString &subKey, const AnsiString &key, bool init = false);
+ bool WriteInt(const AnsiString &subKey, const AnsiString &key, int value);
+ int ReadInt(const AnsiString &subKey, const AnsiString &key, int init = 0);
+ bool WriteString(const AnsiString &subKey, const AnsiString &key, const AnsiString &value);
+ AnsiString ReadString(const AnsiString &subKey, const AnsiString &key, const AnsiString &init = "");
+ CBRegistry(CBGame *inGame);
+ virtual ~CBRegistry();
+
+ void SetBasePath(const char *basePath);
+ AnsiString GetBasePath() const {
+ return m_BasePath;
+ }
+
+ void LoadValues(bool local);
+ void SaveValues();
+
+private:
+ char *m_IniName;
+
+ typedef std::map<AnsiString, AnsiString> KeyValuePair;
+ typedef std::map<AnsiString, KeyValuePair> PathValueMap;
+
+ PathValueMap m_LocalValues;
+ PathValueMap m_Values;
+
+ AnsiString m_BasePath;
+
+ void LoadXml(const AnsiString fileName, PathValueMap &values);
+ void SaveXml(const AnsiString fileName, PathValueMap &values);
+
+ AnsiString GetValue(PathValueMap &values, const AnsiString path, const AnsiString &key, bool &found);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BRenderSDL.cpp b/engines/wintermute/BRenderSDL.cpp
new file mode 100644
index 0000000000..312954097d
--- /dev/null
+++ b/engines/wintermute/BRenderSDL.cpp
@@ -0,0 +1,408 @@
+/* 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 "BRenderSDL.h"
+#include "BRegistry.h"
+#include "BSurfaceSDL.h"
+#include "BImage.h"
+#include "MathUtil.h"
+#include "BGame.h"
+#include "BSprite.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBRenderSDL::CBRenderSDL(CBGame *inGame) : CBRenderer(inGame) {
+ m_Renderer = NULL;
+ m_Win = NULL;
+
+ m_BorderLeft = m_BorderRight = m_BorderTop = m_BorderBottom = 0;
+ m_RatioX = m_RatioY = 1.0f;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBRenderSDL::~CBRenderSDL() {
+ if (m_Renderer) SDL_DestroyRenderer(m_Renderer);
+ if (m_Win) SDL_DestroyWindow(m_Win);
+
+ SDL_Quit();
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::InitRenderer(int width, int height, bool windowed) {
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) return E_FAIL;
+
+
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
+ SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
+
+
+ m_Width = width;
+ m_Height = height;
+
+ m_RealWidth = width;
+ m_RealHeight = height;
+
+
+ // find suitable resolution
+#ifdef __IPHONEOS__
+ m_RealWidth = 480;
+ m_RealHeight = 320;
+
+ int numModes = SDL_GetNumDisplayModes(0);
+ for (int i = 0; i < numModes; i++) {
+ SDL_DisplayMode mode;
+ SDL_GetDisplayMode(0, i, &mode);
+
+ if (mode.w > mode.h) {
+ m_RealWidth = mode.w;
+ m_RealHeight = mode.h;
+ break;
+ }
+ }
+#else
+ m_RealWidth = Game->m_Registry->ReadInt("Debug", "ForceResWidth", m_Width);
+ m_RealHeight = Game->m_Registry->ReadInt("Debug", "ForceResHeight", m_Height);
+#endif
+
+ /*
+ m_RealWidth = 480;
+ m_RealHeight = 320;
+ */
+
+
+ float origAspect = (float)m_Width / (float)m_Height;
+ float realAspect = (float)m_RealWidth / (float)m_RealHeight;
+
+ float ratio;
+ if (origAspect < realAspect) {
+ // normal to wide
+ ratio = (float)m_RealHeight / (float)m_Height;
+ } else {
+ // wide to normal
+ ratio = (float)m_RealWidth / (float)m_Width;
+ }
+
+ m_BorderLeft = (m_RealWidth - (m_Width * ratio)) / 2;
+ m_BorderRight = m_RealWidth - (m_Width * ratio) - m_BorderLeft;
+
+ m_BorderTop = (m_RealHeight - (m_Height * ratio)) / 2;
+ m_BorderBottom = m_RealHeight - (m_Height * ratio) - m_BorderTop;
+
+
+
+ m_RatioX = (float)(m_RealWidth - m_BorderLeft - m_BorderRight) / (float)m_Width;
+ m_RatioY = (float)(m_RealHeight - m_BorderTop - m_BorderBottom) / (float)m_Height;
+
+
+ Uint32 flags = SDL_WINDOW_SHOWN;
+#ifdef __IPHONEOS__
+ flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS;
+#endif
+
+ //m_Windowed = Game->m_Registry->ReadBool("Video", "Windowed", true);
+ if (!windowed) flags |= SDL_WINDOW_FULLSCREEN;
+
+
+ m_Win = SDL_CreateWindow("WME Lite",
+ SDL_WINDOWPOS_UNDEFINED,
+ SDL_WINDOWPOS_UNDEFINED,
+ m_RealWidth, m_RealHeight,
+ flags);
+
+ if (!m_Win) return E_FAIL;
+
+ SDL_ShowCursor(SDL_DISABLE);
+
+#ifdef __IPHONEOS__
+ // SDL defaults to OGL ES2, which doesn't work on old devices
+ SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles");
+#else
+ //SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");
+#endif
+
+ m_Renderer = SDL_CreateRenderer(m_Win, -1, 0);
+ if (!m_Renderer) return E_FAIL;
+
+ m_Active = true;
+
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::Flip() {
+
+#ifdef __IPHONEOS__
+ // hack: until viewports work correctly, we just paint black bars instead
+ SDL_SetRenderDrawColor(m_Renderer, 0x00, 0x00, 0x00, 0xFF);
+
+ static bool firstRefresh = true; // prevents a weird color glitch
+ if (firstRefresh) {
+ firstRefresh = false;
+ } else {
+ SDL_Rect rect;
+ if (m_BorderLeft > 0) {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = m_BorderLeft;
+ rect.h = m_RealHeight;
+ SDL_RenderFillRect(m_Renderer, &rect);
+ }
+ if (m_BorderRight > 0) {
+ rect.x = (m_RealWidth - m_BorderRight);
+ rect.y = 0;
+ rect.w = m_BorderRight;
+ rect.h = m_RealHeight;
+ SDL_RenderFillRect(m_Renderer, &rect);
+ }
+ if (m_BorderTop > 0) {
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = m_RealWidth;
+ rect.h = m_BorderTop;
+ SDL_RenderFillRect(m_Renderer, &rect);
+ }
+ if (m_BorderBottom > 0) {
+ rect.x = 0;
+ rect.y = m_RealHeight - m_BorderBottom;
+ rect.w = m_RealWidth;
+ rect.h = m_BorderBottom;
+ SDL_RenderFillRect(m_Renderer, &rect);
+ }
+ }
+#endif
+
+
+ SDL_RenderPresent(m_Renderer);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::Fill(byte r, byte g, byte b, RECT *rect) {
+ SDL_SetRenderDrawColor(m_Renderer, r, g, b, 0xFF);
+ SDL_RenderClear(m_Renderer);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::Fade(WORD Alpha) {
+ uint32 dwAlpha = 255 - Alpha;
+ return FadeToColor(dwAlpha << 24);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::FadeToColor(uint32 Color, RECT *rect) {
+ SDL_Rect fillRect;
+
+ if (rect) {
+ fillRect.x = rect->left;
+ fillRect.y = rect->top;
+ fillRect.w = rect->right - rect->left;
+ fillRect.h = rect->bottom - rect->top;
+ } else {
+ RECT rc;
+ Game->GetCurrentViewportRect(&rc);
+ fillRect.x = rc.left;
+ fillRect.y = rc.top;
+ fillRect.w = rc.right - rc.left;
+ fillRect.h = rc.bottom - rc.top;
+ }
+ ModTargetRect(&fillRect);
+
+ byte r = D3DCOLGetR(Color);
+ byte g = D3DCOLGetG(Color);
+ byte b = D3DCOLGetB(Color);
+ byte a = D3DCOLGetA(Color);
+
+ SDL_SetRenderDrawColor(m_Renderer, r, g, b, a);
+ SDL_SetRenderDrawBlendMode(m_Renderer, SDL_BLENDMODE_BLEND);
+ SDL_RenderFillRect(m_Renderer, &fillRect);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::DrawLine(int X1, int Y1, int X2, int Y2, uint32 Color) {
+ byte r = D3DCOLGetR(Color);
+ byte g = D3DCOLGetG(Color);
+ byte b = D3DCOLGetB(Color);
+ byte a = D3DCOLGetA(Color);
+
+ SDL_SetRenderDrawColor(m_Renderer, r, g, b, a);
+ SDL_SetRenderDrawBlendMode(m_Renderer, SDL_BLENDMODE_BLEND);
+
+ POINT point1, point2;
+ point1.x = X1;
+ point1.y = Y1;
+ PointToScreen(&point1);
+
+ point2.x = X2;
+ point2.y = Y2;
+ PointToScreen(&point2);
+
+
+ SDL_RenderDrawLine(m_Renderer, point1.x, point1.y, point2.x, point2.y);
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBImage *CBRenderSDL::TakeScreenshot() {
+// TODO: Fix this
+#if 0
+ SDL_Rect viewport;
+
+ SDL_RenderGetViewport(m_Renderer, &viewport);
+
+ SDL_Surface *surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0x00000000);
+ if (!surface) return NULL;
+
+ if (SDL_RenderReadPixels(m_Renderer, NULL, surface->format->format, surface->pixels, surface->pitch) < 0) return NULL;
+
+ FIBITMAP *dib = FreeImage_Allocate(viewport.w, viewport.h, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
+
+ int bytespp = FreeImage_GetLine(dib) / FreeImage_GetWidth(dib);
+
+ for (unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
+ byte *bits = FreeImage_GetScanLine(dib, y);
+ byte *src = (byte *)surface->pixels + (viewport.h - y - 1) * surface->pitch;
+ memcpy(bits, src, bytespp * viewport.w);
+ }
+
+ return new CBImage(Game, dib);
+#endif
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::SwitchFullscreen() {
+ if (m_Windowed) SDL_SetWindowFullscreen(m_Win, SDL_TRUE);
+ else SDL_SetWindowFullscreen(m_Win, SDL_FALSE);
+
+ m_Windowed = !m_Windowed;
+
+ Game->m_Registry->WriteBool("Video", "Windowed", m_Windowed);
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+const char *CBRenderSDL::GetName() {
+ if (m_Name.empty()) {
+ if (m_Renderer) {
+ SDL_RendererInfo info;
+ SDL_GetRendererInfo(m_Renderer, &info);
+ m_Name = AnsiString(info.name);
+ }
+ }
+ return m_Name.c_str();
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderSDL::SetViewport(int left, int top, int right, int bottom) {
+ SDL_Rect rect;
+ rect.x = left + m_BorderLeft;
+ rect.y = top + m_BorderTop;
+ rect.w = (right - left) * m_RatioX;
+ rect.h = (bottom - top) * m_RatioY;
+
+ // TODO fix this once viewports work correctly in SDL/landscape
+#ifndef __IPHONEOS__
+ SDL_RenderSetViewport(GetSdlRenderer(), &rect);
+#endif
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRenderSDL::ModTargetRect(SDL_Rect *rect) {
+ SDL_Rect viewportRect;
+ SDL_RenderGetViewport(GetSdlRenderer(), &viewportRect);
+
+ rect->x = MathUtil::Round(rect->x * m_RatioX + m_BorderLeft - viewportRect.x);
+ rect->y = MathUtil::Round(rect->y * m_RatioY + m_BorderTop - viewportRect.y);
+ rect->w = MathUtil::RoundUp(rect->w * m_RatioX);
+ rect->h = MathUtil::RoundUp(rect->h * m_RatioY);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRenderSDL::PointFromScreen(POINT *point) {
+ SDL_Rect viewportRect;
+ SDL_RenderGetViewport(GetSdlRenderer(), &viewportRect);
+
+ point->x = point->x / m_RatioX - m_BorderLeft / m_RatioX + viewportRect.x;
+ point->y = point->y / m_RatioY - m_BorderTop / m_RatioY + viewportRect.y;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBRenderSDL::PointToScreen(POINT *point) {
+ SDL_Rect viewportRect;
+ SDL_RenderGetViewport(GetSdlRenderer(), &viewportRect);
+
+ point->x = MathUtil::RoundUp(point->x * m_RatioX) + m_BorderLeft - viewportRect.x;
+ point->y = MathUtil::RoundUp(point->y * m_RatioY) + m_BorderTop - viewportRect.y;
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBRenderSDL::DumpData(char *Filename) {
+ FILE *f = fopen(Filename, "wt");
+ if (!f) return;
+
+ CBSurfaceStorage *Mgr = Game->m_SurfaceStorage;
+
+ int TotalKB = 0;
+ int TotalLoss = 0;
+ fprintf(f, "Filename;Usage;Size;KBytes\n");
+ for (int i = 0; i < Mgr->m_Surfaces.GetSize(); i++) {
+ CBSurfaceSDL *Surf = (CBSurfaceSDL *)Mgr->m_Surfaces[i];
+ if (!Surf->m_Filename) continue;
+ if (!Surf->m_Valid) continue;
+
+ fprintf(f, "%s;%d;", Surf->m_Filename, Surf->m_ReferenceCount);
+ fprintf(f, "%dx%d;", Surf->GetWidth(), Surf->GetHeight());
+
+ int kb = Surf->GetWidth() * Surf->GetHeight() * 4 / 1024;
+
+ TotalKB += kb;
+ fprintf(f, "%d;", kb);
+ fprintf(f, "\n");
+ }
+ fprintf(f, "Total %d;;;%d\n", Mgr->m_Surfaces.GetSize(), TotalKB);
+
+
+ fclose(f);
+ Game->LOG(0, "Texture Stats Dump completed.");
+ Game->QuickMessage("Texture Stats Dump completed.");
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BRenderSDL.h b/engines/wintermute/BRenderSDL.h
new file mode 100644
index 0000000000..3489881e14
--- /dev/null
+++ b/engines/wintermute/BRenderSDL.h
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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_BRENDERER_SDL_H
+#define WINTERMUTE_BRENDERER_SDL_H
+
+#include "BRenderer.h"
+#include "SDL.h"
+
+namespace WinterMute {
+
+class CBRenderSDL : public CBRenderer {
+public:
+ CBRenderSDL(CBGame *inGame);
+ ~CBRenderSDL();
+
+ const char *GetName();
+
+ HRESULT InitRenderer(int width, int height, bool windowed);
+ HRESULT Flip();
+ HRESULT Fill(byte r, byte g, byte b, RECT *rect);
+
+ HRESULT Fade(WORD Alpha);
+ HRESULT FadeToColor(uint32 Color, RECT *rect = NULL);
+
+ HRESULT SwitchFullscreen();
+
+ HRESULT DrawLine(int X1, int Y1, int X2, int Y2, uint32 Color);
+
+ CBImage *TakeScreenshot();
+
+ SDL_Renderer *GetSdlRenderer() const {
+ return m_Renderer;
+ }
+ SDL_Window *GetSdlWindow() const {
+ return m_Win;
+ }
+
+ HRESULT SetViewport(int left, int top, int right, int bottom);
+
+ void ModTargetRect(SDL_Rect *rect);
+ void PointFromScreen(POINT *point);
+ void PointToScreen(POINT *point);
+
+ void DumpData(char *Filename);
+
+ float GetScaleRatioX() const {
+ return m_RatioX;
+ }
+ float GetScaleRatioY() const {
+ return m_RatioY;
+ }
+
+private:
+ SDL_Renderer *m_Renderer;
+ SDL_Window *m_Win;
+ AnsiString m_Name;
+
+ int m_BorderLeft;
+ int m_BorderTop;
+ int m_BorderRight;
+ int m_BorderBottom;
+
+ float m_RatioX;
+ float m_RatioY;
+};
+
+} // end of namespace WinterMute
+
+#endif // __WmeBRenderSDL_H__
diff --git a/engines/wintermute/BRenderer.cpp b/engines/wintermute/BRenderer.cpp
new file mode 100644
index 0000000000..aaaca902fa
--- /dev/null
+++ b/engines/wintermute/BRenderer.cpp
@@ -0,0 +1,259 @@
+/* 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 "BActiveRect.h"
+#include "BRenderer.h"
+#include "BSurface.h"
+#include "BSubFrame.h"
+#include "BRegion.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+CBRenderer::CBRenderer(CBGame *inGame): CBBase(inGame) {
+ m_Instance = NULL;
+ m_Window = NULL;
+ m_ClipperWindow = NULL;
+ m_Active = false;
+ m_Ready = false;
+ m_Windowed = true;
+ m_ForceAlphaColor = 0x00;
+
+ m_Width = m_Height = m_BPP = 0;
+ CBPlatform::SetRectEmpty(&m_MonitorRect);
+
+ m_RealWidth = m_RealHeight = 0;
+ m_DrawOffsetX = m_DrawOffsetY = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBRenderer::~CBRenderer() {
+ DeleteRectList();
+ UnclipCursor();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBRenderer::InitLoop() {
+ DeleteRectList();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBObject *CBRenderer::GetObjectAt(int X, int Y) {
+ POINT point;
+ point.x = X;
+ point.y = Y;
+
+ for (int i = m_RectList.GetSize() - 1; i >= 0; i--) {
+ if (CBPlatform::PtInRect(&m_RectList[i]->m_Rect, point)) {
+ if (m_RectList[i]->m_Precise) {
+ // frame
+ if (m_RectList[i]->m_Frame) {
+ int XX = (int)((m_RectList[i]->m_Frame->m_Rect.left + X - m_RectList[i]->m_Rect.left + m_RectList[i]->m_OffsetX) / (float)((float)m_RectList[i]->m_ZoomX / (float)100));
+ int YY = (int)((m_RectList[i]->m_Frame->m_Rect.top + Y - m_RectList[i]->m_Rect.top + m_RectList[i]->m_OffsetY) / (float)((float)m_RectList[i]->m_ZoomY / (float)100));
+
+ if (m_RectList[i]->m_Frame->m_MirrorX) {
+ int Width = m_RectList[i]->m_Frame->m_Rect.right - m_RectList[i]->m_Frame->m_Rect.left;
+ XX = Width - XX;
+ }
+
+ if (m_RectList[i]->m_Frame->m_MirrorY) {
+ int Height = m_RectList[i]->m_Frame->m_Rect.bottom - m_RectList[i]->m_Frame->m_Rect.top;
+ YY = Height - YY;
+ }
+
+ if (!m_RectList[i]->m_Frame->m_Surface->IsTransparentAt(XX, YY)) return m_RectList[i]->m_Owner;
+ }
+ // region
+ else if (m_RectList[i]->m_Region) {
+ if (m_RectList[i]->m_Region->PointInRegion(X + m_RectList[i]->m_OffsetX, Y + m_RectList[i]->m_OffsetY)) return m_RectList[i]->m_Owner;
+ }
+ } else return m_RectList[i]->m_Owner;
+ }
+ }
+
+ return (CBObject *)NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBRenderer::DeleteRectList() {
+ for (int i = 0; i < m_RectList.GetSize(); i++) {
+ delete m_RectList[i];
+ }
+ m_RectList.RemoveAll();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::SwitchFullscreen() {
+ return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::Flip() {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::InitRenderer(int width, int height, bool windowed) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBRenderer::OnWindowChange() {
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::Fill(byte r, byte g, byte b, RECT *rect) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::WindowedBlt() {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::Setup2D(bool Force) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::SetupLines() {
+ return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::DrawLine(int X1, int Y1, int X2, int Y2, uint32 Color) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::DrawRect(int X1, int Y1, int X2, int Y2, uint32 Color, int Width) {
+ for (int i = 0; i < Width; i++) {
+ DrawLine(X1 + i, Y1 + i, X2 - i, Y1 + i, Color); // up
+ DrawLine(X1 + i, Y2 - i, X2 - i + 1, Y2 - i, Color); // down
+
+ DrawLine(X1 + i, Y1 + i, X1 + i, Y2 - i, Color); // left
+ DrawLine(X2 - i, Y1 + i, X2 - i, Y2 - i + 1, Color); // right
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::Fade(WORD Alpha) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::FadeToColor(uint32 Color, RECT *rect) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::SetViewport(int left, int top, int right, int bottom) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::SetScreenViewport() {
+ return SetViewport(m_DrawOffsetX, m_DrawOffsetY, m_Width + m_DrawOffsetX, m_Height + m_DrawOffsetY);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::SetViewport(RECT *Rect) {
+ return SetViewport(Rect->left + m_DrawOffsetX,
+ Rect->top + m_DrawOffsetY,
+ Rect->right + m_DrawOffsetX,
+ Rect->bottom + m_DrawOffsetY);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBImage *CBRenderer::TakeScreenshot() {
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::ClipCursor() {
+ /*
+ if(!m_Windowed)
+ {
+ RECT rc;
+ GetWindowRect(m_Window, &rc);
+
+ // if "maintain aspect ratio" is in effect, lock mouse to visible area
+ rc.left = m_DrawOffsetX;
+ rc.top = m_DrawOffsetY;
+ rc.right = rc.left + m_Width;
+ rc.bottom = rc.top + m_Height;
+
+ ::ClipCursor(&rc);
+ }
+ */
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBRenderer::UnclipCursor() {
+ /*
+ if(!m_Windowed) ::ClipCursor(NULL);
+ */
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBRenderer::PointInViewport(POINT *P) {
+ if (P->x < m_DrawOffsetX) return false;
+ if (P->y < m_DrawOffsetY) return false;
+ if (P->x > m_DrawOffsetX + m_Width) return false;
+ if (P->y > m_DrawOffsetY + m_Height) return false;
+
+ return true;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BRenderer.h b/engines/wintermute/BRenderer.h
new file mode 100644
index 0000000000..c1180a5ef5
--- /dev/null
+++ b/engines/wintermute/BRenderer.h
@@ -0,0 +1,124 @@
+/* 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_BRENDERER_H
+#define WINTERMUTE_BRENDERER_H
+
+
+#include "coll_templ.h"
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBImage;
+class CBActiveRect;
+class CBObject;
+
+class CBRenderer: public CBBase {
+public:
+ int m_RealWidth;
+ int m_RealHeight;
+ int m_DrawOffsetX;
+ int m_DrawOffsetY;
+
+ virtual void DumpData(char *Filename) {};
+ virtual CBImage *TakeScreenshot();
+ virtual HRESULT SetViewport(int left, int top, int right, int bottom);
+ virtual HRESULT SetViewport(RECT *Rect);
+ virtual HRESULT SetScreenViewport();
+ virtual HRESULT Fade(WORD Alpha);
+ virtual HRESULT FadeToColor(uint32 Color, RECT *rect = NULL);
+ virtual HRESULT DrawLine(int X1, int Y1, int X2, int Y2, uint32 Color);
+ virtual HRESULT DrawRect(int X1, int Y1, int X2, int Y2, uint32 Color, int Width = 1);
+ CBRenderer(CBGame *inGame = NULL);
+ virtual ~CBRenderer();
+ virtual HRESULT SetProjection() {
+ return S_OK;
+ };
+
+ virtual HRESULT WindowedBlt();
+ virtual HRESULT Fill(byte r, byte g, byte b, RECT *rect = NULL);
+ virtual void OnWindowChange();
+ virtual HRESULT InitRenderer(int width, int height, bool windowed);
+ virtual HRESULT Flip();
+ virtual void InitLoop();
+ virtual HRESULT SwitchFullscreen();
+ virtual HRESULT Setup2D(bool Force = false);
+ virtual HRESULT SetupLines();
+
+ virtual const char *GetName() {
+ return "";
+ };
+ virtual HRESULT DisplayDebugInfo() {
+ return E_FAIL;
+ };
+ virtual HRESULT DrawShaderQuad() {
+ return E_FAIL;
+ }
+
+ virtual float GetScaleRatioX() const {
+ return 1.0f;
+ }
+ virtual float GetScaleRatioY() const {
+ return 1.0f;
+ }
+
+ HRESULT ClipCursor();
+ HRESULT UnclipCursor();
+
+ CBObject *GetObjectAt(int X, int Y);
+ void DeleteRectList();
+
+ virtual HRESULT StartSpriteBatch() {
+ return S_OK;
+ };
+ virtual HRESULT EndSpriteBatch() {
+ return S_OK;
+ };
+ bool PointInViewport(POINT *P);
+ uint32 m_ForceAlphaColor;
+ HINSTANCE m_Instance;
+ HWND m_Window;
+ HWND m_ClipperWindow;
+ bool m_Active;
+ bool m_Ready;
+ bool m_Windowed;
+ RECT m_WindowRect;
+ RECT m_ViewportRect;
+ RECT m_ScreenRect;
+ RECT m_MonitorRect;
+ int m_BPP;
+ int m_Height;
+ int m_Width;
+
+ CBArray<CBActiveRect *, CBActiveRect *> m_RectList;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BResourceFile.cpp b/engines/wintermute/BResourceFile.cpp
new file mode 100644
index 0000000000..84811d0e73
--- /dev/null
+++ b/engines/wintermute/BResourceFile.cpp
@@ -0,0 +1,103 @@
+/* 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 "BResourceFile.h"
+#include "BResources.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBResourceFile::CBResourceFile(CBGame *inGame): CBFile(inGame) {
+ m_Data = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBResourceFile::~CBResourceFile() {
+ Close();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBResourceFile::Open(Common::String Filename) {
+ Close();
+
+ if (CBResources::GetFile(Filename.c_str(), m_Data, m_Size)) {
+ m_Pos = 0;
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBResourceFile::Close() {
+ m_Data = NULL;
+ m_Pos = 0;
+ m_Size = 0;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBResourceFile::Read(void *Buffer, uint32 Size) {
+ if (!m_Data || m_Pos + Size > m_Size) return E_FAIL;
+
+ memcpy(Buffer, (byte *)m_Data + m_Pos, Size);
+ m_Pos += Size;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBResourceFile::Seek(uint32 Pos, TSeek Origin) {
+ if (!m_Data) return E_FAIL;
+
+ uint32 NewPos = 0;
+
+ switch (Origin) {
+ case SEEK_TO_BEGIN:
+ NewPos = Pos;
+ break;
+ case SEEK_TO_END:
+ NewPos = m_Size + Pos;
+ break;
+ case SEEK_TO_CURRENT:
+ NewPos = m_Pos + Pos;
+ break;
+ }
+
+ if (NewPos < 0 || NewPos > m_Size) return E_FAIL;
+ else m_Pos = NewPos;
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BResourceFile.h b/engines/wintermute/BResourceFile.h
new file mode 100644
index 0000000000..4d995d674d
--- /dev/null
+++ b/engines/wintermute/BResourceFile.h
@@ -0,0 +1,50 @@
+/* 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_BRESOURCEFILE_H
+#define WINTERMUTE_BRESOURCEFILE_H
+
+#include "BFile.h"
+
+namespace WinterMute {
+
+class CBResourceFile : public CBFile {
+public:
+ CBResourceFile(CBGame *inGame);
+ virtual ~CBResourceFile();
+ virtual HRESULT Seek(uint32 Pos, TSeek Origin = SEEK_TO_BEGIN);
+ virtual HRESULT Read(void *Buffer, uint32 Size);
+ virtual HRESULT Close();
+ virtual HRESULT Open(Common::String Filename);
+private:
+ byte *m_Data;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BResources.cpp b/engines/wintermute/BResources.cpp
new file mode 100644
index 0000000000..dceade0984
--- /dev/null
+++ b/engines/wintermute/BResources.cpp
@@ -0,0 +1,2830 @@
+/* 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 "PlatformSDL.h"
+#include "BResources.h"
+#include "common/str.h"
+
+namespace WinterMute {
+
+unsigned char invalid[] = {
+ 0x42, 0x4d, 0x36, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x04, 0x00, 0x00, 0x28, 0x00,
+ 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x4e, 0x00, 0x00, 0x20, 0x4e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+} ;
+
+unsigned char invaliddebug[] = {
+ 0x42, 0x4d, 0x36, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x04, 0x00, 0x00, 0x28, 0x00,
+ 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xdc, 0xc0, 0x00, 0xf0, 0xca, 0xa6, 0x00, 0x00, 0x20,
+ 0x40, 0x00, 0x00, 0x20, 0x60, 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x20, 0xa0, 0x00, 0x00, 0x20,
+ 0xc0, 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x40,
+ 0x40, 0x00, 0x00, 0x40, 0x60, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x40,
+ 0xc0, 0x00, 0x00, 0x40, 0xe0, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x60,
+ 0x40, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x80, 0x00, 0x00, 0x60, 0xa0, 0x00, 0x00, 0x60,
+ 0xc0, 0x00, 0x00, 0x60, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0x80,
+ 0x40, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0xa0, 0x00, 0x00, 0x80,
+ 0xc0, 0x00, 0x00, 0x80, 0xe0, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x20, 0x00, 0x00, 0xa0,
+ 0x40, 0x00, 0x00, 0xa0, 0x60, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0xa0, 0xa0, 0x00, 0x00, 0xa0,
+ 0xc0, 0x00, 0x00, 0xa0, 0xe0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, 0xc0,
+ 0x40, 0x00, 0x00, 0xc0, 0x60, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00, 0xc0, 0xa0, 0x00, 0x00, 0xc0,
+ 0xc0, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x00, 0x00, 0xe0,
+ 0x40, 0x00, 0x00, 0xe0, 0x60, 0x00, 0x00, 0xe0, 0x80, 0x00, 0x00, 0xe0, 0xa0, 0x00, 0x00, 0xe0,
+ 0xc0, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x40, 0x00, 0x80, 0x00, 0x40, 0x00, 0xa0, 0x00, 0x40, 0x00,
+ 0xc0, 0x00, 0x40, 0x00, 0xe0, 0x00, 0x40, 0x20, 0x00, 0x00, 0x40, 0x20, 0x20, 0x00, 0x40, 0x20,
+ 0x40, 0x00, 0x40, 0x20, 0x60, 0x00, 0x40, 0x20, 0x80, 0x00, 0x40, 0x20, 0xa0, 0x00, 0x40, 0x20,
+ 0xc0, 0x00, 0x40, 0x20, 0xe0, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x40, 0x20, 0x00, 0x40, 0x40,
+ 0x40, 0x00, 0x40, 0x40, 0x60, 0x00, 0x40, 0x40, 0x80, 0x00, 0x40, 0x40, 0xa0, 0x00, 0x40, 0x40,
+ 0xc0, 0x00, 0x40, 0x40, 0xe0, 0x00, 0x40, 0x60, 0x00, 0x00, 0x40, 0x60, 0x20, 0x00, 0x40, 0x60,
+ 0x40, 0x00, 0x40, 0x60, 0x60, 0x00, 0x40, 0x60, 0x80, 0x00, 0x40, 0x60, 0xa0, 0x00, 0x40, 0x60,
+ 0xc0, 0x00, 0x40, 0x60, 0xe0, 0x00, 0x40, 0x80, 0x00, 0x00, 0x40, 0x80, 0x20, 0x00, 0x40, 0x80,
+ 0x40, 0x00, 0x40, 0x80, 0x60, 0x00, 0x40, 0x80, 0x80, 0x00, 0x40, 0x80, 0xa0, 0x00, 0x40, 0x80,
+ 0xc0, 0x00, 0x40, 0x80, 0xe0, 0x00, 0x40, 0xa0, 0x00, 0x00, 0x40, 0xa0, 0x20, 0x00, 0x40, 0xa0,
+ 0x40, 0x00, 0x40, 0xa0, 0x60, 0x00, 0x40, 0xa0, 0x80, 0x00, 0x40, 0xa0, 0xa0, 0x00, 0x40, 0xa0,
+ 0xc0, 0x00, 0x40, 0xa0, 0xe0, 0x00, 0x40, 0xc0, 0x00, 0x00, 0x40, 0xc0, 0x20, 0x00, 0x40, 0xc0,
+ 0x40, 0x00, 0x40, 0xc0, 0x60, 0x00, 0x40, 0xc0, 0x80, 0x00, 0x40, 0xc0, 0xa0, 0x00, 0x40, 0xc0,
+ 0xc0, 0x00, 0x40, 0xc0, 0xe0, 0x00, 0x40, 0xe0, 0x00, 0x00, 0x40, 0xe0, 0x20, 0x00, 0x40, 0xe0,
+ 0x40, 0x00, 0x40, 0xe0, 0x60, 0x00, 0x40, 0xe0, 0x80, 0x00, 0x40, 0xe0, 0xa0, 0x00, 0x40, 0xe0,
+ 0xc0, 0x00, 0x40, 0xe0, 0xe0, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00,
+ 0x40, 0x00, 0x80, 0x00, 0x60, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xa0, 0x00, 0x80, 0x00,
+ 0xc0, 0x00, 0x80, 0x00, 0xe0, 0x00, 0x80, 0x20, 0x00, 0x00, 0x80, 0x20, 0x20, 0x00, 0x80, 0x20,
+ 0x40, 0x00, 0x80, 0x20, 0x60, 0x00, 0x80, 0x20, 0x80, 0x00, 0x80, 0x20, 0xa0, 0x00, 0x80, 0x20,
+ 0xc0, 0x00, 0x80, 0x20, 0xe0, 0x00, 0x80, 0x40, 0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x80, 0x40,
+ 0x40, 0x00, 0x80, 0x40, 0x60, 0x00, 0x80, 0x40, 0x80, 0x00, 0x80, 0x40, 0xa0, 0x00, 0x80, 0x40,
+ 0xc0, 0x00, 0x80, 0x40, 0xe0, 0x00, 0x80, 0x60, 0x00, 0x00, 0x80, 0x60, 0x20, 0x00, 0x80, 0x60,
+ 0x40, 0x00, 0x80, 0x60, 0x60, 0x00, 0x80, 0x60, 0x80, 0x00, 0x80, 0x60, 0xa0, 0x00, 0x80, 0x60,
+ 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x20, 0x00, 0x80, 0x80,
+ 0x40, 0x00, 0x80, 0x80, 0x60, 0x00, 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0xa0, 0x00, 0x80, 0x80,
+ 0xc0, 0x00, 0x80, 0x80, 0xe0, 0x00, 0x80, 0xa0, 0x00, 0x00, 0x80, 0xa0, 0x20, 0x00, 0x80, 0xa0,
+ 0x40, 0x00, 0x80, 0xa0, 0x60, 0x00, 0x80, 0xa0, 0x80, 0x00, 0x80, 0xa0, 0xa0, 0x00, 0x80, 0xa0,
+ 0xc0, 0x00, 0x80, 0xa0, 0xe0, 0x00, 0x80, 0xc0, 0x00, 0x00, 0x80, 0xc0, 0x20, 0x00, 0x80, 0xc0,
+ 0x40, 0x00, 0x80, 0xc0, 0x60, 0x00, 0x80, 0xc0, 0x80, 0x00, 0x80, 0xc0, 0xa0, 0x00, 0x80, 0xc0,
+ 0xc0, 0x00, 0x80, 0xc0, 0xe0, 0x00, 0x80, 0xe0, 0x00, 0x00, 0x80, 0xe0, 0x20, 0x00, 0x80, 0xe0,
+ 0x40, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x80, 0xe0, 0x80, 0x00, 0x80, 0xe0, 0xa0, 0x00, 0x80, 0xe0,
+ 0xc0, 0x00, 0x80, 0xe0, 0xe0, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x20, 0x00, 0xc0, 0x00,
+ 0x40, 0x00, 0xc0, 0x00, 0x60, 0x00, 0xc0, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xa0, 0x00, 0xc0, 0x00,
+ 0xc0, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0xc0, 0x20, 0x00, 0x00, 0xc0, 0x20, 0x20, 0x00, 0xc0, 0x20,
+ 0x40, 0x00, 0xc0, 0x20, 0x60, 0x00, 0xc0, 0x20, 0x80, 0x00, 0xc0, 0x20, 0xa0, 0x00, 0xc0, 0x20,
+ 0xc0, 0x00, 0xc0, 0x20, 0xe0, 0x00, 0xc0, 0x40, 0x00, 0x00, 0xc0, 0x40, 0x20, 0x00, 0xc0, 0x40,
+ 0x40, 0x00, 0xc0, 0x40, 0x60, 0x00, 0xc0, 0x40, 0x80, 0x00, 0xc0, 0x40, 0xa0, 0x00, 0xc0, 0x40,
+ 0xc0, 0x00, 0xc0, 0x40, 0xe0, 0x00, 0xc0, 0x60, 0x00, 0x00, 0xc0, 0x60, 0x20, 0x00, 0xc0, 0x60,
+ 0x40, 0x00, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x80, 0x00, 0xc0, 0x60, 0xa0, 0x00, 0xc0, 0x60,
+ 0xc0, 0x00, 0xc0, 0x60, 0xe0, 0x00, 0xc0, 0x80, 0x00, 0x00, 0xc0, 0x80, 0x20, 0x00, 0xc0, 0x80,
+ 0x40, 0x00, 0xc0, 0x80, 0x60, 0x00, 0xc0, 0x80, 0x80, 0x00, 0xc0, 0x80, 0xa0, 0x00, 0xc0, 0x80,
+ 0xc0, 0x00, 0xc0, 0x80, 0xe0, 0x00, 0xc0, 0xa0, 0x00, 0x00, 0xc0, 0xa0, 0x20, 0x00, 0xc0, 0xa0,
+ 0x40, 0x00, 0xc0, 0xa0, 0x60, 0x00, 0xc0, 0xa0, 0x80, 0x00, 0xc0, 0xa0, 0xa0, 0x00, 0xc0, 0xa0,
+ 0xc0, 0x00, 0xc0, 0xa0, 0xe0, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0xc0, 0xc0, 0x20, 0x00, 0xc0, 0xc0,
+ 0x40, 0x00, 0xc0, 0xc0, 0x60, 0x00, 0xc0, 0xc0, 0x80, 0x00, 0xc0, 0xc0, 0xa0, 0x00, 0xf0, 0xfb,
+ 0xff, 0x00, 0xa4, 0xa0, 0xa0, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0xf9,
+ 0xf9, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0xf9, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0xf9, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00,
+ 0xf9, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0xf9, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
+ 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9
+} ;
+
+unsigned char systemfont[] = {
+ 0x42, 0x4d, 0x36, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x04, 0x00, 0x00, 0x28, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x70, 0x0b, 0x00, 0x00, 0x70, 0x0b, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x80, 0x80,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00,
+ 0x01, 0x02, 0x02, 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00,
+ 0x02, 0x00, 0x01, 0x02, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00,
+ 0x02, 0x01, 0x00, 0x02, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x01, 0x02, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00,
+ 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x00, 0x01, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x01, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x00,
+ 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02,
+ 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x01, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x00, 0x01, 0x02, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x01,
+ 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x02, 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x00, 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02,
+ 0x00, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+} ;
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBResources::GetFile(const char *fileName, byte*& buffer, uint32 &size) {
+ // better!
+ if (scumm_stricmp(fileName, "invalid.bmp") == 0) {
+ buffer = invalid;
+ size = sizeof(invalid);
+ return true;
+ } else if (scumm_stricmp(fileName, "invalid_debug.bmp") == 0) {
+ buffer = invaliddebug;
+ size = sizeof(invaliddebug);
+ return true;
+ } else if (scumm_stricmp(fileName, "system_font.bmp") == 0) {
+ buffer = systemfont;
+ size = sizeof(systemfont);
+ return true;
+ }
+
+
+ return false;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BResources.h b/engines/wintermute/BResources.h
new file mode 100644
index 0000000000..ff8c050fa8
--- /dev/null
+++ b/engines/wintermute/BResources.h
@@ -0,0 +1,41 @@
+/* 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_BRESOURCES_H
+#define WINTERMUTE_BRESOURCES_H
+
+namespace WinterMute {
+
+class CBResources {
+public:
+ static bool GetFile(const char *fileName, byte*& buffer, uint32 &size);
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSaveThumbFile.cpp b/engines/wintermute/BSaveThumbFile.cpp
new file mode 100644
index 0000000000..aeba924684
--- /dev/null
+++ b/engines/wintermute/BSaveThumbFile.cpp
@@ -0,0 +1,146 @@
+/* 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 "BGame.h"
+#include "BSaveThumbFile.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSaveThumbFile::CBSaveThumbFile(CBGame *inGame): CBFile(inGame) {
+ m_Data = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSaveThumbFile::~CBSaveThumbFile() {
+ Close();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSaveThumbFile::Open(Common::String Filename) {
+ Close();
+
+ if (scumm_strnicmp(Filename.c_str(), "savegame:", 9) != 0) return E_FAIL;
+
+ char *TempFilename = new char[strlen(Filename.c_str()) - 8];
+ strcpy(TempFilename, Filename.c_str() + 9);
+ for (int i = 0; i < strlen(TempFilename); i++) {
+ if (TempFilename[i] < '0' || TempFilename[i] > '9') {
+ TempFilename[i] = '\0';
+ break;
+ }
+ }
+
+ // get slot number from name
+ int Slot = atoi(TempFilename);
+ delete [] TempFilename;
+
+ char SlotFilename[MAX_PATH + 1];
+ Game->GetSaveSlotFilename(Slot, SlotFilename);
+ CBPersistMgr *pm = new CBPersistMgr(Game);
+ if (!pm) return E_FAIL;
+
+ Game->m_DEBUG_AbsolutePathWarning = false;
+ if (FAILED(pm->InitLoad(SlotFilename))) {
+ Game->m_DEBUG_AbsolutePathWarning = true;
+ delete pm;
+ return E_FAIL;
+ }
+ Game->m_DEBUG_AbsolutePathWarning = true;
+
+ HRESULT res;
+
+ if (pm->m_ThumbnailDataSize != 0) {
+ m_Data = new byte[pm->m_ThumbnailDataSize];
+ memcpy(m_Data, pm->m_ThumbnailData, pm->m_ThumbnailDataSize);
+ m_Size = pm->m_ThumbnailDataSize;
+ res = S_OK;
+ } else res = E_FAIL;
+ delete pm;
+
+ return res;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSaveThumbFile::Close() {
+ delete[] m_Data;
+ m_Data = NULL;
+
+ m_Pos = 0;
+ m_Size = 0;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSaveThumbFile::Read(void *Buffer, uint32 Size) {
+ if (!m_Data || m_Pos + Size > m_Size) return E_FAIL;
+
+ memcpy(Buffer, (byte *)m_Data + m_Pos, Size);
+ m_Pos += Size;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSaveThumbFile::Seek(uint32 Pos, TSeek Origin) {
+ if (!m_Data) return E_FAIL;
+
+ uint32 NewPos = 0;
+
+ switch (Origin) {
+ case SEEK_TO_BEGIN:
+ NewPos = Pos;
+ break;
+ case SEEK_TO_END:
+ NewPos = m_Size + Pos;
+ break;
+ case SEEK_TO_CURRENT:
+ NewPos = m_Pos + Pos;
+ break;
+ }
+
+ if (NewPos < 0 || NewPos > m_Size) return E_FAIL;
+ else m_Pos = NewPos;
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSaveThumbFile.h b/engines/wintermute/BSaveThumbFile.h
new file mode 100644
index 0000000000..7c22eda237
--- /dev/null
+++ b/engines/wintermute/BSaveThumbFile.h
@@ -0,0 +1,51 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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_BSAVETHUMBFILE_H
+#define WINTERMUTE_BSAVETHUMBFILE_H
+
+
+#include "BFile.h"
+
+namespace WinterMute {
+
+class CBSaveThumbFile : public CBFile {
+public:
+ CBSaveThumbFile(CBGame *Game);
+ virtual ~CBSaveThumbFile();
+ virtual HRESULT Seek(uint32 Pos, TSeek Origin = SEEK_TO_BEGIN);
+ virtual HRESULT Read(void *Buffer, uint32 Size);
+ virtual HRESULT Close();
+ virtual HRESULT Open(Common::String Filename);
+private:
+ byte *m_Data;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSaveThumbHelper.cpp b/engines/wintermute/BSaveThumbHelper.cpp
new file mode 100644
index 0000000000..3342f7aa3a
--- /dev/null
+++ b/engines/wintermute/BSaveThumbHelper.cpp
@@ -0,0 +1,79 @@
+/* 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 "BSaveThumbHelper.h"
+#include "BImage.h"
+#include "BGame.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBSaveThumbHelper::CBSaveThumbHelper(CBGame *inGame): CBBase(inGame) {
+ m_Thumbnail = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBSaveThumbHelper::~CBSaveThumbHelper(void) {
+ delete m_Thumbnail;
+ m_Thumbnail = NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSaveThumbHelper::StoreThumbnail(bool DoFlip) {
+ delete m_Thumbnail;
+ m_Thumbnail = NULL;
+
+ if (Game->m_ThumbnailWidth > 0 && Game->m_ThumbnailHeight > 0) {
+ if (DoFlip) {
+ // when using opengl on windows it seems to be necessary to do this twice
+ // works normally for direct3d
+ Game->DisplayContent(false);
+ Game->m_Renderer->Flip();
+
+ Game->DisplayContent(false);
+ Game->m_Renderer->Flip();
+ }
+
+ CBImage *Screenshot = Game->m_Renderer->TakeScreenshot();
+ if (!Screenshot) return E_FAIL;
+
+ // normal thumbnail
+ if (Game->m_ThumbnailWidth > 0 && Game->m_ThumbnailHeight > 0) {
+ m_Thumbnail = new CBImage(Game);
+ m_Thumbnail->CopyFrom(Screenshot, Game->m_ThumbnailWidth, Game->m_ThumbnailHeight);
+ }
+
+
+ delete Screenshot;
+ Screenshot = NULL;
+ }
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSaveThumbHelper.h b/engines/wintermute/BSaveThumbHelper.h
new file mode 100644
index 0000000000..6c1e411f5f
--- /dev/null
+++ b/engines/wintermute/BSaveThumbHelper.h
@@ -0,0 +1,50 @@
+/* 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_BSAVETHUMBHELPER_H
+#define WINTERMUTE_BSAVETHUMBHELPER_H
+
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBImage;
+
+class CBSaveThumbHelper : public CBBase {
+public:
+ CBSaveThumbHelper(CBGame *inGame);
+ virtual ~CBSaveThumbHelper(void);
+ HRESULT StoreThumbnail(bool DoFlip = false);
+
+ CBImage *m_Thumbnail;
+ CBImage *m_RichThumbnail;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BScriptHolder.cpp b/engines/wintermute/BScriptHolder.cpp
new file mode 100644
index 0000000000..96ed14461c
--- /dev/null
+++ b/engines/wintermute/BScriptHolder.cpp
@@ -0,0 +1,470 @@
+/*
+This file is part of WME Lite.
+http://dead-code.org/redir.php?target=wmelite
+
+Copyright (c) 2011 Jan Nedoma
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "dcgf.h"
+#include "AdGame.h"
+#include "BScriptHolder.h"
+#include "BParser.h"
+#include "ScValue.h"
+#include "ScEngine.h"
+#include "ScScript.h"
+#include "ScStack.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBScriptHolder, false)
+
+//////////////////////////////////////////////////////////////////////
+CBScriptHolder::CBScriptHolder(CBGame *inGame): CBScriptable(inGame) {
+ SetName("<unnamed>");
+
+ m_Freezable = true;
+ m_Filename = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBScriptHolder::~CBScriptHolder() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::Cleanup() {
+ delete[] m_Filename;
+ m_Filename = NULL;
+
+ int i;
+
+ for (i = 0; i < m_Scripts.GetSize(); i++) {
+ m_Scripts[i]->Finish(true);
+ m_Scripts[i]->m_Owner = NULL;
+ }
+ m_Scripts.RemoveAll();
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////
+void CBScriptHolder::SetFilename(char *Filename) {
+ if (m_Filename != NULL) delete [] m_Filename;
+
+ m_Filename = new char [strlen(Filename) + 1];
+ if (m_Filename != NULL) strcpy(m_Filename, Filename);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::ApplyEvent(const char *EventName, bool Unbreakable) {
+ int NumHandlers = 0;
+
+ HRESULT ret = E_FAIL;
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (!m_Scripts[i]->m_Thread) {
+ CScScript *handler = m_Scripts[i]->InvokeEventHandler(EventName, Unbreakable);
+ if (handler) {
+ //m_Scripts.Add(handler);
+ NumHandlers++;
+ ret = S_OK;
+ }
+ }
+ }
+ if (NumHandlers > 0 && Unbreakable) Game->m_ScEngine->TickUnbreakable();
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::Listen(CBScriptHolder *param1, uint32 param2) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ //////////////////////////////////////////////////////////////////////////
+ // DEBUG_CrashMe
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "DEBUG_CrashMe") == 0) {
+ Stack->CorrectParams(0);
+ byte *p = 0;
+ *p = 10;
+ Stack->PushNULL();
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // ApplyEvent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "ApplyEvent") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *val = Stack->Pop();
+ HRESULT ret;
+ ret = ApplyEvent(val->GetString());
+
+ if (SUCCEEDED(ret)) Stack->PushBool(true);
+ else Stack->PushBool(false);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CanHandleEvent
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CanHandleEvent") == 0) {
+ Stack->CorrectParams(1);
+ Stack->PushBool(CanHandleEvent(Stack->Pop()->GetString()));
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CanHandleMethod
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CanHandleMethod") == 0) {
+ Stack->CorrectParams(1);
+ Stack->PushBool(CanHandleMethod(Stack->Pop()->GetString()));
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AttachScript
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AttachScript") == 0) {
+ Stack->CorrectParams(1);
+ Stack->PushBool(SUCCEEDED(AddScript(Stack->Pop()->GetString())));
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DetachScript
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DetachScript") == 0) {
+ Stack->CorrectParams(2);
+ char *Filename = Stack->Pop()->GetString();
+ bool KillThreads = Stack->Pop()->GetBool(false);
+ bool ret = false;
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (scumm_stricmp(m_Scripts[i]->m_Filename, Filename) == 0) {
+ m_Scripts[i]->Finish(KillThreads);
+ ret = true;
+ break;
+ }
+ }
+ Stack->PushBool(ret);
+
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // IsScriptRunning
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "IsScriptRunning") == 0) {
+ Stack->CorrectParams(1);
+ char *Filename = Stack->Pop()->GetString();
+ bool ret = false;
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (scumm_stricmp(m_Scripts[i]->m_Filename, Filename) == 0 && m_Scripts[i]->m_State != SCRIPT_FINISHED && m_Scripts[i]->m_State != SCRIPT_ERROR) {
+ ret = true;
+ break;
+ }
+ }
+ Stack->PushBool(ret);
+
+ return S_OK;
+ } else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBScriptHolder::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("script_holder");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Name") == 0) {
+ m_ScValue->SetString(m_Name);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Filename (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Filename") == 0) {
+ m_ScValue->SetString(m_Filename);
+ return m_ScValue;
+ }
+
+ else return CBScriptable::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // Name
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Name") == 0) {
+ SetName(Value->GetString());
+ return S_OK;
+ } else return CBScriptable::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBScriptHolder::ScToString() {
+ return "[script_holder]";
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::SaveAsText(CBDynBuffer *Buffer, int Indent) {
+ return CBBase::SaveAsText(Buffer, Indent);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::Persist(CBPersistMgr *PersistMgr) {
+ CBScriptable::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_Filename));
+ PersistMgr->Transfer(TMEMBER(m_Freezable));
+ PersistMgr->Transfer(TMEMBER(m_Name));
+ m_Scripts.Persist(PersistMgr);
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::AddScript(char *Filename) {
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (scumm_stricmp(m_Scripts[i]->m_Filename, Filename) == 0) {
+ if (m_Scripts[i]->m_State != SCRIPT_FINISHED) {
+ Game->LOG(0, "CBScriptHolder::AddScript - trying to add script '%s' mutiple times (obj: '%s')", Filename, m_Name);
+ return S_OK;
+ }
+ }
+ }
+
+ CScScript *scr = Game->m_ScEngine->RunScript(Filename, this);
+ if (!scr) {
+ if (Game->m_EditorForceScripts) {
+ // editor hack
+ scr = new CScScript(Game, Game->m_ScEngine);
+ scr->m_Filename = new char[strlen(Filename) + 1];
+ strcpy(scr->m_Filename, Filename);
+ scr->m_State = SCRIPT_ERROR;
+ scr->m_Owner = this;
+ m_Scripts.Add(scr);
+ Game->m_ScEngine->m_Scripts.Add(scr);
+ Game->GetDebugMgr()->OnScriptInit(scr);
+
+ return S_OK;
+ }
+ return E_FAIL;
+ } else {
+ scr->m_Freezable = m_Freezable;
+ m_Scripts.Add(scr);
+ return S_OK;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::RemoveScript(CScScript *Script) {
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (m_Scripts[i] == Script) {
+ m_Scripts.RemoveAt(i);
+ break;
+ }
+ }
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBScriptHolder::CanHandleEvent(char *EventName) {
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (!m_Scripts[i]->m_Thread && m_Scripts[i]->CanHandleEvent(EventName)) return true;
+ }
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBScriptHolder::CanHandleMethod(char *MethodName) {
+ for (int i = 0; i < m_Scripts.GetSize(); i++) {
+ if (!m_Scripts[i]->m_Thread && m_Scripts[i]->CanHandleMethod(MethodName)) return true;
+ }
+ return false;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(PROPERTY)
+TOKEN_DEF(NAME)
+TOKEN_DEF(VALUE)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBScriptHolder::ParseProperty(byte *Buffer, bool Complete) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(PROPERTY)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(VALUE)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ if (Complete) {
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_PROPERTY) {
+ Game->LOG(0, "'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 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 PROPERTY definition");
+ return E_FAIL;
+ }
+
+
+ CScValue *val = new CScValue(Game);
+ val->SetString(PropValue);
+ ScSetProperty(PropName, val);
+
+ delete val;
+ delete[] PropName;
+ delete[] PropValue;
+ PropName = NULL;
+ PropValue = NULL;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBScriptHolder::MakeFreezable(bool Freezable) {
+ m_Freezable = Freezable;
+ for (int i = 0; i < m_Scripts.GetSize(); i++)
+ m_Scripts[i]->m_Freezable = Freezable;
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScScript *CBScriptHolder::InvokeMethodThread(char *MethodName) {
+ for (int i = m_Scripts.GetSize() - 1; i >= 0; i--) {
+ if (m_Scripts[i]->CanHandleMethod(MethodName)) {
+
+ CScScript *thread = new CScScript(Game, m_Scripts[i]->m_Engine);
+ if (thread) {
+ HRESULT ret = thread->CreateMethodThread(m_Scripts[i], MethodName);
+ if (SUCCEEDED(ret)) {
+ m_Scripts[i]->m_Engine->m_Scripts.Add(thread);
+ Game->GetDebugMgr()->OnScriptMethodThreadInit(thread, m_Scripts[i], MethodName);
+
+ return thread;
+ } else {
+ delete thread;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBScriptHolder::ScDebuggerDesc(char *Buf, int BufSize) {
+ strcpy(Buf, ScToString());
+ if (m_Name && strcmp(m_Name, "<unnamed>") != 0) {
+ strcat(Buf, " Name: ");
+ strcat(Buf, m_Name);
+ }
+ if (m_Filename) {
+ strcat(Buf, " File: ");
+ strcat(Buf, m_Filename);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// IWmeObject
+//////////////////////////////////////////////////////////////////////////
+bool CBScriptHolder::SendEvent(const char *EventName) {
+ return SUCCEEDED(ApplyEvent((char *)EventName));
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSound.cpp b/engines/wintermute/BSound.cpp
new file mode 100644
index 0000000000..b6261f8117
--- /dev/null
+++ b/engines/wintermute/BSound.cpp
@@ -0,0 +1,266 @@
+/* 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 "BSound.h"
+#include "BGame.h"
+#include "BSoundMgr.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBSound, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBSound::CBSound(CBGame *inGame): CBBase(inGame) {
+ m_Sound = NULL;
+ m_SoundFilename = NULL;
+
+ m_SoundType = SOUND_SFX;
+ m_SoundStreamed = false;
+ m_SoundLooping = false;
+ m_SoundPlaying = false;
+ m_SoundPaused = false;
+ m_SoundFreezePaused = false;
+ m_SoundPosition = 0;
+ m_SoundPrivateVolume = 0;
+ m_SoundLoopStart = 0;
+
+ m_SFXType = SFX_NONE;
+ m_SFXParam1 = m_SFXParam2 = m_SFXParam3 = m_SFXParam4 = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSound::~CBSound() {
+ if (m_Sound) Game->m_SoundMgr->RemoveSound(m_Sound);
+ m_Sound = NULL;
+
+ delete[] m_SoundFilename;
+ m_SoundFilename = NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetSound(char *Filename, TSoundType Type, bool Streamed) {
+ if (m_Sound) {
+ Game->m_SoundMgr->RemoveSound(m_Sound);
+ m_Sound = NULL;
+ }
+ delete[] m_SoundFilename;
+ m_SoundFilename = NULL;
+
+ m_Sound = Game->m_SoundMgr->AddSound(Filename, Type, Streamed);
+ if (m_Sound) {
+ m_SoundFilename = new char[strlen(Filename) + 1];
+ strcpy(m_SoundFilename, Filename);
+
+ m_SoundType = Type;
+ m_SoundStreamed = Streamed;
+
+ return S_OK;
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetSoundSimple() {
+ m_Sound = Game->m_SoundMgr->AddSound(m_SoundFilename, m_SoundType, m_SoundStreamed);
+ if (m_Sound) {
+ if (m_SoundPosition) m_Sound->SetPosition(m_SoundPosition);
+ m_Sound->SetLooping(m_SoundLooping);
+ m_Sound->SetPrivateVolume(m_SoundPrivateVolume);
+ m_Sound->SetLoopStart(m_SoundLoopStart);
+ m_Sound->m_FreezePaused = m_SoundFreezePaused;
+ if (m_SoundPlaying) return m_Sound->Resume();
+ else return S_OK;
+ } else return E_FAIL;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBSound::GetLength() {
+ if (m_Sound) return m_Sound->GetLength();
+ else return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::Play(bool Looping) {
+ if (m_Sound) {
+ m_SoundPaused = false;
+ return m_Sound->Play(Looping, m_SoundPosition);
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::Stop() {
+ if (m_Sound) {
+ m_SoundPaused = false;
+ return m_Sound->Stop();
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::Pause(bool FreezePaused) {
+ if (m_Sound) {
+ m_SoundPaused = true;
+ if (FreezePaused) m_Sound->m_FreezePaused = true;
+ return m_Sound->Pause();
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::Resume() {
+ if (m_Sound && m_SoundPaused) {
+ m_SoundPaused = false;
+ return m_Sound->Resume();
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::Persist(CBPersistMgr *PersistMgr) {
+ if (PersistMgr->m_Saving && m_Sound) {
+ m_SoundPlaying = m_Sound->IsPlaying();
+ m_SoundLooping = m_Sound->m_Looping;
+ m_SoundPrivateVolume = m_Sound->m_PrivateVolume;
+ if (m_SoundPlaying) m_SoundPosition = m_Sound->GetPosition();
+ m_SoundLoopStart = m_Sound->m_LoopStart;
+ m_SoundFreezePaused = m_Sound->m_FreezePaused;
+ }
+
+ if (PersistMgr->m_Saving) {
+ m_SFXType = SFX_NONE;
+ m_SFXParam1 = m_SFXParam2 = m_SFXParam3 = m_SFXParam4 = 0;
+ }
+
+ PersistMgr->Transfer(TMEMBER(Game));
+
+ PersistMgr->Transfer(TMEMBER(m_SoundFilename));
+ PersistMgr->Transfer(TMEMBER(m_SoundLooping));
+ PersistMgr->Transfer(TMEMBER(m_SoundPaused));
+ PersistMgr->Transfer(TMEMBER(m_SoundFreezePaused));
+ PersistMgr->Transfer(TMEMBER(m_SoundPlaying));
+ PersistMgr->Transfer(TMEMBER(m_SoundPosition));
+ PersistMgr->Transfer(TMEMBER(m_SoundPrivateVolume));
+ PersistMgr->Transfer(TMEMBER(m_SoundStreamed));
+ PersistMgr->Transfer(TMEMBER_INT(m_SoundType));
+ PersistMgr->Transfer(TMEMBER(m_SoundLoopStart));
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSound::IsPlaying() {
+ return m_Sound && m_Sound->IsPlaying();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSound::IsPaused() {
+ return m_Sound && m_SoundPaused;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetPositionTime(uint32 Time) {
+ if (!m_Sound) return E_FAIL;
+ m_SoundPosition = Time;
+ HRESULT ret = m_Sound->SetPosition(m_SoundPosition);
+ if (m_Sound->IsPlaying()) m_SoundPosition = 0;
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBSound::GetPositionTime() {
+ if (!m_Sound) return 0;
+
+ if (!m_Sound->IsPlaying()) return 0;
+ else return m_Sound->GetPosition();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetVolume(int Volume) {
+ if (!m_Sound) return E_FAIL;
+ else return m_Sound->SetPrivateVolume(Volume);
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetPrivateVolume(int Volume) {
+ if (!m_Sound) return E_FAIL;
+ else return m_Sound->m_PrivateVolume = Volume;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBSound::GetVolume() {
+ if (!m_Sound) return 0;
+ else return m_Sound->m_PrivateVolume;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetLoopStart(uint32 Pos) {
+ if (!m_Sound) return E_FAIL;
+ else {
+ m_Sound->SetLoopStart(Pos);
+ return S_OK;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::SetPan(float Pan) {
+ if (m_Sound) return m_Sound->SetPan(Pan);
+ else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSound::ApplyFX(TSFXType Type, float Param1, float Param2, float Param3, float Param4) {
+ if (!m_Sound) return S_OK;
+
+ if (Type != m_SFXType || Param1 != m_SFXParam1 || Param2 != m_SFXParam2 || Param3 != m_SFXParam3 || Param4 != m_SFXParam4) {
+ HRESULT Ret = m_Sound->ApplyFX(Type, Param1, Param2, Param3, Param4);
+
+ m_SFXType = Type;
+ m_SFXParam1 = Param1;
+ m_SFXParam2 = Param2;
+ m_SFXParam3 = Param3;
+ m_SFXParam4 = Param4;
+
+ return Ret;
+ }
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSound.h b/engines/wintermute/BSound.h
new file mode 100644
index 0000000000..0320030c72
--- /dev/null
+++ b/engines/wintermute/BSound.h
@@ -0,0 +1,85 @@
+/* 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_BSOUND_H
+#define WINTERMUTE_BSOUND_H
+
+#include "BBase.h"
+#include "dctypes.h" // Added by ClassView
+#include "BSoundBuffer.h"
+#include "persistent.h"
+
+namespace WinterMute {
+
+class CBSound : public CBBase {
+public:
+ HRESULT SetPan(float Pan);
+ int m_SoundPrivateVolume;
+ int GetVolume();
+ HRESULT SetVolume(int Volume);
+ HRESULT SetPrivateVolume(int Volume);
+ HRESULT SetLoopStart(uint32 Pos);
+ uint32 GetPositionTime();
+ HRESULT SetPositionTime(uint32 Time);
+ bool m_SoundPaused;
+ bool m_SoundFreezePaused;
+ bool IsPlaying();
+ bool IsPaused();
+ bool m_SoundPlaying;
+ bool m_SoundLooping;
+ uint32 m_SoundLoopStart;
+ uint32 m_SoundPosition;
+ DECLARE_PERSISTENT(CBSound, CBBase)
+ HRESULT Resume();
+ HRESULT Pause(bool FreezePaused = false);
+ HRESULT Stop();
+ HRESULT Play(bool Looping = false);
+ uint32 GetLength();
+ bool m_SoundStreamed;
+ TSoundType m_SoundType;
+ char *m_SoundFilename;
+ HRESULT SetSoundSimple();
+ HRESULT SetSound(char *Filename, TSoundType Type = SOUND_SFX, bool Streamed = false);
+ CBSound(CBGame *inGame);
+ virtual ~CBSound();
+
+ HRESULT ApplyFX(TSFXType Type = SFX_NONE, float Param1 = 0, float Param2 = 0, float Param3 = 0, float Param4 = 0);
+
+private:
+ TSFXType m_SFXType;
+ float m_SFXParam1;
+ float m_SFXParam2;
+ float m_SFXParam3;
+ float m_SFXParam4;
+ CBSoundBuffer *m_Sound;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSoundBuffer.cpp b/engines/wintermute/BSoundBuffer.cpp
new file mode 100644
index 0000000000..48c63bf4d9
--- /dev/null
+++ b/engines/wintermute/BSoundBuffer.cpp
@@ -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
+ */
+
+#include "dcgf.h"
+#include "BFile.h"
+#include "BGame.h"
+#include "BSoundMgr.h"
+#include "BSoundBuffer.h"
+#include "BFileManager.h"
+#include "utils.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+#define MAX_NONSTREAMED_FILE_SIZE 1024*1024
+
+//////////////////////////////////////////////////////////////////////////
+CBSoundBuffer::CBSoundBuffer(CBGame *inGame): CBBase(inGame) {
+#if 0
+ m_Stream = NULL;
+ m_Sync = NULL;
+
+ m_Streamed = false;
+ m_Filename = NULL;
+ m_File = NULL;
+ m_PrivateVolume = 100;
+
+ m_Looping = false;
+ m_LoopStart = 0;
+
+ m_Type = SOUND_SFX;
+
+ m_FreezePaused = false;
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSoundBuffer::~CBSoundBuffer() {
+#if 0
+ Stop();
+
+ if (m_Stream) {
+ BASS_StreamFree(m_Stream);
+ m_Stream = NULL;
+ }
+
+ if (m_File) {
+ Game->m_FileManager->CloseFile(m_File);
+ m_File = NULL;
+ }
+
+ SAFE_DELETE_ARRAY(m_Filename);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBSoundBuffer::SetStreaming(bool Streamed, uint32 NumBlocks, uint32 BlockSize) {
+ m_Streamed = Streamed;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::LoadFromFile(const char *Filename, bool ForceReload) {
+#if 0
+ if (m_Stream) {
+ BASS_StreamFree(m_Stream);
+ m_Stream = NULL;
+ }
+
+ if (m_File) Game->m_FileManager->CloseFile(m_File);
+
+ m_File = Game->m_FileManager->OpenFile(Filename);
+ if (!m_File) {
+ Game->LOG(0, "Error opening sound file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ BASS_FILEPROCS fileProc;
+ fileProc.close = CBSoundBuffer::FileCloseProc;
+ fileProc.read = CBSoundBuffer::FileReadProc;
+ fileProc.seek = CBSoundBuffer::FileSeekProc;
+ fileProc.length = CBSoundBuffer::FileLenProc;
+
+ m_Stream = BASS_StreamCreateFileUser(STREAMFILE_NOBUFFER, 0, &fileProc, (void *)m_File);
+ if (!m_Stream) {
+ Game->LOG(0, "BASS error: %d while loading '%s'", BASS_ErrorGetCode(), Filename);
+ return E_FAIL;
+ }
+
+ CBUtils::SetString(&m_Filename, Filename);
+
+ /*
+ HRESULT res;
+ bool NewlyCreated = false;
+
+ if(!m_SoundBuffer || ForceReload || m_Streamed){
+ if(!m_File) m_File = Game->m_FileManager->OpenFile(Filename);
+ if(!m_File){
+ Game->LOG(0, "Error opening sound file '%s'", Filename);
+ return E_FAIL;
+ }
+ // switch to streamed for big files
+ if(!m_Streamed && (m_File->GetSize() > MAX_NONSTREAMED_FILE_SIZE && !Game->m_ForceNonStreamedSounds)) SetStreaming(true);
+ }
+
+ // create buffer
+ if(!m_SoundBuffer){
+ NewlyCreated = true;
+
+ res = InitializeBuffer(m_File);
+ if(FAILED(res)){
+ Game->LOG(res, "Error creating sound buffer for file '%s'", Filename);
+ return res;
+ }
+ }
+
+
+
+ // store filename
+ if(!m_Filename){
+ m_Filename = new char[strlen(Filename)+1];
+ strcpy(m_Filename, Filename);
+ }
+
+ // close file (if not streaming)
+ if(!m_Streamed && m_File){
+ Game->m_FileManager->CloseFile(m_File);
+ m_File = NULL;
+ }
+ */
+
+ return S_OK;
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::Play(bool Looping, uint32 StartSample) {
+#if 0
+ if (m_Stream) {
+ SetLooping(Looping);
+ BASS_ChannelPlay(m_Stream, TRUE);
+ }
+ return S_OK;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBSoundBuffer::SetLooping(bool looping) {
+#if 0
+ m_Looping = looping;
+
+ if (m_Stream) {
+ BASS_ChannelFlags(m_Stream, looping ? BASS_SAMPLE_LOOP : 0, BASS_SAMPLE_LOOP);
+ }
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::Resume() {
+#if 0
+ if (m_Stream) {
+ BASS_ChannelPlay(m_Stream, FALSE);
+ }
+ return S_OK;
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::Stop() {
+#if 0
+ if (m_Stream) {
+ BASS_ChannelStop(m_Stream);
+ }
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::Pause() {
+#if 0
+ if (m_Stream) {
+ BASS_ChannelPause(m_Stream);
+ }
+#endif
+ return S_OK;
+
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBSoundBuffer::GetLength() {
+#if 0
+ QWORD len = BASS_ChannelGetLength(m_Stream, BASS_POS_BYTE);
+ return 1000 * BASS_ChannelBytes2Seconds(m_Stream, len);
+#endif
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBSoundBuffer::SetType(TSoundType Type) {
+ m_Type = Type;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::SetVolume(int Volume) {
+#if 0
+ if (m_Stream) {
+ BASS_ChannelSetAttribute(m_Stream, BASS_ATTRIB_VOL, (float)Volume / 100.0f);
+ }
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::SetPrivateVolume(int Volume) {
+#if 0
+ m_PrivateVolume = Volume;
+
+ switch (m_Type) {
+ case SOUND_SFX:
+ Volume = Game->m_SoundMgr->m_VolumeSFX;
+ break;
+ case SOUND_SPEECH:
+ Volume = Game->m_SoundMgr->m_VolumeSpeech;
+ break;
+ case SOUND_MUSIC:
+ Volume = Game->m_SoundMgr->m_VolumeMusic;
+ break;
+ }
+#endif
+ return SetVolume(Volume);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSoundBuffer::IsPlaying() {
+#if 0
+ return m_FreezePaused || BASS_ChannelIsActive(m_Stream) == BASS_ACTIVE_PLAYING;
+#endif
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBSoundBuffer::GetPosition() {
+#if 0
+ if (m_Stream) {
+ QWORD len = BASS_ChannelGetPosition(m_Stream, BASS_POS_BYTE);
+ return 1000 * BASS_ChannelBytes2Seconds(m_Stream, len);
+ } else return 0;
+#endif
+ return 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::SetPosition(uint32 Pos) {
+#if 0
+ if (m_Stream) {
+ QWORD pos = BASS_ChannelSeconds2Bytes(m_Stream, (float)Pos / 1000.0f);
+ BASS_ChannelSetPosition(m_Stream, pos, BASS_POS_BYTE);
+ }
+#endif
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::SetLoopStart(uint32 Pos) {
+ m_LoopStart = Pos;
+#if 0
+ if (m_Stream) {
+ if (m_Sync) {
+ BASS_ChannelRemoveSync(m_Stream, m_Sync);
+ m_Sync = NULL;
+ }
+ if (m_LoopStart > 0) {
+ QWORD len = BASS_ChannelGetLength(m_Stream, BASS_POS_BYTE);
+ m_Sync = BASS_ChannelSetSync(m_Stream, BASS_SYNC_POS | BASS_SYNC_MIXTIME, len, CBSoundBuffer::LoopSyncProc, (void *)this);
+ }
+ }
+#endif
+ return S_OK;
+}
+#if 0
+//////////////////////////////////////////////////////////////////////////
+void CBSoundBuffer::LoopSyncProc(HSYNC handle, uint32 channel, uint32 data, void *user) {
+ CBSoundBuffer *soundBuf = static_cast<CBSoundBuffer *>(user);
+ QWORD pos = BASS_ChannelSeconds2Bytes(channel, (float)soundBuf->GetLoopStart() / 1000.0f);
+
+ if (!BASS_ChannelSetPosition(channel, pos, BASS_POS_BYTE))
+ BASS_ChannelSetPosition(channel, 0, BASS_POS_BYTE);
+}
+#endif
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::SetPan(float Pan) {
+#if 0
+ if (m_Stream) {
+ BASS_ChannelSetAttribute(m_Stream, BASS_ATTRIB_PAN, Pan);
+ }
+#endif
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundBuffer::ApplyFX(TSFXType Type, float Param1, float Param2, float Param3, float Param4) {
+#if 0
+ switch (Type) {
+ case SFX_ECHO:
+ break;
+
+ case SFX_REVERB:
+ break;
+
+ default:
+ break;
+ }
+#endif
+ return S_OK;
+}
+
+#if 0
+//////////////////////////////////////////////////////////////////////////
+void CBSoundBuffer::FileCloseProc(void *user) {
+ /*
+ CBFile* file = static_cast<CBFile*>(user);
+ file->Game->m_FileManager->CloseFile(file);
+ */
+}
+
+//////////////////////////////////////////////////////////////////////////
+QWORD CBSoundBuffer::FileLenProc(void *user) {
+ CBFile *file = static_cast<CBFile *>(user);
+ return file->GetSize();
+}
+
+//////////////////////////////////////////////////////////////////////////
+uint32 CBSoundBuffer::FileReadProc(void *buffer, uint32 length, void *user) {
+ CBFile *file = static_cast<CBFile *>(user);
+ uint32 oldPos = file->GetPos();
+ file->Read(buffer, length);
+ return file->GetPos() - oldPos;
+}
+
+//////////////////////////////////////////////////////////////////////////
+BOOL CBSoundBuffer::FileSeekProc(QWORD offset, void *user) {
+ CBFile *file = static_cast<CBFile *>(user);
+ return SUCCEEDED(file->Seek(offset));
+}
+#endif
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSoundBuffer.h b/engines/wintermute/BSoundBuffer.h
new file mode 100644
index 0000000000..4571612122
--- /dev/null
+++ b/engines/wintermute/BSoundBuffer.h
@@ -0,0 +1,95 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 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_BSOUNDBUFFER_H
+#define WINTERMUTE_BSOUNDBUFFER_H
+
+
+#include "BBase.h"
+//#include "bass.h"
+
+namespace WinterMute {
+
+class CBFile;
+class CBSoundBuffer : public CBBase {
+public:
+
+ CBSoundBuffer(CBGame *inGame);
+ virtual ~CBSoundBuffer();
+
+
+ HRESULT Pause();
+ HRESULT Play(bool Looping = false, uint32 StartSample = 0);
+ HRESULT Resume();
+ HRESULT Stop();
+ bool IsPlaying();
+
+ void SetLooping(bool looping);
+
+ uint32 GetPosition();
+ HRESULT SetPosition(uint32 Pos);
+ uint32 GetLength();
+
+ HRESULT SetLoopStart(uint32 Pos);
+ uint32 GetLoopStart() const {
+ return m_LoopStart;
+ }
+
+ HRESULT SetPan(float Pan);
+ HRESULT SetPrivateVolume(int Volume);
+ HRESULT SetVolume(int Volume);
+
+ void SetType(TSoundType Type);
+
+ HRESULT LoadFromFile(const char *Filename, bool ForceReload = false);
+ void SetStreaming(bool Streamed, uint32 NumBlocks = 0, uint32 BlockSize = 0);
+ HRESULT ApplyFX(TSFXType Type, float Param1, float Param2, float Param3, float Param4);
+
+ //HSTREAM m_Stream;
+ //HSYNC m_Sync;
+
+ bool m_FreezePaused;
+ uint32 m_LoopStart;
+ TSoundType m_Type;
+ bool m_Looping;
+ CBFile *m_File;
+ char *m_Filename;
+ bool m_Streamed;
+ int m_PrivateVolume;
+
+ /*static void CALLBACK LoopSyncProc(HSYNC handle, uint32 channel, uint32 data, void *user);
+
+ static void CALLBACK FileCloseProc(void *user);
+ static QWORD CALLBACK FileLenProc(void *user);
+ static uint32 CALLBACK FileReadProc(void *buffer, uint32 length, void *user);
+ static BOOL CALLBACK FileSeekProc(QWORD offset, void *user);*/
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSoundMgr.cpp b/engines/wintermute/BSoundMgr.cpp
new file mode 100644
index 0000000000..894a586ee4
--- /dev/null
+++ b/engines/wintermute/BSoundMgr.cpp
@@ -0,0 +1,330 @@
+/* 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 "BSoundMgr.h"
+#include "BRegistry.h"
+#include "PathUtil.h"
+#include "StringUtil.h"
+#include "BGame.h"
+#include "BFileManager.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//IMPLEMENT_PERSISTENT(CBSoundMgr, true);
+
+//////////////////////////////////////////////////////////////////////////
+CBSoundMgr::CBSoundMgr(CBGame *inGame): CBBase(inGame) {
+ m_SoundAvailable = false;
+
+ m_VolumeSFX = m_VolumeSpeech = m_VolumeMusic = m_VolumeMaster = 100;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSoundMgr::~CBSoundMgr() {
+ SaveSettings();
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::Cleanup() {
+#if 0
+ for (int i = 0; i < m_Sounds.GetSize(); i++) delete m_Sounds[i];
+ m_Sounds.RemoveAll();
+
+ BASS_Free();
+#endif
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBSoundMgr::SaveSettings() {
+ if (m_SoundAvailable) {
+ Game->m_Registry->WriteInt("Audio", "MasterVolume", m_VolumeMaster);
+
+ Game->m_Registry->WriteInt("Audio", "SFXVolume", m_VolumeSFX);
+ Game->m_Registry->WriteInt("Audio", "SpeechVolume", m_VolumeSpeech);
+ Game->m_Registry->WriteInt("Audio", "MusicVolume", m_VolumeMusic);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::Initialize() {
+ m_SoundAvailable = false;
+#if 0
+
+#ifdef __IPHONEOS__
+#define BASS_CONFIG_IOS_MIXAUDIO 34
+ BASS_SetConfig(BASS_CONFIG_IOS_MIXAUDIO, 0);
+#endif
+
+
+ if (HIWORD(BASS_GetVersion()) != BASSVERSION) {
+ Game->LOG(0, "An incorrect version of BASS was loaded");
+ return E_FAIL;
+ }
+
+ if (!BASS_Init(-1, 44100, 0, 0, NULL)) {
+ Game->LOG(0, "Can't initialize sound device");
+ return E_FAIL;
+ }
+#endif
+
+ m_VolumeMaster = Game->m_Registry->ReadInt("Audio", "MasterVolume", 100);
+
+ m_VolumeSFX = Game->m_Registry->ReadInt("Audio", "SFXVolume", 100);
+ m_VolumeSpeech = Game->m_Registry->ReadInt("Audio", "SpeechVolume", 100);
+ m_VolumeMusic = Game->m_Registry->ReadInt("Audio", "MusicVolume", 100);
+
+#if 0
+ m_SoundAvailable = true;
+ SetMasterVolumePercent(m_VolumeMaster);
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::InitLoop() {
+ if (!m_SoundAvailable) return S_OK;
+#if 0
+
+ BASS_Update(500);
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSoundBuffer *CBSoundMgr::AddSound(const char *Filename, TSoundType Type, bool Streamed) {
+ if (!m_SoundAvailable) return NULL;
+#if 0
+
+ CBSoundBuffer *sound;
+
+ // try to switch WAV to OGG file (if available)
+ AnsiString ext = PathUtil::GetExtension(Filename);
+ if (StringUtil::CompareNoCase(ext, ".wav")) {
+ AnsiString path = PathUtil::GetDirectoryName(Filename);
+ AnsiString name = PathUtil::GetFileNameWithoutExtension(Filename);
+
+ AnsiString newFile = PathUtil::Combine(path, name + ".ogg");
+ CBFile *file = Game->m_FileManager->OpenFile(newFile.c_str());
+ if (file) {
+ Filename = newFile.c_str();
+ Game->m_FileManager->CloseFile(file);
+ }
+ }
+
+ sound = new CBSoundBuffer(Game);
+ if (!sound) return NULL;
+
+ sound->SetStreaming(Streamed);
+ sound->SetType(Type);
+
+
+ HRESULT res = sound->LoadFromFile(Filename);
+ if (FAILED(res)) {
+ Game->LOG(res, "Error loading sound '%s'", Filename);
+ delete sound;
+ return NULL;
+ }
+
+ // set volume appropriately
+ switch (Type) {
+ case SOUND_SFX:
+ sound->SetVolume(m_VolumeSFX);
+ break;
+ case SOUND_SPEECH:
+ sound->SetVolume(m_VolumeSpeech);
+ break;
+ case SOUND_MUSIC:
+ sound->SetVolume(m_VolumeMusic);
+ break;
+ }
+
+ // register sound
+ m_Sounds.Add(sound);
+
+ return sound;
+#endif
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::AddSound(CBSoundBuffer *Sound, TSoundType Type) {
+ if (!Sound) return E_FAIL;
+#if 0
+ // set volume appropriately
+ switch (Type) {
+ case SOUND_SFX:
+ Sound->SetVolume(m_VolumeSFX);
+ break;
+ case SOUND_SPEECH:
+ Sound->SetVolume(m_VolumeSpeech);
+ break;
+ case SOUND_MUSIC:
+ Sound->SetVolume(m_VolumeMusic);
+ break;
+ }
+
+ // register sound
+ m_Sounds.Add(Sound);
+#endif
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::RemoveSound(CBSoundBuffer *Sound) {
+#if 0
+ for (int i = 0; i < m_Sounds.GetSize(); i++) {
+ if (m_Sounds[i] == Sound) {
+ delete m_Sounds[i];
+ m_Sounds.RemoveAt(i);
+ return S_OK;
+ }
+ }
+#endif
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::SetVolume(TSoundType Type, int Volume) {
+ if (!m_SoundAvailable) return S_OK;
+#if 0
+ switch (Type) {
+ case SOUND_SFX:
+ m_VolumeSFX = Volume;
+ break;
+ case SOUND_SPEECH:
+ m_VolumeSpeech = Volume;
+ break;
+ case SOUND_MUSIC:
+ m_VolumeMusic = Volume;
+ break;
+ }
+
+ for (int i = 0; i < m_Sounds.GetSize(); i++) {
+ if (m_Sounds[i]->m_Type == Type) m_Sounds[i]->SetVolume(Volume);
+ }
+#endif
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::SetVolumePercent(TSoundType Type, byte Percent) {
+ return SetVolume(Type, Percent);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+byte CBSoundMgr::GetVolumePercent(TSoundType Type) {
+ int Volume;
+ switch (Type) {
+ case SOUND_SFX:
+ Volume = m_VolumeSFX;
+ break;
+ case SOUND_SPEECH:
+ Volume = m_VolumeSpeech;
+ break;
+ case SOUND_MUSIC:
+ Volume = m_VolumeMusic;
+ break;
+ }
+
+ return (byte )Volume;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::SetMasterVolumePercent(byte Percent) {
+ m_VolumeMaster = Percent;
+#if 0
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, (uint32)(10000.0f / 100.0f * (float)Percent));
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+byte CBSoundMgr::GetMasterVolumePercent() {
+#if 0
+ uint32 val = BASS_GetConfig(BASS_CONFIG_GVOL_STREAM);
+ return (float)val / 10000.0f * 100.0f;
+#endif
+ return 0;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::PauseAll(bool IncludingMusic) {
+#if 0
+ for (int i = 0; i < m_Sounds.GetSize(); i++) {
+ if (m_Sounds[i]->IsPlaying() && (m_Sounds[i]->m_Type != SOUND_MUSIC || IncludingMusic)) {
+ m_Sounds[i]->Pause();
+ m_Sounds[i]->m_FreezePaused = true;
+ }
+ }
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSoundMgr::ResumeAll() {
+#if 0
+ for (int i = 0; i < m_Sounds.GetSize(); i++) {
+ if (m_Sounds[i]->m_FreezePaused) {
+ m_Sounds[i]->Resume();
+ m_Sounds[i]->m_FreezePaused = false;
+ }
+ }
+#endif
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+float CBSoundMgr::PosToPan(int X, int Y) {
+ float relPos = (float)X / ((float)Game->m_Renderer->m_Width);
+
+ float minPan = -0.7f;
+ float maxPan = 0.7f;
+
+ return minPan + relPos * (maxPan - minPan);
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSoundMgr.h b/engines/wintermute/BSoundMgr.h
new file mode 100644
index 0000000000..1ffc977211
--- /dev/null
+++ b/engines/wintermute/BSoundMgr.h
@@ -0,0 +1,70 @@
+/* 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_BSOUNDMGR_H
+#define WINTERMUTE_BSOUNDMGR_H
+
+#include "coll_templ.h"
+#include "BBase.h"
+#include "BSoundBuffer.h"
+//#include "bass.h"
+
+namespace WinterMute {
+
+class CBSoundMgr : public CBBase {
+public:
+ float PosToPan(int X, int Y);
+ HRESULT ResumeAll();
+ HRESULT PauseAll(bool IncludingMusic = true);
+ HRESULT Cleanup();
+ //DECLARE_PERSISTENT(CBSoundMgr, CBBase);
+ byte GetMasterVolumePercent();
+ HRESULT SetMasterVolumePercent(byte Percent);
+ byte GetVolumePercent(TSoundType Type);
+ HRESULT SetVolumePercent(TSoundType Type, byte Percent);
+ HRESULT SetVolume(TSoundType Type, int Volume);
+ uint32 m_VolumeOriginal;
+ int m_VolumeMaster;
+ int m_VolumeMusic;
+ int m_VolumeSpeech;
+ int m_VolumeSFX;
+ HRESULT RemoveSound(CBSoundBuffer *Sound);
+ CBSoundBuffer *AddSound(const char *Filename, TSoundType Type = SOUND_SFX, bool Streamed = false);
+ HRESULT AddSound(CBSoundBuffer *Sound, TSoundType Type = SOUND_SFX);
+ HRESULT InitLoop();
+ HRESULT Initialize();
+ bool m_SoundAvailable;
+ CBSoundMgr(CBGame *inGame);
+ virtual ~CBSoundMgr();
+ CBArray<CBSoundBuffer *, CBSoundBuffer *> m_Sounds;
+ void SaveSettings();
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSprite.cpp b/engines/wintermute/BSprite.cpp
new file mode 100644
index 0000000000..912fe18f99
--- /dev/null
+++ b/engines/wintermute/BSprite.cpp
@@ -0,0 +1,753 @@
+/* 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 "BSprite.h"
+#include "StringUtil.h"
+#include "PathUtil.h"
+#include "BParser.h"
+#include "BDynBuffer.h"
+#include "ScValue.h"
+#include "BSurface.h"
+#include "BGame.h"
+#include "BFrame.h"
+#include "BSound.h"
+#include "BSubFrame.h"
+#include "ScScript.h"
+#include "ScStack.h"
+#include "BFileManager.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBSprite, false)
+
+//////////////////////////////////////////////////////////////////////
+CBSprite::CBSprite(CBGame *inGame, CBObject *Owner): CBScriptHolder(inGame) {
+ m_EditorAllFrames = false;
+ m_Owner = Owner;
+ SetDefaults();
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBSprite::~CBSprite() {
+ Cleanup();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBSprite::SetDefaults() {
+ m_CurrentFrame = -1;
+ m_Looping = false;
+ m_LastFrameTime = 0;
+ m_Filename = NULL;
+ m_Finished = false;
+ m_Changed = false;
+ m_Paused = false;
+ m_Continuous = false;
+ m_MoveX = m_MoveY = 0;
+
+ m_EditorMuted = false;
+ m_EditorBgFile = NULL;
+ m_EditorBgOffsetX = m_EditorBgOffsetY = 0;
+ m_EditorBgAlpha = 0xFF;
+ m_Streamed = false;
+ m_StreamedKeepLoaded = false;
+
+ SetName("");
+
+ m_Precise = true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBSprite::Cleanup() {
+ CBScriptHolder::Cleanup();
+
+ for (int i = 0; i < m_Frames.GetSize(); i++)
+ delete m_Frames[i];
+ m_Frames.RemoveAll();
+
+ SAFE_DELETE_ARRAY(m_EditorBgFile);
+
+ SetDefaults();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::Draw(int X, int Y, CBObject *Register, float ZoomX, float ZoomY, uint32 Alpha) {
+ GetCurrentFrame(ZoomX, ZoomY);
+ if (m_CurrentFrame < 0 || m_CurrentFrame >= m_Frames.GetSize()) return S_OK;
+
+ // move owner if allowed to
+ if (m_Changed && m_Owner && m_Owner->m_Movable) {
+ m_Owner->m_PosX += m_MoveX;
+ m_Owner->m_PosY += m_MoveY;
+ m_Owner->AfterMove();
+
+ X = m_Owner->m_PosX;
+ Y = m_Owner->m_PosY;
+ }
+
+ // draw frame
+ return Display(X, Y, Register, ZoomX, ZoomY, Alpha);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::LoadFile(char *Filename, int LifeTime, TSpriteCacheType CacheType) {
+ CBFile *File = Game->m_FileManager->OpenFile(Filename);
+ if (!File) {
+ Game->LOG(0, "CBSprite::LoadFile failed for file '%s'", Filename);
+ if (Game->m_DEBUG_DebugMode) return LoadFile("invalid_debug.bmp", LifeTime, CacheType);
+ else return LoadFile("invalid.bmp", LifeTime, CacheType);
+ } else {
+ Game->m_FileManager->CloseFile(File);
+ File = NULL;
+ }
+
+ HRESULT ret;
+
+ AnsiString ext = PathUtil::GetExtension(Filename);
+ if (StringUtil::StartsWith(Filename, "savegame:", true) || StringUtil::CompareNoCase(ext, ".bmp") || StringUtil::CompareNoCase(ext, ".tga") || StringUtil::CompareNoCase(ext, ".png") || StringUtil::CompareNoCase(ext, ".jpg")) {
+ CBFrame *frame = new CBFrame(Game);
+ CBSubFrame *subframe = new CBSubFrame(Game);
+ subframe->SetSurface(Filename, true, 0, 0, 0, LifeTime, true);
+ if (subframe->m_Surface == NULL) {
+ Game->LOG(0, "Error loading simple sprite '%s'", Filename);
+ ret = E_FAIL;
+ delete frame;
+ delete subframe;
+ } else {
+ CBPlatform::SetRect(&subframe->m_Rect, 0, 0, subframe->m_Surface->GetWidth(), subframe->m_Surface->GetHeight());
+ frame->m_Subframes.Add(subframe);
+ m_Frames.Add(frame);
+ m_CurrentFrame = 0;
+ ret = S_OK;
+ }
+ } else {
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename);
+ if (Buffer) {
+ if (FAILED(ret = LoadBuffer(Buffer, true, LifeTime, CacheType))) Game->LOG(0, "Error parsing SPRITE file '%s'", Filename);
+ delete [] Buffer;
+ }
+ }
+
+ m_Filename = new char [strlen(Filename) + 1];
+ strcpy(m_Filename, Filename);
+
+
+ return ret;
+}
+
+
+
+TOKEN_DEF_START
+TOKEN_DEF(CONTINUOUS)
+TOKEN_DEF(SPRITE)
+TOKEN_DEF(LOOPING)
+TOKEN_DEF(FRAME)
+TOKEN_DEF(NAME)
+TOKEN_DEF(PRECISE)
+TOKEN_DEF(EDITOR_MUTED)
+TOKEN_DEF(STREAMED_KEEP_LOADED)
+TOKEN_DEF(STREAMED)
+TOKEN_DEF(SCRIPT)
+TOKEN_DEF(EDITOR_BG_FILE)
+TOKEN_DEF(EDITOR_BG_OFFSET_X)
+TOKEN_DEF(EDITOR_BG_OFFSET_Y)
+TOKEN_DEF(EDITOR_BG_ALPHA)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::LoadBuffer(byte *Buffer, bool Complete, int LifeTime, TSpriteCacheType CacheType) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(CONTINUOUS)
+ TOKEN_TABLE(SPRITE)
+ TOKEN_TABLE(LOOPING)
+ TOKEN_TABLE(FRAME)
+ TOKEN_TABLE(NAME)
+ TOKEN_TABLE(PRECISE)
+ TOKEN_TABLE(EDITOR_MUTED)
+ TOKEN_TABLE(STREAMED_KEEP_LOADED)
+ TOKEN_TABLE(STREAMED)
+ TOKEN_TABLE(SCRIPT)
+ TOKEN_TABLE(EDITOR_BG_FILE)
+ TOKEN_TABLE(EDITOR_BG_OFFSET_X)
+ TOKEN_TABLE(EDITOR_BG_OFFSET_Y)
+ TOKEN_TABLE(EDITOR_BG_ALPHA)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ byte *params;
+ int cmd;
+ CBParser parser(Game);
+
+ Cleanup();
+
+
+ if (Complete) {
+ if (parser.GetCommand((char **)&Buffer, commands, (char **)&params) != TOKEN_SPRITE) {
+ Game->LOG(0, "'SPRITE' keyword expected.");
+ return E_FAIL;
+ }
+ Buffer = params;
+ }
+
+ int frame_count = 1;
+ CBFrame *frame;
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, (char **)&params)) > 0) {
+ switch (cmd) {
+ case TOKEN_CONTINUOUS:
+ parser.ScanStr((char *)params, "%b", &m_Continuous);
+ break;
+
+ case TOKEN_EDITOR_MUTED:
+ parser.ScanStr((char *)params, "%b", &m_EditorMuted);
+ break;
+
+ case TOKEN_SCRIPT:
+ AddScript((char *)params);
+ break;
+
+ case TOKEN_LOOPING:
+ parser.ScanStr((char *)params, "%b", &m_Looping);
+ break;
+
+ case TOKEN_PRECISE:
+ parser.ScanStr((char *)params, "%b", &m_Precise);
+ break;
+
+ case TOKEN_STREAMED:
+ parser.ScanStr((char *)params, "%b", &m_Streamed);
+ if (m_Streamed && LifeTime == -1) {
+ LifeTime = 500;
+ CacheType = CACHE_ALL;
+ }
+ break;
+
+ case TOKEN_STREAMED_KEEP_LOADED:
+ parser.ScanStr((char *)params, "%b", &m_StreamedKeepLoaded);
+ break;
+
+ case TOKEN_NAME:
+ SetName((char *)params);
+ break;
+
+ case TOKEN_EDITOR_BG_FILE:
+ if (Game->m_EditorMode) {
+ SAFE_DELETE_ARRAY(m_EditorBgFile);
+ m_EditorBgFile = new char[strlen((char *)params) + 1];
+ if (m_EditorBgFile) strcpy(m_EditorBgFile, (char *)params);
+ }
+ break;
+
+ case TOKEN_EDITOR_BG_OFFSET_X:
+ parser.ScanStr((char *)params, "%d", &m_EditorBgOffsetX);
+ break;
+
+ case TOKEN_EDITOR_BG_OFFSET_Y:
+ parser.ScanStr((char *)params, "%d", &m_EditorBgOffsetY);
+ break;
+
+ case TOKEN_EDITOR_BG_ALPHA:
+ parser.ScanStr((char *)params, "%d", &m_EditorBgAlpha);
+ m_EditorBgAlpha = std::min(m_EditorBgAlpha, 255);
+ m_EditorBgAlpha = std::max(m_EditorBgAlpha, 0);
+ break;
+
+ case TOKEN_FRAME: {
+ int FrameLifeTime = LifeTime;
+ if (CacheType == CACHE_HALF && frame_count % 2 != 1) FrameLifeTime = -1;
+
+ frame = new CBFrame(Game);
+
+ if (FAILED(frame->LoadBuffer(params, FrameLifeTime, m_StreamedKeepLoaded))) {
+ delete frame;
+ Game->LOG(0, "Error parsing frame %d", frame_count);
+ return E_FAIL;
+ }
+
+ m_Frames.Add(frame);
+ frame_count++;
+ if (m_CurrentFrame == -1) m_CurrentFrame = 0;
+ }
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ ParseEditorProperty(params, false);
+ break;
+ }
+ }
+
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in SPRITE definition");
+ return E_FAIL;
+ }
+ m_CanBreak = !m_Continuous;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+void CBSprite::Reset() {
+ if (m_Frames.GetSize() > 0) m_CurrentFrame = 0;
+ else m_CurrentFrame = -1;
+
+ KillAllSounds();
+
+ m_LastFrameTime = 0;
+ m_Finished = false;
+ m_MoveX = m_MoveY = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+bool CBSprite::GetCurrentFrame(float ZoomX, float ZoomY) {
+ //if(m_Owner && m_Owner->m_Freezable && Game->m_State == GAME_FROZEN) return true;
+
+ if (m_CurrentFrame == -1) return false;
+
+ uint32 timer;
+ if (m_Owner && m_Owner->m_Freezable) timer = Game->m_Timer;
+ else timer = Game->m_LiveTimer;
+
+ int LastFrame = m_CurrentFrame;
+
+ // get current frame
+ if (!m_Paused && !m_Finished && timer >= m_LastFrameTime + m_Frames[m_CurrentFrame]->m_Delay && m_LastFrameTime != 0) {
+ if (m_CurrentFrame < m_Frames.GetSize() - 1) {
+ m_CurrentFrame++;
+ if (m_Continuous) m_CanBreak = (m_CurrentFrame == m_Frames.GetSize() - 1);
+ } else {
+ if (m_Looping) {
+ m_CurrentFrame = 0;
+ m_CanBreak = true;
+ } else {
+ m_Finished = true;
+ m_CanBreak = true;
+ }
+ }
+
+ m_LastFrameTime = timer;
+ }
+
+ m_Changed = (LastFrame != m_CurrentFrame || (m_Looping && m_Frames.GetSize() == 1));
+
+ if (m_LastFrameTime == 0) {
+ m_LastFrameTime = timer;
+ m_Changed = true;
+ if (m_Continuous) m_CanBreak = (m_CurrentFrame == m_Frames.GetSize() - 1);
+ }
+
+ if (m_Changed) {
+ m_MoveX = m_Frames[m_CurrentFrame]->m_MoveX;
+ m_MoveY = m_Frames[m_CurrentFrame]->m_MoveY;
+
+ if (ZoomX != 100 || ZoomY != 100) {
+ m_MoveX = (int)((float)m_MoveX * (float)(ZoomX / 100.0f));
+ m_MoveY = (int)((float)m_MoveY * (float)(ZoomY / 100.0f));
+ }
+ }
+
+ return m_Changed;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::Display(int X, int Y, CBObject *Register, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode) {
+ if (m_CurrentFrame < 0 || m_CurrentFrame >= m_Frames.GetSize()) return S_OK;
+
+ // on change...
+ if (m_Changed) {
+ if (m_Frames[m_CurrentFrame]->m_KillSound) {
+ KillAllSounds();
+ }
+ ApplyEvent("FrameChanged");
+ m_Frames[m_CurrentFrame]->OneTimeDisplay(m_Owner, Game->m_EditorMode && m_EditorMuted);
+ }
+
+ // draw frame
+ return m_Frames[m_CurrentFrame]->Draw(X - Game->m_OffsetX, Y - Game->m_OffsetY, Register, ZoomX, ZoomY, m_Precise, Alpha, m_EditorAllFrames, Rotate, BlendMode);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSurface *CBSprite::GetSurface() {
+ // only used for animated textures for 3D models
+ if (m_CurrentFrame < 0 || m_CurrentFrame >= m_Frames.GetSize()) return NULL;
+ CBFrame *Frame = m_Frames[m_CurrentFrame];
+ if (Frame && Frame->m_Subframes.GetSize() > 0) {
+ CBSubFrame *Subframe = Frame->m_Subframes[0];
+ if (Subframe) return Subframe->m_Surface;
+ else return NULL;
+ } else return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSprite::GetBoundingRect(LPRECT Rect, int X, int Y, float ScaleX, float ScaleY) {
+ if (!Rect) return false;
+
+ CBPlatform::SetRectEmpty(Rect);
+ for (int i = 0; i < m_Frames.GetSize(); i++) {
+ RECT frame;
+ RECT temp;
+ CBPlatform::CopyRect(&temp, Rect);
+ m_Frames[i]->GetBoundingRect(&frame, X, Y, ScaleX, ScaleY);
+ CBPlatform::UnionRect(Rect, &temp, &frame);
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::SaveAsText(CBDynBuffer *Buffer, int Indent) {
+ Buffer->PutTextIndent(Indent, "SPRITE {\n");
+ Buffer->PutTextIndent(Indent + 2, "NAME=\"%s\"\n", m_Name);
+ Buffer->PutTextIndent(Indent + 2, "LOOPING=%s\n", m_Looping ? "TRUE" : "FALSE");
+ Buffer->PutTextIndent(Indent + 2, "CONTINUOUS=%s\n", m_Continuous ? "TRUE" : "FALSE");
+ Buffer->PutTextIndent(Indent + 2, "PRECISE=%s\n", m_Precise ? "TRUE" : "FALSE");
+ if (m_Streamed) {
+ Buffer->PutTextIndent(Indent + 2, "STREAMED=%s\n", m_Streamed ? "TRUE" : "FALSE");
+
+ if (m_StreamedKeepLoaded)
+ Buffer->PutTextIndent(Indent + 2, "STREAMED_KEEP_LOADED=%s\n", m_StreamedKeepLoaded ? "TRUE" : "FALSE");
+ }
+
+ if (m_EditorMuted)
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_MUTED=%s\n", m_EditorMuted ? "TRUE" : "FALSE");
+
+ if (m_EditorBgFile) {
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_BG_FILE=\"%s\"\n", m_EditorBgFile);
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_BG_OFFSET_X=%d\n", m_EditorBgOffsetX);
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_BG_OFFSET_Y=%d\n", m_EditorBgOffsetY);
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_BG_ALPHA=%d\n", m_EditorBgAlpha);
+ }
+
+ CBScriptHolder::SaveAsText(Buffer, Indent + 2);
+
+ int i;
+
+ // scripts
+ for (i = 0; i < m_Scripts.GetSize(); i++) {
+ Buffer->PutTextIndent(Indent + 2, "SCRIPT=\"%s\"\n", m_Scripts[i]->m_Filename);
+ }
+
+
+ for (i = 0; i < m_Frames.GetSize(); i++) {
+ m_Frames[i]->SaveAsText(Buffer, Indent + 2);
+ }
+
+ Buffer->PutTextIndent(Indent, "}\n\n");
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::Persist(CBPersistMgr *PersistMgr) {
+ CBScriptHolder::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_CanBreak));
+ PersistMgr->Transfer(TMEMBER(m_Changed));
+ PersistMgr->Transfer(TMEMBER(m_Paused));
+ PersistMgr->Transfer(TMEMBER(m_Continuous));
+ PersistMgr->Transfer(TMEMBER(m_CurrentFrame));
+ PersistMgr->Transfer(TMEMBER(m_EditorAllFrames));
+ PersistMgr->Transfer(TMEMBER(m_EditorBgAlpha));
+ PersistMgr->Transfer(TMEMBER(m_EditorBgFile));
+ PersistMgr->Transfer(TMEMBER(m_EditorBgOffsetX));
+ PersistMgr->Transfer(TMEMBER(m_EditorBgOffsetY));
+ PersistMgr->Transfer(TMEMBER(m_EditorMuted));
+ PersistMgr->Transfer(TMEMBER(m_Finished));
+
+ m_Frames.Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_LastFrameTime));
+ PersistMgr->Transfer(TMEMBER(m_Looping));
+ PersistMgr->Transfer(TMEMBER(m_MoveX));
+ PersistMgr->Transfer(TMEMBER(m_MoveY));
+ PersistMgr->Transfer(TMEMBER(m_Owner));
+ PersistMgr->Transfer(TMEMBER(m_Precise));
+ PersistMgr->Transfer(TMEMBER(m_Streamed));
+ PersistMgr->Transfer(TMEMBER(m_StreamedKeepLoaded));
+
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+ //////////////////////////////////////////////////////////////////////////
+ // GetFrame
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "GetFrame") == 0) {
+ Stack->CorrectParams(1);
+ int Index = Stack->Pop()->GetInt(-1);
+ if (Index < 0 || Index >= m_Frames.GetSize()) {
+ Script->RuntimeError("Sprite.GetFrame: Frame index %d is out of range.", Index);
+ Stack->PushNULL();
+ } else Stack->PushNative(m_Frames[Index], true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // DeleteFrame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "DeleteFrame") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+ if (Val->IsInt()) {
+ int Index = Val->GetInt(-1);
+ if (Index < 0 || Index >= m_Frames.GetSize()) {
+ Script->RuntimeError("Sprite.DeleteFrame: Frame index %d is out of range.", Index);
+ }
+ } else {
+ CBFrame *Frame = (CBFrame *)Val->GetNative();
+ for (int i = 0; i < m_Frames.GetSize(); i++) {
+ if (m_Frames[i] == Frame) {
+ if (i == m_CurrentFrame) m_LastFrameTime = 0;
+ delete m_Frames[i];
+ m_Frames.RemoveAt(i);
+ break;
+ }
+ }
+ }
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Reset
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Reset") == 0) {
+ Stack->CorrectParams(0);
+ Reset();
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AddFrame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AddFrame") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+ char *Filename = NULL;
+ if (!Val->IsNULL()) Filename = Val->GetString();
+
+ CBFrame *Frame = new CBFrame(Game);
+ if (Filename != NULL) {
+ CBSubFrame *Sub = new CBSubFrame(Game);
+ if (SUCCEEDED(Sub->SetSurface(Filename))) {
+ Sub->SetDefaultRect();
+ Frame->m_Subframes.Add(Sub);
+ } else delete Sub;
+ }
+ m_Frames.Add(Frame);
+
+ Stack->PushNative(Frame, true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // InsertFrame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "InsertFrame") == 0) {
+ Stack->CorrectParams(2);
+ int Index = Stack->Pop()->GetInt();
+ if (Index < 0) Index = 0;
+
+ CScValue *Val = Stack->Pop();
+ char *Filename = NULL;
+ if (!Val->IsNULL()) Filename = Val->GetString();
+
+ CBFrame *Frame = new CBFrame(Game);
+ if (Filename != NULL) {
+ CBSubFrame *Sub = new CBSubFrame(Game);
+ if (SUCCEEDED(Sub->SetSurface(Filename))) Frame->m_Subframes.Add(Sub);
+ else delete Sub;
+ }
+
+ if (Index >= m_Frames.GetSize()) m_Frames.Add(Frame);
+ else m_Frames.InsertAt(Index, Frame);
+
+ Stack->PushNative(Frame, true);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Pause
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Pause") == 0) {
+ Stack->CorrectParams(0);
+ m_Paused = true;
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Play
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Play") == 0) {
+ Stack->CorrectParams(0);
+ m_Paused = false;
+ Stack->PushNULL();
+ return S_OK;
+ }
+
+ else return CBScriptHolder::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBSprite::ScGetProperty(char *Name) {
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("sprite");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // NumFrames (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "NumFrames") == 0) {
+ m_ScValue->SetInt(m_Frames.GetSize());
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // CurrentFrame
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "CurrentFrame") == 0) {
+ m_ScValue->SetInt(m_CurrentFrame);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PixelPerfect
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PixelPerfect") == 0) {
+ m_ScValue->SetBool(m_Precise);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Looping
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Looping") == 0) {
+ m_ScValue->SetBool(m_Looping);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Owner (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Owner") == 0) {
+ if (m_Owner == NULL) m_ScValue->SetNULL();
+ else m_ScValue->SetNative(m_Owner, true);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Finished (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Finished") == 0) {
+ m_ScValue->SetBool(m_Finished);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Paused (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Paused") == 0) {
+ m_ScValue->SetBool(m_Paused);
+ return m_ScValue;
+ }
+
+ else return CBScriptHolder::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // CurrentFrame
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "CurrentFrame") == 0) {
+ m_CurrentFrame = Value->GetInt(0);
+ if (m_CurrentFrame >= m_Frames.GetSize() || m_CurrentFrame < 0) {
+ m_CurrentFrame = -1;
+ }
+ m_LastFrameTime = 0;
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // PixelPerfect
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "PixelPerfect") == 0) {
+ m_Precise = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Looping
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Looping") == 0) {
+ m_Looping = Value->GetBool();
+ return S_OK;
+ }
+
+ else return CBScriptHolder::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBSprite::ScToString() {
+ return "[sprite]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSprite::KillAllSounds() {
+ for (int i = 0; i < m_Frames.GetSize(); i++) {
+ if (m_Frames[i]->m_Sound) m_Frames[i]->m_Sound->Stop();
+ }
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSprite.h b/engines/wintermute/BSprite.h
new file mode 100644
index 0000000000..01a89a6931
--- /dev/null
+++ b/engines/wintermute/BSprite.h
@@ -0,0 +1,90 @@
+/* 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_BSPRITE_H
+#define WINTERMUTE_BSPRITE_H
+
+
+#include "coll_templ.h"
+#include "BScriptHolder.h"
+
+namespace WinterMute {
+class CBFrame;
+class CBSurface;
+class CBObject;
+class CBSprite: public CBScriptHolder {
+public:
+ HRESULT KillAllSounds();
+ CBSurface *GetSurface();
+ char *m_EditorBgFile;
+ int m_EditorBgOffsetX;
+ int m_EditorBgOffsetY;
+ int m_EditorBgAlpha;
+ bool m_Streamed;
+ bool m_StreamedKeepLoaded;
+ void Cleanup();
+ void SetDefaults();
+ bool m_Precise;
+ DECLARE_PERSISTENT(CBSprite, CBScriptHolder)
+
+ bool m_EditorAllFrames;
+ bool GetBoundingRect(LPRECT Rect, int X, int Y, float ScaleX = 100, float ScaleY = 100);
+ int m_MoveY;
+ int m_MoveX;
+ HRESULT Display(int X, int Y, CBObject *Register = NULL, float ZoomX = 100, float ZoomY = 100, uint32 Alpha = 0xFFFFFFFF, float Rotate = 0.0f, TSpriteBlendMode BlendMode = BLEND_NORMAL);
+ bool GetCurrentFrame(float ZoomX = 100, float ZoomY = 100);
+ bool m_CanBreak;
+ bool m_EditorMuted;
+ bool m_Continuous;
+ void Reset();
+ CBObject *m_Owner;
+ bool m_Changed;
+ bool m_Paused;
+ bool m_Finished;
+ HRESULT LoadBuffer(byte *Buffer, bool Compete = true, int LifeTime = -1, TSpriteCacheType CacheType = CACHE_ALL);
+ HRESULT LoadFile(char *Filename, int LifeTime = -1, TSpriteCacheType CacheType = CACHE_ALL);
+ uint32 m_LastFrameTime;
+ HRESULT Draw(int X, int Y, CBObject *Register = NULL, float ZoomX = 100, float ZoomY = 100, uint32 Alpha = 0xFFFFFFFF);
+ bool m_Looping;
+ int m_CurrentFrame;
+ HRESULT AddFrame(char *Filename, uint32 Delay = 0, int HotspotX = 0, int HotspotY = 0, RECT *Rect = NULL);
+ CBSprite(CBGame *inGame, CBObject *Owner = NULL);
+ virtual ~CBSprite();
+ CBArray<CBFrame *, CBFrame *> m_Frames;
+ HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent);
+
+ // 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/BStringTable.cpp b/engines/wintermute/BStringTable.cpp
new file mode 100644
index 0000000000..e3bf2fd89b
--- /dev/null
+++ b/engines/wintermute/BStringTable.cpp
@@ -0,0 +1,229 @@
+/* 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 "PlatformSDL.h"
+#include "BFileManager.h"
+#include "BGame.h"
+#include "BStringTable.h"
+#include "StringUtil.h"
+#include "common/str.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBStringTable::CBStringTable(CBGame *inGame): CBBase(inGame) {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBStringTable::~CBStringTable() {
+ // delete strings
+ m_Strings.clear();
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBStringTable::AddString(const char *Key, const char *Val, bool ReportDuplicities) {
+ if (Key == NULL || Val == NULL) return E_FAIL;
+
+ if (scumm_stricmp(Key, "@right-to-left") == 0) {
+ Game->m_TextRTL = true;
+ return S_OK;
+ }
+
+ std::string final_key = Key;
+ StringUtil::ToLowerCase(final_key);
+
+ m_StringsIter = m_Strings.find(final_key);
+ if (m_StringsIter != m_Strings.end() && ReportDuplicities) Game->LOG(0, " Warning: Duplicate definition of string '%s'.", final_key.c_str());
+
+ m_Strings[final_key] = Val;
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+char *CBStringTable::GetKey(const char *Str) {
+ if (Str == NULL || Str[0] != '/') return NULL;
+
+ char *value = strchr((char *)Str + 1, '/');
+ if (value == NULL) return NULL;
+
+ char *key = new char[value - Str];
+ strncpy(key, Str + 1, value - Str - 1);
+ key[value - Str - 1] = '\0';
+ CBPlatform::strlwr(key);
+
+ char *new_str;
+
+ m_StringsIter = m_Strings.find(key);
+ if (m_StringsIter != m_Strings.end()) {
+ new_str = new char[m_StringsIter->second.length() + 1];
+ strcpy(new_str, m_StringsIter->second.c_str());
+ if (strlen(new_str) > 0 && new_str[0] == '/' && strchr(new_str + 1, '/')) {
+ delete [] key;
+ char *Ret = GetKey(new_str);
+ delete [] new_str;
+ return Ret;
+ } else {
+ delete [] new_str;
+ return key;
+ }
+ } else {
+ return key;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBStringTable::Expand(char **Str, bool ForceExpand) {
+ if (Game->m_DoNotExpandStrings && !ForceExpand) return;
+
+ if (Str == NULL || *Str == NULL || *Str[0] != '/') return;
+
+ char *value = strchr(*Str + 1, '/');
+ if (value == NULL) return;
+
+ char *key = new char[value - *Str];
+ strncpy(key, *Str + 1, value - *Str - 1);
+ key[value - *Str - 1] = '\0';
+ CBPlatform::strlwr(key);
+
+ value++;
+
+ char *new_str;
+
+ m_StringsIter = m_Strings.find(key);
+ if (m_StringsIter != m_Strings.end()) {
+ new_str = new char[m_StringsIter->second.length() + 1];
+ strcpy(new_str, m_StringsIter->second.c_str());
+ } else {
+ new_str = new char[strlen(value) + 1];
+ strcpy(new_str, value);
+ }
+
+ delete [] key;
+ delete [] *Str;
+ *Str = new_str;
+
+ if (strlen(*Str) > 0 && *Str[0] == '/') Expand(Str, ForceExpand);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+const char *CBStringTable::ExpandStatic(const char *String, bool ForceExpand) {
+ if (Game->m_DoNotExpandStrings && !ForceExpand) return String;
+
+ if (String == NULL || String[0] == '\0' || String[0] != '/') return String;
+
+ const char *value = strchr(String + 1, '/');
+ if (value == NULL) return String;
+
+ char *key = new char[value - String];
+ strncpy(key, String + 1, value - String - 1);
+ key[value - String - 1] = '\0';
+ CBPlatform::strlwr(key);
+
+ value++;
+
+ const char *new_str;
+
+ m_StringsIter = m_Strings.find(key);
+ if (m_StringsIter != m_Strings.end()) {
+ new_str = m_StringsIter->second.c_str();
+ } else {
+ new_str = value;
+ }
+
+ delete [] key;
+
+ if (strlen(new_str) > 0 && new_str[0] == '/') return ExpandStatic(new_str, ForceExpand);
+ else return new_str;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBStringTable::LoadFile(char *Filename, bool ClearOld) {
+ Game->LOG(0, "Loading string table...");
+
+ if (ClearOld) m_Strings.clear();
+
+ uint32 Size;
+ byte *Buffer = Game->m_FileManager->ReadWholeFile(Filename, &Size);
+ if (Buffer == NULL) {
+ Game->LOG(0, "CBStringTable::LoadFile failed for file '%s'", Filename);
+ return E_FAIL;
+ }
+
+ int Pos = 0;
+
+ if (Size > 3 && Buffer[0] == 0xEF && Buffer[1] == 0xBB && Buffer[2] == 0xBF) {
+ Pos += 3;
+ if (Game->m_TextEncoding != TEXT_UTF8) {
+ Game->m_TextEncoding = TEXT_UTF8;
+ //Game->m_TextEncoding = TEXT_ANSI;
+ Game->LOG(0, " UTF8 file detected, switching to UTF8 text encoding");
+ }
+ } else Game->m_TextEncoding = TEXT_ANSI;
+
+ int LineLength = 0;
+ while (Pos < Size) {
+ LineLength = 0;
+ while (Pos + LineLength < Size && Buffer[Pos + LineLength] != '\n' && Buffer[Pos + LineLength] != '\0') LineLength++;
+
+ int RealLength = LineLength - (Pos + LineLength >= Size ? 0 : 1);
+ char *line = new char[RealLength + 1];
+ strncpy(line, (char *)&Buffer[Pos], RealLength);
+ line[RealLength] = '\0';
+ char *value = strchr(line, '\t');
+ if (value == NULL) value = strchr(line, ' ');
+
+ if (line[0] != ';') {
+ if (value != NULL) {
+ value[0] = '\0';
+ value++;
+ for (int i = 0; i < strlen(value); i++) {
+ if (value[i] == '|') value[i] = '\n';
+ }
+ AddString(line, value, ClearOld);
+ } else if (line[0] != '\0') AddString(line, "", ClearOld);
+ }
+
+ delete [] line;
+ Pos += LineLength + 1;
+ }
+
+ delete [] Buffer;
+
+ Game->LOG(0, " %d strings loaded", m_Strings.size());
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BStringTable.h b/engines/wintermute/BStringTable.h
new file mode 100644
index 0000000000..6b28f5307d
--- /dev/null
+++ b/engines/wintermute/BStringTable.h
@@ -0,0 +1,55 @@
+/* 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_BSTRINGTABLE_H
+#define WINTERMUTE_BSTRINGTABLE_H
+
+
+#include <map>
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBStringTable : public CBBase {
+public:
+ const char *ExpandStatic(const char *String, bool ForceExpand = false);
+ HRESULT LoadFile(char *Filename, bool DeleteAll = true);
+ void Expand(char **Str, bool ForceExpand = false);
+ HRESULT AddString(const char *Key, const char *Val, bool ReportDuplicities = true);
+ CBStringTable(CBGame *inGame);
+ virtual ~CBStringTable();
+ std::map<std::string, std::string> m_Strings;
+ char *GetKey(const char *Str);
+private:
+ std::map<std::string, std::string>::iterator m_StringsIter;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSubFrame.cpp b/engines/wintermute/BSubFrame.cpp
new file mode 100644
index 0000000000..415bcc7b52
--- /dev/null
+++ b/engines/wintermute/BSubFrame.cpp
@@ -0,0 +1,588 @@
+/* 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 "BSubFrame.h"
+#include "BActiveRect.h"
+#include "BDynBuffer.h"
+#include "BSurface.h"
+#include "ScValue.h"
+#include "ScStack.h"
+#include "BGame.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBSubFrame, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBSubFrame::CBSubFrame(CBGame *inGame): CBScriptable(inGame, true) {
+ m_Surface = NULL;
+ m_HotspotX = m_HotspotY = 0;
+ m_Alpha = 0xFFFFFFFF;
+ m_Transparent = 0xFFFF00FF;
+
+ CBPlatform::SetRectEmpty(&m_Rect);
+
+ m_EditorSelected = false;
+
+ m_SurfaceFilename = NULL;
+ m_CKDefault = true;
+ m_CKRed = m_CKBlue = m_CKGreen = 0;
+ m_LifeTime = -1;
+ m_KeepLoaded = false;
+
+ m_2DOnly = m_3DOnly = false;
+ m_Decoration = false;
+
+ m_MirrorX = m_MirrorY = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBSubFrame::~CBSubFrame() {
+ if (m_Surface) Game->m_SurfaceStorage->RemoveSurface(m_Surface);
+ delete[] m_SurfaceFilename;
+ m_SurfaceFilename = NULL;
+}
+
+
+TOKEN_DEF_START
+TOKEN_DEF(IMAGE)
+TOKEN_DEF(TRANSPARENT)
+TOKEN_DEF(RECT)
+TOKEN_DEF(HOTSPOT)
+TOKEN_DEF(2D_ONLY)
+TOKEN_DEF(3D_ONLY)
+TOKEN_DEF(DECORATION)
+TOKEN_DEF(ALPHA_COLOR)
+TOKEN_DEF(ALPHA)
+TOKEN_DEF(MIRROR_X)
+TOKEN_DEF(MIRROR_Y)
+TOKEN_DEF(EDITOR_SELECTED)
+TOKEN_DEF(EDITOR_PROPERTY)
+TOKEN_DEF_END
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::LoadBuffer(byte *Buffer, int LifeTime, bool KeepLoaded) {
+ TOKEN_TABLE_START(commands)
+ TOKEN_TABLE(IMAGE)
+ TOKEN_TABLE(TRANSPARENT)
+ TOKEN_TABLE(RECT)
+ TOKEN_TABLE(HOTSPOT)
+ TOKEN_TABLE(2D_ONLY)
+ TOKEN_TABLE(3D_ONLY)
+ TOKEN_TABLE(DECORATION)
+ TOKEN_TABLE(ALPHA_COLOR)
+ TOKEN_TABLE(ALPHA)
+ TOKEN_TABLE(MIRROR_X)
+ TOKEN_TABLE(MIRROR_Y)
+ TOKEN_TABLE(EDITOR_SELECTED)
+ TOKEN_TABLE(EDITOR_PROPERTY)
+ TOKEN_TABLE_END
+
+ char *params;
+ int cmd;
+ CBParser parser(Game);
+ RECT rect;
+ int r = 255, g = 255, b = 255;
+ int ar = 255, ag = 255, ab = 255, alpha = 255;
+ bool custom_trans = false;
+ CBPlatform::SetRectEmpty(&rect);
+ char *surface_file = NULL;
+
+ delete m_Surface;
+ m_Surface = NULL;
+
+ while ((cmd = parser.GetCommand((char **)&Buffer, commands, &params)) > 0) {
+ switch (cmd) {
+ case TOKEN_IMAGE:
+ surface_file = params;
+ break;
+
+ case TOKEN_TRANSPARENT:
+ parser.ScanStr(params, "%d,%d,%d", &r, &g, &b);
+ custom_trans = true;
+ break;
+
+ case TOKEN_RECT:
+ parser.ScanStr(params, "%d,%d,%d,%d", &rect.left, &rect.top, &rect.right, &rect.bottom);
+ break;
+
+ case TOKEN_HOTSPOT:
+ parser.ScanStr(params, "%d,%d", &m_HotspotX, &m_HotspotY);
+ break;
+
+ case TOKEN_2D_ONLY:
+ parser.ScanStr(params, "%b", &m_2DOnly);
+ break;
+
+ case TOKEN_3D_ONLY:
+ parser.ScanStr(params, "%b", &m_3DOnly);
+ break;
+
+ case TOKEN_MIRROR_X:
+ parser.ScanStr(params, "%b", &m_MirrorX);
+ break;
+
+ case TOKEN_MIRROR_Y:
+ parser.ScanStr(params, "%b", &m_MirrorY);
+ break;
+
+ case TOKEN_DECORATION:
+ parser.ScanStr(params, "%b", &m_Decoration);
+ break;
+
+ case TOKEN_ALPHA_COLOR:
+ parser.ScanStr(params, "%d,%d,%d", &ar, &ag, &ab);
+ break;
+
+ case TOKEN_ALPHA:
+ parser.ScanStr(params, "%d", &alpha);
+ break;
+
+ case TOKEN_EDITOR_SELECTED:
+ parser.ScanStr(params, "%b", &m_EditorSelected);
+ break;
+
+ case TOKEN_EDITOR_PROPERTY:
+ ParseEditorProperty((byte *)params, false);
+ break;
+ }
+ }
+ if (cmd == PARSERR_TOKENNOTFOUND) {
+ Game->LOG(0, "Syntax error in SUBFRAME definition");
+ return E_FAIL;
+ }
+
+ if (surface_file != NULL) {
+ if (custom_trans) SetSurface(surface_file, false, r, g, b, LifeTime, KeepLoaded);
+ else SetSurface(surface_file, true, 0, 0, 0, LifeTime, KeepLoaded);
+ }
+
+ m_Alpha = DRGBA(ar, ag, ab, alpha);
+ if (custom_trans) m_Transparent = DRGBA(r, g, b, 0xFF);
+
+ /*
+ if(m_Surface == NULL)
+ {
+ Game->LOG(0, "Error parsing sub-frame. Image not set.");
+ return E_FAIL;
+ }
+ */
+ if (CBPlatform::IsRectEmpty(&rect)) SetDefaultRect();
+ else m_Rect = rect;
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::Draw(int X, int Y, CBObject *Register, float ZoomX, float ZoomY, bool Precise, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode) {
+ if (!m_Surface) return S_OK;
+
+ if (Register != NULL && !m_Decoration) {
+ if (ZoomX == 100 && ZoomY == 100) {
+ Game->m_Renderer->m_RectList.Add(new CBActiveRect(Game, Register, this, X - m_HotspotX + m_Rect.left, Y - m_HotspotY + m_Rect.top, m_Rect.right - m_Rect.left, m_Rect.bottom - m_Rect.top, ZoomX, ZoomY, Precise));
+ } else {
+ Game->m_Renderer->m_RectList.Add(new CBActiveRect(Game, Register, this, (int)(X - (m_HotspotX + m_Rect.left) * (ZoomX / 100)), (int)(Y - (m_HotspotY + m_Rect.top) * (ZoomY / 100)), (int)((m_Rect.right - m_Rect.left) * (ZoomX / 100)), (int)((m_Rect.bottom - m_Rect.top) * (ZoomY / 100)), ZoomX, ZoomY, Precise));
+ }
+ }
+ if (Game->m_SuspendedRendering) return S_OK;
+
+ HRESULT res;
+
+ //if(Alpha==0xFFFFFFFF) Alpha = m_Alpha; // TODO: better (combine owner's and self alpha)
+ if (m_Alpha != 0xFFFFFFFF) Alpha = m_Alpha;
+
+ if (Rotate != 0.0f) {
+ res = m_Surface->DisplayTransform((int)(X - m_HotspotX * (ZoomX / 100)), (int)(Y - m_HotspotY * (ZoomY / 100)), m_HotspotX, m_HotspotY, m_Rect, ZoomX, ZoomY, Alpha, Rotate, BlendMode, m_MirrorX, m_MirrorY);
+ } else {
+ if (ZoomX == 100 && ZoomY == 100) res = m_Surface->DisplayTrans(X - m_HotspotX, Y - m_HotspotY, m_Rect, Alpha, BlendMode, m_MirrorX, m_MirrorY);
+ else res = m_Surface->DisplayTransZoom((int)(X - m_HotspotX * (ZoomX / 100)), (int)(Y - m_HotspotY * (ZoomY / 100)), m_Rect, ZoomX, ZoomY, Alpha, BlendMode, m_MirrorX, m_MirrorY);
+ }
+
+ return res;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSubFrame::GetBoundingRect(LPRECT Rect, int X, int Y, float ScaleX, float ScaleY) {
+ if (!Rect) return false;
+
+ float RatioX = ScaleX / 100.0f;
+ float RatioY = ScaleY / 100.0f;
+
+ CBPlatform::SetRect(Rect,
+ X - m_HotspotX * RatioX,
+ Y - m_HotspotY * RatioY,
+ X - m_HotspotX * RatioX + (m_Rect.right - m_Rect.left)*RatioX,
+ Y - m_HotspotY * RatioY + (m_Rect.bottom - m_Rect.top)*RatioY);
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::SaveAsText(CBDynBuffer *Buffer, int Indent, bool Complete) {
+ if (Complete)
+ Buffer->PutTextIndent(Indent, "SUBFRAME {\n");
+
+ if (m_Surface && m_Surface->m_Filename != NULL)
+ Buffer->PutTextIndent(Indent + 2, "IMAGE = \"%s\"\n", m_Surface->m_Filename);
+
+ if (m_Transparent != 0xFFFF00FF)
+ Buffer->PutTextIndent(Indent + 2, "TRANSPARENT { %d,%d,%d }\n", D3DCOLGetR(m_Transparent), D3DCOLGetG(m_Transparent), D3DCOLGetB(m_Transparent));
+
+ RECT rect;
+ CBPlatform::SetRectEmpty(&rect);
+ if (m_Surface) CBPlatform::SetRect(&rect, 0, 0, m_Surface->GetWidth(), m_Surface->GetHeight());
+ if (!CBPlatform::EqualRect(&rect, &m_Rect))
+ Buffer->PutTextIndent(Indent + 2, "RECT { %d,%d,%d,%d }\n", m_Rect.left, m_Rect.top, m_Rect.right, m_Rect.bottom);
+
+ if (m_HotspotX != 0 || m_HotspotY != 0)
+ Buffer->PutTextIndent(Indent + 2, "HOTSPOT {%d, %d}\n", m_HotspotX, m_HotspotY);
+
+ if (m_Alpha != 0xFFFFFFFF) {
+ Buffer->PutTextIndent(Indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", D3DCOLGetR(m_Alpha), D3DCOLGetG(m_Alpha), D3DCOLGetB(m_Alpha));
+ Buffer->PutTextIndent(Indent + 2, "ALPHA = %d\n", D3DCOLGetA(m_Alpha));
+ }
+
+ if (m_MirrorX)
+ Buffer->PutTextIndent(Indent + 2, "MIRROR_X=%s\n", m_MirrorX ? "TRUE" : "FALSE");
+
+ if (m_MirrorY)
+ Buffer->PutTextIndent(Indent + 2, "MIRROR_Y=%s\n", m_MirrorY ? "TRUE" : "FALSE");
+
+ if (m_2DOnly)
+ Buffer->PutTextIndent(Indent + 2, "2D_ONLY=%s\n", m_2DOnly ? "TRUE" : "FALSE");
+
+ if (m_3DOnly)
+ Buffer->PutTextIndent(Indent + 2, "3D_ONLY=%s\n", m_3DOnly ? "TRUE" : "FALSE");
+
+ if (m_Decoration)
+ Buffer->PutTextIndent(Indent + 2, "DECORATION=%s\n", m_Decoration ? "TRUE" : "FALSE");
+
+ if (m_EditorSelected)
+ Buffer->PutTextIndent(Indent + 2, "EDITOR_SELECTED=%s\n", m_EditorSelected ? "TRUE" : "FALSE");
+
+ CBBase::SaveAsText(Buffer, Indent + 2);
+
+
+ if (Complete)
+ Buffer->PutTextIndent(Indent, "}\n\n");
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBSubFrame::SetDefaultRect() {
+ if (m_Surface) {
+ CBPlatform::SetRect(&m_Rect, 0, 0, m_Surface->GetWidth(), m_Surface->GetHeight());
+ } else CBPlatform::SetRectEmpty(&m_Rect);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::Persist(CBPersistMgr *PersistMgr) {
+
+ CBScriptable::Persist(PersistMgr);
+
+ PersistMgr->Transfer(TMEMBER(m_2DOnly));
+ PersistMgr->Transfer(TMEMBER(m_3DOnly));
+ PersistMgr->Transfer(TMEMBER(m_Alpha));
+ PersistMgr->Transfer(TMEMBER(m_Decoration));
+ PersistMgr->Transfer(TMEMBER(m_EditorSelected));
+ PersistMgr->Transfer(TMEMBER(m_HotspotX));
+ PersistMgr->Transfer(TMEMBER(m_HotspotY));
+ PersistMgr->Transfer(TMEMBER(m_Rect));
+
+ PersistMgr->Transfer(TMEMBER(m_SurfaceFilename));
+ PersistMgr->Transfer(TMEMBER(m_CKDefault));
+ PersistMgr->Transfer(TMEMBER(m_CKRed));
+ PersistMgr->Transfer(TMEMBER(m_CKGreen));
+ PersistMgr->Transfer(TMEMBER(m_CKBlue));
+ PersistMgr->Transfer(TMEMBER(m_LifeTime));
+
+ PersistMgr->Transfer(TMEMBER(m_KeepLoaded));
+ PersistMgr->Transfer(TMEMBER(m_MirrorX));
+ PersistMgr->Transfer(TMEMBER(m_MirrorY));
+ PersistMgr->Transfer(TMEMBER(m_Transparent));
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// high level scripting interface
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // GetImage
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "GetImage") == 0) {
+ Stack->CorrectParams(0);
+
+ if (!m_SurfaceFilename) Stack->PushNULL();
+ else Stack->PushString(m_SurfaceFilename);
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // SetImage
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "SetImage") == 0) {
+ Stack->CorrectParams(1);
+ CScValue *Val = Stack->Pop();
+
+ if (Val->IsNULL()) {
+ if (m_Surface) Game->m_SurfaceStorage->RemoveSurface(m_Surface);
+ delete[] m_SurfaceFilename;
+ m_SurfaceFilename = NULL;
+ Stack->PushBool(true);
+ } else {
+ char *Filename = Val->GetString();
+ if (SUCCEEDED(SetSurface(Filename))) {
+ SetDefaultRect();
+ Stack->PushBool(true);
+ } else Stack->PushBool(false);
+ }
+
+ return S_OK;
+ }
+
+ else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CScValue *CBSubFrame::ScGetProperty(char *Name) {
+ if (!m_ScValue) m_ScValue = new CScValue(Game);
+ m_ScValue->SetNULL();
+
+ //////////////////////////////////////////////////////////////////////////
+ // Type (RO)
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "Type") == 0) {
+ m_ScValue->SetString("subframe");
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // AlphaColor
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "AlphaColor") == 0) {
+
+ m_ScValue->SetInt((int)m_Alpha);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // TransparentColor (RO)
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "TransparentColor") == 0) {
+ m_ScValue->SetInt((int)m_Transparent);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Is2DOnly
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Is2DOnly") == 0) {
+ m_ScValue->SetBool(m_2DOnly);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Is3DOnly
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Is3DOnly") == 0) {
+ m_ScValue->SetBool(m_3DOnly);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MirrorX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MirrorX") == 0) {
+ m_ScValue->SetBool(m_MirrorX);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MirrorY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MirrorY") == 0) {
+ m_ScValue->SetBool(m_MirrorY);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Decoration
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Decoration") == 0) {
+ m_ScValue->SetBool(m_Decoration);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HotspotX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HotspotX") == 0) {
+ m_ScValue->SetInt(m_HotspotX);
+ return m_ScValue;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HotspotY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HotspotY") == 0) {
+ m_ScValue->SetInt(m_HotspotY);
+ return m_ScValue;
+ }
+
+ else return CBScriptable::ScGetProperty(Name);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::ScSetProperty(char *Name, CScValue *Value) {
+ //////////////////////////////////////////////////////////////////////////
+ // AlphaColor
+ //////////////////////////////////////////////////////////////////////////
+ if (strcmp(Name, "AlphaColor") == 0) {
+ m_Alpha = (uint32)Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Is2DOnly
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Is2DOnly") == 0) {
+ m_2DOnly = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Is3DOnly
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Is3DOnly") == 0) {
+ m_3DOnly = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MirrorX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MirrorX") == 0) {
+ m_MirrorX = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // MirrorY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "MirrorY") == 0) {
+ m_MirrorY = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Decoration
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "Decoration") == 0) {
+ m_Decoration = Value->GetBool();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HotspotX
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HotspotX") == 0) {
+ m_HotspotX = Value->GetInt();
+ return S_OK;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // HotspotY
+ //////////////////////////////////////////////////////////////////////////
+ else if (strcmp(Name, "HotspotY") == 0) {
+ m_HotspotY = Value->GetInt();
+ return S_OK;
+ }
+
+ else return CBScriptable::ScSetProperty(Name, Value);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+char *CBSubFrame::ScToString() {
+ return "[subframe]";
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::SetSurface(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime, bool KeepLoaded) {
+ if (m_Surface) {
+ Game->m_SurfaceStorage->RemoveSurface(m_Surface);
+ m_Surface = NULL;
+ }
+
+ delete[] m_SurfaceFilename;
+ m_SurfaceFilename = NULL;
+
+ m_Surface = Game->m_SurfaceStorage->AddSurface(Filename, default_ck, ck_red, ck_green, ck_blue, LifeTime, KeepLoaded);
+ if (m_Surface) {
+ m_SurfaceFilename = new char[strlen(Filename) + 1];
+ strcpy(m_SurfaceFilename, Filename);
+
+ m_CKDefault = default_ck;
+ m_CKRed = ck_red;
+ m_CKGreen = ck_green;
+ m_CKBlue = ck_blue;
+ m_LifeTime = LifeTime;
+ m_KeepLoaded = KeepLoaded;
+
+ return S_OK;
+ } else return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSubFrame::SetSurfaceSimple() {
+ if (!m_SurfaceFilename) {
+ m_Surface = NULL;
+ return S_OK;
+ }
+ m_Surface = Game->m_SurfaceStorage->AddSurface(m_SurfaceFilename, m_CKDefault, m_CKRed, m_CKGreen, m_CKBlue, m_LifeTime, m_KeepLoaded);
+ if (m_Surface) return S_OK;
+ else return E_FAIL;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSubFrame.h b/engines/wintermute/BSubFrame.h
new file mode 100644
index 0000000000..6147b75811
--- /dev/null
+++ b/engines/wintermute/BSubFrame.h
@@ -0,0 +1,85 @@
+/* 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_BSUBFRAME_H
+#define WINTERMUTE_BSUBFRAME_H
+
+
+#include "BBase.h"
+#include "BScriptable.h"
+
+namespace WinterMute {
+class CBObject;
+class CBSurface;
+class CBSubFrame : public CBScriptable {
+public:
+ bool m_MirrorX;
+ bool m_MirrorY;
+ bool m_Decoration;
+ HRESULT SetSurface(char *Filename, bool default_ck = true, byte ck_red = 0, byte ck_green = 0, byte ck_blue = 0, int LifeTime = -1, bool KeepLoaded = false);
+ HRESULT SetSurfaceSimple();
+ DECLARE_PERSISTENT(CBSubFrame, CBScriptable)
+ void SetDefaultRect();
+ uint32 m_Transparent;
+ HRESULT SaveAsText(CBDynBuffer *Buffer, int Indent, bool Complete = true);
+ bool m_EditorSelected;
+ CBSubFrame(CBGame *inGame);
+ virtual ~CBSubFrame();
+ HRESULT LoadBuffer(byte *Buffer, int LifeTime, bool KeepLoaded);
+ HRESULT Draw(int X, int Y, CBObject *Register = NULL, float ZoomX = 100, float ZoomY = 100, bool Precise = true, uint32 Alpha = 0xFFFFFFFF, float Rotate = 0.0f, TSpriteBlendMode BlendMode = BLEND_NORMAL);
+ bool GetBoundingRect(LPRECT Rect, int X, int Y, float ScaleX = 100, float ScaleY = 100);
+
+ int m_HotspotX;
+ int m_HotspotY;
+ uint32 m_Alpha;
+ RECT m_Rect;
+
+ bool m_CKDefault;
+ byte m_CKRed;
+ byte m_CKGreen;
+ byte m_CKBlue;
+ int m_LifeTime;
+ bool m_KeepLoaded;
+ char *m_SurfaceFilename;
+
+ bool m_2DOnly;
+ bool m_3DOnly;
+
+ CBSurface *m_Surface;
+
+ // 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/BSurface.cpp b/engines/wintermute/BSurface.cpp
new file mode 100644
index 0000000000..16deda3c59
--- /dev/null
+++ b/engines/wintermute/BSurface.cpp
@@ -0,0 +1,196 @@
+/* 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 "wintypes.h"
+#include "BGame.h"
+#include "BSurface.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////
+CBSurface::CBSurface(CBGame *inGame): CBBase(inGame) {
+ m_ReferenceCount = 0;
+
+ m_Width = m_Height = 0;
+
+ m_Filename = NULL;
+
+ m_PixelOpReady = false;
+
+ m_CKDefault = true;
+ m_CKRed = m_CKGreen = m_CKBlue = 0;
+ m_LifeTime = 0;
+ m_KeepLoaded = false;
+
+ m_LastUsedTime = 0;
+ m_Valid = false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBSurface::~CBSurface() {
+ if (m_PixelOpReady) EndPixelOp();
+ if (m_Filename) delete [] m_Filename;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::Create(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime, bool KeepLoaded) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::Restore() {
+ return E_FAIL;
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////
+bool CBSurface::IsTransparentAt(int X, int Y) {
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::Display(int X, int Y, RECT rect, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::DisplayTrans(int X, int Y, RECT rect, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::DisplayTransOffset(int X, int Y, RECT rect, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY, int offsetX, int offsetY) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::DisplayTransZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::DisplayZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha, bool Transparent, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::DisplayHalfTrans(int X, int Y, RECT rect) {
+ return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::DisplayTransform(int X, int Y, int HotX, int HotY, RECT Rect, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return DisplayTransZoom(X, Y, Rect, ZoomX, ZoomY, Alpha, BlendMode, MirrorX, MirrorY);
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::Create(int Width, int Height) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::StartPixelOp() {
+ return E_FAIL;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::EndPixelOp() {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::GetPixel(int X, int Y, byte *R, byte *G, byte *B, byte *A) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::PutPixel(int X, int Y, byte R, byte G, byte B, int A) {
+ return E_FAIL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSurface::ComparePixel(int X, int Y, byte R, byte G, byte B, int A) {
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+bool CBSurface::IsTransparentAtLite(int X, int Y) {
+ return false;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::Invalidate() {
+ return E_FAIL;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurface::PrepareToDraw() {
+ m_LastUsedTime = Game->m_LiveTimer;
+
+ if (!m_Valid) {
+ //Game->LOG(0, "Reviving: %s", m_Filename);
+ return Create(m_Filename, m_CKDefault, m_CKRed, m_CKGreen, m_CKBlue, m_LifeTime, m_KeepLoaded);
+ } else return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+void CBSurface::SetFilename(const char *Filename) {
+ delete[] m_Filename;
+ m_Filename = NULL;
+ if (!Filename) return;
+
+ m_Filename = new char[strlen(Filename) + 1];
+ if (m_Filename) strcpy(m_Filename, Filename);
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBSurface::SetSize(int Width, int Height) {
+ m_Width = Width;
+ m_Height = Height;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSurface.h b/engines/wintermute/BSurface.h
new file mode 100644
index 0000000000..5fa355fcfa
--- /dev/null
+++ b/engines/wintermute/BSurface.h
@@ -0,0 +1,93 @@
+/* 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_BSURFACE_H
+#define WINTERMUTE_BSURFACE_H
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBSurface: public CBBase {
+public:
+ virtual HRESULT Invalidate();
+ virtual HRESULT PrepareToDraw();
+ bool m_CKDefault;
+ byte m_CKRed;
+ byte m_CKGreen;
+ byte m_CKBlue;
+
+ uint32 m_LastUsedTime;
+ bool m_Valid;
+ int m_LifeTime;
+ bool m_KeepLoaded;
+
+ bool m_PixelOpReady;
+ CBSurface(CBGame *inGame);
+ virtual ~CBSurface();
+
+ virtual HRESULT DisplayHalfTrans(int X, int Y, RECT rect);
+ virtual bool IsTransparentAt(int X, int Y);
+ virtual HRESULT DisplayTransZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha = 0xFFFFFFFF, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ virtual HRESULT DisplayTrans(int X, int Y, RECT rect, uint32 Alpha = 0xFFFFFFFF, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ virtual HRESULT DisplayTransOffset(int X, int Y, RECT rect, uint32 Alpha = 0xFFFFFFFF, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false, int offsetX = 0, int offsetY = 0);
+ virtual HRESULT Display(int X, int Y, RECT rect, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ virtual HRESULT DisplayZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha = 0xFFFFFFFF, bool Transparent = false, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ virtual HRESULT DisplayTransform(int X, int Y, int HotX, int HotY, RECT Rect, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ virtual HRESULT Restore();
+ virtual HRESULT Create(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime = -1, bool KeepLoaded = false);
+ virtual HRESULT Create(int Width, int Height);
+ virtual HRESULT PutPixel(int X, int Y, byte R, byte G, byte B, int A = -1);
+ virtual HRESULT GetPixel(int X, int Y, byte *R, byte *G, byte *B, byte *A = NULL);
+ virtual bool ComparePixel(int X, int Y, byte R, byte G, byte B, int A = -1);
+ virtual HRESULT StartPixelOp();
+ virtual HRESULT EndPixelOp();
+ virtual bool IsTransparentAtLite(int X, int Y);
+ void SetFilename(const char *Filename);
+ void SetSize(int Width, int Height);
+
+ int m_ReferenceCount;
+ char *m_Filename;
+
+ int GetWidth() {
+ return m_Width;
+ }
+ int GetHeight() {
+ return m_Height;
+ }
+ //void SetWidth(int Width){ m_Width = Width; }
+ //void SetHeight(int Height){ m_Height = Height; }
+protected:
+ int m_Height;
+ int m_Width;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BSurfaceSDL.cpp b/engines/wintermute/BSurfaceSDL.cpp
new file mode 100644
index 0000000000..66c9256cf0
--- /dev/null
+++ b/engines/wintermute/BSurfaceSDL.cpp
@@ -0,0 +1,402 @@
+/* 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 "BFile.h"
+#include "BGame.h"
+#include "BSurfaceSDL.h"
+#include "BRenderSDL.h"
+#include "SdlUtil.h"
+#include "graphics/decoders/png.h"
+#include "graphics/decoders/bmp.h"
+#include "graphics/pixelformat.h"
+#include "graphics/surface.h"
+#include "stream.h"
+#include "BFileManager.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBSurfaceSDL::CBSurfaceSDL(CBGame *inGame) : CBSurface(inGame) {
+ m_Texture = NULL;
+ m_AlphaMask = NULL;
+
+ m_LockPixels = NULL;
+ m_LockPitch = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+CBSurfaceSDL::~CBSurfaceSDL() {
+ if (m_Texture) SDL_DestroyTexture(m_Texture);
+ delete[] m_AlphaMask;
+ m_AlphaMask = NULL;
+
+ Game->AddMem(-m_Width * m_Height * 4);
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::Create(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime, bool KeepLoaded) {
+ CBRenderSDL *renderer = static_cast<CBRenderSDL *>(Game->m_Renderer);
+ Common::String strFileName(Filename);
+
+ Graphics::ImageDecoder *imgDecoder;
+
+ if (strFileName.hasSuffix(".png")) {
+ imgDecoder = new Graphics::PNGDecoder();
+ } else if (strFileName.hasSuffix(".bmp")) {
+ imgDecoder = new Graphics::BitmapDecoder();
+ } else {
+ error("CBSurfaceSDL::Create : Unsupported fileformat %s", Filename);
+ }
+
+ CBFile *file = Game->m_FileManager->OpenFile(Filename);
+ if (!file) return E_FAIL;
+
+ imgDecoder->loadStream(*file->getMemStream());
+ const Graphics::Surface *surface = imgDecoder->getSurface();
+ Game->m_FileManager->CloseFile(file);
+
+ if (default_ck) {
+ ck_red = 255;
+ ck_green = 0;
+ ck_blue = 255;
+ }
+
+ m_Width = surface->w;
+ m_Height = surface->h;
+
+ bool isSaveGameGrayscale = scumm_strnicmp(Filename, "savegame:", 9) == 0 && (Filename[strFileName.size() - 1] == 'g' || Filename[strFileName.size() - 1] == 'G');
+ if (isSaveGameGrayscale) {
+ warning("grayscaleConversion not yet implemented");
+/* FIBITMAP *newImg = FreeImage_ConvertToGreyscale(img);
+ if (newImg) {
+ FreeImage_Unload(img);
+ img = newImg;
+ }*/
+ }
+
+ // convert 32-bit BMPs to 24-bit or they appear totally transparent (does any app actually write alpha in BMP properly?)
+/* if (FreeImage_GetBPP(img) != 32 || (imgFormat == FIF_BMP && FreeImage_GetBPP(img) != 24)) {
+ FIBITMAP *newImg = FreeImage_ConvertTo24Bits(img);
+ if (newImg) {
+ FreeImage_Unload(img);
+ img = newImg;
+ } else {
+ FreeImage_Unload(img);
+ return -1;
+ }
+ }
+
+ FreeImage_FlipVertical(img);*/
+
+ //TODO: This is rather endian-specific, but should be replaced by non-SDL-code anyhow:
+ uint32 rmask = surface->format.rMax() << surface->format.rShift;
+ uint32 gmask = surface->format.gMax() << surface->format.gShift;
+ uint32 bmask = surface->format.bMax() << surface->format.bShift;
+ uint32 amask = surface->format.aMax();
+
+ SDL_Surface *surf = SDL_CreateRGBSurfaceFrom(surface->pixels, m_Width, m_Height, surface->format.bytesPerPixel * 8, surface->pitch, rmask, gmask, bmask, amask);
+
+ // no alpha, set color key
+ if (surface->format.bytesPerPixel != 4)
+ SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf->format, ck_red, ck_green, ck_blue));
+
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
+ //m_Texture = SdlUtil::CreateTextureFromSurface(renderer->GetSdlRenderer(), surf);
+ m_Texture = SDL_CreateTextureFromSurface(renderer->GetSdlRenderer(), surf);
+ if (!m_Texture) {
+ SDL_FreeSurface(surf);
+ delete imgDecoder;
+ return E_FAIL;
+ }
+
+ GenAlphaMask(surf);
+
+ SDL_FreeSurface(surf);
+ delete imgDecoder; // TODO: Update this if ImageDecoder doesn't end up owning the surface.
+
+ m_CKDefault = default_ck;
+ m_CKRed = ck_red;
+ m_CKGreen = ck_green;
+ m_CKBlue = ck_blue;
+
+
+ if (!m_Filename || scumm_stricmp(m_Filename, Filename) != 0) {
+ SetFilename(Filename);
+ }
+
+ if (m_LifeTime == 0 || LifeTime == -1 || LifeTime > m_LifeTime)
+ m_LifeTime = LifeTime;
+
+ m_KeepLoaded = KeepLoaded;
+ if (m_KeepLoaded) m_LifeTime = -1;
+
+ m_Valid = true;
+
+ Game->AddMem(m_Width * m_Height * 4);
+
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CBSurfaceSDL::GenAlphaMask(SDL_Surface *surface) {
+ delete[] m_AlphaMask;
+ m_AlphaMask = NULL;
+ if (!surface) return;
+
+ SDL_LockSurface(surface);
+
+ bool hasColorKey;
+ Uint32 colorKey;
+ Uint8 ckRed, ckGreen, ckBlue;
+ if (SDL_GetColorKey(surface, &colorKey) == 0) {
+ hasColorKey = true;
+ SDL_GetRGB(colorKey, surface->format, &ckRed, &ckGreen, &ckBlue);
+ } else hasColorKey = false;
+
+ m_AlphaMask = new byte[surface->w * surface->h];
+
+ bool hasTransparency = false;
+ for (int y = 0; y < surface->h; y++) {
+ for (int x = 0; x < surface->w; x++) {
+ Uint32 pixel = GetPixel(surface, x, y);
+
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);
+
+ if (hasColorKey && r == ckRed && g == ckGreen && b == ckBlue)
+ a = 0;
+
+ m_AlphaMask[y * surface->w + x] = a;
+ if (a < 255) hasTransparency = true;
+ }
+ }
+
+ SDL_UnlockSurface(surface);
+
+ if (!hasTransparency) {
+ delete[] m_AlphaMask;
+ m_AlphaMask = NULL;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+Uint32 CBSurfaceSDL::GetPixel(SDL_Surface *surface, int x, int y) {
+ int bpp = surface->format->BytesPerPixel;
+ /* Here p is the address to the pixel we want to retrieve */
+ Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
+
+ switch (bpp) {
+ case 1:
+ return *p;
+ break;
+
+ case 2:
+ return *(Uint16 *)p;
+ break;
+
+ case 3:
+ if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+ return p[0] << 16 | p[1] << 8 | p[2];
+ else
+ return p[0] | p[1] << 8 | p[2] << 16;
+ break;
+
+ case 4:
+ return *(Uint32 *)p;
+ break;
+
+ default:
+ return 0; /* shouldn't happen, but avoids warnings */
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::Create(int Width, int Height) {
+ CBRenderSDL *renderer = static_cast<CBRenderSDL *>(Game->m_Renderer);
+ m_Texture = SDL_CreateTexture(renderer->GetSdlRenderer(), SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height);
+
+ m_Width = Width;
+ m_Height = Height;
+
+ Game->AddMem(m_Width * m_Height * 4);
+
+ m_Valid = true;
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::CreateFromSDLSurface(SDL_Surface *surface) {
+ CBRenderSDL *renderer = static_cast<CBRenderSDL *>(Game->m_Renderer);
+ m_Texture = SDL_CreateTextureFromSurface(renderer->GetSdlRenderer(), surface);
+
+ m_Width = surface->w;
+ m_Height = surface->h;
+
+ Game->AddMem(m_Width * m_Height * 4);
+
+ m_Valid = true;
+
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSurfaceSDL::IsTransparentAt(int X, int Y) {
+ int access;
+ int width, height;
+ SDL_QueryTexture(m_Texture, NULL, &access, &width, &height);
+ //if (access != SDL_TEXTUREACCESS_STREAMING) return false;
+ if (X < 0 || X >= width || Y < 0 || Y >= height) return true;
+
+
+ StartPixelOp();
+ bool ret = IsTransparentAtLite(X, Y);
+ EndPixelOp();
+
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool CBSurfaceSDL::IsTransparentAtLite(int X, int Y) {
+ //if (!m_LockPixels) return false;
+
+ Uint32 format;
+ int access;
+ int width, height;
+ SDL_QueryTexture(m_Texture, &format, &access, &width, &height);
+ //if (access != SDL_TEXTUREACCESS_STREAMING) return false;
+ if (X < 0 || X >= width || Y < 0 || Y >= height) return true;
+
+ if (!m_AlphaMask) return false;
+ else return m_AlphaMask[Y * width + X] <= 128;
+
+ /*
+ Uint32* dst = (Uint32*)((Uint8*)m_LockPixels + Y * m_LockPitch);
+ Uint32 pixel = dst[X];
+
+ SDL_PixelFormat* pixelFormat = SDL_AllocFormat(format);
+ Uint8 r, g, b, a;
+ SDL_GetRGBA(pixel, pixelFormat, &r, &g, &b, &a);
+ SDL_FreeFormat(pixelFormat);
+
+ return a <= 128;
+ */
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::StartPixelOp() {
+ //SDL_LockTexture(m_Texture, NULL, &m_LockPixels, &m_LockPitch);
+ return S_OK;
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::EndPixelOp() {
+ //SDL_UnlockTexture(m_Texture);
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::Display(int X, int Y, RECT rect, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return DrawSprite(X, Y, &rect, 100, 100, 0xFFFFFFFF, true, BlendMode, MirrorX, MirrorY);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::DisplayTrans(int X, int Y, RECT rect, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return DrawSprite(X, Y, &rect, 100, 100, Alpha, false, BlendMode, MirrorX, MirrorY);
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::DisplayTransOffset(int X, int Y, RECT rect, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY, int offsetX, int offsetY) {
+ return DrawSprite(X, Y, &rect, 100, 100, Alpha, false, BlendMode, MirrorX, MirrorY, offsetX, offsetY);
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::DisplayTransZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return DrawSprite(X, Y, &rect, ZoomX, ZoomY, Alpha, false, BlendMode, MirrorX, MirrorY);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::DisplayZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha, bool Transparent, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return DrawSprite(X, Y, &rect, ZoomX, ZoomY, Alpha, !Transparent, BlendMode, MirrorX, MirrorY);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::DisplayTransform(int X, int Y, int HotX, int HotY, RECT Rect, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY) {
+ return DrawSprite(X, Y, &Rect, ZoomX, ZoomY, Alpha, false, BlendMode, MirrorX, MirrorY);
+}
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceSDL::DrawSprite(int X, int Y, RECT *Rect, float ZoomX, float ZoomY, uint32 Alpha, bool AlphaDisable, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY, int offsetX, int offsetY) {
+ CBRenderSDL *renderer = static_cast<CBRenderSDL *>(Game->m_Renderer);
+
+ if (renderer->m_ForceAlphaColor != 0) Alpha = renderer->m_ForceAlphaColor;
+
+ byte r = D3DCOLGetR(Alpha);
+ byte g = D3DCOLGetG(Alpha);
+ byte b = D3DCOLGetB(Alpha);
+ byte a = D3DCOLGetA(Alpha);
+
+ SDL_SetTextureColorMod(m_Texture, r, g, b);
+ SDL_SetTextureAlphaMod(m_Texture, a);
+
+ if (AlphaDisable)
+ SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_NONE);
+ else
+ SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_BLEND);
+
+ SDL_Rect srcRect;
+ srcRect.x = Rect->left;
+ srcRect.y = Rect->top;
+ srcRect.w = Rect->right - Rect->left;
+ srcRect.h = Rect->bottom - Rect->top;
+
+ SDL_Rect position;
+ position.x = X;
+ position.y = Y;
+ position.w = (float)srcRect.w * ZoomX / 100.f;
+ position.h = (float)srcRect.h * ZoomX / 100.f;
+
+ renderer->ModTargetRect(&position);
+
+ position.x += offsetX;
+ position.y += offsetY;
+
+ SDL_RenderCopy(renderer->GetSdlRenderer(), m_Texture, &srcRect, &position);
+
+
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSurfaceSDL.h b/engines/wintermute/BSurfaceSDL.h
new file mode 100644
index 0000000000..e32bec90b1
--- /dev/null
+++ b/engines/wintermute/BSurfaceSDL.h
@@ -0,0 +1,79 @@
+/* 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_BSURFACESDL_H
+#define WINTERMUTE_BSURFACESDL_H
+
+#include "BSurface.h"
+class SDL_Texture;
+class SDL_Surface;
+namespace WinterMute {
+
+class CBSurfaceSDL : public CBSurface {
+public:
+ CBSurfaceSDL(CBGame *inGame);
+ ~CBSurfaceSDL();
+
+ HRESULT Create(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime = -1, bool KeepLoaded = false);
+ HRESULT Create(int Width, int Height);
+
+ HRESULT CreateFromSDLSurface(SDL_Surface *surface);
+
+ bool IsTransparentAt(int X, int Y);
+ bool IsTransparentAtLite(int X, int Y);
+
+ HRESULT StartPixelOp();
+ HRESULT EndPixelOp();
+
+
+ HRESULT DisplayTransZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha = 0xFFFFFFFF, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ HRESULT DisplayTrans(int X, int Y, RECT rect, uint32 Alpha = 0xFFFFFFFF, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ HRESULT DisplayTransOffset(int X, int Y, RECT rect, uint32 Alpha = 0xFFFFFFFF, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false, int offsetX = 0, int offsetY = 0);
+ HRESULT Display(int X, int Y, RECT rect, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ HRESULT DisplayZoom(int X, int Y, RECT rect, float ZoomX, float ZoomY, uint32 Alpha = 0xFFFFFFFF, bool Transparent = false, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+ HRESULT DisplayTransform(int X, int Y, int HotX, int HotY, RECT Rect, float ZoomX, float ZoomY, uint32 Alpha, float Rotate, TSpriteBlendMode BlendMode = BLEND_NORMAL, bool MirrorX = false, bool MirrorY = false);
+
+/* static unsigned DLL_CALLCONV ReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle);
+ static int DLL_CALLCONV SeekProc(fi_handle handle, long offset, int origin);
+ static long DLL_CALLCONV TellProc(fi_handle handle);*/
+
+private:
+ SDL_Texture *m_Texture;
+
+ HRESULT DrawSprite(int X, int Y, RECT *Rect, float ZoomX, float ZoomY, uint32 Alpha, bool AlphaDisable, TSpriteBlendMode BlendMode, bool MirrorX, bool MirrorY, int offsetX = 0, int offsetY = 0);
+ void GenAlphaMask(SDL_Surface *surface);
+ uint32 GetPixel(SDL_Surface *surface, int x, int y);
+
+ void *m_LockPixels;
+ int m_LockPitch;
+ byte *m_AlphaMask;
+};
+
+} // end of namespace WinterMute
+
+#endif // __WmeBSurfaceSDL_H__
diff --git a/engines/wintermute/BSurfaceStorage.cpp b/engines/wintermute/BSurfaceStorage.cpp
new file mode 100644
index 0000000000..45f70db8f6
--- /dev/null
+++ b/engines/wintermute/BSurfaceStorage.cpp
@@ -0,0 +1,192 @@
+/* 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 "BSurfaceStorage.h"
+#include "BSurfaceSDL.h"
+#include "BGame.h"
+#include "BFileManager.h"
+#include "PlatformSDL.h"
+#include "common/str.h"
+
+namespace WinterMute {
+
+//IMPLEMENT_PERSISTENT(CBSurfaceStorage, true);
+
+//////////////////////////////////////////////////////////////////////
+CBSurfaceStorage::CBSurfaceStorage(CBGame *inGame): CBBase(inGame) {
+ m_LastCleanupTime = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBSurfaceStorage::~CBSurfaceStorage() {
+ Cleanup(true);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceStorage::Cleanup(bool Warn) {
+ for (int i = 0; i < m_Surfaces.GetSize(); i++) {
+ if (Warn) Game->LOG(0, "CBSurfaceStorage warning: purging surface '%s', usage:%d", m_Surfaces[i]->m_Filename, m_Surfaces[i]->m_ReferenceCount);
+ delete m_Surfaces[i];
+ }
+ m_Surfaces.RemoveAll();
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceStorage::InitLoop() {
+ if (Game->m_SmartCache && Game->m_LiveTimer - m_LastCleanupTime >= Game->m_SurfaceGCCycleTime) {
+ m_LastCleanupTime = Game->m_LiveTimer;
+ SortSurfaces();
+ for (int i = 0; i < m_Surfaces.GetSize(); i++) {
+ if (m_Surfaces[i]->m_LifeTime <= 0) break;
+
+ if (m_Surfaces[i]->m_LifeTime > 0 && m_Surfaces[i]->m_Valid && Game->m_LiveTimer - m_Surfaces[i]->m_LastUsedTime >= m_Surfaces[i]->m_LifeTime) {
+ //Game->QuickMessageForm("Invalidating: %s", m_Surfaces[i]->m_Filename);
+ m_Surfaces[i]->Invalidate();
+ }
+ }
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceStorage::RemoveSurface(CBSurface *surface) {
+ for (int i = 0; i < m_Surfaces.GetSize(); i++) {
+ if (m_Surfaces[i] == surface) {
+ m_Surfaces[i]->m_ReferenceCount--;
+ if (m_Surfaces[i]->m_ReferenceCount <= 0) {
+ delete m_Surfaces[i];
+ m_Surfaces.RemoveAt(i);
+ }
+ break;
+ }
+ }
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+CBSurface *CBSurfaceStorage::AddSurface(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime, bool KeepLoaded) {
+ for (int i = 0; i < m_Surfaces.GetSize(); i++) {
+ if (scumm_stricmp(m_Surfaces[i]->m_Filename, Filename) == 0) {
+ m_Surfaces[i]->m_ReferenceCount++;
+ return m_Surfaces[i];
+ }
+ }
+
+ CBFile *File = Game->m_FileManager->OpenFile(Filename);
+ if (!File) {
+ if (Filename) Game->LOG(0, "Missing image: '%s'", Filename);
+ if (Game->m_DEBUG_DebugMode)
+ return AddSurface("invalid_debug.bmp", default_ck, ck_red, ck_green, ck_blue, LifeTime, KeepLoaded);
+ else
+ return AddSurface("invalid.bmp", default_ck, ck_red, ck_green, ck_blue, LifeTime, KeepLoaded);
+ } else Game->m_FileManager->CloseFile(File);
+
+
+ CBSurface *surface;
+ surface = new CBSurfaceSDL(Game);
+
+
+ if (!surface) return NULL;
+
+ if (FAILED(surface->Create(Filename, default_ck, ck_red, ck_green, ck_blue, LifeTime, KeepLoaded))) {
+ delete surface;
+ return NULL;
+ } else {
+ surface->m_ReferenceCount = 1;
+ m_Surfaces.Add(surface);
+ return surface;
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceStorage::RestoreAll() {
+ HRESULT ret;
+ for (int i = 0; i < m_Surfaces.GetSize(); i++) {
+ ret = m_Surfaces[i]->Restore();
+ if (ret != S_OK) {
+ Game->LOG(0, "CBSurfaceStorage::RestoreAll failed");
+ return ret;
+ }
+ }
+ return S_OK;
+}
+
+
+/*
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceStorage::Persist(CBPersistMgr *PersistMgr)
+{
+
+ if(!PersistMgr->m_Saving) Cleanup(false);
+
+ PersistMgr->Transfer(TMEMBER(Game));
+
+ //m_Surfaces.Persist(PersistMgr);
+
+ return S_OK;
+}
+*/
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBSurfaceStorage::SortSurfaces() {
+ qsort(m_Surfaces.GetData(), m_Surfaces.GetSize(), sizeof(CBSurface *), SurfaceSortCB);
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBSurfaceStorage::SurfaceSortCB(const void *arg1, const void *arg2) {
+ CBSurface *s1 = *((CBSurface **)arg1);
+ CBSurface *s2 = *((CBSurface **)arg2);
+
+ // sort by life time
+ if (s1->m_LifeTime <= 0 && s2->m_LifeTime > 0) return 1;
+ else if (s1->m_LifeTime > 0 && s2->m_LifeTime <= 0) return -1;
+
+
+ // sort by validity
+ if (s1->m_Valid && !s2->m_Valid) return -1;
+ else if (!s1->m_Valid && s2->m_Valid) return 1;
+
+ // sort by time
+ else if (s1->m_LastUsedTime > s2->m_LastUsedTime) return 1;
+ else if (s1->m_LastUsedTime < s2->m_LastUsedTime) return -1;
+ else return 0;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BSurfaceStorage.h b/engines/wintermute/BSurfaceStorage.h
new file mode 100644
index 0000000000..5ebfe3c7d7
--- /dev/null
+++ b/engines/wintermute/BSurfaceStorage.h
@@ -0,0 +1,58 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_BSURFACESTORAGE_H
+#define WINTERMUTE_BSURFACESTORAGE_H
+
+
+#include "coll_templ.h"
+#include "BBase.h"
+
+namespace WinterMute {
+class CBSurface;
+class CBSurfaceStorage : public CBBase {
+public:
+ uint32 m_LastCleanupTime;
+ HRESULT InitLoop();
+ HRESULT SortSurfaces();
+ static int SurfaceSortCB(const void *arg1, const void *arg2);
+ HRESULT Cleanup(bool Warn = false);
+ //DECLARE_PERSISTENT(CBSurfaceStorage, CBBase);
+
+ HRESULT RestoreAll();
+ CBSurface *AddSurface(char *Filename, bool default_ck = true, byte ck_red = 0, byte ck_green = 0, byte ck_blue = 0, int LifeTime = -1, bool KeepLoaded = false);
+ HRESULT RemoveSurface(CBSurface *surface);
+ CBSurfaceStorage(CBGame *inGame);
+ virtual ~CBSurfaceStorage();
+
+ CBArray<CBSurface *, CBSurface *> m_Surfaces;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BTransitionMgr.cpp b/engines/wintermute/BTransitionMgr.cpp
new file mode 100644
index 0000000000..56703b3336
--- /dev/null
+++ b/engines/wintermute/BTransitionMgr.cpp
@@ -0,0 +1,126 @@
+/* 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 "BTransitionMgr.h"
+#include "BGame.h"
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+CBTransitionMgr::CBTransitionMgr(CBGame *inGame): CBBase(inGame) {
+ m_State = TRANS_MGR_READY;
+ m_Type = TRANSITION_NONE;
+ m_OrigInteractive = false;
+ m_PreserveInteractive = false;
+ m_LastTime = 0;
+ m_Started = false;
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////
+CBTransitionMgr::~CBTransitionMgr() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+bool CBTransitionMgr::IsReady() {
+ return (m_State == TRANS_MGR_READY);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBTransitionMgr::Start(TTransitionType Type, bool NonInteractive) {
+ if (m_State != TRANS_MGR_READY) return S_OK;
+
+ if (Type == TRANSITION_NONE || Type >= NUM_TRANSITION_TYPES) {
+ m_State = TRANS_MGR_READY;
+ return S_OK;
+ }
+
+ if (NonInteractive) {
+ m_PreserveInteractive = true;
+ m_OrigInteractive = Game->m_Interactive;
+ Game->m_Interactive = false;
+ } else m_PreserveInteractive;
+
+ m_Type = Type;
+ m_State = TRANS_MGR_RUNNING;
+ m_Started = false;
+
+ return S_OK;
+}
+
+#define FADE_DURATION 200
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBTransitionMgr::Update() {
+ if (IsReady()) return S_OK;
+
+ if (!m_Started) {
+ m_Started = true;
+ m_LastTime = CBPlatform::GetTime();
+ }
+
+ switch (m_Type) {
+ case TRANSITION_NONE:
+ m_State = TRANS_MGR_READY;
+ break;
+
+ case TRANSITION_FADE_OUT: {
+ uint32 time = CBPlatform::GetTime() - m_LastTime;
+ int Alpha = 255 - (float)time / (float)FADE_DURATION * 255;
+ Alpha = std::min(255, std::max(Alpha, 0));
+ Game->m_Renderer->Fade((WORD)Alpha);
+
+ if (time > FADE_DURATION) m_State = TRANS_MGR_READY;
+ }
+ break;
+
+ case TRANSITION_FADE_IN: {
+ uint32 time = CBPlatform::GetTime() - m_LastTime;
+ int Alpha = (float)time / (float)FADE_DURATION * 255;
+ Alpha = std::min(255, std::max(Alpha, 0));
+ Game->m_Renderer->Fade((WORD)Alpha);
+
+ if (time > FADE_DURATION) m_State = TRANS_MGR_READY;
+ }
+ break;
+
+ }
+
+ if (IsReady()) {
+ if (m_PreserveInteractive) Game->m_Interactive = m_OrigInteractive;
+ }
+ return S_OK;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BTransitionMgr.h b/engines/wintermute/BTransitionMgr.h
new file mode 100644
index 0000000000..6bcf3ea89b
--- /dev/null
+++ b/engines/wintermute/BTransitionMgr.h
@@ -0,0 +1,54 @@
+/* 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_BTRANSITIONMGR_H
+#define WINTERMUTE_BTRANSITIONMGR_H
+
+#include "BBase.h"
+
+namespace WinterMute {
+
+class CBTransitionMgr : public CBBase {
+public:
+ bool m_Started;
+ uint32 m_LastTime;
+ bool m_OrigInteractive;
+ bool m_PreserveInteractive;
+ HRESULT Update();
+ HRESULT Start(TTransitionType Type, bool NonInteractive = false);
+ bool IsReady();
+ TTransMgrState m_State;
+ CBTransitionMgr(CBGame *inGame);
+ virtual ~CBTransitionMgr();
+ TTransitionType m_Type;
+
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/BViewport.cpp b/engines/wintermute/BViewport.cpp
new file mode 100644
index 0000000000..bb2f5b6b29
--- /dev/null
+++ b/engines/wintermute/BViewport.cpp
@@ -0,0 +1,98 @@
+/* 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 "BViewport.h"
+
+namespace WinterMute {
+
+IMPLEMENT_PERSISTENT(CBViewport, false)
+
+//////////////////////////////////////////////////////////////////////////
+CBViewport::CBViewport(CBGame *inGame): CBBase(inGame) {
+ CBPlatform::SetRectEmpty(&m_Rect);
+ m_MainObject = NULL;
+ m_OffsetX = m_OffsetY = 0;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+CBViewport::~CBViewport() {
+
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBViewport::Persist(CBPersistMgr *PersistMgr) {
+
+ PersistMgr->Transfer(TMEMBER(Game));
+
+ PersistMgr->Transfer(TMEMBER(m_MainObject));
+ PersistMgr->Transfer(TMEMBER(m_OffsetX));
+ PersistMgr->Transfer(TMEMBER(m_OffsetY));
+ PersistMgr->Transfer(TMEMBER(m_Rect));
+
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+HRESULT CBViewport::SetRect(int left, int top, int right, int bottom, bool NoCheck) {
+ if (!NoCheck) {
+ left = std::max(left, 0);
+ top = std::max(top, 0);
+ right = std::min(right, Game->m_Renderer->m_Width);
+ bottom = std::min(bottom, Game->m_Renderer->m_Height);
+ }
+
+ CBPlatform::SetRect(&m_Rect, left, top, right, bottom);
+ m_OffsetX = left;
+ m_OffsetY = top;
+ return S_OK;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+RECT *CBViewport::GetRect() {
+ return &m_Rect;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBViewport::GetWidth() {
+ return m_Rect.right - m_Rect.left;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+int CBViewport::GetHeight() {
+ return m_Rect.bottom - m_Rect.top;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/BViewport.h b/engines/wintermute/BViewport.h
new file mode 100644
index 0000000000..06a5a1952f
--- /dev/null
+++ b/engines/wintermute/BViewport.h
@@ -0,0 +1,55 @@
+/* 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_BVIEWPORT_H
+#define WINTERMUTE_BVIEWPORT_H
+
+
+#include "BBase.h"
+
+namespace WinterMute {
+class CBObject;
+class CBViewport : public CBBase {
+public:
+ int GetHeight();
+ int GetWidth();
+ RECT *GetRect();
+ HRESULT SetRect(int left, int top, int right, int bottom, bool NoCheck = false);
+ DECLARE_PERSISTENT(CBViewport, CBBase)
+ int m_OffsetY;
+ int m_OffsetX;
+ CBObject *m_MainObject;
+ CBViewport(CBGame *inGame = NULL);
+ virtual ~CBViewport();
+private:
+ RECT m_Rect;
+};
+
+} // end of namespace WinterMute
+
+#endif
diff --git a/engines/wintermute/PathUtil.cpp b/engines/wintermute/PathUtil.cpp
new file mode 100644
index 0000000000..d7d632f398
--- /dev/null
+++ b/engines/wintermute/PathUtil.cpp
@@ -0,0 +1,196 @@
+/* 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 <algorithm>
+#include <fstream>
+#include "PathUtil.h"
+#include "StringUtil.h"
+
+
+#ifdef __WIN32__
+# include <shlobj.h>
+#endif
+
+#ifdef __MACOSX__
+# include <CoreServices/CoreServices.h>
+#endif
+
+#ifdef __IPHONEOS__
+# include "ios_utils.h"
+#endif
+
+namespace WinterMute {
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::UnifySeparators(const AnsiString &path) {
+ AnsiString newPath = path;
+
+ std::replace(newPath.begin(), newPath.end(), L'\\', L'/');
+ return newPath;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::NormalizeFileName(const AnsiString &path) {
+ AnsiString newPath = UnifySeparators(path);
+ StringUtil::ToLowerCase(newPath);
+ return newPath;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::Combine(const AnsiString &path1, const AnsiString &path2) {
+ AnsiString newPath1 = UnifySeparators(path1);
+ AnsiString newPath2 = UnifySeparators(path2);
+
+ if (!StringUtil::EndsWith(newPath1, "/", true) && !StringUtil::StartsWith(newPath2, "/", true))
+ newPath1 += "/";
+
+ return newPath1 + newPath2;
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::GetDirectoryName(const AnsiString &path) {
+ AnsiString newPath = UnifySeparators(path);
+
+ size_t pos = newPath.find_last_of(L'/');
+
+ if (pos == AnsiString::npos) return "";
+ else return newPath.substr(0, pos + 1);
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::GetFileName(const AnsiString &path) {
+ AnsiString newPath = UnifySeparators(path);
+
+ size_t pos = newPath.find_last_of(L'/');
+
+ if (pos == AnsiString::npos) return path;
+ else return newPath.substr(pos + 1);
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::GetFileNameWithoutExtension(const AnsiString &path) {
+ AnsiString fileName = GetFileName(path);
+
+ size_t pos = fileName.find_last_of('.');
+
+ if (pos == AnsiString::npos) return fileName;
+ else return fileName.substr(0, pos);
+}
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::GetExtension(const AnsiString &path) {
+ AnsiString fileName = GetFileName(path);
+
+ size_t pos = fileName.find_last_of('.');
+
+ if (pos == AnsiString::npos) return "";
+ else return fileName.substr(pos);
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::GetSafeLogFileName() {
+ AnsiString logFileName = GetUserDirectory();
+
+#ifdef __WIN32__
+ char moduleName[MAX_PATH];
+ ::GetModuleFileName(NULL, moduleName, MAX_PATH);
+
+ AnsiString fileName = GetFileNameWithoutExtension(moduleName) + ".log";
+ fileName = Combine("/Wintermute Engine/Logs/", fileName);
+ logFileName = Combine(logFileName, fileName);
+
+#else
+ // !PORTME
+ logFileName = Combine(logFileName, "/Wintermute Engine/wme.log");
+#endif
+
+ CreateDirectory(GetDirectoryName(logFileName));
+ return logFileName;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool PathUtil::CreateDirectory(const AnsiString &path) {
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool PathUtil::MatchesMask(const AnsiString &fileName, const AnsiString &mask) {
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+bool PathUtil::FileExists(const AnsiString &fileName) {
+ std::ifstream stream;
+
+ stream.open(fileName.c_str());
+ bool ret = stream.is_open();
+ stream.close();
+
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+AnsiString PathUtil::GetUserDirectory() {
+ AnsiString userDir = "./";
+
+#ifdef __WIN32__
+ char buffer[MAX_PATH];
+ buffer[0] = '\0';
+ LPITEMIDLIST pidl = NULL;
+ LPMALLOC pMalloc;
+ if (SUCCEEDED(SHGetMalloc(&pMalloc))) {
+ SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl);
+ if (pidl) {
+ SHGetPathFromIDList(pidl, buffer);
+ }
+ pMalloc->Free(pidl);
+ userDir = AnsiString(buffer);
+ }
+#elif __MACOSX__
+ FSRef fileRef;
+ OSStatus error = FSFindFolder(kUserDomain, kApplicationSupportFolderType, true, &fileRef);
+ if (error == noErr) {
+ char buffer[MAX_PATH];
+ error = FSRefMakePath(&fileRef, (UInt8 *)buffer, sizeof(buffer));
+ if (error == noErr)
+ userDir = buffer;
+
+ }
+#elif __IPHONEOS__
+ char path[MAX_PATH];
+ IOS_GetDataDir(path);
+ userDir = AnsiString(path);
+#endif
+
+ return userDir;
+}
+
+} // end of namespace WinterMute
diff --git a/engines/wintermute/PathUtil.h b/engines/wintermute/PathUtil.h
new file mode 100644
index 0000000000..72dcf806b1
--- /dev/null
+++ b/engines/wintermute/PathUtil.h
@@ -0,0 +1,56 @@
+/* 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_BPATHUTILS_H
+#define WINTERMUTE_BPATHUTILS_H
+
+#include "PlatformSDL.h"
+
+namespace WinterMute {
+
+class PathUtil {
+public:
+ static AnsiString UnifySeparators(const AnsiString &path);
+ static AnsiString NormalizeFileName(const AnsiString &path);
+ static AnsiString Combine(const AnsiString &path1, const AnsiString &path2);
+ static AnsiString GetDirectoryName(const AnsiString &path);
+ static AnsiString GetFileName(const AnsiString &path);
+ static AnsiString GetFileNameWithoutExtension(const AnsiString &path);
+ static AnsiString GetExtension(const AnsiString &path);
+ static bool CreateDirectory(const AnsiString &path);
+ static bool MatchesMask(const AnsiString &fileName, const AnsiString &mask);
+
+ static bool FileExists(const AnsiString &fileName);
+
+ static AnsiString GetSafeLogFileName();
+ static AnsiString GetUserDirectory();
+};
+
+} // end of namespace WinterMute
+
+#endif // __WmePathUtils_H__
diff --git a/engines/wintermute/StringUtil.cpp b/engines/wintermute/StringUtil.cpp
index 6a42857615..f3b4e0c0db 100644
--- a/engines/wintermute/StringUtil.cpp
+++ b/engines/wintermute/StringUtil.cpp
@@ -1,27 +1,30 @@
+/* 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 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.
-*/
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
#include "dcgf.h"
#include <algorithm>
diff --git a/engines/wintermute/StringUtil.h b/engines/wintermute/StringUtil.h
index 20758ed0cd..80c95ced03 100644
--- a/engines/wintermute/StringUtil.h
+++ b/engines/wintermute/StringUtil.h
@@ -1,30 +1,33 @@
-/*
-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:
+/* 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.
+ *
+ */
-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.
-*/
+/*
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
-#ifndef __WmeStringUtil_H__
-#define __WmeStringUtil_H__
+#ifndef WINTERMUTE_STRINGUTIL_H
+#define WINTERMUTE_STRINGUTIL_H
#include "PlatformSDL.h"
diff --git a/engines/wintermute/SysClass.h b/engines/wintermute/SysClass.h
index ede3d41c22..48d7a2626e 100644
--- a/engines/wintermute/SysClass.h
+++ b/engines/wintermute/SysClass.h
@@ -1,27 +1,30 @@
+/* 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 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.
-*/
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
#ifndef WINTERMUTE_SYSCLASS_H
#define WINTERMUTE_SYSCLASS_H
diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk
index 45708e2b84..a33861cd19 100644
--- a/engines/wintermute/module.mk
+++ b/engines/wintermute/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
BNamedObject.o \
BParser.o \
BScriptable.o \
+ BViewport.o \
detection.o \
SysClass.o \
SysInstance.o \
diff --git a/engines/wintermute/persistent.h b/engines/wintermute/persistent.h
index 5d0b7ee5fb..130e080e79 100644
--- a/engines/wintermute/persistent.h
+++ b/engines/wintermute/persistent.h
@@ -24,7 +24,6 @@
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
-
*/
#ifndef WINTERMUTE_PERSISTENT_H
diff --git a/engines/wintermute/utils.cpp b/engines/wintermute/utils.cpp
index dd649d8afd..c69a0068b6 100644
--- a/engines/wintermute/utils.cpp
+++ b/engines/wintermute/utils.cpp
@@ -1,27 +1,30 @@
+/* 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 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.
-*/
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
#include "dcgf.h"
#include "utils.h"
diff --git a/engines/wintermute/utils.h b/engines/wintermute/utils.h
index 56d9876c5c..6fdac018ce 100644
--- a/engines/wintermute/utils.h
+++ b/engines/wintermute/utils.h
@@ -1,30 +1,33 @@
+/* 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 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 __WmeUtils_H__
-#define __WmeUtils_H__
+ * This file is based on WME Lite.
+ * http://dead-code.org/redir.php?target=wmelite
+ * Copyright (c) 2011 Jan Nedoma
+ */
+
+#ifndef WINTERMUTE_UTILS_H
+#define WINTERMUTE_UTILS_H
#include "wintypes.h"