diff options
author | Eugene Sandulenko | 2006-02-22 22:40:53 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2006-02-22 22:40:53 +0000 |
commit | 71c170bb136ab94d70eb10d55cfd897dc89c9682 (patch) | |
tree | d555cf8177ba4f6fe3fbc0b0fd1d5d45df58874e | |
parent | a467247e6ed972e0a13bf26af07811dda55bd69a (diff) | |
download | scummvm-rg350-71c170bb136ab94d70eb10d55cfd897dc89c9682.tar.gz scummvm-rg350-71c170bb136ab94d70eb10d55cfd897dc89c9682.tar.bz2 scummvm-rg350-71c170bb136ab94d70eb10d55cfd897dc89c9682.zip |
Initial version of Cinematique engine evo 1.
svn-id: r20813
51 files changed, 13495 insertions, 5 deletions
@@ -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 @@ -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(¶m2); + + param3 = + *(s16 *) (currentScriptPtr + + currentPosition); + currentPosition += 2; + flipU16(¶m3); + + param4 = + *(s16 *) (currentScriptPtr + + currentPosition); + currentPosition += 2; + flipU16(¶m4); + + param5 = + *(s16 *) (currentScriptPtr + + currentPosition); + currentPosition += 2; + flipU16(¶m5); + + 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(¶m5); + flipU16(¶m6); + flipU16(¶m7); + + 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(¶m2); + + DEBUG_SCRIPT(currentLine, + "additionalBgVScroll = %d", + param2); + + additionalBgVScroll = param2; + } + + break; + } + case 0xA0: + { + u16 param1; + u16 param2; + + param1 = + *(s16 *) (currentScriptPtr + + currentPosition); + currentPosition += 2; + flipU16(¶m1); + + param2 = + *(s16 *) (currentScriptPtr + + currentPosition); + currentPosition += 2; + flipU16(¶m2); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m2); + flipU16(¶m3); + flipU16(¶m4); + flipU16(¶m5); + + 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(¶m2); + flipU16(¶m3); + flipU16(¶m4); + flipU16(¶m5); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + + 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(¶m3); + flipU16(¶m4); + flipU16(¶m5); + + 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(¶m2); + flipU16(¶m3); + flipU16(¶m4); + flipU16(¶m5); + + 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(¶m3); + + 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(¶m3); + + 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(¶m2); + + 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(¶m3); + flipU16(¶m5); + flipU16(¶m6); + + 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(¶m3); + flipU16(¶m5); + flipU16(¶m6); + + 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(¶m5); + flipU16(¶m6); + flipU16(¶m7); + + 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(¶m3); + + param4 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m4); + + 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(¶m1); + + param2 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m2); + + param3 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m3); + + param4 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m4); + + param5 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m5); + + param6 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m6); + + param7 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m7); + + param8 = *(s16 *) (localScriptPtr + position); + position += 2; + flipU16(¶m8); + + 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(¶m2); + + 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(¤tDisk, 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(¤tHead->objIdx); + flipU16(¤tHead->type); + flipU16((u16 *) & currentHead->x); + flipU16((u16 *) & currentHead->y); + flipU16((u16 *) & currentHead->var10); + flipU16((u16 *) & currentHead->var12); + + fHandle.write(currentHead, 0x14); + + flipU16(¤tHead->objIdx); + flipU16(¤tHead->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 .",¤tSaveName[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, + ¤tSelectedObject); + + 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ł Koł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"); |