aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-05-03 00:49:59 +1000
committerPaul Gilbert2012-05-03 00:49:59 +1000
commit2eb9ebd8aa28fabfc443b85507d3c85b6525684e (patch)
treec8d2ca19a6c030e0875d6b271f3485a0d5e862f3
parent4300db9ee4798d43eb2214db87b575ed12640458 (diff)
downloadscummvm-rg350-2eb9ebd8aa28fabfc443b85507d3c85b6525684e.tar.gz
scummvm-rg350-2eb9ebd8aa28fabfc443b85507d3c85b6525684e.tar.bz2
scummvm-rg350-2eb9ebd8aa28fabfc443b85507d3c85b6525684e.zip
TONY: Implemented loc.cpp and font.cpp methods
-rw-r--r--engines/tony/font.cpp2510
-rw-r--r--engines/tony/loc.cpp2067
-rw-r--r--engines/tony/loc.h5
-rw-r--r--engines/tony/utils.h50
4 files changed, 4620 insertions, 12 deletions
diff --git a/engines/tony/font.cpp b/engines/tony/font.cpp
new file mode 100644
index 0000000000..2996b30f04
--- /dev/null
+++ b/engines/tony/font.cpp
@@ -0,0 +1,2510 @@
+/* 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.
+ *
+ */
+/**************************************************************************
+ * 様様様様様様様様様様様様様様様様様 *
+ * Nayma Software srl *
+ * e -= We create much MORE than ALL =- *
+ * u- z$$$c '. 様様様様様様様様様様様様様様様様様 *
+ * .d" d$$$$$b "b. *
+ * .z$* d$$$$$$$L ^*$c. *
+ * #$$$. $$$$$$$$$ .$$$" Project: Roasted Moths........ *
+ * ^*$b 4$$$$$$$$$F .d$*" *
+ * ^$$. 4$$$$$$$$$F .$P" Module: Font.CPP............. *
+ * *$. '$$$$$$$$$ 4$P 4 *
+ * J *$ "$$$$$$$" $P r Author: Giovanni Bajo........ *
+ * z$ '$$$P*4c.*$$$*.z@*R$$$ $. *
+ * z$" "" #$F^ "" '$c *
+ * z$$beu .ue=" $ "=e.. .zed$$c *
+ * "#$e z$*" . `. ^*Nc e$"" *
+ * "$$". .r" ^4. .^$$" *
+ * ^.@*"6L=\ebu^+C$"*b." *
+ * "**$. "c 4$$$ J" J$P*" OS: [ ] DOS [X] WIN95 [ ] PORT *
+ * ^"--.^ 9$" .--"" COMP: [ ] WATCOM [X] VISUAL C++ *
+ * " [ ] EIFFEL [ ] GCC/GXX/DJGPP *
+ * *
+ * This source code is Copyright (C) Nayma Software. ALL RIGHTS RESERVED *
+ * *
+ **************************************************************************/
+
+#include "common/textconsole.h"
+#include "tony/mpal/mpalutils.h"
+#include "tony/mpal/stubs.h"
+#include "tony/font.h"
+#include "tony/input.h"
+#include "tony/inventory.h"
+#include "tony/loc.h"
+#include "tony/tony.h"
+
+namespace Tony {
+
+/****************************************************************************\
+* Metodi di RMFont
+\****************************************************************************/
+
+RMFont::RMFont() {
+ m_letter = NULL;
+}
+
+RMFont::~RMFont() {
+ Unload();
+}
+
+/****************************************************************************\
+*
+* Function: void RMFont::Load(byte *buf, int nChars, int dimx, int dimy);
+*
+* Description: Carica un font da buffer
+*
+* Input: byte *buf Buffer contenente il font
+* int nChars Numero di caratteri (max 256)
+* int dimx,dimy Dimensione in pixel di un carattere
+*
+\****************************************************************************/
+
+void DumpFontBMP(const char *filename, const byte *buf, int nChars, int charX, int charY, byte *pal) {
+ error("DumpFontBMP not supported in ScummVM");
+}
+
+
+void RMFont::Load(const byte *buf, int nChars, int dimx, int dimy, uint32 palResID) {
+ m_letter = new RMGfxSourceBuffer8RLEByte[nChars];
+
+#if 0
+ if (nChars == 112 && palResID == RES_F_PAL)
+ {
+ // Font parla
+ DumpFontBMP("font_parla.bmp", buf, nChars, dimx, dimy, RMRes(palResID));
+ }
+ else if (nChars == 102 && palResID == RES_F_PAL)
+ {
+ // Font macc
+ DumpFontBMP("font_macc.bmp", buf, nChars, dimx, dimy, RMRes(palResID));
+ }
+ else if (nChars == 85 && palResID == RES_F_PAL)
+ {
+ // Font obj
+ DumpFontBMP("font_obj.bmp", buf, nChars, dimx, dimy, RMRes(palResID));
+ }
+ else if (nChars == 112 && palResID == RES_F_CPAL)
+ {
+ // Font credits
+ DumpFontBMP("font_credits.bmp", buf, nChars, dimx, dimy, RMRes(palResID));
+ }
+#endif
+
+ // Carichiamoce 'sto font
+ for (int i = 0; i < nChars; i++)
+ {
+ // Inizializza il buffer con le lettere
+ m_letter[i].Init(buf + i * (dimx * dimy + 8) + 8, dimx, dimy);
+ m_letter[i].LoadPaletteWA(palResID);
+ }
+
+ m_fontDimx = dimx;
+ m_fontDimy = dimy;
+
+ nLetters=nChars;
+}
+
+
+void RMFont::Unload(void) {
+ if (m_letter != NULL) {
+ delete[] m_letter;
+ m_letter = NULL;
+ }
+}
+
+
+RMGfxPrimitive *RMFont::MakeLetterPrimitive(byte bChar, int &nLength) {
+ RMFontPrimitive *prim;
+ int nLett;
+
+ // Converte da carattere a lettera
+ nLett = ConvertToLetter(bChar);
+
+ // Crea la primitiva per il font
+ prim = new RMFontPrimitive(this);
+ prim->m_nChar = nLett;
+
+ // Si fa' dare la lunghezza della lettera in pixel
+ nLength = LetterLength(bChar);
+
+ return prim;
+}
+
+void RMFont::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim2) {
+ RMFontPrimitive *prim = (RMFontPrimitive *)prim2;
+
+ // Richiama la Draw della lettera assegnata alla primitiva
+ if (prim->m_nChar != -1)
+ m_letter[prim->m_nChar].Draw(bigBuf,prim);
+}
+
+void RMFont::Close(void) {
+ Unload();
+}
+
+int RMFont::StringLen(RMString text) {
+ int len, i;
+
+ len = 0;
+ for (i = 0; i < text.Length() - 1; i++)
+ len += LetterLength(text[i], text[i + 1]);
+ len += LetterLength(text[i]);
+
+ return len;
+}
+
+int RMFont::StringLen(char bChar, char bNext) {
+ return LetterLength(bChar, bNext);
+}
+
+/****************************************************************************\
+* Metodi di RMFontColor
+\****************************************************************************/
+
+RMFontColor::RMFontColor() : RMFont() {
+ m_r = m_g = m_b = 255;
+}
+
+RMFontColor::~RMFontColor() {
+
+}
+
+void RMFontColor::SetBaseColor(byte r1, byte g1, byte b1) {
+ int r = (int)r1 << 16;
+ int g = (int)g1 << 16;
+ int b = (int)b1 << 16;
+
+ int rstep = r / 14;
+ int gstep = g / 14;
+ int bstep = b / 14;
+
+ int i;
+ byte pal[768*3];
+
+ // Controlla se siamo gia' sul colore giusto
+ if (m_r == r1 && m_g == g1 && m_b == b1)
+ return;
+
+ m_r = r1;
+ m_g = g1;
+ m_b = b1;
+
+ // Costruisce la nuova palette per il font
+ for (i = 1; i < 16; i++) {
+ pal[i * 3 + 0] = r >> 16;
+ pal[i * 3 + 1] = g >> 16;
+ pal[i * 3 + 2] = b >> 16;
+
+ r -= rstep;
+ g -= gstep;
+ b -= bstep;
+ }
+
+ pal[15*3 + 0] += 8;
+ pal[15*3 + 1] += 8;
+ pal[15*3 + 2] += 8;
+
+ // La mette in tutte le lettere
+ for (i = 0; i < nLetters; i++)
+ m_letter[i].LoadPaletteWA(pal);
+}
+
+
+/***************************************************************************\
+* Metodi di RMFontParla
+\****************************************************************************/
+
+void RMFontParla::Init(void) {
+ int i;
+
+ // bernie: numero di caratteri nel font
+ int nchars =
+ 112 // base
+ + 18 // polish
+ + 66 // russian
+ + 30 // czech
+ + 8 // french
+ + 5; // deutsch
+
+ Load(RES_F_PARL, nchars, 20, 20);
+
+ // Inizializziamo le tabelline del cazzo
+ lDefault = 13;
+ hDefault = 18;
+ Common::fill(&l2Table[0][0], &l2Table[0][0] + (256 * 256), '\0');
+ for (i = 0; i < 256; i++)
+ {
+ cTable[i] = -1;
+ lTable[i] = lDefault;
+ }
+
+ for (i = 0; i < 26; i++)
+ cTable['A' + i] = i + 0;
+
+ for (i = 0; i < 26; i++)
+ cTable['a' + i] = i + 26;
+
+ for (i = 0; i < 10; i++)
+ cTable['0' + i] = i + 52;
+
+ cTable[';'] = 62;
+ cTable[','] = 63;
+ cTable['.'] = 64;
+ cTable[':'] = 65;
+ cTable['-'] = 66;
+ cTable['_'] = 67;
+ cTable['+'] = 68;
+ cTable['<'] = 69;
+ cTable['>'] = 70;
+ cTable['!'] = 71;
+ //cTable['!'] = 72; Esclamativo alla rovescia
+ cTable['?'] = 73;
+ //cTable['?'] = 74; Interrogativo alla rovescia
+ cTable['('] = 75;
+ cTable[')'] = 76;
+ cTable['\"'] = 77;
+ cTable['^'] = 77;
+ cTable['/'] = 78;
+ cTable[''] = 79;
+ cTable['$'] = 80;
+ cTable['%'] = 81;
+ cTable['&'] = 82;
+ cTable['='] = 83;
+ cTable[''] = 84;
+ cTable[''] = 85;
+ cTable[''] = 86;
+ cTable[''] = 87;
+ cTable[''] = 88;
+ cTable[''] = 89;
+ cTable[''] = 89;
+ cTable[''] = 90;
+ cTable[''] = 91;
+ cTable[''] = 92;
+ cTable[''] = 93;
+ cTable[''] = 94;
+ cTable[''] = 95;
+ cTable[''] = 96;
+ cTable[''] = 97;
+ cTable[''] = 98;
+ cTable[''] = 99;
+ //cTable[' '] = 100; e cerchietto
+ //cTable[' '] = 101; i cerchietto
+ //cTable[' '] = 102; o cerchietto
+ //cTable[' '] = 103; u cerchietto
+ cTable[''] = 104;
+ cTable[''] = 105;
+ cTable[''] = 106;
+ cTable[''] = 107;
+ cTable[''] = 108;
+ cTable[''] = 109;
+ //cTable[''] = 110; integrale
+ cTable['\''] = 111;
+
+ // Un po' di lunghezze
+ lTable[' '] = 9;
+ lTable['\''] = 5;
+ lTable['.'] = 5;
+ lTable[','] = 5;
+ lTable[':'] = 5;
+ lTable[';'] = 5;
+ lTable['!'] = 5;
+ lTable['?'] = 10;
+ lTable['\"'] = 5;
+ lTable['^'] = 5;
+ lTable['('] = 7;
+ lTable[')'] = 7;
+
+ lTable['4'] = 10;
+
+ lTable['a'] = 14;
+ lTable['b'] = 15;
+ lTable['c'] = 12;
+ lTable['e'] = 12;
+ lTable['i'] = 6;
+ lTable[''] = 6;
+ lTable['l'] = 5;
+ lTable['m'] = 16;
+ lTable['n'] = 12;
+ lTable['o'] = 11;
+ lTable['p'] = 11;
+ lTable['s'] = 12;
+ lTable['u'] = 12;
+
+ lTable['E'] = 10;
+ lTable['F'] = 11;
+
+
+ // Polish characters
+ //AaCcEeLlNnOoSsZzZz
+ //ス謎戊3剔囀
+
+ cTable[''] = 112;
+ cTable[''] = 113;
+ cTable[''] = 114;
+ cTable[''] = 115;
+ cTable[''] = 116;
+ cTable[''] = 117;
+ cTable[''] = 118;
+ cTable[''] = 119;
+ cTable[''] = 120;
+ cTable[''] = 121;
+ cTable[''] = 122;
+ cTable[''] = 123;
+ cTable[''] = 124;
+ cTable[''] = 125;
+ cTable[''] = 126;
+ cTable[''] = 127;
+ cTable[''] = 128;
+ cTable[''] = 129;
+
+ lTable[''] = 14;
+ lTable[''] = 16;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 14;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 13;
+ lTable[''] = 14;
+ lTable[''] = 13;
+
+#ifdef FONT_RUSSIAN
+ // Russian Characters
+ // WARNING: Il russo usa molti dei caratteri ISO-Latin-1 che servono
+ // per le altre traduzioni. Per compilare Tony in altre lingue,
+ // commentare via queste definizioni.
+
+ cTable[''] = 130;
+ cTable[''] = 131;
+ cTable[''] = 132;
+ cTable[''] = 133;
+ cTable[''] = 134;
+ cTable[''] = 135;
+ cTable[''] = 136;
+ cTable[''] = 137;
+ cTable[''] = 138;
+ cTable[''] = 139;
+ cTable[''] = 140;
+ cTable[''] = 141;
+ cTable[''] = 142;
+ cTable[''] = 143;
+ cTable[''] = 144;
+ cTable[''] = 145;
+ cTable[''] = 146;
+ cTable[''] = 147;
+ cTable[''] = 148;
+ cTable[''] = 149;
+ cTable[''] = 150;
+ cTable[''] = 151;
+ cTable[''] = 152;
+ cTable[''] = 153;
+ cTable[''] = 154;
+ cTable[''] = 155;
+ cTable[''] = 156;
+ cTable[''] = 157;
+ cTable[''] = 158;
+ cTable[''] = 159;
+ cTable[''] = 160;
+ cTable[''] = 161;
+ cTable[''] = 162;
+
+ cTable[''] = 163;
+ cTable[''] = 164;
+ cTable[''] = 165;
+ cTable[''] = 166;
+ cTable[''] = 167;
+ cTable[''] = 168;
+ cTable[''] = 169;
+ cTable[''] = 170;
+ cTable[''] = 171;
+ cTable[''] = 172;
+ cTable[''] = 173;
+ cTable[''] = 174;
+ cTable[''] = 175;
+ cTable[''] = 176;
+ cTable[''] = 177;
+ cTable[''] = 178;
+ cTable[''] = 179;
+ cTable[''] = 180;
+ cTable[''] = 181;
+ cTable[''] = 182;
+ cTable[''] = 183;
+ cTable[''] = 184;
+ cTable[''] = 185;
+ cTable[''] = 186;
+ cTable[''] = 187;
+ cTable[''] = 188;
+ cTable[''] = 189;
+ cTable[''] = 190;
+ cTable[''] = 191;
+ cTable[''] = 192;
+ cTable[''] = 193;
+ cTable[''] = 194;
+ cTable[''] = 195;
+
+ lTable[''] = 13;
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 11;
+ lTable[''] = 15;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 13;
+ lTable[''] = 13;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 14;
+ lTable[''] = 14;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 18;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 12;
+ lTable[''] = 17;
+ lTable[''] = 18;
+ lTable[''] = 16;
+ lTable[''] = 18;
+ lTable[''] = 19;
+ lTable[''] = 11;
+ lTable[''] = 16;
+ lTable[''] = 14;
+
+ lTable[''] = 14;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 14;
+ lTable[''] = 8;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 16;
+ lTable[''] = 14;
+ lTable[''] = 16;
+ lTable[''] = 16;
+ lTable[''] = 9;
+ lTable[''] = 15;
+ lTable[''] = 14;
+
+#endif // FONT_RUSSIAN
+
+#ifdef FONT_CZECH
+
+ cTable[''] = 196;
+ cTable[''] = 197;
+ cTable[''] = 198;
+ cTable[''] = 199;
+ cTable[''] = 200;
+ cTable[''] = 201;
+ cTable[''] = 202;
+ cTable[''] = 203;
+ cTable[''] = 204;
+ cTable[''] = 205;
+ cTable[''] = 206;
+ cTable[''] = 207;
+ cTable[''] = 208;
+ cTable[''] = 209;
+ cTable[''] = 210;
+
+ cTable[''] = 211;
+ cTable[''] = 212;
+ cTable[''] = 213;
+ cTable[''] = 214;
+ cTable[''] = 215;
+ cTable[''] = 216;
+ cTable[''] = 217;
+ cTable[''] = 218;
+ cTable[''] = 219;
+ cTable[''] = 220;
+ cTable[''] = 221;
+ cTable[''] = 222;
+ cTable[''] = 223;
+ cTable[''] = 224;
+ cTable[''] = 225;
+
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 14;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 15;
+ lTable[''] = 19;
+ lTable[''] = 10;
+ lTable[''] = 13;
+ lTable[''] = 13;
+ lTable[''] = 13;
+
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 15;
+ lTable[''] = 7;
+ lTable[''] = 12;
+ lTable[''] = 17;
+ lTable[''] = 16;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 13;
+
+#endif // FONT_CZECH
+
+#ifdef FONT_FRENCH
+ cTable[''] = 226;
+ cTable[''] = 227;
+ cTable[''] = 228;
+ cTable[''] = 229;
+ cTable[''] = 230;
+ cTable[''] = 231;
+ cTable[''] = 232;
+ cTable[''] = 233;
+
+ lTable[''] = 15;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 9;
+ lTable[''] = 13;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 11;
+
+#endif // FONT_FRENCH
+
+#ifdef FONT_GERMAN
+ cTable[''] = 234;
+ // 'SS' = 235
+ cTable[''] = 236;
+ cTable[''] = 237;
+ cTable[''] = 238;
+
+ lTable[''] = 15;
+
+#endif // FONT_GERMAN
+}
+
+
+/***************************************************************************\
+* Metodi di RMFontMacc
+\****************************************************************************/
+
+void RMFontMacc::Init(void) {
+ int i;
+
+ // bernie: numero di caratteri nel font
+ int nchars =
+ 102 // base
+ + 18 // polish
+ + 66 // russian
+ + 30 // czech
+ + 8 // francais
+ + 5; // deutsch
+
+
+ Load(RES_F_MACC, nchars, 11, 16);
+
+ // Default
+ lDefault = 10;
+ hDefault = 17;
+ Common::fill(&l2Table[0][0], &l2Table[0][0] + (256 * 256), '\0');
+
+ for (i = 0; i < 256; i++) {
+ cTable[i] = -1;
+ lTable[i] = lDefault;
+ }
+
+ for (i = 0; i < 26; i++)
+ cTable['A'+i] = i + 0;
+
+ for (i = 0; i < 26; i++)
+ cTable['a'+i] = i + 26;
+
+ for (i = 0; i < 10; i++)
+ cTable['0'+i] = i + 52;
+
+ cTable['!'] = 62;
+ //cTable['!'] = 63; // ! rovescia
+ cTable['\"'] = 64;
+ cTable['$'] = 65;
+ cTable['%'] = 66;
+ cTable['&'] = 67;
+ cTable['/'] = 68;
+ cTable['('] = 69;
+ cTable[')'] = 70;
+ cTable['='] = 71;
+ cTable['?'] = 72;
+ //cTable['?'] = 73; // ? rovescia
+ cTable['*'] = 74;
+ cTable['+'] = 75;
+ cTable[''] = 76;
+ cTable[';'] = 77;
+ cTable[','] = 78;
+ cTable['.'] = 79;
+ cTable[':'] = 80;
+ cTable['-'] = 81;
+ cTable['<'] = 82;
+ cTable[' > '] = 83;
+ cTable['/'] = 84;
+ cTable[''] = 85;
+ cTable[''] = 86;
+ cTable[''] = 87;
+ cTable[''] = 88;
+ cTable[''] = 89;
+ cTable[''] = 90;
+ //cTable[''] = 91; // e col pallino
+ cTable[''] = 92;
+ cTable[''] = 93;
+ //cTable[''] = 94; // i col pallino
+ cTable[''] = 95;
+ cTable[''] = 96;
+ //cTable[''] = 97; // o col pallino
+ cTable[''] = 98;
+ cTable[''] = 99;
+ //cTable[''] = 100; // u col pallino
+ cTable[''] = 101;
+
+ // Polish characters
+ //AaCcEeLlNnOoSsZzZz
+ //ス謎戊3剔囀
+
+ cTable[''] = 102;
+ cTable[''] = 103;
+ cTable[''] = 104;
+ cTable[''] = 105;
+ cTable[''] = 106;
+ cTable[''] = 107;
+ cTable[''] = 108;
+ cTable[''] = 109;
+ cTable[''] = 110;
+ cTable[''] = 111;
+ cTable[''] = 112;
+ cTable[''] = 113;
+ cTable[''] = 114;
+ cTable[''] = 115;
+ cTable[''] = 116;
+ cTable[''] = 117;
+ cTable[''] = 118;
+ cTable[''] = 119;
+
+ lTable[''] = 14;
+ lTable[''] = 16;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 14;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 13;
+ lTable[''] = 14;
+ lTable[''] = 13;
+
+
+#ifdef FONT_RUSSIAN
+ // Russian Characters
+ // WARNING: Il russo usa molti dei caratteri ISO-Latin-1 che servono
+ // per le altre traduzioni. Per compilare Tony in altre lingue,
+ // commentare via queste definizioni.
+
+ cTable[''] = 120;
+ cTable[''] = 121;
+ cTable[''] = 122;
+ cTable[''] = 123;
+ cTable[''] = 124;
+ cTable[''] = 125;
+ cTable[''] = 126;
+ cTable[''] = 127;
+ cTable[''] = 128;
+ cTable[''] = 129;
+ cTable[''] = 130;
+ cTable[''] = 131;
+ cTable[''] = 132;
+ cTable[''] = 133;
+ cTable[''] = 134;
+ cTable[''] = 135;
+ cTable[''] = 136;
+ cTable[''] = 137;
+ cTable[''] = 138;
+ cTable[''] = 139;
+ cTable[''] = 140;
+ cTable[''] = 141;
+ cTable[''] = 142;
+ cTable[''] = 143;
+ cTable[''] = 144;
+ cTable[''] = 145;
+ cTable[''] = 146;
+ cTable[''] = 147;
+ cTable[''] = 148;
+ cTable[''] = 149;
+ cTable[''] = 150;
+ cTable[''] = 151;
+ cTable[''] = 152;
+
+ cTable[''] = 153;
+ cTable[''] = 154;
+ cTable[''] = 155;
+ cTable[''] = 156;
+ cTable[''] = 157;
+ cTable[''] = 158;
+ cTable[''] = 159;
+ cTable[''] = 160;
+ cTable[''] = 161;
+ cTable[''] = 162;
+ cTable[''] = 163;
+ cTable[''] = 164;
+ cTable[''] = 165;
+ cTable[''] = 166;
+ cTable[''] = 167;
+ cTable[''] = 168;
+ cTable[''] = 169;
+ cTable[''] = 170;
+ cTable[''] = 171;
+ cTable[''] = 172;
+ cTable[''] = 173;
+ cTable[''] = 174;
+ cTable[''] = 175;
+ cTable[''] = 176;
+ cTable[''] = 177;
+ cTable[''] = 178;
+ cTable[''] = 179;
+ cTable[''] = 180;
+ cTable[''] = 181;
+ cTable[''] = 182;
+ cTable[''] = 183;
+ cTable[''] = 184;
+ cTable[''] = 185;
+
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 8;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 11;
+
+#endif // FONT_RUSSIAN
+
+#ifdef FONT_CZECH
+
+ cTable[''] = 186;
+ cTable[''] = 187;
+ cTable[''] = 188;
+ cTable[''] = 189;
+ cTable[''] = 190;
+ cTable[''] = 191;
+ cTable[''] = 192;
+ cTable[''] = 193;
+ cTable[''] = 194;
+ cTable[''] = 195;
+ cTable[''] = 196;
+ cTable[''] = 197;
+ cTable[''] = 198;
+ cTable[''] = 199;
+ cTable[''] = 200;
+
+ cTable[''] = 201;
+ cTable[''] = 202;
+ cTable[''] = 203;
+ cTable[''] = 204;
+ cTable[''] = 205;
+ cTable[''] = 206;
+ cTable[''] = 207;
+ cTable[''] = 208;
+ cTable[''] = 209;
+ cTable[''] = 210;
+ cTable[''] = 211;
+ cTable[''] = 212;
+ cTable[''] = 213;
+ cTable[''] = 214;
+ cTable[''] = 215;
+
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 9;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+
+#endif // FONT_CZECH
+
+#ifdef FONT_FRENCH
+
+ cTable[''] = 226;
+ cTable[''] = 227;
+ cTable[''] = 228;
+ cTable[''] = 229;
+ cTable[''] = 230;
+ cTable[''] = 231;
+ cTable[''] = 232;
+ cTable[''] = 233;
+
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 8;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 10;
+
+#endif // FONT_FRENCH
+
+#ifdef FONT_GERMAN
+ cTable[''] = 234;
+ // 'SS' = 235
+ cTable[''] = 236;
+ cTable[''] = 237;
+ cTable[''] = 238;
+
+ lTable[''] = 11;
+#endif // FONT_GERMAN
+}
+
+/***************************************************************************\
+* Metodi di RMFontCredits
+\****************************************************************************/
+
+void RMFontCredits::Init(void) {
+ int i;
+
+ // bernie: numero di caratteri nel font
+ int nchars =
+ 112 // base
+ + 18 // polish
+ + 66 // russian
+ + 30 // czech
+ + 8 // french
+ + 2; // deutsch
+
+
+ Load(RES_F_CREDITS, nchars, 27, 28, RES_F_CPAL);
+
+ // Default
+ lDefault=10;
+ hDefault=28;
+ Common::fill(&l2Table[0][0], &l2Table[0][0] + (256 * 256), '\0');
+
+ for (i = 0; i < 256; i++)
+ {
+ cTable[i] = -1;
+ lTable[i] = lDefault;
+ }
+
+ for (i = 0; i < 26; i++)
+ cTable['A' + i] = i + 0;
+
+ for (i = 0; i < 26; i++)
+ cTable['a' + i] = i + 26;
+
+
+
+ cTable[''] = 52;
+ cTable[''] = 53;
+// cTable[''] = 54; // a ^
+// cTable[''] = 55; // a pallini
+ cTable[''] = 56;
+ cTable[''] = 57;
+// cTable[''] = 58; // e ^
+// cTable[''] = 59; // e pallini
+ cTable[''] = 60;
+ cTable[''] = 61;
+// cTable[''] = 62; // i ^
+// cTable[''] = 63; // i pallini
+ cTable[''] = 64;
+ cTable[''] = 65;
+// cTable[''] = 66; // o ^
+// cTable[''] = 67; // o pallini
+ cTable[''] = 68;
+ cTable[''] = 69;
+// cTable[''] = 70; // u ^
+// cTable[''] = 71; // u pallini
+// cTable[''] = 72; // y pallini
+ cTable[''] = 73;
+ cTable[''] = 74;
+// cTable[''] = 75; // o barrato
+// cTable[''] = 76; // ac
+ cTable[''] = 77;
+// cTable[''] = 78; // ? rovesciato
+ cTable['?'] = 79;
+// cTable[''] = 80; // ! rovesciato
+ cTable['!'] = 81;
+// cTable[''] = 82; // 1/2
+// cTable[''] = 83; // 1/4
+ cTable['('] = 84;
+ cTable[')'] = 85;
+ cTable[''] = 86;
+ cTable[''] = 87;
+// cTable[''] = 88; // AE
+ cTable[':'] = 89;
+ cTable['%'] = 90;
+ cTable['&'] = 91;
+ cTable['/'] = 92;
+ cTable['+'] = 93;
+ cTable[';'] = 94;
+ cTable[','] = 95;
+ cTable['^'] = 96;
+ cTable['='] = 97;
+ cTable['_'] = 98;
+ cTable['*'] = 99;
+ cTable['.'] = 100;
+
+ for (i = 0; i < 10; i++)
+ cTable['0'+i] = i+101;
+ cTable['\''] = 111;
+
+ lTable[' '] = 11;
+ lTable[''] = lTable['A'] = 19;
+ lTable['B'] = 15;
+ lTable['C'] = 14;
+ lTable['D'] = 13;
+ lTable['E'] = 14;
+ lTable['F'] = 13;
+ lTable['G'] = 16;
+ lTable['H'] = 15;
+ lTable['I'] = 5;
+ lTable['J'] = 8;
+ lTable['K'] = 15;
+ lTable['L'] = 13;
+ lTable['M'] = 17;
+ lTable['N'] = 15;
+ lTable[''] = lTable['O'] = 14;
+ lTable['P'] = 12;
+ lTable['Q'] = 14;
+ lTable['R'] = 14;
+ lTable['S'] = 15;
+ lTable['T'] = 11;
+ lTable[''] = lTable['U'] = 12;
+ lTable['V'] = 12;
+ lTable['W'] = 16;
+ lTable['X'] = 12;
+ lTable['Y'] = 13;
+ lTable['Z'] = 14;
+
+ lTable['a'] = 11;
+ lTable['b'] = 9;
+ lTable['c'] = 9;
+ lTable['d'] = 10;
+ lTable['e'] = 9;
+ lTable['f'] = 8;
+ lTable['g'] = 9;
+ lTable['h'] = 10;
+ lTable['i'] = 5;
+ lTable['j'] = 6;
+ lTable['k'] = 12;
+ lTable['l'] = 6;
+ lTable['m'] = 14;
+ lTable['n'] = 10;
+ lTable['o'] = 11;
+ lTable['p'] = 11;
+ lTable['q'] = 9;
+ lTable['r'] = 9;
+ lTable['s'] = 9;
+ lTable['t'] = 6;
+ lTable['u'] = 9;
+ lTable['v'] = 10;
+ lTable['w'] = 14;
+ lTable['x'] = 9;
+ lTable['y'] = 10;
+ lTable['z'] = 9;
+
+ lTable['0'] = 12;
+ lTable['1'] = 8;
+ lTable['2'] = 10;
+ lTable['3'] = 11;
+ lTable['4'] = 12;
+ lTable['5'] = 11;
+ lTable['6'] = 12;
+ lTable['7'] = 10;
+ lTable['8'] = 11;
+ lTable['9'] = 10;
+
+ lTable['/'] = 10;
+ lTable['^'] = 9;
+ lTable[','] = 5;
+ lTable['.'] = 5;
+ lTable[';'] = 5;
+ lTable[':'] = 5;
+ lTable['\''] = 5;
+
+
+
+ // Polish characters
+ //AaCcEeLlNnOoSsZzZz
+ //ス謎戊3剔囀
+
+ cTable[''] = 112;
+ cTable[''] = 113;
+ cTable[''] = 114;
+ cTable[''] = 115;
+ cTable[''] = 116;
+ cTable[''] = 117;
+ cTable[''] = 118;
+ cTable[''] = 119;
+ cTable[''] = 120;
+ cTable[''] = 121;
+ cTable[''] = 122;
+ cTable[''] = 123;
+ cTable[''] = 124;
+ cTable[''] = 125;
+ cTable[''] = 126;
+ cTable[''] = 127;
+ cTable[''] = 128;
+ cTable[''] = 129;
+
+ lTable[''] = 20;
+ lTable[''] = 12;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 14;
+ lTable[''] = 11;
+ lTable[''] = 16;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 11;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 10;
+
+
+#ifdef FONT_RUSSIAN
+ // Russian Characters
+ // WARNING: Il russo usa molti dei caratteri ISO-Latin-1 che servono
+ // per le altre traduzioni. Per compilare Tony in altre lingue,
+ // commentare via queste definizioni.
+
+ cTable[''] = 130;
+ cTable[''] = 131;
+ cTable[''] = 132;
+ cTable[''] = 133;
+ cTable[''] = 134;
+ cTable[''] = 135;
+ cTable[''] = 136;
+ cTable[''] = 137;
+ cTable[''] = 138;
+ cTable[''] = 139;
+ cTable[''] = 140;
+ cTable[''] = 141;
+ cTable[''] = 142;
+ cTable[''] = 143;
+ cTable[''] = 144;
+ cTable[''] = 145;
+ cTable[''] = 146;
+ cTable[''] = 147;
+ cTable[''] = 148;
+ cTable[''] = 149;
+ cTable[''] = 150;
+ cTable[''] = 151;
+ cTable[''] = 152;
+ cTable[''] = 153;
+ cTable[''] = 154;
+ cTable[''] = 155;
+ cTable[''] = 156;
+ cTable[''] = 157;
+ cTable[''] = 158;
+ cTable[''] = 159;
+ cTable[''] = 160;
+ cTable[''] = 161;
+ cTable[''] = 162;
+
+ cTable[''] = 163;
+ cTable[''] = 164;
+ cTable[''] = 165;
+ cTable[''] = 166;
+ cTable[''] = 167;
+ cTable[''] = 168;
+ cTable[''] = 169;
+ cTable[''] = 170;
+ cTable[''] = 171;
+ cTable[''] = 172;
+ cTable[''] = 173;
+ cTable[''] = 174;
+ cTable[''] = 175;
+ cTable[''] = 176;
+ cTable[''] = 177;
+ cTable[''] = 178;
+ cTable[''] = 179;
+ cTable[''] = 180;
+ cTable[''] = 181;
+ cTable[''] = 182;
+ cTable[''] = 183;
+ cTable[''] = 184;
+ cTable[''] = 185;
+ cTable[''] = 186;
+ cTable[''] = 187;
+ cTable[''] = 188;
+ cTable[''] = 189;
+ cTable[''] = 190;
+ cTable[''] = 191;
+ cTable[''] = 192;
+ cTable[''] = 193;
+ cTable[''] = 194;
+ cTable[''] = 195;
+
+ lTable[''] = 20;
+ lTable[''] = 16;
+ lTable[''] = 16;
+ lTable[''] = 14;
+ lTable[''] = 22;
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 20;
+ lTable[''] = 12;
+ lTable[''] = 16;
+ lTable[''] = 16;
+ lTable[''] = 16;
+ lTable[''] = 22;
+ lTable[''] = 18;
+ lTable[''] = 16;
+ lTable[''] = 15;
+ lTable[''] = 14;
+ lTable[''] = 13;
+ lTable[''] = 15;
+ lTable[''] = 12;
+ lTable[''] = 14;
+ lTable[''] = 15;
+ lTable[''] = 13;
+ lTable[''] = 16;
+ lTable[''] = 14;
+ lTable[''] = 23;
+ lTable[''] = 23;
+ lTable[''] = 10;
+ lTable[''] = 12;
+ lTable[''] = 16;
+ lTable[''] = 12;
+ lTable[''] = 20;
+ lTable[''] = 15;
+
+ lTable[''] = 12;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 16;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 13;
+ lTable[''] = 12;
+ lTable[''] = 13;
+ lTable[''] = 14;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 12;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 10;
+ lTable[''] = 12;
+ lTable[''] = 16;
+ lTable[''] = 11;
+ lTable[''] = 13;
+ lTable[''] = 11;
+
+#endif // FONT_RUSSIAN
+
+#ifdef FONT_CZECH
+
+ cTable[''] = 196;
+ cTable[''] = 197;
+ cTable[''] = 198;
+ cTable[''] = 199;
+ cTable[''] = 200;
+ cTable[''] = 201;
+ cTable[''] = 202;
+ cTable[''] = 203;
+ cTable[''] = 204;
+ cTable[''] = 205;
+ cTable[''] = 206;
+ cTable[''] = 207;
+ cTable[''] = 208;
+ cTable[''] = 209;
+ cTable[''] = 210;
+
+ cTable[''] = 211;
+ cTable[''] = 212;
+ cTable[''] = 213;
+ cTable[''] = 214;
+ cTable[''] = 215;
+ cTable[''] = 216;
+ cTable[''] = 217;
+ cTable[''] = 218;
+ cTable[''] = 219;
+ cTable[''] = 220;
+ cTable[''] = 221;
+ cTable[''] = 222;
+ cTable[''] = 223;
+ cTable[''] = 224;
+ cTable[''] = 225;
+
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 15;
+ lTable[''] = 14;
+ lTable[''] = 20;
+ lTable[''] = 7;
+ lTable[''] = 15;
+ lTable[''] = 20;
+ lTable[''] = 19;
+ lTable[''] = 16;
+ lTable[''] = 15;
+ lTable[''] = 13;
+ lTable[''] = 13;
+
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 12;
+ lTable[''] = 6;
+ lTable[''] = 10;
+ lTable[''] = 15;
+ lTable[''] = 12;
+ lTable[''] = 11;
+ lTable[''] = 11;
+ lTable[''] = 10;
+ lTable[''] = 10;
+
+#endif // FONT_CZECH
+
+#ifdef FONT_FRENCH
+
+ cTable[''] = 226;
+ cTable[''] = 227;
+ cTable[''] = 228;
+ cTable[''] = 229;
+ cTable[''] = 230;
+ cTable[''] = 231;
+ cTable[''] = 232;
+ cTable[''] = 233;
+
+ lTable[''] = 12;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 6;
+ lTable[''] = 10;
+ lTable[''] = 10;
+ lTable[''] = 11;
+ lTable[''] = 11;
+
+#endif // FONT_FRENCH
+
+#ifdef FONT_GERMAN
+ cTable[''] = 234;
+ // 'SS' = 235
+
+ // old chars overrides
+ cTable[''] = cTable[''] = 55;
+ cTable[''] = cTable[''] = 67;
+ cTable[''] = cTable[''] = 71;
+
+ lTable[''] = 11;
+
+#endif // FONT_GERMAN
+}
+
+
+
+/***************************************************************************\
+* Metodi di RMFontObj
+\****************************************************************************/
+
+#define TOUPPER(a) ((a) >='a'&&(a)<='z'?(a)+'A'-'a':(a))
+#define TOLOWER(a) ((a) >='A'&&(a)<='Z'?(a)+'a'-'A':(a))
+
+void RMFontObj::SetBothCase(int nChar, int nNext, signed char spiazz) {
+ l2Table[TOUPPER(nChar)][TOUPPER(nNext)] = spiazz;
+ l2Table[TOUPPER(nChar)][TOLOWER(nNext)] = spiazz;
+ l2Table[TOLOWER(nChar)][TOUPPER(nNext)] = spiazz;
+ l2Table[TOLOWER(nChar)][TOLOWER(nNext)] = spiazz;
+}
+
+
+void RMFontObj::Init(void) {
+ int i;
+
+ //bernie: numero di caratteri nel font (solo maiuscolo)
+ int nchars =
+ 85 // base
+ + 9 // polish
+ + 33 // russian
+ + 15 // czech
+ + 0 // francais (no uppercase chars)
+ + 1; // deutsch
+
+
+ Load(RES_F_OBJ, nchars, 25, 30);
+
+ // Inizializziamo le tabelline del cazzo
+ lDefault = 26;
+ hDefault = 30;
+ Common::fill(&l2Table[0][0], &l2Table[0][0] + (256 * 256), '\0');
+
+ for (i = 0; i < 256; i++)
+ {
+ cTable[i] = -1;
+ lTable[i] = lDefault;
+ }
+
+ for (i = 0; i < 26; i++)
+ {
+ cTable['A'+i] = i+0;
+ cTable['a'+i] = i+0;
+ }
+
+ for (i = 0; i < 10; i++)
+ cTable['0'+i] = i+26;
+
+ cTable[','] = 36;
+ cTable[';'] = 37;
+ cTable['.'] = 38;
+ cTable[':'] = 39;
+ cTable['-'] = 40;
+ cTable['+'] = 41;
+ cTable['!'] = 42;
+ // cTable['!'] = 43; Esclamativo alla rovescia
+ cTable['?'] = 44;
+ //cTable['?'] = 45; Interrogativo alla rovescia
+ cTable['/'] = 46;
+ cTable['('] = 47;
+ cTable[')'] = 48;
+ cTable['='] = 49;
+ cTable['\''] = 50;
+ cTable['\"'] = 51;
+ cTable[''] = 52;
+ cTable['$'] = 53;
+ cTable['%'] = 54;
+ cTable['&'] = 55;
+ cTable['^'] = 56;
+ cTable['*'] = 57;
+ cTable['<'] = 58;
+ cTable[' > '] = 59;
+ cTable[''] = 60;
+ cTable[''] = 61;
+ cTable[''] = 62;
+ cTable[''] = 63;
+ //cTable[''] = 64; integrale
+ cTable[''] = 65;
+ cTable[''] = 66;
+ cTable[''] = 67;
+ cTable[''] = 68;
+ cTable[''] = 69;
+ cTable[''] = cTable[''] = 70;
+ cTable[''] = 71;
+ cTable[''] = 72;
+ cTable[''] = 73;
+ //cTable[' '] = 74; e cerchietto
+ cTable[''] = 75;
+ cTable[''] = 76;
+ //cTable[' '] = 77; i cerchietto
+ cTable[''] = 78;
+ cTable[''] = cTable[''] = 79;
+ //cTable[' '] = 80; o cerchietto
+ cTable[''] = 81;
+ cTable[''] = cTable[''] = 82;
+ //cTable[' '] = 83; u cerchietto
+ //cTable[' '] = 84; y dieresi
+
+ /* Un po' di lunghezze */
+ lTable[' '] = 11;
+ lTable['.'] = 8;
+ lTable['-'] = 12;
+ lTable['\''] = 8;
+ lTable['0'] = 20;
+ lTable['1'] = 20;
+ lTable['2'] = 15;
+ lTable['3'] = 20;
+ lTable['4'] = 20;
+ lTable['5'] = 20;
+ lTable['6'] = 20;
+ lTable['7'] = 20;
+ lTable['8'] = 20;
+ lTable['9'] = 20;
+
+
+ lTable['a'] = lTable['A'] = lTable[''] = lTable[''] = 17;
+ lTable['b'] = lTable['B'] = 17;
+ lTable['c'] = lTable['C'] = 19;
+ lTable['d'] = lTable['D'] = 17;
+ lTable['e'] = lTable['E'] = 15;
+ lTable['f'] = lTable['F'] = 17;
+ lTable['g'] = lTable['G'] = 19;
+ lTable['i'] = lTable['I'] = 16;
+ lTable['h'] = lTable['H'] = 17;
+ lTable['k'] = lTable['K'] = 17;
+ lTable['l'] = lTable['L'] = 14;
+ lTable['m'] = lTable['M'] = 19;
+ lTable['n'] = lTable['N'] = 17;
+ lTable['o'] = lTable['O'] = lTable[''] = lTable[''] = 19;
+ lTable['p'] = lTable['P'] = 17;
+ lTable['q'] = lTable['Q'] = 19;
+ lTable['r'] = lTable['R'] = 14;
+ lTable['s'] = lTable['S'] = 13;
+ lTable['t'] = lTable['T'] = 15;
+ lTable['u'] = lTable['U'] = lTable[''] = lTable[''] = 15;
+ lTable['v'] = lTable['V'] = 13;
+ lTable['x'] = lTable['X'] = 15;
+ lTable['y'] = lTable['Y'] = 13;
+ lTable['w'] = lTable['W'] = 19;
+ lTable['z'] = lTable['Z'] = 20;
+ lTable[''] = 17;
+
+ /* Casi particolari */
+ SetBothCase('C','C',2);
+ SetBothCase('A','T',-2);
+ SetBothCase('R','S',2);
+ SetBothCase('H','I',-2);
+ SetBothCase('T','S',2);
+ SetBothCase('O','R',2);
+ SetBothCase('O','L',2);
+ SetBothCase('O','G',2);
+ SetBothCase('Z','A',-1);
+ SetBothCase('R','R',1);
+ SetBothCase('R','U',3);
+
+
+ // Polish characters
+ //ス謎戊3剔囀
+ //AaCcEeLlNnOoSsZzZz
+ cTable[''] = cTable[''] = 85;
+ lTable[''] = lTable[''] = 20;
+
+ cTable[''] = cTable[''] = 86;
+ lTable[''] = lTable[''] = 22;
+
+ cTable[''] = cTable[''] = 87;
+ lTable[''] = lTable[''] = 17;
+
+ cTable[''] = cTable[''] = 88;
+ lTable[''] = lTable[''] = 19;
+
+ cTable[''] = cTable[''] = 89;
+ lTable[''] = lTable[''] = 17;
+
+ cTable[''] = cTable[''] = 90;
+ lTable[''] = lTable[''] = 22;
+
+ cTable[''] = cTable[''] = 91;
+ lTable[''] = lTable[''] = 15;
+
+ cTable[''] = cTable[''] = 92;
+ lTable[''] = lTable[''] = 21;
+
+ cTable[''] = cTable[''] = 93;
+ lTable[''] = lTable[''] = 21;
+
+
+#ifdef FONT_RUSSIAN
+ // Russian Characters
+ // WARNING: Il russo usa molti dei caratteri ISO-Latin-1 che servono
+ // per le altre traduzioni. Per compilare Tony in altre lingue,
+ // commentare via queste definizioni.
+
+ cTable[''] = cTable[''] = 85;
+ lTable[''] = lTable[''] = 20;
+
+ cTable[''] = cTable[''] =94;
+ cTable[''] = cTable[''] =95;
+ cTable[''] = cTable[''] =96;
+ cTable[''] = cTable[''] =97;
+ cTable[''] = cTable[''] =98;
+ cTable[''] = cTable[''] =99;
+ cTable[''] = cTable[''] =100;
+ cTable[''] = cTable[''] =101;
+ cTable[''] = cTable[''] =102;
+ cTable[''] = cTable[''] =103;
+ cTable[''] = cTable[''] =104;
+ cTable[''] = cTable[''] =105;
+ cTable[''] = cTable[''] =106;
+ cTable[''] = cTable[''] =107;
+ cTable[''] = cTable[''] =108;
+ cTable[''] = cTable[''] =109;
+ cTable[''] = cTable[''] =110;
+ cTable[''] = cTable[''] =111;
+ cTable[''] = cTable[''] =112;
+ cTable[''] = cTable[''] =113;
+ cTable[''] = cTable[''] =114;
+ cTable[''] = cTable[''] =115;
+ cTable[''] = cTable[''] =116;
+ cTable[''] = cTable[''] =117;
+ cTable[''] = cTable[''] =118;
+ cTable[''] = cTable[''] =119;
+ cTable[''] = cTable[''] =120;
+ cTable[''] = cTable[''] =121;
+ cTable[''] = cTable[''] =122;
+ cTable[''] = cTable[''] =123;
+ cTable[''] = cTable[''] =124;
+ cTable[''] = cTable[''] =125;
+ cTable[''] = cTable[''] =126;
+
+
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 17;
+ lTable[''] = lTable[''] = 16;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 20;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 16;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 15;
+ lTable[''] = lTable[''] = 22;
+ lTable[''] = lTable[''] = 15;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 22;
+ lTable[''] = lTable[''] = 19;
+ lTable[''] = lTable[''] = 16;
+ lTable[''] = lTable[''] = 21;
+ lTable[''] = lTable[''] = 20;
+ lTable[''] = lTable[''] = 16;
+ lTable[''] = lTable[''] = 16;
+ lTable[''] = lTable[''] = 19;
+ lTable[''] = lTable[''] = 22;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 19;
+ lTable[''] = lTable[''] = 19;
+ lTable[''] = lTable[''] = 15;
+ lTable[''] = lTable[''] = 18;
+ lTable[''] = lTable[''] = 18;
+
+#endif // FONT_RUSSIAN
+
+#ifdef FONT_CZECH
+ // rep. ceca characters
+
+ cTable[''] = cTable[''] = 127;
+ cTable[''] = cTable[''] = 128;
+ cTable[''] = cTable[''] = 129;
+ cTable[''] = cTable[''] = 130;
+ cTable[''] = cTable[''] = 131;
+ cTable[''] = cTable[''] = 132;
+ cTable[''] = cTable[''] = 133;
+ cTable[''] = cTable[''] = 134;
+ cTable[''] = cTable[''] = 135;
+ cTable[''] = cTable[''] = 136;
+ cTable[''] = cTable[''] = 137;
+ cTable[''] = cTable[''] = 138;
+ cTable[''] = cTable[''] = 139;
+ cTable[''] = cTable[''] = 140;
+ cTable[''] = cTable[''] = 141;
+
+ lTable[''] = lTable[''] =17;
+ lTable[''] = lTable[''] =15;
+ lTable[''] = lTable[''] =22;
+ lTable[''] = lTable[''] =18;
+ lTable[''] = lTable[''] =21;
+ lTable[''] = lTable[''] =16;
+ lTable[''] = lTable[''] =18;
+ lTable[''] = lTable[''] =19;
+ lTable[''] = lTable[''] =17;
+ lTable[''] = lTable[''] =23;
+ lTable[''] = lTable[''] =24;
+ lTable[''] = lTable[''] =17;
+ lTable[''] = lTable[''] =22;
+ lTable[''] = lTable[''] =16;
+ lTable[''] = lTable[''] =16;
+
+#endif // FONT_CZECH
+
+#ifdef FONT_FRENCH
+
+ // traduci le lettere accentate in lettere normali
+
+ cTable[''] = cTable[''] = cTable[''] = 0; // a
+ lTable[''] = lTable[''] = lTable[''] = 17;
+
+ cTable[''] = cTable[''] = 4; // e
+ lTable[''] = lTable[''] = 15;
+
+ cTable[''] = cTable[''] = cTable[''] = 8; // i
+ lTable[''] = lTable[''] = lTable[''] = 16;
+
+ cTable[''] = cTable[''] = cTable[''] = cTable[''] = 14; // o
+ lTable[''] = lTable[''] = lTable[''] = lTable[''] = 19;
+
+ cTable[''] = cTable[''] = 20; // u
+ lTable[''] = lTable[''] = 15;
+
+#endif // FONT_FRENCH
+
+#ifdef FONT_GERMAN
+ cTable[''] = 142;
+ // SS = 143
+
+ lTable[''] = 24;
+#endif // FONT_GERMAN
+}
+
+
+/****************************************************************************\
+* Metodi di RMText
+\****************************************************************************/
+
+RMFontColor *RMText::m_fonts[4] = { NULL, NULL, NULL, NULL };
+OSystem::MutexRef RMText::m_cs;
+RMGfxClearTask RMText::m_clear;
+
+RMText::RMText() {
+ // Colore di default: bianco
+ m_r = m_g = m_b = 255;
+
+ // Lunghezza di default
+ maxLineLength = 350;
+
+ m_bTrasp0 = true;
+ aHorType = HCENTER;
+ aVerType = VTOP;
+ SetPriority(150);
+}
+
+RMText::~RMText() {
+
+}
+
+void RMText::SetMaxLineLength(int max) {
+ maxLineLength = max;
+}
+
+bool RMText::RemoveThis() {
+ // Qui possiamo fare i controlli sul numero di frame, sul tempo trascorso
+ // etc.
+ return true;
+}
+
+
+void RMText::WriteText(RMString text, int nFont, int *time) {
+ // Inizializza i font (una volta sola)
+ if (m_fonts[0] == NULL) {
+ m_fonts[0] = new RMFontParla; m_fonts[0]->Init();
+ m_fonts[1] = new RMFontObj; m_fonts[1]->Init();
+ m_fonts[2] = new RMFontMacc; m_fonts[2]->Init();
+ m_fonts[3] = new RMFontCredits; m_fonts[3]->Init();
+ }
+
+ g_system->lockMutex(m_cs);
+ WriteText(text,m_fonts[nFont],time);
+ g_system->unlockMutex(m_cs);
+}
+
+
+void RMText::WriteText(RMString text, RMFontColor *font, int *time) {
+ RMGfxPrimitive *prim;
+ char *p, *old_p;
+ int i, j, x, y;
+ int len;
+ int numchar;
+ int width, height;
+ char *string;
+ int numlines;
+
+ // Setta il colore di base
+ font->SetBaseColor(m_r, m_g, m_b);
+
+ // Si autodistrugge il buffer prima di iniziare
+ Destroy();
+
+ // Se la stringa vuota, non fare nulla
+ if (text == NULL || text[0] == '\0')
+ return;
+
+ // Divide la frase in linee. In questo ciclo, X contiene la lunghezza massima raggiunta da una linea
+ // e I il numero delle linee
+ string=p = text;
+ i = j = x = 0;
+ while (*p != '\0') {
+ j += font->StringLen(*p);
+ if (j > (((aHorType == HLEFTPAR) && (i > 0)) ? maxLineLength - 25 : maxLineLength)) {
+ j -= font->StringLen(*p, p[1]);
+ if (j > x) x = j;
+
+ // Torna indietro al primo spazio utile
+ //
+ // BERNIE: nella versione originale le frasi contenenti
+ // parole che superano la larghezza di una riga causavano
+ // l'interruzione dell'intera frase.
+ // Questo workaround e' parziale: la parola troppo lunga
+ // viene spezzata bruscamente e si perde una lettera.
+ // Oltre allo spazio e' ammesso il wrap sul carattere '-'.
+ //
+ old_p = p;
+ while (*p != ' ' && *p != '-' && p > string) p--;
+
+ if (p == string)
+ p = old_p;
+
+ // Controlla se sono tutti spazi fino alla fine
+ while (*p == ' ' && *p != '\0') p++;
+ if (*p == '\0')
+ break;
+ p--;
+ i++;
+ *p = '\0';
+ j = 0;
+ }
+ p++;
+ }
+
+ if (j > x) x = j;
+
+ i++;
+ numlines = i;
+
+ // X=Lunghezza della linea piu' lunga. Controlla se puo' essere puttata a X1
+ //x+=font->StringLen(-1)+1; // Meglio esagerare per sicurezza
+ x += 8;
+
+ // Posizione di partenza per la surface: X1,Y
+ width = x;
+ height = (numlines - 1) * font->LetterHeight() + font->m_fontDimy;
+
+ // Crea la surface
+ Create(width, height);
+ //AddPrim(new RMGfxPrimitive(&m_clear));
+ Common::fill(m_buf, m_buf + width * height * 2, 0);
+
+ p = string;
+
+ y = 0;
+ numchar = 0;
+ for (; i > 0; i--) {
+ // Misura la lunghezza della linea
+ x = 0;
+ j = font->StringLen(RMString(p));
+
+ switch (aHorType) {
+ case HLEFT:
+ x = 0;
+ break;
+
+ case HLEFTPAR:
+ if (i == numlines)
+ x=0;
+ else
+ x = 25;
+ break;
+
+ case HCENTER:
+ x = width / 2 - j / 2;
+ break;
+
+ case HRIGHT:
+ x = width - j - 1;
+ break;
+ }
+
+ while (*p != '\0') {
+ if (*p == ' ') {
+ x += font->StringLen(*p);
+ p++;
+ continue;
+ }
+
+ prim = font->MakeLetterPrimitive(*p, len);
+ prim->Dst().x1 = x;
+ prim->Dst().y1 = y;
+ AddPrim(prim);
+
+ numchar++;
+
+ x += font->StringLen(*p, p[1]);
+ p++;
+ }
+ p++;
+ y += font->LetterHeight();
+ }
+
+ if (time != NULL)
+ *time = 1000 + numchar * (11 - nCfgTextSpeed) * 14;
+}
+
+void RMText::ClipOnScreen(RMGfxPrimitive *prim) {
+ // Cerca di non farlo uscire dallo schermo
+ if (prim->Dst().x1 < 5) prim->Dst().x1 = 5;
+ if (prim->Dst().y1 < 5) prim->Dst().y1 = 5;
+ if (prim->Dst().x1+m_dimx > 635) prim->Dst().x1 = 635 - m_dimx;
+ if (prim->Dst().y1+m_dimy > 475) prim->Dst().y1 = 475 - m_dimy;
+}
+
+void RMText::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ // Allinea orizzontalmente
+ if (aHorType == HCENTER)
+ prim->Dst().TopLeft() -= RMPoint(m_dimx / 2, 0);
+ else if (aHorType == HRIGHT)
+ prim->Dst().TopLeft() -= RMPoint(m_dimx, 0);
+
+
+ // Alinea verticalemente
+ switch (aVerType) {
+ case VTOP:
+ break;
+
+ case VCENTER:
+ prim->Dst().y1-=m_dimy/2;
+ break;
+
+ case VBOTTOM:
+ prim->Dst().y1-=m_dimy;
+ break;
+ }
+
+ ClipOnScreen(prim);
+
+ RMGfxWoodyBuffer::Draw(bigBuf,prim);
+}
+
+/****************************************************************************\
+* Metodi di RMTextDialog
+\****************************************************************************/
+
+RMTextDialog::RMTextDialog() : RMText() {
+ m_startTime = 0;
+ dst = RMPoint(0,0);
+
+ m_bSkipStatus = true;
+ m_bShowed = true;
+ m_bForceTime = false;
+ m_bForceNoTime = false;
+ m_bAlwaysDisplay = false;
+ m_bNoTab = false;
+ hCustomSkip = INVALID_HANDLE_VALUE;
+ hCustomSkip2 = INVALID_HANDLE_VALUE;
+ m_input = NULL;
+
+ // Crea l'evento di fine displaying
+ hEndDisplay = CreateEvent(NULL, false, false, NULL);
+}
+
+RMTextDialog::~RMTextDialog() {
+ CloseHandle(hEndDisplay);
+}
+
+void RMTextDialog::Show(void) {
+ m_bShowed = true;
+}
+
+void RMTextDialog::Hide(void) {
+ m_bShowed = false;
+}
+
+void RMTextDialog::WriteText(RMString text, int font, int *time) {
+ RMText::WriteText(text,font,&m_time);
+
+ if (time != NULL)
+ *time = m_time;
+}
+
+void RMTextDialog::WriteText(RMString text, RMFontColor *font, int *time) {
+ RMText::WriteText(text,font,&m_time);
+
+ if (time != NULL)
+ *time = m_time;
+}
+
+
+void RMTextDialog::SetSkipStatus(bool bEnabled) {
+ m_bSkipStatus=bEnabled;
+}
+
+void RMTextDialog::ForceTime(void) {
+ m_bForceTime = true;
+}
+
+void RMTextDialog::ForceNoTime(void) {
+ m_bForceNoTime = true;
+}
+
+void RMTextDialog::SetNoTab(void) {
+ m_bNoTab = true;
+}
+
+void RMTextDialog::SetForcedTime(uint32 dwTime) {
+ m_time = dwTime;
+}
+
+void RMTextDialog::SetAlwaysDisplay(void) {
+ m_bAlwaysDisplay = true;
+}
+
+bool RMTextDialog::RemoveThis(void) {
+ // Frase NON di background
+ if (m_bSkipStatus) {
+ if (!(bCfgDubbing && hCustomSkip2 != INVALID_HANDLE_VALUE))
+ if (bCfgTimerizedText) {
+ if (!m_bForceNoTime)
+ if (_vm->GetTime() > (uint32)m_time + m_startTime)
+ return true;
+ }
+
+ if (!m_bNoTab)
+ if ((GetAsyncKeyState(Common::KEYCODE_TAB) & 0x8001) == 0x8001)
+ return true;
+
+ if (!m_bNoTab)
+ if (m_input)
+ if (m_input->MouseLeftClicked() || m_input->MouseRightClicked())
+ return true;
+ }
+ // Frase di background
+ else {
+ if (!(bCfgDubbing && hCustomSkip2 != INVALID_HANDLE_VALUE))
+ if (!m_bForceNoTime)
+ if (_vm->GetTime() > (uint32)m_time + m_startTime)
+ return true;
+ }
+
+ // Se il tempo forzato
+ if (m_bForceTime)
+ if (_vm->GetTime() > (uint32)m_time + m_startTime)
+ return true;
+
+ if (hCustomSkip != INVALID_HANDLE_VALUE)
+ if (WaitForSingleObject(hCustomSkip, 0) == WAIT_OBJECT_0)
+ return true;
+
+ if (bCfgDubbing && hCustomSkip2 != INVALID_HANDLE_VALUE)
+ if (WaitForSingleObject(hCustomSkip2,0) == WAIT_OBJECT_0)
+ return true;
+
+ return false;
+}
+
+void RMTextDialog::Unregister(void) {
+ RMGfxTask::Unregister();
+ assert(m_nInList == 0);
+ SetEvent(hEndDisplay);
+}
+
+void RMTextDialog::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ if (m_startTime == 0)
+ m_startTime = _vm->GetTime();
+
+ if (m_bShowed) {
+ if (bCfgSottotitoli || m_bAlwaysDisplay) {
+ prim->Dst().TopLeft() = dst;
+ RMText::Draw(bigBuf, prim);
+ }
+ }
+}
+
+void RMTextDialog::SetCustomSkipHandle(HANDLE hCustom) {
+ hCustomSkip = hCustom;
+}
+
+void RMTextDialog::SetCustomSkipHandle2(HANDLE hCustom) {
+ hCustomSkip2 = hCustom;
+}
+
+void RMTextDialog::WaitForEndDisplay(void) {
+ WaitForSingleObject(hEndDisplay, INFINITE);
+}
+
+void RMTextDialog::SetInput(RMInput *input) {
+ m_input = input;
+}
+
+/****************************************************************************\
+* Metodi di RMTextDialogScrolling
+\****************************************************************************/
+
+RMTextDialogScrolling::RMTextDialogScrolling() {
+ curLoc = NULL;
+}
+
+RMTextDialogScrolling::RMTextDialogScrolling(RMLocation *loc) {
+ curLoc = loc;
+ startScroll = loc->ScrollPosition();
+}
+
+RMTextDialogScrolling::~RMTextDialogScrolling() {
+}
+
+void RMTextDialogScrolling::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ RMPoint curDst;
+
+ curDst = dst;
+
+ if (curLoc != NULL)
+ dst -= curLoc->ScrollPosition() - startScroll;
+
+ RMTextDialog::Draw(bigBuf, prim);
+
+ dst = curDst;
+}
+
+void RMTextDialogScrolling::ClipOnScreen(RMGfxPrimitive *prim) {
+ // Non dobbiamo fare nulla!
+}
+
+
+/****************************************************************************\
+* Metodi di RMTextItemName
+\****************************************************************************/
+
+RMTextItemName::RMTextItemName() : RMText() {
+ m_item = NULL;
+ SetPriority(220);
+}
+
+RMTextItemName::~RMTextItemName() {
+
+}
+
+void RMTextItemName::DoFrame(RMGfxTargetBuffer& bigBuf, RMLocation &loc, RMPointer &ptr, RMInventory &inv) {
+ RMString itemName;
+ RMItem *lastItem = m_item;
+
+ // Si aggiunge alla lista se c'e' bisogno
+ if (!m_nInList)
+ bigBuf.AddPrim(new RMGfxPrimitive(this));
+
+ // Aggiorna le coordinate di scrolling
+ m_curscroll = loc.ScrollPosition();
+
+ // Controlla se siamo sopra l'inventario
+ if (inv.ItemInFocus(m_mpos))
+ m_item = inv.WhichItemIsIn(m_mpos);
+ else
+ m_item = loc.WhichItemIsIn(m_mpos);
+
+ itemName = "";
+
+ // Si fa dare il nuovo nome
+ if (m_item != NULL)
+ m_item->GetName(itemName);
+
+ // Se lo scrive
+ WriteText(itemName, 1);
+
+ // Se e' diverso dal precedente, e' il caso di aggiornare anche il puntatore con la WhichPointer
+ if (lastItem != m_item)
+ {
+ if (m_item == NULL)
+ ptr.SetSpecialPointer(RMPointer::PTR_NONE);
+ else {
+ HANDLE hThread = mpalQueryDoAction(20, m_item->MpalCode(), 0);
+ if (hThread == INVALID_HANDLE_VALUE)
+ ptr.SetSpecialPointer(RMPointer::PTR_NONE);
+ else
+ WaitForSingleObject(hThread,INFINITE);
+ }
+ }
+}
+
+
+void RMTextItemName::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ // Se non c'e' testo, e' inutile continuare
+ if (m_buf == NULL)
+ return;
+
+ // Setta come coordinate destinazione quelle del mouse
+ prim->Dst().TopLeft() = m_mpos-RMPoint(0, 30);
+
+ RMText::Draw(bigBuf,prim);
+}
+
+
+/****************************************************************************\
+* Metodi di RMDialogChoice
+\****************************************************************************/
+
+RMDialogChoice::RMDialogChoice() {
+ RMResRaw dlg1(RES_I_DLGTEXT);
+ RMResRaw dlg2(RES_I_DLGTEXTLINE);
+ RMRes dlgpal(RES_I_DLGTEXTPAL);
+
+ DlgText.Init(dlg1, dlg1.Width(), dlg1.Height());
+ DlgTextLine.Init(dlg2, dlg2.Width(), dlg2.Height());
+
+ DlgText.LoadPaletteWA(dlgpal);
+ DlgTextLine.LoadPaletteWA(dlgpal);
+
+ hUnreg=CreateEvent(NULL, false, false, NULL);
+ bRemoveFromOT = false;
+}
+
+RMDialogChoice::~RMDialogChoice() {
+ CloseHandle(hUnreg);
+}
+
+void RMDialogChoice::Unregister(void) {
+ RMGfxWoodyBuffer::Unregister();
+ assert(!m_nInList);
+ PulseEvent(hUnreg);
+
+ bRemoveFromOT = false;
+}
+
+void RMDialogChoice::Init(void)
+{
+ m_numChoices = 0;
+ m_drawedStrings = NULL;
+ m_ptDrawStrings = NULL;
+ m_curSelection = -1;
+
+ Create(640, 477);
+ SetPriority(140);
+}
+
+
+void RMDialogChoice::Close(void) {
+ if (m_drawedStrings != NULL) {
+ delete[] m_drawedStrings;
+ m_drawedStrings = NULL;
+ }
+
+ if (m_ptDrawStrings != NULL) {
+ delete[] m_ptDrawStrings;
+ m_ptDrawStrings = NULL;
+ }
+
+ Destroy();
+}
+
+void RMDialogChoice::SetNumChoices(int num) {
+ int i;
+
+ m_numChoices = num;
+ m_curAdded = 0;
+
+ // Alloca lo spazio per le stringhe disegnate
+ m_drawedStrings = new RMText[num];
+ m_ptDrawStrings = new RMPoint[num];
+
+ // Le inizializza
+ for (i = 0; i < m_numChoices; i++) {
+ m_drawedStrings[i].SetColor(0, 255, 0);
+ m_drawedStrings[i].SetAlignType(RMText::HLEFTPAR, RMText::VTOP);
+ m_drawedStrings[i].SetMaxLineLength(600);
+ m_drawedStrings[i].SetPriority(10);
+ }
+}
+
+void RMDialogChoice::AddChoice(RMString string) {
+ // Si disegna la stringa
+ assert(m_curAdded < m_numChoices);
+ m_drawedStrings[m_curAdded++].WriteText(string,0);
+}
+
+void RMDialogChoice::Prepare(void) {
+ int i;
+ RMPoint ptPos;
+
+ AddPrim(new RMGfxPrimitive(&DlgText,RMPoint(0,0)));
+ AddPrim(new RMGfxPrimitive(&DlgTextLine,RMPoint(0,155)));
+ AddPrim(new RMGfxPrimitive(&DlgTextLine,RMPoint(0,155+83)));
+ AddPrim(new RMGfxPrimitive(&DlgTextLine,RMPoint(0,155+83+83)));
+ AddPrim(new RMGfxPrimitive(&DlgTextLine,RMPoint(0,155+83+83+83)));
+
+ ptPos.Set(20,90);
+
+ for (i = 0; i < m_numChoices; i++) {
+ AddPrim(new RMGfxPrimitive(&m_drawedStrings[i], ptPos));
+ m_ptDrawStrings[i] = ptPos;
+ ptPos.Offset(0,m_drawedStrings[i].Dimy() + 15);
+ }
+
+ DrawOT();
+ ClearOT();
+
+ m_ptDrawPos.Set(0,480-ptPos.y);
+}
+
+void RMDialogChoice::SetSelected(int pos) {
+ //uint16 * buf = (uint16 *)m_buf;
+ RMGfxBox box;
+ RMRect rc;
+
+ if (pos == m_curSelection)
+ return;
+
+ box.SetPriority(5);
+
+ if (m_curSelection != -1) {
+ box.SetColor(0xCC, 0xCC, 0xFF);
+ rc.TopLeft()=RMPoint(18, m_ptDrawStrings[m_curSelection].y);
+ rc.BottomRight() = rc.TopLeft() + RMPoint(597, m_drawedStrings[m_curSelection].Dimy());
+ AddPrim(new RMGfxPrimitive(&box, rc));
+
+ AddPrim(new RMGfxPrimitive(&m_drawedStrings[m_curSelection], m_ptDrawStrings[m_curSelection]));
+ DrawOT();
+ ClearOT();
+ }
+
+ if (pos != -1) {
+ box.SetColor(100, 100, 100);
+ rc.TopLeft()=RMPoint(18, m_ptDrawStrings[pos].y);
+ rc.BottomRight() = rc.TopLeft()+RMPoint(597, m_drawedStrings[pos].Dimy());
+ AddPrim(new RMGfxPrimitive(&box, rc));
+ AddPrim(new RMGfxPrimitive(&m_drawedStrings[pos], m_ptDrawStrings[pos]));
+ }
+
+ DrawOT();
+ ClearOT();
+
+ m_curSelection = pos;
+}
+
+void RMDialogChoice::Show(RMGfxTargetBuffer *bigBuf) {
+ Prepare();
+ m_bShow = false;
+
+ if (!m_nInList && bigBuf != NULL)
+ bigBuf->AddPrim(new RMGfxPrimitive(this));
+
+ if (0) {
+ m_bShow = true;
+ } else {
+ RMPoint destpt;
+ int deltay;
+ int starttime = _vm->GetTime();
+ int elaps;
+
+ deltay=480 - m_ptDrawPos.y;
+ destpt = m_ptDrawPos;
+ m_ptDrawPos.Set(0, 480);
+
+ if (!m_nInList && bigBuf != NULL)
+ bigBuf->AddPrim(new RMGfxPrimitive(this));
+ m_bShow = true;
+
+ elaps = 0;
+ while (elaps < 700) {
+ MainWaitFrame();
+ MainFreeze();
+ elaps = _vm->GetTime() - starttime;
+ m_ptDrawPos.y = 480 - ((deltay * 100) / 700 * elaps) / 100;
+ MainUnfreeze();
+ }
+
+ m_ptDrawPos.y = destpt.y;
+ }
+}
+
+void RMDialogChoice::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ if (m_bShow == false)
+ return;
+
+ prim->SetDst(m_ptDrawPos);
+ RMGfxSourceBuffer16::Draw(bigBuf, prim);
+}
+
+
+void RMDialogChoice::Hide(void) {
+ if (1) {
+ int deltay;
+ int starttime = _vm->GetTime();
+ int elaps;
+
+ deltay=480 - m_ptDrawPos.y;
+ elaps = 0;
+ while (elaps < 700) {
+ MainWaitFrame();
+ MainFreeze();
+ elaps=_vm->GetTime()-starttime;
+ m_ptDrawPos.y=480-((deltay*100)/700*(700-elaps))/100;
+ MainUnfreeze();
+ }
+ }
+
+ m_bShow = false;
+ bRemoveFromOT = true;
+ WaitForSingleObject(hUnreg, INFINITE);
+}
+
+
+bool RMDialogChoice::RemoveThis(void) {
+ return bRemoveFromOT;
+}
+
+void RMDialogChoice::DoFrame(RMPoint ptMousePos) {
+ int i;
+
+ if (ptMousePos.y > m_ptDrawPos.y) {
+ for (i = 0; i < m_numChoices; i++) {
+ if ((ptMousePos.y >= m_ptDrawPos.y+m_ptDrawStrings[i].y) && (ptMousePos.y < m_ptDrawPos.y+m_ptDrawStrings[i].y+m_drawedStrings[i].Dimy())) {
+ SetSelected(i);
+ break;
+ }
+ }
+
+ if (i == m_numChoices)
+ SetSelected(-1);
+ }
+}
+
+int RMDialogChoice::GetSelection(void) {
+ return m_curSelection;
+}
+
+} // End of namespace Tony
diff --git a/engines/tony/loc.cpp b/engines/tony/loc.cpp
index 83c48bb938..141b993714 100644
--- a/engines/tony/loc.cpp
+++ b/engines/tony/loc.cpp
@@ -45,15 +45,1616 @@
* *
**************************************************************************/
-#include "tony/loc.h"
-#include "tony/utils.h"
-#include "tony/mpal/lzo.h"
+#include "common/scummsys.h"
#include "tony/mpal/mpalutils.h"
+#include "tony/adv.h"
+#include "tony/loc.h"
+#include "tony/tony.h"
namespace Tony {
using namespace ::Tony::MPAL;
+static char rcsid[] = "$Id: $";
+
+extern bool bSkipSfxNoLoop;
+
+
+/****************************************************************************\
+* Metodi di RMPalette
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: friend RMDataStream &operator>>(RMDataStream &ds,
+* RMPalette& pal);
+*
+* Description: Operatore di estrazione di palette da data stream
+*
+* Input: RMDataStream &ds Data stream
+* RMPalette& pal Palette di destinazione
+*
+* Return: Reference allo stream
+*
+\****************************************************************************/
+
+RMDataStream &operator>>(RMDataStream &ds, RMPalette &pal) {
+ ds.Read(pal.m_data,1024);
+ return ds;
+}
+
+/****************************************************************************\
+* Metodi di RMSlot
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: friend RMDataStream &operator>>(RMDataStream &ds,
+* RMSlot& slot)
+*
+* Description: Operatore per estrarre uno slot di un pattern da un data
+* stream
+*
+* Input: RMDataStream &ds Data stream
+* RMSlot& slot Slot di destinazione
+*
+* Return: Reference allo stream
+*
+\****************************************************************************/
+
+RMDataStream &operator>>(RMDataStream &ds, RMPattern::RMSlot &slot) {
+ slot.ReadFromStream(ds);
+ return ds;
+}
+
+
+void RMPattern::RMSlot::ReadFromStream(RMDataStream &ds, bool bLOX) {
+ byte type;
+
+ // Type
+ ds >> type;
+ m_type = (RMPattern::RMSlotType)type;
+
+ // Dati
+ ds >> m_data;
+
+ // Posizione
+ ds >> m_pos;
+
+ // Flag generica
+ ds >> m_flag;
+}
+
+
+/****************************************************************************\
+* Metodi di RMPattern
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: friend RMDataStream &operator>>(RMDataStream &ds,
+* RMPattern& pat)
+*
+* Description: Operatore per estrarre un pattern da un data stream
+*
+* Input: RMDataStream &ds Data stream
+* RMPattern& pat Pattern di destinazione
+*
+* Return: Reference allo stream
+*
+\****************************************************************************/
+
+RMDataStream &operator>>(RMDataStream &ds, RMPattern &pat) {
+ pat.ReadFromStream(ds);
+ return ds;
+}
+
+void RMPattern::ReadFromStream(RMDataStream &ds, bool bLOX) {
+ int i;
+
+ // Nome del pattern
+ if (!bLOX)
+ ds >> m_name;
+
+ // Velocita'
+ ds >> m_speed;
+
+ // Posizione
+ ds >> m_pos;
+
+ // Flag di loop del pattern
+ ds >> m_bLoop;
+
+ // Numero di slot
+ ds >> m_nSlots;
+
+ // Creazione e lettura degli slot
+ m_slots = new RMSlot[m_nSlots];
+
+ for (i = 0; i < m_nSlots && !ds.IsError(); i++) {
+ if (bLOX)
+ m_slots[i].ReadFromStream(ds, true);
+ else
+ m_slots[i].ReadFromStream(ds, false);
+ }
+}
+
+void RMPattern::UpdateCoord(void) {
+ m_curPos = m_pos + m_slots[m_nCurSlot].Pos();
+}
+
+void RMPattern::StopSfx(RMSfx *sfx) {
+ for (int i = 0; i < m_nSlots; i++) {
+ if (m_slots[i].m_type == SOUND) {
+ if (sfx[m_slots[i].m_data].m_name[0] == '_')
+ sfx[m_slots[i].m_data].Stop();
+ else if (bSkipSfxNoLoop)
+ sfx[m_slots[i].m_data].Stop();
+ }
+ }
+}
+
+int RMPattern::Init(RMSfx *sfx, bool bPlayP0, byte *bFlag) {
+ int i;
+
+ // Prendiamo il tempo corrente
+ m_nStartTime = _vm->GetTime();
+ m_nCurSlot = 0;
+
+ // Cerca il primo frame nel pattern
+ i = 0;
+ while (m_slots[i].m_type != SPRITE) {
+ assert(i + 1 < m_nSlots);
+ i++;
+ }
+
+ m_nCurSlot = i;
+ m_nCurSprite = m_slots[i].m_data;
+ if (bFlag)
+ *bFlag = m_slots[i].m_flag;
+
+ // Calcola le coordinate correnti
+ UpdateCoord();
+
+ // Controlla per il sonoro:
+ // Se sta alla slot 0, lo playa
+ // Se speed = 0, deve suonare solo se va in loop '_', oppure se specificato dal parametro
+ // Se speed! = 0, suona solo quelli in loop
+ for (i = 0;i < m_nSlots; i++) {
+ if (m_slots[i].m_type == SOUND) {
+ if (i == 0)
+ {
+ if (sfx[m_slots[i].m_data].m_name[0]=='_')
+ {
+ sfx[m_slots[i].m_data].SetVolume(m_slots[i].Pos().x);
+ sfx[m_slots[i].m_data].Play(true);
+ }
+ else
+ {
+ sfx[m_slots[i].m_data].SetVolume(m_slots[i].Pos().x);
+ sfx[m_slots[i].m_data].Play();
+ }
+ }
+ else if (m_speed == 0) {
+ if (bPlayP0) {
+ sfx[m_slots[i].m_data].SetVolume(m_slots[i].Pos().x);
+ sfx[m_slots[i].m_data].Play();
+ } else if (sfx[m_slots[i].m_data].m_name[0] == '_') {
+ sfx[m_slots[i].m_data].SetVolume(m_slots[i].Pos().x);
+ sfx[m_slots[i].m_data].Play(true);
+ }
+ } else {
+ if (m_bLoop && sfx[m_slots[i].m_data].m_name[0] == '_') {
+ sfx[m_slots[i].m_data].SetVolume(m_slots[i].Pos().x);
+ sfx[m_slots[i].m_data].Play(true);
+ }
+ }
+ }
+ }
+
+ return m_nCurSprite;
+}
+
+int RMPattern::Update(HANDLE hEndPattern, byte &bFlag, RMSfx *sfx) {
+ int CurTime = _vm->GetTime();
+
+ // Se la speed e' 0, il pattern non avanza mai
+ if (m_speed == 0) {
+ PulseEvent(hEndPattern);
+ bFlag=m_slots[m_nCurSlot].m_flag;
+ return m_nCurSprite;
+ }
+
+ // E' arrivato il momento di cambiare slot?
+ while (m_nStartTime + m_speed <= (uint32)CurTime) {
+ m_nStartTime += m_speed;
+ if (m_slots[m_nCurSlot].m_type == SPRITE)
+ m_nCurSlot++;
+ if (m_nCurSlot == m_nSlots) {
+ m_nCurSlot = 0;
+ bFlag = m_slots[m_nCurSlot].m_flag;
+ PulseEvent(hEndPattern);
+
+ // @@@ Se non c'e' loop avverte che il pattern e' finito
+ // Se non c'e' loop rimane sull'ultimo frame
+ if (!m_bLoop) {
+ m_nCurSlot = m_nSlots - 1;
+ bFlag = m_slots[m_nCurSlot].m_flag;
+ return m_nCurSprite;
+ }
+ }
+
+ for (;;) {
+ switch (m_slots[m_nCurSlot].m_type) {
+ case SPRITE:
+ // Legge il prossimo sprite
+ m_nCurSprite = m_slots[m_nCurSlot].m_data;
+
+ // Aggiorna le coordinate babbo+figlio
+ UpdateCoord();
+ break;
+
+ case SOUND:
+ if (sfx != NULL) {
+ sfx[m_slots[m_nCurSlot].m_data].SetVolume(m_slots[m_nCurSlot].Pos().x);
+
+ if (sfx[m_slots[m_nCurSlot].m_data].m_name[0] != '_')
+ sfx[m_slots[m_nCurSlot].m_data].Play(false);
+ else
+ sfx[m_slots[m_nCurSlot].m_data].Play(true);
+ }
+ break;
+
+ case COMMAND:
+ assert(0);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ if (m_slots[m_nCurSlot].m_type == SPRITE)
+ break;
+ m_nCurSlot++;
+ }
+ }
+
+ // Ritorna lo sprite corrente
+ bFlag=m_slots[m_nCurSlot].m_flag;
+ return m_nCurSprite;
+}
+
+RMPattern::RMPattern() {
+ m_slots = NULL;
+}
+
+RMPattern::~RMPattern() {
+ if (m_slots != NULL)
+ {
+ delete[] m_slots;
+ m_slots = NULL;
+ }
+}
+
+
+
+
+/****************************************************************************\
+* Metodi di RMSprite
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: friend RMDataStream &operator>>(RMDataStream &ds,
+* RMSprite& sprite)
+*
+* Description: Operatore per estrarre uno sprite da un data stream
+*
+* Input: RMDataStream &ds Data stream
+* RMItem &item Sprite di destinazione
+*
+* Return: Reference allo stream
+*
+\****************************************************************************/
+
+RMDataStream &operator>>(RMDataStream &ds, RMSprite &sprite) {
+ sprite.ReadFromStream(ds);
+ return ds;
+}
+
+void RMSprite::Init(RMGfxSourceBuffer *buf) {
+ m_buf = buf;
+}
+
+void RMSprite::LOXGetSizeFromStream(RMDataStream &ds, int *dimx, int *dimy) {
+ int pos = ds.Pos();
+
+ ds >> *dimx >> *dimy;
+
+ ds.Seek(pos, ds.START);
+}
+
+void RMSprite::GetSizeFromStream(RMDataStream &ds, int *dimx, int *dimy) {
+ int pos = ds.Pos();
+
+ ds >> m_name;
+ ds >> *dimx >> *dimy;
+
+ ds.Seek(pos, ds.START);
+}
+
+void RMSprite::ReadFromStream(RMDataStream &ds, bool bLOX) {
+ int dimx,dimy;
+
+ // Nome dello sprite
+ if (!bLOX)
+ ds >> m_name;
+
+ // Dimensioni
+ ds >> dimx >> dimy;
+
+ // Bouding box
+ ds >> m_rcBox;
+
+ // Spazio inutilizzato
+ if (!bLOX)
+ ds+=32;
+
+ // Crezione del buffer e lettura
+ m_buf->Init(ds, dimx,dimy);
+}
+
+void RMSprite::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ m_buf->Draw(bigBuf, prim);
+}
+
+void RMSprite::SetPalette(byte *buf) {
+ ((RMGfxSourceBufferPal*)m_buf)->LoadPalette(buf);
+}
+
+RMSprite::RMSprite() {
+ m_buf= NULL;
+}
+
+RMSprite::~RMSprite() {
+ if (m_buf) {
+ delete m_buf;
+ m_buf = NULL;
+ }
+}
+
+
+/****************************************************************************\
+* Metodi di RMSfx
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: friend RMDataStream &operator>>(RMDataStream &ds,
+* RMSfx &sfx)
+*
+* Description: Operatore per estrarre uno sfx da un data stream
+*
+* Input: RMDataStream &ds Data stream
+* RMSfx &sfx Sfx di destinazione
+*
+* Return: Reference allo stream
+*
+\****************************************************************************/
+
+RMDataStream &operator>>(RMDataStream &ds, RMSfx &sfx) {
+ sfx.ReadFromStream(ds);
+ return ds;
+}
+
+void RMSfx::ReadFromStream(RMDataStream &ds, bool bLOX) {
+ char id[4];
+ int size;
+ byte *raw;
+
+ // Nome dello sfx
+ ds >> m_name;
+
+ ds >> size;
+
+ // Carica l'effetto sonoro dal buffer
+ ds.Read(id,4);
+
+ // Controlla che sia un riff
+ assert(id[0] == 'R' && id[1] == 'I' && id[2] == 'F' && id[3] == 'F');
+
+ // Legge la dimensione
+ ds >> size;
+
+ // Carica il wav
+ raw = new byte[size];
+ ds.Read(raw, size);
+
+ // Crea l'effetto sonoro
+ m_fx = _vm->CreateSFX(raw);
+ m_fx->SetLoop(false);
+
+ // Cancella il buffer che non serve pi a nessuno
+ delete[] raw;
+}
+
+RMSfx::RMSfx() {
+ m_fx = NULL;
+ m_bPlayingLoop = false;
+}
+
+RMSfx::~RMSfx() {
+ if (m_fx) {
+ m_fx->Release();
+ m_fx = NULL;
+ }
+}
+
+void RMSfx::Play(bool bLoop) {
+ if (m_fx && !m_bPlayingLoop) {
+ m_fx->SetLoop(bLoop);
+ m_fx->Play();
+
+ if (bLoop)
+ m_bPlayingLoop=true;
+ }
+}
+
+void RMSfx::SetVolume(int vol) {
+ if (m_fx) {
+ m_fx->SetVolume(vol);
+ }
+}
+
+void RMSfx::Pause(bool bPause) {
+ if (m_fx) {
+ m_fx->Pause(bPause);
+ }
+}
+
+void RMSfx::Stop(void) {
+ if (m_fx) {
+ m_fx->Stop();
+ m_bPlayingLoop = false;
+ }
+}
+
+
+
+/****************************************************************************\
+* Metodi di RMItem
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: friend RMDataStream &operator>>(RMDataStream &ds,
+* RMItem &item)
+*
+* Description: Operatore per estrarre un item da un data stream
+*
+* Input: RMDataStream &ds Data stream
+* RMItem &item Item di destinazione
+*
+* Return: Reference allo stream
+*
+\****************************************************************************/
+
+RMDataStream &operator>>(RMDataStream &ds, RMItem &item) {
+ item.ReadFromStream(ds);
+ return ds;
+}
+
+
+RMGfxSourceBuffer *RMItem::NewItemSpriteBuffer(int dimx, int dimy, bool bPreRLE) {
+ if (m_cm == CM_256) {
+ RMGfxSourceBuffer8RLE *spr;
+
+ if (m_FX == 2) { // AB
+ spr = new RMGfxSourceBuffer8RLEWordAB;
+ } else if (m_FX == 1) { // OMBRA+AA
+ if (dimx == -1 || dimx > 255)
+ spr = new RMGfxSourceBuffer8RLEWordAA;
+ else
+ spr = new RMGfxSourceBuffer8RLEByteAA;
+
+ spr->SetAlphaBlendColor(m_FXparm);
+ if (bPreRLE)
+ spr->SetAlreadyCompressed();
+ } else {
+ if (dimx == -1 || dimx > 255)
+ spr = new RMGfxSourceBuffer8RLEWord;
+ else
+ spr = new RMGfxSourceBuffer8RLEByte;
+
+ if (bPreRLE)
+ spr->SetAlreadyCompressed();
+ }
+
+ return spr;
+ } else
+ return new RMGfxSourceBuffer16;
+}
+
+bool RMItem::IsIn(RMPoint pt, int *size) {
+ RMRect rc;
+
+ if (!m_bIsActive)
+ return false;
+
+ // Cerca il rettangolo giusto da usare, che quello dello sprite se ce l'ha, altrimenti
+ // quello generico dell'oggeto
+ if (m_nCurPattern != 0 && !m_sprites[m_nCurSprite].m_rcBox.IsEmpty())
+ rc=m_sprites[m_nCurSprite].m_rcBox + CalculatePos();
+ else if (!m_rcBox.IsEmpty())
+ rc = m_rcBox;
+ // Se non ha box, esce subito
+ else
+ return false;
+
+ if (size != NULL)
+ *size = rc.Size();
+
+ return rc.PtInRect(pt + m_curScroll);
+}
+
+
+void RMItem::ReadFromStream(RMDataStream &ds, bool bLOX) {
+ int i, dimx, dimy;
+ byte cm;
+
+ // Codice mpal
+ ds >> m_mpalCode;
+
+ // Nome dell'oggetto
+ ds >> m_name;
+
+ // Z (signed)
+ ds >> m_z;
+
+ // Posizione nonno
+ ds >> m_pos;
+
+ // Hotspot
+ ds >> m_hot;
+
+ // Bounding box
+ ds >> m_rcBox;
+
+ // Numero sprite, effetti sonori e pattern
+ ds >> m_nSprites >> m_nSfx >> m_nPatterns;
+
+ // Color mode
+ ds >> cm; m_cm=(RMColorMode)cm;
+
+ // Flag di presenza della palette differnziata
+ ds >> m_bPal;
+
+ if (m_cm == CM_256) {
+ // Se c'e' la palette, leggiamola
+ if (m_bPal)
+ ds >> m_pal;
+ }
+
+ // Dati MPAL
+ if (!bLOX)
+ ds += 20;
+
+ ds >> m_FX;
+ ds >> m_FXparm;
+
+ if (!bLOX)
+ ds += 106;
+
+ // Creazione delle classi
+ if (m_nSprites > 0)
+ m_sprites = new RMSprite[m_nSprites];
+ if (m_nSfx > 0)
+ m_sfx = new RMSfx[m_nSfx];
+ m_patterns = new RMPattern[m_nPatterns+1];
+
+ // Lettura delle classi
+ if (!ds.IsError())
+ for (i = 0; i < m_nSprites && !ds.IsError(); i++) {
+ // Carica lo sprite
+ if (bLOX) {
+ m_sprites[i].LOXGetSizeFromStream(ds, &dimx, &dimy);
+ m_sprites[i].Init(NewItemSpriteBuffer(dimx, dimy, true));
+ m_sprites[i].ReadFromStream(ds, true);
+ } else {
+ m_sprites[i].GetSizeFromStream(ds, &dimx, &dimy);
+ m_sprites[i].Init(NewItemSpriteBuffer(dimx, dimy, false));
+ m_sprites[i].ReadFromStream(ds, false);
+ }
+
+ if (m_cm == CM_256 && m_bPal)
+ m_sprites[i].SetPalette(m_pal.m_data);
+ }
+
+ if (!ds.IsError())
+ for (i = 0;i < m_nSfx && !ds.IsError(); i++) {
+ if (bLOX)
+ m_sfx[i].ReadFromStream(ds, true);
+ else
+ m_sfx[i].ReadFromStream(ds, false);
+ }
+
+ // Leggiamo i pattern a partire dal pattern 1
+ if (!ds.IsError())
+ for (i = 1;i <= m_nPatterns && !ds.IsError(); i++) {
+ if (bLOX)
+ m_patterns[i].ReadFromStream(ds, true);
+ else
+ m_patterns[i].ReadFromStream(ds, false);
+ }
+
+ // Inizializza il curpattern
+ if (m_bInitCurPattern)
+ SetPattern(mpalQueryItemPattern(m_mpalCode));
+
+ // Inizializza lo stato di attivazione
+ m_bIsActive=mpalQueryItemIsActive(m_mpalCode);
+}
+
+
+RMGfxPrimitive *RMItem::NewItemPrimitive() {
+ return new RMGfxPrimitive(this);
+}
+
+void RMItem::SetScrollPosition(RMPoint scroll) {
+ m_curScroll = scroll;
+}
+
+bool RMItem::DoFrame(RMGfxTargetBuffer *bigBuf, bool bAddToList) {
+ int oldSprite = m_nCurSprite;
+
+ // Pattern 0 = Non disegnare nulla!
+ if (m_nCurPattern == 0)
+ return false;
+
+ // Facciamo un update del pattern, che ci ritorna anche il frame corrente
+ if (m_nCurPattern != 0)
+ m_nCurSprite=m_patterns[m_nCurPattern].Update(m_hEndPattern,m_bCurFlag, m_sfx);
+
+ // Se la funzione ha ritornato -1, vuol dire che il pattern e' finito
+ if (m_nCurSprite == -1) {
+ // Mettiamo il pattern 0, e usciamo. La classe si auto-deregistrera' della OT list
+ m_nCurPattern = 0;
+ return false;
+ }
+
+ // Se non siamo in OT list, mettiamoci
+ if (!m_nInList && bAddToList)
+ bigBuf->AddPrim(NewItemPrimitive());
+
+ return oldSprite != m_nCurSprite;
+}
+
+RMPoint RMItem::CalculatePos(void) {
+ return m_pos + m_patterns[m_nCurPattern].Pos();
+}
+
+void RMItem::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ // Se CurSprite == -1, allora e' finito il pattern
+ if (m_nCurSprite == -1)
+ return;
+
+ // Settiamo la flag
+ prim->SetFlag(m_bCurFlag);
+
+ // Offset inverso per lo scrolling
+ prim->Dst().Offset(-m_curScroll);
+
+ // Dobbiamo sparaflashare le coordinate dell'item dentro la primitiva.
+ // Si calcola nonno+(babbo+figlio)
+ prim->Dst().Offset(CalculatePos());
+
+ // No stretching, please
+ prim->SetStrecth(false);
+
+ // Ora la passiamo alla routine di drawing generica per surface
+ m_sprites[m_nCurSprite].Draw(bigBuf, prim);
+}
+
+
+bool RMItem::RemoveThis() {
+ // Rimuove dalla OT list se il frame corrente e' -1 (pattern finito)
+ return (m_nCurSprite == -1);
+}
+
+
+void RMItem::SetStatus(int nStatus) {
+ m_bIsActive = (nStatus>0);
+}
+
+void RMItem::SetPattern(int nPattern, bool bPlayP0) {
+ int i;
+
+ assert(nPattern >= 0 && nPattern <= m_nPatterns);
+
+ if (m_sfx)
+ if (m_nCurPattern>0)
+ m_patterns[m_nCurPattern].StopSfx(m_sfx);
+
+ // Si ricorda il pattern corrente
+ m_nCurPattern = nPattern;
+
+ // Inizia il pattern per cominciare l'animazione
+ if (m_nCurPattern != 0)
+ m_nCurSprite = m_patterns[m_nCurPattern].Init(m_sfx, bPlayP0, &m_bCurFlag);
+ else {
+ m_nCurSprite = -1;
+
+ // Cerca l'effetto sonoro per il pattern 0
+ if (bPlayP0)
+ for (i = 0;i < m_nSfx; i++)
+ if (strcmp(m_sfx[i].m_name, "p0") == 0)
+ m_sfx[i].Play();
+ }
+}
+
+
+bool RMItem::GetName(RMString& name)
+{
+ char buf[256];
+
+ mpalQueryItemName(m_mpalCode, buf);
+ name = buf;
+ if (buf[0] == '\0')
+ return false;
+ return true;
+}
+
+
+void RMItem::Unload(void) {
+ if (m_patterns != NULL)
+ {
+ delete[] m_patterns;
+ m_patterns = NULL;
+ }
+
+ if (m_sprites != NULL) {
+ delete[] m_sprites;
+ m_sprites = NULL;
+ }
+
+ if (m_sfx != NULL) {
+ delete[] m_sfx;
+ m_sfx = NULL;
+ }
+}
+
+RMItem::RMItem() {
+ m_bCurFlag = 0;
+ m_patterns = NULL;
+ m_sprites = NULL;
+ m_sfx= NULL;
+ m_curScroll.Set(0, 0);
+ m_bInitCurPattern=true;
+ m_nCurPattern = 0;
+
+ m_hEndPattern = CreateEvent(NULL, false, false, NULL);
+}
+
+RMItem::~RMItem() {
+ Unload();
+ CloseHandle(m_hEndPattern);
+}
+
+void RMItem::WaitForEndPattern(HANDLE hCustomSkip) {
+ if (m_nCurPattern != 0) {
+ if (hCustomSkip == INVALID_HANDLE_VALUE)
+ WaitForSingleObject(m_hEndPattern,INFINITE);
+ else {
+ HANDLE h[2];
+
+ h[0] = hCustomSkip;
+ h[1] = m_hEndPattern;
+ WaitForMultipleObjects(2, h, false, INFINITE);
+ }
+ }
+}
+
+void RMItem::ChangeHotspot(RMPoint pt) {
+ m_hot = pt;
+}
+
+void RMItem::PlaySfx(int nSfx) {
+ if (nSfx < m_nSfx)
+ m_sfx[nSfx].Play();
+}
+
+void RMItem::PauseSound(bool bPause) {
+ int i;
+
+ for (i = 0; i < m_nSfx; i++)
+ m_sfx[i].Pause(bPause);
+}
+
+
+
+/****************************************************************************\
+* Metodi di RMWipe
+\****************************************************************************/
+
+
+RMWipe::RMWipe() {
+ m_hUnregistered=CreateEvent(NULL,false,false,NULL);
+ m_hEndOfFade=CreateEvent(NULL,false,false,NULL);
+}
+
+RMWipe::~RMWipe() {
+ CloseHandle(m_hUnregistered);
+ CloseHandle(m_hEndOfFade);
+}
+
+int RMWipe::Priority(void) {
+ return 200;
+}
+
+void RMWipe::Unregister(void) {
+ RMGfxTask::Unregister();
+ assert(m_nInList == 0);
+ SetEvent(m_hUnregistered);
+}
+
+bool RMWipe::RemoveThis(void) {
+ return m_bUnregister;
+}
+
+void RMWipe::WaitForFadeEnd(void) {
+ WaitForSingleObject(m_hEndOfFade, INFINITE);
+ m_bEndFade = true;
+ m_bFading = false;
+ MainWaitFrame();
+ MainWaitFrame();
+}
+
+void RMWipe::CloseFade(void) {
+// m_bUnregister=true;
+// WaitForSingleObject(m_hUnregistered,INFINITE);
+ m_wip0r.Unload();
+}
+
+void RMWipe::InitFade(int type) {
+ // Attiva il fade
+ m_bUnregister = false;
+ m_bEndFade = false;
+
+ m_nFadeStep = 0;
+
+ m_bMustRegister = true;
+
+ RMRes res(RES_W_CERCHIO);
+ RMDataStream ds;
+
+ ds.OpenBuffer(res);
+ ds >> m_wip0r;
+ ds.Close();
+
+ m_wip0r.SetPattern(1);
+
+ m_bFading = true;
+}
+
+void RMWipe::DoFrame(RMGfxTargetBuffer &bigBuf) {
+ if (m_bMustRegister) {
+ bigBuf.AddPrim(new RMGfxPrimitive(this));
+ m_bMustRegister = false;
+ }
+
+ if (m_bFading)
+ {
+ m_wip0r.DoFrame(&bigBuf, false);
+
+ m_nFadeStep++;
+
+ if (m_nFadeStep == 10) {
+ SetEvent(m_hEndOfFade);
+ }
+ }
+}
+
+void RMWipe::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ if (m_bFading) {
+ m_wip0r.Draw(bigBuf, prim);
+ }
+
+ if (m_bEndFade)
+ Common::fill((byte *)bigBuf, (byte *)bigBuf + bigBuf.Dimx() * bigBuf.Dimy() * 2, 0x0);
+}
+
+
+
+/****************************************************************************\
+* Metodi di RMCharacter
+\****************************************************************************/
+
+/***************************************************************************/
+/* Cerca il percorso minimo tra due nodi del grafo di connessione dei BOX */
+/* Restituisce il percorso lungo pathlenght nel vettore path[] */
+/***************************************************************************/
+
+short RMCharacter::FindPath(short source, short destination) {
+ // FIXME: Refactor
+ static RMBox BOX[MAXBOXES]; // Matrice di Adjacenza
+ static short COSTO[MAXBOXES]; // Costi per Nodo
+ static short VALIDO[MAXBOXES]; // 0:non valido 1:valido 2:saturo
+ static short NEXT[MAXBOXES]; // Prossimo Nodo
+ short i, j, k, costominimo, fine, errore = 0;
+ RMBoxLoc *cur;
+
+ g_system->lockMutex(csMove);
+
+ if (source == -1 || destination == -1) {
+ g_system->unlockMutex(csMove);
+ return 0;
+ }
+
+ // Si fa dare i box
+ cur = theBoxes->GetBoxes(curLocation);
+
+ // Effettua una copia di riserva per lavorarci
+ for (i = 0; i < cur->numbbox; i++)
+ memcpy(&BOX[i], &cur->boxes[i], sizeof(RMBox));
+
+ // Invalida tutti i Nodi
+ for (i = 0; i < cur->numbbox; i++)
+ VALIDO[i] = 0;
+
+ // Prepara sorgente e variabili globali alla procedura
+ COSTO[source] = 0;
+ VALIDO[source] = 1;
+ fine = 0;
+
+ // Ricerca del percorso minimo
+ while(!fine) {
+ costominimo = 32000; // risetta il costo minimo
+ errore = 1; // errore possibile
+
+ // 1 ciclo : ricerca di possibili nuovi nodi
+ for (i = 0; i < cur->numbbox; i++)
+ if (VALIDO[i] == 1) {
+ errore = 0; // errore sfatato
+ j = 0;
+ while (((BOX[i].adj[j]) != 1) && (j < cur->numbbox))
+ j++;
+
+ if (j >= cur->numbbox)
+ VALIDO[i] = 2; // nodo saturo?
+ else {
+ NEXT[i] = j;
+ if (COSTO[i] + 1 < costominimo)
+ costominimo = COSTO[i] + 1;
+ }
+ }
+
+ if (errore)
+ fine = 1; // tutti i nodi saturi
+
+ // 2 ciclo : aggiunta nuovi nodi trovati , saturazione nodi vecchi
+ for (i = 0; i < cur->numbbox; i++)
+ if ((VALIDO[i] == 1) && ((COSTO[i] + 1) == costominimo)) {
+ BOX[i].adj[NEXT[i]] = 2;
+ COSTO[NEXT[i]] = costominimo;
+ VALIDO[NEXT[i]] = 1;
+ for (j = 0; j < cur->numbbox; j++)
+ if (BOX[j].adj[NEXT[i]] == 1)
+ BOX[j].adj[NEXT[i]] = 0;
+
+ if (NEXT[i] == destination)
+ fine = 1;
+ }
+ }
+
+ // Estrazione del percorso dalla matrice di adiacenza modificata
+ if (!errore) {
+ pathlenght = COSTO[destination];
+ k = pathlenght;
+ path[k] = destination;
+
+ while (path[k] != source) {
+ i = 0;
+ while (BOX[i].adj[path[k]] != 2)
+ i++;
+ k--;
+ path[k] = i;
+ }
+
+ pathlenght++;
+ }
+
+ g_system->unlockMutex(csMove);
+
+ return !errore;
+}
+
+
+void RMCharacter::GoTo(RMPoint destcoord, bool bReversed) {
+ if (m_pos == destcoord) {
+ if (minpath == 0) {
+ Stop();
+ PulseEvent(hEndOfPath);
+ return;
+ }
+ }
+
+ status = WALK;
+ linestart = m_pos;
+ lineend = destcoord;
+ dx = linestart.x - lineend.x;
+ dy = linestart.y - lineend.y;
+ fx = dx;
+ fy = dy;
+ dx = ABS(dx);
+ dy = ABS(dy);
+ walkspeed = curSpeed;
+ walkcount = 0;
+
+ if (bReversed) {
+ while (0) ;
+ }
+
+ int nPatt = GetCurPattern();
+
+ if (dx > dy) {
+ slope = fy / fx;
+ if (lineend.x < linestart.x)
+ walkspeed = -walkspeed;
+ walkstatus = 1;
+
+ // Cambia il proprio pattern per la nuova direzione
+ bNeedToStop = true;
+ if ((walkspeed < 0 && !bReversed) || (walkspeed >= 0 && bReversed)) {
+ if (nPatt != PAT_WALKLEFT)
+ SetPattern(PAT_WALKLEFT);
+ } else {
+ if (nPatt != PAT_WALKRIGHT)
+ SetPattern(PAT_WALKRIGHT);
+ }
+ } else {
+ slope = fx / fy;
+ if (lineend.y < linestart.y)
+ walkspeed = -walkspeed;
+ walkstatus = 0;
+
+ bNeedToStop=true;
+ if ((walkspeed < 0 && !bReversed) || (walkspeed >= 0 && bReversed)) {
+ if (nPatt != PAT_WALKUP)
+ SetPattern(PAT_WALKUP);
+ } else {
+ if (nPatt != PAT_WALKDOWN)
+ SetPattern(PAT_WALKDOWN);
+ }
+ }
+
+ olddx = dx;
+ olddy = dy;
+
+ // ResetEvent(hTonyEndMovement); @@@
+}
+
+
+RMPoint RMCharacter::Searching(char UP, char DOWN, char RIGHT, char LEFT, RMPoint punto) {
+ short passi, minimo;
+ RMPoint nuovo, trovato;
+ minimo = 32000;
+
+ if (UP) {
+ nuovo = punto;
+ passi = 0;
+ while((InWhichBox(nuovo) == -1) && (nuovo.y >= 0)) { nuovo.y--; passi++; }
+ if ((InWhichBox(nuovo) != -1) && (passi < minimo)&&
+ FindPath(InWhichBox(m_pos), InWhichBox(nuovo))) {
+ minimo = passi;
+ nuovo.y--; // to avoid error?
+ trovato = nuovo;
+ }
+ }
+
+ if (DOWN) {
+ nuovo = punto;
+ passi = 0;
+ while ((InWhichBox(nuovo) == -1) && (nuovo.y < 480)) { nuovo.y++; passi++; }
+ if ((InWhichBox(nuovo) != -1) && (passi < minimo) &&
+ FindPath(InWhichBox(m_pos), InWhichBox(nuovo))) {
+ minimo = passi;
+ nuovo.y++; // to avoid error?
+ trovato = nuovo;
+ }
+ }
+
+ if (RIGHT) {
+ nuovo = punto;
+ passi = 0;
+ while ((InWhichBox(nuovo) == -1) && (nuovo.x < 640)) { nuovo.x++; passi++; }
+ if ((InWhichBox(nuovo) != -1) && (passi < minimo) &&
+ FindPath(InWhichBox(m_pos), InWhichBox(nuovo))) {
+ minimo = passi;
+ nuovo.x++; // to avoid error?
+ trovato = nuovo;
+ }
+ }
+
+ if (LEFT) {
+ nuovo = punto;
+ passi = 0;
+ while ((InWhichBox(nuovo) == -1) && (nuovo.x >= 0)) { nuovo.x--; passi++; }
+ if ((InWhichBox(nuovo) != -1) && (passi < minimo) &&
+ FindPath(InWhichBox(m_pos), InWhichBox(nuovo))) {
+ minimo = passi;
+ nuovo.x--; // to avoid error?
+ trovato = nuovo;
+ }
+ }
+
+ if (minimo == 32000) trovato = punto;
+ return trovato;
+}
+
+
+RMPoint RMCharacter::NearestPoint(RMPoint punto) {
+/*
+ RMPoint tofind;
+ signed short difx,dify;
+
+ difx = m_pos.x-punto.x;
+ dify = m_pos.y-punto.y;
+
+ if ((difx>0) && (dify>0)) tofind=Searching(0,1,1,0,punto);
+ if ((difx>0) && (dify<0)) tofind=Searching(1,0,1,0,punto);
+ if ((difx<0) && (dify>0)) tofind=Searching(0,1,0,1,punto);
+ if ((difx<0) && (dify<0)) tofind=Searching(1,0,0,1,punto);
+
+ // potrebbero essere tolti? Pensaci @@@@
+ if ((difx= = 0) && (dify>0)) tofind=Searching(0,1,1,1,punto);
+ if ((difx= = 0) && (dify<0)) tofind=Searching(1,0,1,1,punto);
+ if ((dify= = 0) && (difx>0)) tofind=Searching(1,1,1,0,punto);
+ if ((dify= = 0) && (difx<0)) tofind=Searching(1,1,0,1,punto);
+
+ if ((dify= = 0) && (difx= = 0)) tofind=punto;
+
+ return tofind;
+*/
+ return Searching(1, 1, 1, 1, punto);
+}
+
+
+short RMCharacter::ScanLine(RMPoint punto) {
+ int Ldx, Ldy, Lcount;
+ float Lfx, Lfy, Lslope;
+ RMPoint Lstart, Lend, Lscan;
+ signed char Lspeed, Lstatus;
+
+ Lstart = m_pos;
+ Lend = punto;
+ Ldx = Lstart.x-Lend.x;
+ Ldy = Lstart.y-Lend.y;
+ Lfx = Ldx;
+ Lfy = Ldy;
+ Ldx = ABS(Ldx);
+ Ldy = ABS(Ldy);
+ Lspeed = 1;
+ Lcount = 0;
+
+ if (Ldx > Ldy) {
+ Lslope = Lfy / Lfx;
+ if (Lend.x < Lstart.x) Lspeed = -Lspeed;
+ Lstatus = 1;
+ } else {
+ Lslope = Lfx / Lfy;
+ if (Lend.y < Lstart.y) Lspeed =- Lspeed;
+ Lstatus = 0;
+ }
+
+ Lscan = Lstart; // Inizio scansione
+ while (InWhichBox(Lscan) != -1) {
+ Lcount++;
+ if (Lstatus) {
+ Ldx = Lspeed * Lcount;
+ Ldy = Lslope * Ldx;
+ } else {
+ Ldy = Lspeed * Lcount;
+ Ldx = Lslope * Ldy;
+ }
+
+ Lscan.x = Lstart.x + Ldx;
+ Lscan.y = Lstart.y + Ldy;
+
+ if ((ABS(Lscan.x - Lend.x) <= 1) && (ABS(Lscan.y - Lend.y) <= 1)) return 1;
+ }
+
+ return 0;
+}
+
+// Calcola intersezioni tra la traiettoria rettilinea ed il pi vicino BBOX
+RMPoint RMCharacter::InvScanLine(RMPoint punto) {
+ int Ldx, Ldy, Lcount;
+ float Lfx, Lfy, Lslope;
+ RMPoint Lstart, Lend, Lscan;
+ signed char Lspeed, Lstatus, Lbox = -1;
+
+ Lstart = punto; // Exchange!
+ Lend = m_pos; // :-)
+ Ldx = Lstart.x - Lend.x;
+ Ldy = Lstart.y - Lend.y;
+ Lfx = Ldx;
+ Lfy = Ldy;
+ Ldx = ABS(Ldx);
+ Ldy = ABS(Ldy);
+ Lspeed = 1;
+ Lcount = 0;
+
+ if (Ldx > Ldy) {
+ Lslope = Lfy / Lfx;
+ if (Lend.x < Lstart.x) Lspeed = -Lspeed;
+ Lstatus=1;
+ } else {
+ Lslope = Lfx / Lfy;
+ if (Lend.y < Lstart.y) Lspeed = -Lspeed;
+ Lstatus = 0;
+ }
+ Lscan = Lstart;
+
+ for (;;) {
+ if (InWhichBox(Lscan) != -1) {
+ if (InWhichBox(Lscan) != Lbox) {
+ if (InWhichBox(m_pos) == InWhichBox(Lscan) || FindPath(InWhichBox(m_pos),InWhichBox(Lscan)))
+ return Lscan;
+ else
+ Lbox = InWhichBox(Lscan);
+ }
+ }
+
+ Lcount++;
+ if (Lstatus) {
+ Ldx = Lspeed * Lcount;
+ Ldy = Lslope * Ldx;
+ } else {
+ Ldy = Lspeed * Lcount;
+ Ldx = Lslope * Ldy;
+ }
+ Lscan.x = Lstart.x + Ldx;
+ Lscan.y = Lstart.y + Ldy;
+ }
+}
+
+
+/***************************************************************************/
+/* Ritorna la coordinata dell'HotSpot di uscita pi vicino al giocatore */
+/***************************************************************************/
+
+RMPoint RMCharacter::NearestHotSpot(int sourcebox, int destbox) {
+ RMPoint puntocaldo;
+ short cc;
+ int x, y, distanzaminima;
+ distanzaminima = 10000000;
+ RMBoxLoc *cur = theBoxes->GetBoxes(curLocation);
+
+ for (cc = 0; cc < cur->boxes[sourcebox].numhotspot; cc++)
+ if ((cur->boxes[sourcebox].hotspot[cc].destination) == destbox) {
+ x = ABS(cur->boxes[sourcebox].hotspot[cc].hotx - m_pos.x);
+ y = ABS(cur->boxes[sourcebox].hotspot[cc].hoty - m_pos.y);
+
+ if ((x * x + y * y) < distanzaminima) {
+ distanzaminima = x * x + y * y;
+ puntocaldo.x = cur->boxes[sourcebox].hotspot[cc].hotx;
+ puntocaldo.y = cur->boxes[sourcebox].hotspot[cc].hoty;
+ }
+ }
+
+ return puntocaldo;
+}
+
+void RMCharacter::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ if (bDrawNow) {
+ prim->Dst() += m_fixedScroll;
+
+ RMItem::Draw(bigBuf, prim);
+ }
+}
+
+void RMCharacter::NewBoxEntered(int nBox) {
+ RMBoxLoc *cur;
+ bool bOldReverse;
+
+ // Richiama la On ExitBox
+ mpalQueryDoAction(3, curLocation, curbox);
+
+ cur = theBoxes->GetBoxes(curLocation);
+ bOldReverse = cur->boxes[curbox].bReversed;
+ curbox = nBox;
+
+ // Se cambiata la Z, dobbiamo rimuoverlo dalla OT
+ if (cur->boxes[curbox].Zvalue != m_z) {
+ bRemoveFromOT = true;
+ m_z = cur->boxes[curbox].Zvalue;
+ }
+
+ // Gestisce l'inversione del movimento SOLO se non siamo nel percorso minimo: se siamo in percorso
+ // minimo direttamente la DoFrame a farlo
+ if (bMovingWithoutMinpath) {
+ if ((cur->boxes[curbox].bReversed && !bOldReverse) || (!cur->boxes[curbox].bReversed && bOldReverse)) {
+ switch (GetCurPattern()) {
+ case PAT_WALKUP:
+ SetPattern(PAT_WALKDOWN);
+ break;
+ case PAT_WALKDOWN:
+ SetPattern(PAT_WALKUP);
+ break;
+ case PAT_WALKRIGHT:
+ SetPattern(PAT_WALKLEFT);
+ break;
+ case PAT_WALKLEFT:
+ SetPattern(PAT_WALKRIGHT);
+ break;
+ }
+ }
+ }
+
+ // Richiama la On EnterBox
+ mpalQueryDoAction(2, curLocation, curbox);
+}
+
+void RMCharacter::DoFrame(RMGfxTargetBuffer* bigBuf, int loc) {
+ bool bEndNow;
+
+ bEndNow = false;
+ bEndOfPath = false;
+ bDrawNow = (curLocation == loc);
+
+ g_system->lockMutex(csMove);
+
+ // Se stiamo camminando...
+ if (status != STAND) {
+ // Se stiamo andando in orizzontale
+ if (walkstatus == 1) {
+ dx = walkspeed * walkcount;
+ dy = slope * dx;
+ m_pos.x = linestart.x + dx;
+ m_pos.y = linestart.y + dy;
+
+ // Destra
+ if (((walkspeed > 0) && (m_pos.x > lineend.x)) || ((walkspeed < 0) && (m_pos.x < lineend.x))) {
+ m_pos = lineend;
+ status = STAND;
+ bEndNow = true;
+ }
+ }
+
+ // Se stiamo andando in verticale
+ if (walkstatus == 0) {
+ dy = walkspeed * walkcount;
+ dx = slope * dy;
+ m_pos.x = linestart.x + dx;
+ m_pos.y = linestart.y + dy;
+
+ // Basso
+ if (((walkspeed > 0) && (m_pos.y > lineend.y)) || ((walkspeed < 0) && (m_pos.y < lineend.y))) {
+ m_pos = lineend;
+ status = STAND;
+ bEndNow = true;
+ }
+ }
+
+ // Controlla se il personaggio uscito dai BOX per errore, nel qual caso
+ // lo fa rientrare subito
+ if (InWhichBox(m_pos) == -1) {
+ m_pos.x = linestart.x + olddx;
+ m_pos.y = linestart.y + olddy;
+ }
+
+ // Se siamo appena arrivati alla destinazione temporanea ed finito il percorso minimo,
+ // ci fermiamo definitivamente
+ if (bEndNow && minpath == 0) {
+ if (!bEndOfPath)
+ Stop();
+ bEndOfPath = true;
+ PulseEvent(hEndOfPath);
+ }
+
+ walkcount++;
+
+ // Aggiorna la Z del personaggio @@@ bisognerebbe rimuoverlo solo se cambiata la Z
+
+ // Controlla se abbiamo cambiato box
+ if (!theBoxes->IsInBox(curLocation, curbox, m_pos))
+ NewBoxEntered(InWhichBox(m_pos));
+
+ // Aggiorna le vecchie coordinate
+ olddx = dx;
+ olddy = dy;
+ }
+
+ // Se siamo fermi
+ if (status == STAND) {
+ // Controlliamo se c' ancora percorso minimo da calcolare
+ if (minpath == 1) {
+ RMBoxLoc *cur = theBoxes->GetBoxes(curLocation);
+
+ // Se dobbiamo ancora attraversare un box
+ if (pathcount < pathlenght) {
+ // Controlliamo che il box su cui stiamo entrando sia attivo
+ if (cur->boxes[path[pathcount-1]].attivo) {
+ // Muoviti in linea retta verso l'hotspot pi vicino, tenendo conto del reversing please
+ // NEWBOX = path[pathcount-1]
+ GoTo(NearestHotSpot(path[pathcount-1], path[pathcount]), cur->boxes[path[pathcount-1]].bReversed);
+ pathcount++;
+ } else {
+ // Se il box disattivato, possiamo solo bloccare tutto
+ // @@@ Questo non dovrebbe pi avvenire, dato che abbiamo migliorato
+ // la ricerca del percorso minimo
+ minpath = 0;
+ if (!bEndOfPath)
+ Stop();
+ bEndOfPath = true;
+ PulseEvent(hEndOfPath);
+ }
+ } else {
+ // Se siamo gi entrati nell'ultimo box, dobbiamo solo muoverci in linea retta verso il
+ // punto di arrivo
+ // NEWBOX = InWhichBox(pathend)
+ minpath = 0;
+ GoTo(pathend, cur->boxes[InWhichBox(pathend)].bReversed);
+ }
+ }
+ }
+
+ g_system->unlockMutex(csMove);
+
+ // Richiama il DoFrame dell'item
+ RMItem::DoFrame(bigBuf);
+}
+
+void RMCharacter::Stop(void) {
+ bMoving = false;
+
+ // Non si sa mai...
+ status = STAND;
+ minpath = 0;
+
+ if (!bNeedToStop)
+ return;
+
+ bNeedToStop = false;
+
+ switch (GetCurPattern()) {
+ case PAT_WALKUP:
+ SetPattern(PAT_STANDUP);
+ break;
+
+ case PAT_WALKDOWN:
+ SetPattern(PAT_STANDDOWN);
+ break;
+
+ case PAT_WALKLEFT:
+ SetPattern(PAT_STANDLEFT);
+ break;
+
+ case PAT_WALKRIGHT:
+ SetPattern(PAT_STANDRIGHT);
+ break;
+
+ default:
+// assert(0);
+// MessageBox(NULL,"E' lo stesso errore di prima, ma non crasha","Ehi!",MB_OK);
+ SetPattern(PAT_STANDDOWN);
+ break;
+ }
+}
+
+inline int RMCharacter::InWhichBox(RMPoint pt) {
+ return theBoxes->WhichBox(curLocation,pt);
+}
+
+
+bool RMCharacter::Move(RMPoint pt) {
+ RMPoint dest;
+ int numbox;
+
+ bMoving = true;
+
+ // Se 0,0, non fare nulla, anzi fermati
+ if (pt.x == 0 && pt.y == 0) {
+ minpath = 0;
+ status = STAND;
+ Stop();
+ return true;
+ }
+
+ // Se clicko fuori dai box
+ numbox = InWhichBox(pt);
+ if (numbox == -1) {
+ // Trova il punto pi vicino dentro i box
+ dest = NearestPoint(pt);
+
+ // ???!??
+ if (dest == pt)
+ dest = InvScanLine(pt);
+
+ pt = dest;
+ numbox = InWhichBox(pt);
+ }
+
+ RMBoxLoc *cur = theBoxes->GetBoxes(curLocation);
+
+ minpath = 0;
+ status = STAND;
+ bMovingWithoutMinpath = true;
+ if (ScanLine(pt))
+ GoTo(pt, cur->boxes[numbox].bReversed);
+ else if (FindPath(InWhichBox(m_pos), InWhichBox(pt))) {
+ bMovingWithoutMinpath = false;
+ minpath = 1;
+ pathcount = 1;
+ pathend = pt;
+ } else {
+ // @@@ Questo caso se un hotspot dentro un box
+ // ma non c' un path per arrivarci. Usiamo quindi
+ // la invscanline per cercare un punto intorno
+ dest = InvScanLine(pt);
+ pt = dest;
+
+ if (ScanLine(pt))
+ GoTo(pt,cur->boxes[numbox].bReversed);
+ else if (FindPath(InWhichBox(m_pos), InWhichBox(pt))) {
+ bMovingWithoutMinpath = false;
+ minpath = 1;
+ pathcount = 1;
+ pathend = pt;
+ return true;
+ } else
+ return false;
+ }
+
+ return true;
+}
+
+void RMCharacter::SetPosition(RMPoint pt, int newloc) {
+ RMBoxLoc *box;
+
+ minpath = 0;
+ status = STAND;
+ m_pos = pt;
+
+ if (newloc != -1)
+ curLocation = newloc;
+
+ // Aggiorna la Z del personaggio
+ box = theBoxes->GetBoxes(curLocation);
+ curbox = InWhichBox(m_pos);
+ assert(curbox != -1);
+ m_z = box->boxes[curbox].Zvalue;
+ bRemoveFromOT = true;
+}
+
+bool RMCharacter::RemoveThis(void) {
+ if (bRemoveFromOT)
+ return true;
+
+ return RMItem::RemoveThis();
+}
+
+RMCharacter::RMCharacter() {
+// InitializeCriticalSection(&csMove);
+ hEndOfPath = CreateEvent(NULL, false, false, NULL);
+ minpath = 0;
+ curSpeed = 3;
+ bRemoveFromOT = false;
+ bMoving = false;
+
+ m_pos.Set(0, 0);
+}
+
+RMCharacter::~RMCharacter() {
+// DeleteCriticalSection(&csMove);
+ CloseHandle(hEndOfPath);
+}
+
+void RMCharacter::LinkToBoxes(RMGameBoxes *boxes) {
+ theBoxes = boxes;
+}
+
/****************************************************************************\
* RMBox Methods
\****************************************************************************/
@@ -94,7 +1695,7 @@ void RMBox::ReadFromStream(RMDataStream &ds) {
}
}
-RMDataStream& operator>>(RMDataStream &ds, RMBox &box) {
+RMDataStream &operator>>(RMDataStream &ds, RMBox &box) {
box.ReadFromStream(ds);
return ds;
@@ -104,7 +1705,7 @@ RMDataStream& operator>>(RMDataStream &ds, RMBox &box) {
* RMBoxLoc Methods
\****************************************************************************/
-void RMBoxLoc::ReadFromStream(RMDataStream& ds) {
+void RMBoxLoc::ReadFromStream(RMDataStream &ds) {
int i;
char buf[2];
byte ver;
@@ -132,7 +1733,7 @@ void RMBoxLoc::RecalcAllAdj(void) {
for (i = 0; i < numbbox; i++) {
Common::fill(boxes[i].adj, boxes[i].adj + MAXBOXES, 0);
- for (j=0; j < boxes[i].numhotspot; j++)
+ for (j = 0; j < boxes[i].numhotspot; j++)
if (boxes[boxes[i].hotspot[j].destination].attivo)
boxes[i].adj[boxes[i].hotspot[j].destination] = 1;
}
@@ -192,7 +1793,7 @@ int RMGameBoxes::WhichBox(int nLoc, RMPoint punto) {
if (!cur) return -1;
- for (i=0; i<cur->numbbox; i++)
+ for (i = 0; i<cur->numbbox; i++)
if (cur->boxes[i].attivo)
if ((punto.x >= cur->boxes[i].left) && (punto.x <= cur->boxes[i].right) &&
(punto.y >= cur->boxes[i].top) && (punto.y <= cur->boxes[i].bottom))
@@ -233,7 +1834,7 @@ void RMGameBoxes::SaveState(byte *state) {
WRITE_LE_UINT32(state, m_allBoxes[i]->numbbox);
state+=4;
- for (j=0; j < m_allBoxes[i]->numbbox; j++)
+ for (j = 0; j < m_allBoxes[i]->numbbox; j++)
*state++ = m_allBoxes[i]->boxes[j].attivo;
}
}
@@ -254,8 +1855,7 @@ void RMGameBoxes::LoadState(byte *state) {
nbox = READ_LE_UINT32(state);
state += 4;
- for (j=0; j<nbox ; j++)
- {
+ for (j = 0; j<nbox ; j++) {
if (j < m_allBoxes[i]->numbbox)
m_allBoxes[i]->boxes[j].attivo = *state;
@@ -266,4 +1866,451 @@ void RMGameBoxes::LoadState(byte *state) {
}
}
+/****************************************************************************\
+* Metodi di RMLocation
+\****************************************************************************/
+
+/****************************************************************************\
+*
+* Function: RMLocation::RMLocation();
+*
+* Description: Costruttore standard
+*
+\****************************************************************************/
+
+RMLocation::RMLocation() {
+ m_nItems = 0;
+ m_items = NULL;
+ m_buf = NULL;
+}
+
+
+/****************************************************************************\
+*
+* Function: bool RMLocation::Load(char *lpszFileName);
+*
+* Description: Carica una locazione (.LOC) da un file di cui viene fornito
+* il pathname.
+*
+* Input: char *lpszFileName Nome del file di dati
+*
+* Return: true se tutto OK, false in caso di errore
+*
+\****************************************************************************/
+
+bool RMLocation::Load(const char *lpszFileName) {
+ Common::File f;
+ bool bRet;
+
+ // Apre il file in lettura
+ if (!f.open(lpszFileName))
+ return false;
+
+ // Lo passa alla routine di loading da file aperto
+ bRet = Load(f);
+
+ // Chiude il file
+ f.close();
+
+ return bRet;
+}
+
+
+/****************************************************************************\
+*
+* Function: bool RMLocation::Load(HANDLE hFile);
+*
+* Description: Carica una locazione (.LOC) da un handle di file aperto
+*
+* Input: HANDLE hFile Handle del file
+*
+* Return: true se tutto OK, false in caso di errore
+*
+\****************************************************************************/
+
+bool RMLocation::Load(Common::File &file) {
+ int size;
+// byte *buf;
+// uint32 dwReadBytes;
+ bool bRet;
+
+ // Calcola la lunghezza del file
+ size = file.size();
+ file.seek(0);
+
+/*
+ // Alloca la memoria per caricare il file in memoria
+ buf=(LPBYTE)GlobalAlloc(GMEM_FIXED,size);
+
+ // Legge il file in memoria
+ ReadFile(hFile,buf,size,&dwReadBytes,0);
+
+ // Parsing del file, utilizzando la funzione di load da memorira
+ bRet=Load(buf);
+
+ // Free della memoria
+ GlobalFree(buf);
+*/
+
+ RMFileStreamSlow fs;
+
+ fs.OpenFile(file);
+ bRet = Load(fs);
+ fs.Close();
+
+ return bRet;
+}
+
+
+bool RMLocation::Load(const byte *buf) {
+ RMDataStream ds;
+ bool bRet;
+
+ ds.OpenBuffer(buf);
+ bRet = Load(ds);
+ ds.Close();
+ return bRet;
+}
+
+
+
+/****************************************************************************\
+*
+* Function: bool RMLocation::Load(byte *buf);
+*
+* Description: Carica una locazione (.LOC) parsando il file gia' caricato
+* in memoria.
+*
+* Input: byte *buf Buffer con il file caricato
+*
+* Return: true se ok, false in caso di errore
+*
+\****************************************************************************/
+
+bool RMLocation::Load(RMDataStream &ds) {
+ char id[3];
+ int dimx, dimy;
+ byte ver;
+ byte cm;
+ int i;
+
+ // Controlla l'ID
+ ds >> id[0] >> id[1] >> id[2];
+
+ // Controlla se siamo in un LOX
+ if (id[0] == 'L' && id[1] == 'O' && id[2] == 'X')
+ return LoadLOX(ds);
+
+ // Altrimenti, controlla che sia un LOC normale
+ if (id[0] != 'L' || id[1] != 'O' || id[2] != 'C')
+ return false;
+
+ // Versione
+ ds >> ver;
+ assert(ver == 6);
+
+ // Nome della locazione
+ ds >> m_name;
+
+ // Skippa i salvataggi MPAL (64 bytes)
+ ds >> TEMPNumLoc;
+ ds >> TEMPTonyStart.x >> TEMPTonyStart.y;
+ ds += 64 - 4 * 3;
+
+ // Skippa il flag di background associato (?!)
+ ds += 1;
+
+ // Dimensioni della locazione
+ ds >> dimx >> dimy;
+ m_curScroll.Set(0, 0);
+
+ // Legge il color mode
+ ds >> cm; m_cmode = (RMColorMode)cm;
+
+ // Inizializza il source buffer e leggi la locazione dentro
+ switch (m_cmode) {
+ case CM_256:
+ m_buf = new RMGfxSourceBuffer8;
+ break;
+
+ case CM_65K:
+ m_buf = new RMGfxSourceBuffer16;
+ break;
+
+ default:
+ assert(0);
+ break;
+ };
+
+ // Inizializza la surface, caricando anche la palette se necessario
+ m_buf->Init(ds, dimx, dimy, true);
+
+ // Controlla le dimensioni della locazione
+// assert(dimy!=512);
+
+ // Numero oggetti
+ ds >> m_nItems;
+
+ // Creazione e lettura degli oggetti
+ if (m_nItems > 0)
+ m_items = new RMItem[m_nItems];
+
+
+ _vm->FreezeTime();
+ for (i = 0;i < m_nItems && !ds.IsError(); i++)
+ ds >> m_items[i];
+ _vm->UnfreezeTime();
+
+ // Setta i pattern iniziali @@@ doppione!!
+ //for (i = 0;i<m_nItems;i++)
+ // m_items[i].SetPattern(mpalQueryItemPattern(m_items[i].MpalCode()));
+
+ return ds.IsError();
+}
+
+
+bool RMLocation::LoadLOX(RMDataStream &ds) {
+ int dimx, dimy;
+ byte ver;
+ int i;
+
+ // Versione
+ ds >> ver;
+ assert(ver == 1);
+
+ // Nome locazione
+ ds >> m_name;
+
+ // Numero loc
+ ds >> TEMPNumLoc;
+ ds >> TEMPTonyStart.x >> TEMPTonyStart.y;
+
+ // Dimensioni
+ ds >> dimx >> dimy;
+ m_curScroll.Set(0, 0);
+
+ // Color mode sempre 65K
+ m_cmode = CM_65K;
+ m_buf = new RMGfxSourceBuffer16;
+
+ // Inizializza la surface, caricando anche la palette se necessario
+ m_buf->Init(ds, dimx, dimy, true);
+
+ // Controlla le dimensioni della locazione
+// assert(dimy!=512);
+
+ // Numero oggetti
+ ds >> m_nItems;
+
+ // Creazione e lettura degli oggetti
+ if (m_nItems > 0)
+ m_items = new RMItem[m_nItems];
+
+ for (i = 0; i < m_nItems && !ds.IsError(); i++)
+ m_items[i].ReadFromStream(ds, true);
+
+ return ds.IsError();
+}
+
+
+
+/****************************************************************************\
+*
+* Function: void RMLocation::Draw(RMGfxTargetBuffer* bigBuf,
+* RMGfxPrimitive* prim);
+*
+* Description: Metodo di drawing in overloading da RMGfxSourceBuffer8
+*
+\****************************************************************************/
+
+void RMLocation::Draw(RMGfxTargetBuffer &bigBuf, RMGfxPrimitive *prim) {
+ // Setta la posizione sorgente dello scrolling
+ if (m_buf->Dimy()>RM_SY || m_buf->Dimx()>RM_SX) {
+ prim->SetSrc(RMRect(m_curScroll,m_curScroll+RMPoint(640,480)));
+ }
+
+ prim->SetDst(m_fixedScroll);
+
+ // Richiama il metodo di drawing della classe dell'immagine, che disegner il background
+ // della locazione
+ m_buf->Draw(bigBuf, prim);
+}
+
+
+/****************************************************************************\
+*
+* Function: void RMLocation::DoFrame(void);
+*
+* Description: Prepara un frame, aggiungendo alla OTList la locazione stessa
+* e tutti gli item che hanno cambiato frame di animazione
+*
+\****************************************************************************/
+
+void RMLocation::DoFrame(RMGfxTargetBuffer *bigBuf) {
+ int i;
+
+ // Se la locazione non e' in OT list, la aggiunge
+ if (!m_nInList)
+ bigBuf->AddPrim(new RMGfxPrimitive(this));
+
+ // Processa tutti gli item della locazione
+ for (i = 0;i < m_nItems; i++)
+ m_items[i].DoFrame(bigBuf);
+}
+
+
+RMItem *RMLocation::GetItemFromCode(uint32 dwCode) {
+ int i;
+
+ for (i = 0; i < m_nItems; i++)
+ if (m_items[i].MpalCode() == (int)dwCode)
+ return &m_items[i];
+
+ return NULL;
+}
+
+RMItem *RMLocation::WhichItemIsIn(RMPoint pt) {
+ int found = -1;
+ int foundSize = 0;
+ int size;
+
+ for (int i = 0; i < m_nItems; i++) {
+ size = 0;
+ if (m_items[i].IsIn(pt, &size)) {
+ if (found == -1 || size < foundSize) {
+ foundSize = size;
+ found = i;
+ }
+ }
+ }
+
+ if (found == -1)
+ return NULL;
+ else
+ return &m_items[found];
+}
+
+
+RMLocation::~RMLocation() {
+ Unload();
+}
+
+void RMLocation::Unload(void) {
+ // Cancella la memoria
+ if (m_items) {
+ delete[] m_items;
+ m_items = NULL;
+ }
+
+ // Cancella il buffer
+ if (m_buf) {
+ delete m_buf;
+ m_buf = NULL;
+ }
+}
+
+void RMLocation::UpdateScrolling(RMPoint ptShowThis) {
+ RMPoint oldScroll = m_curScroll;
+
+ if (m_curScroll.x + 250 > ptShowThis.x) {
+ m_curScroll.x = ptShowThis.x - 250;
+ } else if (m_curScroll.x + RM_SX - 250 < ptShowThis.x) {
+ m_curScroll.x = ptShowThis.x + 250 - RM_SX;
+ } else if (ABS(m_curScroll.x + RM_SX / 2 - ptShowThis.x) > 32 && m_buf->Dimx() > RM_SX) {
+ if (m_curScroll.x + RM_SX / 2 < ptShowThis.x)
+ m_curScroll.x++;
+ else
+ m_curScroll.x--;
+ }
+
+ if (m_curScroll.y + 180 > ptShowThis.y) {
+ m_curScroll.y = ptShowThis.y - 180;
+ } else if (m_curScroll.y + RM_SY - 180 < ptShowThis.y) {
+ m_curScroll.y = ptShowThis.y + 180 - RM_SY;
+ } else if (ABS(m_curScroll.y + RM_SY / 2 - ptShowThis.y) > 16 && m_buf->Dimy() > RM_SY) {
+ if (m_curScroll.y + RM_SY / 2 < ptShowThis.y)
+ m_curScroll.y++;
+ else
+ m_curScroll.y--;
+ }
+
+ if (m_curScroll.x < 0) m_curScroll.x = 0;
+ if (m_curScroll.y < 0) m_curScroll.y = 0;
+ if (m_curScroll.x + RM_SX > m_buf->Dimx()) m_curScroll.x = m_buf->Dimx() - RM_SX;
+ if (m_curScroll.y + RM_SY > m_buf->Dimy()) m_curScroll.y = m_buf->Dimy() - RM_SY;
+
+ if (oldScroll != m_curScroll)
+ for (int i = 0; i < m_nItems; i++)
+ m_items[i].SetScrollPosition(m_curScroll);
+}
+
+void RMLocation::SetFixedScroll(const RMPoint &scroll) {
+ m_fixedScroll = scroll;
+
+ for (int i = 0; i < m_nItems; i++)
+ m_items[i].SetScrollPosition(m_curScroll - m_fixedScroll);
+}
+
+void RMLocation::SetScrollPosition(const RMPoint &scroll) {
+ RMPoint pt = scroll;
+ if (pt.x < 0) pt.x = 0;
+ if (pt.y < 0) pt.y = 0;
+ if (pt.x + RM_SX>m_buf->Dimx()) pt.x = m_buf->Dimx() - RM_SX;
+ if (pt.y + RM_SY>m_buf->Dimy()) pt.y = m_buf->Dimy() - RM_SY;
+
+ m_curScroll = pt;
+
+ for (int i = 0; i < m_nItems; i++)
+ m_items[i].SetScrollPosition(m_curScroll);
+}
+
+
+void RMLocation::PauseSound(bool bPause) {
+ int i;
+
+ for (i = 0; i < m_nItems; i++)
+ m_items[i].PauseSound(bPause);
+}
+
+
+/****************************************************************************\
+* Metodi di RMMessage
+\****************************************************************************/
+
+RMMessage::RMMessage(uint32 dwId) {
+ lpMessage=mpalQueryMessage(dwId);
+ assert(lpMessage != NULL);
+
+ if (lpMessage)
+ ParseMessage();
+}
+
+RMMessage::~RMMessage() {
+ if (lpMessage)
+ GlobalFree(lpMessage);
+}
+
+void RMMessage::ParseMessage(void) {
+ char *p;
+
+ assert(lpMessage != NULL);
+
+ nPeriods = 1;
+ p = lpPeriods[0] = lpMessage;
+
+ for (;;) {
+ // Trova la fine del periodo corrente
+ while (*p != '\0')
+ p++;
+
+ // Se c'e' un altro '\0' siamo alla fine del messaggio
+ p++;
+ if (*p == '\0')
+ break;
+
+ // Altrimenti c'e' un altro periodo, e ci ricordiamo il suo inizio
+ lpPeriods[nPeriods++] = p;
+ }
+}
+
} // End of namespace Tony
diff --git a/engines/tony/loc.h b/engines/tony/loc.h
index 73effc85c1..c5c7859e73 100644
--- a/engines/tony/loc.h
+++ b/engines/tony/loc.h
@@ -50,6 +50,7 @@
#include "common/scummsys.h"
#include "common/system.h"
+#include "common/file.h"
#include "tony/mpal/stubs.h"
#include "tony/sound.h"
#include "tony/utils.h"
@@ -539,8 +540,8 @@ public:
virtual ~RMLocation();
// Caricamento da disco
- bool Load(char *lpszFileName);
- bool Load(HANDLE hFile);
+ bool Load(const char *lpszFileName);
+ bool Load(Common::File &file);
bool Load(const byte *buf);
bool Load(RMDataStream &ds);
bool LoadLOX(RMDataStream &ds);
diff --git a/engines/tony/utils.h b/engines/tony/utils.h
index bd4b152f1f..f9c9e614ac 100644
--- a/engines/tony/utils.h
+++ b/engines/tony/utils.h
@@ -118,6 +118,56 @@ public:
bool IsError();
};
+
+/**
+ * Data stream per lettura di dati aperto da file
+ */
+class RMFileStream : public RMDataStream {
+private:
+ byte *m_buf;
+
+public:
+ RMFileStream();
+ virtual ~RMFileStream();
+
+ // Apre lo stream da file
+ bool OpenFile(const char *lpFN);
+ bool OpenFile(Common::File &file);
+
+ void Close(void);
+};
+
+
+class RMFileStreamSlow : public RMDataStream {
+private:
+ Common::File f;
+ bool bMustClose;
+
+public:
+ RMFileStreamSlow();
+ virtual ~RMFileStreamSlow();
+
+ bool OpenFile(const char *lpFN);
+ bool OpenFile(Common::File &file);
+
+ void Close(void);
+
+ RMDataStream& operator+=(int nBytes);
+ int Seek(int nBytes, RMDSPos where = CUR);
+
+ int Pos();
+ virtual bool IsEOF();
+
+ bool Read(void *buf, int size);
+
+ friend RMFileStreamSlow& operator>>(RMFileStreamSlow &df, char &var);
+ friend RMFileStreamSlow& operator>>(RMFileStreamSlow &df, byte &var);
+ friend RMFileStreamSlow& operator>>(RMFileStreamSlow &df, uint16 &var);
+ friend RMFileStreamSlow& operator>>(RMFileStreamSlow &df, int16 &var);
+ friend RMFileStreamSlow& operator>>(RMFileStreamSlow &df, int &var);
+ friend RMFileStreamSlow& operator>>(RMFileStreamSlow &df, uint32 &var);
+};
+
/**
* String class
*/