aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2006-02-22 22:40:53 +0000
committerEugene Sandulenko2006-02-22 22:40:53 +0000
commit71c170bb136ab94d70eb10d55cfd897dc89c9682 (patch)
treed555cf8177ba4f6fe3fbc0b0fd1d5d45df58874e
parenta467247e6ed972e0a13bf26af07811dda55bd69a (diff)
downloadscummvm-rg350-71c170bb136ab94d70eb10d55cfd897dc89c9682.tar.gz
scummvm-rg350-71c170bb136ab94d70eb10d55cfd897dc89c9682.tar.bz2
scummvm-rg350-71c170bb136ab94d70eb10d55cfd897dc89c9682.zip
Initial version of Cinematique engine evo 1.
svn-id: r20813
-rw-r--r--AUTHORS7
-rwxr-xr-xconfigure13
-rw-r--r--doc/10.tex10
-rw-r--r--engines/cine/anim.cpp1057
-rw-r--r--engines/cine/anim.h66
-rw-r--r--engines/cine/auto00.cpp49
-rw-r--r--engines/cine/auto00.h32
-rw-r--r--engines/cine/bg.cpp154
-rw-r--r--engines/cine/bg.h39
-rw-r--r--engines/cine/bg_list.cpp47
-rw-r--r--engines/cine/bg_list.h30
-rw-r--r--engines/cine/cine.cpp256
-rw-r--r--engines/cine/cine.h109
-rw-r--r--engines/cine/flip_support.cpp57
-rw-r--r--engines/cine/flip_support.h34
-rw-r--r--engines/cine/font.cpp62
-rw-r--r--engines/cine/font.h37
-rw-r--r--engines/cine/gfx.cpp386
-rw-r--r--engines/cine/gfx.h71
-rw-r--r--engines/cine/main_loop.cpp232
-rw-r--r--engines/cine/main_loop.h31
-rw-r--r--engines/cine/module.mk36
-rw-r--r--engines/cine/msg.cpp76
-rw-r--r--engines/cine/msg.h30
-rw-r--r--engines/cine/object.cpp490
-rw-r--r--engines/cine/object.h76
-rw-r--r--engines/cine/pal.cpp123
-rw-r--r--engines/cine/pal.h44
-rw-r--r--engines/cine/part.cpp226
-rw-r--r--engines/cine/part.h66
-rw-r--r--engines/cine/prc.cpp144
-rw-r--r--engines/cine/prc.h47
-rw-r--r--engines/cine/rel.cpp127
-rw-r--r--engines/cine/rel.h45
-rw-r--r--engines/cine/resource.cpp28
-rw-r--r--engines/cine/resource.h30
-rw-r--r--engines/cine/script.cpp4421
-rw-r--r--engines/cine/script.h64
-rw-r--r--engines/cine/sfx_player.cpp287
-rw-r--r--engines/cine/sfx_player.h59
-rw-r--r--engines/cine/sound_driver.cpp435
-rw-r--r--engines/cine/sound_driver.h91
-rw-r--r--engines/cine/texte.cpp82
-rw-r--r--engines/cine/texte.h33
-rw-r--r--engines/cine/unpack.cpp151
-rw-r--r--engines/cine/unpack.h30
-rw-r--r--engines/cine/various.cpp3263
-rw-r--r--engines/cine/various.h193
-rw-r--r--engines/module.mk7
-rw-r--r--gui/credits.h7
-rwxr-xr-xtools/credits.pl10
51 files changed, 13495 insertions, 5 deletions
diff --git a/AUTHORS b/AUTHORS
index 40c12ffece..6c1fbd31ad 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -37,6 +37,11 @@ ScummVM Team
Torbjorn Andersson
Jonathan Gray
+ Cinematique evo 1:
+ Pawel Kolodziejski
+ Gregory Montoir
+ Eugene Sandulenko
+
FOTAQ:
David Eriksson
Gregory Montoir
@@ -100,7 +105,7 @@ ScummVM Team
Tore Anderson - Former Debian GNU/Linux maintainer
Ralph Brorsen - Help with GUI implementation
Jamieson Christian - iMUSE, MIDI, all things musical
- Vincent Hamm - Co-Founder
+ Vincent Hamm - Co-Founder, original CinE engine author
Ruediger Hanke - Port: MorphOS
Felix Jakschitsch - Zak256 reverse engineering
Mutwin Kraus - Original MacOS porter
diff --git a/configure b/configure
index a99cacb022..a915832dd8 100755
--- a/configure
+++ b/configure
@@ -58,6 +58,7 @@ _build_saga=yes
_build_gob=yes
_build_kyra=yes
_build_lure=no
+_build_cine=no
_need_memalign=no
_build_plugins=no
_nasm=auto
@@ -305,6 +306,7 @@ Optional Features:
--disable-gob don't build the Gobli*ns engine
--disable-kyra don't build the Legend of Kyrandia engine
--enable-lure build the Lure of the Temptress engine
+ --enable-cine build the Cinematique engine evo 1
--enable-plugins build engines as loadable modules instead of
static linking them
--disable-mt32emu don't enable the integrated MT-32 emulator
@@ -371,6 +373,7 @@ for ac_option in $@; do
--disable-gob) _build_gob=no ;;
--disable-kyra) _build_kyra=no ;;
--enable-lure) _build_lure=yes ;;
+ --enable-cine) _build_cine=yes ;;
--disable-hq-scalers) _build_hq_scalers=no ;;
--disable-scalers) _build_scalers=no ;;
--enable-alsa) _alsa=yes ;;
@@ -691,6 +694,12 @@ else
_mak_lure='# DISABLE_LURE = 1'
fi
+if test "$_build_cine" = no ; then
+ _mak_lure='DISABLE_CINE = 1'
+else
+ _mak_lure='# DISABLE_CINE = 1'
+fi
+
if test "$_build_hq_scalers" = no ; then
_mak_hq_scalers='DISABLE_HQ_SCALERS = 1'
else
@@ -1259,6 +1268,9 @@ fi
if test "$_build_lure" = yes ; then
echo " Lure of the Temptress"
fi
+if test "$_build_cine" = yes ; then
+ echo " Cinematique evo 1"
+fi
echo
@@ -1395,6 +1407,7 @@ $_mak_kyra
$_mak_saga
$_mak_gob
$_mak_lure
+$_mak_cine
$_mak_mt32emu
$_mak_hq_scalers
diff --git a/doc/10.tex b/doc/10.tex
index 0c7f86765a..5fd657df16 100644
--- a/doc/10.tex
+++ b/doc/10.tex
@@ -54,6 +54,14 @@
Jonathan Gray & \textit{}\\
\end{tabular}
\end{list}
+\item \textbf{ Cinematique evo 1}
+\begin{list}{}{\setlength{\leftmargin}{0.2cm}}
+\item \begin{tabular}[h]{p{0.3\linewidth}p{0.6\linewidth}}
+ Pawe{\l} Ko{\l}odziejski & \textit{}\\
+ Gregory Montoir & \textit{}\\
+ Eugene Sandulenko & \textit{}\\
+ \end{tabular}
+\end{list}
\item \textbf{ FOTAQ}
\begin{list}{}{\setlength{\leftmargin}{0.2cm}}
\item \begin{tabular}[h]{p{0.3\linewidth}p{0.6\linewidth}}
@@ -159,7 +167,7 @@ All active team members
Tore Anderson & \textit{Former Debian GNU/Linux maintainer}\\
Ralph Brorsen & \textit{Help with GUI implementation}\\
Jamieson Christian & \textit{iMUSE, MIDI, all things musical}\\
- Vincent Hamm & \textit{Co-Founder}\\
+ Vincent Hamm & \textit{Co-Founder, original CinE engine author}\\
Ruediger Hanke & \textit{Port: MorphOS}\\
Felix Jakschitsch & \textit{Zak256 reverse engineering}\\
Mutwin Kraus & \textit{Original MacOS porter}\\
diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp
new file mode 100644
index 0000000000..808404a5b1
--- /dev/null
+++ b/engines/cine/anim.cpp
@@ -0,0 +1,1057 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+struct animHeader2Struct {
+ u32 field_0;
+ u16 width;
+ u16 height;
+ u16 type;
+ u16 field_A;
+ u16 field_C;
+ u16 field_E;
+};
+
+typedef struct animHeader2Struct animHeader2Struct;
+
+u16 frameVar0 = 0;
+
+animHeaderStruct animHeader;
+
+animDataEntry animData[] = {
+ {"ALPHA", 0xF},
+ {"TITRE2", 0xF},
+ {"ET", 0xC},
+ {"L311", 0x3},
+ {"L405", 0x1},
+ {"L515", 0xC},
+ {"L009", 0xE},
+ {"L010", 0xE},
+ {"FUTUR", 0x6},
+ {"PAYSAN3", 0xB},
+ {"L801", 0xC},
+ {"L802", 0xC},
+ {"L803", 0xC},
+ {"L901", 0xD},
+ {"L902", 0x8},
+ {"L903", 0xD},
+ {"L904", 0xD},
+ {"L905", 0xD},
+ {"L906", 0xD},
+ {"L907", 0xD},
+ {"LA03", 0x4},
+ {"MOINE", 0xB},
+ {"L908", 0x8},
+ {"L909", 0x8},
+ {"L807", 0xC},
+ {"L808", 0xC},
+ {"LA01", 0xB},
+ {"L1201", 0xC},
+ {"L1202", 0xC},
+ {"L1203", 0xC},
+ {"L1210", 0x5},
+ {"L1211", 0xC},
+ {"L1214", 0xC},
+ {"L1215", 0xC},
+ {"L1216", 0xC},
+ {"L1217", 0xC},
+ {"L1218", 0xC},
+ {"L1219", 0xC},
+ {"L1220", 0xC},
+ {"SEIGNEUR", 0x6},
+ {"PERE0", 0xD},
+ {"L1302", 0x4},
+ {"L1303", 0x4},
+ {"L1304", 0x4},
+ {"L1401", 0xF},
+ {"L1402", 0xF},
+ {"L1501", 0x8},
+ {"L1503", 0x8},
+ {"L1504", 0x4},
+ {"L1505", 0x8},
+ {"L1506", 0x8},
+ {"L1601", 0xB},
+ {"L1602", 0xB},
+ {"L1603", 0xB},
+ {"L1604", 0x4},
+ {"L1605", 0x4},
+ {"L1701", 0x4},
+ {"L1702", 0x4},
+ {"L1801", 0x6},
+ {"L1904", 0x8},
+ {"L2002", 0x8},
+ {"L2003", 0x8},
+ {"L2101", 0x4},
+ {"L2102", 0x4},
+ {"L2201", 0x7},
+ {"L2202", 0x7},
+ {"L2203", 0xE},
+ {"L2305", 0x9},
+ {"L2306", 0x9},
+ {"GARDE1", 0x7},
+ {"L2402", 0x7},
+ {"L2407", 0x7},
+ {"L2408", 0x7},
+ {"GARDE2", 0x6},
+ {"L2601", 0x6},
+ {"L2602", 0x6},
+ {"L2603", 0x6},
+ {"L2604", 0x6},
+ {"L2605", 0x8},
+ {"L2606", 0x8},
+ {"L2607", 0x8},
+ {"L2610", 0x6},
+ {"L2611", 0x6},
+ {"L2612", 0x6},
+ {"L2613", 0x8},
+ {"L2614", 0x6},
+ {"VOYAGEUR", 0x6},
+ {"L2701", 0xD},
+ {"L2702", 0xD},
+ {"L2703", 0x6},
+ {"L2801", 0xD},
+ {"L2802", 0xD},
+ {"L2803", 0xD},
+ {"L2804", 0xD},
+ {"L2807", 0xD},
+ {"L2902", 0x8},
+ {"L2903", 0x8},
+ {"L3101", 0xA},
+ {"L3102", 0xA},
+ {"L3103", 0xA},
+ {"L3203", 0xF},
+ {"L3204", 0xF},
+ {"L3001", 0x7},
+ {"L3002", 0x7},
+ {"L3416", 0xC},
+ {"L3601", 0x5},
+ {"L3602", 0x5},
+ {"L3603", 0x5},
+ {"L3607", 0x5},
+ {"L3701", 0x8},
+ {"L3702", 0x8},
+ {"L3703", 0x8},
+ {"L4001", 0xD},
+ {"L4002", 0xD},
+ {"L4103", 0xF},
+ {"L4106", 0xF},
+ {"CRUGHON1", 0xC},
+ {"L4203", 0xC},
+ {"L4301", 0xC},
+ {"L4302", 0xC},
+ {"L4303", 0xC},
+ {"FUTUR2", 0x6},
+ {"L4601", 0xE},
+ {"L4603", 0x1},
+ {"L4106", 0xF},
+ {"L4801", 0xD},
+ {"L4802", 0xD},
+ {"FIN01", 0xB},
+ {"FIN02", 0xB},
+ {"FIN03", 0xB},
+ {"FIN", 0x9},
+};
+
+#define NUM_ANIM_DATA (sizeof(animData)/sizeof(animDataEntry))
+
+u8 findAnimInHardcodedData(char *animName) {
+ char name[15];
+ u16 i;
+
+ removeExtention(name, animName);
+
+ for (i = 0; i < NUM_ANIM_DATA; i++) {
+ if (!strcmp(name, animData[i].name)) {
+ return (animData[i].param);
+ }
+ }
+
+ return (0);
+}
+
+s16 allocFrame(u16 width, u16 height, s8 isMask) {
+ u16 i;
+ u32 frameSize;
+
+ for (i = 0; i < NUM_MAX_PARTDATA; i++) {
+ if (!animDataTable[i].ptr1)
+ break;
+ }
+
+ if (i == NUM_MAX_PARTDATA)
+ return -1;
+
+ if (!isMask) { // sprite + generated mask
+ frameSize = width * height;
+
+ animDataTable[i].ptr1 = (u8 *) malloc(frameSize);
+ animDataTable[i].ptr2 = (u8 *) malloc(frameSize);
+
+ animDataTable[i].width = width;
+ animDataTable[i].var1 = width >> 3;
+ animDataTable[i].field_4 = 4;
+ animDataTable[i].var2 = height;
+
+ animDataTable[i].fileIdx = -1;
+ animDataTable[i].frameIdx = -1;
+ } else {
+ // mask
+ frameSize = width * height * 8;
+
+ animDataTable[i].ptr1 = (u8 *) malloc(frameSize);
+ animDataTable[i].ptr2 = NULL;
+
+ animDataTable[i].width = width;
+ animDataTable[i].var1 = width >> 3;
+ animDataTable[i].field_4 = 4;
+ animDataTable[i].var2 = height;
+
+ animDataTable[i].fileIdx = -1;
+ animDataTable[i].frameIdx = -1;
+ }
+
+ frameVar0++;
+
+ return (i);
+}
+
+s16 allocFrame2(u16 width, u16 height, u16 type) {
+ u16 i;
+ u32 frameSize;
+
+ for (i = 0; i < NUM_MAX_PARTDATA; i++) {
+ if (!animDataTable[i].ptr1)
+ break;
+ }
+
+ if (i == NUM_MAX_PARTDATA)
+ return -1;
+
+ frameSize = width * height;
+
+ if (type == 4) // 16 color sprites to 256
+ {
+ frameSize *= 2;
+ type = 8;
+ width *= 2;
+ }
+
+ if (type == 5) {
+ frameSize += 16;
+ }
+
+ frameSize *= 2;
+
+ animDataTable[i].ptr1 = (u8 *) malloc(frameSize);
+
+ ASSERT_PTR(animDataTable[i].ptr1);
+
+ animDataTable[i].width = width;
+
+ if (type == 5) {
+ animDataTable[i].var1 = width / 8;
+ } else {
+ animDataTable[i].var1 = width / 16;
+ }
+
+ animDataTable[i].field_4 = type; // bbp ?
+
+ animDataTable[i].var2 = height;
+
+ animDataTable[i].fileIdx = -1;
+ animDataTable[i].frameIdx = -1;
+
+ frameVar0++;
+
+ return (i);
+}
+
+s16 reserveFrame(u16 width, u16 height, u16 type, u16 idx) {
+ u16 i;
+ u32 frameSize;
+
+ i = idx;
+
+ frameSize = width * height;
+
+ if (type == 4) // 256 color sprites
+ {
+ frameSize *= 2;
+ type = 8;
+ width *= 2;
+ }
+
+ if (type == 5) {
+ frameSize += 16;
+ }
+
+ frameSize *= 2;
+
+ animDataTable[i].ptr1 = (u8 *) malloc(frameSize);
+
+ ASSERT_PTR(animDataTable[i].ptr1);
+
+ animDataTable[i].width = width;
+
+ if (type == 5) {
+ animDataTable[i].var1 = width / 8;
+ } else {
+ animDataTable[i].var1 = width / 16;
+ }
+
+ animDataTable[i].field_4 = type; // bbp ?
+
+ animDataTable[i].var2 = height;
+
+ animDataTable[i].fileIdx = -1;
+ animDataTable[i].frameIdx = -1;
+
+ frameVar0++;
+
+ return (i);
+}
+
+void generateMask(u8 * sprite, u8 * mask, u16 size, u8 transparency) {
+ u16 i;
+
+ for (i = 0; i < size; i++) {
+ if (*(sprite++) != transparency) {
+ *(mask++) = 0;
+ } else {
+ *(mask++) = 1;
+ }
+ }
+}
+
+void convertMask(u8 * dest, u8 * source, s16 width, s16 height) {
+ s16 i;
+ s16 j;
+
+ for (i = 0; i < width * height; i++) {
+ u8 maskEntry = *(source++);
+ for (j = 0; j < 8; j++) {
+ if (maskEntry & 0x80) {
+ *(dest++) = 0;
+ } else {
+ *(dest++) = 1;
+ }
+
+ maskEntry <<= 1;
+ }
+ }
+}
+
+void convert4BBP(u8 * dest, u8 * source, s16 width, s16 height) {
+ s16 i;
+
+ for (i = 0; i < width * height; i++) {
+ u8 maskEntry = *(source++);
+ *(dest++) = (maskEntry & 0xF0) >> 4;
+ *(dest++) = (maskEntry & 0xF);
+ }
+}
+
+void loadSpl(char *resourceName) {
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ entry =
+ allocFrame((u16) partBuffer[foundFileIdx].unpacked_size, 1, -1);
+
+ ASSERT(entry != -1);
+
+ memcpy(animDataTable[entry].ptr1, dataPtr,
+ (u16) partBuffer[foundFileIdx].unpacked_size);
+
+ animDataTable[entry].fileIdx = foundFileIdx;
+ animDataTable[entry].frameIdx = 0;
+ strcpy(animDataTable[entry].name, currentPartName);
+}
+
+void loadMsk(char *resourceName) {
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+ u8 *ptr;
+ s16 i;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ ptr = dataPtr;
+
+ memcpy(&animHeader, ptr, sizeof(animHeaderStruct));
+ ptr += sizeof(animHeaderStruct);
+
+ flipU16(&animHeader.frameWidth);
+ flipU16(&animHeader.frameHeight);
+ flipU16(&animHeader.numFrames);
+
+ for (i = 0; i < animHeader.numFrames; i++) {
+ entry =
+ allocFrame(animHeader.frameWidth * 2,
+ animHeader.frameHeight, 1);
+
+ ASSERT(entry != -1);
+
+ convertMask(animDataTable[entry].ptr1, ptr,
+ animHeader.frameWidth, animHeader.frameHeight);
+ ptr += animHeader.frameWidth * animHeader.frameHeight;
+
+ animDataTable[entry].fileIdx = foundFileIdx;
+ animDataTable[entry].frameIdx = i;
+ strcpy(animDataTable[entry].name, currentPartName);
+ }
+}
+
+void loadAni(char *resourceName) {
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+ u8 *ptr;
+ s16 i;
+ u8 transparentColor;
+ u32 fullSize;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ ptr = dataPtr;
+
+ memcpy(&animHeader, ptr, sizeof(animHeaderStruct));
+ ptr += sizeof(animHeaderStruct);
+
+ flipU16(&animHeader.frameWidth);
+ flipU16(&animHeader.frameHeight);
+ flipU16(&animHeader.numFrames);
+
+ transparentColor = findAnimInHardcodedData(resourceName);
+
+ fullSize = animHeader.frameWidth * animHeader.frameHeight;
+
+ for (i = 0; i < animHeader.numFrames; i++) {
+ u8 *animPtr;
+
+ entry =
+ allocFrame(animHeader.frameWidth * 2,
+ animHeader.frameHeight, 0);
+
+ ASSERT(entry != -1);
+
+ // special case transparency handling
+ if (!strcmp(resourceName, "L2202.ANI")) {
+ if (i < 2) {
+ transparentColor = 0;
+ } else {
+ transparentColor = 7;
+ }
+ }
+
+ if (!strcmp(resourceName, "L4601.ANI")) {
+ if (i < 1) {
+ transparentColor = 0xE;
+ } else {
+ transparentColor = 0;
+ }
+ }
+
+ animPtr = (u8 *) malloc(fullSize);
+
+ memcpy(animPtr, ptr, fullSize);
+ ptr += fullSize;
+
+ gfxConvertSpriteToRaw(animDataTable[entry].ptr1, animPtr,
+ animHeader.frameWidth, animHeader.frameHeight);
+
+ generateMask(animDataTable[entry].ptr1,
+ animDataTable[entry].ptr2,
+ animHeader.frameWidth * 2 * animHeader.frameHeight,
+ transparentColor);
+
+ free(animPtr);
+
+ animDataTable[entry].fileIdx = foundFileIdx;
+ animDataTable[entry].frameIdx = i;
+ strcpy(animDataTable[entry].name, currentPartName);
+ }
+}
+
+void convert8BBP(u8 * dest, u8 * source, s16 width, s16 height) {
+ u16 i;
+ u8 table[16];
+
+ memcpy(table, source, 16);
+ source += 16;
+
+ for (i = 0; i < width * height; i++) {
+ u8 color = *(source++);
+
+ *(dest++) = table[color >> 4];
+ *(dest++) = table[color & 0xF];
+ }
+}
+
+void convert8BBP2(u8 * dest, u8 * source, s16 width, s16 height) {
+ u16 i;
+ u16 j;
+
+ u8 al;
+ u8 ah;
+ u8 bl;
+ u8 bh;
+ u8 cl;
+ u8 ch;
+ u8 dl;
+ u8 dh;
+ u8 color;
+
+ for (j = 0; j < (width * height) / 16; j++) {
+ al = *(source);
+ ah = *(source + 2);
+ bl = *(source + 4);
+ bh = *(source + 6);
+ cl = *(source + 8);
+ ch = *(source + 0xA);
+ dl = *(source + 0xC);
+ dh = *(source + 0xE);
+
+ for (i = 0; i < 8; i++) {
+ color = 0;
+
+ color |= ((dh & 0x080) >> 7);
+ dh <<= 1;
+ color <<= 1;
+ color |= ((dl & 0x080) >> 7);
+ dl <<= 1;
+ color <<= 1;
+ color |= ((ch & 0x080) >> 7);
+ ch <<= 1;
+ color <<= 1;
+ color |= ((cl & 0x080) >> 7);
+ cl <<= 1;
+ color <<= 1;
+ color |= ((bh & 0x080) >> 7);
+ bh <<= 1;
+ color <<= 1;
+ color |= ((bl & 0x080) >> 7);
+ bl <<= 1;
+ color <<= 1;
+ color |= ((ah & 0x080) >> 7);
+ ah <<= 1;
+ color <<= 1;
+ color |= ((al & 0x080) >> 7);
+ al <<= 1;
+
+ *(dest++) = color;
+ }
+
+ al = *(source + 1);
+ ah = *(source + 3);
+ bl = *(source + 5);
+ bh = *(source + 7);
+ cl = *(source + 9);
+ ch = *(source + 0xB);
+ dl = *(source + 0xD);
+ dh = *(source + 0xF);
+
+ for (i = 0; i < 8; i++) {
+ color = 0;
+
+ color |= ((dh & 0x080) >> 7);
+ dh <<= 1;
+ color <<= 1;
+ color |= ((dl & 0x080) >> 7);
+ dl <<= 1;
+ color <<= 1;
+ color |= ((ch & 0x080) >> 7);
+ ch <<= 1;
+ color <<= 1;
+ color |= ((cl & 0x080) >> 7);
+ cl <<= 1;
+ color <<= 1;
+ color |= ((bh & 0x080) >> 7);
+ bh <<= 1;
+ color <<= 1;
+ color |= ((bl & 0x080) >> 7);
+ bl <<= 1;
+ color <<= 1;
+ color |= ((ah & 0x080) >> 7);
+ ah <<= 1;
+ color <<= 1;
+ color |= ((al & 0x080) >> 7);
+ al <<= 1;
+
+ *(dest++) = color;
+ }
+
+ source += 0x10;
+ }
+}
+
+void loadSet(char *resourceName) {
+ animHeader2Struct header2;
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+ u8 *ptr;
+ s16 i;
+ u32 fullSize;
+ u16 numSpriteInAnim;
+ u8 *startOfDataPtr;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ ASSERT(!memcmp(dataPtr, "SET", 3));
+
+ ptr = dataPtr + 4;
+
+ numSpriteInAnim = *(u16 *) ptr;
+ flipU16(&numSpriteInAnim);
+ ptr += 2;
+
+ startOfDataPtr = ptr + numSpriteInAnim * 0x10;
+
+ for (i = 0; i < numSpriteInAnim; i++) {
+ s16 typeParam;
+ u8 table[16] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+ memcpy(&header2, ptr, 0x10);
+ ptr += 0x10;
+
+ flipU32(&header2.field_0);
+ flipU16(&header2.width);
+ flipU16(&header2.height);
+ flipU16(&header2.type);
+
+ fullSize = header2.width * header2.height;
+
+ typeParam = 0;
+
+ if (header2.type == 5) {
+ fullSize += 16;
+ }
+
+ if (header2.type == 4) {
+ header2.type = 5;
+ typeParam = 1;
+ }
+
+ if (typeParam) {
+ entry =
+ allocFrame2(header2.width * 2, header2.height,
+ header2.type);
+ } else {
+ if (header2.type == 1) {
+ entry =
+ allocFrame2(header2.width * 2,
+ header2.height, header2.type);
+ } else {
+ entry =
+ allocFrame2(header2.width * 2,
+ header2.height, header2.type);
+ }
+ }
+
+ ASSERT(entry != -1);
+
+ dataPtr = startOfDataPtr + header2.field_0;
+
+ if (typeParam) {
+ memcpy(animDataTable[entry].ptr1, table, 0x10);
+ gfxConvertSpriteToRaw(animDataTable[entry].ptr1,
+ dataPtr, header2.width, header2.height);
+ //memcpy(animDataTable[entry].ptr1+0x10,dataPtr,fullSize);
+ } else {
+ if (header2.type == 1) {
+ convert4BBP(animDataTable[entry].ptr1, dataPtr,
+ header2.width, header2.height);
+ } else if (header2.type == 5) {
+ convert8BBP(animDataTable[entry].ptr1, dataPtr,
+ header2.width, header2.height);
+ } else if (header2.type == 4) {
+ ASSERT(0);
+ } else {
+ convert8BBP2(animDataTable[entry].ptr1,
+ dataPtr, header2.width, header2.height);
+ }
+ }
+
+ animDataTable[entry].fileIdx = foundFileIdx;
+ animDataTable[entry].frameIdx = i;
+ strcpy(animDataTable[entry].name, currentPartName);
+ }
+}
+
+void loadSetAbs(char *resourceName, u16 idx) {
+ animHeader2Struct header2;
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+ u8 *ptr;
+ s16 i;
+ u32 fullSize;
+ u16 numSpriteInAnim;
+ u8 *startOfDataPtr;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ ASSERT(!memcmp(dataPtr, "SET", 3));
+
+ ptr = dataPtr + 4;
+
+ numSpriteInAnim = *(u16 *) ptr;
+ flipU16(&numSpriteInAnim);
+ ptr += 2;
+
+ startOfDataPtr = ptr + numSpriteInAnim * 0x10;
+
+ for (i = 0; i < numSpriteInAnim; i++) {
+ s16 typeParam;
+ u8 table[16] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+ memcpy(&header2, ptr, 0x10);
+ ptr += 0x10;
+
+ flipU32(&header2.field_0);
+ flipU16(&header2.width);
+ flipU16(&header2.height);
+ flipU16(&header2.type);
+
+ fullSize = header2.width * header2.height;
+
+ typeParam = 0;
+
+ if (header2.type == 5) {
+ fullSize += 16;
+ }
+
+ if (header2.type == 4) {
+ header2.type = 5;
+ typeParam = 1;
+ }
+
+ if (typeParam) {
+ entry =
+ reserveFrame(header2.width * 2, header2.height,
+ header2.type, idx + i);
+ } else {
+ if (header2.type == 1) {
+ entry =
+ reserveFrame(header2.width * 2,
+ header2.height, header2.type, idx + i);
+ } else {
+ entry =
+ reserveFrame(header2.width * 2,
+ header2.height, header2.type, idx + i);
+ }
+ }
+
+ ASSERT(entry != -1);
+
+ dataPtr = startOfDataPtr + header2.field_0;
+
+ if (typeParam) {
+ memcpy(animDataTable[entry].ptr1, table, 0x10);
+ gfxConvertSpriteToRaw(animDataTable[entry].ptr1,
+ dataPtr, header2.width, header2.height);
+ //memcpy(animDataTable[entry].ptr1+0x10,dataPtr,fullSize);
+ } else {
+ if (header2.type == 1) {
+ convert4BBP(animDataTable[entry].ptr1, dataPtr,
+ header2.width, header2.height);
+ } else if (header2.type == 5) {
+ convert8BBP(animDataTable[entry].ptr1, dataPtr,
+ header2.width, header2.height);
+ } else if (header2.type == 4) {
+ ASSERT(0);
+ } else {
+ convert8BBP2(animDataTable[entry].ptr1,
+ dataPtr, header2.width, header2.height);
+ }
+ }
+
+ animDataTable[entry].fileIdx = foundFileIdx;
+ animDataTable[entry].frameIdx = i;
+ strcpy(animDataTable[entry].name, currentPartName);
+ }
+}
+
+void loadSeq(char *resourceName) {
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ entry =
+ allocFrame2((u16) partBuffer[foundFileIdx].unpacked_size, 1, 0);
+
+ memcpy(animDataTable[entry].ptr1, dataPtr + 0x16,
+ (u16) partBuffer[foundFileIdx].unpacked_size - 0x16);
+}
+
+void loadSeqAbs(char *resourceName, u16 idx) {
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ s16 entry;
+
+ foundFileIdx = findFileInBundle(resourceName);
+ dataPtr = readBundleFile(foundFileIdx);
+
+ entry =
+ reserveFrame((u16) partBuffer[foundFileIdx].unpacked_size, 1, 0,
+ idx);
+
+ memcpy(animDataTable[entry].ptr1, dataPtr + 0x16,
+ (u16) partBuffer[foundFileIdx].unpacked_size - 0x16);
+}
+
+void loadResource(char *resourceName) {
+ u8 isMask = 0;
+ u8 isSpl = 0;
+
+ if (strstr(resourceName, ".SPL")) {
+ loadSpl(resourceName);
+
+ return;
+ } else if (strstr(resourceName, ".MSK")) {
+ loadMsk(resourceName);
+
+ return;
+ } else if (strstr(resourceName, ".ANI")) {
+ loadAni(resourceName);
+
+ return;
+ } else if (strstr(resourceName, ".ANM")) {
+ loadAni(resourceName);
+
+ return;
+ } else if (strstr(resourceName, ".SET")) {
+ loadSet(resourceName);
+
+ return;
+ } else if (strstr(resourceName, ".SEQ")) {
+ loadSeq(resourceName);
+
+ return;
+ }
+
+ ASSERT(0);
+}
+
+void loadAbs(char *resourceName, u16 idx) {
+ u8 isMask = 0;
+ u8 isSpl = 0;
+
+ if (strstr(resourceName, ".SET")) {
+ loadSetAbs(resourceName, idx);
+
+ return;
+ } else if (strstr(resourceName, ".H32")) {
+ return;
+ } else if (strstr(resourceName, ".SEQ")) {
+ loadSeqAbs(resourceName, idx);
+ return;
+ } else if (strstr(resourceName, ".SPL")) {
+ return;
+ } else if (strstr(resourceName, ".AMI")) {
+ return;
+ } else if (strstr(resourceName, ".ANI")) {
+ return;
+ }
+
+ ASSERT(0);
+}
+
+void loadResourcesFromSave() {
+ char part[256];
+ s16 currentAnim;
+
+ strcpy(part, currentPartName);
+
+ for (currentAnim = 0; currentAnim < NUM_MAX_ANIMDATA; currentAnim++) {
+ animDataStruct *currentPtr = &animDataTable[currentAnim];
+ if (currentPtr->ptr1 && currentPtr->fileIdx != -1) {
+ s8 isMask = 0;
+ s8 isSpl = 0;
+ s16 foundFileIdx;
+ u8 *dataPtr;
+ u8 *ptr;
+ char animName[256];
+
+ if (strcmp(currentPartName, currentPtr->name)) {
+ closePart();
+ loadPart(currentPtr->name);
+ }
+
+ foundFileIdx = currentPtr->fileIdx;
+
+ strcpy(animName, partBuffer[foundFileIdx].part_name);
+
+ if (strstr(animName, ".SPL")) {
+ isSpl = 1;
+ } else {
+ isSpl = 0;
+ }
+
+ dataPtr = readBundleFile(foundFileIdx);
+
+ ptr = dataPtr;
+
+ if (strstr(animName, ".MSK")) {
+ isMask = 1;
+ }
+
+ if (isSpl) {
+ animHeader.frameWidth =
+ (u16) partBuffer[foundFileIdx].
+ unpacked_size;
+ animHeader.frameHeight = 1;
+ animHeader.numFrames = 1;
+ isMask = -1;
+ } else {
+ memcpy(&animHeader, ptr,
+ sizeof(animHeaderStruct));
+ ptr += sizeof(animHeaderStruct);
+
+ flipU16(&animHeader.frameWidth);
+ flipU16(&animHeader.frameHeight);
+ flipU16(&animHeader.numFrames);
+ }
+
+ {
+ u16 fullSize;
+ u16 i;
+ u8 transparentColor;
+
+ fullSize =
+ animHeader.frameWidth *
+ animHeader.frameHeight;
+
+ loadRelatedPalette(animName);
+
+ transparentColor =
+ findAnimInHardcodedData(animName);
+
+ for (i = 0; i < animHeader.numFrames; i++) // load all the frames
+ {
+ s16 entry;
+ u8 *animPtr;
+
+ // special case transparency handling
+ if (!strcmp(animName, "L2202.ANI")) {
+ if (i < 2) {
+ transparentColor = 0;
+ } else {
+ transparentColor = 7;
+ }
+ }
+
+ if (!strcmp(animName, "L4601.ANI")) {
+ if (i < 1) {
+ transparentColor = 0xE;
+ } else {
+ transparentColor = 0;
+ }
+ }
+
+ currentPtr[i].ptr1 = NULL;
+ entry =
+ allocFrame(animHeader.frameWidth *
+ 2, animHeader.frameHeight, isMask);
+
+ currentPtr->fileIdx = foundFileIdx;
+
+ ASSERT(entry != -1);
+
+ if (isSpl) {
+ memcpy(animDataTable[entry].
+ ptr1, ptr, fullSize);
+ ptr += fullSize;
+ } else {
+ if (!isMask) {
+ animPtr =
+ (u8 *)
+ malloc(fullSize);
+
+ memcpy(animPtr, ptr,
+ fullSize);
+ ptr += fullSize;
+
+ gfxConvertSpriteToRaw
+ (animDataTable
+ [entry].ptr1,
+ animPtr,
+ animHeader.
+ frameWidth,
+ animHeader.
+ frameHeight);
+
+ generateMask
+ (animDataTable
+ [entry].ptr1,
+ animDataTable
+ [entry].ptr2,
+ animHeader.
+ frameWidth * 2 *
+ animHeader.
+ frameHeight,
+ transparentColor);
+
+ free(animPtr);
+ } else {
+ convertMask
+ (animDataTable
+ [entry].ptr1, ptr,
+ animHeader.
+ frameWidth,
+ animHeader.
+ frameHeight);
+ ptr += fullSize;
+ }
+ }
+
+ // animDataTable[entry].fileIdx = foundFileIdx; // Only when reading from bundles
+
+ animDataTable[entry].frameIdx = i;
+ strcpy(animDataTable[entry].name,
+ currentPartName);
+ }
+ }
+
+ }
+ }
+
+ loadPart(part);
+}
diff --git a/engines/cine/anim.h b/engines/cine/anim.h
new file mode 100644
index 0000000000..5b1bbef3ef
--- /dev/null
+++ b/engines/cine/anim.h
@@ -0,0 +1,66 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_ANIM_H_
+#define CINE_ANIM_H_
+
+extern u16 frameVar0;
+
+struct animHeaderStruct {
+ u8 field_0;
+ u8 field_1;
+ u8 field_2;
+ u8 field_3;
+ u16 frameWidth;
+ u16 frameHeight;
+ u8 field_8;
+ u8 field_9;
+ u8 field_A;
+ u8 field_B;
+ u8 field_C;
+ u8 field_D;
+ u16 numFrames;
+ u8 field_10;
+ u8 field_11;
+ u8 field_12;
+ u8 field_13;
+ u16 field_14;
+};
+
+typedef struct animHeaderStruct animHeaderStruct;
+
+struct animDataEntry {
+ char name[9];
+ u8 param;
+};
+
+typedef struct animDataEntry animDataEntry;
+
+extern animDataEntry animData[];
+
+void loadResource(char *animName);
+void loadAbs(char *resourceName, u16 idx);
+void loadResourcesFromSave();
+
+#endif
diff --git a/engines/cine/auto00.cpp b/engines/cine/auto00.cpp
new file mode 100644
index 0000000000..f44185cd40
--- /dev/null
+++ b/engines/cine/auto00.cpp
@@ -0,0 +1,49 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+unsigned char AUT000[] = {
+ 0x00, 0x32, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x6b, 0x6c, 0x01, 0x40,
+ 0x50, 0x41, 0x52, 0x54,
+ 0x30, 0x31, 0x00, 0x42, 0x00, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x2e, 0x50,
+ 0x52, 0x43, 0x00, 0x42,
+ 0x02, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x2e, 0x4f, 0x42, 0x4a, 0x00, 0x3d,
+ 0x4c, 0x4f, 0x47, 0x4f,
+ 0x2e, 0x50, 0x49, 0x31, 0x00, 0x46, 0x50, 0x6e, 0x44, 0x55, 0x47, 0x47,
+ 0x45, 0x52, 0x2e, 0x44,
+ 0x41, 0x54, 0x00, 0x3d, 0x43, 0x49, 0x4e, 0x45, 0x4d, 0x41, 0x2e, 0x50,
+ 0x49, 0x31, 0x00, 0x47,
+ 0x46, 0x6f, 0x43, 0x51, 0x00, 0x1e, 0x1e, 0x43, 0x51, 0x00,
+};
diff --git a/engines/cine/auto00.h b/engines/cine/auto00.h
new file mode 100644
index 0000000000..a240240d78
--- /dev/null
+++ b/engines/cine/auto00.h
@@ -0,0 +1,32 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_AUTO00_H_
+#define CINE_AUTO00_H_
+
+extern unsigned char AUT000[];
+
+#define AUT000_size sizeof(AUT000);
+
+#endif
diff --git a/engines/cine/bg.cpp b/engines/cine/bg.cpp
new file mode 100644
index 0000000000..8dc72ed38e
--- /dev/null
+++ b/engines/cine/bg.cpp
@@ -0,0 +1,154 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+u16 bgVar0;
+
+void loadCtHigh(u8 * currentPtr) {
+ currentPtr += 256 * 3;
+
+ memcpy(page3Raw, currentPtr, 320 * 200);
+}
+
+u8 loadCt(const char *ctName) {
+ u8 *ptr;
+ u8 *currentPtr;
+ u8 i;
+ u16 header[0x20];
+
+ ///
+
+ strcpy(currentCtName, ctName);
+
+ currentPtr = ptr = readBundleFile(findFileInBundle(ctName));
+
+ if (gameType == Cine::GID_OS) {
+ if (*(u16 *) currentPtr == 0x800) // detect 256 color background
+ {
+ loadCtHigh(currentPtr + 2);
+ return 0;
+ }
+
+ currentPtr += 2;
+
+ currentPtr += 0x20;
+ gfxResetRawPage(page3Raw);
+ gfxConvertSpriteToRaw(page3Raw, ptr + 0x22, 160, 200);
+ } else {
+ loadRelatedPalette(ctName);
+
+ ASSERT(strstr(ctName, ".NEO"));
+
+ memcpy(header, currentPtr, 0x20);
+ currentPtr += 0x20;
+
+ for (i = 0; i < 0x20; i++) {
+ flipU16(&header[i]);
+ }
+
+ gfxConvertSpriteToRaw(page3Raw, ptr + 0x80, 160, 200);
+ }
+
+ return 0;
+}
+
+void loadBgHigh(char *currentPtr) {
+ memcpy(palette256, currentPtr, 256 * 3);
+ currentPtr += 256 * 3;
+
+ memcpy(page2Raw, currentPtr, 320 * 200);
+
+ colorMode256 = 1;
+}
+
+u8 loadBg(const char *bgName) {
+ u8 *ptr;
+ u8 *currentPtr;
+ u8 i;
+ u8 fileIdx;
+
+ strcpy(currentBgName[0], bgName);
+
+ fileIdx = findFileInBundle(bgName);
+
+ currentPtr = ptr = readBundleFile(fileIdx);
+
+ if (*(u16 *) currentPtr == 0x800) // detect 256 color background
+ {
+ loadBgHigh((char *)currentPtr + 2);
+ return 0;
+ }
+
+ colorMode256 = 0;
+
+ memcpy(&dummyU16, currentPtr, 2);
+ currentPtr += 2;
+
+ memcpy(tempPalette, currentPtr, 32);
+ currentPtr += 0x20;
+
+ for (i = 0; i < 16; i++) {
+ flipU16(&tempPalette[i]);
+ }
+
+ loadRelatedPalette(bgName);
+
+ gfxResetRawPage(page2Raw);
+ gfxConvertSpriteToRaw(page2Raw, ptr + 0x22, 160, 200);
+
+ return 0;
+}
+
+u8 *additionalBgTable[9] =
+ { page2Raw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, page3Raw };
+u8 currentAdditionalBgIdx = 0;
+u8 currentAdditionalBgIdx2 = 0;
+
+void addBackground(char *bgName, u16 bgIdx) {
+ u8 *ptr;
+ u8 *currentPtr;
+ u8 fileIdx;
+
+ strcpy(currentBgName[bgIdx], bgName);
+
+ fileIdx = findFileInBundle(bgName);
+
+ currentPtr = ptr = readBundleFile(fileIdx);
+
+ additionalBgTable[bgIdx] = (u8 *) malloc(320 * 200);
+
+ if (*(u16 *) currentPtr == 0x800) // detect 256 color background
+ {
+ memcpy(additionalBgTable[bgIdx], currentPtr + 2 + 3 * 256,
+ 320 * 200);
+ return;
+ }
+
+ currentPtr += 2;
+
+ currentPtr += 0x20;
+
+ gfxConvertSpriteToRaw(additionalBgTable[bgIdx], ptr + 0x22, 160, 200);
+}
diff --git a/engines/cine/bg.h b/engines/cine/bg.h
new file mode 100644
index 0000000000..26947131e2
--- /dev/null
+++ b/engines/cine/bg.h
@@ -0,0 +1,39 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_BG_H_
+#define CINE_BG_H_
+
+u8 loadBg(const char *bgName);
+u8 loadCt(const char *bgName);
+
+extern u8 *additionalBgTable[9];
+extern u8 currentAdditionalBgIdx;
+extern u8 currentAdditionalBgIdx2;
+
+void addBackground(char *bgName, u16 bgIdx);
+
+extern u16 bgVar0;
+
+#endif
diff --git a/engines/cine/bg_list.cpp b/engines/cine/bg_list.cpp
new file mode 100644
index 0000000000..1d3dab6cb1
--- /dev/null
+++ b/engines/cine/bg_list.cpp
@@ -0,0 +1,47 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+void createVar9Element(s16 objIdx, s16 param);
+
+void addSpriteFilledToBGList(s16 idx) {
+ s16 x;
+ s16 y;
+ s16 width;
+ s16 height;
+
+ x = objectTable[idx].x;
+ y = objectTable[idx].y;
+
+ width = animDataTable[objectTable[idx].frame].width;
+ height = animDataTable[objectTable[idx].frame].var2;
+
+ if (animDataTable[objectTable[idx].frame].ptr1) {
+ gfxFillSprite(animDataTable[objectTable[idx].frame].ptr1,
+ width / 2, height, page2Raw, x, y);
+ }
+
+ createVar9Element(idx, 1);
+}
diff --git a/engines/cine/bg_list.h b/engines/cine/bg_list.h
new file mode 100644
index 0000000000..9724d492ce
--- /dev/null
+++ b/engines/cine/bg_list.h
@@ -0,0 +1,30 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_BGLIST_H_
+#define CINE_BGLIST_H_
+
+void addSpriteFilledToBGList(s16 idx);
+
+#endif
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
new file mode 100644
index 0000000000..c941690dd2
--- /dev/null
+++ b/engines/cine/cine.cpp
@@ -0,0 +1,256 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/config-manager.h"
+
+#include "base/gameDetector.h"
+#include "base/plugins.h"
+
+#include "backends/fs/fs.h"
+
+#include "sound/mididrv.h"
+#include "sound/mixer.h"
+
+#include "cine/cine.h"
+#include "cine/sound_driver.h"
+
+Audio::Mixer * cine_g_mixer;
+AdlibMusic *g_cine_adlib;
+
+static void initialize();
+
+char *savePath;
+
+struct CINEGameSettings {
+ const char *name;
+ const char *description;
+ byte id;
+ uint32 features;
+ const char *detectname;
+ GameSettings toGameSettings() const {
+ GameSettings dummy = { name, description };
+ return dummy;
+ }
+};
+
+static const CINEGameSettings cine_settings[] = {
+ {"fw", "Future Wars", Cine::GID_FW, MDT_ADLIB, "AUTO00.PRC"},
+ {"os", "Operation Stealth", Cine::GID_OS, MDT_ADLIB, "PROCS00"},
+ {NULL, NULL, 0, 0, NULL}
+};
+
+// Keep list of different supported games
+static const GameSettings cine_list[] = {
+ {"fw", "Future Wars"},
+ {"os", "Operation Stealth"},
+ {0, 0}
+};
+
+GameList Engine_CINE_gameIDList() {
+ GameList games;
+ const GameSettings *g = cine_list;
+
+ while (g->gameid) {
+ games.push_back(*g);
+ g++;
+ }
+
+ return games;
+}
+
+GameSettings Engine_CINE_findGameID(const char *gameid) {
+ const GameSettings *g = cine_list;
+ while (g->gameid) {
+ if (0 == strcmp(gameid, g->gameid))
+ break;
+ g++;
+ }
+ return *g;
+}
+
+DetectedGameList Engine_CINE_detectGames(const FSList &fslist) {
+ DetectedGameList detectedGames;
+ const CINEGameSettings *g;
+
+ for (g = cine_settings; g->name; ++g) {
+ // Iterate over all files in the given directory
+ for (FSList::const_iterator file = fslist.begin();
+ file != fslist.end(); ++file) {
+ const char *gameName = file->displayName().c_str();
+
+ if (0 == scumm_stricmp(g->detectname, gameName)) {
+ // Match found, add to list of candidates, then abort inner loop.
+ detectedGames.push_back(g->toGameSettings());
+ break;
+ }
+ }
+ }
+ return detectedGames;
+}
+
+Engine *Engine_CINE_create(GameDetector *detector, OSystem *syst) {
+ return new Cine::CineEngine(detector, syst);
+}
+
+REGISTER_PLUGIN(CINE, "CINE Engine")
+
+namespace Cine {
+
+CineEngine::CineEngine(GameDetector *detector, OSystem *syst) : Engine(syst) {
+
+ // Setup mixer
+ if (!_mixer->isReady()) {
+ warning("Sound initialization failed.");
+ }
+
+ cine_g_mixer = _mixer;
+ _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType,
+ ConfMan.getInt("sfx_volume"));
+ _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType,
+ ConfMan.getInt("music_volume"));
+
+ _dataPath = getGameDataPath();
+ _savePath = _saveFileMan->getSavePath();
+
+ Common::File::addDefaultDirectory(_gameDataPath);
+
+ const CINEGameSettings *g;
+
+ for (g = cine_settings; g->name; ++g)
+ if (!scumm_stricmp(g->name, detector->_targetName.c_str()))
+ _gameId = g->id;
+
+ gameType = _gameId;
+}
+
+CineEngine::~CineEngine() {
+}
+
+void CineEngine::errorString(const char *buf1, char *buf2) {
+ strcpy(buf2, buf1);
+}
+
+int CineEngine::init(GameDetector &detector) {
+ // Initialize backend
+ _system->beginGFXTransaction();
+ initCommonGFX(detector, false);
+ _system->initSize(320, 200);
+ _system->endGFXTransaction();
+
+ g_cine_adlib = new AdlibMusic(_mixer);
+
+ initialize();
+
+ return 0;
+}
+
+int CineEngine::go() {
+ _system->showMouse(true);
+
+ mainLoop(1);
+
+ if (gameType == Cine::GID_FW)
+ snd_clearBasesonEntries();
+
+ delete g_cine_adlib;
+
+ return 0;
+}
+
+ }
+
+int gameType;
+
+static void initialize() {
+ u16 i;
+
+ init_video();
+
+ textDataPtr = (u8 *) malloc(8000);
+
+ partBuffer = (partBufferStruct *) malloc(255 * sizeof(animDataStruct));
+
+ loadTextData("texte.dat", textDataPtr);
+ snd_loadBasesonEntries("BASESON.SND");
+
+ for (i = 0; i < NUM_MAX_OBJECT; i++) {
+ objectTable[i].part = 0;
+ objectTable[i].name[0] = 0;
+ }
+
+ for (i = 0; i < NUM_MAX_OBJECTDATA; i++) {
+ globalVars[i] = 0;
+ }
+
+ globalVars[255] = 1;
+
+ for (i = 0; i < NUM_MAX_SCRIPT; i++) {
+ scriptTable[i].ptr = NULL;
+ scriptTable[i].var4 = 0;
+ }
+
+ for (i = 0; i < NUM_MAX_MESSAGE; i++) {
+ messageTable[i].ptr = NULL;
+ messageTable[i].len = 0;
+ }
+
+ for (i = 0; i < NUM_MAX_REL; i++) {
+ relTable[i].ptr0 = NULL;
+ relTable[i].var4 = 0;
+ relTable[i].var6 = 0;
+ relTable[i].var8 = 0;
+ }
+
+ for (i = 0; i < NUM_MAX_PARTDATA; i++) {
+ animDataTable[i].ptr1 = NULL;
+ animDataTable[i].ptr2 = NULL;
+ }
+
+ overlayHead.next = NULL;
+ overlayHead.previous = NULL;
+
+ var8 = 0;
+ var9 = NULL;
+
+ objScriptList.next = NULL;
+ globalScriptsHead.next = NULL;
+
+ objScriptList.scriptPtr = NULL;
+ globalScriptsHead.scriptPtr = NULL;
+
+ var2 = 0;
+ var3 = 0;
+ var4 = 0;
+ var5 = 0;
+
+ freePrcLinkedList();
+
+ loadPrc(BOOT_PRC_NAME);
+ strcpy(currentPrcName, BOOT_PRC_NAME);
+
+ processPendingUpdates(0);
+}
diff --git a/engines/cine/cine.h b/engines/cine/cine.h
new file mode 100644
index 0000000000..29c77ec8dd
--- /dev/null
+++ b/engines/cine/cine.h
@@ -0,0 +1,109 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_H
+#define CINE_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/util.h"
+#include "common/file.h"
+#include "common/savefile.h"
+#include "common/system.h"
+
+#include "base/engine.h"
+#include "base/gameDetector.h"
+
+namespace Cine {
+
+enum CineGameId {
+ GID_FW = 1,
+ GID_OS
+};
+
+class CineEngine : public ::Engine {
+ int _gameId;
+
+ void errorString(const char *buf_input, char *buf_output);
+
+protected:
+ int init(GameDetector & detector);
+ int go();
+ void shutdown();
+
+ const char *_dataPath;
+ const char *_savePath;
+
+public:
+ CineEngine(GameDetector *detector, OSystem *syst);
+ virtual ~CineEngine();
+ int getGameId() {
+ return _gameId;
+ }
+};
+
+}
+
+extern char *savePath;
+
+typedef unsigned char u8;
+typedef unsigned short int u16;
+typedef unsigned long int u32;
+
+typedef signed char s8;
+typedef signed short int s16;
+typedef signed long int s32;
+
+#define ASSERT_PTR assert
+#define ASSERT assert
+
+#pragma pack(1)
+
+#define BOOT_PRC_NAME "AUTO00.PRC"
+
+#include "cine/font.h"
+#include "cine/various.h"
+#include "cine/flip_support.h"
+#include "cine/texte.h"
+#include "cine/object.h"
+#include "cine/rel.h"
+#include "cine/script.h"
+#include "cine/part.h"
+#include "cine/prc.h"
+#include "cine/main_loop.h"
+#include "cine/resource.h"
+#include "cine/msg.h"
+#include "cine/bg.h"
+#include "cine/pal.h"
+#include "cine/gfx.h"
+#include "cine/anim.h"
+#include "cine/auto00.h"
+#include "cine/unpack.h"
+#include "cine/bg_list.h"
+#include "cine/sfx_player.h"
+#include "cine/sound_driver.h"
+
+extern AdlibMusic *g_cine_adlib;
+
+#endif
diff --git a/engines/cine/flip_support.cpp b/engines/cine/flip_support.cpp
new file mode 100644
index 0000000000..decd04d057
--- /dev/null
+++ b/engines/cine/flip_support.cpp
@@ -0,0 +1,57 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+void flipU16(u16 * pVar) {
+ *pVar = (((*pVar) & 0xFF) << 8) | (((*pVar) & 0xFF00) >> 8);
+}
+
+void flipU32(u32 * pVar) {
+ u16 part1;
+ u16 part2;
+
+ part1 = (u16) ((*pVar) & 0xFFFF);
+ part2 = (u16) (((*pVar) & 0xFFFF0000) >> 16);
+
+ flipU16(&part1);
+ flipU16(&part2);
+
+ *pVar = (part2) | ((u32) part1 << 16);
+}
+
+u16 readU16LE(const void *ptr) {
+ const u8 *b = (const u8 *)ptr;
+ return (b[1] << 8) | b[0];
+}
+
+u16 readU16BE(const void *ptr) {
+ const u8 *b = (const u8 *)ptr;
+ return (b[0] << 8) | b[1];
+}
+
+u32 readU32BE(const void *ptr) {
+ const u8 *b = (const u8 *)ptr;
+ return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
+}
diff --git a/engines/cine/flip_support.h b/engines/cine/flip_support.h
new file mode 100644
index 0000000000..6f8e86b218
--- /dev/null
+++ b/engines/cine/flip_support.h
@@ -0,0 +1,34 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_FLIPSUPPORT_H_
+#define CINE_FLIPSUPPORT_H_
+
+void flipU16(u16 *);
+void flipU32(u32 *);
+u16 readU16LE(const void *ptr);
+u16 readU16BE(const void *ptr);
+u32 readU32BE(const void *ptr);
+
+#endif
diff --git a/engines/cine/font.cpp b/engines/cine/font.cpp
new file mode 100644
index 0000000000..84cc39e0da
--- /dev/null
+++ b/engines/cine/font.cpp
@@ -0,0 +1,62 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+characterEntry fontParamTable[256] = {
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, {63, 1}, {69, 5}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, {68, 3},
+ {64, 3}, {65, 3}, { 0, 0}, { 0, 0}, {62, 2}, {74, 6}, {66, 1}, {67, 6},
+ {52, 6}, {53, 6}, {54, 6}, {55, 6}, {56, 6}, {57, 6}, {58, 6}, {59, 6},
+ {60, 6}, {61, 6}, {76, 3}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, {75, 6},
+ { 0, 0}, { 0, 6}, //a
+ { 1, 6}, { 2, 6}, { 3, 6}, { 4, 6}, { 5, 6}, { 6, 6},
+ { 7, 6}, { 8, 3}, { 9, 6}, {10, 6}, {11, 6}, {12, 7}, {13, 6}, {14, 6},
+ {15, 6}, {16, 6}, {17, 6}, {18, 6}, {19, 6}, {20, 6}, {21, 6}, {22, 7},
+ {23, 6}, {24, 6}, {25, 6}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, {26, 6}, //a
+ {27, 6}, {28, 5}, {29, 6}, {30, 6}, {31, 5}, {32, 6},
+ {33, 6}, {34, 4}, {35, 4}, {36, 5}, {37, 3}, {38, 7}, {39, 6}, {40, 6},
+ {41, 6}, {42, 6}, {43, 6}, {44, 6}, {45, 6}, {46, 6}, {47, 6}, {48, 7},
+ {49, 6}, {50, 6}, {51, 6}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, {70, 6}, { 0, 0}, { 0, 0}, {72, 6}, { 0, 0}, {73, 5},
+ {77, 6}, { 0, 0}, {71, 6}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, {77, 6},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
+ { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}
+};
diff --git a/engines/cine/font.h b/engines/cine/font.h
new file mode 100644
index 0000000000..2228779aa2
--- /dev/null
+++ b/engines/cine/font.h
@@ -0,0 +1,37 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_FONT_H_
+#define CINE_FONT_H_
+
+struct characterEntry {
+ u8 characterIdx;
+ u8 characterWidth;
+};
+
+typedef struct characterEntry characterEntry;
+
+extern characterEntry fontParamTable[256];
+
+#endif
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
new file mode 100644
index 0000000000..6536964516
--- /dev/null
+++ b/engines/cine/gfx.cpp
@@ -0,0 +1,386 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+byte *screenBuffer;
+
+u16 c_palette[256];
+
+unsigned char *page0;
+unsigned char *page1;
+unsigned char *page2;
+unsigned char *page3;
+
+u8 page1Raw[320 * 200];
+u8 page2Raw[320 * 200];
+u8 page3Raw[320 * 200];
+
+void init_video() {
+ screenBuffer = (byte *) malloc(320 * 200 * 3);
+ assert(screenBuffer);
+
+ page0 = (unsigned char *)malloc(0x8000);
+ page1 = (unsigned char *)malloc(0x8000);
+ page2 = (unsigned char *)malloc(0x8000);
+ page3 = (unsigned char *)malloc(0x8000);
+}
+
+u16 transformColor(u16 baseColor, s8 r, s8 g, s8 b) {
+ s8 oriR = (baseColor & 0x7);
+ s8 oriG = (baseColor & 0x70) >> 4;
+ s8 oriB = (baseColor & 0x700) >> 8;
+
+ oriR += r;
+ oriG += g;
+ oriB += b;
+
+ if (oriR < 0)
+ oriR = 0;
+
+ if (oriR > 7)
+ oriR = 7;
+
+ if (oriG < 0)
+ oriG = 0;
+
+ if (oriG > 7)
+ oriG = 7;
+
+ if (oriB < 0)
+ oriB = 0;
+
+ if (oriB > 7)
+ oriB = 7;
+
+ return (oriR | (oriG << 4) | (oriB << 8));
+}
+
+void transformPaletteRange(u8 startColor, u8 stopColor, s8 r, s8 g, s8 b) {
+ u8 i;
+
+ for (i = startColor; i <= stopColor; i++) {
+ c_palette[i] = transformColor(tempPalette[i], b, g, r);
+ }
+ //gfxFlipPage(page2);
+}
+
+void gfxFillSprite(u8 *spritePtr, u16 width, u16 height, u8 *page, s16 x, s16 y) {
+ s16 i;
+ s16 j;
+
+ for (i = 0; i < height; i++) {
+ u8 *destPtr = page + x + y * 320;
+ destPtr += i * 320;
+
+ for (j = 0; j < width * 8; j++) {
+ if (x + j >= 0 && x + j < 320 && i + y >= 0
+ && i + y < 200) {
+ if (!*(spritePtr++)) {
+ *(destPtr++) = 0;
+ } else {
+ destPtr++;
+ }
+ } else {
+ destPtr++;
+ spritePtr++;
+ }
+ }
+ }
+}
+
+void gfxDrawLine(s16 x1, s16 y1, s16 x2, s16 y2, u8 color, u8 *page) {
+ s16 t;
+ if (x1 == x2) {
+ if (y1 > y2) {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ while (y1 <= y2) {
+ *(page + (y1 * 320 + x1)) = color;
+ y1++;
+ }
+ } else {
+ if (x1 > x2) {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ while (x1 <= x2) {
+ *(page + (y1 * 320 + x1)) = color;
+ x1++;
+ }
+ }
+
+}
+
+void gfxDrawPlainBoxRaw(s16 x1, s16 y1, s16 x2, s16 y2, u8 color, u8 *page) {
+ s16 t;
+
+ if (x1 > x2) {
+ t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+
+ if (y1 > y2) {
+ t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+
+ t = x1;
+ while (y1 <= y2) {
+ x1 = t;
+ while (x1 <= x2) {
+ *(page + y1 * 320 + x1) = color;
+ x1++;
+ }
+ y1++;
+ }
+}
+
+s16 gfxGetBit(s16 x, s16 y, u8 *ptr, s16 width) {
+ u8 *ptrToData = (ptr) + y * width + x;
+
+ if (x > width) {
+ return 0;
+ }
+
+ if (*ptrToData) {
+ return 0;
+ }
+
+ return (1);
+}
+
+void gfxResetRawPage(u8 *pageRaw) {
+ memset(pageRaw, 0, 320 * 200);
+}
+
+void gfxConvertSpriteToRaw(u8 *dest, u8 *source, u16 width, u16 height) {
+ int x, y;
+ u8 b1, b2, b3, b4, b5, b6, b7, b8, d1a, d1b, d2a, d2b, d3a, d3b, d4a,
+ d4b;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < (width >> 3); x++) {
+ b4 = *(source++);
+ b8 = *(source++);
+ b3 = *(source++);
+ b7 = *(source++);
+ b2 = *(source++);
+ b6 = *(source++);
+ b1 = *(source++);
+ b5 = *(source++);
+
+ d1a = d1b = d2a = d2b = d3a = d3b = d4a = d4b = 0;
+
+ d1a |=
+ (((b4 & 1) >> 0) | ((b3 & 1) << 1) | ((b2 & 1) <<
+ 2) | ((b1 & 1) << 3)) << 0;
+ d1b |=
+ (((b4 & 2) >> 1) | ((b3 & 2) >> 0) | ((b2 & 2) <<
+ 1) | ((b1 & 2) << 2)) << 0;
+ d2a |=
+ (((b4 & 4) >> 2) | ((b3 & 4) >> 1) | ((b2 & 4) >>
+ 0) | ((b1 & 4) << 1)) << 0;
+ d2b |=
+ (((b4 & 8) >> 3) | ((b3 & 8) >> 2) | ((b2 & 8) >>
+ 1) | ((b1 & 8) >> 0)) << 0;
+
+ b1 >>= 4;
+ b2 >>= 4;
+ b3 >>= 4;
+ b4 >>= 4;
+
+ d3a |=
+ (((b4 & 1) >> 0) | ((b3 & 1) << 1) | ((b2 & 1) <<
+ 2) | ((b1 & 1) << 3)) << 0;
+ d3b |=
+ (((b4 & 2) >> 1) | ((b3 & 2) >> 0) | ((b2 & 2) <<
+ 1) | ((b1 & 2) << 2)) << 0;
+ d4a |=
+ (((b4 & 4) >> 2) | ((b3 & 4) >> 1) | ((b2 & 4) >>
+ 0) | ((b1 & 4) << 1)) << 0;
+ d4b |=
+ (((b4 & 8) >> 3) | ((b3 & 8) >> 2) | ((b2 & 8) >>
+ 1) | ((b1 & 8) >> 0)) << 0;
+
+ *(dest++) = d4b;
+ *(dest++) = d4a;
+ *(dest++) = d3b;
+ *(dest++) = d3a;
+ *(dest++) = d2b;
+ *(dest++) = d2a;
+ *(dest++) = d1b;
+ *(dest++) = d1a;
+
+ b1 = b5;
+ b2 = b6;
+ b3 = b7;
+ b4 = b8;
+
+ d1a = d1b = d2a = d2b = d3a = d3b = d4a = d4b = 0;
+
+ d1a |=
+ (((b4 & 1) >> 0) | ((b3 & 1) << 1) | ((b2 & 1) <<
+ 2) | ((b1 & 1) << 3)) << 0;
+ d1b |=
+ (((b4 & 2) >> 1) | ((b3 & 2) >> 0) | ((b2 & 2) <<
+ 1) | ((b1 & 2) << 2)) << 0;
+ d2a |=
+ (((b4 & 4) >> 2) | ((b3 & 4) >> 1) | ((b2 & 4) >>
+ 0) | ((b1 & 4) << 1)) << 0;
+ d2b |=
+ (((b4 & 8) >> 3) | ((b3 & 8) >> 2) | ((b2 & 8) >>
+ 1) | ((b1 & 8) >> 0)) << 0;
+
+ b1 >>= 4;
+ b2 >>= 4;
+ b3 >>= 4;
+ b4 >>= 4;
+
+ d3a |=
+ (((b4 & 1) >> 0) | ((b3 & 1) << 1) | ((b2 & 1) <<
+ 2) | ((b1 & 1) << 3)) << 0;
+ d3b |=
+ (((b4 & 2) >> 1) | ((b3 & 2) >> 0) | ((b2 & 2) <<
+ 1) | ((b1 & 2) << 2)) << 0;
+ d4a |=
+ (((b4 & 4) >> 2) | ((b3 & 4) >> 1) | ((b2 & 4) >>
+ 0) | ((b1 & 4) << 1)) << 0;
+ d4b |=
+ (((b4 & 8) >> 3) | ((b3 & 8) >> 2) | ((b2 & 8) >>
+ 1) | ((b1 & 8) >> 0)) << 0;
+
+ *(dest++) = d4b;
+ *(dest++) = d4a;
+ *(dest++) = d3b;
+ *(dest++) = d3a;
+ *(dest++) = d2b;
+ *(dest++) = d2a;
+ *(dest++) = d1b;
+ *(dest++) = d1a;
+
+ }
+ }
+}
+
+void gfxCopyRawPage(u8 *source, u8 *dest) {
+ memcpy(dest, source, 320 * 200);
+}
+
+void gfxFlipRawPage(u8 *frontBuffer) {
+ u8 *page = frontBuffer;
+ int x, y;
+ u8 *pixels = (u8 *) screenBuffer;
+ byte c;
+
+ for (y = 0; y < 200; y++) {
+ for (x = 0; x < 320; x++) {
+ c = *(page++);
+
+ if (!colorMode256) {
+ c = c & 15;
+ }
+
+ pixels[x + 0 + y * 320] = c;
+ }
+ }
+
+ byte pal[256 * 4];
+ int i;
+
+ if (colorMode256) {
+ for (i = 0; i < 256; i++) {
+ pal[i * 4 + 0] = palette256[i * 3 + 0];
+ pal[i * 4 + 1] = palette256[i * 3 + 1];
+ pal[i * 4 + 2] = palette256[i * 3 + 2];
+ pal[i * 4 + 3] = 0;
+ }
+ g_system->setPalette(pal, 0, 256);
+ } else {
+ for (i = 0; i < 16; i++) {
+ pal[i * 4 + 2] =
+ ((c_palette[i] & 0x00f) >> 0) * 255 / 7;
+ pal[i * 4 + 1] =
+ ((c_palette[i] & 0x0f0) >> 4) * 255 / 7;
+ pal[i * 4 + 0] =
+ ((c_palette[i] & 0xf00) >> 8) * 255 / 7;
+ pal[i * 4 + 3] = 0;
+ }
+ g_system->setPalette(pal, 0, 16);
+ }
+
+ g_system->copyRectToScreen(screenBuffer, 320, 0, 0, 320, 200);
+ g_system->updateScreen();
+ g_system->delayMillis(100);
+}
+
+void drawSpriteRaw(u8 *spritePtr, u8 *maskPtr, s16 width, s16 height,
+ u8 *page, s16 x, s16 y) {
+ s16 i;
+ s16 j;
+
+ for (i = 0; i < height; i++) {
+ u8 *destPtr = page + x + y * 320;
+ destPtr += i * 320;
+
+ for (j = 0; j < width * 8; j++) {
+ if (((gameType == Cine::GID_FW && !(*maskPtr))
+ || (gameType == Cine::GID_OS)) && (x + j >= 0
+ && x + j < 320 && i + y >= 0 && i + y < 200)) {
+ *(destPtr++) = *(spritePtr++);
+ } else {
+ destPtr++;
+ spritePtr++;
+ }
+
+ maskPtr++;
+ }
+ }
+}
+
+void drawSpriteRaw2(u8 *spritePtr, u8 transColor, s16 width, s16 height,
+ u8 *page, s16 x, s16 y) {
+ s16 i;
+ s16 j;
+
+ for (i = 0; i < height; i++) {
+ u8 *destPtr = page + x + y * 320;
+ destPtr += i * 320;
+
+ for (j = 0; j < width * 8; j++) {
+ if ((*(spritePtr) != transColor) && (x + j >= 0
+ && x + j < 320 && i + y >= 0 && i + y < 200)) {
+ *(destPtr++) = *(spritePtr++);
+ } else {
+ destPtr++;
+ spritePtr++;
+ }
+ }
+ }
+}
diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h
new file mode 100644
index 0000000000..2b465b24a5
--- /dev/null
+++ b/engines/cine/gfx.h
@@ -0,0 +1,71 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_GFX_H_
+#define CINE_GFX_H_
+
+void gfxDrawSprite(u8 *src4, u16 sw, u16 sh, u8 *dst4, s16 sx, s16 sy);
+
+extern unsigned char *page0;
+extern unsigned char *page1;
+extern unsigned char *page2;
+extern unsigned char *page3;
+
+void init_video();
+
+void convertGfx(u8 *source, u8 *dest, const u16 width, const u16 height);
+void convertGfx2(u8 *source, u8 *dest, const u16 width, const u16 height);
+void gfxCopyPage(u8 *source, u8 *dest);
+
+void transformPaletteRange(u8 startColor, u8 numColor, s8 r, s8 g, s8 b);
+void gfxFlipPage(void);
+
+void gfxSpriteFunc1(u8 *ptr, u16 width, u16 height, u8 *page, s16 x, s16 y);
+void gfxFillSprite(u8 *src4, u16 sw, u16 sh, u8 *dst4, s16 sx, s16 sy);
+
+void gfxSpriteFunc2(u8 *spritePtr, s16 width, s16 height, u8 *maskPtr,
+ s16 maskWidth, s16 maskHeight, u8 *bufferPtr, s16 x, s16 y, u8 maskIdx);
+
+void gfxDrawLine(s16 x1, s16 y1, s16 x2, s16 y2, u8 color, u8 *page);
+void gfxDrawPlainBox(s16 x1, s16 y1, s16 x2, s16 y2, u8 color);
+
+void gfxResetPage(u8 *pagePtr);
+
+s16 gfxGetBit(s16 x, s16 y, u8 *ptr, s16 width);
+
+extern u8 page1Raw[320 * 200];
+extern u8 page2Raw[320 * 200];
+extern u8 page3Raw[320 * 200];
+
+void gfxResetRawPage(u8 *pageRaw);
+void gfxConvertSpriteToRaw(u8 *dest, u8 *source, u16 width, u16 height);
+void gfxCopyRawPage(u8 *source, u8 * dest);
+void gfxFlipRawPage(u8 *frontBuffer);
+void drawSpriteRaw(u8 *spritePtr, u8 *maskPtr, s16 width, s16 height,
+ u8 *page, s16 x, s16 y);
+void gfxDrawPlainBoxRaw(s16 x1, s16 y1, s16 x2, s16 y2, u8 color, u8 *page);
+void drawSpriteRaw2(u8 *spritePtr, u8 transColor, s16 width, s16 height,
+ u8 *page, s16 x, s16 y);
+
+#endif
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
new file mode 100644
index 0000000000..7d3b98038f
--- /dev/null
+++ b/engines/cine/main_loop.cpp
@@ -0,0 +1,232 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+mouseStatusStruct mouseData;
+
+u16 mouseRight = 0;
+u16 mouseLeft = 0;
+
+u16 mouseUpdateStatus;
+u16 dummyU16;
+
+void manageEvents(void) {
+ OSystem::Event event;
+
+ while (g_system->pollEvent(event)) {
+ switch (event.type) {
+ case OSystem::EVENT_LBUTTONDOWN:
+ mouseLeft = 1;
+ break;
+ case OSystem::EVENT_RBUTTONDOWN:
+ mouseRight = 1;
+ break;
+ case OSystem::EVENT_MOUSEMOVE:
+ mouseData.X = event.mouse.x;
+ mouseData.Y = event.mouse.y;
+ break;
+ case OSystem::EVENT_QUIT:
+ exit(0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ mouseData.left = mouseLeft;
+ mouseData.right = mouseRight;
+
+ mouseLeft = 0;
+ mouseRight = 0;
+}
+
+void getMouseData(u16 param, u16 *pButton, u16 *pX, u16 *pY) {
+ *pX = mouseData.X;
+ *pY = mouseData.Y;
+
+ *pButton = 0;
+
+ if (mouseData.right) {
+ (*pButton) |= 2;
+ }
+
+ if (mouseData.left) {
+ (*pButton) |= 1;
+ }
+}
+
+void mainLoop(int bootScriptIdx) {
+ u16 var_6;
+ u16 var_2;
+ u16 i;
+ char *di;
+ u16 mouseButton;
+
+ closeEngine3();
+ resetMessageHead();
+ resetUnkList();
+ resetglobalScriptsHead();
+ resetObjectScriptHead();
+ mainLoopSub1();
+
+ mainLoopSub2(0, 0, 20, 200);
+
+ errorVar = 0;
+
+ addScriptToList0(bootScriptIdx);
+
+ menuVar = 0;
+
+ gfxFuncGen1(page0c, page0, page0c, page0, -1);
+
+ ptrGfxFunc13();
+
+ gfxFuncGen2();
+
+ var_2 = 0;
+ allowPlayerInput = 0;
+ checkForPendingDataLoadSwitch = 0;
+
+ fadeRequired = 0;
+ isDrawCommandEnabled = 0;
+ waitForPlayerClick = 0;
+ var16 = 0;
+
+ playerCommand = -1;
+ strcpy(commandBuffer, "");
+
+ globalVars[0x1F2] = 0;
+ globalVars[0x1F4] = 0;
+
+ for (i = 0; i < 16; i++) {
+ c_palette[i] = 0;
+ }
+
+ var17 = 1;
+
+ strcpy(newPrcName, "");
+ strcpy(newRelName, "");
+ strcpy(newObjectName, "");
+ strcpy(newMsgName, "");
+ strcpy(currentBgName[0], "");
+ strcpy(currentCtName, "");
+ strcpy(currentPartName, "");
+
+ stopSample();
+
+ do {
+ mainLoopSub3();
+ di = (char *)executePlayerInput();
+
+ if (var18 != 0) {
+ if (var18 >= 100 || var19) {
+ stopSample();
+ }
+ }
+
+ processUnkList();
+ executeList1();
+ executeList0();
+
+ purgeList1();
+ purgeList0();
+
+ if (playerCommand == -1) {
+ processPendingUpdates(0);
+ } else {
+ processPendingUpdates(2);
+ }
+
+ drawOverlays();
+ flip();
+
+ if (waitForPlayerClick) {
+ var_6 = 0;
+
+ var20 <<= 3;
+
+ if (var20 < 0x800)
+ var20 = 0x800;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &mouseButton,
+ &dummyU16, &dummyU16);
+ } while (mouseButton != 0);
+
+ menuVar = 0;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &mouseButton,
+ &dummyU16, &dummyU16);
+
+ if (mouseButton == 0) {
+ if (processKeyboard(menuVar)) {
+ var_6 = 1;
+ }
+ } else {
+ var_6 = 1;
+ }
+
+ mainLoopSub6();
+ } while (!var_6);
+
+ menuVar = 0;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &mouseButton,
+ &dummyU16, &dummyU16);
+ } while (mouseButton != 0);
+
+ waitForPlayerClick = 0;
+ }
+
+ if (checkForPendingDataLoadSwitch) {
+ checkForPendingDataLoad();
+
+ checkForPendingDataLoadSwitch = 0;
+ }
+
+ if (di) {
+ if (!strcmp(di, "quit")) {
+ var_2 = 1;
+ }
+ }
+
+ manageEvents();
+
+ } while (!exitEngine && !var_2 && var21 != 7);
+
+ hideMouse();
+ stopSample();
+ closeEngine3();
+ unloadAllMasks();
+ freePrcLinkedList();
+ releaseObjectScripts();
+ closeEngine7();
+ closePart();
+}
diff --git a/engines/cine/main_loop.h b/engines/cine/main_loop.h
new file mode 100644
index 0000000000..91c6a6cdfa
--- /dev/null
+++ b/engines/cine/main_loop.h
@@ -0,0 +1,31 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_MAINLOOP_H_
+#define CINE_MAINLOOP_H_
+
+void mainLoop(int bootScriptIdx);
+void manageEvents(void);
+
+#endif
diff --git a/engines/cine/module.mk b/engines/cine/module.mk
new file mode 100644
index 0000000000..89f833f071
--- /dev/null
+++ b/engines/cine/module.mk
@@ -0,0 +1,36 @@
+MODULE := engines/cine
+
+MODULE_OBJS = \
+ anim.o \
+ auto00.o \
+ bg.o \
+ bg_list.o \
+ cine.o \
+ flip_support.o \
+ font.o \
+ gfx.o \
+ main_loop.o \
+ msg.o \
+ object.o \
+ pal.o \
+ part.o \
+ prc.o \
+ rel.o \
+ resource.o \
+ script.o \
+ sfx_player.o \
+ sound_driver.o \
+ texte.o \
+ unpack.o \
+ various.o
+
+MODULE_DIRS += \
+ cine
+
+# This module can be built as a plugin
+ifdef BUILD_PLUGINS
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/common.rules
diff --git a/engines/cine/msg.cpp b/engines/cine/msg.cpp
new file mode 100644
index 0000000000..e500fd8816
--- /dev/null
+++ b/engines/cine/msg.cpp
@@ -0,0 +1,76 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+u16 msgVar0;
+
+void loadMsg(char *pMsgName) {
+ u16 i;
+ u8 *ptr;
+
+ checkDataDisk(-1);
+
+ msgVar0 = 0;
+
+ for (i = 0; i < NUM_MAX_MESSAGE; i++) {
+ messageTable[i].len = 0;
+
+ if (messageTable[i].ptr) {
+ ASSERT_PTR(messageTable[i].ptr);
+
+ free(messageTable[i].ptr);
+ }
+
+ messageTable[i].ptr = NULL;
+ }
+
+ ptr = readBundleFile(findFileInBundle(pMsgName));
+
+ processPendingUpdates(1);
+
+ msgVar0 = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&msgVar0);
+
+ ASSERT(msgVar0 <= NUM_MAX_MESSAGE);
+
+ for (i = 0; i < msgVar0; i++) {
+ messageTable[i].len = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&messageTable[i].len);
+ }
+
+ for (i = 0; i < msgVar0; i++) {
+ if (messageTable[i].len) {
+ messageTable[i].ptr =
+ (u8 *) malloc(messageTable[i].len);
+
+ ASSERT_PTR(messageTable[i].ptr);
+
+ memcpy(messageTable[i].ptr, ptr, messageTable[i].len);
+ ptr += messageTable[i].len;
+ }
+ }
+}
diff --git a/engines/cine/msg.h b/engines/cine/msg.h
new file mode 100644
index 0000000000..4c442a6586
--- /dev/null
+++ b/engines/cine/msg.h
@@ -0,0 +1,30 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_MSG_H_
+#define CINE_MSG_H_
+
+void loadMsg(char *pMsgName);
+
+#endif
diff --git a/engines/cine/object.cpp b/engines/cine/object.cpp
new file mode 100644
index 0000000000..f9376f422d
--- /dev/null
+++ b/engines/cine/object.cpp
@@ -0,0 +1,490 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+objectStruct objectTable[NUM_MAX_OBJECT];
+u16 globalVars[NUM_MAX_OBJECTDATA];
+overlayHeadElement overlayHead;
+
+void unloadAllMasks(void) {
+ overlayHeadElement *current = overlayHead.next;
+
+ while (current) {
+ overlayHeadElement *next = current->next;
+
+ free(current);
+
+ current = next;
+ }
+
+ resetMessageHead();
+}
+
+void resetMessageHead(void) {
+ overlayHead.next = NULL;
+ overlayHead.previous = NULL;
+}
+
+void loadObject(char *pObjectName) {
+ u16 numEntry;
+ u16 entrySize;
+ u16 i;
+ u8 *ptr;
+
+ checkDataDisk(-1);
+
+ ptr = readBundleFile(findFileInBundle(pObjectName));
+
+ processPendingUpdates(1);
+
+ numEntry = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&numEntry);
+
+ entrySize = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&entrySize);
+
+ ASSERT(numEntry <= NUM_MAX_OBJECT);
+ ASSERT(entrySize == sizeof(objectStruct)); // carefull, it's directly read to memory
+
+ for (i = 0; i < numEntry; i++) {
+ if (objectTable[i].costume != -2) // flag is keep ?
+ {
+ memcpy(&objectTable[i], ptr, entrySize);
+
+ flipU16((u16 *) & objectTable[i].x);
+ flipU16((u16 *) & objectTable[i].y);
+ flipU16(&objectTable[i].mask);
+ flipU16((u16 *) & objectTable[i].frame);
+ flipU16((u16 *) & objectTable[i].costume);
+ flipU16(&objectTable[i].part);
+ }
+
+ ptr += entrySize;
+ }
+
+ if (!strcmp(pObjectName, "INTRO.OBJ")) {
+ for (i = 0; i < 10; i++) {
+ objectTable[i].costume = 0;
+ }
+ }
+}
+
+s8 removeOverlayElement(u16 objIdx, u16 param) {
+ overlayHeadElement *currentHeadPtr = &overlayHead;
+ overlayHeadElement *tempHead = currentHeadPtr;
+ overlayHeadElement *tempPtr2;
+
+ currentHeadPtr = tempHead->next;
+
+ while (currentHeadPtr && (objIdx == currentHeadPtr->objIdx
+ || param == currentHeadPtr->type)) {
+ tempHead = currentHeadPtr;
+
+ currentHeadPtr = tempHead->next;
+ }
+
+ if (!currentHeadPtr) {
+ return -1;
+ }
+
+ if (objIdx != currentHeadPtr->objIdx || param != currentHeadPtr->type) {
+ return -1;
+ }
+
+ tempHead->next = currentHeadPtr->next;
+ tempPtr2 = currentHeadPtr->next;
+
+ if (!tempPtr2) {
+ tempPtr2 = &overlayHead;
+ }
+
+ tempPtr2->previous = currentHeadPtr->previous;
+
+ free(currentHeadPtr);
+
+ return (0);
+}
+
+s16 freeOverlay(u16 objIdx, u16 param) {
+ overlayHeadElement *currentHeadPtr = overlayHead.next;
+ overlayHeadElement *tempHead = &overlayHead;
+ overlayHeadElement *tempPtr2;
+
+ while (currentHeadPtr && ((currentHeadPtr->objIdx != objIdx)
+ || (currentHeadPtr->type != param))) {
+ tempHead = currentHeadPtr;
+ currentHeadPtr = tempHead->next;
+ }
+
+ if (!currentHeadPtr) {
+ return -1;
+ }
+
+ if (!((currentHeadPtr->objIdx == objIdx)
+ && (currentHeadPtr->type == param))) {
+ return -1;
+ }
+
+ tempHead->next = currentHeadPtr->next;
+ tempPtr2 = currentHeadPtr->next;
+
+ if (!tempPtr2) {
+ tempPtr2 = &overlayHead;
+ }
+
+ tempPtr2->previous = currentHeadPtr->previous;
+
+ //TODO: fix !
+ //free(currentHeadPtr);
+
+ return 0;
+}
+
+void loadOverlayElement(u16 objIdx, u16 param) {
+ overlayHeadElement *currentHeadPtr = &overlayHead;
+ overlayHeadElement *pNewElement;
+
+ u16 si = objectTable[objIdx].mask;
+
+ overlayHeadElement *tempHead = currentHeadPtr;
+
+ currentHeadPtr = tempHead->next;
+
+ while (currentHeadPtr
+ && (objectTable[currentHeadPtr->objIdx].mask < si)) {
+ tempHead = currentHeadPtr;
+
+ currentHeadPtr = tempHead->next;
+ }
+
+ pNewElement =
+ (overlayHeadElement *) malloc(sizeof(overlayHeadElement));
+
+ ASSERT_PTR(pNewElement);
+
+ pNewElement->next = tempHead->next;
+ tempHead->next = pNewElement;
+
+ pNewElement->objIdx = objIdx;
+ pNewElement->type = param;
+
+ if (!currentHeadPtr) {
+ currentHeadPtr = &overlayHead;
+ }
+
+ pNewElement->previous = currentHeadPtr->previous;
+ currentHeadPtr->previous = pNewElement;
+}
+
+void setupObject(u8 objIdx, u16 param1, u16 param2, u16 param3, u16 param4) {
+ objectTable[objIdx].x = param1;
+ objectTable[objIdx].y = param2;
+ objectTable[objIdx].mask = param3;
+ objectTable[objIdx].frame = param4;
+
+ if (!removeOverlayElement(objIdx, 0)) {
+ loadOverlayElement(objIdx, 0);
+ }
+}
+
+void subObjectParam(u8 objIdx, u8 paramIdx, s16 newValue) {
+ ASSERT(objIdx <= NUM_MAX_OBJECT);
+
+ paramIdx--;
+
+ ASSERT(paramIdx >= 0 && paramIdx <= 5);
+
+ switch (paramIdx) {
+ case 0:
+ {
+ objectTable[objIdx].x -= newValue;
+ break;
+ }
+ case 1:
+ {
+ objectTable[objIdx].y -= newValue;
+ break;
+ }
+ case 2:
+ {
+ objectTable[objIdx].mask -= newValue;
+
+ if (!removeOverlayElement(objIdx, 0)) {
+ loadOverlayElement(objIdx, 0);
+ }
+ break;
+ }
+ case 3:
+ {
+ objectTable[objIdx].frame -= newValue;
+ break;
+ }
+ case 4:
+ {
+ objectTable[objIdx].costume -= newValue;
+ break;
+ }
+ case 5:
+ {
+ objectTable[objIdx].part -= newValue;
+ break;
+ }
+ }
+}
+
+void addObjectParam(u8 objIdx, u8 paramIdx, s16 newValue) {
+ ASSERT(objIdx <= NUM_MAX_OBJECT);
+
+ paramIdx--;
+
+ ASSERT(paramIdx >= 0 && paramIdx <= 5);
+
+ switch (paramIdx) {
+ case 0:
+ {
+ objectTable[objIdx].x += newValue;
+ break;
+ }
+ case 1:
+ {
+ objectTable[objIdx].y += newValue;
+ break;
+ }
+ case 2:
+ {
+ objectTable[objIdx].mask += newValue;
+
+ if (!removeOverlayElement(objIdx, 0)) {
+ loadOverlayElement(objIdx, 0);
+ }
+ break;
+ }
+ case 3:
+ {
+ objectTable[objIdx].frame += newValue;
+ break;
+ }
+ case 4:
+ {
+ objectTable[objIdx].costume += newValue;
+ break;
+ }
+ case 5:
+ {
+ objectTable[objIdx].part += newValue;
+ break;
+ }
+ }
+}
+
+void modifyObjectParam(u8 objIdx, u8 paramIdx, s16 newValue) {
+ ASSERT(objIdx <= NUM_MAX_OBJECT);
+
+ paramIdx--;
+
+ ASSERT(paramIdx >= 0 && paramIdx <= 5);
+
+ switch (paramIdx) {
+ case 0:
+ {
+ objectTable[objIdx].x = newValue;
+ break;
+ }
+ case 1:
+ {
+ objectTable[objIdx].y = newValue;
+ break;
+ }
+ case 2:
+ {
+ objectTable[objIdx].mask = newValue;
+
+ if (!removeOverlayElement(objIdx, 0)) {
+ loadOverlayElement(objIdx, 0);
+ }
+ break;
+ }
+ case 3:
+ {
+ objectTable[objIdx].frame = newValue;
+ break;
+ }
+ case 4:
+ {
+ if (newValue == -1) {
+ objectTable[objIdx].costume = globalVars[0];
+ } else {
+ objectTable[objIdx].costume = newValue;
+ }
+ break;
+ }
+ case 5:
+ {
+ objectTable[objIdx].part = newValue;
+ break;
+ }
+ }
+}
+
+u8 compareObjectParam(u8 objIdx, u8 param1, s16 param2) {
+ u8 compareResult = 0;
+
+ switch (param1 - 1) {
+ case 0:
+ {
+ if (objectTable[objIdx].x == param2) {
+ compareResult |= 1;
+ }
+
+ if (objectTable[objIdx].x > param2) {
+ compareResult |= 2;
+ }
+
+ if (objectTable[objIdx].x < param2) {
+ compareResult |= 4;
+ }
+
+ break;
+ }
+ case 1:
+ {
+ if (objectTable[objIdx].y == param2) {
+ compareResult |= 1;
+ }
+
+ if (objectTable[objIdx].y > param2) {
+ compareResult |= 2;
+ }
+
+ if (objectTable[objIdx].y < param2) {
+ compareResult |= 4;
+ }
+
+ break;
+ }
+ case 2:
+ {
+ if (objectTable[objIdx].mask == param2) {
+ compareResult |= 1;
+ }
+
+ if (objectTable[objIdx].mask > param2) {
+ compareResult |= 2;
+ }
+
+ if (objectTable[objIdx].mask < param2) {
+ compareResult |= 4;
+ }
+
+ break;
+ }
+ case 3:
+ {
+ if (objectTable[objIdx].frame == param2) {
+ compareResult |= 1;
+ }
+
+ if (objectTable[objIdx].frame > param2) {
+ compareResult |= 2;
+ }
+
+ if (objectTable[objIdx].frame < param2) {
+ compareResult |= 4;
+ }
+
+ break;
+ }
+ case 4:
+ {
+ if (objectTable[objIdx].costume == param2) {
+ compareResult |= 1;
+ }
+
+ if (objectTable[objIdx].costume > param2) {
+ compareResult |= 2;
+ }
+
+ if (objectTable[objIdx].costume < param2) {
+ compareResult |= 4;
+ }
+
+ break;
+ }
+ default:
+ {
+ printf
+ ("Unsupported compare type: %d in compareObjectParam\n",
+ param1 - 1);
+ exit(1);
+ }
+ }
+
+ return (compareResult);
+}
+
+s16 getObjectParam(u16 objIdx, u16 paramIdx) {
+ ASSERT(objIdx <= NUM_MAX_OBJECT);
+
+ paramIdx--;
+
+ ASSERT(paramIdx >= 0 && paramIdx <= 5);
+
+ switch (paramIdx) {
+ case 0:
+ {
+ return objectTable[objIdx].x;
+ break;
+ }
+ case 1:
+ {
+ return objectTable[objIdx].y;
+ break;
+ }
+ case 2:
+ {
+ return objectTable[objIdx].mask;
+ break;
+ }
+ case 3:
+ {
+ return objectTable[objIdx].frame;
+ break;
+ }
+ case 4:
+ {
+ return objectTable[objIdx].costume;
+ break;
+ }
+ case 5:
+ {
+ return objectTable[objIdx].part;
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/engines/cine/object.h b/engines/cine/object.h
new file mode 100644
index 0000000000..061ce8253e
--- /dev/null
+++ b/engines/cine/object.h
@@ -0,0 +1,76 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_OBJECT_H_
+#define CINE_OBJECT_H_
+
+typedef struct {
+ s16 x;
+ s16 y;
+ u16 mask;
+ s16 frame;
+ s16 costume;
+ char name[20];
+ u16 part;
+} objectStruct;
+
+struct overlayHeadElement {
+ struct overlayHeadElement *next;
+ struct overlayHeadElement *previous;
+ u16 objIdx;
+ u16 type;
+ s16 x;
+ s16 y;
+ s16 var10;
+ s16 var12;
+};
+
+typedef struct overlayHeadElement overlayHeadElement;
+
+#define NUM_MAX_OBJECT 255
+#define NUM_MAX_OBJECTDATA 255
+
+extern objectStruct objectTable[NUM_MAX_OBJECT];
+extern u16 globalVars[NUM_MAX_OBJECTDATA];
+
+extern overlayHeadElement overlayHead;
+
+void unloadAllMasks(void);
+void resetMessageHead(void);
+
+void loadObject(char *pObjectName);
+void setupObject(u8 objIdx, u16 param1, u16 param2, u16 param3, u16 param4);
+void modifyObjectParam(u8 objIdx, u8 paramIdx, s16 newValue);
+
+void loadOverlayElement(u16 objIdx, u16 param);
+s8 removeOverlayElement(u16 objIdx, u16 param);
+
+s16 getObjectParam(u16 objIdx, u16 paramIdx);
+s16 freeOverlay(u16 objIdx, u16 param);
+
+void addObjectParam(u8 objIdx, u8 paramIdx, s16 newValue);
+void subObjectParam(u8 objIdx, u8 paramIdx, s16 newValue);
+u8 compareObjectParam(u8 objIdx, u8 param1, s16 param2);
+
+#endif
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp
new file mode 100644
index 0000000000..a6acb33ac4
--- /dev/null
+++ b/engines/cine/pal.cpp
@@ -0,0 +1,123 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+u16 tempPalette[256];
+
+u8 colorMode256 = 0;
+u8 palette256[256 * 3];
+
+u16 palVar;
+u16 palVar0;
+
+Common::File palFileHandle;
+
+palEntryStruct *palPtr;
+
+u8 paletteBuffer1[16];
+u8 paletteBuffer2[16];
+
+void loadPal(const char *fileName) {
+ char buffer[20];
+
+ removeExtention(buffer, fileName);
+
+ strcat(buffer, ".PAL");
+
+ palFileHandle.close();
+
+ if (palPtr) {
+ free(palPtr);
+ palPtr = NULL;
+ }
+
+ palVar = 0;
+ palVar0 = 42;
+
+ palFileHandle.open(buffer);
+
+ ASSERT(palFileHandle.isOpen());
+
+ palFileHandle.read(&palVar, 2); // endian: not fliped !
+ palFileHandle.read(&palVar0, 2);
+
+ palPtr = (palEntryStruct *) malloc(palVar * palVar0);
+
+ ASSERT_PTR(palPtr);
+
+ palFileHandle.read(palPtr, palVar * palVar0);
+}
+
+s16 findPaletteFromName(const char *fileName) {
+ char buffer[10];
+ u16 position = 0;
+ u16 i;
+
+ strcpy(buffer, fileName);
+
+ while (position < strlen(fileName)) {
+ if (buffer[position] > 'a' && buffer[position] < 'z') {
+ buffer[position] += 0xE0;
+ }
+
+ position++;
+ }
+
+ for (i = 0; i < palVar; i++) {
+ if (!strcmp(buffer, palPtr[i].name)) {
+ return i;
+ }
+ }
+
+ return -1;
+
+}
+
+void loadRelatedPalette(const char *fileName) {
+ char localName[16];
+ u8 i;
+ s16 paletteIndex;
+
+ removeExtention(localName, fileName);
+
+ paletteIndex = findPaletteFromName(localName);
+
+ if (paletteIndex == -1) {
+ for (i = 0; i < 16; i++) // generate default palette
+ {
+ paletteBuffer1[i] = paletteBuffer2[i] = (i << 4) + i;
+ }
+ } else {
+ palEntryStruct *palEntryPtr = &palPtr[paletteIndex];
+
+ ASSERT_PTR(paletteBuffer2);
+
+ for (i = 0; i < 16; i++) // convert palette
+ {
+ paletteBuffer1[i] = palEntryPtr->pal1[i];
+ paletteBuffer2[i] = palEntryPtr->pal2[i];
+ }
+ }
+}
diff --git a/engines/cine/pal.h b/engines/cine/pal.h
new file mode 100644
index 0000000000..75d20e7cde
--- /dev/null
+++ b/engines/cine/pal.h
@@ -0,0 +1,44 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_PAL_H_
+#define CINE_PAL_H_
+
+struct palEntryStruct {
+ char name[10];
+ u8 pal1[16];
+ u8 pal2[16];
+};
+
+typedef struct palEntryStruct palEntryStruct;
+
+void loadPal(const char *fileName);
+
+extern u16 tempPalette[256];
+extern u8 colorMode256;
+extern u8 palette256[256 * 3];
+
+void loadRelatedPalette(const char *fileName);
+
+#endif
diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp
new file mode 100644
index 0000000000..70f4eae88b
--- /dev/null
+++ b/engines/cine/part.cpp
@@ -0,0 +1,226 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+u16 numElementInPart;
+u16 partVar1;
+
+animDataStruct animDataTable[NUM_MAX_PARTDATA];
+partBufferStruct *partBuffer;
+
+void loadPart(const char *partName) {
+ u16 i;
+
+ ASSERT(sizeof(partBufferStruct) == 0x1E);
+
+ for (i = 0; i < 255; i++) {
+ partBuffer[i].part_name[0] = 0;
+
+ partBuffer[i].offset = 0;
+ partBuffer[i].packed_size = 0;
+ partBuffer[i].unpacked_size = 0;
+ partBuffer[i].var1A = 0;
+ }
+
+ numElementInPart = 0;
+ partVar1 = 30;
+
+ partFileHandle.close();
+
+ checkDataDisk(-1);
+
+ partFileHandle.open(partName);
+
+ ASSERT(partFileHandle.isOpen());
+
+ processPendingUpdates(-1);
+
+ partFileHandle.read(&numElementInPart, 2);
+ partFileHandle.read(&partVar1, 2);
+
+ flipU16(&numElementInPart);
+ flipU16(&partVar1);
+
+ partFileHandle.read(partBuffer, numElementInPart * partVar1);
+
+ strcpy(currentPartName, partName);
+
+ for (i = 0; i < numElementInPart; i++) {
+ flipU32(&partBuffer[i].offset);
+ flipU32(&partBuffer[i].packed_size);
+ flipU32(&partBuffer[i].unpacked_size);
+ }
+
+ if (gameType == Cine::GID_FW)
+ loadPal(partName);
+}
+
+void freePartEntry(u8 idx) {
+ if (animDataTable[idx].ptr1) {
+ //free(animDataTable[idx].ptr1);
+
+ animDataTable[idx].ptr1 = NULL;
+ animDataTable[idx].ptr2 = NULL;
+
+ // TODO: finish
+
+ if (frameVar0 > 0)
+ frameVar0--;
+ }
+}
+
+void freePartRange(u8 startIdx, u8 numIdx) {
+ u8 i;
+
+ for (i = 0; i < numIdx; i++) {
+ freePartEntry(i + startIdx);
+ }
+}
+
+void closePart(void) {
+}
+
+const char *bundleNames[] = {
+ "EGOUBASE",
+ "LABYBASE",
+ "PROCEGOU",
+ "PROCLABY",
+ "PROCS00",
+ "PROCS01",
+ "PROCS02",
+ "PROCS03",
+ "PROCS04",
+ "PROCS06",
+ "PROCS07",
+ "PROCS08",
+ "PROCS10",
+ "PROCS12",
+ "PROCS13",
+ "PROCS15",
+ "PROCS16",
+ "RSC00",
+ "RSC01",
+ "RSC02",
+ "RSC03",
+ "RSC04",
+ "RSC05",
+ "RSC06",
+ "RSC07",
+ "RSC08",
+ "RSC09",
+ "RSC10",
+ "RSC11",
+ "RSC12",
+ "RSC13",
+ "RSC14",
+ "RSC15",
+ "RSC16",
+ "RSC17",
+// english version
+ "SONS1",
+ "SONS2",
+ "SONS3",
+ "SONS4",
+ "SONS5",
+ "SONS6",
+ "SONS7",
+ "SONS8",
+ "SONS9",
+/*
+"SONS31", // french version
+"SONS32",
+"SONS33",
+"SONS34"
+*/
+};
+
+s16 findFileInBundle(const char *fileName) {
+ u16 i;
+
+ if (gameType == Cine::GID_OS) {
+ u16 j;
+
+ for (i = 0; i < numElementInPart; i++) {
+ if (!strcmp(fileName, partBuffer[i].part_name)) {
+ return i;
+ }
+ }
+
+ for (j = 0; j < 39; j++) {
+ loadPart(bundleNames[j]);
+
+ for (i = 0; i < numElementInPart; i++) {
+ if (!strcmp(fileName, partBuffer[i].part_name)) {
+ return i;
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < numElementInPart; i++) {
+ if (!strcmp(fileName, partBuffer[i].part_name)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+void readFromPart(s16 idx, u8 *dataPtr) {
+ processPendingUpdates(1);
+
+ partFileHandle.seek(partBuffer[idx].offset, SEEK_SET);
+
+ partFileHandle.read(dataPtr, partBuffer[idx].packed_size);
+}
+
+u8 *readBundleFile(s16 foundFileIdx) {
+ u8 *dataPtr;
+
+ dataPtr = (u8 *) malloc(partBuffer[foundFileIdx].unpacked_size + 2);
+ memset(dataPtr, 0, partBuffer[foundFileIdx].unpacked_size + 2);
+
+ if (partBuffer[foundFileIdx].unpacked_size !=
+ partBuffer[foundFileIdx].packed_size) {
+ u8 *unpackBuffer;
+ u16 realSize;
+
+ unpackBuffer =
+ (u8 *) malloc(partBuffer[foundFileIdx].packed_size + 500);
+ readFromPart(foundFileIdx, unpackBuffer);
+
+ realSize =
+ *(u16 *) (unpackBuffer +
+ partBuffer[foundFileIdx].packed_size - 2);
+ flipU16(&realSize);
+
+ decomp(unpackBuffer + partBuffer[foundFileIdx].packed_size - 4,
+ dataPtr + realSize, realSize);
+ free(unpackBuffer);
+ } else {
+ readFromPart(foundFileIdx, dataPtr);
+ }
+
+ return dataPtr;
+}
diff --git a/engines/cine/part.h b/engines/cine/part.h
new file mode 100644
index 0000000000..d5504f53e8
--- /dev/null
+++ b/engines/cine/part.h
@@ -0,0 +1,66 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_PART_H_
+#define CINE_PART_H_
+
+typedef struct {
+ char part_name[10];
+ u32 varA; /* unused */
+ u32 offset;
+ u32 packed_size;
+ u32 unpacked_size;
+ u32 var1A; /* unused */
+} partBufferStruct;
+
+typedef struct {
+ u16 width;
+ u16 var1;
+ u16 field_4;
+ u16 var2;
+
+ u8 *ptr1;
+ u8 *ptr2;
+ s16 fileIdx;
+ s16 frameIdx;
+ char name[10];
+} animDataStruct;
+
+#define NUM_MAX_PARTDATA 255
+#define NUM_MAX_ANIMDATA 255
+
+extern animDataStruct animDataTable[NUM_MAX_ANIMDATA];
+extern partBufferStruct *partBuffer;
+
+void loadPart(const char *partName);
+void freePartRange(u8 startIdx, u8 numIdx);
+void closePart(void);
+
+s16 findFileInBundle(const char *fileName);
+
+void readFromPart(s16 idx, u8 *dataPtr);
+
+u8 *readBundleFile(s16 foundFileIdx);
+
+#endif
diff --git a/engines/cine/prc.cpp b/engines/cine/prc.cpp
new file mode 100644
index 0000000000..d39d4cb163
--- /dev/null
+++ b/engines/cine/prc.cpp
@@ -0,0 +1,144 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+prcLinkedListStruct globalScriptsHead;
+prcLinkedListStruct objScriptList;
+
+//char currentPrcName[20];
+
+void resetglobalScriptsHead(void) {
+ globalScriptsHead.next = NULL;
+ globalScriptsHead.scriptIdx = -1;
+}
+
+void freePrcLinkedList(void) {
+ prcLinkedListStruct *currentHead = globalScriptsHead.next;
+
+ while (currentHead) {
+ prcLinkedListStruct *temp;
+
+ ASSERT_PTR(currentHead);
+
+ temp = currentHead->next;
+
+ free(currentHead);
+
+ currentHead = temp;
+ }
+
+ resetglobalScriptsHead();
+}
+
+void loadPrc(char *pPrcName) {
+ u8 i;
+ u16 numEntry;
+
+ ASSERT_PTR(pPrcName);
+
+ for (i = 0; i < NUM_MAX_SCRIPT; i++) {
+ if (scriptTable[i].ptr) {
+ ASSERT_PTR(scriptTable[i].ptr);
+
+ free(scriptTable[i].ptr);
+
+ scriptTable[i].ptr = NULL;
+ scriptTable[i].var4 = 0;
+ }
+ }
+
+ checkDataDisk(-1);
+ if ((gameType == Cine::GID_FW) && (!strcmp(pPrcName, "AUTO00.PRC"))) {
+ unsigned char *readPtr = AUT000;
+
+ processPendingUpdates(1);
+
+ numEntry = *(unsigned short int *)readPtr;
+ readPtr += 2;
+ flipU16(&numEntry);
+
+ ASSERT(numEntry <= NUM_MAX_SCRIPT);
+
+ for (i = 0; i < numEntry; i++) {
+ scriptTable[i].var4 = *(unsigned short int *)readPtr;
+ readPtr += 2;
+ flipU16(&scriptTable[i].var4);
+ }
+
+ for (i = 0; i < numEntry; i++) {
+ u16 size;
+
+ size = scriptTable[i].var4;
+
+ if (size) {
+ scriptTable[i].ptr = (byte *) malloc(size);
+
+ ASSERT_PTR(scriptTable[i].ptr);
+
+ memcpy(scriptTable[i].ptr, readPtr, size);
+ readPtr += size;
+
+ computeScriptStack(scriptTable[i].ptr,
+ scriptTable[i].stack, size);
+ }
+ }
+ } else {
+ u8 *ptr = readBundleFile(findFileInBundle(pPrcName));
+
+ ASSERT_PTR(ptr);
+
+ processPendingUpdates(1);
+
+ numEntry = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&numEntry);
+
+ ASSERT(numEntry <= NUM_MAX_SCRIPT);
+
+ for (i = 0; i < numEntry; i++) {
+ scriptTable[i].var4 = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&scriptTable[i].var4);
+ }
+
+ for (i = 0; i < numEntry; i++) {
+ u16 size;
+
+ size = scriptTable[i].var4;
+
+ if (size) {
+ scriptTable[i].ptr = (byte *) malloc(size);
+
+ ASSERT_PTR(scriptTable[i].ptr);
+
+ memcpy(scriptTable[i].ptr, ptr, size);
+ ptr += size;
+
+ computeScriptStack(scriptTable[i].ptr,
+ scriptTable[i].stack, size);
+ }
+ }
+ }
+}
diff --git a/engines/cine/prc.h b/engines/cine/prc.h
new file mode 100644
index 0000000000..7a5eb7fec6
--- /dev/null
+++ b/engines/cine/prc.h
@@ -0,0 +1,47 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_PRC_H_
+#define CINE_PRC_H_
+
+struct prcLinkedListStruct {
+ struct prcLinkedListStruct *next;
+ s16 stack[SCRIPT_STACK_SIZE];
+ s16 localVars[50];
+ u16 compareResult;
+ u16 scriptPosition;
+ byte *scriptPtr;
+ s16 scriptIdx;
+};
+
+typedef struct prcLinkedListStruct prcLinkedListStruct;
+
+extern prcLinkedListStruct globalScriptsHead;
+extern prcLinkedListStruct objScriptList;
+
+void resetglobalScriptsHead(void);
+void freePrcLinkedList(void);
+void loadPrc(char *pPrcName);
+
+#endif
diff --git a/engines/cine/rel.cpp b/engines/cine/rel.cpp
new file mode 100644
index 0000000000..a42d46f01a
--- /dev/null
+++ b/engines/cine/rel.cpp
@@ -0,0 +1,127 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+relStruct relTable[NUM_MAX_REL];
+
+void resetObjectScriptHead(void) {
+ objScriptList.next = NULL;
+ objScriptList.scriptIdx = -1;
+}
+
+void releaseObjectScripts(void) {
+ prcLinkedListStruct *currentHead = objScriptList.next;
+
+ while (currentHead) {
+ prcLinkedListStruct *temp;
+
+ ASSERT_PTR(currentHead);
+
+ temp = currentHead->next;
+
+ free(currentHead);
+
+ currentHead = temp;
+ }
+
+ resetObjectScriptHead();
+}
+
+void loadRel(char *pRelName) {
+ u16 numEntry;
+ u16 i;
+ u8 *ptr;
+
+ checkDataDisk(-1);
+
+ for (i = 0; i < NUM_MAX_REL; i++) {
+ if (relTable[i].ptr0) {
+ ASSERT_PTR(relTable[i].ptr0);
+
+ free(relTable[i].ptr0);
+
+ relTable[i].ptr0 = NULL;
+
+ relTable[i].var4 = 0;
+ }
+ }
+
+ ptr = readBundleFile(findFileInBundle(pRelName));
+
+ processPendingUpdates(1);
+
+ numEntry = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&numEntry);
+
+ ASSERT(numEntry <= NUM_MAX_REL);
+
+ for (i = 0; i < numEntry; i++) {
+ relTable[i].var4 = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&relTable[i].var4);
+
+ relTable[i].var6 = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&relTable[i].var6);
+
+ relTable[i].var8 = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&relTable[i].var8);
+
+ relTable[i].varA = *(u16 *) ptr;
+ ptr += 2;
+ flipU16(&relTable[i].varA);
+ }
+
+ for (i = 0; i < numEntry; i++) {
+ if (relTable[i].var4) {
+ relTable[i].ptr0 = (char *)malloc(relTable[i].var4);
+
+ ASSERT_PTR(relTable[i].ptr0);
+
+ memcpy(relTable[i].ptr0, ptr, relTable[i].var4);
+ ptr += relTable[i].var4;
+ }
+ }
+
+#ifdef DUMP_SCRIPTS_OBJ
+
+ {
+ u16 i;
+ u8 buffer[256];
+
+ for (i = 0; i < numEntry; i++) {
+ if (relTable[i].var4) {
+ sprintf(buffer, "%s_%03d.txt", pRelName, i);
+
+ decompileScript(relTable[i].ptr0, NULL,
+ relTable[i].var4, i);
+ dumpScript(buffer);
+ }
+ }
+ }
+#endif
+}
diff --git a/engines/cine/rel.h b/engines/cine/rel.h
new file mode 100644
index 0000000000..3a46c8bc9d
--- /dev/null
+++ b/engines/cine/rel.h
@@ -0,0 +1,45 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_REL_H_
+#define CINE_REL_H_
+
+typedef struct relData {
+ char *ptr0;
+ u16 var4;
+ u16 var6;
+ u16 var8;
+ u16 varA;
+} relStruct;
+
+#define NUM_MAX_REL 255
+
+extern relStruct relTable[NUM_MAX_REL];
+
+void releaseObjectScripts(void);
+void resetObjectScriptHead(void);
+
+void loadRel(char *pRelName);
+
+#endif
diff --git a/engines/cine/resource.cpp b/engines/cine/resource.cpp
new file mode 100644
index 0000000000..aaa0ce31c4
--- /dev/null
+++ b/engines/cine/resource.cpp
@@ -0,0 +1,28 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+void checkDataDisk(s16 param) {
+}
diff --git a/engines/cine/resource.h b/engines/cine/resource.h
new file mode 100644
index 0000000000..ad3fa1fd4c
--- /dev/null
+++ b/engines/cine/resource.h
@@ -0,0 +1,30 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_RESOURCE_H_
+#define CINE_RESOURCE_H_
+
+void checkDataDisk(s16 param);
+
+#endif
diff --git a/engines/cine/script.cpp b/engines/cine/script.cpp
new file mode 100644
index 0000000000..85268c9fad
--- /dev/null
+++ b/engines/cine/script.cpp
@@ -0,0 +1,4421 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+void addGfxElementA0(s16 param1, s16 param2) {
+ overlayHeadElement *currentHead = &overlayHead;
+ overlayHeadElement *tempHead = currentHead;
+ overlayHeadElement *newElement;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ if (objectTable[currentHead->objIdx].mask ==
+ objectTable[param1].mask) {
+ if (currentHead->type == 2 || currentHead->objIdx == 3) {
+ break;
+ }
+ }
+
+ tempHead = currentHead;
+ currentHead = currentHead->next;
+ }
+
+ if (currentHead && currentHead->objIdx == param1
+ && currentHead->type == 20 && currentHead->x == param2)
+ return;
+
+ newElement = (overlayHeadElement *) malloc(sizeof(overlayHeadElement));
+
+ newElement->next = tempHead->next;
+ tempHead->next = newElement;
+
+ newElement->objIdx = param1;
+ newElement->type = 20;
+
+ newElement->x = param2;
+ newElement->y = 0;
+ newElement->var10 = 0;
+ newElement->var12 = 0;
+
+ if (!currentHead)
+ currentHead = &overlayHead;
+
+ newElement->previous = currentHead->previous;
+
+ currentHead->previous = newElement;
+}
+
+void removeSeq(u16 param1, u16 param2, u16 param3) {
+ unkListElementStruct *currentHead = &unkList;
+ unkListElementStruct *tempHead = currentHead;
+
+ while (currentHead && (currentHead->var6 != param1
+ || currentHead->var4 != param2
+ || currentHead->varE != param3)) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ if (currentHead && currentHead->var6 == param1
+ && currentHead->var4 == param2 && currentHead->varE == param3) {
+ currentHead->var4 = -1;
+ }
+}
+
+u16 isSeqRunning(u16 param1, u16 param2, u16 param3) {
+ unkListElementStruct *currentHead = &unkList;
+ unkListElementStruct *tempHead = currentHead;
+
+ while (currentHead && (currentHead->var6 != param1
+ || currentHead->var4 != param2
+ || currentHead->varE != param3)) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ if (currentHead && currentHead->var6 == param1
+ && currentHead->var4 == param2 && currentHead->varE == param3) {
+ return (1);
+ }
+
+ return (0);
+}
+
+scriptStruct scriptTable[NUM_MAX_SCRIPT];
+
+void createVar9Element(s16 objIdx, s16 param) {
+}
+
+void addToBGList(s16 objIdx) {
+ s16 x;
+ s16 y;
+ s16 width;
+ s16 height;
+ s16 part;
+
+ x = objectTable[objIdx].x;
+ y = objectTable[objIdx].y;
+
+ width = animDataTable[objectTable[objIdx].frame].var1;
+ height = animDataTable[objectTable[objIdx].frame].var2;
+
+ part = objectTable[objIdx].part;
+
+ if (gameType == Cine::GID_OS) {
+ drawSpriteRaw2(animDataTable[objectTable[objIdx].frame].ptr1,
+ objectTable[objIdx].part, width, height, page2Raw, x, y);
+ } else {
+ drawSpriteRaw(animDataTable[objectTable[objIdx].frame].ptr1,
+ animDataTable[objectTable[objIdx].frame].ptr2, width,
+ height, page2Raw, x, y);
+ }
+
+ createVar9Element(objIdx, 0);
+}
+
+void stopGlobalScript(u16 scriptIdx) {
+ prcLinkedListStruct *currentHead = &globalScriptsHead;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead && (currentHead->scriptIdx != scriptIdx)) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ if (!currentHead) {
+ return;
+ }
+
+ if (currentHead->scriptIdx != scriptIdx) {
+ return;
+ }
+
+ currentHead->scriptIdx = -1;
+}
+
+u16 computeScriptStackSub(u8 mode, byte *scriptPtr, s16 *stackPtr,
+ u16 scriptSize, u8 param1, u16 startOffset) {
+ byte *localScriptPtr = scriptPtr;
+ u16 exitScript;
+ u16 i;
+ u16 position;
+ u16 di;
+
+ ASSERT_PTR(scriptPtr);
+ ASSERT_PTR(stackPtr);
+
+ if (mode == 1) {
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ stackPtr[i] = -1;
+ }
+
+ position = 0;
+ } else {
+ position = startOffset;
+ }
+
+ exitScript = 0;
+
+ do {
+ u16 opcode = *(localScriptPtr + position);
+ position++;
+
+ //printf("Opcode: %X\n",opcode-1);
+
+ switch (opcode - 1) {
+ case -1:
+ case 0x1B:
+ {
+ break;
+ }
+ case 0x89:
+ case 0x32:
+ case 0x7A:
+ case 0x91:
+ case 0x9D:
+ case 0x8F:
+ case 0x7B:
+ case 0x8C:
+ case 0x8B:
+ case 0x85:
+ case 0x86:
+ case 0x84:
+ case 0x88:
+ {
+ position++;
+ break;
+ }
+ case 0x80:
+ case 0x83:
+ case 0x26:
+ {
+ position += 2;
+ break;
+ }
+ case 0xF:
+ case 0x1:
+ case 0x66:
+ case 0x4A:
+ {
+ position += 3;
+ break;
+ }
+ case 0x0:
+ case 0x2:
+ case 0x3:
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0xA0:
+ case 0xA1:
+ case 0xA2:
+ case 0xA3:
+ {
+ position += 4;
+ break;
+ }
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0xD:
+ case 0xE:
+ case 0x52:
+ case 0x53:
+ {
+ u8 param;
+ position++;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ if (param) {
+ position++;
+ } else {
+ position += 2;
+ }
+ break;
+ }
+ case 0x9E:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ if (param) {
+ position++;
+ } else {
+ position += 2;
+ }
+ break;
+ }
+ case 0x82:
+ {
+ position += 7;
+ break;
+ }
+ case 0x47:
+ {
+ position += 8;
+ break;
+ }
+ case 0x51:
+ case 0x7:
+ case 0x77:
+ case 0x78:
+ case 0x8:
+ {
+ position += 9;
+ break;
+ }
+ case 0x7F:
+ {
+ position += 10;
+ break;
+ }
+ case 0x1D:
+ {
+ di = *(localScriptPtr + position);
+ position++;
+
+ if (mode == 1) {
+ stackPtr[di] = position;
+ } else {
+ if (param1 == di) {
+ return (position);
+ }
+ }
+
+ break;
+ }
+ case 0x59:
+ case 0x3B:
+ case 0x3C:
+ case 0x3D:
+ case OP_loadPart: // skipString
+ case 0x6D:
+ case 0x8E:
+ {
+ do {
+ position++;
+ } while (*(localScriptPtr + position));
+ break;
+ }
+ case 0x90:
+ case OP_loadNewPrcName: //skipVarAndString
+ {
+ di = *(localScriptPtr + position);
+ position++;
+
+ do {
+ position++;
+ } while (*(localScriptPtr + position));
+
+ break;
+ }
+ case 0x46:
+ case 0x65:
+ case 0x4F:
+ case 0x40:
+ case 0x6A:
+ case 0x69:
+ case 0x45:
+ case 0x6E:
+ case 0x6F:
+ case 0x70:
+ {
+ break;
+ }
+ case 0x1E:
+ case 0x1F:
+ case 0x20:
+ case 0x21:
+ case 0x22:
+ case 0x23:
+ case 0x24:
+ case 0x25:
+ case 0x68:
+ case 0x49:
+ case 0x31:
+ case 0x13:
+ case 0x14:
+ case 0x15:
+ case 0x16:
+ case 0x17:
+ case 0x18:
+ case 0x19:
+ case 0x1A:
+ {
+ position++;
+ break;
+ }
+ case 0x5A:
+ {
+ position += 2;
+ break;
+ }
+ case 0x5B:
+ {
+ break;
+ }
+ case OP_changeDataDisk: // skipVar
+ case OP_79:
+ {
+ di = *(localScriptPtr + position);
+ position++;
+
+ break;
+ }
+ case OP_endScript: // end
+ {
+ exitScript = 1;
+ break;
+ }
+ case OP_requestCheckPendingDataLoad: // nop
+ {
+ break;
+ }
+ default:
+ {
+ printf
+ ("Unsupported opcode %X in computeScriptStack\n",
+ opcode - 1);
+ exit(1);
+ }
+ }
+
+ if (position > scriptSize) {
+ exitScript = 1;
+ }
+
+ } while (!exitScript);
+
+ return (position);
+}
+
+void computeScriptStack(byte *scriptPtr, s16 *stackPtr, u16 scriptSize) {
+ computeScriptStackSub(1, scriptPtr, stackPtr, scriptSize, 0, 0);
+}
+
+u16 computeScriptStackFromScript(byte *scriptPtr, u16 currentPosition,
+ u16 labelIdx, u16 scriptSize) {
+ return computeScriptStackSub(0, scriptPtr, (s16 *) & dummyU16,
+ (u16) scriptSize, labelIdx, currentPosition);
+}
+
+void palRotate(u8 var1, u8 var2, u8 var3) {
+ s16 i;
+ u16 currentColor;
+
+ if (var3 == 1) {
+ currentColor = c_palette[var2];
+
+ for (i = var2; i > var1; i--) {
+ c_palette[i] = c_palette[i - 1];
+ }
+
+ c_palette[var1] = currentColor;
+ }
+}
+
+void addScriptToList0(u16 idx) {
+ u16 i;
+ prcLinkedListStruct *pNewElement;
+ prcLinkedListStruct *currentHead = &globalScriptsHead;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ ASSERT(idx <= NUM_MAX_SCRIPT);
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ tempHead = currentHead;
+
+ ASSERT_PTR(tempHead);
+
+ currentHead = tempHead->next;
+ }
+
+ pNewElement =
+ (prcLinkedListStruct *) malloc(sizeof(prcLinkedListStruct));
+
+ ASSERT_PTR(pNewElement);
+
+ pNewElement->next = tempHead->next;
+ tempHead->next = pNewElement;
+
+ // copy the stack into the script instance
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ pNewElement->stack[i] = scriptTable[idx].stack[i];
+ }
+
+ for (i = 0; i < 50; i++) {
+ pNewElement->localVars[i] = 0;
+ }
+
+ pNewElement->compareResult = 0;
+ pNewElement->scriptPosition = 0;
+
+ pNewElement->scriptPtr = scriptTable[idx].ptr;
+ pNewElement->scriptIdx = idx;
+}
+
+#ifdef _DEBUG
+#define DEBUG_SCRIPT debugScript
+void debugScript(int currentLine, char *string, ...) {
+ va_list va;
+
+ va_start(va, string);
+ vprintf(string, va);
+ va_end(va);
+ printf("\n");
+}
+#else
+#define DEBUG_SCRIPT debugScriptInline
+void debugScriptInline(int currentLine, char *string, ...) {
+}
+#endif
+
+s16 endScript0(u16 scriptIdx) {
+ prcLinkedListStruct *currentHead = &globalScriptsHead;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ //ASSERT(scriptIdx <= NUM_MAX_SCRIPT);
+
+ currentHead = tempHead->next;
+
+ while (currentHead && currentHead->scriptIdx != scriptIdx) {
+ tempHead = currentHead;
+
+ currentHead = tempHead->next;
+ }
+
+ if (!currentHead) {
+ return -1;
+ }
+
+ if (currentHead->scriptIdx != scriptIdx) {
+ return -1;
+ }
+
+ currentHead->scriptIdx = -1;
+
+ return (0);
+}
+
+s16 endScript1(u16 scriptIdx) {
+ prcLinkedListStruct *currentHead = &objScriptList;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead && currentHead->scriptIdx != scriptIdx) {
+ tempHead = currentHead;
+
+ currentHead = tempHead->next;
+ }
+
+ if (!currentHead) {
+ return -1;
+ }
+
+ if (currentHead->scriptIdx != scriptIdx) {
+ return -1;
+ }
+
+ currentHead->scriptIdx = -1;
+
+ return (0);
+}
+
+s16 getZoneFromPosition(u8 *page, s16 x, s16 y, s16 width) {
+ u8 *ptr = page + (y * width) + x / 2;
+ u8 zoneVar;
+
+ if (!(x % 2)) {
+ zoneVar = (*(ptr) >> 4) & 0xF;
+ } else {
+ zoneVar = (*(ptr)) & 0xF;
+ }
+
+ return (zoneVar);
+}
+
+s16 getZoneFromPositionRaw(u8 *page, s16 x, s16 y, s16 width) {
+ u8 *ptr = page + (y * width) + x;
+ u8 zoneVar;
+
+ zoneVar = (*(ptr)) & 0xF;
+
+ return (zoneVar);
+}
+
+s16 checkCollision(s16 objIdx, s16 x, s16 y, s16 numZones, s16 zoneIdx) {
+ s16 i;
+ s16 lx;
+ s16 ly;
+
+ lx = objectTable[objIdx].x + x;
+ ly = objectTable[objIdx].y + y;
+
+ for (i = 0; i < numZones; i++) {
+ s16 idx;
+
+ // if(gameType == GAME_OS)
+ {
+ idx =
+ getZoneFromPositionRaw(page3Raw, lx + i, ly, 320);
+ }
+ /* else
+ * {
+ * idx = getZoneFromPosition(page3,lx+i,ly,160);
+ * } */
+
+ ASSERT(idx >= 0 && idx <= NUM_MAX_ZONE);
+
+ if (zoneData[idx] == zoneIdx) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+u16 compareVars(s16 var1, s16 var2) {
+ u16 flag = 0;
+
+ if (var1 == var2) {
+ flag |= 1;
+ }
+
+ if (var1 > var2) {
+ flag |= 2;
+ }
+
+ if (var1 < var2) {
+ flag |= 4;
+ }
+
+ return flag;
+}
+
+void executeScript(prcLinkedListStruct *scriptElement, u16 param) {
+ byte *currentScriptPtr;
+ u16 closeScript;
+ u16 currentPosition;
+
+ ASSERT_PTR(scriptElement);
+
+ if (scriptElement->scriptIdx == -1) {
+ return;
+ }
+
+ currentScriptPtr = scriptElement->scriptPtr;
+
+ ASSERT_PTR(currentScriptPtr);
+
+ currentPosition = scriptElement->scriptPosition;
+ closeScript = 0;
+
+ while (!closeScript) {
+ u16 currentLine;
+ u16 opcode;
+
+ currentLine = currentPosition;
+
+ opcode = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ //printf("Op: %X\n",opcode-1);
+
+ switch (opcode - 1) {
+ case -1:
+ {
+ break;
+ }
+ case 0x0: //OP_modifyObjectParam
+ {
+ u8 objIdx;
+ u8 paramIdx;
+ s16 newValue;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ paramIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ newValue =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & newValue);
+
+ DEBUG_SCRIPT(currentLine,
+ "modifyObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)",
+ objIdx, paramIdx, newValue);
+
+ modifyObjectParam(objIdx, paramIdx, newValue);
+
+ break;
+ }
+ case 0x1: //OP_getObjectParam
+ {
+ u8 objIdx;
+ u8 paramIdx;
+ u8 newValue;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ paramIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ newValue =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "getObjectParam(objIdx:%d,paramIdx:%d,var:%d)",
+ objIdx, paramIdx, newValue);
+
+ scriptElement->localVars[newValue] =
+ getObjectParam(objIdx, paramIdx);
+
+ break;
+ }
+ case 0x2:
+ {
+ u8 objIdx;
+ u8 paramIdx;
+ s16 newValue;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ paramIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ newValue =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & newValue);
+
+ DEBUG_SCRIPT(currentLine,
+ "addObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)",
+ objIdx, paramIdx, newValue);
+
+ addObjectParam(objIdx, paramIdx, newValue);
+
+ break;
+ }
+ case 0x3:
+ {
+ u8 objIdx;
+ u8 paramIdx;
+ s16 newValue;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ paramIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ newValue =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & newValue);
+
+ DEBUG_SCRIPT(currentLine,
+ "subObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)",
+ objIdx, paramIdx, newValue);
+
+ subObjectParam(objIdx, paramIdx, newValue);
+
+ break;
+ }
+ case 0x6:
+ {
+ u8 objIdx;
+ u8 param1;
+ s16 param2;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "compareObjectParam(objIdx:%d,type:%d,value:%d)",
+ objIdx, param1, param2);
+
+ scriptElement->compareResult =
+ compareObjectParam(objIdx, param1, param2);
+
+ break;
+ }
+ case 0x7:
+ {
+ u8 objIdx;
+ s16 param1;
+ s16 param2;
+ s16 param3;
+ s16 param4;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param1 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param1);
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ param3 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param3);
+
+ param4 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param4);
+
+ DEBUG_SCRIPT(currentLine,
+ "setupObject(objIdx:%d,%d,%d,%d,%d)",
+ objIdx, param1, param2, param3, param4);
+
+ setupObject(objIdx, param1, param2, param3,
+ param4);
+
+ break;
+ }
+ case 0x8:
+ {
+ u8 objIdx;
+ s16 param1;
+ s16 param2;
+ s16 param3;
+ s16 param4;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param1 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param1);
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ param3 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param3);
+
+ param4 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param4);
+
+ DEBUG_SCRIPT(currentLine,
+ "checkCollision(objIdx:%d,%d,%d,%d,%d)",
+ objIdx, param1, param2, param3, param4);
+
+ scriptElement->compareResult =
+ checkCollision(objIdx, param1, param2,
+ param3, param4);
+
+ break;
+ }
+ case 0x9: // OP_loadVar
+ {
+ u8 varIdx;
+ u8 varType;
+
+ varIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ varType =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (varType) {
+ u8 dataIdx;
+
+ dataIdx =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ switch (varType) {
+ case 1:
+ {
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = var[%d]",
+ varIdx, dataIdx);
+ scriptElement->
+ localVars[varIdx] =
+ scriptElement->
+ localVars[dataIdx];
+ break;
+ }
+ case 2:
+ {
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = globalVars[%d]",
+ varIdx, dataIdx);
+ scriptElement->
+ localVars[varIdx] =
+ globalVars
+ [dataIdx];
+ break;
+ }
+ case 3:
+ {
+ s16 var;
+
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = mouseX",
+ varIdx, dataIdx);
+ getMouseData
+ (mouseUpdateStatus,
+ &dummyU16,
+ (u16 *) & var,
+ (u16 *) &
+ dummyU16);
+ scriptElement->
+ localVars[varIdx] =
+ var;
+ break;
+ }
+ case 4:
+ {
+ s16 var;
+
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = mouseY",
+ varIdx, dataIdx);
+ getMouseData
+ (mouseUpdateStatus,
+ &dummyU16,
+ (u16 *) & dummyU16,
+ (u16 *) & var);
+ scriptElement->
+ localVars[varIdx] =
+ var;
+ break;
+ }
+ case 5:
+ {
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = rand mod %d",
+ varIdx, dataIdx);
+ scriptElement->
+ localVars[varIdx] =
+ rand() % dataIdx;
+ break;
+ }
+ case 8:
+ {
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = file[%d].packedSize",
+ varIdx, dataIdx);
+ scriptElement->
+ localVars[varIdx] =
+ partBuffer
+ [dataIdx].
+ packed_size;
+ break;
+ }
+ case 9:
+ {
+ DEBUG_SCRIPT
+ (currentLine,
+ "var[%d] = file[%d].unpackedSize",
+ varIdx, dataIdx);
+ scriptElement->
+ localVars[varIdx] =
+ partBuffer
+ [dataIdx].
+ unpacked_size;
+ break;
+ }
+ default:
+ {
+ ASSERT(0);
+ }
+ }
+ } else {
+ s16 newData;
+
+ newData =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & newData);
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] = %d", varIdx, newData);
+
+ scriptElement->localVars[varIdx] =
+ newData;
+ }
+ break;
+ }
+ case 0xA: // OP_addVar
+ {
+ u8 param1;
+ u8 type;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 param2;
+
+ param2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] += var[%d]", param1,
+ param2);
+
+ scriptElement->localVars[param1] +=
+ scriptElement->localVars[param2];
+ } else {
+ s16 param2;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] += %d", param1, param2);
+
+ scriptElement->localVars[param1] +=
+ param2;
+ }
+
+ break;
+ }
+ case 0xB: // OP_subVar
+ {
+ u8 param1;
+ u8 type;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 param2;
+
+ param2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] -= var[%d]", param1,
+ param2);
+
+ scriptElement->localVars[param1] =
+ scriptElement->localVars[param1] -
+ scriptElement->localVars[param2];
+ } else {
+ s16 param2;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] -= %d", param1, param2);
+
+ scriptElement->localVars[param1] =
+ scriptElement->localVars[param1] -
+ param2;
+ }
+
+ break;
+ }
+ case 0xC: // OP_mulVar
+ {
+ u8 param1;
+ u8 type;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 param2;
+
+ param2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] *= var[%d]", param1,
+ param2);
+
+ scriptElement->localVars[param1] =
+ scriptElement->localVars[param1] *
+ scriptElement->localVars[param2];
+ } else {
+ s16 param2;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] *= %d", param1, param2);
+
+ scriptElement->localVars[param1] =
+ scriptElement->localVars[param1] *
+ param2;
+ }
+
+ break;
+ }
+ case 0xD: // OP_modVar
+ {
+ u8 param1;
+ u8 type;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 param2;
+
+ param2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] /= var[%d]", param1,
+ param2);
+
+ scriptElement->localVars[param1] =
+ scriptElement->localVars[param1] /
+ scriptElement->localVars[param2];
+ } else {
+ s16 param2;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "var[%d] /= %d", param1, param2);
+
+ scriptElement->localVars[param1] =
+ scriptElement->localVars[param1] /
+ param2;
+ }
+
+ break;
+ }
+ case 0xE: // OP_ compareVar
+ {
+ u8 varIdx;
+ u8 varType;
+
+ varIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ varType =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (varType) {
+ u8 value;
+
+ value =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ // printf("Val: %d\n",value);
+
+ if (varType == 1) {
+ DEBUG_SCRIPT(currentLine,
+ "compare var[%d] and var[%d]",
+ varIdx, value);
+
+ ASSERT(varIdx < 50);
+ ASSERT(value < 50);
+
+ scriptElement->compareResult =
+ compareVars(scriptElement->
+ localVars[varIdx],
+ scriptElement->
+ localVars[value]);
+ } else if (varType == 2) {
+ DEBUG_SCRIPT(currentLine,
+ "compare var[%d] and globalVar[%d]",
+ varIdx, value);
+
+ ASSERT(varIdx < 50);
+ ASSERT(value < 256);
+
+ scriptElement->compareResult =
+ compareVars(scriptElement->
+ localVars[varIdx],
+ globalVars[value]);
+ }
+ } else {
+ s16 value;
+
+ value =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & value);
+
+ DEBUG_SCRIPT(currentLine,
+ "compare var[%d] and %d", varIdx,
+ value);
+
+ scriptElement->compareResult =
+ compareVars(scriptElement->
+ localVars[varIdx], value);
+ }
+
+ break;
+ }
+ case 0xF: //OP_modifyObjectParam2
+ {
+ u8 objIdx;
+ u8 paramIdx;
+ u8 newValue;
+
+ objIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ paramIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ newValue =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "modifyObjectParam2(objIdx:%d,paramIdx:%d,var[%d])",
+ objIdx, paramIdx, newValue);
+
+ modifyObjectParam(objIdx, paramIdx,
+ scriptElement->localVars[newValue]);
+
+ break;
+ }
+ case 0x13: // OP_loadV7Element
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "addSpriteOverlay(%d)", param);
+
+ loadOverlayElement(param, 0);
+
+ break;
+ }
+ case 0x14:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "removeSpriteOverlay(%d)", param);
+
+ freeOverlay(param, 0);
+
+ break;
+ }
+ case 0x15:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "addToBGList(%d)",
+ param);
+
+ addToBGList(param);
+
+ break;
+ }
+ case 0x16:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "addOverlay1(%d)",
+ param);
+
+ loadOverlayElement(param, 1);
+
+ break;
+ }
+ case 0x17:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "removeOverlay1(%d)",
+ param);
+
+ freeOverlay(param, 1);
+
+ break;
+ }
+ case 0x18:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "addOverlayType4(%d)", param);
+
+ loadOverlayElement(param, 4);
+
+ break;
+ }
+ case 0x19:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "removeSpriteOverlay4(%d)", param);
+
+ freeOverlay(param, 4);
+
+ break;
+ }
+ case 0x1A:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "op1A(%d) -> TODO !",
+ param);
+
+ addSpriteFilledToBGList(param);
+
+ break;
+ }
+ case 0x1B:
+ {
+ DEBUG_SCRIPT(currentLine, "closeEngine7");
+ closeEngine7();
+ break;
+ }
+ case 0x1D: // OP_label
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "label(%d)",
+ labelIdx);
+
+ scriptElement->stack[labelIdx] =
+ currentPosition;
+
+ break;
+ }
+ case 0x1E: // OP_goto
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "goto label(%d)",
+ labelIdx);
+
+ ASSERT(scriptElement->stack[labelIdx] !=
+ 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+
+ break;
+ }
+ case 0x1F: // OP_gotoIfSup
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if ((scriptElement->compareResult & 2)
+ && !(scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(>) goto %d (true)", labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(>) goto %d (false)", labelIdx);
+ }
+
+ break;
+ }
+ case 0x20: // OP_gotoIfSupEqu
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (scriptElement->compareResult & 2
+ || scriptElement->compareResult & 1) {
+ DEBUG_SCRIPT(currentLine,
+ "if(>=) goto %d (true)", labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(>=) goto %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x21: // OP_gotoIfInf
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if ((scriptElement->compareResult & 4)
+ && !(scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(<) goto %d (true)", labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(<) goto %d (false)", labelIdx);
+ }
+
+ break;
+ }
+ case 0x22: // OP_gotoIfInfEqu
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if ((scriptElement->compareResult & 4)
+ || (scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(<=) goto %d (true)", labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(<=) goto %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x23: // OP_gotoIfEqu
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (scriptElement->compareResult & 1) {
+ DEBUG_SCRIPT(currentLine,
+ "if(==) goto %d (true)", labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(==) goto %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x24: // OP_gotoIfDiff
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (!(scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(!=) goto %d (true)", labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(!=) goto %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x26: // loop
+ {
+ u8 varIdx;
+ u8 labelIdx;
+
+ varIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ scriptElement->localVars[varIdx]--;
+
+ if (scriptElement->localVars[varIdx] >= 0) {
+ DEBUG_SCRIPT(currentLine,
+ "loop(var[%]) goto %d (continue)",
+ varIdx, labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ scriptElement->stack[labelIdx];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "loop(var[%]) goto %d (stop)",
+ varIdx, labelIdx);
+ }
+
+ break;
+ }
+ case 0x31: // OP_startScript
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ ASSERT(param >= 0 && param < NUM_MAX_SCRIPT);
+
+ DEBUG_SCRIPT(currentLine, "startScript(%d)",
+ param);
+
+ addScriptToList0(param);
+ break;
+ }
+ case 0x32:
+ {
+ u8 scriptIdx;
+
+ scriptIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "stopGlobalScript(%d)", scriptIdx);
+
+ stopGlobalScript(scriptIdx);
+ break;
+ }
+ case 0x3B: // OP_loadResource
+ {
+ DEBUG_SCRIPT(currentLine,
+ "loadResource(\"%s\")",
+ currentScriptPtr + currentPosition);
+
+ loadResource((char *)(currentScriptPtr +
+ currentPosition));
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+
+ break;
+ }
+ case 0x3C: // OP_loadBg
+ {
+ DEBUG_SCRIPT(currentLine, "loadBg(\"%s\")",
+ currentScriptPtr + currentPosition);
+
+ loadBg((char *)(currentScriptPtr +
+ currentPosition));
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+
+ closeEngine7();
+
+ bgVar0 = 0;
+
+ break;
+ }
+ case 0x3D: // OP_loadCt
+ {
+ DEBUG_SCRIPT(currentLine, "loadCt(\"%s\")",
+ currentScriptPtr + currentPosition);
+
+ loadCt((char *)(currentScriptPtr +
+ currentPosition));
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+
+ break;
+ }
+ case 0x3F: // OP_loadPart
+ {
+ DEBUG_SCRIPT(currentLine, "loadPart(\"%s\")",
+ currentScriptPtr + currentPosition);
+
+ if (gameType == Cine::GID_FW)
+ loadPart((char *)(currentScriptPtr +
+ currentPosition));
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ case 0x40:
+ {
+ DEBUG_SCRIPT(currentLine, "closePart");
+
+ closePart();
+
+ break;
+ }
+ case 0x41: // OP_loadData
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ ASSERT(param >= 0 && param <= 3);
+
+ switch (param) {
+ case 0:
+ {
+ DEBUG_SCRIPT(currentLine,
+ "loadPrc(\"%s\")",
+ currentScriptPtr +
+ currentPosition);
+ strcpy(newPrcName,
+ (char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ case 1:
+ {
+ DEBUG_SCRIPT(currentLine,
+ "loadRel(\"%s\")",
+ currentScriptPtr +
+ currentPosition);
+ strcpy(newRelName,
+ (char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ case 2:
+ {
+ DEBUG_SCRIPT(currentLine,
+ "loadObject(\"%s\")",
+ currentScriptPtr +
+ currentPosition);
+ strcpy(newObjectName,
+ (char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ case 3:
+ {
+ DEBUG_SCRIPT(currentLine,
+ "loadMsg(\"%s\")",
+ currentScriptPtr +
+ currentPosition);
+ strcpy(newMsgName,
+ (char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ }
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition)) + 1;
+ break;
+ }
+ case 0x42:
+ {
+ DEBUG_SCRIPT(currentLine, "request data load");
+ checkForPendingDataLoadSwitch = 1;
+ break;
+ }
+ case 0x45:
+ {
+ DEBUG_SCRIPT(currentLine, "request fadein");
+ // TODO: use real code
+
+ memcpy(c_palette, tempPalette,
+ sizeof(u16) * 16);
+ drawOverlays();
+ flip();
+
+ fadeRequired = 1;
+ break;
+ }
+ case 0x46:
+ {
+ DEBUG_SCRIPT(currentLine, "request fadeout");
+ //fadeToBlack();
+ break;
+ }
+ case 0x47:
+ {
+ u8 startColor;
+ u8 numColor;
+ u16 r;
+ u16 g;
+ u16 b;
+
+ startColor =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ numColor =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ r = *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&r);
+
+ g = *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&g);
+
+ b = *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&b);
+
+ DEBUG_SCRIPT(currentLine,
+ "transformPaletteRange(from:%d,numIdx:%d,r:%d,g:%d,b:%d) -> unimplemented",
+ startColor, numColor, r, g, b);
+
+ transformPaletteRange(startColor, numColor, r,
+ g, b);
+
+ break;
+ }
+ case 0x4A:
+ {
+ u8 var1;
+ u8 var2;
+ u8 var3;
+
+ var1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ var2 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ var3 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "palRotate(%d,%d,%d)", var1, var2, var3);
+
+ palRotate(var1, var2, var3);
+ break;
+ }
+ case 0x4F: // break;
+ {
+ DEBUG_SCRIPT(currentLine, "break");
+
+ scriptElement->scriptPosition =
+ currentPosition;
+ closeScript = 1;
+ break;
+ }
+ case 0x49:
+ {
+ defaultMenuBoxColor2 =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "setDefaultMenuColor2(%d)",
+ defaultMenuBoxColor2);
+
+ break;
+ }
+ case 0x50: // OP_endScript
+ {
+ DEBUG_SCRIPT(currentLine, "endScript");
+
+ if (param == 0) {
+ endScript0(scriptElement->scriptIdx);
+ } else {
+ endScript1(scriptElement->scriptIdx);
+ }
+
+ closeScript = 1;
+
+ break;
+ }
+ case 0x51:
+ {
+ u8 param1;
+ u16 param2;
+ u16 param3;
+ u16 param4;
+ u16 param5;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param2);
+
+ param3 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param3);
+
+ param4 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param4);
+
+ param5 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param5);
+
+ DEBUG_SCRIPT(currentLine,
+ "message(%d,%d,%d,%d,%d)", param1, param2,
+ param3, param4, param5);
+
+ addMessage(param1, param2, param3, param4,
+ param5);
+
+ break;
+ }
+ case 0x52: // OP_loadGlobalVar
+ {
+ u8 idx;
+ u8 type;
+
+ idx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 idx2;
+
+ idx2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ if (type == 1) {
+ DEBUG_SCRIPT(currentLine,
+ "globalVars[%d] = var[%d]",
+ idx, idx2);
+
+ globalVars[idx] =
+ scriptElement->
+ localVars[idx2];
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "globalVars[%d] = globalVars[%d]",
+ idx, idx2);
+
+ globalVars[idx] =
+ globalVars[idx2];
+ }
+ } else {
+ u16 newData;
+
+ newData =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&newData);
+
+ DEBUG_SCRIPT(currentLine,
+ "globalVars[%d] = %d", idx,
+ newData);
+
+ globalVars[idx] = newData;
+ }
+
+ break;
+ }
+ case 0x53: // OP_compareGlobalVar
+ {
+ u8 idx;
+ u8 type;
+
+ idx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 var2;
+
+ var2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "compare globalVars[%d] and var[%d]",
+ idx, var2);
+
+ scriptElement->compareResult =
+ compareVars(globalVars[idx],
+ scriptElement->localVars[var2]);
+ } else {
+ u16 newData;
+
+ newData =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&newData);
+
+ DEBUG_SCRIPT(currentLine,
+ "compare globalVars[%d] and %d",
+ idx, newData);
+
+ if (idx == 255 && (gameType == Cine::GID_FW)) // TODO: fix
+ {
+ scriptElement->compareResult =
+ 1;
+ } else {
+ scriptElement->compareResult =
+ compareVars(globalVars
+ [idx], newData);
+ }
+ }
+
+ break;
+ }
+ case 0x59:
+ {
+ DEBUG_SCRIPT(currentLine, "comment(%s)",
+ currentScriptPtr + currentPosition);
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ case 0x5A:
+ {
+ u8 startIdx;
+ u8 numIdx;
+
+ startIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ numIdx = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ ASSERT(startIdx <= NUM_MAX_PARTDATA);
+ ASSERT(startIdx + numIdx <= NUM_MAX_PARTDATA);
+
+ DEBUG_SCRIPT(currentLine,
+ "freePartRange(%d,%d)", startIdx, numIdx);
+
+ freePartRange(startIdx, numIdx);
+
+ break;
+ }
+ case 0x5B:
+ {
+ DEBUG_SCRIPT(currentLine, "unloadAllMasks()");
+
+ unloadAllMasks();
+
+ break;
+ }
+ case 0x65:
+ {
+ u8 i;
+
+ DEBUG_SCRIPT(currentLine,
+ "initializeZoneData()");
+
+ for (i = 0; i < NUM_MAX_ZONE; i++) {
+ zoneData[i] = i;
+ }
+
+ break;
+ }
+ case 0x66:
+ {
+ u8 zoneIdx;
+ u16 var;
+
+ zoneIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ var =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&var);
+
+ DEBUG_SCRIPT(currentLine, "setZone[%d] = %d",
+ zoneIdx, var);
+
+ zoneData[zoneIdx] = var;
+
+ break;
+ }
+ case 0x68:
+ {
+ defaultMenuBoxColor =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "setDefaultMenuColor(%d)",
+ defaultMenuBoxColor2);
+
+ break;
+ }
+ case 0x69: // OP_allowPlayerInput
+ {
+ DEBUG_SCRIPT(currentLine,
+ "allowPlayerInput()");
+
+ allowPlayerInput = 1;
+ break;
+ }
+ case 0x6A: // OP_dissallowPlayerInput
+ {
+ DEBUG_SCRIPT(currentLine,
+ "dissallowPlayerInput()");
+
+ allowPlayerInput = 0;
+ break;
+ }
+ case 0x6B: // OP_changeDataDisk
+ {
+ u8 newDisk;
+
+ newDisk =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "changeDataDisk(%d)",
+ newDisk);
+
+ checkDataDisk(newDisk);
+ break;
+ }
+ case 0x6D:
+ {
+ DEBUG_SCRIPT(currentLine, "loadMusic(%s)",
+ currentScriptPtr + currentPosition);
+ snd_loadSong((char *)(currentScriptPtr +
+ currentPosition));
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition)) + 1;
+ break;
+ }
+ case 0x6E:
+ {
+ DEBUG_SCRIPT(currentLine, "playMusic()");
+ snd_playSong();
+ break;
+ }
+ case 0x6F:
+ {
+ DEBUG_SCRIPT(currentLine, "fadeOutMusic()");
+ snd_fadeOutSong();
+ break;
+ }
+ case 0x70:
+ {
+ DEBUG_SCRIPT(currentLine, "stopSample()");
+ snd_stopSong();
+ break;
+ }
+ case 0x77:
+ case 0x78:
+ {
+ DEBUG_SCRIPT(currentLine, "playSample()");
+ u8 anim, channel;
+ s16 volume;
+ u16 flag;
+
+ anim = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ channel =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ /* unused */
+ currentPosition += 2;
+
+ /* unused */
+
+ currentPosition++;
+
+ volume =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16((u16 *) & volume);
+
+ flag =
+ *(u16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&flag);
+
+ if (volume > 63)
+ volume = 63;
+ if (volume < 0)
+ volume = 63;
+
+ if (animDataTable[anim].ptr1) {
+ if (channel >= 10)
+ channel -= 10;
+ if (volume < 50)
+ volume = 50;
+ if (snd_songIsPlaying)
+ snd_stopSong();
+ if (flag == 0xFFFF)
+ (*snd_driver.
+ playSound) (animDataTable
+ [anim].ptr1, channel,
+ volume);
+ else
+ snd_resetChannel(channel);
+ }
+ break;
+ }
+ case 0x79:
+ {
+ var22 = *(currentScriptPtr + currentPosition);
+
+ DEBUG_SCRIPT(currentLine,
+ "OP79 load var22 to %d -> TODO", var22);
+
+ currentPosition++;
+ break;
+ }
+ case 0x7A:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "addOverlay5(%d)",
+ param);
+
+ loadOverlayElement(param, 5);
+
+ break;
+ }
+ case 0x7B:
+ {
+ u8 param;
+
+ param = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "freeOverlay5(%d)",
+ param);
+
+ freeOverlay(param, 5);
+
+ break;
+ }
+ case 0x7F:
+ {
+ u8 param1;
+ u8 param2;
+ u8 param3;
+ u8 param4;
+ u16 param5;
+ u16 param6;
+ u16 param7;
+
+ param1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param2 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param3 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param4 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ param5 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+
+ param6 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+
+ param7 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+
+ flipU16(&param5);
+ flipU16(&param6);
+ flipU16(&param7);
+
+ DEBUG_SCRIPT(currentLine,
+ "addUnkListElement(%d,%d,%d,%d,%d)",
+ param1, param2, param3, param4, param5,
+ param6, param7);
+
+ addUnkListElement(param1, 0, param2, param3,
+ param4, param5, param6, 0, param7);
+
+ break;
+ }
+ case 0x80:
+ {
+ u8 var1;
+ u8 var2;
+
+ var1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ var2 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "removeSeq(%d,%d) -> TODO", var1, var2);
+
+ removeSeq(var1, 0, var2);
+
+ break;
+ }
+ case 0x83:
+ {
+ u8 var1;
+ u8 var2;
+
+ var1 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ var2 = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "OP83(%d,%d) -> TODO", var1, var2);
+
+ if (isSeqRunning(var1, 0, var2)) {
+ scriptElement->compareResult = 1;
+ } else {
+ scriptElement->compareResult = 0;
+ }
+ break;
+ }
+ case 0x84: // OP_gotoIfSup nearest
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if ((scriptElement->compareResult & 2)
+ && !(scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(>) goto nearest %d (true)",
+ labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ computeScriptStackFromScript
+ (scriptElement->scriptPtr,
+ currentPosition, labelIdx,
+ scriptTable[scriptElement->
+ scriptIdx].var4);
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(>) goto nearest %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x85: // OP_gotoIfSupEqu nearest
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (scriptElement->compareResult & 2
+ || scriptElement->compareResult & 1) {
+ DEBUG_SCRIPT(currentLine,
+ "if(>=) goto nearest %d (true)",
+ labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ computeScriptStackFromScript
+ (scriptElement->scriptPtr,
+ currentPosition, labelIdx,
+ scriptTable[scriptElement->
+ scriptIdx].var4);
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(>=) goto nearest %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x86: // OP_gotoIfInf nearest
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if ((scriptElement->compareResult & 4)
+ && !(scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(<) goto nearest %d (true)",
+ labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ computeScriptStackFromScript
+ (scriptElement->scriptPtr,
+ currentPosition, labelIdx,
+ scriptTable[scriptElement->
+ scriptIdx].var4);
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(<) goto nearest %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x87: // OP_gotoIfInfEqu nearest
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if ((scriptElement->compareResult & 4)
+ || (scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(<=) goto nearest %d (true)",
+ labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ computeScriptStackFromScript
+ (scriptElement->scriptPtr,
+ currentPosition, labelIdx,
+ scriptTable[scriptElement->
+ scriptIdx].var4);
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(<=) goto nearest %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x88: // OP_gotoIfEqu nearest
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (scriptElement->compareResult & 1) {
+ DEBUG_SCRIPT(currentLine,
+ "if(==) goto nearest %d (true)",
+ labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ computeScriptStackFromScript
+ (scriptElement->scriptPtr,
+ currentPosition, labelIdx,
+ scriptTable[scriptElement->
+ scriptIdx].var4);
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(==) goto nearest %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x89: // OP_gotoIfDiff nearest
+ {
+ u8 labelIdx;
+
+ labelIdx =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (!(scriptElement->compareResult & 1)) {
+ DEBUG_SCRIPT(currentLine,
+ "if(!=) goto nearest %d (true)",
+ labelIdx);
+ ASSERT(scriptElement->
+ stack[labelIdx] != 0xFFFF);
+ currentPosition =
+ computeScriptStackFromScript
+ (scriptElement->scriptPtr,
+ currentPosition, labelIdx,
+ scriptTable[scriptElement->
+ scriptIdx].var4);
+ } else {
+ DEBUG_SCRIPT(currentLine,
+ "if(!=) goto nearest %d (false)",
+ labelIdx);
+ }
+
+ break;
+ }
+ case 0x8B:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "startObjectScript(%d,%d)", temp,
+ currentScriptPtr + currentPosition);
+
+ runObjectScript(temp);
+ break;
+ }
+ case 0x8C:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "startObjectScript(%d,%d)", temp,
+ currentScriptPtr + currentPosition);
+
+ stopObjectScript(temp);
+ break;
+ }
+ case 0x8E:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "addBackground(%s,%d)",
+ currentScriptPtr + currentPosition, temp);
+
+ addBackground((char *)(currentScriptPtr +
+ currentPosition), temp);
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+ break;
+ }
+ case 0x8F:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "removeBackground(%d)", temp);
+
+ ASSERT(temp);
+ if (additionalBgTable[temp]) {
+ free(additionalBgTable[temp]);
+ additionalBgTable[temp] = NULL;
+ }
+
+ if (currentAdditionalBgIdx == temp) {
+ currentAdditionalBgIdx = 0;
+ }
+
+ if (currentAdditionalBgIdx2 == temp) {
+ currentAdditionalBgIdx = 0;
+ }
+
+ strcpy(currentBgName[temp], "");
+
+ break;
+ }
+ case 0x90:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "loadABS(%d,%s)",
+ temp, currentScriptPtr + currentPosition);
+
+ loadAbs((char *)(currentScriptPtr +
+ currentPosition), temp);
+
+ currentPosition +=
+ strlen((char *)(currentScriptPtr +
+ currentPosition));
+
+ break;
+ }
+ case 0x91:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "useBg(%d)", temp);
+
+ ASSERT(temp >= 0 && temp <= 8);
+
+ if (additionalBgTable[temp]) {
+ currentAdditionalBgIdx = temp;
+ /* if(adBgVar0 == 0)
+ * {
+ * adBgVar1 = 1;
+ * } */
+ }
+ break;
+ }
+ case 0x9D:
+ {
+ u8 temp =
+ *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine, "useBgScroll(%d)",
+ temp);
+
+ ASSERT(temp >= 0 && temp <= 8);
+
+ if (additionalBgTable[temp]) {
+ currentAdditionalBgIdx2 = temp;
+ }
+ break;
+ }
+ case 0x9E:
+ {
+ u8 type;
+
+ type = *(currentScriptPtr + currentPosition);
+ currentPosition++;
+
+ if (type) {
+ u8 param2;
+
+ param2 =
+ *(currentScriptPtr +
+ currentPosition);
+ currentPosition++;
+
+ DEBUG_SCRIPT(currentLine,
+ "additionalBgVScroll = var[%d]",
+ param2);
+
+ additionalBgVScroll =
+ scriptElement->localVars[param2];
+ } else {
+ u16 param2;
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "additionalBgVScroll = %d",
+ param2);
+
+ additionalBgVScroll = param2;
+ }
+
+ break;
+ }
+ case 0xA0:
+ {
+ u16 param1;
+ u16 param2;
+
+ param1 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param1);
+
+ param2 =
+ *(s16 *) (currentScriptPtr +
+ currentPosition);
+ currentPosition += 2;
+ flipU16(&param2);
+
+ DEBUG_SCRIPT(currentLine,
+ "addGfxElementA0(%d,%d)", param1, param2);
+
+ addGfxElementA0(param1, param2);
+ break;
+ }
+ case 0xA1:
+ {
+ currentPosition += 4;
+ break;
+ }
+ case 0xA2:
+ {
+ currentPosition += 4;
+ break;
+ }
+ case 0xA3:
+ {
+ currentPosition += 4;
+ break;
+ }
+ default:
+ {
+ printf("Unsupported opcode %X\n", opcode - 1);
+ exit(1);
+ }
+ }
+ }
+}
+
+void executeList1(void) {
+ prcLinkedListStruct *currentHead = objScriptList.next;
+
+ while (currentHead) {
+ prcLinkedListStruct *tempHead;
+
+ tempHead = currentHead->next;
+
+ executeScript(currentHead, 1);
+
+ currentHead = tempHead;
+ }
+}
+
+void executeList0(void) {
+ prcLinkedListStruct *currentHead = globalScriptsHead.next;
+
+ while (currentHead) {
+ prcLinkedListStruct *tempHead;
+
+ executeScript(currentHead, 0);
+
+ tempHead = currentHead->next;
+ currentHead = tempHead;
+ }
+}
+
+void purgeList1(void) {
+}
+
+void purgeList0(void)
+{
+}
+
+////////////////////////////////////
+// SCRIPT DECOMPILER
+
+#ifdef DUMP_SCRIPTS
+
+u8 decompileBuffer[10000][1000];
+u16 decompileBufferPosition = 0;
+
+u8 bufferDec[256];
+
+u8 compareString1[256];
+u8 compareString2[256];
+
+u8 *getObjPramName(u8 paramIdx) {
+ switch (paramIdx) {
+ case 1:
+ {
+ return (".X");
+ }
+ case 2:
+ {
+ return (".Y");
+ }
+ case 3:
+ {
+ return (".mask");
+ }
+ case 4:
+ {
+ return (".frame");
+ }
+ case 5:
+ {
+ return (".status");
+ }
+ case 6:
+ {
+ return (".costume");
+ }
+ default:
+ {
+ sprintf(bufferDec, ".param%d", paramIdx);
+ return (bufferDec);
+ }
+ }
+}
+
+void decompileScript(u8 *scriptPtr, s16 *stackPtr, u16 scriptSize,
+ u16 scriptIdx) {
+ u8 lineBuffer[256];
+ u8 *localScriptPtr = scriptPtr;
+ u16 exitScript;
+ u32 position = 0;
+
+ ASSERT_PTR(scriptPtr);
+ // ASSERT_PTR(stackPtr);
+
+ exitScript = 0;
+
+ sprintf(decompileBuffer[decompileBufferPosition++],
+ "--------- SCRIPT %d ---------\n", scriptIdx);
+
+ do {
+ u16 opcode = *(localScriptPtr + position);
+ position++;
+
+ if (position == scriptSize) {
+ opcode = 0;
+ }
+
+ printf("%X\n", opcode - 1);
+
+ strcpy(lineBuffer, "");
+
+ switch (opcode - 1) {
+ case -1:
+ {
+ break;
+ }
+ case 0x0:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "obj[%d]%s = %d\n", param1,
+ getObjPramName(param2), param3);
+
+ break;
+ }
+ case 0x1:
+ {
+ u8 param1;
+ u8 param2;
+ u8 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "var[%d]=obj[%d]%s\n",
+ param3, param1, getObjPramName(param2));
+ break;
+ }
+ case 0x2:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "obj[%d]%s+=%d\n", param1,
+ getObjPramName(param2), param3);
+
+ break;
+ }
+ case 0x3:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "obj[%d]%s-=%d\n", param1,
+ getObjPramName(param2), param3);
+
+ break;
+ }
+ case 0x4:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "obj[%d]%s+=obj[%d]%s\n",
+ param1, getObjPramName(param2), param3,
+ getObjPramName(param2));
+
+ break;
+ }
+ case 0x5:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "obj[%d]%s-=obj[%d]%s\n",
+ param1, getObjPramName(param2), param3,
+ getObjPramName(param2));
+
+ break;
+ }
+ case 0x6:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(compareString1, "obj[%d]%s", param1,
+ getObjPramName(param2));
+ sprintf(compareString2, "%d", param3);
+
+ break;
+ }
+ case 0x7:
+ {
+ u8 param1;
+ s16 param2;
+ s16 param3;
+ s16 param4;
+ s16 param5;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param4 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param2);
+ flipU16(&param3);
+ flipU16(&param4);
+ flipU16(&param5);
+
+ sprintf(lineBuffer,
+ "setupObject(Idx:%d,X:%d,Y:%d,mask:%d,frame:%d)\n",
+ param1, param2, param3, param4, param5);
+
+ break;
+ }
+ case 0x8:
+ {
+ u8 param1;
+ s16 param2;
+ s16 param3;
+ s16 param4;
+ s16 param5;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param4 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param2);
+ flipU16(&param3);
+ flipU16(&param4);
+ flipU16(&param5);
+
+ sprintf(lineBuffer,
+ "checkCollision(%d,%d,%d,%d,%d)\n", param1,
+ param2, param3, param4, param5);
+
+ break;
+ }
+ case 0x9:
+ {
+ u8 param1;
+ s16 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ if (param2 == 1) {
+ sprintf(lineBuffer,
+ "var[%d]=var[%d]\n",
+ param1, param3);
+ } else if (param2 == 2) {
+ sprintf(lineBuffer,
+ "var[%d]=globalVar[%d]\n",
+ param1, param3);
+ } else if (param2 == 3) {
+ sprintf(lineBuffer,
+ "var[%d]=mouse.X\n",
+ param1);
+ } else if (param2 == 4) {
+ sprintf(lineBuffer,
+ "var[%d]=mouse.Y\n",
+ param1);
+ } else if (param2 == 5) {
+ sprintf(lineBuffer,
+ "var[%d]=rand() mod %d\n",
+ param1, param3);
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "var[%d]=%d\n",
+ param1, param3);
+ }
+
+ break;
+ }
+ case 0xA:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "var[%d]+=var[%d]\n", param1,
+ param3);
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "var[%d]+=%d\n",
+ param1, param3);
+ }
+ break;
+ }
+ case 0xB:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "var[%d]-=var[%d]\n", param1,
+ param3);
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "var[%d]-=%d\n",
+ param1, param3);
+ }
+ break;
+ }
+ case 0xC:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "var[%d]*=var[%d]\n", param1,
+ param3);
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "var[%d]*=%d\n",
+ param1, param3);
+ }
+ break;
+ }
+ case 0xD:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "var[%d]/=var[%d]\n", param1,
+ param3);
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer, "var[%d]/=%d\n",
+ param1, param3);
+ }
+ break;
+ }
+ case 0xE:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ if (param2 == 1) {
+ sprintf(compareString1,
+ "var[%d]", param1);
+ sprintf(compareString2,
+ "var[%d]", param3);
+
+ } else if (param2 == 2) {
+ sprintf(compareString1,
+ "var[%d]", param1);
+ sprintf(compareString2,
+ "globalVar[%d]", param3);
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(compareString1, "var[%d]",
+ param1);
+ sprintf(compareString2, "%d", param3);
+ }
+ break;
+ }
+ case 0xF:
+ {
+ u8 param1;
+ u8 param2;
+ u8 param3;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "obj[%d]%s=var[%d]\n",
+ param1, getObjPramName(param2), param3);
+
+ break;
+ }
+ case 0x13:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "loadMask0(%d)\n", param);
+
+ break;
+ }
+ case 0x14:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "unloadMask0(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x15:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_15(%d)\n", param);
+
+ break;
+ }
+ case 0x16:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "loadMask1(%d)\n", param);
+
+ break;
+ }
+ case 0x17:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "unloadMask0(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x18:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "loadMask4(%d)\n", param);
+
+ break;
+ }
+ case 0x19:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "unloadMask4(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x1A:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_1A(%d)\n", param);
+
+ break;
+ }
+ case 0x1B:
+ {
+ sprintf(lineBuffer, "closeEngine7()\n");
+ break;
+ }
+ case 0x1D:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "label(%d)\n", param);
+
+ break;
+ }
+ case 0x1E:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "goto(%d)\n", param);
+
+ break;
+ }
+ case 0x1F:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "if(%s>%s) goto(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x20:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "if(%s>=%s) goto(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x21:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "if(%s<%s) goto(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x22:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "if(%s<=%s) goto(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x23:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "if(%s==%s) goto(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x24:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "if(%s!=%s) goto(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x25:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "removeLabel(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x26:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "loop(--var[%d]) -> label(%d)\n", param1,
+ param2);
+
+ break;
+ }
+ case 0x31:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "startGlobalScript(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x32:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "endGlobalScript(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x3B:
+ {
+ sprintf(lineBuffer, "loadResource(%s)\n",
+ localScriptPtr + position);
+
+ position +=
+ strlen(localScriptPtr + position) + 1;
+ break;
+ }
+ case 0x3C:
+ {
+ sprintf(lineBuffer, "loadBg(%s)\n",
+ localScriptPtr + position);
+
+ position +=
+ strlen(localScriptPtr + position) + 1;
+ break;
+ }
+ case 0x3D:
+ {
+ sprintf(lineBuffer, "loadCt(%s)\n",
+ localScriptPtr + position);
+
+ position +=
+ strlen(localScriptPtr + position) + 1;
+ break;
+ }
+ case OP_loadPart:
+ {
+ sprintf(lineBuffer, "loadPart(%s)\n",
+ localScriptPtr + position);
+
+ position +=
+ strlen(localScriptPtr + position) + 1;
+ break;
+ }
+ case 0x40:
+ {
+ sprintf(lineBuffer, "closePart()\n");
+ break;
+ }
+ case OP_loadNewPrcName:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "loadPrc(%d,%s)\n", param,
+ localScriptPtr + position);
+
+ position +=
+ strlen(localScriptPtr + position) + 1;
+ break;
+ }
+ case OP_requestCheckPendingDataLoad: // nop
+ {
+ sprintf(lineBuffer,
+ "requestCheckPendingDataLoad()\n");
+ break;
+ }
+ case 0x45:
+ {
+ sprintf(lineBuffer, "blitAndFade()\n");
+ break;
+ }
+ case 0x46:
+ {
+ sprintf(lineBuffer, "fadeToBlack()\n");
+ break;
+ }
+ case 0x47:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+ s16 param4;
+ s16 param5;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param4 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+ flipU16(&param4);
+ flipU16(&param5);
+
+ sprintf(lineBuffer,
+ "transformPaletteRange(%d,%d,%d,%d,%d)\n",
+ param1, param2, param3, param4, param5);
+
+ break;
+ }
+ case 0x49:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "setDefaultMenuColor2(%d)\n", param);
+
+ break;
+ }
+ case 0x4F:
+ {
+ sprintf(lineBuffer, "break()\n");
+ exitScript = 1;
+ break;
+ }
+ case 0x50:
+ {
+ sprintf(lineBuffer, "endScript()\n\n");
+ break;
+ }
+ case 0x51:
+ {
+ u8 param1;
+ s16 param2;
+ s16 param3;
+ s16 param4;
+ s16 param5;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param4 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param2);
+ flipU16(&param3);
+ flipU16(&param4);
+ flipU16(&param5);
+
+ sprintf(lineBuffer,
+ "message(%d,%d,%d,%d,%d)\n", param1,
+ param2, param3, param4, param5);
+
+ break;
+ }
+ case 0x52:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ if (param2 == 1) {
+ sprintf(lineBuffer,
+ "globalVar[%d] = var[%d]\n",
+ param1, param3);
+ } else if (param2 == 2) {
+ sprintf(lineBuffer,
+ "globalVar[%d] = globalVar[%d]\n",
+ param1, param3);
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(lineBuffer,
+ "globalVar[%d] = %d\n", param1,
+ param3);
+ }
+ break;
+ }
+ case 0x53:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ if (param2) {
+ u8 param3;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ if (param2 == 1) {
+ sprintf(compareString1,
+ "globalVar[%d]", param1);
+ sprintf(compareString2,
+ "var[%d]", param3);
+ } else if (param2 == 2) {
+ sprintf(compareString1,
+ "globalVar[%d]", param1);
+ sprintf(compareString2,
+ "globalVar[%d]", param3);
+ } else {
+ ASSERT(0);
+ }
+ } else {
+ s16 param3;
+
+ param3 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+
+ flipU16(&param3);
+
+ sprintf(compareString1,
+ "globalVar[%d]", param1);
+ sprintf(compareString2, "%d", param3);
+ }
+ break;
+ }
+ case 0x59:
+ {
+ sprintf(lineBuffer, "comment: %s\n",
+ localScriptPtr + position);
+
+ position += strlen(localScriptPtr + position);
+ break;
+ }
+ case 0x5A:
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "freePartRang(%d,%d)\n",
+ param1, param2);
+
+ break;
+ }
+ case 0x5B:
+ {
+ sprintf(lineBuffer, "unloadAllMasks()\n");
+ break;
+ }
+ case 0x65:
+ {
+ sprintf(lineBuffer, "setupTableUnk1()\n");
+ break;
+ }
+ case 0x66:
+ {
+ u8 param1;
+ s16 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param2);
+
+ sprintf(lineBuffer, "tableUnk1[%d] = %d\n",
+ param1, param2);
+
+ break;
+ }
+ case 0x68:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "setDefaultMenuBoxColor(%d)\n", param);
+
+ break;
+ }
+ case 0x69:
+ {
+ sprintf(lineBuffer, "allowPlayerInput()\n");
+ break;
+ }
+ case 0x6A:
+ {
+ sprintf(lineBuffer, "disallowPlayerInput()\n");
+ break;
+ }
+ case OP_changeDataDisk:
+ {
+ u8 newDisk;
+
+ newDisk = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "changeDataDisk(%d)\n",
+ newDisk);
+
+ break;
+ }
+ case 0x6D:
+ {
+ sprintf(lineBuffer, "loadDat(%s)\n",
+ localScriptPtr + position);
+
+ position +=
+ strlen(localScriptPtr + position) + 1;
+ break;
+ }
+ case 0x6E: // nop
+ {
+ sprintf(lineBuffer, "updateDat()\n");
+ break;
+ }
+ case 0x6F:
+ {
+ sprintf(lineBuffer,
+ "OP_6F() -> dat related\n");
+ break;
+ }
+ case 0x70:
+ {
+ sprintf(lineBuffer, "stopSample()\n");
+ break;
+ }
+ case OP_79:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "allowSystemMenu(%d)\n",
+ param);
+
+ break;
+ }
+ case 0x77:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+ u8 param4;
+ s16 param5;
+ s16 param6;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param4 = *(localScriptPtr + position);
+ position++;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param6 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+ flipU16(&param5);
+ flipU16(&param6);
+
+ sprintf(lineBuffer,
+ "playSample(%d,%d,%d,%d,%d,%d)\n", param1,
+ param2, param3, param4, param5, param6);
+
+ break;
+ }
+ case 0x78:
+ {
+ u8 param1;
+ u8 param2;
+ s16 param3;
+ u8 param4;
+ s16 param5;
+ s16 param6;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param4 = *(localScriptPtr + position);
+ position++;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param6 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param3);
+ flipU16(&param5);
+ flipU16(&param6);
+
+ sprintf(lineBuffer,
+ "OP_78(%d,%d,%d,%d,%d,%d)\n", param1,
+ param2, param3, param4, param5, param6);
+
+ break;
+ }
+ case 0x7A:
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_7A(%d)\n", param);
+
+ break;
+ }
+ case 0x7B: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_7B(%d)\n", param);
+
+ break;
+ }
+ case 0x7F: // OS only
+ {
+ u8 param1;
+ u8 param2;
+ u8 param3;
+ u8 param4;
+ s16 param5;
+ s16 param6;
+ s16 param7;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(localScriptPtr + position);
+ position++;
+
+ param4 = *(localScriptPtr + position);
+ position++;
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param6 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ param7 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+
+ flipU16(&param5);
+ flipU16(&param6);
+ flipU16(&param7);
+
+ sprintf(lineBuffer, "OP_7F(%d,%d,%d,%d,%d)\n",
+ param1, param2, param3, param4, param5,
+ param6, param7);
+
+ break;
+ }
+ case 0x80: // OS only
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_80(%d,%d)\n", param1,
+ param2);
+
+ break;
+ }
+ case 0x82: // OS only
+ {
+ u8 param1;
+ u8 param2;
+ u16 param3;
+ u16 param4;
+ u8 param5;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param3);
+
+ param4 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param4);
+
+ param5 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_82(%d,%d,%d,%d,%d)\n",
+ param1, param2, param3, param4, param5);
+
+ break;
+ }
+ case 0x83: // OS only
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_83(%d,%d)\n", param1,
+ param2);
+
+ break;
+ }
+ case 0x89: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "if(%s!=%s) goto next label(%d)\n",
+ compareString1, compareString2, param);
+
+ break;
+ }
+ case 0x8B: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_8B(%d)\n", param);
+
+ break;
+ }
+ case 0x8C: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_8C(%d)\n", param);
+
+ break;
+ }
+ case 0x8D: // OS only
+ {
+ s16 param1;
+ s16 param2;
+ s16 param3;
+ s16 param4;
+ s16 param5;
+ s16 param6;
+ s16 param7;
+ s16 param8;
+
+ param1 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param1);
+
+ param2 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param2);
+
+ param3 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param3);
+
+ param4 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param4);
+
+ param5 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param5);
+
+ param6 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param6);
+
+ param7 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param7);
+
+ param8 = *(s16 *) (localScriptPtr + position);
+ position += 2;
+ flipU16(&param8);
+
+ sprintf(compareString1, "obj[%d]", param1);
+ sprintf(compareString2,
+ "{%d,%d,%d,%d,%d,%d,%d}", param2, param3,
+ param4, param5, param6, param7, param8);
+
+ break;
+ }
+ case 0x8E: // OS only
+ {
+ u8 param1;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "ADDBG(%d,%s)\n", param1,
+ localScriptPtr + position);
+
+ position += strlen(localScriptPtr + position);
+
+ break;
+ }
+ case 0x8F: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_8F(%d)\n", param);
+
+ break;
+ }
+ case 0x90: // OS only
+ {
+ u8 param1;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "loadABS(%d,%s)\n", param1,
+ localScriptPtr + position);
+
+ position += strlen(localScriptPtr + position);
+
+ break;
+ }
+ case 0x91: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_91(%d)\n", param);
+
+ break;
+ }
+ case 0x9D: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer,
+ "OP_9D(%d) -> flip img idx\n", param);
+
+ break;
+ }
+ case 0x9E: // OS only
+ {
+ u8 param;
+
+ param = *(localScriptPtr + position);
+ position++;
+
+ if (param) {
+ u8 param2;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_9E(%d,%d)\n",
+ param, param2);
+ } else {
+ s16 param2;
+
+ param2 =
+ *(s16 *) (localScriptPtr +
+ position);
+ position += 2;
+ flipU16(&param2);
+
+ sprintf(lineBuffer, "OP_9E(%d,%d)\n",
+ param, param2);
+ }
+
+ break;
+ }
+ case 0xA0: // OS only
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_A0(%d,%d)\n", param1,
+ param2);
+
+ break;
+ }
+ case 0xA1: // OS only
+ {
+ u8 param1;
+ u8 param2;
+
+ param1 = *(localScriptPtr + position);
+ position++;
+
+ param2 = *(localScriptPtr + position);
+ position++;
+
+ sprintf(lineBuffer, "OP_A1(%d,%d)\n", param1,
+ param2);
+
+ break;
+ }
+ default:
+ {
+ sprintf(lineBuffer,
+ "Unsupported opcode %X in decompileScript\n\n",
+ opcode - 1);
+ position = scriptSize;
+ break;
+ }
+ }
+
+ // printf(lineBuffer);
+ strcpy(decompileBuffer[decompileBufferPosition++], lineBuffer);
+
+ exitScript = 0;
+ if (position >= scriptSize) {
+ exitScript = 1;
+ }
+
+ } while (!exitScript);
+}
+
+void dumpScript(u8 * dumpName)
+{
+ File *fHandle;
+ u16 i;
+
+ fHandle = fopen(dumpName, "wt+");
+
+ for (i = 0; i < decompileBufferPosition; i++) {
+ fprintf(fHandle, decompileBuffer[i]);
+ }
+
+ fclose(fHandle);
+
+ decompileBufferPosition = 0;
+}
+
+#endif
diff --git a/engines/cine/script.h b/engines/cine/script.h
new file mode 100644
index 0000000000..e04624e568
--- /dev/null
+++ b/engines/cine/script.h
@@ -0,0 +1,64 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_SCRIPT_H_
+#define CINE_SCRIPT_H_
+
+#define SCRIPT_STACK_SIZE 50
+
+typedef struct {
+ byte *ptr;
+ u16 var4;
+ s16 stack[SCRIPT_STACK_SIZE];
+} scriptStruct;
+
+#define NUM_MAX_SCRIPT 50
+
+extern scriptStruct scriptTable[NUM_MAX_SCRIPT];
+
+void computeScriptStack(byte *scriptPtr, s16 *stackPtr, u16 scriptSize);
+void decompileScript(byte *scriptPtr, s16 *stackPtr, u16 scriptSize,
+ u16 scriptIdx);
+void dumpScript(char *dumpName);
+
+#define OP_loadPart 0x3F
+#define OP_loadNewPrcName 0x41
+#define OP_requestCheckPendingDataLoad 0x42
+#define OP_endScript 0x50
+#define OP_changeDataDisk 0x6B
+#define OP_79 0x79
+
+void addScriptToList0(u16 idx);
+s16 checkCollision(s16 objIdx, s16 x, s16 y, s16 numZones, s16 zoneIdx);
+
+void runObjectScript(s16 entryIdx);
+s16 stopObjectScript(s16 entryIdx);
+
+void executeList1(void);
+void executeList0(void);
+
+void purgeList1(void);
+void purgeList0(void);
+
+#endif
diff --git a/engines/cine/sfx_player.cpp b/engines/cine/sfx_player.cpp
new file mode 100644
index 0000000000..ac94450010
--- /dev/null
+++ b/engines/cine/sfx_player.cpp
@@ -0,0 +1,287 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/system.h"
+#include "common/file.h"
+
+#include "cine/cine.h"
+
+u16 snd_eventsDelay;
+int snd_songIsPlaying = 0;
+u8 snd_nullInstrument[] = { 0, 0 };
+sfxStateStruct snd_sfxState;
+
+static u8 snd_mute = 0;
+static char snd_songFileName[30];
+
+/* LVDT specific */
+static Common::File *snd_baseSndFile = NULL;
+static u16 snd_numBasesonEntries = 0;
+static BasesonEntryStruct *snd_basesonEntries = NULL;
+
+int snd_loadBasesonEntries(const char *fileName) {
+ int i;
+
+ snd_baseSndFile = new Common::File();
+ snd_baseSndFile->open(fileName);
+ if (!snd_baseSndFile->isOpen())
+ return -1;
+
+ snd_numBasesonEntries = snd_baseSndFile->readUint16BE();
+ snd_baseSndFile->readUint16BE(); /* entry_size */
+ snd_basesonEntries =
+ (BasesonEntryStruct *) malloc(snd_numBasesonEntries *
+ sizeof(BasesonEntryStruct));
+ if (snd_basesonEntries) {
+ for (i = 0; i < snd_numBasesonEntries; ++i) {
+ BasesonEntryStruct *be = &snd_basesonEntries[i];
+ snd_baseSndFile->read(be->name, 14);
+ be->offset = snd_baseSndFile->readUint32BE();
+ be->size = snd_baseSndFile->readUint32BE();
+ be->unpackedSize = snd_baseSndFile->readUint32BE();
+ snd_baseSndFile->readUint32BE(); /* unused */
+ }
+ }
+ return 0;
+}
+
+void snd_clearBasesonEntries() {
+ snd_baseSndFile->close();
+ delete snd_baseSndFile;
+ free(snd_basesonEntries);
+ snd_basesonEntries = NULL;
+ snd_numBasesonEntries = 0;
+}
+
+static int snd_findBasesonEntry(const char *entryName) {
+ int i;
+ char *p;
+ char basesonEntryName[20];
+
+ assert(strlen(entryName) < 20);
+ strcpy(basesonEntryName, entryName);
+ for (p = basesonEntryName; *p; ++p) {
+ if (*p >= 'a' && *p <= 'z')
+ *p += 'A' - 'a';
+ }
+
+ for (i = 0; i < snd_numBasesonEntries; ++i) {
+ if (strcmp(snd_basesonEntries[i].name, basesonEntryName) == 0)
+ return i;
+ }
+ return -1;
+}
+
+static u8 *snd_loadBasesonEntry(const char *entryName) {
+ int entryNum;
+ u8 *entryData = NULL;
+
+ if (gameType == Cine::GID_OS) {
+ entryNum = findFileInBundle((const char *)entryName);
+ if (entryNum != -1)
+ entryData = readBundleFile(entryNum);
+ } else {
+ entryNum = snd_findBasesonEntry(entryName);
+ if (entryNum != -1 && entryNum < snd_numBasesonEntries) {
+ const BasesonEntryStruct *be =
+ &snd_basesonEntries[entryNum];
+ entryData = (u8 *) malloc(be->unpackedSize);
+ if (entryData) {
+ if (be->unpackedSize > be->size) {
+ u8 *tempData = (u8 *) malloc(be->size);
+ if (tempData) {
+ snd_baseSndFile->seek(be->
+ offset, SEEK_SET);
+ snd_baseSndFile->read(tempData,
+ be->size);
+ decomp(tempData + be->size - 4,
+ entryData +
+ be->unpackedSize,
+ be->unpackedSize);
+ free(tempData);
+ }
+ } else {
+ snd_baseSndFile->seek(be->offset,
+ SEEK_SET);
+ snd_baseSndFile->read(entryData,
+ be->size);
+ }
+ }
+ }
+ }
+ return entryData;
+}
+
+void snd_stopSong() {
+ int i;
+
+ snd_songFileName[0] = '\0';
+ snd_songIsPlaying = 0;
+ snd_fadeOutCounter = 0;
+
+ for (i = 0; i < 4; ++i)
+ (*snd_driver.stopChannel) (i);
+
+ snd_adlibDriverStopSong();
+ snd_freeSong();
+}
+
+void snd_freeSong() {
+ int i;
+
+ for (i = 0; i < 15; ++i) {
+ if (snd_sfxState.instruments[i] != snd_nullInstrument)
+ free(snd_sfxState.instruments[i]);
+ }
+ free(snd_sfxState.songData);
+ memset(&snd_sfxState, 0, sizeof(snd_sfxState));
+}
+
+int snd_loadSong(const char *songName) {
+ int i;
+
+ while (snd_fadeOutCounter != 0 && snd_fadeOutCounter < 100)
+ g_system->delayMillis(40);
+
+ snd_fadeOutCounter = 0;
+
+ if (snd_songIsPlaying)
+ snd_stopSong();
+
+ if ((gameType == Cine::GID_OS) && (strncmp(songName, "INTRO", 5) == 0))
+ return 0;
+
+ strcpy(snd_songFileName, songName);
+ if (gameType == Cine::GID_OS)
+ strcat(snd_songFileName, ".IST");
+
+ snd_sfxState.songData = snd_loadBasesonEntry(songName);
+ if (!snd_sfxState.songData)
+ return 0;
+
+ for (i = 0; i < 15; ++i) {
+ char instrumentName[13];
+ memcpy(instrumentName, snd_sfxState.songData + 20 + i * 30,
+ 12);
+ instrumentName[12] = '\0';
+
+ snd_sfxState.instruments[i] = snd_nullInstrument;
+ if (strlen(instrumentName) != 0) {
+ char *dot = strrchr(instrumentName, '.');
+ if (dot)
+ *dot = '\0';
+
+ if (gameType == Cine::GID_OS)
+ strcat(instrumentName, ".ADL");
+ else
+ strcat(instrumentName, ".INS");
+
+ snd_sfxState.instruments[i] =
+ snd_loadBasesonEntry(instrumentName);
+ }
+ }
+ return 1;
+}
+
+void snd_fadeOutSong() {
+ if (snd_songIsPlaying) {
+ snd_songFileName[0] = '\0';
+ snd_songIsPlaying = 0;
+ snd_fadeOutCounter = 1;
+ }
+}
+
+void snd_playSong() {
+ if (strlen(snd_songFileName) != 0) {
+ snd_sfxState.currentInstrumentChannel[0] = -1;
+ snd_sfxState.currentInstrumentChannel[1] = -1;
+ snd_sfxState.currentInstrumentChannel[2] = -1;
+ snd_sfxState.currentInstrumentChannel[3] = -1;
+ snd_sfxState.currentOrder = 0;
+ snd_sfxState.currentPos = 0;
+ snd_sfxState.numOrders = snd_sfxState.songData[470];
+ snd_eventsDelay =
+ (252 - snd_sfxState.songData[471]) * 25 * 2 / 1060;
+ snd_songTicksCounter = 0;
+ snd_songIsPlaying = 1;
+ }
+}
+
+void snd_handleEvents() {
+ int i;
+ const u8 *patternData = snd_sfxState.songData + 600;
+ const u8 *orderTable = snd_sfxState.songData + 472;
+ u16 patternNum = orderTable[snd_sfxState.currentOrder] * 1024;
+
+ for (i = 0; i < 4; ++i) {
+ snd_handlePattern(i,
+ patternData + patternNum + snd_sfxState.currentPos);
+ patternData += 4;
+ }
+
+ if (snd_fadeOutCounter != 0 && snd_fadeOutCounter < 100)
+ snd_fadeOutCounter += 4;
+
+ snd_sfxState.currentPos += 16;
+ if (snd_sfxState.currentPos >= 1024) {
+ snd_sfxState.currentPos = 0;
+ ++snd_sfxState.currentOrder;
+ if (snd_sfxState.currentOrder == snd_sfxState.numOrders)
+ snd_sfxState.currentOrder = 0;
+ }
+}
+
+void snd_handlePattern(int channelNum, const u8 *patternData) {
+ u16 instrNum = patternData[2] >> 4;
+ snd_adlibInstrumentsTable[channelNum] = snd_nullInstrument;
+ if (instrNum != 0) {
+ if (snd_sfxState.currentInstrumentChannel[channelNum] !=
+ instrNum) {
+ snd_sfxState.currentInstrumentChannel[channelNum] =
+ instrNum;
+ (*snd_driver.setupChannel) (channelNum,
+ snd_sfxState.instruments[instrNum - 1],
+ instrNum - 1);
+ } else if (snd_fadeOutCounter != 0) {
+ instrNum =
+ snd_sfxState.currentInstrumentChannel[channelNum];
+ if (instrNum != 0)
+ (*snd_driver.setupChannel) (channelNum,
+ snd_sfxState.instruments[instrNum - 1],
+ instrNum - 1);
+ }
+ snd_adlibInstrumentsTable[channelNum] =
+ snd_sfxState.instruments[instrNum - 1];
+ }
+ if (snd_mute != 0)
+ (*snd_driver.stopChannel) (channelNum);
+ else {
+ s16 freq = (s16) readU16BE(patternData);
+ if (freq > 0) {
+ (*snd_driver.stopChannel) (channelNum);
+ (*snd_driver.setChannelFrequency) (channelNum, freq);
+ }
+ }
+}
diff --git a/engines/cine/sfx_player.h b/engines/cine/sfx_player.h
new file mode 100644
index 0000000000..e7a3e68e1e
--- /dev/null
+++ b/engines/cine/sfx_player.h
@@ -0,0 +1,59 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_SFXPLAYER_H_
+#define CINE_SFXPLAYER_H_
+
+typedef struct {
+ char name[14];
+ u32 offset;
+ u32 size;
+ u32 unpackedSize;
+} BasesonEntryStruct;
+
+typedef struct {
+ u8 *songData;
+ int currentInstrumentChannel[4];
+ u8 *instruments[15];
+ int currentOrder;
+ int currentPos;
+ int numOrders;
+} sfxStateStruct;
+
+extern u16 snd_eventsDelay;
+extern int snd_songIsPlaying;
+extern u8 snd_nullInstrument[];
+extern sfxStateStruct snd_sfxState;
+
+extern int snd_loadBasesonEntries(const char *fileName);
+extern void snd_clearBasesonEntries();
+extern void snd_stopSong();
+extern void snd_freeSong();
+extern int snd_loadSong(const char *songName);
+extern void snd_fadeOutSong();
+extern void snd_playSong();
+extern void snd_handleEvents();
+extern void snd_handlePattern(int channelNum, const u8 *patternData);
+
+#endif /* _SFXPLAYER_H_ */
diff --git a/engines/cine/sound_driver.cpp b/engines/cine/sound_driver.cpp
new file mode 100644
index 0000000000..b027c76ec0
--- /dev/null
+++ b/engines/cine/sound_driver.cpp
@@ -0,0 +1,435 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+#include "cine/sound_driver.h"
+
+#include "sound/mixer.h"
+#include "sound/fmopl.h"
+
+u8 snd_useAdlib = 0;
+u16 snd_fadeOutCounter = 0;
+u16 snd_songTicksCounter = 0;
+u8 *snd_adlibInstrumentsTable[4];
+sndDriverStruct snd_driver;
+
+static u8 snd_adlibVibrato = 0;
+static s16 snd_adlibChannelVolume[4];
+
+static const u16 snd_adlibFreqTable[] = {
+ 0x0157, 0x016C, 0x0181, 0x0198, 0x01B1, 0x01CB, 0x01E6, 0x0203,
+ 0x0222, 0x0243, 0x0266, 0x028A
+};
+
+static const u8 snd_adlibOpTable[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0C, 0x0D, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15
+};
+
+static const u8 snd_adlibNoteTable[] = {
+ 0x00, 0x03, 0x01, 0x04, 0x02, 0x05, 0x06, 0x09, 0x07,
+ 0x0A, 0x08, 0x0B, 0x0C, 0x0F, 0x10, 0x10, 0x0E, 0x0E,
+ 0x11, 0x11, 0x0D, 0x0D, 0x00, 0x00
+};
+
+static const s16 snd_adlibNoteFreqTable[] = {
+ 0x0EEE, 0x0E17, 0x0D4D, 0x0C8C, 0x0BD9, 0x0B2F, 0x0A8E, 0x09F7,
+ 0x0967, 0x08E0, 0x0861, 0x07E8, 0x0777, 0x070B, 0x06A6, 0x0647,
+ 0x05EC, 0x0597, 0x0547, 0x04FB, 0x04B3, 0x0470, 0x0430, 0x03F4,
+ 0x03BB, 0x0385, 0x0353, 0x0323, 0x02F6, 0x02CB, 0x02A3, 0x027D,
+ 0x0259, 0x0238, 0x0218, 0x01FA, 0x01DD, 0x01C2, 0x01A9, 0x0191,
+ 0x017B, 0x0165, 0x0151, 0x013E, 0x012C, 0x011C, 0x010C, 0x00FD,
+ 0x00EE, 0x00E1, 0x00D4, 0x00C8, 0x00BD, 0x00B2, 0x00A8, 0x009F,
+ 0x0096, 0x008E, 0x0086, 0x007E, 0x0077, 0x0070, 0x006A, 0x0064,
+ 0x005E, 0x0059, 0x0054, 0x004F, 0x004B, 0x0047, 0x0043, 0x003F,
+ 0x003B, 0x0038, 0x0035, 0x0032, 0x002F, 0x002C, 0x002A, 0x0027,
+ 0x0025, 0x0023, 0x0021, 0x001F, 0x001D, 0x001C, 0x001A, 0x0019,
+ 0x0017, 0x0016, 0x0015, 0x0013, 0x0012, 0x0011, 0x0010, 0x000F
+};
+
+static void snd_adlibWriteData(int port, int value)
+{
+ OPLWriteReg(g_cine_adlib->getOPL(), port, value);
+}
+
+static void snd_adlibDriverSetupInstrument(const u8 *instrumentData, int channelNum) {
+ s16 tmp;
+
+ u8 waveSelect1 = instrumentData[54] & 3; /* var2 */
+ u8 waveSelect2 = instrumentData[56] & 3; /* var1 */
+
+ u8 fl = *instrumentData++; /* varB */
+ u8 ch = *instrumentData++; /* var4 */
+
+ u8 adlibOp1, adlibOp2; /* _di, varA */
+
+ if (fl != 0) {
+ adlibOp1 = snd_adlibOpTable[snd_adlibNoteTable[ch * 2 + 0]];
+ adlibOp2 = snd_adlibOpTable[snd_adlibNoteTable[ch * 2 + 1]];
+ } else {
+ adlibOp1 =
+ snd_adlibOpTable[snd_adlibNoteTable[channelNum * 2 + 0]];
+ adlibOp2 =
+ snd_adlibOpTable[snd_adlibNoteTable[channelNum * 2 + 1]];
+ }
+
+ if (fl == 0 || ch == 6) {
+ /* vibrato */
+ tmp = 0;
+ if (readU16LE(instrumentData + 18) != 0)
+ tmp |= 0x80;
+ if (readU16LE(instrumentData + 20) != 0)
+ tmp |= 0x40;
+ if (readU16LE(instrumentData + 10) != 0)
+ tmp |= 0x20;
+ if (readU16LE(instrumentData + 22) != 0)
+ tmp |= 0x10;
+ tmp |= (readU16LE(instrumentData + 2) & 0xF);
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_EG_KS + adlibOp1, tmp);
+
+ /* key scaling */
+ tmp = 0x3F - (readU16LE(instrumentData + 16) & 0x3F);
+ tmp = snd_adlibChannelVolume[channelNum] * tmp;
+ tmp += tmp + 0x7F;
+ tmp = 0x3F - (tmp / 0xFE);
+ if (readU16LE(instrumentData + 24) != 0)
+ tmp = readU16LE(instrumentData + 16) & 0x3F;
+ tmp |= readU16LE(instrumentData) << 6;
+ snd_adlibWriteData(ADLIB_REG_KEY_SCALING_OPERATOR_OUTPUT +
+ adlibOp1, tmp);
+
+ /* attack/decay rates */
+ tmp =
+ (readU16LE(instrumentData +
+ 6) << 4) | (readU16LE(instrumentData + 12) & 0xF);
+ snd_adlibWriteData(ADLIB_REG_ATTACK_RATE_DECAY_RATE + adlibOp1,
+ tmp);
+
+ /* sustain/release rates */
+ tmp =
+ (readU16LE(instrumentData +
+ 8) << 4) | (readU16LE(instrumentData + 14) & 0xF);
+ snd_adlibWriteData(ADLIB_REG_SUSTAIN_LEVEL_RELEASE_RATE_0 +
+ adlibOp1, tmp);
+
+ if (fl != 0) {
+ tmp = readU16LE(instrumentData + 4) * 2;
+ if (readU16LE(instrumentData + 24) == 0)
+ tmp |= 1;
+
+ snd_adlibWriteData
+ (ADLIB_REG_FEEDBACK_STRENGTH_CONNECTION_TYPE + ch,
+ tmp);
+ } else {
+ tmp = readU16LE(instrumentData + 4) * 2;
+ if (readU16LE(instrumentData + 24) == 0)
+ tmp |= 1;
+
+ snd_adlibWriteData
+ (ADLIB_REG_FEEDBACK_STRENGTH_CONNECTION_TYPE +
+ channelNum, tmp);
+ }
+ snd_adlibWriteData(ADLIB_REG_WAVE_SELECT + adlibOp1,
+ waveSelect1);
+ instrumentData += 26;
+ }
+
+ /* vibrato */
+ tmp = 0;
+ if (readU16LE(instrumentData + 18) != 0)
+ tmp |= 0x80;
+ if (readU16LE(instrumentData + 20) != 0)
+ tmp |= 0x40;
+ if (readU16LE(instrumentData + 10) != 0)
+ tmp |= 0x20;
+ if (readU16LE(instrumentData + 22) != 0)
+ tmp |= 0x10;
+ tmp |= (readU16LE(instrumentData + 2) & 0xF);
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_EG_KS + adlibOp2, tmp);
+
+ /* key scaling */
+ tmp = 0x3F - (readU16LE(instrumentData + 16) & 0x3F);
+ tmp = snd_adlibChannelVolume[channelNum] * tmp;
+ tmp += tmp + 0x7F;
+ tmp = 0x3F - (tmp / 0xFE);
+ tmp |= readU16LE(instrumentData) << 6;
+ snd_adlibWriteData(ADLIB_REG_KEY_SCALING_OPERATOR_OUTPUT + adlibOp2,
+ tmp);
+
+ /* attack/decay rates */
+ tmp =
+ (readU16LE(instrumentData + 6) << 4) | (readU16LE(instrumentData +
+ 12) & 0xF);
+ snd_adlibWriteData(ADLIB_REG_ATTACK_RATE_DECAY_RATE + adlibOp2, tmp);
+
+ /* sustain/release rates */
+ tmp =
+ (readU16LE(instrumentData + 8) << 4) | (readU16LE(instrumentData +
+ 14) & 0xF);
+ snd_adlibWriteData(ADLIB_REG_SUSTAIN_LEVEL_RELEASE_RATE_0 + adlibOp2,
+ tmp);
+ snd_adlibWriteData(ADLIB_REG_WAVE_SELECT + adlibOp2, waveSelect2);
+}
+
+static void snd_adlibInterrupt(void *param, s16 *buf, int len) {
+ int16 *origData = buf;
+ uint origLen = len;
+ static int samplesLeft = 0;
+
+ while (len != 0) {
+ int count;
+ if (samplesLeft == 0) {
+ if (snd_songIsPlaying || (snd_fadeOutCounter != 0
+ && snd_fadeOutCounter < 100)) {
+ ++snd_songTicksCounter;
+ if (snd_songTicksCounter > snd_eventsDelay) {
+ snd_handleEvents();
+ snd_songTicksCounter = 0;
+ }
+ }
+ samplesLeft = g_cine_adlib->getRate() / 50;
+ }
+ count = samplesLeft;
+ if (count > len)
+ count = len;
+
+ YM3812UpdateOne(g_cine_adlib->getOPL(), buf, count);
+
+ samplesLeft -= count;
+ len -= count;
+ buf += count;
+ }
+
+ // Convert mono data to stereo
+ for (int i = (origLen - 1); i >= 0; i--) {
+ origData[2 * i] = origData[2 * i + 1] = origData[i];
+ }
+}
+
+static void snd_adlibDriverSetupChannel(int channelNum, const u8 *data,
+ int instrumentNum) {
+ s16 vol = snd_sfxState.songData[instrumentNum];
+ if (vol != 0 && vol < 0x50)
+ vol = 0x50;
+
+ vol -= snd_fadeOutCounter;
+ if (vol < 0)
+ vol = 0;
+
+ vol += vol / 4;
+ if (vol > 0x7F)
+ vol = 0x7F;
+
+ snd_adlibChannelVolume[channelNum] = vol;
+ snd_adlibDriverSetupInstrument(data, channelNum);
+}
+
+static void snd_getAdlibFrequency(int frequency, int *adlibFreq) {
+ int i;
+
+ *adlibFreq = 95;
+ for (i = 0; i < 96; ++i) {
+ if (snd_adlibNoteFreqTable[i] <= frequency) {
+ *adlibFreq = i;
+ break;
+ }
+ }
+}
+
+static void snd_adlibDriverSetChannelFrequency(int channelNum, int frequency) {
+ const u8 *instr = snd_adlibInstrumentsTable[channelNum];
+ u8 fl = *instr++; /* var2 */
+ u8 ch = *instr++; /* var1 */
+
+ if (fl != 0 && ch == 6)
+ channelNum = 6;
+
+ if (fl == 0 || channelNum == 6) {
+ u16 freqLow, freqHigh; /* var8 */
+ int adlibFreq;
+
+ snd_getAdlibFrequency(frequency, &adlibFreq);
+ if (channelNum == 6)
+ adlibFreq %= 12;
+
+ freqLow = snd_adlibFreqTable[adlibFreq % 12];
+ snd_adlibWriteData(ADLIB_REG_FREQUENCY_0 + channelNum,
+ freqLow);
+ freqHigh = ((adlibFreq / 12) << 2) | ((freqLow & 0x300) >> 8);
+ if (fl == 0)
+ freqHigh |= 0x20;
+
+ snd_adlibWriteData(ADLIB_REG_KEY_ON_OCTAVE_FREQUENCY_0 +
+ channelNum, freqHigh);
+ }
+ if (fl != 0) {
+ snd_adlibVibrato |= 1 << (10 - ch);
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_RHYTHM,
+ snd_adlibVibrato);
+ }
+}
+
+static void snd_adlibDriverStopChannel(int channelNum) {
+ const u8 *instr = snd_adlibInstrumentsTable[channelNum];
+ u8 fl = *instr++; /* var2 */
+ u8 ch = *instr++; /* var1 */
+
+ if (fl != 0 && ch == 6)
+ channelNum = 6;
+
+ if (fl == 0 || channelNum == 6)
+ snd_adlibWriteData(ADLIB_REG_KEY_ON_OCTAVE_FREQUENCY_0 +
+ channelNum, 0);
+
+ if (fl != 0) {
+ snd_adlibVibrato &= (1 << (10 - ch)) ^ 0xFF;
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_RHYTHM,
+ snd_adlibVibrato);
+ }
+}
+
+static void snd_adlibDriverPlaySound(u8 * data, int channelNum, int volume) {
+/* if (_snd_mute) return;*/
+ u8 fl, ch; /* var2, var1 */
+
+ assert(channelNum < 4);
+ data += 257;
+ snd_adlibInstrumentsTable[channelNum] = data;
+ snd_resetChannel(channelNum);
+ snd_adlibChannelVolume[channelNum] = 0x7F;
+ snd_adlibDriverSetupInstrument(data, channelNum);
+ fl = *data++;
+ ch = *data++;
+
+ if (fl != 0 && ch == 6)
+ channelNum = 6;
+
+ if (fl == 0 || channelNum == 6) {
+ u16 freqLow, freqHigh;
+ freqLow = snd_adlibFreqTable[0];
+ snd_adlibWriteData(ADLIB_REG_FREQUENCY_0 + channelNum,
+ freqLow);
+ freqHigh = 4 | ((freqLow & 0x300) >> 8);
+ if (fl == 0)
+ freqHigh |= 0x20;
+
+ snd_adlibWriteData(ADLIB_REG_KEY_ON_OCTAVE_FREQUENCY_0 +
+ channelNum, freqHigh);
+ }
+ if (fl != 0) {
+ snd_adlibVibrato = 1 << (10 - ch);
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_RHYTHM,
+ snd_adlibVibrato);
+ }
+}
+
+static sndDriverStruct snd_adlibDriver = {
+ &snd_adlibDriverSetupChannel,
+ &snd_adlibDriverSetChannelFrequency,
+ &snd_adlibDriverStopChannel,
+ &snd_adlibDriverPlaySound
+};
+
+void snd_adlibDriverStopSong() {
+ int i;
+
+ for (i = 0; i < 18; ++i)
+ snd_adlibWriteData(ADLIB_REG_KEY_SCALING_OPERATOR_OUTPUT +
+ snd_adlibOpTable[i], 0x3F);
+
+ for (i = 0; i < 9; ++i)
+ snd_adlibWriteData(ADLIB_REG_KEY_ON_OCTAVE_FREQUENCY_0 + i, 0);
+
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_RHYTHM, 0);
+}
+
+void snd_resetChannel(int channelNum) {
+ (*snd_driver.stopChannel) (channelNum);
+ if (snd_useAdlib)
+ snd_adlibDriverStopSong();
+}
+
+AdlibMusic::AdlibMusic(Audio::Mixer *pMixer) {
+ _mixer = pMixer;
+ _sampleRate = pMixer->getOutputRate();
+ g_cine_adlib = this;
+ _opl = makeAdlibOPL(_sampleRate);
+
+ snd_adlibVibrato = 0x20;
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_RHYTHM, snd_adlibVibrato);
+ snd_adlibWriteData(0x08, 0x40);
+
+ int i;
+
+ for (i = 0; i < 18; ++i)
+ snd_adlibWriteData(ADLIB_REG_KEY_SCALING_OPERATOR_OUTPUT +
+ snd_adlibOpTable[i], 0);
+
+ for (i = 0; i < 9; ++i)
+ snd_adlibWriteData(ADLIB_REG_KEY_ON_OCTAVE_FREQUENCY_0 + i, 0);
+
+ for (i = 0; i < 9; ++i)
+ snd_adlibWriteData(ADLIB_REG_FEEDBACK_STRENGTH_CONNECTION_TYPE
+ + i, 0);
+
+ for (i = 0; i < 18; ++i)
+ snd_adlibWriteData(ADLIB_REG_ATTACK_RATE_DECAY_RATE +
+ snd_adlibOpTable[i], 0);
+
+ for (i = 0; i < 18; ++i)
+ snd_adlibWriteData(ADLIB_REG_SUSTAIN_LEVEL_RELEASE_RATE_0 +
+ snd_adlibOpTable[i], 0);
+
+ for (i = 0; i < 18; ++i)
+ snd_adlibWriteData(ADLIB_REG_AM_VIBRATO_EG_KS +
+ snd_adlibOpTable[i], 0);
+
+ for (i = 0; i < 18; ++i)
+ snd_adlibWriteData(ADLIB_REG_WAVE_SELECT + snd_adlibOpTable[i],
+ 0);
+
+ snd_adlibWriteData(1, 0x20);
+ snd_adlibWriteData(1, 0);
+
+ for (i = 0; i < 4; ++i)
+ snd_adlibInstrumentsTable[i] = snd_nullInstrument;
+
+ snd_useAdlib = 1;
+ snd_driver = snd_adlibDriver;
+
+ _mixer->setupPremix(this);
+}
+
+void AdlibMusic::premixerCall(int16 *data, uint len) {
+ snd_adlibInterrupt(NULL, data, len);
+}
+
+void AdlibMusic::setVolume(uint8 volume) {
+ for (int i = 0; i < 4; ++i)
+ snd_adlibChannelVolume[i] = volume | 128;
+}
+
+AdlibMusic::~AdlibMusic(void) {
+ _mixer->setupPremix(NULL);
+}
diff --git a/engines/cine/sound_driver.h b/engines/cine/sound_driver.h
new file mode 100644
index 0000000000..85a94b4fe0
--- /dev/null
+++ b/engines/cine/sound_driver.h
@@ -0,0 +1,91 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_SNDDRIVER_H_
+#define CINE_SNDDRIVER_H_
+
+#define ADLIB_REG_TIMER_1_DATA 2
+#define ADLIB_REG_TIMER_CONTROL_FLAGS 4
+#define ADLIB_REG_AM_VIBRATO_EG_KS 0x20
+#define ADLIB_REG_KEY_SCALING_OPERATOR_OUTPUT 0x40
+#define ADLIB_REG_ATTACK_RATE_DECAY_RATE 0x60
+#define ADLIB_REG_SUSTAIN_LEVEL_RELEASE_RATE_0 0x80
+#define ADLIB_REG_FREQUENCY_0 0xA0
+#define ADLIB_REG_KEY_ON_OCTAVE_FREQUENCY_0 0xB0
+#define ADLIB_REG_AM_VIBRATO_RHYTHM 0xBD
+#define ADLIB_REG_FEEDBACK_STRENGTH_CONNECTION_TYPE 0xC0
+#define ADLIB_REG_WAVE_SELECT 0xE0
+
+typedef struct {
+ void (*setupChannel) (int channelNum, const u8 * data,
+ int instrumentNum);
+ void (*setChannelFrequency) (int channelNum, int frequency);
+ void (*stopChannel) (int channelNum);
+ void (*playSound) (u8 * data, int channelNum, int volume);
+} sndDriverStruct;
+
+extern u16 snd_fadeOutCounter, snd_songTicksCounter;
+extern u8 *snd_adlibInstrumentsTable[4];
+extern sndDriverStruct snd_driver;
+
+extern void snd_adlibDriverInit();
+extern void snd_adlibDriverExit();
+extern void snd_adlibDriverStopSong();
+extern void snd_resetChannel(int channelNum);
+
+#include "sound/audiostream.h"
+#include "sound/fmopl.h"
+
+namespace Audio {
+ class Mixer;
+}
+
+class AdlibMusic : public AudioStream {
+public:
+ AdlibMusic(Audio::Mixer * pMixer);
+ ~AdlibMusic(void);
+ virtual void setVolume(uint8 volume);
+
+ FM_OPL *getOPL() {
+ return _opl;
+ }
+
+ // AudioStream API
+ int readBuffer(int16 *buffer, const int numSamples) {
+ premixerCall(buffer, numSamples / 2);
+ return numSamples;
+ }
+ bool isStereo() const { return true; }
+ bool endOfData() const { return false; }
+ int getRate() const { return _sampleRate; }
+
+private:
+ FM_OPL *_opl;
+ Audio::Mixer * _mixer;
+ uint32 _sampleRate;
+
+ void premixerCall(int16 *buf, uint len);
+};
+
+#endif /* CINE_SNDDRIVER_H_ */
diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp
new file mode 100644
index 0000000000..60d45e303a
--- /dev/null
+++ b/engines/cine/texte.cpp
@@ -0,0 +1,82 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+u8 *textDataPtr;
+
+u8 textTable[256][2][16 * 8];
+
+void generateMask(u8 *sprite, u8 *mask, u16 size, u8 transparency);
+
+void loadTextData(char *pFileName, u8 *pDestinationBuffer) {
+ Common::File pFileHandle;
+ u16 entrySize;
+ u16 numEntry;
+ u16 i;
+ u8 *tempBuffer;
+ u16 dataSize;
+
+ assert(pFileName);
+ assert(pDestinationBuffer);
+
+ pFileHandle.open(pFileName);
+
+ assert(pFileHandle.isOpen());
+
+ pFileHandle.read(&entrySize, 2);
+ flipU16(&entrySize);
+
+ pFileHandle.read(&numEntry, 2);
+ flipU16(&numEntry);
+
+ dataSize = numEntry * entrySize;
+ pFileHandle.read(pDestinationBuffer, numEntry * entrySize);
+
+ tempBuffer = pDestinationBuffer;
+
+ if (gameType == Cine::GID_FW) {
+ dataSize = dataSize / 0x4E;
+
+ loadRelatedPalette(pFileName);
+
+ for (i = 0; i < 0x4E; i++) {
+ gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 16,
+ 8);
+ generateMask(textTable[i][0], textTable[i][1], 16 * 8,
+ 0);
+ tempBuffer += dataSize;
+ }
+ } else {
+ for (i = 0; i < 90; i++) {
+ gfxConvertSpriteToRaw(textTable[i][0], tempBuffer, 8,
+ 8);
+ generateMask(textTable[i][0], textTable[i][1], 8 * 8,
+ 0);
+ tempBuffer += 0x40;
+ }
+ }
+
+ pFileHandle.close();
+}
diff --git a/engines/cine/texte.h b/engines/cine/texte.h
new file mode 100644
index 0000000000..495bd95c02
--- /dev/null
+++ b/engines/cine/texte.h
@@ -0,0 +1,33 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_TEXTE_H_
+#define CINE_TEXTE_H_
+
+extern u8 *textDataPtr;
+extern u8 textTable[256][2][16 * 8];
+
+void loadTextData(char *pFileName, u8 *pDestinationBuffer);
+
+#endif
diff --git a/engines/cine/unpack.cpp b/engines/cine/unpack.cpp
new file mode 100644
index 0000000000..652e0bf7f0
--- /dev/null
+++ b/engines/cine/unpack.cpp
@@ -0,0 +1,151 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+u32 crc; // variable at 5C5A
+u32 bitbucket; // dx:bx
+
+u16 swap16(u16 r) {
+ return (r >> 8) | (r << 8);
+}
+
+#define loadd(p, d) {\
+ d = *(--p);\
+ d |= (*(--p)) << 8;\
+ d |= (*(--p)) << 16;\
+ d |= (*(--p)) << 24;\
+}
+#define store(p, b) *(--p) = b
+#define getbit(p, b) {\
+ b = bitbucket & 1;\
+ bitbucket >>= 1;\
+ if (!bitbucket) {\
+ loadd(p, bitbucket);\
+ crc ^= bitbucket;\
+ b = bitbucket & 1;\
+ bitbucket >>= 1;\
+ bitbucket |= 0x80000000;\
+ }\
+}
+
+#define loadbits(p, b) {\
+ b = 0;\
+ do {\
+ getbit(p, bit);\
+ b <<= 1;\
+ b |= bit;\
+ nbits--;\
+ } while (nbits);\
+}
+
+int decomp(u8 *in, u8 *out, int size) {
+ u8 bit; // Carry flag
+ u8 nbits; // cl
+ u8 byte = 0; // ch
+ u16 counter; // bp
+ u16 var = 0; // variable at 5C58
+ u16 ptr;
+ u16 flags;
+
+ enum {
+ DO_COPY,
+ DO_UNPACK
+ } action;
+
+ loadd(in, crc);
+ loadd(in, bitbucket);
+ crc ^= bitbucket;
+
+ do { // 5A4C
+ getbit(in, bit);
+ if (!bit) { // 5A94
+ getbit(in, bit);
+ if (!bit) { // 5AC8
+ nbits = 3;
+ byte = 0;
+ action = DO_COPY;
+ } else { // 5ACA
+ var = 1;
+ nbits = 8;
+ action = DO_UNPACK;
+ }
+ } else { // 5B4F
+ nbits = 2;
+ loadbits(in, flags);
+ if (flags < 2) {
+ nbits = flags + 9; // 5BC3
+ var = flags + 2;
+ action = DO_UNPACK;
+ } else if (flags == 3) {
+ nbits = 8; // 5B4A
+ byte = 8;
+ action = DO_COPY;
+ } else {
+ nbits = 8;
+ loadbits(in, var);
+ nbits = 12;
+ action = DO_UNPACK;
+ }
+ }
+
+ switch (action) {
+ case DO_COPY:
+ {
+ // 5AD1
+ loadbits(in, counter); // 5AFD
+ counter += byte;
+ counter++;
+ size -= counter;
+ do {
+ nbits = 8;
+ loadbits(in, byte); // 5B3F
+ store(out, byte);
+ counter--;
+ } while (counter); // 5B45
+ break;
+ }
+
+ case DO_UNPACK:
+
+ // 5BD3
+ loadbits(in, ptr); // 5BFF
+ counter = var + 1;
+ size -= counter;
+ do {
+ byte = *(out + ptr - 1);
+ store(out, byte);
+ counter--;
+ } while (counter);
+ }
+ } while (size > 0);
+
+ // 5C32
+ // ???
+ if (crc) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
diff --git a/engines/cine/unpack.h b/engines/cine/unpack.h
new file mode 100644
index 0000000000..0e0fd2594a
--- /dev/null
+++ b/engines/cine/unpack.h
@@ -0,0 +1,30 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_UNPACK_H_
+#define CINE_UNPACK_H_
+
+int decomp(u8 *in, u8 *out, int size);
+
+#endif
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
new file mode 100644
index 0000000000..ed8a2aa72b
--- /dev/null
+++ b/engines/cine/various.cpp
@@ -0,0 +1,3263 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "cine/cine.h"
+
+s16 allowSystemMenu = 0;
+
+s16 commandVar3[4];
+s16 commandVar1;
+s16 commandVar2;
+
+unk1Struct messageTable[NUM_MAX_MESSAGE];
+
+u32 var6;
+u32 var8;
+u8 *var9;
+
+u16 var2;
+u16 var3;
+u16 var4;
+u16 var5;
+
+void drawString(char *string, u8 param) {
+}
+
+void blitRawScreen(u8 *frontBuffer) {
+ gfxFlipRawPage(frontBuffer);
+}
+
+void processPendingUpdates(s16 param) {
+}
+
+Common::File partFileHandle;
+
+void waitPlayerInput(void) {
+}
+
+void closeEngine3(void) {
+}
+
+void mainLoopSub1(void) {
+}
+
+void mainLoopSub2(u16 param1, u16 param2, u16 param3, u16 param4) {
+}
+
+u16 errorVar;
+u8 menuVar;
+
+void gfxFuncGen1(u8 *param1, u8 *param2, u8 *param3, u8 *param4,
+ s16 param5) {
+}
+
+u8 *page0c;
+
+void ptrGfxFunc13(void) {
+}
+
+void gfxFuncGen2(void) {
+}
+
+u16 allowPlayerInput;
+
+u16 checkForPendingDataLoadSwitch;
+
+u16 fadeRequired;
+u16 isDrawCommandEnabled;
+u16 waitForPlayerClick;
+u16 var16;
+u16 var17;
+u16 var18;
+u16 var19;
+u16 var20;
+u8 var21;
+
+s16 playerCommand;
+
+char commandBuffer[80];
+
+u16 palette_[256];
+
+char currentPrcName[20];
+char currentRelName[20];
+char currentObjectName[20];
+char currentMsgName[20];
+char newPrcName[20];
+char newRelName[20];
+char newObjectName[20];
+char newMsgName[20];
+
+char currentBgName[8][15];
+char currentCtName[15];
+char currentPartName[15];
+char currentDatName[30];
+
+s16 saveVar2;
+
+u8 isInPause = 0;
+
+u16 defaultMenuBoxColor;
+
+u8 inputVar1 = 0;
+
+u16 inputVar2;
+u16 inputVar3;
+
+commandeType defaultActionCommand[] = {
+ "EXAMINE",
+ "TAKE",
+ "INVENTORY",
+ "USE",
+ "OPERATE",
+ "SPEAK",
+ "NOACTION"
+// french
+/*
+ "EXAMINER",
+ "PRENDRE",
+ "INVENTAIRE",
+ "UTILISER",
+ "ACTIONNER",
+ "PARLER",
+ "NOACTION"
+*/
+};
+
+selectedObjStruct currentSelectedObject;
+
+void stopSample(void) {
+ snd_stopSong();
+}
+
+void mainLoopSub3(void) {
+}
+
+s16 stopObjectScript(s16 entryIdx) {
+ prcLinkedListStruct *currentHead = &objScriptList;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ if (currentHead->scriptIdx == entryIdx) {
+ currentHead->scriptIdx = -1;
+
+ return 0;
+ }
+
+ currentHead = currentHead->next;
+ }
+
+ return (-1);
+}
+
+void runObjectScript(s16 entryIdx) {
+ u16 i;
+ prcLinkedListStruct *pNewElement;
+ prcLinkedListStruct *currentHead = &objScriptList;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ tempHead = currentHead;
+
+ ASSERT_PTR(tempHead);
+
+ currentHead = tempHead->next;
+ }
+
+ pNewElement =
+ (prcLinkedListStruct *) malloc(sizeof(prcLinkedListStruct));
+
+ ASSERT_PTR(pNewElement);
+
+ pNewElement->next = tempHead->next;
+ tempHead->next = pNewElement;
+
+ // copy the stack into the script instance
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ pNewElement->stack[i] = 0;
+ }
+
+ for (i = 0; i < 50; i++) {
+ pNewElement->localVars[i] = 0;
+ }
+
+ pNewElement->compareResult = 0;
+ pNewElement->scriptPosition = 0;
+
+ pNewElement->scriptPtr = (byte *) relTable[entryIdx].ptr0;
+ pNewElement->scriptIdx = entryIdx;
+
+ computeScriptStack(pNewElement->scriptPtr, pNewElement->stack,
+ relTable[entryIdx].var4);
+}
+
+s16 getRelEntryForObject(u16 param1, u16 param2,
+ selectedObjStruct *pSelectedObject) {
+ s16 i;
+ s16 di = -1;
+
+ for (i = 0; i < NUM_MAX_REL; i++) {
+ if (relTable[i].ptr0 && relTable[i].var6 == param1
+ && relTable[i].var8 == pSelectedObject->idx) {
+ if (param2 == 1) {
+ di = i;
+ } else if (param2 == 2) {
+ if (relTable[i].varA == pSelectedObject->param) {
+ di = i;
+ }
+ }
+ }
+
+ if (di != -1)
+ break;
+ }
+
+ return di;
+}
+
+s16 getObjectUnderCursor(u16 x, u16 y) {
+ overlayHeadElement *currentHead = overlayHead.previous;
+
+ while (currentHead) {
+ if (currentHead->type < 2) {
+ if (objectTable[currentHead->objIdx].name[0]) {
+ s16 objX;
+ s16 objY;
+ s16 frame;
+ s16 part;
+ s16 treshold;
+ s16 height;
+ s16 xdif;
+ s16 ydif;
+
+ objX = objectTable[currentHead->objIdx].x;
+ objY = objectTable[currentHead->objIdx].y;
+
+ frame =
+ abs((s16) (objectTable[currentHead->
+ objIdx].frame));
+
+ part = objectTable[currentHead->objIdx].part;
+
+ if (currentHead->type == 0) {
+ treshold = animDataTable[frame].var1;
+ } else {
+ treshold =
+ animDataTable[frame].width / 2;
+ }
+
+ height = animDataTable[frame].var2;
+
+ xdif = x - objX;
+ ydif = y - objY;
+
+ if ((xdif >= 0) && ((treshold << 4) > xdif)
+ && (ydif > 0) && (ydif < height)) {
+ if (animDataTable[frame].ptr1) {
+ if (gameType == Cine::GID_OS)
+ return currentHead->
+ objIdx;
+
+ if (currentHead->type == 0) // use generated mask
+ {
+ if (gfxGetBit(x - objX,
+ y - objY,
+ animDataTable
+ [frame].ptr2,
+ animDataTable
+ [frame].
+ width)) {
+ return
+ currentHead->
+ objIdx;
+ }
+ } else if (currentHead->type == 1) // is mask
+ {
+ if (gfxGetBit(x - objX,
+ y - objY,
+ animDataTable
+ [frame].ptr1,
+ animDataTable
+ [frame].width *
+ 4)) {
+ return
+ currentHead->
+ objIdx;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ currentHead = currentHead->previous;
+ }
+
+ return -1;
+}
+
+const commandeType systemMenu[] = {
+ "Pause",
+ "Nouvelle partie",
+ "Quitter",
+ "Lecteur de Svg. A:",
+ "Charger une partie",
+ "Sauver la partie"
+};
+
+const commandeType confirmMenu[] = {
+ "Ok , Vas-y ...",
+ "Surtout Pas !"
+};
+
+commandeType currentSaveName[10];
+
+s16 loadSaveDirectory(void) {
+ Common::File fHandle;
+
+ if (gameType == Cine::GID_FW)
+ fHandle.open("FW.DIR", Common::File::kFileReadMode, savePath);
+ else
+ fHandle.open("OS.DIR", Common::File::kFileReadMode, savePath);
+
+ if (!fHandle.isOpen()) {
+ return 0;
+ }
+
+ fHandle.read(currentSaveName, 10 * 20);
+ fHandle.close();
+
+ return 1;
+}
+
+s16 currentDisk;
+
+void loadObjectScritpFromSave(Common::File *fHandle) {
+ s16 i;
+
+ prcLinkedListStruct *newElement;
+ prcLinkedListStruct *currentHead = &globalScriptsHead;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ newElement =
+ (prcLinkedListStruct *) malloc(sizeof(prcLinkedListStruct));
+
+ newElement->next = tempHead->next;
+ tempHead->next = newElement;
+
+ fHandle->read(&newElement->stack, 100);
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ flipU16((u16 *) & newElement->stack[i]);
+ }
+
+ fHandle->read(&newElement->localVars, 100);
+ for (i = 0; i < 50; i++) {
+ flipU16((u16 *) & newElement->localVars[i]);
+ }
+
+ fHandle->read(&newElement->compareResult, 2);
+ flipU16(&newElement->compareResult);
+
+ fHandle->read(&newElement->scriptPosition, 2);
+ flipU16(&newElement->scriptPosition);
+
+ fHandle->read(&newElement->scriptIdx, 2);
+ flipU16((u16 *) & newElement->scriptIdx);
+
+ newElement->scriptPtr = (byte *) relTable[newElement->scriptIdx].ptr0;
+}
+
+void loadGlobalScritpFromSave(Common::File *fHandle) {
+ s16 i;
+
+ prcLinkedListStruct *newElement;
+ prcLinkedListStruct *currentHead = &globalScriptsHead;
+ prcLinkedListStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ newElement =
+ (prcLinkedListStruct *) malloc(sizeof(prcLinkedListStruct));
+
+ newElement->next = tempHead->next;
+ tempHead->next = newElement;
+
+ fHandle->read(&newElement->stack, 100);
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ flipU16((u16 *) & newElement->stack[i]);
+ }
+
+ fHandle->read(&newElement->localVars, 100);
+ for (i = 0; i < 50; i++) {
+ flipU16((u16 *) & newElement->localVars[i]);
+ }
+
+ fHandle->read(&newElement->compareResult, 2);
+ flipU16(&newElement->compareResult);
+
+ fHandle->read(&newElement->scriptPosition, 2);
+ flipU16(&newElement->scriptPosition);
+
+ fHandle->read(&newElement->scriptIdx, 2);
+ flipU16((u16 *) & newElement->scriptIdx);
+
+ newElement->scriptPtr = scriptTable[newElement->scriptIdx].ptr;
+}
+
+void loadOverlayFromSave(Common::File *fHandle) {
+ overlayHeadElement *newElement;
+ overlayHeadElement *currentHead = &overlayHead;
+ overlayHeadElement *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ newElement = (overlayHeadElement *) malloc(sizeof(overlayHeadElement));
+
+ fHandle->read(newElement, 0x14);
+
+ flipU16(&newElement->objIdx);
+ flipU16(&newElement->type);
+ flipU16((u16 *) & newElement->x);
+ flipU16((u16 *) & newElement->y);
+ flipU16((u16 *) & newElement->var10);
+ flipU16((u16 *) & newElement->var12);
+
+ newElement->next = tempHead->next;
+ tempHead->next = newElement;
+
+ if (!currentHead)
+ currentHead = &overlayHead;
+
+ newElement->previous = currentHead->previous;
+
+ currentHead->previous = newElement;
+
+}
+
+void setupGlobalScriptList(void) {
+ prcLinkedListStruct *currentHead = globalScriptsHead.next;
+
+ while (currentHead) {
+ currentHead->scriptPtr =
+ scriptTable[currentHead->scriptIdx].ptr;
+
+ currentHead = currentHead->next;
+ }
+}
+
+void setupObjectScriptList(void) {
+ prcLinkedListStruct *currentHead = objScriptList.next;
+
+ while (currentHead) {
+ currentHead->scriptPtr =
+ (byte *)relTable[currentHead->scriptIdx].ptr0;
+
+ currentHead = currentHead->next;
+ }
+}
+
+s16 makeLoad(char *saveName) {
+ s16 i;
+ s16 size;
+ Common::File fHandle;
+
+ fHandle.open(saveName, Common::File::kFileReadMode, savePath);
+
+ if (!fHandle.isOpen()) {
+ drawString("Cette sauvegarde n'existe pas ...", 0);
+ waitPlayerInput();
+ // restoreScreen();
+ checkDataDisk(-1);
+ return -1;
+ }
+
+ stopSample();
+ closeEngine3();
+ unloadAllMasks();
+ freePrcLinkedList();
+ releaseObjectScripts();
+ closeEngine7();
+ closePart();
+
+ for (i = 0; i < NUM_MAX_REL; i++) {
+ if (relTable[i].ptr0) {
+ free(relTable[i].ptr0);
+
+ relTable[i].ptr0 = NULL;
+ relTable[i].var4 = 0;
+ relTable[i].var6 = 0;
+ relTable[i].var8 = 0;
+ relTable[i].varA = 0;
+ }
+ }
+
+ for (i = 0; i < NUM_MAX_SCRIPT; i++) {
+ if (scriptTable[i].ptr) {
+ free(scriptTable[i].ptr);
+
+ scriptTable[i].ptr = NULL;
+ scriptTable[i].var4 = 0;
+ }
+ }
+
+ for (i = 0; i < NUM_MAX_MESSAGE; i++) {
+ messageTable[i].len = 0;
+
+ if (messageTable[i].ptr) {
+ free(messageTable[i].ptr);
+ messageTable[i].ptr = NULL;
+ }
+ }
+
+ for (i = 0; i < NUM_MAX_OBJECT; i++) {
+ objectTable[i].part = 0;
+ objectTable[i].name[0] = 0;
+ objectTable[i].frame = 0;
+ objectTable[i].mask = 0;
+ objectTable[i].costume = 0;
+ }
+
+ for (i = 0; i < 255; i++) {
+ globalVars[i] = 0;
+ }
+
+ var2 = 0;
+ var3 = 0;
+ var4 = 0;
+ var5 = 0;
+
+ strcpy(newPrcName, "");
+ strcpy(newRelName, "");
+ strcpy(newObjectName, "");
+ strcpy(newMsgName, "");
+ strcpy(currentBgName[0], "");
+ strcpy(currentCtName, "");
+
+ allowPlayerInput = 0;
+ waitForPlayerClick = 0;
+ playerCommand = -1;
+ isDrawCommandEnabled = 0;
+
+ strcpy(commandBuffer, "");
+
+ globalVars[249] = 0;
+ globalVars[250] = 0;
+
+ fadeRequired = 0;
+
+ for (i = 0; i < 16; i++) {
+ palette_[i] = 0;
+ }
+
+ checkForPendingDataLoadSwitch = 0;
+
+ fHandle.read(&currentDisk, 2);
+ flipU16((u16 *) & currentDisk);
+
+ fHandle.read(currentPartName, 13);
+ fHandle.read(currentDatName, 13);
+
+ fHandle.read(&saveVar2, 2);
+ flipU16((u16 *) & saveVar2);
+
+ fHandle.read(currentPrcName, 13);
+ fHandle.read(currentRelName, 13);
+ fHandle.read(currentMsgName, 13);
+ fHandle.read(currentBgName[0], 13);
+ fHandle.read(currentCtName, 13);
+
+ fHandle.read(&i, 2);
+ fHandle.read(&i, 2);
+ flipU16((u16 *) & i);
+
+ fHandle.read(objectTable, i * 255);
+
+ for (i = 0; i < NUM_MAX_OBJECT; i++) {
+ flipU16((u16 *) & objectTable[i].x);
+ flipU16((u16 *) & objectTable[i].y);
+ flipU16(&objectTable[i].mask);
+ flipU16((u16 *) & objectTable[i].frame);
+ flipU16((u16 *) & objectTable[i].costume);
+ flipU16(&objectTable[i].part);
+ }
+
+ fHandle.read(palette_, 32);
+ for (i = 0; i < 16; i++) {
+ flipU16(&palette_[i]);
+ }
+
+ fHandle.read(tempPalette, 32);
+ for (i = 0; i < 16; i++) {
+ flipU16(&tempPalette[i]);
+ }
+
+ fHandle.read(globalVars, 510);
+ for (i = 0; i < 255; i++) {
+ flipU16(&globalVars[i]);
+ }
+
+ fHandle.read(zoneData, 0x20);
+ for (i = 0; i < 16; i++) {
+ flipU16(&zoneData[i]);
+ }
+
+ fHandle.read(&commandVar3, 8);
+ for (i = 0; i < 4; i++) {
+ flipU16((u16 *) & commandVar3[i]);
+ }
+
+ fHandle.read(commandBuffer, 0x50);
+
+ fHandle.read(&defaultMenuBoxColor, 2);
+ flipU16(&defaultMenuBoxColor);
+
+ fHandle.read(&bgVar0, 2);
+ flipU16(&bgVar0);
+
+ fHandle.read(&allowPlayerInput, 2);
+ flipU16(&allowPlayerInput);
+
+ fHandle.read(&playerCommand, 2);
+ flipU16((u16 *) & playerCommand);
+
+ fHandle.read(&commandVar1, 2);
+ flipU16((u16 *) & commandVar1);
+
+ fHandle.read(&isDrawCommandEnabled, 2);
+ flipU16(&isDrawCommandEnabled);
+
+ fHandle.read(&var5, 2);
+ flipU16(&var5);
+
+ fHandle.read(&var4, 2);
+ flipU16(&var4);
+
+ fHandle.read(&var3, 2);
+ flipU16(&var3);
+
+ fHandle.read(&var2, 2);
+ flipU16(&var2);
+
+ fHandle.read(&commandVar2, 2);
+ flipU16((u16 *) & commandVar2);
+
+ fHandle.read(&defaultMenuBoxColor2, 2);
+ flipU16(&defaultMenuBoxColor2);
+
+ fHandle.read(&i, 2);
+ fHandle.read(&i, 2);
+ flipU16((u16 *) & i);
+ fHandle.read(animDataTable, i * 255);
+ for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
+ flipU16(&animDataTable[i].width);
+ flipU16(&animDataTable[i].var1);
+ flipU16(&animDataTable[i].field_4);
+ flipU16(&animDataTable[i].var2);
+ flipU16((u16 *) & animDataTable[i].fileIdx);
+ flipU16((u16 *) & animDataTable[i].frameIdx);
+ }
+
+ fHandle.seek(12, SEEK_CUR); // TODO: handle screen params (realy required ?)
+
+ fHandle.read(&size, 2);
+ flipU16((u16 *) & size);
+ for (i = 0; i < size; i++) {
+ loadGlobalScritpFromSave(&fHandle);
+ }
+
+ fHandle.read(&size, 2);
+ flipU16((u16 *) & size);
+ for (i = 0; i < size; i++) {
+ loadObjectScritpFromSave(&fHandle);
+ }
+
+ fHandle.read(&size, 2);
+ flipU16((u16 *) & size);
+ for (i = 0; i < size; i++) {
+ loadOverlayFromSave(&fHandle);
+ }
+
+ fHandle.read(&size, 2);
+ flipU16((u16 *) & size);
+ for (i = 0; i < size; i++) {
+ // loadBgIncrustFromSave(fHandle);
+ }
+
+ fHandle.close();
+
+ checkDataDisk(currentDisk);
+
+ if (strlen(currentPartName)) {
+ loadPart(currentPartName);
+ }
+
+ if (strlen(currentPrcName)) {
+ loadPrc(currentPrcName);
+ setupGlobalScriptList();
+ }
+
+ if (strlen(currentRelName)) {
+ loadRel(currentRelName);
+ setupObjectScriptList();
+ }
+
+ if (strlen(currentMsgName)) {
+ loadMsg(currentMsgName);
+ }
+
+ if (strlen(currentBgName[0])) {
+ loadBg(currentBgName[0]);
+ }
+
+ if (strlen(currentCtName)) {
+ loadCt(currentCtName);
+ }
+
+ loadResourcesFromSave();
+ //reincrustAllBg();
+
+ processPendingUpdates(0);
+
+ if (strlen(currentDatName)) {
+/* i = saveVar2;
+ saveVar2 = 0;
+ loadMusic();
+ if(i)
+ {
+ playMusic();
+ }*/
+ }
+
+ return (0);
+}
+
+void saveU16(u16 var, Common::File * fHandle) {
+ flipU16(&var);
+ fHandle->write(&var, 2);
+}
+
+void makeSave(char *saveFileName) {
+ s16 i;
+ Common::File fHandle;
+
+ fHandle.open(saveFileName, Common::File::kFileWriteMode, savePath);
+
+ saveU16(currentDisk, &fHandle);
+ fHandle.write(currentPartName, 13);
+ fHandle.write(currentDatName, 13);
+ saveU16(saveVar2, &fHandle);
+ fHandle.write(currentPrcName, 13);
+ fHandle.write(currentRelName, 13);
+ fHandle.write(currentMsgName, 13);
+ fHandle.write(currentBgName[0], 13);
+ fHandle.write(currentCtName, 13);
+
+ saveU16(0xFF, &fHandle);
+ saveU16(0x20, &fHandle);
+
+ for (i = 0; i < 255; i++) {
+ saveU16(objectTable[i].x, &fHandle);
+ saveU16(objectTable[i].y, &fHandle);
+ saveU16(objectTable[i].mask, &fHandle);
+ saveU16(objectTable[i].frame, &fHandle);
+ saveU16(objectTable[i].costume, &fHandle);
+ fHandle.write(objectTable[i].name, 20);
+ saveU16(objectTable[i].part, &fHandle);
+ }
+
+ for (i = 0; i < 16; i++) {
+ saveU16(palette_[i], &fHandle);
+ }
+
+ for (i = 0; i < 16; i++) {
+ saveU16(tempPalette[i], &fHandle);
+ }
+
+ for (i = 0; i < 255; i++) {
+ saveU16(globalVars[i], &fHandle);
+ }
+
+ for (i = 0; i < 16; i++) {
+ saveU16(zoneData[i], &fHandle);
+ }
+
+ for (i = 0; i < 4; i++) {
+ saveU16(commandVar3[i], &fHandle);
+ }
+
+ fHandle.write(commandBuffer, 0x50);
+
+ saveU16(defaultMenuBoxColor, &fHandle);
+ saveU16(bgVar0, &fHandle);
+ saveU16(allowPlayerInput, &fHandle);
+ saveU16(playerCommand, &fHandle);
+ saveU16(commandVar1, &fHandle);
+ saveU16(isDrawCommandEnabled, &fHandle);
+ saveU16(var5, &fHandle);
+ saveU16(var4, &fHandle);
+ saveU16(var3, &fHandle);
+ saveU16(var2, &fHandle);
+ saveU16(commandVar2, &fHandle);
+ saveU16(defaultMenuBoxColor2, &fHandle);
+ saveU16(0xFF, &fHandle);
+ saveU16(0x1E, &fHandle);
+
+ for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
+ flipU16(&animDataTable[i].width);
+ flipU16(&animDataTable[i].var1);
+ flipU16(&animDataTable[i].field_4);
+ flipU16(&animDataTable[i].var2);
+ flipU16((u16 *) & animDataTable[i].fileIdx);
+ flipU16((u16 *) & animDataTable[i].frameIdx);
+
+ fHandle.write(&animDataTable[i], sizeof(animDataStruct));
+
+ flipU16(&animDataTable[i].width);
+ flipU16(&animDataTable[i].var1);
+ flipU16(&animDataTable[i].field_4);
+ flipU16(&animDataTable[i].var2);
+ flipU16((u16 *) & animDataTable[i].fileIdx);
+ flipU16((u16 *) & animDataTable[i].frameIdx);
+ }
+
+ saveU16(0, &fHandle); // Screen params, unhandled
+ saveU16(0, &fHandle);
+ saveU16(0, &fHandle);
+ saveU16(0, &fHandle);
+ saveU16(0, &fHandle);
+ saveU16(0, &fHandle);
+
+ {
+ s16 numScript = 0;
+ prcLinkedListStruct *currentHead = globalScriptsHead.next;
+
+ while (currentHead) {
+ numScript++;
+ currentHead = currentHead->next;
+ }
+
+ saveU16(numScript, &fHandle);
+
+ // actual save
+ currentHead = globalScriptsHead.next;
+
+ while (currentHead) {
+ s16 i;
+
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ saveU16(currentHead->stack[i], &fHandle);
+ }
+
+ for (i = 0; i < 50; i++) {
+ saveU16(currentHead->localVars[i], &fHandle);
+ }
+
+ saveU16(currentHead->compareResult, &fHandle);
+ saveU16(currentHead->scriptPosition, &fHandle);
+
+ saveU16(currentHead->scriptIdx, &fHandle);
+
+ currentHead = currentHead->next;
+ }
+ }
+
+ {
+ s16 numScript = 0;
+ prcLinkedListStruct *currentHead = objScriptList.next;
+
+ while (currentHead) {
+ numScript++;
+ currentHead = currentHead->next;
+ }
+
+ saveU16(numScript, &fHandle);
+
+ // actual save
+ currentHead = objScriptList.next;
+
+ while (currentHead) {
+ s16 i;
+
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ saveU16(currentHead->stack[i], &fHandle);
+ }
+
+ for (i = 0; i < 50; i++) {
+ saveU16(currentHead->localVars[i], &fHandle);
+ }
+
+ saveU16(currentHead->compareResult, &fHandle);
+ saveU16(currentHead->scriptPosition, &fHandle);
+
+ saveU16(currentHead->scriptIdx, &fHandle);
+
+ currentHead = currentHead->next;
+ }
+ }
+
+ {
+ s16 numScript = 0;
+ overlayHeadElement *currentHead = overlayHead.next;
+
+ while (currentHead) {
+ numScript++;
+ currentHead = currentHead->next;
+ }
+
+ saveU16(numScript, &fHandle);
+
+ // actual save
+ currentHead = overlayHead.next;
+
+ ASSERT(sizeof(overlayHeadElement) == 0x14);
+ while (currentHead) {
+ flipU16(&currentHead->objIdx);
+ flipU16(&currentHead->type);
+ flipU16((u16 *) & currentHead->x);
+ flipU16((u16 *) & currentHead->y);
+ flipU16((u16 *) & currentHead->var10);
+ flipU16((u16 *) & currentHead->var12);
+
+ fHandle.write(currentHead, 0x14);
+
+ flipU16(&currentHead->objIdx);
+ flipU16(&currentHead->type);
+ flipU16((u16 *) & currentHead->x);
+ flipU16((u16 *) & currentHead->y);
+ flipU16((u16 *) & currentHead->var10);
+ flipU16((u16 *) & currentHead->var12);
+
+ currentHead = currentHead->next;
+ }
+ }
+
+ saveU16(0, &fHandle);
+
+ fHandle.close();
+
+ processPendingUpdates(0);
+}
+
+void makeSystemMenu(void) {
+ s16 numEntry;
+ s16 mouseButton;
+ s16 mouseX;
+ s16 mouseY;
+ s16 systemCommand;
+
+ if (!allowSystemMenu) {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, (u16 *) & mouseButton,
+ (u16 *) & mouseX, (u16 *) & mouseY);
+
+ while (mouseButton) {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, (u16 *) & mouseButton,
+ (u16 *) & mouseX, (u16 *) & mouseY);
+ }
+
+ numEntry = 6;
+
+ if (!allowPlayerInput) {
+ numEntry--;
+ }
+
+ systemCommand =
+ makeMenuChoice(systemMenu, numEntry, mouseX, mouseY, 140);
+
+ switch (systemCommand) {
+ case 0:
+ {
+ drawString("PAUSE", 0);
+ waitPlayerInput();
+ break;
+ }
+ case 1:
+ {
+ getMouseData(mouseUpdateStatus,
+ (u16 *) & mouseButton, (u16 *) & mouseX,
+ (u16 *) & mouseY);
+ if (!makeMenuChoice(confirmMenu, 2, mouseX,
+ mouseY + 8, 100)) {
+ //reinitEngine();
+ }
+ break;
+ }
+ case 2:
+ {
+ getMouseData(mouseUpdateStatus,
+ (u16 *) & mouseButton, (u16 *) & mouseX,
+ (u16 *) & mouseY);
+ if (!makeMenuChoice(confirmMenu, 2, mouseX,
+ mouseY + 8, 100)) {
+ exitEngine = 1;
+ }
+ break;
+ }
+ case 3: // Select save drive... change ?
+ {
+ break;
+ }
+ case 4: // load game
+ {
+ if (loadSaveDirectory()) {
+ s16 selectedSave;
+
+ getMouseData(mouseUpdateStatus,
+ (u16 *) & mouseButton,
+ (u16 *) & mouseX,
+ (u16 *) & mouseY);
+ selectedSave =
+ makeMenuChoice(currentSaveName, 10,
+ mouseX, mouseY + 8, 180);
+
+ if (selectedSave >= 0) {
+ char saveNameBuffer[256];
+ if (gameType == Cine::GID_FW)
+ sprintf(saveNameBuffer,
+ "FW.%1d",
+ selectedSave);
+ else
+ sprintf(saveNameBuffer,
+ "OS.%1d",
+ selectedSave);
+
+ getMouseData(mouseUpdateStatus,
+ (u16 *) & mouseButton,
+ (u16 *) & mouseX,
+ (u16 *) & mouseY);
+ if (!makeMenuChoice
+ (confirmMenu, 2, mouseX,
+ mouseY + 8, 100)) {
+ char loadString[256];
+
+ sprintf(loadString,
+ "Chargement de | %s",
+ currentSaveName
+ [selectedSave]);
+ drawString(loadString,
+ 0);
+
+ makeLoad
+ (saveNameBuffer);
+ } else {
+ drawString
+ ("Chargement Annulé ...",
+ 0);
+ waitPlayerInput();
+ checkDataDisk(-1);
+ }
+ } else {
+ drawString
+ ("Chargement Annulé ...",
+ 0);
+ waitPlayerInput();
+ checkDataDisk(-1);
+ }
+ } else {
+ drawString
+ ("Aucune sauvegarde dans le lecteur ...",
+ 0);
+ waitPlayerInput();
+ checkDataDisk(-1);
+ }
+ break;
+ }
+ case 5:
+ {
+ s16 selectedSave;
+
+ loadSaveDirectory();
+ selectedSave =
+ makeMenuChoice(currentSaveName, 10, mouseX,
+ mouseY + 8, 180);
+
+ if (selectedSave >= 0) {
+ char saveFileName[256];
+ //makeTextEntryMenu("Veuillez entrer le Nom de la Sauvegarde .",&currentSaveName[selectedSave],120);
+ sprintf(currentSaveName[selectedSave],
+ "temporary save name");
+
+ if (gameType == Cine::GID_FW)
+ sprintf(saveFileName, "FW.%1d",
+ selectedSave);
+ else
+ sprintf(saveFileName, "OS.%1d",
+ selectedSave);
+
+ getMouseData(mouseUpdateStatus,
+ (u16 *) & mouseButton,
+ (u16 *) & mouseX,
+ (u16 *) & mouseY);
+ if (!makeMenuChoice(confirmMenu, 2,
+ mouseX, mouseY + 8, 100)) {
+ char saveString[256];
+
+ Common::File fHandle;
+
+ if (gameType == Cine::GID_FW)
+ fHandle.open("FW.DIR",
+ Common::File::
+ kFileWriteMode,
+ savePath);
+ else
+ fHandle.open("OS.DIR",
+ Common::File::
+ kFileWriteMode,
+ savePath);
+
+ fHandle.write(currentSaveName,
+ 200);
+ fHandle.close();
+
+ sprintf(saveString,
+ "Sauvegarde de |%s",
+ currentSaveName
+ [selectedSave]);
+ drawString(saveString, 0);
+
+ makeSave(saveFileName);
+
+ checkDataDisk(-1);
+ } else {
+ drawString
+ ("Sauvegarde Annulée ...",
+ 0);
+ waitPlayerInput();
+ checkDataDisk(-1);
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+const s16 choiceResultTable[] = {
+ 1,
+ 1,
+ 1,
+ 2,
+ 1,
+ 1,
+ 1
+};
+
+const s16 subObjectUseTable[] = {
+ 3,
+ 3,
+ 3,
+ 3,
+ 3,
+ 0,
+ 0
+};
+
+const s16 canUseOnItemTable[] = {
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 0,
+ 0
+};
+
+commandeType objectListCommand[20];
+s16 objListTab[20];
+
+s16 processInventory(s16 x, s16 y) {
+ return 0;
+}
+
+s16 buildObjectListCommand(void) {
+ s16 i;
+ s16 j;
+
+ ASSERT(gameType == Cine::GID_FW);
+
+ for (i = 0; i < 20; i++) {
+ objectListCommand[i][0] = 0;
+ }
+
+ j = 0;
+
+ for (i = 0; i < 255; i++) {
+ if (objectTable[i].name[0] && objectTable[i].costume == -2) {
+ strcpy(objectListCommand[j], objectTable[i].name);
+ objListTab[j] = i;
+ j++;
+ }
+ }
+
+ return (j);
+}
+
+s16 buildObjectListCommand2(s16 param) {
+ s16 i;
+ s16 j;
+
+ ASSERT(gameType == Cine::GID_OS);
+
+ for (i = 0; i < 20; i++) {
+ objectListCommand[i][0] = 0;
+ }
+
+ j = 0;
+
+ for (i = 0; i < 255; i++) {
+ if (objectTable[i].name[0] && objectTable[i].costume == param) {
+ strcpy(objectListCommand[j], objectTable[i].name);
+ objListTab[j] = i;
+ j++;
+ }
+ }
+
+ return (j);
+}
+
+s16 selectSubObject(s16 x, s16 y) {
+ s16 listSize = buildObjectListCommand();
+ s16 selectedObject;
+
+ if (!listSize) {
+ return -2;
+ }
+
+ selectedObject =
+ makeMenuChoice(objectListCommand, listSize, x, y, 140);
+
+ if (selectedObject == -1)
+ return -1;
+
+ return objListTab[selectedObject];
+}
+
+s16 selectSubObject2(s16 x, s16 y, s16 param) {
+ s16 listSize = buildObjectListCommand2(param);
+ s16 selectedObject;
+
+ if (!listSize) {
+ return -2;
+ }
+
+ selectedObject =
+ makeMenuChoice2(objectListCommand, listSize, x, y, 140);
+
+ if (selectedObject == -1)
+ return -1;
+
+ if (selectedObject >= 8000) {
+ return objListTab[selectedObject - 8000] + 8000;
+ }
+
+ return objListTab[selectedObject];
+}
+
+s16 canUseOnObject = 0;
+
+void makeCommandLine(void) {
+ u16 x;
+ u16 y;
+
+ commandVar1 = 0;
+ commandVar2 = -10;
+
+ if (playerCommand != -1) {
+ strcpy(commandBuffer, defaultActionCommand[playerCommand]);
+ } else {
+ strcpy(commandBuffer, "");
+ }
+
+ if ((playerCommand != -1) && (choiceResultTable[playerCommand] == 2)) // need object selection ?
+ {
+ s16 si;
+
+ getMouseData(mouseUpdateStatus, &dummyU16, &x, &y);
+
+ if (gameType == Cine::GID_FW) {
+ si = selectSubObject(x, y + 8);
+ } else {
+ si = selectSubObject2(x, y + 8,
+ -subObjectUseTable[playerCommand]);
+ }
+
+ if (si < 0) {
+ playerCommand = -1;
+ strcpy(commandBuffer, "");
+ } else {
+ if (gameType == Cine::GID_OS) {
+ if (si >= 8000) {
+ si -= 8000;
+ canUseOnObject =
+ canUseOnItemTable[playerCommand];
+ } else {
+ canUseOnObject = 0;
+ }
+ }
+
+ commandVar3[0] = si;
+ commandVar1 = 1;
+
+ strcat(commandBuffer, " ");
+ strcat(commandBuffer,
+ objectTable[commandVar3[0]].name);
+ strcat(commandBuffer, " sur");
+ }
+ } else {
+ if (playerCommand == 2) {
+ getMouseData(mouseUpdateStatus, &dummyU16, &x, &y);
+ processInventory(x, y + 8);
+ playerCommand = -1;
+ commandVar1 = 0;
+ strcpy(commandBuffer, "");
+ }
+ }
+
+ if (gameType == Cine::GID_OS) {
+ if (playerCommand != -1 && canUseOnObject != 0) // call use on sub object
+ {
+ s16 si;
+
+ getMouseData(mouseUpdateStatus, &dummyU16, &x, &y);
+
+ si = selectSubObject2(x, y + 8,
+ -subObjectUseTable[playerCommand]);
+
+ if (si) {
+ if (si >= 8000) {
+ si -= 8000;
+ }
+
+ commandVar3[commandVar1] = si;
+
+ commandVar1++;
+
+ // TODO: add command message draw
+ }
+
+ isDrawCommandEnabled = 1;
+
+ if (playerCommand != -1
+ && choiceResultTable[playerCommand] ==
+ commandVar1) {
+ s16 di =
+ getRelEntryForObject(playerCommand,
+ commandVar1,
+ (selectedObjStruct *) & commandVar3);
+
+ if (di != -1) {
+ runObjectScript(di);
+ }
+ }
+ }
+ }
+
+ if (allowSystemMenu == 0) {
+ isDrawCommandEnabled = 1;
+ }
+}
+
+u16 needMouseSave = 0;
+
+u16 menuVar4 = 0;
+u16 menuVar5 = 0;
+
+s16 makeMenuChoice(const commandeType commandList[], u16 height, u16 X, u16 Y,
+ u16 width) {
+ u8 color = 2;
+ u8 color2;
+ s16 paramY;
+ s16 currentX;
+ s16 currentY;
+ s16 i;
+ u16 button;
+ s16 var_A;
+ s16 di;
+ u16 j;
+ s16 mouseX;
+ s16 mouseY;
+ s16 var_16;
+ s16 var_14;
+ s16 currentSelection;
+ s16 oldSelection;
+ s16 var_4;
+
+ if (allowSystemMenu)
+ return -1;
+
+ paramY = (height * 9) + 10;
+
+ if (X + width > 319) {
+ X = 319 - width;
+ }
+
+ if (Y + paramY > 199) {
+ Y = 199 - paramY;
+ }
+
+ color2 = defaultMenuBoxColor2;
+
+ hideMouse();
+ blitRawScreen(page1Raw);
+
+ gfxDrawPlainBoxRaw(X, Y, X + width, Y + 4, color2, page1Raw);
+
+ currentX = X + 4;
+ currentY = Y + 4;
+
+ for (i = 0; i < height; i++) {
+ gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 9,
+ color2, page1Raw);
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[i]); j++) {
+ u8 currentChar = commandList[i][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable[currentChar].
+ characterIdx;
+ drawSpriteRaw(textTable[characterIdx]
+ [0], textTable[characterIdx][1], 2,
+ 8, page1Raw, currentX, currentY);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ currentY += 9;
+ }
+
+ gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 4, color2, page1Raw); // bottom part
+
+ gfxDrawLine(X + 1, Y + 1, X + width - 1, Y + 1, 0, page1Raw); // top
+ gfxDrawLine(X + 1, currentY + 3, X + width - 1, currentY + 3, 0, page1Raw); // bottom
+ gfxDrawLine(X + 1, Y + 1, X + 1, currentY + 3, 0, page1Raw); // left
+ gfxDrawLine(X + width - 1, Y + 1, X + width - 1, currentY + 3, 0, page1Raw); // left
+
+ gfxDrawLine(X, Y, X + width, Y, color, page1Raw);
+ gfxDrawLine(X, currentY + 4, X + width, currentY + 4, color, page1Raw);
+ gfxDrawLine(X, Y, X, currentY + 4, color, page1Raw);
+ gfxDrawLine(X + width, Y, X + width, currentY + 4, color, page1Raw);
+
+ blitRawScreen(page1Raw);
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
+ } while (button);
+
+ var_A = 0;
+
+ currentSelection = 0;
+
+ di = currentSelection * 9 + Y + 4;
+ gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // draw black box behind selection
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[currentSelection]); j++) {
+ u8 currentChar = commandList[currentSelection][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable[currentChar].characterIdx;
+ drawSpriteRaw(textTable[characterIdx][0],
+ textTable[characterIdx][1], 2, 8, page1Raw,
+ currentX, di);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ blitRawScreen(page1Raw);
+
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, (u16 *) & mouseX,
+ (u16 *) & mouseY);
+
+ var_16 = mouseX;
+ var_14 = mouseY;
+
+ menuVar = 0;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, (u16 *) & mouseX,
+ (u16 *) & mouseY);
+
+ if (button) {
+ var_A = 1;
+ }
+
+ oldSelection = currentSelection;
+
+ if (needMouseSave) {
+ for (j = 0; j < 3; j++) {
+ mainLoopSub6();
+ }
+
+ if (menuVar4 && currentSelection > 0) // go up
+ {
+ currentSelection--;
+ }
+
+ if (menuVar5) // go down
+ {
+ if (height - 1 > currentSelection) {
+ currentSelection++;
+ }
+ }
+ } else {
+ if (mouseX > X && mouseX < X + width && mouseY > Y
+ && mouseY < Y + height * 9) {
+ currentSelection = (mouseY - (Y + 4)) / 9;
+
+ if (currentSelection < 0)
+ currentSelection = 0;
+
+ if (currentSelection >= height)
+ currentSelection = height - 1;
+ }
+ }
+
+ if (currentSelection != oldSelection) // old != new
+ {
+ if (needMouseSave) {
+ hideMouse();
+ }
+
+ di = oldSelection * 9 + Y + 4;
+
+ gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, color2, page1Raw); // restore color
+
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[oldSelection]); j++) {
+ u8 currentChar = commandList[oldSelection][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].
+ characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable
+ [currentChar].characterIdx;
+ drawSpriteRaw(textTable
+ [characterIdx][0],
+ textTable[characterIdx][1],
+ 2, 8, page1Raw, currentX,
+ di);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ di = currentSelection * 9 + Y + 4;
+
+ gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // black new
+
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[currentSelection]);
+ j++) {
+ u8 currentChar =
+ commandList[currentSelection][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].
+ characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable
+ [currentChar].characterIdx;
+ drawSpriteRaw(textTable
+ [characterIdx][0],
+ textTable[characterIdx][1],
+ 2, 8, page1Raw, currentX,
+ di);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ blitRawScreen(page1Raw);
+
+ if (needMouseSave) {
+ gfxFuncGen2();
+ }
+ }
+
+ } while (!var_A);
+
+ if (needMouseSave) {
+ ASSERT(0);
+ }
+
+ var_4 = button;
+
+ menuVar = 0;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
+ } while (button);
+
+ if (var_4 == 2) // recheck
+ {
+ return -1;
+ }
+
+ return currentSelection;
+}
+
+s16 makeMenuChoice2(const commandeType commandList[], u16 height, u16 X, u16 Y,
+ u16 width) {
+ u8 color = 2;
+ u8 color2;
+ s16 paramY;
+ s16 currentX;
+ s16 currentY;
+ s16 i;
+ u16 button;
+ s16 var_A;
+ s16 di;
+ u16 j;
+ s16 mouseX;
+ s16 mouseY;
+ s16 var_16;
+ s16 var_14;
+ s16 currentSelection;
+ s16 oldSelection;
+ s16 var_4;
+
+ if (allowSystemMenu)
+ return -1;
+
+ paramY = (height * 9) + 10;
+
+ if (X + width > 319) {
+ X = 319 - width;
+ }
+
+ if (Y + paramY > 199) {
+ Y = 199 - paramY;
+ }
+
+ color2 = defaultMenuBoxColor2;
+
+ hideMouse();
+ blitRawScreen(page1Raw);
+
+ gfxDrawPlainBoxRaw(X, Y, X + width, Y + 4, color2, page1Raw);
+
+ currentX = X + 4;
+ currentY = Y + 4;
+
+ for (i = 0; i < height; i++) {
+ gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 9,
+ color2, page1Raw);
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[i]); j++) {
+ u8 currentChar = commandList[i][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable[currentChar].
+ characterIdx;
+ drawSpriteRaw(textTable[characterIdx]
+ [0], textTable[characterIdx][1], 2,
+ 8, page1Raw, currentX, currentY);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ currentY += 9;
+ }
+
+ gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 4, color2, page1Raw); // bottom part
+
+ gfxDrawLine(X + 1, Y + 1, X + width - 1, Y + 1, 0, page1Raw); // top
+ gfxDrawLine(X + 1, currentY + 3, X + width - 1, currentY + 3, 0, page1Raw); // bottom
+ gfxDrawLine(X + 1, Y + 1, X + 1, currentY + 3, 0, page1Raw); // left
+ gfxDrawLine(X + width - 1, Y + 1, X + width - 1, currentY + 3, 0, page1Raw); // left
+
+ gfxDrawLine(X, Y, X + width, Y, color, page1Raw);
+ gfxDrawLine(X, currentY + 4, X + width, currentY + 4, color, page1Raw);
+ gfxDrawLine(X, Y, X, currentY + 4, color, page1Raw);
+ gfxDrawLine(X + width, Y, X + width, currentY + 4, color, page1Raw);
+
+ blitRawScreen(page1Raw);
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
+ } while (button);
+
+ var_A = 0;
+
+ currentSelection = 0;
+
+ di = currentSelection * 9 + Y + 4;
+ gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // draw black box behind selection
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[currentSelection]); j++) {
+ u8 currentChar = commandList[currentSelection][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable[currentChar].characterIdx;
+ drawSpriteRaw(textTable[characterIdx][0],
+ textTable[characterIdx][1], 2, 8, page1Raw,
+ currentX, di);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ blitRawScreen(page1Raw);
+
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, (u16 *) & mouseX,
+ (u16 *) & mouseY);
+
+ var_16 = mouseX;
+ var_14 = mouseY;
+
+ menuVar = 0;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, (u16 *) & mouseX,
+ (u16 *) & mouseY);
+
+ if (button) {
+ var_A = 1;
+ }
+
+ oldSelection = currentSelection;
+
+ if (needMouseSave) {
+ for (j = 0; j < 3; j++) {
+ mainLoopSub6();
+ }
+
+ if (menuVar4 && currentSelection > 0) // go up
+ {
+ currentSelection--;
+ }
+
+ if (menuVar5) // go down
+ {
+ if (height - 1 > currentSelection) {
+ currentSelection++;
+ }
+ }
+ } else {
+ if (mouseX > X && mouseX < X + width && mouseY > Y
+ && mouseY < Y + height * 9) {
+ currentSelection = (mouseY - (Y + 4)) / 9;
+
+ if (currentSelection < 0)
+ currentSelection = 0;
+
+ if (currentSelection >= height)
+ currentSelection = height - 1;
+ }
+ }
+
+ if (currentSelection != oldSelection) // old != new
+ {
+ if (needMouseSave) {
+ hideMouse();
+ }
+
+ di = oldSelection * 9 + Y + 4;
+
+ gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, color2, page1Raw); // restore color
+
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[oldSelection]); j++) {
+ u8 currentChar = commandList[oldSelection][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].
+ characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable
+ [currentChar].characterIdx;
+ drawSpriteRaw(textTable
+ [characterIdx][0],
+ textTable[characterIdx][1],
+ 2, 8, page1Raw, currentX,
+ di);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ di = currentSelection * 9 + Y + 4;
+
+ gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // black new
+
+ currentX = X + 4;
+
+ for (j = 0; j < strlen(commandList[currentSelection]);
+ j++) {
+ u8 currentChar =
+ commandList[currentSelection][j];
+
+ if (currentChar == ' ') {
+ currentX += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].
+ characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable
+ [currentChar].characterIdx;
+ drawSpriteRaw(textTable
+ [characterIdx][0],
+ textTable[characterIdx][1],
+ 2, 8, page1Raw, currentX,
+ di);
+ currentX += characterWidth + 1;
+ }
+ }
+ }
+
+ blitRawScreen(page1Raw);
+
+ if (needMouseSave) {
+ gfxFuncGen2();
+ }
+ }
+
+ } while (!var_A);
+
+ if (needMouseSave) {
+ ASSERT(0);
+ }
+
+ var_4 = button;
+
+ menuVar = 0;
+
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16);
+ } while (button);
+
+ if (var_4 == 2) // recheck
+ {
+ return currentSelection + 8000;
+ }
+
+ return currentSelection;
+}
+
+void drawMenuBox(char *command, s16 x, s16 y) {
+ u8 j;
+ u8 lColor = 2;
+
+ hideMouse();
+
+ gfxDrawPlainBoxRaw(x, y, x + 300, y + 10, 0, page2Raw);
+
+ gfxDrawLine(x - 1, y - 1, x + 301, y - 1, lColor, page2Raw); // top
+ gfxDrawLine(x - 1, y + 11, x + 301, y + 11, lColor, page2Raw); // bottom
+ gfxDrawLine(x - 1, y - 1, x - 1, y + 11, lColor, page2Raw); // left
+ gfxDrawLine(x + 301, y - 1, x + 301, y + 11, lColor, page2Raw); // right
+
+ x += 2;
+ y += 2;
+
+ for (j = 0; j < strlen(command); j++) {
+ u8 currentChar = command[j];
+
+ if (currentChar == ' ') {
+ x += 5;
+ } else {
+ u8 characterWidth =
+ fontParamTable[currentChar].characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable[currentChar].characterIdx;
+ drawSpriteRaw(textTable[characterIdx][0],
+ textTable[characterIdx][1], 2, 8, page2Raw,
+ x, y);
+ x += characterWidth + 1;
+ }
+ }
+ }
+
+ gfxFuncGen2();
+}
+
+u16 executePlayerInput(void) {
+ u16 var_5E;
+ u16 var_2;
+ u16 mouseButton;
+ u16 mouseX;
+ u16 mouseY;
+
+ canUseOnObject = 0;
+
+ if (isInPause) {
+ drawString("PAUSE", 0);
+ waitPlayerInput();
+ isInPause = 0;
+ }
+
+ if (allowPlayerInput) {
+ u16 currentEntry = 0;
+ u16 di = 0;
+
+ if (isDrawCommandEnabled) {
+ drawMenuBox(commandBuffer, 10, defaultMenuBoxColor);
+
+ isDrawCommandEnabled = 0;
+ }
+
+ getMouseData(mouseUpdateStatus, &mouseButton, &mouseX,
+ &mouseY);
+
+ while (mouseButton && currentEntry < 200) {
+ if (mouseButton & 1) {
+ di |= 1;
+ }
+
+ if (mouseButton & 2) {
+ di |= 2;
+ }
+
+ getMouseData(mouseUpdateStatus, &mouseButton, &mouseX,
+ &mouseY);
+
+ currentEntry++;
+ }
+
+ if (di) {
+ mouseButton = di;
+ }
+
+ if (playerCommand != -1) {
+ if (mouseButton & 1) {
+ if (mouseButton & 2) {
+ makeSystemMenu();
+ } else {
+ s16 si;
+ do {
+ manageEvents();
+ getMouseData(mouseUpdateStatus,
+ &mouseButton, &dummyU16,
+ &dummyU16);
+ } while (mouseButton);
+
+ si = getObjectUnderCursor(mouseX,
+ mouseY);
+
+ if (si != -1) {
+ commandVar3[commandVar1] = si;
+ commandVar1++;
+
+ strcat(commandBuffer, " ");
+ strcat(commandBuffer,
+ objectTable[si].name);
+
+ isDrawCommandEnabled = 1;
+
+ if (choiceResultTable
+ [playerCommand] ==
+ commandVar1) {
+ s16 relEntry;
+
+ drawMenuBox
+ (commandBuffer, 10,
+ defaultMenuBoxColor);
+
+ relEntry =
+ getRelEntryForObject
+ (playerCommand,
+ commandVar1,
+ (selectedObjStruct
+ *)
+ commandVar3);
+
+ if (relEntry != -1) {
+ runObjectScript
+ (relEntry);
+ } else {
+ //addPlayerCommandMessage(playerCommand);
+ }
+
+ playerCommand = -1;
+
+ commandVar1 = 0;
+ strcpy(commandBuffer,
+ "");
+ }
+ } else {
+ globalVars[249] = mouseX;
+ globalVars[250] = mouseY;
+ }
+ }
+ } else {
+ if (mouseButton & 2) {
+ if (mouseButton & 1) {
+ makeSystemMenu();
+ }
+
+ if (gameType == Cine::GID_OS) {
+ playerCommand =
+ makeMenuChoice2
+ (defaultActionCommand, 6,
+ mouseX, mouseY, 70);
+
+ if (playerCommand >= 8000) {
+ playerCommand -= 8000;
+ canUseOnObject = 1;
+ }
+ } else {
+ playerCommand =
+ makeMenuChoice
+ (defaultActionCommand, 6,
+ mouseX, mouseY, 70);
+ }
+
+ makeCommandLine();
+ } else {
+ s16 objIdx;
+
+ objIdx =
+ getObjectUnderCursor(mouseX,
+ mouseY);
+
+ if (commandVar2 != objIdx) {
+ if (objIdx != -1) {
+ char command[256];
+
+ strcpy(command,
+ commandBuffer);
+ strcat(command, " ");
+ strcat(command,
+ objectTable
+ [objIdx].name);
+
+ drawMenuBox(command,
+ 10,
+ defaultMenuBoxColor);
+ } else {
+ isDrawCommandEnabled =
+ 1;
+ }
+ }
+
+ commandVar2 = objIdx;
+ }
+ }
+ } else {
+ if (mouseButton & 2) {
+ if (!(mouseButton & 1)) {
+ if (gameType == Cine::GID_OS) {
+ playerCommand =
+ makeMenuChoice2
+ (defaultActionCommand, 6,
+ mouseX, mouseY, 70);
+
+ if (playerCommand >= 8000) {
+ playerCommand -= 8000;
+ canUseOnObject = 1;
+ }
+ } else {
+ playerCommand =
+ makeMenuChoice
+ (defaultActionCommand, 6,
+ mouseX, mouseY, 70);
+ }
+
+ makeCommandLine();
+ } else {
+ makeSystemMenu();
+ }
+ } else {
+ if (mouseButton & 1) {
+ if (!(mouseButton & 2)) {
+ s16 objIdx;
+ s16 relEntry;
+
+ globalVars[249] = mouseX;
+ if (!mouseX) {
+ globalVars[249]++;
+ }
+
+ globalVars[250] = mouseY;
+
+ objIdx =
+ getObjectUnderCursor
+ (mouseX, mouseY);
+
+ if (objIdx != -1) {
+ currentSelectedObject.
+ idx = objIdx;
+ currentSelectedObject.
+ param = -1;
+
+ relEntry =
+ getRelEntryForObject
+ (6, 1,
+ &currentSelectedObject);
+
+ if (relEntry != -1) {
+ runObjectScript
+ (relEntry);
+ }
+ }
+ } else {
+ makeSystemMenu();
+ }
+ }
+ }
+ }
+ } else {
+ u16 di = 0;
+ getMouseData(mouseUpdateStatus, &mouseButton, &mouseX,
+ &mouseY);
+
+ while (mouseButton) {
+ if (mouseButton & 1) {
+ di |= 1;
+ }
+
+ if (mouseButton & 2) {
+ di |= 2;
+ }
+
+ manageEvents();
+ getMouseData(mouseUpdateStatus, &mouseButton, &mouseX,
+ &mouseY);
+ }
+
+ if (di) {
+ mouseButton = di;
+ }
+
+ if ((mouseButton & 1) && (mouseButton & 2)) {
+ makeSystemMenu();
+ }
+ }
+
+ var_2 = menuVar & 0x7F;
+ var_5E = var_2;
+
+ if (menuVar & 0x80) {
+ var_5E = 0;
+ var_2 = 0;
+ }
+
+ if (inputVar1 && allowPlayerInput) // use keyboard
+ {
+ inputVar1 = 0;
+
+ switch (globalVars[253]) {
+ case 1:
+ {
+ mouseX = objectTable[1].x + 12;
+ break;
+ }
+ case 2:
+ {
+ mouseX = objectTable[1].x + 7;
+ break;
+ }
+ default:
+ {
+ mouseX = globalVars[249];
+ break;
+ }
+ }
+
+ switch (globalVars[251]) {
+ case 1:
+ {
+ mouseY = objectTable[1].y + 34;
+ break;
+ }
+ case 2:
+ {
+ mouseY = objectTable[1].y + 28;
+ break;
+ }
+ default:
+ {
+ mouseX = globalVars[250];
+ break;
+ }
+ }
+
+ if (var_5E == bgVar0) {
+ var_5E = 0;
+
+ globalVars[249] = mouseX;
+ globalVars[250] = mouseY;
+ } else {
+ if (inputVar2) {
+ if (inputVar2 == 2) {
+ globalVars[249] = 1;
+ } else {
+ globalVars[249] = 320;
+ }
+ } else {
+ globalVars[249] = mouseX;
+ }
+
+ if (inputVar3) {
+ if (inputVar3 == 2) {
+ globalVars[250] = 1;
+ } else {
+ globalVars[250] = 200;
+ }
+ } else {
+ globalVars[250] = mouseY;
+ }
+ }
+
+ bgVar0 = var_5E;
+ } else // don't use keyboard for move -> shortcuts to commands
+ {
+ getMouseData(mouseUpdateStatus, &mouseButton, &mouseX,
+ &mouseY);
+
+ switch (var_2 - 59) {
+ case 0:
+ {
+ if (allowPlayerInput) {
+ playerCommand = 0;
+ makeCommandLine();
+ }
+ break;
+ }
+ case 1:
+ {
+ if (allowPlayerInput) {
+ playerCommand = 1;
+ makeCommandLine();
+ }
+ break;
+ }
+ case 2:
+ {
+ if (allowPlayerInput) {
+ playerCommand = 2;
+ makeCommandLine();
+ }
+ break;
+ }
+ case 3:
+ {
+ if (allowPlayerInput) {
+ playerCommand = 3;
+ makeCommandLine();
+ }
+ break;
+ }
+ case 4:
+ {
+ if (allowPlayerInput) {
+ playerCommand = 4;
+ makeCommandLine();
+ }
+ break;
+ }
+ case 5:
+ {
+ if (allowPlayerInput) {
+ playerCommand = 5;
+ makeCommandLine();
+ }
+ break;
+ }
+ case 6:
+ case 7:
+ case 8:
+ case 23:
+ {
+ break;
+ }
+ case 9:
+ case 24:
+ {
+ makeSystemMenu();
+ break;
+ }
+ default:
+ {
+ // printf("Unhandled case %d in last part of executePLayerInput\n",var2-59);
+ break;
+ }
+ }
+ }
+
+ return var_5E;
+}
+
+void drawSprite(overlayHeadElement *currentOverlay, u8 *spritePtr,
+ u8 *maskPtr, u16 width, u16 height, u8 *page, s16 x, s16 y) {
+ u8 *ptr = NULL;
+ u8 i = 0;
+ u16 si = 0;
+ overlayHeadElement *pCurrentOverlay = currentOverlay;
+
+#if 0
+ while(pCurrentOverlay) { // unfinished, probably for mask handling..
+ if (pCurrentOverlay->type == 5) {
+ s16 maskX;
+ s16 maskY;
+ s16 maskWidth;
+ s16 maskHeight;
+ u16 maskSpriteIdx;
+
+ if (!si) {
+ ptr = (u8 *)malloc(width * height);
+ si = 1;
+ }
+
+ maskX = objectTable[pCurrentOverlay->objIdx].x;
+ maskY = objectTable[pCurrentOverlay->objIdx].y;
+
+ maskSpriteIdx = objectTable[pCurrentOverlay->objIdx].frame;
+
+ maskWidth = animDataTable[maskSpriteIdx].width/2;
+ maskHeight = animDataTable[maskSpriteIdx].var2;
+
+ gfxSpriteFunc2(spritePtr, width, height, animDataTable[maskSpriteIdx].ptr1, maskWidth, maskHeight, ptr, maskX-x ,maskY-y, i++);
+ }
+
+ pCurrentOverlay = pCurrentOverlay->next;
+ }
+
+ if(si) {
+ gfxSpriteFunc1(ptr, width, height, page, x, y);
+ free(ptr);
+ } else
+#endif
+
+ if (gameType == Cine::GID_OS) {
+ drawSpriteRaw2(spritePtr,
+ objectTable[currentOverlay->objIdx].part, width, height,
+ page, x, y);
+ } else {
+ drawSpriteRaw(spritePtr, maskPtr, width, height, page, x, y);
+ }
+
+}
+
+s16 additionalBgVScroll = 0;
+
+void backupOverlayPage(void) {
+ u8 *bgPage;
+ u8 *scrollBg;
+
+ bgPage = additionalBgTable[currentAdditionalBgIdx];
+
+ if (bgPage) {
+ if (!additionalBgVScroll) {
+ memcpy(page1Raw, bgPage, 320 * 200);
+ } else {
+ s16 i;
+
+ scrollBg = additionalBgTable[currentAdditionalBgIdx2];
+
+ for (i = additionalBgVScroll;
+ i < 200 + additionalBgVScroll; i++) {
+ if (i > 200) {
+ memcpy(page1Raw + (i -
+ additionalBgVScroll) * 320,
+ scrollBg + (i - 200) * 320, 320);
+ } else {
+ memcpy(page1Raw + (i -
+ additionalBgVScroll) * 320,
+ bgPage + (i) * 320, 320);
+ }
+ }
+ }
+ }
+}
+
+u16 computeMessageLength(u8 *ptr, u16 width, u16 *numWords,
+ u16 *messageWidth, u16 *lineResult) {
+ u8 *localPtr = ptr;
+
+ u16 var_2 = 0;
+ u16 localLineResult = 0;
+ u16 var_6 = 0;
+ u16 var_8 = 0;
+ u16 localMessageWidth = 0;
+ u16 var_16 = 0;
+ u16 finished = 0;
+ u16 si = 0;
+ u16 di = 0;
+
+ while (!finished) {
+ u8 character = *(localPtr++);
+
+ if (character == ' ') {
+ var_8 = var_16;
+ var_6 = localMessageWidth;
+ localLineResult = si;
+ var_2 = di;
+
+ if (si + 5 < width) {
+ var_16++;
+ si += 5;
+ } else {
+ finished = 1;
+ }
+ } else if (character == 0x7C || character == 0) {
+ finished = 1;
+ si = 0;
+ } else {
+ if (fontParamTable[character].characterWidth) {
+ u16 var_C =
+ fontParamTable[character].characterWidth;
+
+ if (si + var_C < width) {
+ si += var_C;
+ localMessageWidth += var_C;
+ } else {
+ finished = 1;
+
+ if (localLineResult) {
+ var_16 = var_8;
+ localMessageWidth = var_6;
+ si = localLineResult;
+ di = var_2;
+ }
+ }
+ }
+ }
+
+ di++;
+ }
+
+ *numWords = var_16;
+ *messageWidth = localMessageWidth;
+ *lineResult = si;
+
+ return (di);
+}
+
+void drawDialogueMessage(u8 msgIdx, s16 x, s16 y, s16 width, s16 color) {
+ u8 color2 = 2;
+ u8 endOfMessageReached = 0;
+ s16 localX;
+ s16 localY;
+ s16 localWidth;
+
+ char *messagePtr = (char *)messageTable[msgIdx].ptr;
+
+ if (!messagePtr) {
+ freeOverlay(msgIdx, 2);
+ }
+
+ var20 += strlen(messagePtr);
+
+ gfxDrawPlainBoxRaw(x, y, x + width, y + 4, color, page1Raw);
+
+ localX = x + 4;
+ localY = y + 4;
+ localWidth = width - 8;
+
+ do {
+ u16 messageLength = 0;
+ u16 numWords;
+ u16 messageWidth;
+ u16 lineResult;
+ char *endOfMessagePtr;
+ u16 fullLineWidth;
+ u16 interWordSize;
+ u16 interWordSizeRemain;
+ u8 currentChar;
+ u8 characterWidth;
+
+ while (messagePtr[messageLength] == ' ') {
+ messageLength++;
+ }
+
+ messagePtr += messageLength;
+
+ messageLength =
+ computeMessageLength((u8 *) messagePtr, localWidth,
+ &numWords, &messageWidth, &lineResult);
+
+ endOfMessagePtr = messagePtr + messageLength;
+
+ if (lineResult) {
+ fullLineWidth = localWidth - messageWidth;
+
+ if (numWords) {
+ interWordSize = fullLineWidth / numWords;
+ interWordSizeRemain = fullLineWidth % numWords;
+ } else {
+ interWordSize = 5;
+ interWordSizeRemain = 0;
+ }
+ } else {
+ interWordSize = 5;
+ interWordSizeRemain = 0;
+ }
+
+ gfxDrawPlainBoxRaw(x, localY, x + width, localY + 9, color,
+ page1Raw);
+
+ do {
+ currentChar = *(messagePtr++);
+
+ if (currentChar == 0) {
+ endOfMessageReached = 1;
+ } else if (currentChar == ' ') {
+ localX += interWordSizeRemain + interWordSize;
+
+ if (interWordSizeRemain)
+ interWordSizeRemain = 0;
+ } else {
+ characterWidth =
+ fontParamTable[currentChar].characterWidth;
+
+ if (characterWidth) {
+ u8 characterIdx =
+ fontParamTable[currentChar].
+ characterIdx;
+ drawSpriteRaw(textTable[characterIdx]
+ [0], textTable[characterIdx][1], 2,
+ 8, page1Raw, localX, localY);
+ localX += characterWidth;
+ }
+ }
+ } while ((messagePtr < endOfMessagePtr)
+ && !endOfMessageReached);
+
+ localX = x + 4;
+ localY += 9;
+ } while (!endOfMessageReached);
+
+ gfxDrawPlainBoxRaw(x, localY, x + width, localY + 4, color, page1Raw);
+
+ gfxDrawLine(x + 1, y + 1, x + width - 1, y + 1, 0, page1Raw); // top
+ gfxDrawLine(x + 1, localY + 3, x + width - 1, localY + 3, 0, page1Raw); // bottom
+ gfxDrawLine(x + 1, y + 1, x + 1, localY + 3, 0, page1Raw); // left
+ gfxDrawLine(x + width - 1, y + 1, x + width - 1, localY + 3, 0, page1Raw); // right
+
+ gfxDrawLine(x, y, x + width, y, color2, page1Raw);
+ gfxDrawLine(x, localY + 4, x + width, localY + 4, color2, page1Raw);
+ gfxDrawLine(x, y, x, localY + 4, color2, page1Raw);
+ gfxDrawLine(x + width, y, x + width, localY + 4, color2, page1Raw);
+
+ freeOverlay(msgIdx, 2);
+}
+
+void drawOverlays(void) {
+ overlayHeadElement *currentOverlay;
+
+ backupOverlayPage();
+
+ var20 = 0;
+
+ currentOverlay = &overlayHead;
+
+ currentOverlay = currentOverlay->next;
+
+ while (currentOverlay) {
+ switch (currentOverlay->type) {
+ case 0: // sprite
+ {
+ objectStruct *objPtr;
+ s16 x;
+ s16 y;
+
+ ASSERT(currentOverlay->objIdx >= 0
+ && currentOverlay->objIdx <=
+ NUM_MAX_OBJECT);
+
+ objPtr = &objectTable[currentOverlay->objIdx];
+
+ x = objPtr->x;
+ y = objPtr->y;
+
+ if (objPtr->frame >= 0) {
+ if (gameType == Cine::GID_OS) {
+ u16 partVar1;
+ u16 partVar2;
+ animDataStruct *pPart;
+ pPart =
+ &animDataTable[objPtr->
+ frame];
+
+ partVar1 = pPart->var1;
+ partVar2 = pPart->var2;
+
+ if (pPart->ptr1) {
+ drawSprite
+ (currentOverlay,
+ pPart->ptr1,
+ pPart->ptr1,
+ partVar1, partVar2,
+ page1Raw, x, y);
+ }
+ } else {
+ u16 partVar1;
+ u16 partVar2;
+ animDataStruct *pPart;
+ s16 part = objPtr->part;
+
+ ASSERT(part >= 0
+ && part <=
+ NUM_MAX_PARTDATA);
+
+ pPart =
+ &animDataTable[objPtr->
+ frame];
+
+ partVar1 = pPart->var1;
+ partVar2 = pPart->var2;
+
+ if (pPart->ptr1) {
+ drawSprite
+ (currentOverlay,
+ pPart->ptr1,
+ pPart->ptr2,
+ partVar1, partVar2,
+ page1Raw, x, y);
+ }
+ }
+ }
+ break;
+ }
+ case 2: // text
+ {
+ u8 messageIdx;
+ s16 x;
+ s16 y;
+ u16 partVar1;
+ u16 partVar2;
+
+ /* gfxWaitVSync();
+ * hideMouse(); */
+
+ messageIdx = currentOverlay->objIdx;
+ x = currentOverlay->x;
+ y = currentOverlay->y;
+ partVar1 = currentOverlay->var10;
+ partVar2 = currentOverlay->var12;
+
+ blitRawScreen(page1Raw);
+
+ drawDialogueMessage(messageIdx, x, y, partVar1,
+ partVar2);
+
+ //blitScreen(page0,NULL);
+
+ gfxFuncGen2();
+
+ waitForPlayerClick = 1;
+
+ break;
+ }
+ case 3:
+ {
+ break;
+ }
+ case 4:
+ {
+ objectStruct *objPtr;
+ s16 x;
+ s16 y;
+
+ ASSERT(currentOverlay->objIdx >= 0
+ && currentOverlay->objIdx <=
+ NUM_MAX_OBJECT);
+
+ objPtr = &objectTable[currentOverlay->objIdx];
+
+ x = objPtr->x;
+ y = objPtr->y;
+
+ if (objPtr->frame >= 0) {
+ u16 partVar1;
+ u16 partVar2;
+ animDataStruct *pPart;
+ s16 part = objPtr->part;
+
+ ASSERT(part >= 0
+ && part <= NUM_MAX_PARTDATA);
+
+ pPart = &animDataTable[objPtr->frame];
+
+ partVar1 = pPart->width / 2;
+ partVar2 = pPart->var2;
+
+ if (pPart->ptr1) {
+ gfxFillSprite(pPart->ptr1,
+ partVar1, partVar2,
+ page1Raw, x, y);
+ }
+ }
+ break;
+ }
+ case 20:
+ {
+ objectStruct *objPtr;
+ s16 x;
+ s16 y;
+
+ var5 = currentOverlay->x;
+
+ ASSERT(currentOverlay->objIdx >= 0
+ && currentOverlay->objIdx <=
+ NUM_MAX_OBJECT);
+
+ objPtr = &objectTable[currentOverlay->objIdx];
+
+ x = objPtr->x;
+ y = objPtr->y;
+
+ if (objPtr->frame >= 0) {
+ if (var5 >= 0 && var5 <= 8) {
+ if (additionalBgTable[var5]) {
+ if (animDataTable
+ [objPtr->frame].
+ field_4 == 1) {
+ s16 x2;
+ s16 y2;
+
+ x2 = animDataTable[objPtr->frame].width / 2;
+ y2 = animDataTable[objPtr->frame].var2;
+
+ if (animDataTable[objPtr->frame].ptr1) {
+ // drawSpriteRaw(animDataTable[objPtr->frame].ptr1,animDataTable[objPtr->frame].ptr1,x2,y2,additionalBgTable[currentAdditionalBgIdx],x,y);
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ currentOverlay = currentOverlay->next;
+ }
+}
+
+void flip(void) {
+ blitRawScreen(page1Raw);
+}
+
+u16 processKeyboard(u16 param) {
+ return 0;
+}
+
+void mainLoopSub6(void) {
+}
+
+void checkForPendingDataLoad(void) {
+ if (newPrcName[0] != 0) {
+ freePrcLinkedList();
+ resetglobalScriptsHead();
+
+ loadPrc(newPrcName);
+
+ strcpy(currentPrcName, newPrcName);
+ strcpy(newPrcName, "");
+
+ addScriptToList0(1);
+ }
+
+ if (newRelName[0] != 0) {
+ releaseObjectScripts();
+ resetObjectScriptHead();
+
+ loadRel(newRelName);
+
+ strcpy(currentRelName, newRelName);
+ strcpy(newRelName, "");
+ }
+
+ if (newObjectName[0] != 0) {
+ unloadAllMasks();
+ resetMessageHead();
+
+ loadObject(newObjectName);
+
+ strcpy(currentObjectName, newObjectName);
+ strcpy(newObjectName, "");
+ }
+
+ if (newMsgName[0] != 0) {
+ loadMsg(newMsgName);
+
+ strcpy(currentMsgName, newMsgName);
+ strcpy(newMsgName, "");
+ }
+}
+
+u16 exitEngine;
+
+void hideMouse(void) {
+}
+
+void closeEngine7(void) {
+}
+
+void removeExtention(char *dest, const char *source) {
+ u8 *ptr;
+
+ strcpy(dest, source);
+
+ ptr = (u8 *) strchr(dest, '.');
+
+ if (ptr) {
+ *ptr = 0;
+ }
+}
+
+u16 var22;
+
+u16 defaultMenuBoxColor2;
+
+u16 zoneData[NUM_MAX_ZONE];
+
+void addMessage(u8 param1, s16 param2, s16 param3, s16 param4, s16 param5) {
+ overlayHeadElement *currentHead = &overlayHead;
+ overlayHeadElement *tempHead = currentHead;
+ overlayHeadElement *newElement;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ newElement = (overlayHeadElement *) malloc(sizeof(overlayHeadElement));
+
+ newElement->next = tempHead->next;
+ tempHead->next = newElement;
+
+ newElement->objIdx = param1;
+ newElement->type = 2;
+
+ newElement->x = param2;
+ newElement->y = param3;
+ newElement->var10 = param4;
+ newElement->var12 = param5;
+
+ if (!currentHead)
+ currentHead = &overlayHead;
+
+ newElement->previous = currentHead->previous;
+
+ currentHead->previous = newElement;
+}
+
+unkListElementStruct unkList;
+
+void addUnkListElement(s16 param0, s16 param1, s16 param2, s16 param3,
+ s16 param4, s16 param5, s16 param6, s16 param7, s16 param8) {
+ unkListElementStruct *currentHead = &unkList;
+ unkListElementStruct *tempHead = currentHead;
+ unkListElementStruct *newElement;
+
+ currentHead = tempHead->next;
+
+ while (currentHead && currentHead->varE < param7) {
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+
+ newElement =
+ (unkListElementStruct *) malloc(sizeof(unkListElementStruct));
+
+ newElement->next = tempHead->next;
+ tempHead->next = newElement;
+
+ newElement->var6 = param0;
+ newElement->var4 = param1;
+ newElement->var8 = param2;
+ newElement->varA = param3;
+ newElement->varC = param4;
+ newElement->var14 = 0;
+ newElement->var16 = 0;
+ newElement->var18 = param5;
+ newElement->var1A = param6;
+ newElement->varE = param7;
+ newElement->var10 = param8;
+ newElement->var12 = param8;
+ newElement->var1C = 0;
+ newElement->var1E = 0;
+}
+
+void resetUnkList() {
+ unkList.next = NULL;
+}
+
+void computeMove1(unkListElementStruct *element, s16 x, s16 y, s16 param1,
+ s16 param2, s16 x2, s16 y2) {
+ element->var16 = 0;
+ element->var14 = 0;
+
+ if (y2) {
+ if (y - param2 > y2) {
+ element->var16 = 2;
+ }
+
+ if (y + param2 < y2) {
+ element->var16 = 1;
+ }
+ }
+
+ if (x2) {
+ if (x - param1 > x2) {
+ element->var14 = 2;
+ }
+
+ if (x + param1 < x2) {
+ element->var14 = 1;
+ }
+ }
+}
+
+u16 computeMove2(unkListElementStruct *element) {
+ s16 returnVar = 0;
+
+ if (element->var16 == 1) {
+ returnVar = 4;
+ } else if (element->var16 == 2) {
+ returnVar = 3;
+ }
+
+ if (element->var14 == 1) {
+ returnVar = 1;
+ } else if (element->var14 == 2) {
+ returnVar = 2;
+ }
+
+ return returnVar;
+}
+
+// sort all the gfx stuff...
+
+void resetGfxEntityEntry(u16 objIdx) {
+#if 0
+ overlayHeadElement* tempHead = &overlayHead;
+ u8* var_16 = NULL;
+ u16 var_10 = 0;
+ u16 var_12 = 0;
+ overlayHeadElement* currentHead = tempHead->next;
+ u8* var_1A = NULL;
+ overlayHeadElement* var1E = &overlayHead;
+
+ while(currentHead) {
+ tempHead2 = currentHead->next;
+
+ if(currentHead->objIdx == objIdx && currentHead->type!=2 && currentHead->type!=3 && currentHead->type!=0x14) {
+ tempHead->next = tempHead2;
+
+ if(tempHead2) {
+ tempHead2->previous = currentHead->previous;
+ } else {
+ seqVar0 = currentHead->previous;
+ }
+
+ var_22 = var_16;
+
+ if(!var_22) {
+ // todo: goto?
+ }
+
+ var_22->previous = currentHead;
+ } else {
+ }
+
+ if(currentHead->type == 0x14) {
+ } else {
+ }
+
+ if(currentHead->type == 0x2 || currentHead->type == 0x3) {
+ si = 10000;
+ } else {
+ si = objectTable[currentHead->objIdx];
+ }
+
+ if(objectTable[objIdx]>si) {
+ var1E = currentHead;
+ }
+
+ tempHead = tempHead->next;
+
+ }
+
+ if(var_1A) {
+ currentHead = var_16;
+ var_22 = var_1E->next;
+ var_1E->next = currentHead;
+ var_1A->next = var_22;
+
+ if(var_1E != &gfxEntityHead) {
+ currentHead->previous = var_1E;
+ }
+
+ if(!var_22) {
+ seqVar0 = var_1A;
+ } else {
+ var_22->previous = var_1A;
+ }
+
+ }
+#endif
+}
+
+u16 addAni(u16 param1, u16 param2, u8 *ptr, unkListElementStruct *element,
+ u16 param3, s16 *param4) {
+ u8 *currentPtr = ptr;
+ u8 *ptrData;
+ u8 *ptr2;
+ s16 di;
+
+ ASSERT_PTR(ptr);
+ ASSERT_PTR(element);
+ ASSERT_PTR(param4);
+
+ dummyU16 = *(u16 *) ((currentPtr + param1 * 2) + 8);
+ flipU16(&dummyU16);
+
+ ptrData = ptr + dummyU16;
+
+ ASSERT(*ptrData);
+
+ di = (objectTable[param2].costume + 1) % (*ptrData);
+ ptr2 = (ptrData + (di * 8)) + 1;
+
+ if ((checkCollision(param2, ptr2[0], ptr2[1], ptr2[2], ptr[0]) & 1)) {
+ return 0;
+ }
+
+ objectTable[param2].x += (s8) ptr2[4];
+ objectTable[param2].y += (s8) ptr2[5];
+ objectTable[param2].mask += (s8) ptr2[6];
+
+ if (objectTable[param2].frame) {
+ resetGfxEntityEntry(param2);
+ }
+
+ objectTable[param2].frame = ptr2[7] + element->var8;
+
+ if (param3 || !element->var14) {
+ objectTable[param2].costume = di;
+ } else {
+ *param4 = di;
+ }
+
+ return 1;
+}
+
+void processUnkListElement(unkListElementStruct *element) {
+ s16 x;
+ s16 y;
+ u8 *ptr1;
+ s16 var_10;
+ s16 var_4;
+ s16 var_2;
+
+ if (element->var12 < element->var10) {
+ element->var12++;
+ return;
+ }
+
+ element->var12 = 0;
+
+ x = objectTable[element->var6].x;
+ y = objectTable[element->var6].y;
+ ptr1 = animDataTable[element->varA].ptr1;
+
+ if (ptr1) {
+ u16 param1;
+ u16 param2;
+
+ param1 = ptr1[1];
+ param2 = ptr1[2];
+
+ if (element->varC == 255) {
+ if (globalVars[249] || globalVars[250]) {
+ computeMove1(element, ptr1[4] + x, ptr1[5] + y,
+ param1, param2, globalVars[249],
+ globalVars[250]);
+ } else {
+ element->var16 = 0;
+ element->var14 = 0;
+ }
+ } else {
+ ASSERT(0);
+ }
+
+ var_10 = computeMove2(element);
+
+ if (var_10) {
+ element->var1C = var_10;
+ element->var1E = var_10;
+ }
+
+ var_4 = -1;
+
+ if ((element->var16 == 1
+ && !addAni(3, element->var6, ptr1, element, 0, &var_4))
+ || (element->var16 == 2
+ && !addAni(2, element->var6, ptr1, element, 0,
+ &var_4))) {
+ if (element->varC == 255) {
+ globalVars[250] = 0;
+ }
+ }
+
+ if ((element->var14 == 1
+ && !addAni(0, element->var6, ptr1, element, 1,
+ &var_2))) {
+ if (element->varC == 255) {
+ globalVars[249] = 0;
+
+ if (var_4 != -1) {
+ objectTable[element->var6].costume =
+ var_4;
+ }
+ }
+ }
+
+ if ((element->var14 == 2
+ && !addAni(1, element->var6, ptr1, element, 1,
+ &var_2))) {
+ if (element->varC == 255) {
+ globalVars[249] = 0;
+
+ if (var_4 != -1) {
+ objectTable[element->var6].costume =
+ var_4;
+ }
+ }
+ }
+
+ if (element->var16 + element->var14) {
+ if (element->var1C) {
+ if (element->var1E) {
+ objectTable[element->var6].costume = 0;
+ element->var1E = 0;
+ }
+
+ addAni(element->var1C + 3, element->var6, ptr1,
+ element, 1, (s16 *) & var2);
+
+ }
+ }
+
+ }
+}
+
+void processUnkList(void) {
+ unkListElementStruct *currentHead = &unkList;
+ unkListElementStruct *tempHead = currentHead;
+
+ currentHead = tempHead->next;
+
+ while (currentHead) {
+ if (currentHead->var4 != -1) {
+ processUnkListElement(currentHead);
+ }
+
+ tempHead = currentHead;
+ currentHead = tempHead->next;
+ }
+}
diff --git a/engines/cine/various.h b/engines/cine/various.h
new file mode 100644
index 0000000000..a8864ea9f2
--- /dev/null
+++ b/engines/cine/various.h
@@ -0,0 +1,193 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2006 The ScummVM project
+ *
+ * cinE Engine is (C) 2004-2005 by CinE Team
+ *
+ * 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef CINE_VARIOUS_H_
+#define CINE_VARIOUS_H_
+
+#include "cine/cine.h"
+
+extern int gameType;
+
+typedef char commandeType[20];
+
+s16 makeMenuChoice(const commandeType commandList[], u16 height, u16 X, u16 Y,
+ u16 width);
+s16 makeMenuChoice2(const commandeType commandList[], u16 height, u16 X, u16 Y,
+ u16 width);
+
+extern s16 allowSystemMenu;
+
+typedef struct {
+ u8 *ptr;
+ u16 len;
+} unk1Struct;
+
+#define NUM_MAX_MESSAGE 255
+
+extern unk1Struct messageTable[NUM_MAX_MESSAGE];
+
+struct unkListElementStruct {
+ struct unkListElementStruct *next;
+ s16 var4;
+ s16 var6;
+ s16 var8;
+ s16 varA;
+ s16 varC;
+ s16 varE;
+ s16 var10;
+ s16 var12;
+ s16 var14;
+ s16 var16;
+ s16 var18;
+ s16 var1A;
+ s16 var1C;
+ s16 var1E;
+};
+
+typedef struct unkListElementStruct unkListElementStruct;
+
+extern unkListElementStruct unkList;
+
+extern u32 var6;
+extern u32 var8;
+extern u8 *var9;
+
+extern u16 var2;
+extern u16 var3;
+extern u16 var4;
+extern u16 var5;
+
+extern Common::File palFileHandle;
+extern Common::File partFileHandle;
+
+void processPendingUpdates(s16 param);
+void closeEngine3(void);
+void mainLoopSub1(void);
+void mainLoopSub2(u16 param1, u16 param2, u16 param3, u16 param4);
+
+extern u16 errorVar;
+extern u8 menuVar;
+
+void gfxFuncGen1(u8 *param1, u8 *param2, u8 *param3, u8 *param4,
+ s16 param5);
+
+extern u8 *page0;
+extern u8 *page0c;
+
+void ptrGfxFunc13(void);
+void gfxFuncGen2(void);
+
+extern u16 allowPlayerInput;
+
+extern u16 checkForPendingDataLoadSwitch;
+
+extern u16 fadeRequired;
+extern u16 isDrawCommandEnabled;
+extern u16 waitForPlayerClick;
+extern u16 var16;
+extern u16 var17;
+extern u16 var18;
+extern u16 var19;
+extern u16 var20;
+extern u8 var21;
+
+extern s16 playerCommand;
+
+extern char commandBuffer[80];
+
+extern u16 c_palette[256];
+
+extern char currentPrcName[20];
+extern char currentRelName[20];
+extern char currentObjectName[20];
+extern char currentMsgName[20];
+extern char newPrcName[20];
+extern char newRelName[20];
+extern char newObjectName[20];
+extern char newMsgName[20];
+
+extern char currentBgName[8][15];
+extern char currentCtName[15];
+extern char currentPartName[15];
+
+void stopSample(void);
+void mainLoopSub3(void);
+u16 executePlayerInput(void);
+
+void drawOverlays(void);
+void flip(void);
+
+extern u16 mouseUpdateStatus;
+extern u16 dummyU16;
+
+void getMouseData(u16 param, u16 *pButton, u16 *pX, u16 *pY);
+
+u16 processKeyboard(u16 param);
+
+void mainLoopSub6(void);
+
+void checkForPendingDataLoad(void);
+
+extern u16 exitEngine;
+
+void hideMouse(void);
+void closeEngine7(void);
+
+extern u16 var22;
+
+void removeExtention(char *dest, const char *source);
+
+struct selectedObjStruct {
+ s16 idx;
+ s16 param;
+};
+
+typedef struct selectedObjStruct selectedObjStruct;
+
+extern u16 defaultMenuBoxColor;
+extern u16 defaultMenuBoxColor2;
+
+#define NUM_MAX_ZONE 16
+extern u16 zoneData[NUM_MAX_ZONE];
+
+void addMessage(u8 param1, s16 param2, s16 param3, s16 param4, s16 param5);
+
+void blitScreen(u8 *frontBuffer, u8 *backbuffer);
+
+struct mouseStatusStruct {
+ int left;
+ int right;
+ int X;
+ int Y;
+};
+
+typedef struct mouseStatusStruct mouseStatusStruct;
+
+extern s16 additionalBgVScroll;
+
+void addUnkListElement(s16 param0, s16 param1, s16 param2, s16 param3,
+ s16 param4, s16 param5, s16 param6, s16 param7, s16 param8);
+void resetUnkList();
+void processUnkList(void);
+#endif
diff --git a/engines/module.mk b/engines/module.mk
index 3b16263df7..0f5a2f265b 100644
--- a/engines/module.mk
+++ b/engines/module.mk
@@ -66,3 +66,10 @@ DEFINES += -DDISABLE_LURE
else
MODULES += engines/lure
endif
+
+ifdef DISABLE_CINE
+DEFINES += -DDISABLE_CINE
+else
+MODULES += engines/cine
+endif
+
diff --git a/gui/credits.h b/gui/credits.h
index 1a4a69cf88..9e863ac431 100644
--- a/gui/credits.h
+++ b/gui/credits.h
@@ -37,6 +37,11 @@ static const char *credits[] = {
"\\C\\c0""Torbjorn Andersson",
"\\C\\c0""Jonathan Gray",
"\\C\\c0""",
+"\\C\\c1""Cinematique evo 1",
+"\\C\\c0""Pawel Kolodziejski",
+"\\C\\c0""Gregory Montoir",
+"\\C\\c0""Eugene Sandulenko",
+"\\C\\c0""",
"\\C\\c1""FOTAQ",
"\\C\\c0""David Eriksson",
"\\C\\c0""Gregory Montoir",
@@ -106,7 +111,7 @@ static const char *credits[] = {
"\\C\\c0""Jamieson Christian",
"\\C\\c2""iMUSE, MIDI, all things musical",
"\\C\\c0""Vincent Hamm",
-"\\C\\c2""Co-Founder",
+"\\C\\c2""Co-Founder, original CinE engine author",
"\\C\\c0""Ruediger Hanke",
"\\C\\c2""Port: MorphOS",
"\\C\\c0""Felix Jakschitsch",
diff --git a/tools/credits.pl b/tools/credits.pl
index ddab381008..6b8ccee56a 100755
--- a/tools/credits.pl
+++ b/tools/credits.pl
@@ -473,6 +473,12 @@ begin_credits("Credits");
add_person("Jonathan Gray", "khalek", "");
end_section();
+ begin_section("Cinematique evo 1");
+ add_person("Pawe&#322; Ko&#322;odziejski", "aquadran", "");
+ add_person("Gregory Montoir", "cyx", "");
+ add_person("Eugene Sandulenko", "sev", "");
+ end_section();
+
begin_section("FOTAQ"); # Flight of the Amazon Queen
add_person("David Eriksson", "twogood", "");
add_person("Gregory Montoir", "cyx", "");
@@ -549,10 +555,10 @@ begin_credits("Credits");
begin_section("Retired Team Members");
begin_persons();
- add_person("Tore Anderson", "tore", "Former Debian GNU/Linux maintainer");
+ add_person("Tore Anderson", "tore", "Former Debian GNU/Linux maintainer");
add_person("Ralph Brorsen", "painelf", "Help with GUI implementation");
add_person("Jamieson Christian", "jamieson630", "iMUSE, MIDI, all things musical");
- add_person('Vincent Hamm', 'yazoo', "Co-Founder");
+ add_person('Vincent Hamm', 'yazoo', "Co-Founder, original CinE engine author");
add_person("Ruediger Hanke", "", "Port: MorphOS");
add_person("Felix Jakschitsch", "yot", "Zak256 reverse engineering");
add_person("Mutwin Kraus", "mutle", "Original MacOS porter");