[Scummvm-cvs-logs] SF.net SVN: scummvm: [31444] scummvm/trunk/engines/cine
sev at users.sourceforge.net
sev at users.sourceforge.net
Mon Apr 7 22:24:40 CEST 2008
Revision: 31444
http://scummvm.svn.sourceforge.net/scummvm/?rev=31444&view=rev
Author: sev
Date: 2008-04-07 13:24:40 -0700 (Mon, 07 Apr 2008)
Log Message:
-----------
Patch #1913862: "CinE Script system"
Modified Paths:
--------------
scummvm/trunk/engines/cine/anim.cpp
scummvm/trunk/engines/cine/anim.h
scummvm/trunk/engines/cine/bg.cpp
scummvm/trunk/engines/cine/bg.h
scummvm/trunk/engines/cine/bg_list.cpp
scummvm/trunk/engines/cine/bg_list.h
scummvm/trunk/engines/cine/cine.cpp
scummvm/trunk/engines/cine/gfx.cpp
scummvm/trunk/engines/cine/gfx.h
scummvm/trunk/engines/cine/main_loop.cpp
scummvm/trunk/engines/cine/object.cpp
scummvm/trunk/engines/cine/object.h
scummvm/trunk/engines/cine/part.cpp
scummvm/trunk/engines/cine/part.h
scummvm/trunk/engines/cine/prc.cpp
scummvm/trunk/engines/cine/prc.h
scummvm/trunk/engines/cine/rel.cpp
scummvm/trunk/engines/cine/rel.h
scummvm/trunk/engines/cine/script.cpp
scummvm/trunk/engines/cine/script.h
scummvm/trunk/engines/cine/sound.cpp
scummvm/trunk/engines/cine/texte.cpp
scummvm/trunk/engines/cine/various.cpp
Added Paths:
-----------
scummvm/trunk/engines/cine/xref.txt
Modified: scummvm/trunk/engines/cine/anim.cpp
===================================================================
--- scummvm/trunk/engines/cine/anim.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/anim.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -23,6 +23,9 @@
*
*/
+/*! \file
+ * \todo Make resource manager class and make load* functions its members
+ */
#include "common/endian.h"
#include "common/stream.h"
@@ -46,11 +49,9 @@
uint16 field_E;
};
-static uint16 animDataCount = 0;
+AnimData animDataTable[NUM_MAX_ANIMDATA];
-AnimHeaderStruct animHeader;
-
-static const AnimDataEntry animData[] = {
+static const AnimDataEntry transparencyData[] = {
{"ALPHA", 0xF},
{"TITRE2", 0xF},
{"ET", 0xC},
@@ -184,135 +185,250 @@
{"FIN", 0x9},
};
-static void freeAnimData(byte idx) {
- assert(idx < NUM_MAX_ANIMDATA);
- if (animDataTable[idx].ptr1) {
- free(animDataTable[idx].ptr1);
- free(animDataTable[idx].ptr2);
- memset(&animDataTable[idx], 0, sizeof(AnimData));
- animDataTable[idx].fileIdx = -1;
- animDataTable[idx].frameIdx = -1;
- if (animDataCount > 0)
- animDataCount--;
- }
-}
+void convertMask(byte *dest, const byte *source, int16 width, int16 height);
+void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency);
+void convert8BBP(byte *dest, const byte *source, int16 width, int16 height);
+void convert8BBP2(byte *dest, byte *source, int16 width, int16 height);
-void freeAnimDataRange(byte startIdx, byte numIdx) {
- for (byte i = 0; i < numIdx; i++) {
- freeAnimData(i + startIdx);
- }
-}
+AnimData::AnimData() : _width(0), _height(0), _bpp(0), _var1(0), _data(NULL),
+ _mask(NULL), _fileIdx(-1), _frameIdx(-1), _realWidth(0), _size(0) {
-void freeAnimDataTable() {
- freeAnimDataRange(0, NUM_MAX_ANIMDATA);
+ memset(_name, 0, 10);
}
-static byte getAnimTransparentColor(const char *animName) {
- char name[15];
+/*! \brief Copy constructor
+ */
+AnimData::AnimData(const AnimData &src) : _width(src._width),
+ _height(src._height), _bpp(src._bpp), _var1(src._var1),
+ _data(NULL), _mask(NULL), _fileIdx(src._fileIdx),
+ _frameIdx(src._frameIdx), _realWidth(src._realWidth), _size(src._size) {
- removeExtention(name, animName);
+ if (src._data) {
+ _data = new byte[_size];
+ assert(_data);
+ memcpy(_data, src._data, _size*sizeof(byte));
+ }
- for (int i = 0; i < ARRAYSIZE(animData); i++) {
- if (!strcmp(name, animData[i].name)) {
- return animData[i].color;
- }
+ if(src._mask) {
+ _mask = new byte[_size];
+ assert(_mask);
+ memcpy(_mask, src._mask, _size*sizeof(byte));
}
- return 0;
+
+ memset(_name, 0, 10);
+ strcpy(_name, src._name);
}
-int16 allocFrame(uint16 width, uint16 height, int8 isMask) {
- uint16 i;
- uint32 frameSize;
+/*! \brief Destructor
+ */
+AnimData::~AnimData() {
+ clear();
+}
- for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
- if (!animDataTable[i].ptr1)
- break;
- }
+/*! \brief Assingment operator
+ */
+AnimData &AnimData::operator=(const AnimData &src) {
+ AnimData tmp = src;
+ byte *ptr;
- if (i == NUM_MAX_ANIMDATA)
- return -1;
+ _width = tmp._width;
+ _height = tmp._height;
+ _bpp = tmp._bpp;
+ _var1 = tmp._var1;
- if (!isMask) { // sprite + generated mask
- frameSize = width * height;
+ ptr = _data;
+ _data = tmp._data;
+ tmp._data = ptr;
- animDataTable[i].ptr1 = (byte *)malloc(frameSize);
- animDataTable[i].ptr2 = (byte *)malloc(frameSize);
- } else {
- // mask
- frameSize = width * height * 8;
+ ptr = _mask;
+ _mask = tmp._mask;
+ tmp._mask = ptr;
- animDataTable[i].ptr1 = (byte *)malloc(frameSize);
- animDataTable[i].ptr2 = NULL;
- }
+ _fileIdx = tmp._fileIdx;
+ _frameIdx = tmp._frameIdx;
+ memset(_name, 0, 10);
+ strcpy(_name, tmp._name);
+ _realWidth = tmp._realWidth;
+ _size = tmp._size;
- animDataTable[i].width = width;
- animDataTable[i].var1 = width >> 3;
- animDataTable[i].bpp = 4;
- animDataTable[i].height = height;
+ return *this;
+}
- animDataTable[i].fileIdx = -1;
- animDataTable[i].frameIdx = -1;
+byte AnimData::getColor(int x, int y) {
+ assert(_data);
+ assert(x >= 0 && x < _realWidth && y >= 0 && y <= _height);
+ assert(x + y * _realWidth < _size);
- animDataCount++;
-
- return i;
+ return _data[x + y * _realWidth];
}
-int16 reserveFrame(uint16 width, uint16 height, uint16 type, int16 idx) {
- uint16 i;
- uint32 frameSize;
+/*! \brief Load and decode image frame
+ * \param d Encoded image data
+ * \param type Encoding type
+ * \param w Image width
+ * \param h Image height
+ * \param file Data file index in bundle
+ * \param frame Image frame index
+ * \param n Part name
+ * \param transparent Transparent color (for ANIM_MASKSPRITE)
+ */
+void AnimData::load(byte *d, int type, uint16 w, uint16 h, int16 file,
+ int16 frame, const char *n, byte transparent) {
- if (idx >= 0) {
- i = (uint16) idx;
- } else {
- for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
- if (!animDataTable[i].ptr1)
- break;
- }
+ assert(d);
- if (i == NUM_MAX_ANIMDATA)
- return -1;
+ if (_data) {
+ clear();
}
- frameSize = width * height;
+ _width = w * 2;
+ _height = h;
+ _var1 = _width >> 3;
+ _data = NULL;
+ _mask = NULL;
+ _fileIdx = file;
+ _frameIdx = frame;
+ memset(_name, 0, 10);
+ strcpy(_name, n);
+ _realWidth = w;
- if (type == 4) { // 256 color sprites
- frameSize *= 2;
- type = 8;
- width *= 2;
- }
+ switch (type) {
+ case ANIM_RAW:
+ _width = w;
+ _var1 = w >> 3;
+ _bpp = 4;
+ _size = w * h;
+ _data = new byte[_size];
+ assert(_data);
+ memcpy(_data, d, _size*sizeof(byte));
+ break;
- if (type == 5) {
- frameSize += 16;
- }
+ case ANIM_MASK:
+ _bpp = 1;
+ _size = w * h * 8;
+ _data = new byte[_size];
+ _realWidth = w * 8;
+ assert(_data);
+ convertMask(_data, d, w, h);
+ break;
- frameSize *= 2;
+ case ANIM_SPRITE:
+ _bpp = 4;
+ _size = w * h * 2;
+ _data = new byte[_size];
+ _realWidth = w * 2;
+ assert(_data);
+ gfxConvertSpriteToRaw(_data, d, w, h);
+ break;
- animDataTable[i].ptr1 = (byte *)malloc(frameSize);
+ case ANIM_MASKSPRITE:
+ _bpp = 4;
+ _size = w * h * 2;
+ _data = new byte[_size];
+ _mask = new byte[_size];
+ _realWidth = w * 2;
+ assert(_data && _mask);
+ gfxConvertSpriteToRaw(_data, d, w, h);
+ generateMask(_data, _mask, _size, transparent);
+ break;
- assert(animDataTable[i].ptr1);
+ case ANIM_PALSPRITE:
+ _bpp = 5;
+ _size = w * h * 2;
+ _data = new byte[_size];
+ _realWidth = w * 2;
+ assert(_data);
+ convert8BBP(_data, d, w, h);
+ break;
- animDataTable[i].width = width;
+ case ANIM_FULLSPRITE:
+ _bpp = 8;
+ _var1 = _width >> 4;
+ _size = w * h;
+ _data = new byte[_size];
+ assert(_data);
+ convert8BBP2(_data, d, w, h);
+ break;
- if (type == 5) {
- animDataTable[i].var1 = width / 8;
- } else {
- animDataTable[i].var1 = width / 16;
+ default:
+ error("AnimData::load: unknown image type");
}
+}
- animDataTable[i].bpp = type;
+/*! \brief Reset image
+ */
+void AnimData::clear() {
+ delete[] _data;
+ delete [] _mask;
- animDataTable[i].height = height;
+ _width = 0;
+ _height = 0;
+ _bpp = 0;
+ _var1 = 0;
+ _data = NULL;
+ _mask = NULL;
+ _fileIdx = -1;
+ _frameIdx = -1;
+ memset(_name, 0, 10);
+ _size = 0;
+}
- animDataTable[i].fileIdx = -1;
- animDataTable[i].frameIdx = -1;
+/*! \brief Write image identifiers to savefile
+ * \param fHandle Savefile open for writing
+ */
+void AnimData::save(Common::OutSaveFile &fHandle) const {
+ fHandle.writeUint16BE(_width);
+ fHandle.writeUint16BE(_var1);
+ fHandle.writeUint16BE(_bpp);
+ fHandle.writeUint16BE(_height);
+ // Just because I write pointers to a file doesn't mean
+ // anyone should actually read those values back!
+ fHandle.writeUint32BE((uint32)_data);
+ fHandle.writeUint32BE((uint32)_mask);
+ fHandle.writeUint16BE(_fileIdx);
+ fHandle.writeUint16BE(_frameIdx);
+ fHandle.write(_name, 10);
+}
- animDataCount++;
+/*! \brief Clear part of animDataTable
+ * \param startIdx First image frame to be cleared
+ * \param numIdx Number of image frames to be cleared
+ */
+void freeAnimDataRange(byte startIdx, byte numIdx) {
+ for (byte i = 0; i < numIdx; i++) {
+ animDataTable[startIdx + i].clear();
+ }
+}
- return i;
+/*! \brief Clear whole animDataTable
+ */
+void freeAnimDataTable() {
+ freeAnimDataRange(0, NUM_MAX_ANIMDATA);
}
-void generateMask(byte * sprite, byte * mask, uint16 size, byte transparency) {
+/*! \brief Find transparent color index for image
+ * \brief animName Image file name
+ */
+static byte getAnimTransparentColor(const char *animName) {
+ char name[15];
+
+ removeExtention(name, animName);
+
+ for (int i = 0; i < ARRAYSIZE(transparencyData); i++) {
+ if (!strcmp(name, transparencyData[i].name)) {
+ return transparencyData[i].color;
+ }
+ }
+ return 0;
+}
+
+/*! \brief Generate mask for image
+ * \param[in] sprite Image data
+ * \param[out] mask Image mask
+ * \param size Image data length
+ * \param transparency Transparent color index
+ */
+void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency) {
for (uint16 i = 0; i < size; i++) {
if (*(sprite++) != transparency) {
*(mask++) = 0;
@@ -322,7 +438,13 @@
}
}
-void convertMask(byte * dest, byte * source, int16 width, int16 height) {
+/*! \brief Decode 1bpp mask
+ * \param[out] dest Decoded mask
+ * \param[in] source Encoded mask
+ * \param width Mask width
+ * \param height Mask height
+ */
+void convertMask(byte *dest, const byte *source, int16 width, int16 height) {
int16 i, j;
byte maskEntry;
@@ -335,7 +457,13 @@
}
}
-void convert4BBP(byte * dest, byte * source, int16 width, int16 height) {
+/*! \brief Decode 4bpp sprite
+ * \param[out] dest Decoded image
+ * \param[in] source Encoded image
+ * \param width Image width
+ * \param height Image height
+ */
+void convert4BBP(byte *dest, const byte *source, int16 width, int16 height) {
byte maskEntry;
for (int16 i = 0; i < width * height; i++) {
@@ -345,7 +473,11 @@
}
}
-void loadAnimHeader(Common::MemoryReadStream readS) {
+/*! \brief Read image header
+ * \param[out] animHeader Image header reference
+ * \param readS Input stream open for reading
+ */
+void loadAnimHeader(AnimHeaderStruct &animHeader, Common::MemoryReadStream readS) {
animHeader.field_0 = readS.readByte();
animHeader.field_1 = readS.readByte();
animHeader.field_2 = readS.readByte();
@@ -366,115 +498,109 @@
animHeader.field_14 = readS.readUint16BE();
}
+/*! \brief Find next empty space animDataTable
+ * \param start First index to check
+ */
+int emptyAnimSpace(int start = 0) {
+ for (; start < NUM_MAX_ANIMDATA; start++) {
+ if (!animDataTable[start].data()) {
+ return start;
+ }
+ }
+
+ return -1;
+}
+
+/*! \brief Load SPL data into animDataTable
+ * \param resourceName SPL filename
+ * \param idx Target index in animDataTable
+ */
void loadSpl(const char *resourceName, int16 idx) {
int16 foundFileIdx = findFileInBundle(resourceName);
- int16 entry;
+ int entry;
+
+ if (foundFileIdx < 0) {
+ return;
+ }
+
byte *dataPtr = readBundleFile(foundFileIdx);
- if (idx >= 0) {
- entry = reserveFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0, idx);
- memcpy(animDataTable[entry].ptr1, dataPtr, partBuffer[foundFileIdx].unpackedSize);
- } else {
- entry = allocFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, -1);
- assert(entry != -1);
- memcpy(animDataTable[entry].ptr1, dataPtr, (uint16) partBuffer[foundFileIdx].unpackedSize);
+ entry = idx < 0 ? emptyAnimSpace() : idx;
+ assert(entry >= 0);
+ animDataTable[entry].load(dataPtr, ANIM_RAW, partBuffer[foundFileIdx].unpackedSize, 1, foundFileIdx, 0, currentPartName);
- animDataTable[entry].fileIdx = foundFileIdx;
- animDataTable[entry].frameIdx = 0;
- strcpy(animDataTable[entry].name, currentPartName);
- }
-
free(dataPtr);
}
+/*! \brief Load 1bpp mask
+ * \param resourceName Mask filename
+ */
void loadMsk(const char *resourceName) {
int16 foundFileIdx = findFileInBundle(resourceName);
- int16 entry;
+ int entry = 0;
byte *dataPtr = readBundleFile(foundFileIdx);
byte *ptr;
+ AnimHeaderStruct animHeader;
Common::MemoryReadStream readS(dataPtr, 0x16);
- loadAnimHeader(readS);
+ loadAnimHeader(animHeader, readS);
ptr = dataPtr + 0x16;
- for (int16 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);
+ for (int16 i = 0; i < animHeader.numFrames; i++, entry++) {
+ entry = emptyAnimSpace(entry);
+ assert(entry >= 0);
+ animDataTable[entry].load(ptr, ANIM_MASK, animHeader.frameWidth, animHeader.frameHeight, foundFileIdx, i, currentPartName);
ptr += animHeader.frameWidth * animHeader.frameHeight;
-
- animDataTable[entry].fileIdx = foundFileIdx;
- animDataTable[entry].frameIdx = i;
- strcpy(animDataTable[entry].name, currentPartName);
}
free(dataPtr);
}
+/*! \brief Load animation
+ * \param resourceName Animation filename
+ */
void loadAni(const char *resourceName) {
int16 foundFileIdx = findFileInBundle(resourceName);
- int16 entry;
+ int entry = 0;
byte *dataPtr = readBundleFile(foundFileIdx);
- byte *ptr, *animPtr;
+ byte *ptr;
byte transparentColor;
- uint32 fullSize;
+ AnimHeaderStruct animHeader;
Common::MemoryReadStream readS(dataPtr, 0x16);
- loadAnimHeader(readS);
+ loadAnimHeader(animHeader, readS);
ptr = dataPtr + 0x16;
transparentColor = getAnimTransparentColor(resourceName);
- fullSize = animHeader.frameWidth * animHeader.frameHeight;
+ for (int16 i = 0; i < animHeader.numFrames; i++, entry++) {
+ entry = emptyAnimSpace(entry);
+ assert(entry >= 0);
- for (int16 i = 0; i < animHeader.numFrames; i++) {
- 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;
- }
+ transparentColor = i < 2 ? 0 : 7;
+ } else if (!strcmp(resourceName, "L4601.ANI")) {
+ transparentColor = i < 1 ? 0xE : 0;
}
- if (!strcmp(resourceName, "L4601.ANI")) {
- if (i < 1) {
- transparentColor = 0xE;
- } else {
- transparentColor = 0;
- }
- }
-
- animPtr = (byte *)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);
+ animDataTable[entry].load(ptr, ANIM_MASKSPRITE, animHeader.frameWidth, animHeader.frameHeight, foundFileIdx, i, currentPartName, transparentColor);
+ ptr += animHeader.frameWidth * animHeader.frameHeight;
}
free(dataPtr);
}
-void convert8BBP(byte * dest, byte * source, int16 width, int16 height) {
- byte table[16];
+/*! \brief Decode 16 color image with palette
+ * \param[out] dest Decoded image
+ * \param[in] source Encoded image
+ * \param width Image width
+ * \param height Image height
+ */
+void convert8BBP(byte *dest, const byte *source, int16 width, int16 height) {
+ const byte *table = source;
byte color;
- memcpy(table, source, 16);
source += 16;
for (uint16 i = 0; i < width * height; i++) {
@@ -485,16 +611,24 @@
}
}
-void convert8BBP2(byte * dest, byte * source, int16 width, int16 height) {
- uint16 i, j, k, m;
+/*! \brief Decode 8bit image
+ * \param[out] dest Decoded image
+ * \param[in] source Encoded image
+ * \param width Image width
+ * \param height Image height
+ * \attention Data in source are destroyed during decoding
+ */
+void convert8BBP2(byte *dest, byte *source, int16 width, int16 height) {
+ uint16 i, j;
+ int k, m;
byte color;
for (j = 0; j < (width * height) / 16; j++) {
// m = 0: even bits, m = 1: odd bits
- for (m = 0; m < 2; m++) {
+ for (m = 0; m <= 1; m++) {
for (i = 0; i < 8; i++) {
color = 0;
- for (k = 14 + m; k >= 0 + m; k = k - 2) {
+ for (k = 14 + m; k >= 0; k -= 2) {
color |= ((*(source + k) & 0x080) >> 7);
*(source + k) <<= 1;
if (k > 0 + m)
@@ -508,14 +642,17 @@
} // end j
}
+/*! \brief Load image set
+ * \param resourceName Image set filename
+ * \param idx Target index in animDataTable
+ */
void loadSet(const char *resourceName, int16 idx) {
AnimHeader2Struct header2;
- uint32 fullSize;
uint16 numSpriteInAnim;
int16 foundFileIdx = findFileInBundle(resourceName);
- int16 entry, typeParam;
+ int16 entry = idx >= 0 ? idx : 0;
byte *ptr, *startOfDataPtr, *dataPtr, *origDataPtr;
- byte table[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ int type;
origDataPtr = dataPtr = readBundleFile(foundFileIdx);
assert(!memcmp(dataPtr, "SET", 3));
@@ -526,9 +663,7 @@
startOfDataPtr = ptr + numSpriteInAnim * 0x10;
- for (int16 i = 0; i < numSpriteInAnim; i++) {
- typeParam = 0;
-
+ for (int16 i = 0; i < numSpriteInAnim; i++, entry++) {
Common::MemoryReadStream readS(ptr, 0x10);
header2.field_0 = readS.readUint32BE();
@@ -541,56 +676,37 @@
ptr += 0x10;
- fullSize = header2.width * header2.height;
+ entry = idx < 0 ? emptyAnimSpace(entry) : idx + i;
+ assert(entry >= 0);
- if (header2.type == 5) {
- fullSize += 16;
- }
-
- if (header2.type == 4) {
- header2.type = 5;
- typeParam = 1;
- }
-
- if (idx >= 0)
- entry = reserveFrame(header2.width * 2, header2.height, header2.type, idx + i);
- else
- entry = reserveFrame(header2.width * 2, header2.height, header2.type, -1);
-
- 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);
+ if (header2.type == 1) {
+ type = ANIM_MASK;
+ } else if (header2.type == 4) {
+ type = ANIM_SPRITE;
+ } else if (header2.type == 5) {
+ type = ANIM_PALSPRITE;
} 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) {
- error("loadSet: header2.type == 4");
- } else {
- convert8BBP2(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
- }
+ type = ANIM_FULLSPRITE;
}
- animDataTable[entry].fileIdx = foundFileIdx;
- animDataTable[entry].frameIdx = i;
- strcpy(animDataTable[entry].name, currentPartName);
+ animDataTable[entry].load(dataPtr, type, header2.width, header2.height, foundFileIdx, i, currentPartName);
}
free(origDataPtr);
}
+/*! \brief Load SEQ data into animDataTable
+ * \param resourceName SEQ data filename
+ * \param idx Target index in animDataTable
+ */
void loadSeq(const char *resourceName, int16 idx) {
int16 foundFileIdx = findFileInBundle(resourceName);
byte *dataPtr = readBundleFile(foundFileIdx);
- int16 entry = reserveFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0, idx);
+ int entry = idx < 0 ? emptyAnimSpace() : idx;
- memcpy(animDataTable[entry].ptr1, dataPtr + 0x16, (uint16) partBuffer[foundFileIdx].unpackedSize - 0x16);
+ animDataTable[entry].load(dataPtr+0x16, ANIM_RAW, partBuffer[foundFileIdx].unpackedSize-0x16, 1, foundFileIdx, 0, currentPartName);
free(dataPtr);
}
@@ -624,6 +740,8 @@
error("loadResource: Cannot determine type for '%s'", resourceName);
}
+/*! \todo There seems to be some additional resource file that is not loaded
+ */
void loadAbs(const char *resourceName, uint16 idx) {
/* byte isMask = 0; */
/* byte isSpl = 0; */
@@ -632,6 +750,7 @@
loadSet(resourceName, idx);
return;
} else if (strstr(resourceName, ".H32")) {
+ warning("Ignoring file %s (load at %d)", resourceName, idx);
return;
} else if (strstr(resourceName, ".SEQ")) {
loadSeq(resourceName, idx);
@@ -640,116 +759,108 @@
loadSpl(resourceName, idx);
return;
} else if (strstr(resourceName, ".AMI")) {
+ warning("Ignoring file %s (load at %d)", resourceName, idx);
return;
} else if (strstr(resourceName, ".ANI")) {
+ warning("Ignoring file %s (load at %d)", resourceName, idx);
return;
}
error("loadAbs: Cannot determine type for '%s'", resourceName);
}
-void loadResourcesFromSave() {
- int16 currentAnim, foundFileIdx, fullSize, entry, i;
+/*! \brief Load animDataTable from save
+ * \param fHandle Savefile open for reading
+ * \param broken Broken/correct file format switch
+ * \todo Add Operation Stealth savefile support
+ *
+ * Unlike the old code, this one actually rebuilds the table one frame
+ * at a time.
+ */
+void loadResourcesFromSave(Common::InSaveFile &fHandle, bool broken) {
+ int16 currentAnim, foundFileIdx;
int8 isMask = 0, isSpl = 0;
- byte *dataPtr, *ptr, *animPtr;
- char animName[256], part[256];
+ byte *dataPtr, *ptr;
+ char *animName, part[256];
byte transparentColor;
AnimData *currentPtr;
+ AnimHeaderStruct animHeader;
+ uint16 width, height, bpp, var1;
+ int16 frame;
+ char name[10];
+ int type;
+
strcpy(part, currentPartName);
for (currentAnim = 0; currentAnim < NUM_MAX_ANIMDATA; currentAnim++) {
currentPtr = &animDataTable[currentAnim];
- if (currentPtr->refresh && currentPtr->fileIdx != -1) {
- if (strcmp(currentPartName, currentPtr->name)) {
- closePart();
- loadPart(currentPtr->name);
- }
- foundFileIdx = currentPtr->fileIdx;
+ width = fHandle.readUint16BE();
+ var1 = fHandle.readUint16BE();
+ bpp = fHandle.readUint16BE();
+ height = fHandle.readUint16BE();
- strcpy(animName, partBuffer[foundFileIdx].partName);
- ptr = dataPtr = readBundleFile(foundFileIdx);
-
- isSpl = (strstr(animName, ".SPL")) ? 1 : 0;
- isMask = (strstr(animName, ".MSK")) ? 1 : 0;
-
- if (isSpl) {
- animHeader.frameWidth = (uint16) partBuffer[foundFileIdx].unpackedSize;
- animHeader.frameHeight = 1;
- animHeader.numFrames = 1;
- isMask = -1;
- } else {
- Common::MemoryReadStream readS(ptr, 0x22);
-
- loadAnimHeader(readS);
-
- ptr += 0x16;
+ if (!broken) {
+ if (!fHandle.readUint32BE()) {
+ fHandle.skip(18);
+ continue;
}
+ fHandle.readUint32BE();
+ }
- {
- fullSize = animHeader.frameWidth * animHeader.frameHeight;
+ foundFileIdx = fHandle.readSint16BE();
+ frame = fHandle.readSint16BE();
+ fHandle.read(name, 10);
- loadRelatedPalette(animName);
+ if (foundFileIdx < 0 || (broken && !fHandle.readByte())) {
+ continue;
+ }
- transparentColor = getAnimTransparentColor(animName);
+ if (strcmp(currentPartName, name)) {
+ closePart();
+ loadPart(name);
+ }
- for (i = 0; i < animHeader.numFrames; i++) { // load all the frames
- // special case transparency handling
- if (!strcmp(animName, "L2202.ANI")) {
- if (i < 2) {
- transparentColor = 0;
- } else {
- transparentColor = 7;
- }
- }
+ animName = partBuffer[foundFileIdx].partName;
+ ptr = dataPtr = readBundleFile(foundFileIdx);
- if (!strcmp(animName, "L4601.ANI")) {
- if (i < 1) {
- transparentColor = 0xE;
- } else {
- transparentColor = 0;
- }
- }
+ isSpl = (strstr(animName, ".SPL")) ? 1 : 0;
+ isMask = (strstr(animName, ".MSK")) ? 1 : 0;
- currentPtr[i].ptr1 = NULL;
- entry = allocFrame(animHeader.frameWidth * 2, animHeader.frameHeight, isMask);
+ if (isSpl) {
+ width = (uint16) partBuffer[foundFileIdx].unpackedSize;
+ height = 1;
+ frame = 0;
+ type = ANIM_RAW;
+ } else {
+ Common::MemoryReadStream readS(ptr, 0x16);
+ loadAnimHeader(animHeader, readS);
+ ptr += 0x16;
- currentPtr->fileIdx = foundFileIdx;
+ width = animHeader.frameWidth;
+ height = animHeader.frameHeight;
- assert(entry != -1);
+ if (isMask) {
+ type = ANIM_MASK;
+ } else {
+ type = ANIM_MASKSPRITE;
- if (isSpl) {
- memcpy(animDataTable[entry].ptr1, ptr, fullSize);
- ptr += fullSize;
- } else {
- if (!isMask) {
- animPtr = (byte *)malloc(fullSize);
- memcpy(animPtr, ptr, fullSize);
- ptr += fullSize;
+ loadRelatedPalette(animName);
+ transparentColor = getAnimTransparentColor(animName);
- 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);
+ // special case transparency handling
+ if (!strcmp(animName, "L2202.ANI")) {
+ transparentColor = (frame < 2) ? 0 : 7;
+ } else if (!strcmp(animName, "L4601.ANI")) {
+ transparentColor = (frame < 1) ? 0xE : 0;
}
}
+ }
- free(dataPtr);
- }
+ ptr += frame * width * height;
+ currentPtr->load(ptr, type, width, height, foundFileIdx, frame, name, transparentColor);
+ free(dataPtr);
}
loadPart(part);
Modified: scummvm/trunk/engines/cine/anim.h
===================================================================
--- scummvm/trunk/engines/cine/anim.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/anim.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -54,11 +54,54 @@
byte color;
};
+#define ANIM_RAW 0 // memcpy
+#define ANIM_MASK 1 // convertMask
+#define ANIM_SPRITE 2 // gfxConvertSpriteToRaw
+#define ANIM_MASKSPRITE 3 // gfxConvertSpriteToRaw + generateMask
+#define ANIM_PALSPRITE 5 // convert8BBP
+#define ANIM_FULLSPRITE 8 // convert8BBP2
+
+class AnimData {
+private:
+ byte *_data; ///< Image data
+ byte *_mask; ///< Image mask (may be NULL)
+ int16 _fileIdx; ///< Source file index in bundle
+ int16 _frameIdx; ///< Frame number in animation
+ char _name[10]; ///< Part filename
+ int _size; ///< _data/_mask size, internal only
+
+public:
+ uint16 _width; ///< Image width (ussually twice the real size)
+ uint16 _height; ///< Image height
+ uint16 _bpp; ///< Bit depth/type information
+ uint16 _var1; ///< Something related to width
+ int _realWidth; ///< Real image width in bytes
+
+ AnimData();
+ AnimData(const AnimData &src);
+ ~AnimData();
+
+ AnimData &operator=(const AnimData &src);
+
+ const byte *data() const { return _data; } ///< Image data
+ const byte *mask() const { return _mask; } ///< Image mask (may be NULL)
+ byte getColor(int x, int y);
+
+ void load(byte *d, int type, uint16 w, uint16 h, int16 file, int16 frame, const char *n, byte transparent = 0);
+ void clear();
+
+ void save(Common::OutSaveFile &fHandle) const;
+};
+
+#define NUM_MAX_ANIMDATA 255
+
+extern AnimData animDataTable[NUM_MAX_ANIMDATA];
+
void freeAnimDataTable(void);
void freeAnimDataRange(byte startIdx, byte numIdx);
void loadResource(const char *animName);
void loadAbs(const char *resourceName, uint16 idx);
-void loadResourcesFromSave();
+void loadResourcesFromSave(Common::InSaveFile &fHandle, bool broken);
} // End of namespace Cine
Modified: scummvm/trunk/engines/cine/bg.cpp
===================================================================
--- scummvm/trunk/engines/cine/bg.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/bg.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -29,6 +29,7 @@
#include "cine/cine.h"
#include "cine/various.h"
+#include "cine/bg.h"
namespace Cine {
@@ -36,10 +37,6 @@
byte *additionalBgTable[9];
byte currentAdditionalBgIdx = 0, currentAdditionalBgIdx2 = 0;
-void loadCtHigh(byte * currentPtr) {
- memcpy(page3Raw, currentPtr, 320 * 200);
-}
-
byte loadCt(const char *ctName) {
uint16 header[32];
byte *ptr, *dataPtr;
@@ -52,10 +49,17 @@
if (g_cine->getGameType() == Cine::GType_OS) {
uint16 bpp = READ_BE_UINT16(ptr); ptr += 2;
if (bpp == 8) {
+ ctColorMode = 1;
+ memcpy(newPalette, ptr, 256*3);
ptr += 3 * 256;
- loadCtHigh(ptr);
+ memcpy(page3Raw, ptr, 320 * 200);
} else {
- ptr += 32;
+ ctColorMode = 0;
+ for (int i = 0; i < 16; i++) {
+ tempPalette[i] = READ_BE_UINT16(ptr);
+ ptr += 2;
+ }
+
gfxResetRawPage(page3Raw);
gfxConvertSpriteToRaw(page3Raw, ptr, 160, 200);
}
@@ -78,12 +82,14 @@
}
void loadBgHigh(const char *currentPtr) {
- memcpy(palette256, currentPtr, 256 * 3);
+ memcpy(newPalette, currentPtr, 256 * 3);
currentPtr += 256 * 3;
memcpy(page2Raw, currentPtr, 320 * 200);
- colorMode256 = 1;
+ newColorMode = 2;
+ bgColorMode = 1;
+
}
byte loadBg(const char *bgName) {
@@ -99,7 +105,8 @@
if (bpp == 8) {
loadBgHigh((const char *)ptr);
} else {
- colorMode256 = 0;
+ newColorMode = 1;
+ bgColorMode = 0;
for (int i = 0; i < 16; i++) {
tempPalette[i] = READ_BE_UINT16(ptr);
@@ -127,12 +134,22 @@
additionalBgTable[bgIdx] = (byte *) malloc(320 * 200);
+ debug("addBackground %d", bgIdx);
+
uint16 bpp = READ_BE_UINT16(ptr); ptr += 2;
+
if (bpp == 8) {
+ bgColorMode = 1;
+ memcpy(newPalette, ptr, 256*3);
ptr += 3 * 256;
memcpy(additionalBgTable[bgIdx], ptr, 320 * 200);
} else {
- ptr += 32;
+ bgColorMode = 0;
+ for (int i = 0; i < 16; i++) {
+ tempPalette[i] = READ_BE_UINT16(ptr);
+ ptr += 2;
+ }
+
gfxConvertSpriteToRaw(additionalBgTable[bgIdx], ptr, 160, 200);
}
free(dataPtr);
Modified: scummvm/trunk/engines/cine/bg.h
===================================================================
--- scummvm/trunk/engines/cine/bg.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/bg.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -27,10 +27,17 @@
#define CINE_BG_H
namespace Cine {
+struct bgData {
+ byte *data;
+ byte colorMode;
+ byte *highPalette;
+ uint16 *lowPalette;
+};
byte loadBg(const char *bgName);
byte loadCt(const char *bgName);
+//extern bgData additionalBgTable[9];
extern byte *additionalBgTable[9];
extern byte currentAdditionalBgIdx;
extern byte currentAdditionalBgIdx2;
Modified: scummvm/trunk/engines/cine/bg_list.cpp
===================================================================
--- scummvm/trunk/engines/cine/bg_list.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/bg_list.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -36,129 +36,116 @@
namespace Cine {
uint32 var8;
-BGIncrustList *bgIncrustList;
+Common::List<BGIncrust> bgIncrustList;
+/*! \brief Add masked sprite to the background
+ * \param objIdx Sprite description
+ * \param addList Add sprite to incrust list if true
+ * \todo Fix incrust objects on CT background. Always drawing incrust elements
+ * on CT background breaks game zones
+ */
void addToBGList(int16 objIdx, bool addList) {
int16 x = objectTable[objIdx].x;
int16 y = objectTable[objIdx].y;
- int16 width = animDataTable[objectTable[objIdx].frame].var1;
- int16 height = animDataTable[objectTable[objIdx].frame].height;
+ int16 width = animDataTable[objectTable[objIdx].frame]._var1;
+ int16 height = animDataTable[objectTable[objIdx].frame]._height;
+ const byte *data = animDataTable[objectTable[objIdx].frame].data();
+ const byte *mask = animDataTable[objectTable[objIdx].frame].mask();
// int16 part = objectTable[objIdx].part;
+ // Operation Stealth may switch among multiple backgrounds
if (g_cine->getGameType() == GType_OS) {
- drawSpriteRaw2(animDataTable[objectTable[objIdx].frame].ptr1, objectTable[objIdx].part, width, height, page2Raw, x, y);
+ for (int i = 0; i < 8; i++) {
+ if (additionalBgTable[i]) {
+ drawSpriteRaw2(data, objectTable[objIdx].part, width, height, additionalBgTable[i], x, y);
+ }
+ }
} else {
- drawSpriteRaw(animDataTable[objectTable[objIdx].frame].ptr1, animDataTable[objectTable[objIdx].frame].ptr2, width, height, page2Raw, x, y);
+ drawSpriteRaw(data, mask, width, height, page2Raw, x, y);
}
if (addList)
createBgIncrustListElement(objIdx, 0);
}
+/*! \brief Add filled sprite to the background
+ * \param objIdx Sprite description
+ * \param addList Add sprite to incrust list if true
+ * \todo Fix incrust objects on CT background. Always drawing incrust elements
+ * on CT background breaks game zones
+ */
void addSpriteFilledToBGList(int16 objIdx, bool addList) {
int16 x = objectTable[objIdx].x;
int16 y = objectTable[objIdx].y;
- int16 width = animDataTable[objectTable[objIdx].frame].width;
- int16 height = animDataTable[objectTable[objIdx].frame].height;
+ int16 width = animDataTable[objectTable[objIdx].frame]._width;
+ int16 height = animDataTable[objectTable[objIdx].frame]._height;
+ const byte *data = animDataTable[objectTable[objIdx].frame].data();
- if (animDataTable[objectTable[objIdx].frame].ptr1) {
- gfxFillSprite(animDataTable[objectTable[objIdx].frame].ptr1, width / 2, height, page2Raw, x, y);
+ if (data) {
+ // Operation Stealth may switch among multiple backgrounds
+ if (g_cine->getGameType() == GType_OS) {
+ for (int i = 0; i < 8; i++) {
+ if (additionalBgTable[i]) {
+ gfxFillSprite(data, width / 2, height, additionalBgTable[i], x, y);
+ }
+ }
+ } else {
+ gfxFillSprite(data, width / 2, height, page2Raw, x, y);
+ }
}
if (addList)
createBgIncrustListElement(objIdx, 1);
}
+/*! \brief Add new element to incrust list
+ * \param objIdx Element description
+ * \param param Type of element
+ */
void createBgIncrustListElement(int16 objIdx, int16 param) {
- BGIncrustList *bgIncrustPtr = bgIncrustList;
- BGIncrustList *bgIncrustPtrP = 0;
+ BGIncrust tmp;
- // Find first empty element
- while (bgIncrustPtr) {
- bgIncrustPtrP = bgIncrustPtr;
- bgIncrustPtr = bgIncrustPtr->next;
- }
+ tmp.objIdx = objIdx;
+ tmp.param = param;
+ tmp.x = objectTable[objIdx].x;
+ tmp.y = objectTable[objIdx].y;
+ tmp.frame = objectTable[objIdx].frame;
+ tmp.part = objectTable[objIdx].part;
- bgIncrustPtr = new BGIncrustList;
- if (bgIncrustPtrP)
- bgIncrustPtrP->next = bgIncrustPtr;
- else
- bgIncrustList = bgIncrustPtr;
-
- bgIncrustPtr->next = 0;
-
- bgIncrustPtr->objIdx = objIdx;
- bgIncrustPtr->param = param;
- bgIncrustPtr->x = objectTable[objIdx].x;
- bgIncrustPtr->y = objectTable[objIdx].y;
- bgIncrustPtr->frame = objectTable[objIdx].frame;
- bgIncrustPtr->part = objectTable[objIdx].part;
+ bgIncrustList.push_back(tmp);
}
-void freeBgIncrustList(void) {
- BGIncrustList *bgIncrustPtr = bgIncrustList;
- BGIncrustList *bgIncrustPtrN;
-
- while (bgIncrustPtr) {
- bgIncrustPtrN = bgIncrustPtr->next;
- delete bgIncrustPtr;
- bgIncrustPtr = bgIncrustPtrN;
- }
-
- resetBgIncrustList();
-}
-
+/*! \brief Reset var8 (probably something related to bgIncrustList
+ */
void resetBgIncrustList(void) {
- bgIncrustList = NULL;
var8 = 0;
}
-void loadBgIncrustFromSave(Common::InSaveFile *fHandle) {
- BGIncrustList *bgIncrustPtr = bgIncrustList;
- BGIncrustList *bgIncrustPtrP = 0;
+/*! \brief Restore incrust list from savefile
+ * \param fHandle Savefile open for reading
+ */
+void loadBgIncrustFromSave(Common::InSaveFile &fHandle) {
+ BGIncrust tmp;
+ int size = fHandle.readSint16BE();
- // Find first empty element
- while (bgIncrustPtr) {
- bgIncrustPtrP = bgIncrustPtr;
- bgIncrustPtr = bgIncrustPtr->next;
- }
+ for (int i = 0; i < size; i++) {
+ fHandle.readUint32BE();
+ fHandle.readUint32BE();
- bgIncrustPtr = new BGIncrustList;
- if (bgIncrustPtrP)
- bgIncrustPtrP->next = bgIncrustPtr;
- else
- bgIncrustList = bgIncrustPtr;
+ tmp.objIdx = fHandle.readUint16BE();
+ tmp.param = fHandle.readUint16BE();
+ tmp.x = fHandle.readUint16BE();
+ tmp.y = fHandle.readUint16BE();
+ tmp.frame = fHandle.readUint16BE();
+ tmp.part = fHandle.readUint16BE();
+
+ bgIncrustList.push_back(tmp);
- bgIncrustPtr->next = 0;
-
- fHandle->readUint32BE();
- fHandle->readUint32BE();
-
- bgIncrustPtr->objIdx = fHandle->readUint16BE();
- bgIncrustPtr->param = fHandle->readUint16BE();
- bgIncrustPtr->x = fHandle->readUint16BE();
- bgIncrustPtr->y = fHandle->readUint16BE();
- bgIncrustPtr->frame = fHandle->readUint16BE();
- bgIncrustPtr->part = fHandle->readUint16BE();
-}
-
-void reincrustAllBg(void) {
- BGIncrustList *bgIncrustPtr = bgIncrustList;
-
- while (bgIncrustPtr) {
-#if 0
- objectTable[bgIncrustPtr->objIdx].x = bgIncrustPtr->x;
- objectTable[bgIncrustPtr->objIdx].y = bgIncrustPtr->y;
- objectTable[bgIncrustPtr->objIdx].frame = bgIncrustPtr->frame;
- objectTable[bgIncrustPtr->objIdx].part = bgIncrustPtr->part;
-#endif
- if (bgIncrustPtr->param == 0) {
- addToBGList(bgIncrustPtr->objIdx, false);
+ if (tmp.param == 0) {
+ addToBGList(tmp.objIdx, false);
} else {
- addSpriteFilledToBGList(bgIncrustPtr->objIdx, false);
+ addSpriteFilledToBGList(tmp.objIdx, false);
}
-
- bgIncrustPtr = bgIncrustPtr->next;
}
}
Modified: scummvm/trunk/engines/cine/bg_list.h
===================================================================
--- scummvm/trunk/engines/cine/bg_list.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/bg_list.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -29,11 +29,11 @@
#include "common/scummsys.h"
#include "common/savefile.h"
+#include "common/list.h"
namespace Cine {
-struct BGIncrustList {
- struct BGIncrustList *next;
+struct BGIncrust {
byte *unkPtr;
int16 objIdx;
int16 param;
@@ -43,17 +43,15 @@
int16 part;
};
-extern BGIncrustList *bgIncrustList;
+extern Common::List<BGIncrust> bgIncrustList;
extern uint32 var8;
void addToBGList(int16 objIdx, bool addList = true);
void addSpriteFilledToBGList(int16 idx, bool addList = true);
void createBgIncrustListElement(int16 objIdx, int16 param);
-void freeBgIncrustList(void);
void resetBgIncrustList(void);
-void loadBgIncrustFromSave(Common::InSaveFile *fHandle);
-void reincrustAllBg(void);
+void loadBgIncrustFromSave(Common::InSaveFile &fHandle);
} // End of namespace Cine
Modified: scummvm/trunk/engines/cine/cine.cpp
===================================================================
--- scummvm/trunk/engines/cine/cine.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/cine.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -111,8 +111,6 @@
partBuffer = (PartBuffer *)malloc(NUM_MAX_PARTDATA * sizeof(PartBuffer));
- animDataTable = (AnimData *)malloc(NUM_MAX_ANIMDATA * sizeof(AnimData));
-
if (g_cine->getGameType() == Cine::GType_OS) {
readVolCnf();
}
@@ -124,30 +122,24 @@
loadErrmessDat("errmess.dat");
}
+ // in case ScummVM engines can be restarted in the future
+ scriptTable.clear();
+ relTable.clear();
+ objectScripts.clear();
+ globalScripts.clear();
+ bgIncrustList.clear();
+ freeAnimDataTable();
+
memset(objectTable, 0, sizeof(objectTable));
- memset(scriptTable, 0, sizeof(scriptTable));
memset(messageTable, 0, sizeof(messageTable));
- memset(relTable, 0, sizeof(relTable));
- for (int i = 0; i < NUM_MAX_ANIMDATA; i++) {
- animDataTable[i].ptr1 = animDataTable[i].ptr2 = NULL;
- }
-
overlayHead.next = overlayHead.previous = NULL;
var8 = 0;
- bgIncrustList = NULL;
+// bgIncrustList = NULL;
- objScriptList.next = NULL;
- objScriptList.scriptPtr = NULL;
-
- globalScriptsHead.next = NULL;
- globalScriptsHead.scriptPtr = NULL;
-
var2 = var3 = var4 = var5 = 0;
- freePrcLinkedList();
-
_preLoad = false;
if (ConfMan.hasKey("save_slot")) {
char saveNameBuffer[256];
Modified: scummvm/trunk/engines/cine/gfx.cpp
===================================================================
--- scummvm/trunk/engines/cine/gfx.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/gfx.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -37,6 +37,10 @@
uint16 c_palette[256];
byte colorMode256 = 0;
byte palette256[256 * 3];
+byte newPalette[256 * 3];
+byte newColorMode = 0;
+byte ctColorMode = 0;
+byte bgColorMode = 0;
byte *screenBuffer;
byte *page1Raw;
@@ -157,7 +161,7 @@
//gfxFlipPage(page2);
}
-void gfxFillSprite(byte *spritePtr, uint16 width, uint16 height, byte *page, int16 x, int16 y, uint8 fillColor) {
+void gfxFillSprite(const byte *spritePtr, uint16 width, uint16 height, byte *page, int16 x, int16 y, uint8 fillColor) {
int16 i, j;
for (i = 0; i < height; i++) {
@@ -180,7 +184,7 @@
}
}
-void gfxDrawMaskedSprite(byte *spritePtr, byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) {
+void gfxDrawMaskedSprite(const byte *spritePtr, const byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) {
int16 i, j;
for (i = 0; i < height; i++) {
@@ -198,7 +202,7 @@
}
}
-void gfxUpdateSpriteMask(byte *spritePtr, byte *spriteMskPtr, int16 width, int16 height, byte *maskPtr,
+void gfxUpdateSpriteMask(const byte *spritePtr, const byte *spriteMskPtr, int16 width, int16 height, const byte *maskPtr,
int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx) {
int16 i, j, d, spritePitch, maskPitch;
@@ -299,8 +303,8 @@
}
}
-int16 gfxGetBit(int16 x, int16 y, byte *ptr, int16 width) {
- byte *ptrToData = (ptr) + y * width + x;
+int16 gfxGetBit(int16 x, int16 y, const byte *ptr, int16 width) {
+ const byte *ptrToData = (ptr) + y * width + x;
if (x > width) {
return 0;
@@ -379,7 +383,7 @@
g_system->copyRectToScreen(screenBuffer, 320, 0, 0, 320, 200);
}
-void drawSpriteRaw(byte *spritePtr, byte *maskPtr, int16 width, int16 height,
+void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height,
byte *page, int16 x, int16 y) {
int16 i, j;
@@ -406,7 +410,7 @@
}
}
-void drawSpriteRaw2(byte *spritePtr, byte transColor, int16 width, int16 height,
+void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height,
byte *page, int16 x, int16 y) {
int16 i, j;
@@ -425,11 +429,84 @@
}
}
+void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 height,
+ byte *page, int16 x, int16 y) {
+ int16 i, j;
+
+ for (i = 0; i < height; i++) {
+ byte *destPtr = page + x + y * 320;
+ const byte *srcPtr = bgPtr + x + y * 320;
+ destPtr += i * 320;
+ srcPtr += i * 320;
+
+ for (j = 0; j < width * 8; j++) {
+ if ((!maskPtr || !(*maskPtr)) && (x + j >= 0
+ && x + j < 320 && i + y >= 0 && i + y < 200)) {
+ *destPtr = *srcPtr;
+ }
+
+ destPtr++;
+ srcPtr++;
+ maskPtr++;
+ }
+ }
+}
+
+/*! \todo Fix rendering to prevent fadein artifacts
+ */
+void fadeFromBlack() {
+ int i, j;
+ int r, g, b, tr, tg, tb;
+ if (newColorMode == 2) {
+ colorMode256 = 1;
+ memset(palette256, 0, 256*3);
+ } else if (newColorMode == 1) {
+ colorMode256 = 0;
+ memset(c_palette, 0, 16 * sizeof(uint16));
+ }
+
+ for (i = 0; i < 8; i++ ) {
+ gfxFlipRawPage(page1Raw);
+ g_system->updateScreen();
+ g_system->delayMillis(50);
+
+ if (colorMode256) {
+ for (j = 0; j < 256*3; j++) {
+ r = palette256[j] + (newPalette[j] + 7) / 8;
+ palette256[j] = CLIP(r, 0, (int)newPalette[j]);
+ }
+ } else {
+ for (j = 0; j < 16; j++) {
+ r = c_palette[j] & 0xf;
+ g = (c_palette[j] & 0xf0) >> 4;
+ b = (c_palette[j] & 0xf00) >> 8;
+
+ tr = tempPalette[j] & 0xf;
+ tg = (tempPalette[j] & 0xf0) >> 4;
+ tb = (tempPalette[j] & 0xf00) >> 8;
+
+ r = CLIP(r + (tr + 7) / 8, 0, tr);
+ g = CLIP(g + (tg + 7) / 8, 0, tg);
+ b = CLIP(b + (tb + 7) / 8, 0, tb);
+
+ c_palette[j] = r | (g << 4) | (b << 8);
+ }
+
+ }
+ }
+
+ if (colorMode256) {
+ memcpy(palette256, newPalette, 256*3);
+ } else {
+ memcpy(c_palette, tempPalette, sizeof(uint16) * 16);
+ }
+}
+
void fadeToBlack() {
for (int i = 0; i < 8; i++) {
if (colorMode256) {
- for (int j = 0; j < 256; j++) {
- palette256[j] = transformColor(palette256[j], -1, -1, -1);
+ for (int j = 0; j < 256*3; j++) {
+ palette256[j] = CLIP(palette256[j] - 32, 0, 255);
}
} else {
for (int j = 0; j < 16; j++) {
@@ -449,7 +526,17 @@
void flip(void) {
blitRawScreen(page1Raw);
if (fadeRequired) {
- memcpy(c_palette, tempPalette, sizeof(uint16) * 16);
+ if (newColorMode == 3) {
+ newColorMode = ctColorMode + 1;
+ }
+
+ if (newColorMode == 2) {
+ colorMode256 = 1;
+ memcpy(palette256, newPalette, 256*3);
+ } else {
+ colorMode256 = 0;
+ memcpy(c_palette, tempPalette, sizeof(uint16) * 16);
+ }
fadeRequired = false;
}
}
Modified: scummvm/trunk/engines/cine/gfx.h
===================================================================
--- scummvm/trunk/engines/cine/gfx.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/gfx.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -37,6 +37,10 @@
extern uint16 c_palette[256];
extern byte colorMode256;
extern byte palette256[256 * 3];
+extern byte newPalette[256 * 3];
+extern byte newColorMode;
+extern byte ctColorMode;
+extern byte bgColorMode;
void gfxInit();
void gfxDestroy();
@@ -46,10 +50,10 @@
void transformPaletteRange(byte startColor, byte numColor, int8 r, int8 g, int8 b);
void gfxFlipPage(void);
-void gfxDrawMaskedSprite(byte *ptr, byte *msk, uint16 width, uint16 height, byte *page, int16 x, int16 y);
-void gfxFillSprite(byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy, uint8 fillColor = 0);
+void gfxDrawMaskedSprite(const byte *ptr, const byte *msk, uint16 width, uint16 height, byte *page, int16 x, int16 y);
+void gfxFillSprite(const byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy, uint8 fillColor = 0);
-void gfxUpdateSpriteMask(byte *spritePtr, byte *spriteMskPtr, int16 width, int16 height, byte *maskPtr,
+void gfxUpdateSpriteMask(const byte *spritePtr, const byte *spriteMskPtr, int16 width, int16 height, const byte *maskPtr,
int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx);
void gfxDrawLine(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page);
@@ -57,19 +61,23 @@
void gfxResetPage(byte *pagePtr);
-int16 gfxGetBit(int16 x, int16 y, byte *ptr, int16 width);
+int16 gfxGetBit(int16 x, int16 y, const byte *ptr, int16 width);
+byte gfxGetColor(int16 x, int16 y, const byte *ptr, int16 width);
void gfxResetRawPage(byte *pageRaw);
void gfxConvertSpriteToRaw(byte *dst, const byte *src, uint16 w, uint16 h);
void gfxCopyRawPage(byte *source, byte * dest);
void gfxFlipRawPage(byte *frontBuffer);
-void drawSpriteRaw(byte *spritePtr, byte *maskPtr, int16 width, int16 height, byte *page, int16 x, int16 y);
+void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, byte *page, int16 x, int16 y);
void gfxDrawPlainBoxRaw(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page);
-void drawSpriteRaw2(byte *spritePtr, byte transColor, int16 width, int16 height, byte *page, int16 x, int16 y);
+void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, byte *page, int16 x, int16 y);
+void maskBgOverlay(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, byte *page, int16 x, int16 y);
+void fadeFromBlack(void);
void fadeToBlack(void);
-void gfxDrawMaskedSprite(byte *param1, byte *param2, byte *param3, byte *param4, int16 param5);
+// wtf?!
+//void gfxDrawMaskedSprite(byte *param1, byte *param2, byte *param3, byte *param4, int16 param5);
void gfxWaitVBL(void);
void gfxRedrawMouseCursor(void);
Modified: scummvm/trunk/engines/cine/main_loop.cpp
===================================================================
--- scummvm/trunk/engines/cine/main_loop.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/main_loop.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -189,11 +189,8 @@
quitFlag = 0;
if (_preLoad == false) {
- freeAnimDataTable();
resetMessageHead();
resetSeqList();
- resetglobalScriptsHead();
- resetObjectScriptHead();
resetBgIncrustList();
setTextWindow(0, 0, 20, 200);
@@ -318,14 +315,10 @@
hideMouse();
g_sound->stopMusic();
- freeAnimDataTable();
unloadAllMasks();
- freePrcLinkedList();
- releaseObjectScripts();
// if (g_cine->getGameType() == Cine::GType_OS) {
// freeUnkList();
// }
- freeBgIncrustList();
closePart();
}
Modified: scummvm/trunk/engines/cine/object.cpp
===================================================================
--- scummvm/trunk/engines/cine/object.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/object.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -231,7 +231,9 @@
objectTable[objIdx].frame = newValue;
break;
case 4:
- if (newValue == -1) {
+ // is it really in Future Wars? it breaks the newspaper machine
+ // on the airport in Operation Stealth
+ if (newValue == -1 && g_cine->getGameType() != Cine::GType_OS) {
objectTable[objIdx].costume = globalVars[0];
} else {
objectTable[objIdx].costume = newValue;
@@ -243,8 +245,8 @@
}
}
-byte compareObjectParam(byte objIdx, byte type, int16 value) {
- byte compareResult = 0;
+uint16 compareObjectParam(byte objIdx, byte type, int16 value) {
+ uint16 compareResult = 0;
int16 objectParam = getObjectParam(objIdx, type);
if (objectParam > value) {
Modified: scummvm/trunk/engines/cine/object.h
===================================================================
--- scummvm/trunk/engines/cine/object.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/object.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -74,7 +74,7 @@
void addObjectParam(byte objIdx, byte paramIdx, int16 newValue);
void subObjectParam(byte objIdx, byte paramIdx, int16 newValue);
-byte compareObjectParam(byte objIdx, byte param1, int16 param2);
+uint16 compareObjectParam(byte objIdx, byte param1, int16 param2);
} // End of namespace Cine
Modified: scummvm/trunk/engines/cine/part.cpp
===================================================================
--- scummvm/trunk/engines/cine/part.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/part.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -33,7 +33,6 @@
uint16 numElementInPart;
-AnimData *animDataTable;
PartBuffer *partBuffer;
void loadPart(const char *partName) {
Modified: scummvm/trunk/engines/cine/part.h
===================================================================
--- scummvm/trunk/engines/cine/part.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/part.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -35,26 +35,8 @@
uint32 unpackedSize;
};
-struct AnimData {
- uint16 width;
- uint16 var1;
- uint16 bpp;
- uint16 height;
-
- byte *ptr1;
- byte *ptr2;
- int16 fileIdx;
- int16 frameIdx;
- char name[10];
-
- // Not part of the data, but used when saving/restoring it.
- bool refresh;
-};
-
#define NUM_MAX_PARTDATA 255
-#define NUM_MAX_ANIMDATA 255
-extern AnimData *animDataTable;
extern PartBuffer *partBuffer;
void loadPart(const char *partName);
Modified: scummvm/trunk/engines/cine/prc.cpp
===================================================================
--- scummvm/trunk/engines/cine/prc.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/prc.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -33,34 +33,14 @@
namespace Cine {
-prcLinkedListStruct globalScriptsHead;
-prcLinkedListStruct objScriptList;
+ScriptList globalScripts;
+ScriptList objectScripts;
//char currentPrcName[20];
-void resetglobalScriptsHead(void) {
- globalScriptsHead.next = NULL;
- globalScriptsHead.scriptIdx = -1;
-}
-
-void freePrcLinkedList(void) {
- prcLinkedListStruct *currentHead = globalScriptsHead.next;
-
- while (currentHead) {
- prcLinkedListStruct *temp;
-
- assert(currentHead);
-
- temp = currentHead->next;
-
- delete currentHead;
-
- currentHead = temp;
- }
-
- resetglobalScriptsHead();
-}
-
+/*! \todo Is script size of 0 valid?
+ * \todo Fix script dump code
+ */
void loadPrc(const char *pPrcName) {
byte i;
uint16 numScripts;
@@ -68,14 +48,8 @@
assert(pPrcName);
- for (i = 0; i < NUM_MAX_SCRIPT; i++) {
- if (scriptTable[i].ptr) {
- assert(scriptTable[i].ptr);
- free(scriptTable[i].ptr);
- scriptTable[i].ptr = NULL;
- scriptTable[i].size = 0;
- }
- }
+ globalScripts.clear();
+ scriptTable.clear();
// This is copy protection. Used to hang the machine
if (!scumm_stricmp(pPrcName, "L201.ANI")) {
@@ -100,17 +74,18 @@
assert(numScripts <= NUM_MAX_SCRIPT);
for (i = 0; i < numScripts; i++) {
- scriptTable[i].size = READ_BE_UINT16(scriptPtr); scriptPtr += 2;
+ RawScriptPtr tmp(new RawScript(READ_BE_UINT16(scriptPtr)));
+ scriptPtr += 2;
+ assert(tmp);
+ scriptTable.push_back(tmp);
}
for (i = 0; i < numScripts; i++) {
- uint16 size = scriptTable[i].size;
+ uint16 size = scriptTable[i]->_size;
+ // TODO: delete the test?
if (size) {
- scriptTable[i].ptr = (byte *) malloc(size);
- assert(scriptTable[i].ptr);
- memcpy(scriptTable[i].ptr, scriptPtr, size);
+ scriptTable[i]->setData(*scriptInfo, scriptPtr);
scriptPtr += size;
- computeScriptStack(scriptTable[i].ptr, scriptTable[i].stack, size);
}
}
Modified: scummvm/trunk/engines/cine/prc.h
===================================================================
--- scummvm/trunk/engines/cine/prc.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/prc.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -28,21 +28,9 @@
namespace Cine {
-struct prcLinkedListStruct {
- struct prcLinkedListStruct *next;
- int16 stack[SCRIPT_STACK_SIZE];
- ScriptVars localVars;
- uint16 compareResult;
- uint16 scriptPosition;
- byte *scriptPtr;
- int16 scriptIdx;
-};
+extern ScriptList globalScripts;
+extern ScriptList objectScripts;
-extern prcLinkedListStruct globalScriptsHead;
-extern prcLinkedListStruct objScriptList;
-
-void resetglobalScriptsHead(void);
-void freePrcLinkedList(void);
void loadPrc(const char *pPrcName);
} // End of namespace Cine
Modified: scummvm/trunk/engines/cine/rel.cpp
===================================================================
--- scummvm/trunk/engines/cine/rel.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/rel.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -31,45 +31,21 @@
namespace Cine {
-RelObjectScript relTable[NUM_MAX_REL];
+RawObjectScriptArray relTable; ///< Object script bytecode table
-void resetObjectScriptHead(void) {
- objScriptList.next = NULL;
- objScriptList.scriptIdx = -1;
-}
-
-void releaseObjectScripts(void) {
- prcLinkedListStruct *currentHead = objScriptList.next;
-
- while (currentHead) {
- prcLinkedListStruct *temp;
-
- assert(currentHead);
-
- temp = currentHead->next;
-
- delete currentHead;
-
- currentHead = temp;
- }
-
- resetObjectScriptHead();
-}
-
+/*! \todo Is script size of 0 valid?
+ * \todo Fix script dump code
+ */
void loadRel(char *pRelName) {
uint16 numEntry;
uint16 i;
+ uint16 size, p1, p2, p3;
byte *ptr, *dataPtr;
checkDataDisk(-1);
- for (i = 0; i < NUM_MAX_REL; i++) {
- if (relTable[i].data) {
- free(relTable[i].data);
- relTable[i].data = NULL;
- relTable[i].size = 0;
- }
- }
+ objectScripts.clear();
+ relTable.clear();
ptr = dataPtr = readBundleFile(findFileInBundle(pRelName));
@@ -77,24 +53,22 @@
numEntry = READ_BE_UINT16(ptr); ptr += 2;
- assert(numEntry <= NUM_MAX_REL);
-
for (i = 0; i < numEntry; i++) {
- relTable[i].size = READ_BE_UINT16(ptr); ptr += 2;
- relTable[i].obj1Param1 = READ_BE_UINT16(ptr); ptr += 2;
- relTable[i].obj1Param2 = READ_BE_UINT16(ptr); ptr += 2;
- relTable[i].obj2Param = READ_BE_UINT16(ptr); ptr += 2;
- relTable[i].runCount = 0;
+ size = READ_BE_UINT16(ptr); ptr += 2;
+ p1 = READ_BE_UINT16(ptr); ptr += 2;
+ p2 = READ_BE_UINT16(ptr); ptr += 2;
+ p3 = READ_BE_UINT16(ptr); ptr += 2;
+ RawObjectScriptPtr tmp(new RawObjectScript(size, p1, p2, p3));
+ assert(tmp);
+ relTable.push_back(tmp);
}
for (i = 0; i < numEntry; i++) {
- if (relTable[i].size) {
- relTable[i].data = (byte *)malloc(relTable[i].size);
-
- assert(relTable[i].data);
-
- memcpy(relTable[i].data, ptr, relTable[i].size);
- ptr += relTable[i].size;
+ size = relTable[i]->_size;
+ // TODO: delete the test?
+ if (size) {
+ relTable[i]->setData(*scriptInfo, ptr);
+ ptr += size;
}
}
Modified: scummvm/trunk/engines/cine/rel.h
===================================================================
--- scummvm/trunk/engines/cine/rel.h 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/rel.h 2008-04-07 20:24:40 UTC (rev 31444)
@@ -26,24 +26,11 @@
#ifndef CINE_REL_H
#define CINE_REL_H
+#include "cine/script.h"
namespace Cine {
-struct RelObjectScript {
- byte *data;
- uint16 size;
- uint16 obj1Param1;
- uint16 obj1Param2;
- uint16 obj2Param;
- uint16 runCount;
-};
+extern RawObjectScriptArray relTable;
-#define NUM_MAX_REL 255
-
-extern RelObjectScript relTable[NUM_MAX_REL];
-
-void releaseObjectScripts(void);
-void resetObjectScriptHead(void);
-
void loadRel(char *pRelName);
} // End of namespace Cine
Modified: scummvm/trunk/engines/cine/script.cpp
===================================================================
--- scummvm/trunk/engines/cine/script.cpp 2008-04-07 17:56:04 UTC (rev 31443)
+++ scummvm/trunk/engines/cine/script.cpp 2008-04-07 20:24:40 UTC (rev 31444)
@@ -23,6 +23,9 @@
*
*/
+/*! \file
+ * Script interpreter file
+ */
#include "common/endian.h"
@@ -31,435 +34,423 @@
#include "cine/object.h"
#include "cine/sound.h"
#include "cine/various.h"
+#include "cine/script.h"
namespace Cine {
-prcLinkedListStruct *_currentScriptElement;
-byte *_currentScriptPtr;
-uint16 _currentScriptParams;
-uint16 _currentPosition;
-uint16 _currentLine;
-uint16 _closeScript;
+uint16 compareVars(int16 a, int16 b);
+void palRotate(byte a, byte b, byte c);
+void removeSeq(uint16 param1, uint16 param2, uint16 param3);
+uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3);
+void addGfxElementA0(int16 param1, int16 param2);
+void removeGfxElementA0(int16 idx, int16 param);
-struct Opcode {
- void (*proc)();
- const char *args;
+const Opcode FWScript::_opcodeTable[] = {
+ /* 00 */
+ { &FWScript::o1_modifyObjectParam, "bbw" },
+ { &FWScript::o1_getObjectParam, "bbb" },
+ { &FWScript::o1_addObjectParam, "bbw" },
+ { &FWScript::o1_subObjectParam, "bbw" },
+ /* 04 */
+ { &FWScript::o1_add2ObjectParam, "bbw" },
+ { &FWScript::o1_sub2ObjectParam, "bbw" },
+ { &FWScript::o1_compareObjectParam, "bbw" },
+ { &FWScript::o1_setupObject, "bwwww" },
+ /* 08 */
+ { &FWScript::o1_checkCollision, "bwwww" },
+ { &FWScript::o1_loadVar, "bc" },
+ { &FWScript::o1_addVar, "bc" },
+ { &FWScript::o1_subVar, "bc" },
+ /* 0C */
+ { &FWScript::o1_mulVar, "bc" },
+ { &FWScript::o1_divVar, "bc" },
+ { &FWScript::o1_compareVar, "bc" },
+ { &FWScript::o1_modifyObjectParam2, "bbb" },
+ /* 10 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_loadMask0, "b" },
+ /* 14 */
+ { &FWScript::o1_unloadMask0, "b" },
+ { &FWScript::o1_addToBgList, "b" },
+ { &FWScript::o1_loadMask1, "b" },
+ { &FWScript::o1_unloadMask1, "b" },
+ /* 18 */
+ { &FWScript::o1_loadMask4, "b" },
+ { &FWScript::o1_unloadMask4, "b" },
+ { &FWScript::o1_addSpriteFilledToBgList, "b" },
+ { &FWScript::o1_op1B, "" },
+ /* 1C */
+ { 0, 0 },
+ { &FWScript::o1_label, "l" },
+ { &FWScript::o1_goto, "b" },
+ { &FWScript::o1_gotoIfSup, "b" },
+ /* 20 */
+ { &FWScript::o1_gotoIfSupEqu, "b" },
+ { &FWScript::o1_gotoIfInf, "b" },
+ { &FWScript::o1_gotoIfInfEqu, "b" },
+ { &FWScript::o1_gotoIfEqu, "b" },
+ /* 24 */
+ { &FWScript::o1_gotoIfDiff, "b" },
+ { &FWScript::o1_removeLabel, "b" },
+ { &FWScript::o1_loop, "bb" },
+ { 0, 0 },
+ /* 28 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 2C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 30 */
+ { 0, 0 },
+ { &FWScript::o1_startGlobalScript, "b" },
+ { &FWScript::o1_endGlobalScript, "b" },
+ { 0, 0 },
+ /* 34 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 38 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_loadAnim, "s" },
+ /* 3C */
+ { &FWScript::o1_loadBg, "s" },
+ { &FWScript::o1_loadCt, "s" },
+ { 0, 0 },
+ { &FWScript::o1_loadPart, "s" },
+ /* 40 */
+ { &FWScript::o1_closePart, "" },
+ { &FWScript::o1_loadNewPrcName, "bs" },
+ { &FWScript::o1_requestCheckPendingDataLoad, "" },
+ { 0, 0 },
+ /* 44 */
+ { 0, 0 },
+ { &FWScript::o1_blitAndFade, "" },
+ { &FWScript::o1_fadeToBlack, "" },
+ { &FWScript::o1_transformPaletteRange, "bbwww" },
+ /* 48 */
+ { 0, 0 },
+ { &FWScript::o1_setDefaultMenuColor2, "b" },
+ { &FWScript::o1_palRotate, "bbb" },
+ { 0, 0 },
+ /* 4C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_break, "" },
+ /* 50 */
+ { &FWScript::o1_endScript, "x" },
+ { &FWScript::o1_message, "bwwww" },
+ { &FWScript::o1_loadGlobalVar, "bc" },
+ { &FWScript::o1_compareGlobalVar, "bc" },
+ /* 54 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 58 */
+ { 0, 0 },
+ { &FWScript::o1_declareFunctionName, "s" },
+ { &FWScript::o1_freePartRange, "bb" },
+ { &FWScript::o1_unloadAllMasks, "" },
+ // 5C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 60 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_setScreenDimensions, "wwww" },
+ /* 64 */
+ { &FWScript::o1_displayBackground, "" },
+ { &FWScript::o1_initializeZoneData, "" },
+ { &FWScript::o1_setZoneDataEntry, "bw" },
+ { &FWScript::o1_getZoneDataEntry, "bb" },
+ /* 68 */
+ { &FWScript::o1_setDefaultMenuColor, "b" },
+ { &FWScript::o1_allowPlayerInput, "" },
+ { &FWScript::o1_disallowPlayerInput, "" },
+ { &FWScript::o1_changeDataDisk, "b" },
+ /* 6C */
+ { 0, 0 },
+ { &FWScript::o1_loadMusic, "s" },
+ { &FWScript::o1_playMusic, "" },
+ { &FWScript::o1_fadeOutMusic, "" },
+ /* 70 */
+ { &FWScript::o1_stopSample, "" },
+ { &FWScript::o1_op71, "bw" },
+ { &FWScript::o1_op72, "wbw" },
+ { &FWScript::o1_op73, "wbw" },
+ /* 74 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_playSample, "bbwbww" },
+ /* 78 */
+ { &FWScript::o1_playSample, "bbwbww" },
+ { &FWScript::o1_disableSystemMenu, "b" },
+ { &FWScript::o1_loadMask5, "b" },
+ { &FWScript::o1_unloadMask5, "b" }
};
+const unsigned int FWScript::_numOpcodes = ARRAYSIZE(FWScript::_opcodeTable);
-const Opcode *_opcodeTable;
-int _numOpcodes;
-void setupOpcodes() {
- static const Opcode opcodeTableFW[] = {
- /* 00 */
- { o1_modifyObjectParam, "bbw" },
- { o1_getObjectParam, "bbb" },
- { o1_addObjectParam, "bbw" },
- { o1_subObjectParam, "bbw" },
- /* 04 */
- { o1_add2ObjectParam, "bbw" },
- { o1_sub2ObjectParam, "bbw" },
- { o1_compareObjectParam, "bbw" },
- { o1_setupObject, "bwwww" },
- /* 08 */
- { o1_checkCollision, "bwwww" },
- { o1_loadVar, "bc" },
- { o1_addVar, "bc" },
- { o1_subVar, "bc" },
- /* 0C */
- { o1_mulVar, "bc" },
- { o1_divVar, "bc" },
- { o1_compareVar, "bc" },
- { o1_modifyObjectParam2, "bbb" },
- /* 10 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_loadMask0, "b" },
- /* 14 */
- { o1_unloadMask0, "b" },
- { o1_addToBgList, "b" },
- { o1_loadMask1, "b" },
- { o1_unloadMask1, "b" },
- /* 18 */
- { o1_loadMask4, "b" },
- { o1_unloadMask4, "b" },
- { o1_addSpriteFilledToBgList, "b" },
- { o1_op1B, "" },
- /* 1C */
- { 0, 0 },
- { o1_label, "l" },
- { o1_goto, "b" },
- { o1_gotoIfSup, "b" },
- /* 20 */
- { o1_gotoIfSupEqu, "b" },
- { o1_gotoIfInf, "b" },
- { o1_gotoIfInfEqu, "b" },
- { o1_gotoIfEqu, "b" },
- /* 24 */
- { o1_gotoIfDiff, "b" },
- { o1_removeLabel, "b" },
- { o1_loop, "bb" },
- { 0, 0 },
- /* 28 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 2C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 30 */
- { 0, 0 },
- { o1_startGlobalScript, "b" },
- { o1_endGlobalScript, "b" },
- { 0, 0 },
- /* 34 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 38 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_loadAnim, "s" },
- /* 3C */
- { o1_loadBg, "s" },
- { o1_loadCt, "s" },
- { 0, 0 },
- { o1_loadPart, "s" },
- /* 40 */
- { o1_closePart, "" },
- { o1_loadNewPrcName, "bs" },
- { o1_requestCheckPendingDataLoad, "" },
- { 0, 0 },
- /* 44 */
- { 0, 0 },
- { o1_blitAndFade, "" },
- { o1_fadeToBlack, "" },
- { o1_transformPaletteRange, "bbwww" },
- /* 48 */
- { 0, 0 },
- { o1_setDefaultMenuColor2, "b" },
- { o1_palRotate, "bbb" },
- { 0, 0 },
- /* 4C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_break, "" },
- /* 50 */
- { o1_endScript, "x" },
- { o1_message, "bwwww" },
- { o1_loadGlobalVar, "bc" },
- { o1_compareGlobalVar, "bc" },
- /* 54 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 58 */
- { 0, 0 },
- { o1_declareFunctionName, "s" },
- { o1_freePartRange, "bb" },
- { o1_unloadAllMasks, "" },
- // 5C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 60 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_setScreenDimensions, "wwww" },
- /* 64 */
- { o1_displayBackground, "" },
- { o1_initializeZoneData, "" },
- { o1_setZoneDataEntry, "bw" },
- { o1_getZoneDataEntry, "bb" },
- /* 68 */
- { o1_setDefaultMenuColor, "b" },
- { o1_allowPlayerInput, "" },
- { o1_disallowPlayerInput, "" },
- { o1_changeDataDisk, "b" },
- /* 6C */
- { 0, 0 },
- { o1_loadMusic, "s" },
- { o1_playMusic, "" },
- { o1_fadeOutMusic, "" },
- /* 70 */
- { o1_stopSample, "" },
- { o1_op71, "bw" },
- { o1_op72, "wbw" },
- { o1_op73, "wbw" },
- /* 74 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_playSample, "bbwbww" },
- /* 78 */
- { o1_playSample, "bbwbww" },
- { o1_disableSystemMenu, "b" },
- { o1_loadMask5, "b" },
- { o1_unloadMask5, "b" }
- };
+const Opcode OSScript::_opcodeTable[] = {
+ /* 00 */
+ { &FWScript::o1_modifyObjectParam, "bbw" },
+ { &FWScript::o1_getObjectParam, "bbb" },
+ { &FWScript::o1_addObjectParam, "bbw" },
+ { &FWScript::o1_subObjectParam, "bbw" },
+ /* 04 */
+ { &FWScript::o1_add2ObjectParam, "bbw" },
+ { &FWScript::o1_sub2ObjectParam, "bbw" },
+ { &FWScript::o1_compareObjectParam, "bbw" },
+ { &FWScript::o1_setupObject, "bwwww" },
+ /* 08 */
+ { &FWScript::o1_checkCollision, "bwwww" },
+ { &FWScript::o1_loadVar, "bc" },
+ { &FWScript::o1_addVar, "bc" },
+ { &FWScript::o1_subVar, "bc" },
+ /* 0C */
+ { &FWScript::o1_mulVar, "bc" },
+ { &FWScript::o1_divVar, "bc" },
+ { &FWScript::o1_compareVar, "bc" },
+ { &FWScript::o1_modifyObjectParam2, "bbb" },
+ /* 10 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_loadMask0, "b" },
+ /* 14 */
+ { &FWScript::o1_unloadMask0, "b" },
+ { &FWScript::o1_addToBgList, "b" },
+ { &FWScript::o1_loadMask1, "b" },
+ { &FWScript::o1_unloadMask1, "b" },
+ /* 18 */
+ { &FWScript::o1_loadMask4, "b" },
+ { &FWScript::o1_unloadMask4, "b" },
+ { &FWScript::o1_addSpriteFilledToBgList, "b" },
+ { &FWScript::o1_op1B, "" },
+ /* 1C */
+ { 0, 0 },
+ { &FWScript::o1_label, "l" },
+ { &FWScript::o1_goto, "b" },
+ { &FWScript::o1_gotoIfSup, "b" },
+ /* 20 */
+ { &FWScript::o1_gotoIfSupEqu, "b" },
+ { &FWScript::o1_gotoIfInf, "b" },
+ { &FWScript::o1_gotoIfInfEqu, "b" },
+ { &FWScript::o1_gotoIfEqu, "b" },
+ /* 24 */
+ { &FWScript::o1_gotoIfDiff, "b" },
+ { &FWScript::o1_removeLabel, "b" },
+ { &FWScript::o1_loop, "bb" },
+ { 0, 0 },
+ /* 28 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 2C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 30 */
+ { 0, 0 },
+ { &FWScript::o1_startGlobalScript, "b" },
+ { &FWScript::o1_endGlobalScript, "b" },
+ { 0, 0 },
+ /* 34 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 38 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_loadAnim, "s" },
+ /* 3C */
+ { &FWScript::o1_loadBg, "s" },
+ { &FWScript::o1_loadCt, "s" },
+ { 0, 0 },
+ { &FWScript::o2_loadPart, "s" },
+ /* 40 */
+ { 0, 0 }, /* o1_closePart, triggered by some scripts (STARTA.PRC 4 for ex.) */
+ { &FWScript::o1_loadNewPrcName, "bs" },
+ { &FWScript::o1_requestCheckPendingDataLoad, "" },
+ { 0, 0 },
+ /* 44 */
+ { 0, 0 },
+ { &FWScript::o1_blitAndFade, "" },
+ { &FWScript::o1_fadeToBlack, "" },
+ { &FWScript::o1_transformPaletteRange, "bbwww" },
+ /* 48 */
+ { 0, 0 },
+ { &FWScript::o1_setDefaultMenuColor2, "b" },
+ { &FWScript::o1_palRotate, "bbb" },
+ { 0, 0 },
+ /* 4C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_break, "" },
+ /* 50 */
+ { &FWScript::o1_endScript, "x" },
+ { &FWScript::o1_message, "bwwww" },
+ { &FWScript::o1_loadGlobalVar, "bc" },
+ { &FWScript::o1_compareGlobalVar, "bc" },
+ /* 54 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 58 */
+ { 0, 0 },
+ { &FWScript::o1_declareFunctionName, "s" },
+ { &FWScript::o1_freePartRange, "bb" },
+ { &FWScript::o1_unloadAllMasks, "" },
+ // 5C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ /* 60 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o1_setScreenDimensions, "wwww" },
+ /* 64 */
+ { &FWScript::o1_displayBackground, "" },
+ { &FWScript::o1_initializeZoneData, "" },
+ { &FWScript::o1_setZoneDataEntry, "bw" },
+ { &FWScript::o1_getZoneDataEntry, "bb" },
+ /* 68 */
+ { &FWScript::o1_setDefaultMenuColor, "b" },
+ { &FWScript::o1_allowPlayerInput, "" },
+ { &FWScript::o1_disallowPlayerInput, "" },
+ { &FWScript::o1_changeDataDisk, "b" },
+ /* 6C */
+ { 0, 0 },
+ { &FWScript::o1_loadMusic, "s" },
+ { &FWScript::o1_playMusic, "" },
+ { &FWScript::o1_fadeOutMusic, "" },
+ /* 70 */
+ { &FWScript::o1_stopSample, "" },
+ { &FWScript::o1_op71, "bw" },
+ { &FWScript::o1_op72, "wbw" },
+ { &FWScript::o1_op72, "wbw" },
+ /* 74 */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o2_playSample, "bbwbww" },
+ /* 78 */
+ { &FWScript::o2_playSampleAlt, "bbwbww" },
+ { &FWScript::o1_disableSystemMenu, "b" },
+ { &FWScript::o1_loadMask5, "b" },
+ { &FWScript::o1_unloadMask5, "b" },
+ /* 7C */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o2_addSeqListElement, "bbbbwww" },
+ /* 80 */
+ { &FWScript::o2_removeSeq, "bb" },
+ { &FWScript::o2_op81, "" },
+ { &FWScript::o2_op82, "bbw" },
+ { &FWScript::o2_isSeqRunning, "bb" },
+ /* 84 */
+ { &FWScript::o2_gotoIfSupNearest, "b" },
+ { &FWScript::o2_gotoIfSupEquNearest, "b" },
+ { &FWScript::o2_gotoIfInfNearest, "b" },
+ { &FWScript::o2_gotoIfInfEquNearest, "b" },
+ /* 88 */
+ { &FWScript::o2_gotoIfEquNearest, "b" },
+ { &FWScript::o2_gotoIfDiffNearest, "b" },
+ { 0, 0 },
+ { &FWScript::o2_startObjectScript, "b" },
+ /* 8C */
+ { &FWScript::o2_stopObjectScript, "b" },
+ { &FWScript::o2_op8D, "wwwwwwww" },
+ { &FWScript::o2_addBackground, "bs" },
+ { &FWScript::o2_removeBackground, "b" },
+ /* 90 */
+ { &FWScript::o2_loadAbs, "bs" },
+ { &FWScript::o2_loadBg, "b" },
+ { 0, 0 },
+ { 0, 0 },
+ /* 94 */
+ { 0, 0 },
+ { &FWScript::o1_changeDataDisk, "b" },
+ { 0, 0 },
+ { 0, 0 },
+ /* 98 */
+ { 0, 0 },
+ { 0, 0 },
+ { &FWScript::o2_wasZoneChecked, "" },
+ { &FWScript::o2_op9B, "wwwwwwww" },
+ /* 9C */
+ { &FWScript::o2_op9C, "wwww" },
+ { &FWScript::o2_useBgScroll, "b" },
+ { &FWScript::o2_setAdditionalBgVScroll, "c" },
+ { &FWScript::o2_op9F, "ww" },
+ /* A0 */
+ { &FWScript::o2_addGfxElementA0, "ww" },
+ { &FWScript::o2_removeGfxElementA0, "ww" },
+ { &FWScript::o2_opA2, "ww" },
+ { &FWScript::o2_opA3, "ww" },
+ /* A4 */
+ { &FWScript::o2_loadMask22, "b" },
+ { &FWScript::o2_unloadMask22, "b" },
+ { 0, 0 },
+ { 0, 0 },
+ /* A8 */
+ { 0, 0 },
+ { &FWScript::o1_changeDataDisk, "b" }
+};
+const unsigned int OSScript::_numOpcodes = ARRAYSIZE(OSScript::_opcodeTable);
- // TODO: We need to verify the Operation Stealth opcodes.
+FWScriptInfo *scriptInfo; ///< Script factory
+RawScriptArray scriptTable; ///< Table of script bytecode
- static const Opcode opcodeTableOS[] = {
- /* 00 */
- { o1_modifyObjectParam, "bbw" },
- { o1_getObjectParam, "bbb" },
- { o1_addObjectParam, "bbw" },
- { o1_subObjectParam, "bbw" },
- /* 04 */
- { o1_add2ObjectParam, "bbw" },
- { o1_sub2ObjectParam, "bbw" },
- { o1_compareObjectParam, "bbw" },
- { o1_setupObject, "bwwww" },
- /* 08 */
- { o1_checkCollision, "bwwww" },
- { o1_loadVar, "bc" },
- { o1_addVar, "bc" },
- { o1_subVar, "bc" },
- /* 0C */
- { o1_mulVar, "bc" },
- { o1_divVar, "bc" },
- { o1_compareVar, "bc" },
- { o1_modifyObjectParam2, "bbb" },
- /* 10 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_loadMask0, "b" },
- /* 14 */
- { o1_unloadMask0, "b" },
- { o1_addToBgList, "b" },
- { o1_loadMask1, "b" },
- { o1_unloadMask1, "b" },
- /* 18 */
- { o1_loadMask4, "b" },
- { o1_unloadMask4, "b" },
- { o1_addSpriteFilledToBgList, "b" },
- { o1_op1B, "" },
- /* 1C */
- { 0, 0 },
- { o1_label, "l" },
- { o1_goto, "b" },
- { o1_gotoIfSup, "b" },
- /* 20 */
- { o1_gotoIfSupEqu, "b" },
- { o1_gotoIfInf, "b" },
- { o1_gotoIfInfEqu, "b" },
- { o1_gotoIfEqu, "b" },
- /* 24 */
- { o1_gotoIfDiff, "b" },
- { o1_removeLabel, "b" },
- { o1_loop, "bb" },
- { 0, 0 },
- /* 28 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 2C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 30 */
- { 0, 0 },
- { o1_startGlobalScript, "b" },
- { o1_endGlobalScript, "b" },
- { 0, 0 },
- /* 34 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 38 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_loadAnim, "s" },
- /* 3C */
- { o1_loadBg, "s" },
- { o1_loadCt, "s" },
- { 0, 0 },
- { o2_loadPart, "s" },
- /* 40 */
- { 0, 0 }, /* o1_closePart, triggered by some scripts (STARTA.PRC 4 for ex.) */
- { o1_loadNewPrcName, "bs" },
- { o1_requestCheckPendingDataLoad, "" },
- { 0, 0 },
- /* 44 */
- { 0, 0 },
- { o1_blitAndFade, "" },
- { o1_fadeToBlack, "" },
- { o1_transformPaletteRange, "bbwww" },
- /* 48 */
- { 0, 0 },
- { o1_setDefaultMenuColor2, "b" },
- { o1_palRotate, "bbb" },
- { 0, 0 },
- /* 4C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_break, "" },
- /* 50 */
- { o1_endScript, "x" },
- { o1_message, "bwwww" },
- { o1_loadGlobalVar, "bc" },
- { o1_compareGlobalVar, "bc" },
- /* 54 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 58 */
- { 0, 0 },
- { o1_declareFunctionName, "s" },
- { o1_freePartRange, "bb" },
- { o1_unloadAllMasks, "" },
- // 5C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- /* 60 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o1_setScreenDimensions, "wwww" },
- /* 64 */
- { o1_displayBackground, "" },
- { o1_initializeZoneData, "" },
- { o1_setZoneDataEntry, "bw" },
- { o1_getZoneDataEntry, "bb" },
- /* 68 */
- { o1_setDefaultMenuColor, "b" },
- { o1_allowPlayerInput, "" },
- { o1_disallowPlayerInput, "" },
- { o1_changeDataDisk, "b" },
- /* 6C */
- { 0, 0 },
- { o1_loadMusic, "s" },
- { o1_playMusic, "" },
- { o1_fadeOutMusic, "" },
- /* 70 */
- { o1_stopSample, "" },
- { o1_op71, "bw" },
- { o1_op72, "wbw" },
- { o1_op72, "wbw" },
- /* 74 */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o2_playSample, "bbwbww" },
- /* 78 */
- { o2_playSampleAlt, "bbwbww" },
- { o1_disableSystemMenu, "b" },
- { o1_loadMask5, "b" },
- { o1_unloadMask5, "b" },
- /* 7C */
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { o2_addSeqListElement, "bbbbwww" },
- /* 80 */
- { o2_removeSeq, "bb" },
- { o2_op81, "" },
- { o2_op82, "bbw" },
- { o2_isSeqRunning, "bb" },
- /* 84 */
- { o2_gotoIfSupNearest, "b" },
- { o2_gotoIfSupEquNearest, "b" },
- { o2_gotoIfInfNearest, "b" },
- { o2_gotoIfInfEquNearest, "b" },
- /* 88 */
- { o2_gotoIfEquNearest, "b" },
- { o2_gotoIfDiffNearest, "b" },
- { 0, 0 },
- { o2_startObjectScript, "b" },
- /* 8C */
- { o2_stopObjectScript, "b" },
- { o2_op8D, "wwwwwwww" },
- { o2_addBackground, "bs" },
- { o2_removeBackground, "b" },
- /* 90 */
- { o2_loadAbs, "bs" },
- { o2_loadBg, "b" },
- { 0, 0 },
- { 0, 0 },
- /* 94 */
- { 0, 0 },
- { o1_changeDataDisk, "b" },
- { 0, 0 },
- { 0, 0 },
- /* 98 */
- { 0, 0 },
- { 0, 0 },
- { o2_wasZoneChecked, "" },
- { o2_op9B, "wwwwwwww" },
- /* 9C */
- { o2_op9C, "wwww" },
- { o2_useBgScroll, "b" },
- { o2_setAdditionalBgVScroll, "c" },
- { o2_op9F, "ww" },
- /* A0 */
- { o2_addGfxElementA0, "ww" },
- { o2_opA1, "ww" },
- { o2_opA2, "ww" },
- { o2_opA3, "ww" },
- /* A4 */
- { o2_loadMask22, "b" },
- { o2_unloadMask22, "b" },
- { 0, 0 },
- { 0, 0 },
- /* A8 */
- { 0, 0 },
- { o1_changeDataDisk, "b" }
- };
-
+/*! \todo: replace with script subsystem
+ */
+void setupOpcodes() {
+ static FWScriptInfo fw;
+ static OSScriptInfo os;
if (g_cine->getGameType() == Cine::GType_FW) {
- _opcodeTable = opcodeTableFW;
- _numOpcodes = ARRAYSIZE(opcodeTableFW);
+ scriptInfo = &fw;
} else {
- _opcodeTable = opcodeTableOS;
- _numOpcodes = ARRAYSIZE(opcodeTableOS);
+ scriptInfo = &os;
}
}
-byte getNextByte() {
- byte val = *(_currentScriptPtr + _currentPosition);
- _currentPosition++;
- return val;
-}
-
-uint16 getNextWord() {
- uint16 val = READ_BE_UINT16(_currentScriptPtr + _currentPosition);
- _currentPosition += 2;
- return val;
-}
-
-const char *getNextString() {
- const char *val = (const char *)(_currentScriptPtr + _currentPosition);
- _currentPosition += strlen(val) + 1;
- return val;
-}
-
-// empty array
+/*! \brief Allocate empty array
+ * \param len Size of array
+ *
+ * Explicit to prevent var=0 instead of var[i]=0 typos.
+ */
ScriptVars::ScriptVars(unsigned int len) : _size(len), _vars(new int16[len]) {
assert(_vars);
reset();
}
-// read game save, for later use
+/*! \brief Allocate array and read contents from savefile
+ * \param fHandle Savefile open for reading
+ * \param len Size of array
+ */
ScriptVars::ScriptVars(Common::InSaveFile &fHandle, unsigned int len)
: _size(len), _vars(new int16[len]) {
@@ -468,16 +459,21 @@
load(fHandle);
}
-// copy constructor
+/*! \brief Copy constructor
+ */
ScriptVars::ScriptVars(const ScriptVars &src) : _size(src._size), _vars(new int16[_size]) {
assert(_vars);
memcpy(_vars, src._vars, _size * sizeof(int16));
}
+/*! \brief Destructor
+ */
ScriptVars::~ScriptVars(void) {
delete[] _vars;
}
+/*! \brief Assignment operator
+ */
ScriptVars &ScriptVars::operator=(const ScriptVars &src) {
ScriptVars tmp(src);
int16 *tmpvars = _vars;
@@ -489,462 +485,708 @@
return *this;
}
-// array access
+/*! \brief Direct array item access
+ * \param idx Item index
+ * \return Reference to item
+ */
int16 &ScriptVars::operator[](unsigned int idx) {
- debugN(5, "assert(%d < %d)", idx, _size);
+ debug(6, "assert(%d < %d)", idx, _size);
assert(idx < _size);
return _vars[idx];
}
+/*! \brief Direct read-only array item access
+ * \param idx Item index
+ * \return Copy of item
+ */
int16 ScriptVars::operator[](unsigned int idx) const {
- debugN(5, "assert(%d < %d)\n", idx, _size);
+ debug(6, "assert(%d < %d)", idx, _size);
assert(idx < _size);
return _vars[idx];
}
-// dump to savefile
-void ScriptVars::save(Common::OutSaveFile &fHandle) {
+/*! \brief Savefile writer
+ * \param fHandle Savefile open for writing
+ */
+void ScriptVars::save(Common::OutSaveFile &fHandle) const {
save(fHandle, _size);
}
-// globalVars[255] is not written to savefiles...
-void ScriptVars::save(Common::OutSaveFile &fHandle, unsigned int len) {
- debugN(5, "assert(%d <= %d)\n", len, _size);
+/*! \brief Savefile writer with data length limit
+ * \param fHandle Savefile open for writing
+ * \param len Length of data to be written (len <= _size)
+ */
+void ScriptVars::save(Common::OutSaveFile &fHandle, unsigned int len) const {
+ debug(6, "assert(%d <= %d)", len, _size);
assert(len <= _size);
for (unsigned int i = 0; i < len; i++) {
fHandle.writeUint16BE(_vars[i]);
}
}
-// read from savefile
+/*! \brief Restore array from savefile
+ * \param fHandle Savefile open for reading
+ */
void ScriptVars::load(Common::InSaveFile &fHandle) {
load(fHandle, _size);
}
+/*! \brief Restore part of array from savefile
+ * \param fHandle Savefile open for reading
+ * \param len Length of data to be read
+ */
void ScriptVars::load(Common::InSaveFile &fHandle, unsigned int len) {
- debugN(5, "assert(%d <= %d)\n", len, _size);
+ debug(6, "assert(%d <= %d)", len, _size);
assert(len <= _size);
for (unsigned int i = 0; i < len; i++) {
_vars[i] = fHandle.readUint16BE();
}
}
+/*! \brief Reset all values to 0
+ */
void ScriptVars::reset(void) {
memset( _vars, 0, _size * sizeof(int16));
}
-void addGfxElementA0(int16 param1, int16 param2) {
- overlayHeadElement *currentHead = &overlayHead;
- overlayHeadElement *tempHead = currentHead;
- overlayHeadElement *newElement;
+/*! \brief Constructor for partial loading
+ * \param s Size of bytecode which will be added later
+ *
+ * This constructor _MUST_ be followed by setdata() method call before the
+ * instance can be used. It leaves the instance in partially invalid state.
+ */
+RawScript::RawScript(uint16 s) : _size(s), _data(NULL),
+ _labels(SCRIPT_STACK_SIZE) { }
- currentHead = tempHead->next;
+/*! \brief Complete constructor
+ * \param data Script bytecode
+ * \param s Bytecode length
+ */
+RawScript::RawScript(const FWScriptInfo &info, const byte *data, uint16 s) :
+ _size(s), _data(NULL), _labels(SCRIPT_STACK_SIZE) {
- while (currentHead) {
- if (objectTable[currentHead->objIdx].mask == objectTable[param1].mask) {
- if (currentHead->type == 2 || currentHead->objIdx == 3) {
- break;
- }
- }
+ setData(info, data);
+}
- tempHead = currentHead;
- currentHead = currentHead->next;
- }
+/*! \brief Copy constructor
+ */
+RawScript::RawScript(const RawScript &src) : _size(src._size),
+ _data(new byte[_size+1]), _labels(src._labels) {
- if (currentHead && currentHead->objIdx == param1 && currentHead->type == 20 && currentHead->x == param2)
- return;
-
- newElement = new overlayHeadElement;
-
- newElement->next = tempHead->next;
- tempHead->next = newElement;
-
- newElement->objIdx = param1;
- newElement->type = 20;
-
- newElement->x = param2;
- newElement->y = 0;
- newElement->width = 0;
- newElement->color = 0;
-
- if (!currentHead)
- currentHead = &overlayHead;
-
- newElement->previous = currentHead->previous;
-
- currentHead->previous = newElement;
+ assert(_data);
+ memcpy(_data, src._data, _size+1);
}
-void removeSeq(uint16 param1, uint16 param2, uint16 param3) {
- SeqListElement *currentHead = &seqList;
- SeqListElement *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;
- }
+/*! \brief Destructor
+ */
+RawScript::~RawScript(void) {
+ delete[] _data;
}
-uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) {
- SeqListElement *currentHead = &seqList;
- SeqListElement *tempHead = currentHead;
+/*! \brief Assignment operator
+ */
+RawScript &RawScript::operator=(const RawScript &src) {
+ assert(src._data);
+ byte *tmp = new byte[src._size+1];
- while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) {
- tempHead = currentHead;
- currentHead = tempHead->next;
- }
+ assert(tmp);
+ _labels = src._labels;
+ _size = src._size;
- if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) {
- return 1;
- }
+ delete[] _data;
+ _data = tmp;
+ memcpy(_data, src._data, _size);
+ _data[_size] = 0;
- return 0;
+ return *this;
}
-ScriptStruct scriptTable[NUM_MAX_SCRIPT];
+/*! \brief Get the next label in bytecode
+ * \param info Script info instance
+ * \param offset Starting offset
+ * \return Index of the next label in bytecode or _size on end of bytecode
+ *
+ * computeScriptStackSub replacement
+ */
+int RawScript::getNextLabel(const FWScriptInfo &info, int offset) const {
+ assert(_data);
+ int pos = offset;
-void stopGlobalScript(uint16 scriptIdx) {
- prcLinkedListStruct *currentHead = &globalScriptsHead;
- prcLinkedListStruct *tempHead = currentHead;
+ assert(pos >= 0);
- currentHead = tempHead->next;
+ while (pos < _size) {
+ uint8 opcode = _data[pos++];
+ const char *ptr = info.opcodeInfo(opcode);
- while (currentHead && (currentHead->scriptIdx != scriptIdx)) {
- tempHead = currentHead;
- currentHead = tempHead->next;
- }
-
- if (!currentHead) {
- return;
- }
-
- if (currentHead->scriptIdx != scriptIdx) {
- return;
- }
-
- currentHead->scriptIdx = -1;
-}
-
-uint16 computeScriptStackSub(bool computeAllLabels, byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, byte labelIndex, uint16 startOffset) {
- uint16 position;
-
- if (computeAllLabels) {
- for (int i = 0; i < SCRIPT_STACK_SIZE; i++) {
- stackPtr[i] = -1;
- }
- position = 0;
- } else {
- position = startOffset;
- }
- while (position < scriptSize) {
- uint8 opcode = scriptPtr[position];
- position++;
- if (opcode == 0 || opcode > _numOpcodes) {
+ if (!ptr) {
continue;
}
- if (!_opcodeTable[opcode - 1].args) {
- warning("Undefined opcode 0x%02X in computeScriptStackSub", opcode - 1);
- continue;
- }
- for (const char *p = _opcodeTable[opcode - 1].args; *p; ++p) {
- switch (*p) {
+
+ for (; *ptr; ++ptr) {
+ switch (*ptr) {
case 'b': // byte
- position++;
+ pos++;
break;
case 'w': // word
- position += 2;
+ pos += 2;
break;
case 'c': { // byte != 0 ? byte : word
- uint8 test = scriptPtr[position];
- position++;
+ uint8 test = _data[pos];
+ pos++;
if (test) {
- position++;
+ pos++;
} else {
- position += 2;
+ pos += 2;
}
}
break;
- case 'l': { // label
- uint8 index = scriptPtr[position];
- position++;
- if (computeAllLabels) {
- stackPtr[index] = position;
- } else {
- if (labelIndex == index) {
- return position;
- }
- }
- }
- break;
+ case 'l': // label
+ return pos;
case 's': // string
- while (scriptPtr[position++] != 0);
+ while (_data[pos++] != 0);
break;
case 'x': // exit script
- return position;
+ return -pos-1;
}
}
}
- return position;
+ return _size;
}
-void computeScriptStack(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize) {
- computeScriptStackSub(true, scriptPtr, stackPtr, scriptSize, 0, 0);
-}
+/*! \brief Calculate initial script labels
+ * \param info Script info instance
+ *
+ * computeScriptStack replacement
+ */
+void RawScript::computeLabels(const FWScriptInfo &info) {
+ assert(_data);
+ int pos = 0;
+ int i;
-uint16 computeScriptStackFromScript(byte *scriptPtr, uint16 currentPosition, uint16 labelIdx, uint16 scriptSize) {
- return computeScriptStackSub(false, scriptPtr, (int16 *)&dummyU16, (uint16)scriptSize, labelIdx, currentPosition);
+ // reset labels
+ for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
+ _labels[i] = -1;
+ }
+
+ // parse bytecode
+ while ((pos = getNextLabel(info, pos)) >= 0) {
+ i = _data[pos];
+ _labels[i] = ++pos;
+ }
}
-void palRotate(byte a, byte b, byte c) {
- if (c == 1) {
- uint16 currentColor = c_palette[b];
+/*! \brief find the next label from current position
+ * \param info Script info instance
+ * \param index Label index to look for
+ * \param offset Current position in script
+ * \return Position of next instruction following the label
+ *
+ * computeScriptStackFromScript replacement
+ */
+uint16 RawScript::getLabel(const FWScriptInfo &info, byte index, uint16 offset)
+ const {
- for (int16 i = b; i > a; i--) {
- c_palette[i] = c_palette[i - 1];
+ assert(_data);
+ int pos = offset;
+
+ while ((pos = getNextLabel(info, pos)) >= 0) {
+ if (_data[pos++] == index) {
+ return pos;
}
+ }
- c_palette[a] = currentColor;
- }
+ return -pos - 1;
}
-void addScriptToList0(uint16 idx) {
- uint16 i;
- prcLinkedListStruct *pNewElement;
- prcLinkedListStruct *currentHead = &globalScriptsHead;
- prcLinkedListStruct *tempHead = currentHead;
+/*! \brief Copy bytecode and calculate labels
+ * \param data Bytecode to copy, must be _size long
+ */
+void RawScript::setData(const FWScriptInfo &info, const byte *data) {
+ assert(!_data); // this function should be called only once per instance
+ _data = new byte[_size+1];
- assert(idx <= NUM_MAX_SCRIPT);
+ assert(data && _data);
+ memcpy(_data, data, _size * sizeof(byte));
+ _data[_size] = 0;
- currentHead = tempHead->next;
+ computeLabels(info);
+}
- while (currentHead) {
- tempHead = currentHead;
+/*! \brief Initial script labels
+ * \return Precalculated script labels
+ */
+const ScriptVars &RawScript::labels(void) const {
+ assert(_data);
+ return _labels;
+}
- assert(tempHead);
+/*! \brief One byte of bytecode
+ * \param pos Index in bytecode
+ * \return Byte from bytecode
+ */
+byte RawScript::getByte(unsigned int pos) const {
+ assert(_data && pos < _size);
- currentHead = tempHead->next;
- }
+ return _data[pos];
+}
- pNewElement = new prcLinkedListStruct;
+/*! \brief One word of bytecode
+ * \param pos Index of the first byte in bytecode
+ * \return Word of bytecode
+ */
+uint16 RawScript::getWord(unsigned int pos) const {
+ assert(_data && pos+1 < _size);
- assert(pNewElement);
+ return READ_BE_UINT16(_data + pos);
+}
- pNewElement->next = tempHead->next;
- tempHead->next = pNewElement;
+/*! \brief String in bytecode
+ * \param pos Index of the first char in string
+ * \return Pointer to part of bytecode
+ */
+const char *RawScript::getString(unsigned int pos) const {
+ assert(_data && pos < _size);
- // copy the stack into the script instance
- for (i = 0; i < SCRIPT_STACK_SIZE; i++) {
- pNewElement->stack[i] = scriptTable[idx].stack[i];
- }
+ return (const char*)(_data+pos);
+}
- pNewElement->compareResult = 0;
- pNewElement->scriptPosition = 0;
+/*! \brief Constructor for partial loading
+ * \param size Size of bytecode which will be added later
+ * \param p1 First object script parameter
+ * \param p2 Second object script parameter
+ * \param p3 Third object script parameter
+ *
+ * This constructor _MUST_ be followed by setdata() method call before the
+ * instance can be used. It leaves the instance in partially invalid state.
+ */
+RawObjectScript::RawObjectScript(uint16 s, uint16 p1, uint16 p2, uint16 p3)
+ : RawScript(s), _runCount(0), _param1(p1), _param2(p2), _param3(p3)
+{ }
- pNewElement->scriptPtr = scriptTable[idx].ptr;
- pNewElement->scriptIdx = idx;
+/*! \brief Complete constructor
+ * \param data Script bytecode
+ * \param s Bytecode length
+ * \param p1 First object script parameter
+ * \param p2 Second object script parameter
+ * \param p3 Third object script parameter
+ */
+RawObjectScript::RawObjectScript(const FWScriptInfo &info, const byte *data,
+ uint16 s, uint16 p1, uint16 p2, uint16 p3) : RawScript(info, data, s),
+ _runCount(0), _param1(p1), _param2(p2), _param3(p3) { }
+
+/*! \brief Contructor for global scripts
+ * \param script Script bytecode reference
+ * \param idx Script bytecode index
+ */
+FWScript::FWScript(const RawScript &script, int16 idx) : _script(script),
+ _pos(0), _line(0), _compare(0), _index(idx),
+ _labels(script.labels()), _localVars(LOCAL_VARS_SIZE),
+ _globalVars(globalVars), _info(new FWScriptInfo) { }
+
+/*! \brief Copy constructor
+ */
+FWScript::FWScript(const FWScript &src) : _script(src._script), _pos(src._pos),
+ _line(src._line), _compare(src._compare), _index(src._index),
+ _labels(src._labels), _localVars(src._localVars),
+ _globalVars(src._globalVars), _info(new FWScriptInfo) { }
+
+/*! \brief Contructor for global scripts in derived classes
+ * \param script Script bytecode reference
+ * \param idx Script bytecode index
+ */
+FWScript::FWScript(const RawScript &script, int16 idx, FWScriptInfo *info) :
+ _script(script), _pos(0), _line(0), _compare(0), _index(idx),
+ _labels(script.labels()), _localVars(LOCAL_VARS_SIZE),
+ _globalVars(globalVars), _info(info) { }
+
+/*! \brief Constructor for object scripts in derived classes
+ * \param script Script bytecode reference
+ * \param idx Script bytecode index
+ */
+FWScript::FWScript(RawObjectScript &script, int16 idx, FWScriptInfo *info) :
+ _script(script), _pos(0), _line(0), _compare(0), _index(idx),
+ _labels(script.labels()), _localVars(LOCAL_VARS_SIZE),
+ _globalVars(globalVars), _info(info) {
+
+ _localVars[0] = script.run();
}
-int16 endScript0(uint16 scriptIdx) {
- prcLinkedListStruct *currentHead = &globalScriptsHead;
- prcLinkedListStruct *tempHead = currentHead;
+/*! \brief Copy constructor for derived classes
+ */
+FWScript::FWScript(const FWScript &src, FWScriptInfo *info) :
+ _script(src._script), _pos(src._pos), _line(src._line),
+ _compare(src._compare), _index(src._index), _labels(src._labels),
+ _localVars(src._localVars), _globalVars(src._globalVars), _info(info) { }
- //assert(scriptIdx <= NUM_MAX_SCRIPT);
+FWScript::~FWScript(void) {
+ delete _info;
+}
- currentHead = tempHead->next;
+/*! \brief Read next byte from bytecode
+ * \return Byte from bytecode
+ */
+byte FWScript::getNextByte() {
+ byte val = _script.getByte(_pos);
+ _pos++;
+ return val;
+}
- while (currentHead && currentHead->scriptIdx != scriptIdx) {
- tempHead = currentHead;
- currentHead = tempHead->next;
- }
+/*! \brief Read next word from bytecode
+ * \return Word from bytecode
+ */
+uint16 FWScript::getNextWord() {
+ uint16 val = _script.getWord(_pos);
+ _pos += 2;
+ return val;
+}
- if (!currentHead) {
- return -1;
- }
+/*! \brief Read next string from bytecode
+ * \return Pointer to string
+ */
+const char *FWScript::getNextString() {
+ const char *val = _script.getString(_pos);
+ _pos += strlen(val) + 1;
+ return val;
+}
- if (currentHead->scriptIdx != scriptIdx) {
- return -1;
+/*! \brief Restore script state from savefile
+ * \param labels Restored script labels
+ * \param local Restored local script variables
+ * \param compare Restored last comparison result
+ * \param pos Restored script position
+ */
+void FWScript::load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) {
+ assert(pos < _script._size);
+ _labels = labels;
+ _localVars = local;
+ _compare = compare;
+ _pos = _line = pos;
+}
+
+/*! \brief Execute script
+ * \return <0 on script termination, >0 on script pause
+ *
+ * executeScript replacement.
+ * Instruction handler must return 0 if the script should continue or
+ * nonzero with the same meaning as return value of this function
+ */
+int FWScript::execute() {
+ int ret = 0;
+
+ while (!ret) {
+ _line = _pos;
+ byte opcode = getNextByte();
+ opFunc handler = _info->opcodeHandler(opcode);
+
+ if (handler) {
+ ret = (this->*handler)();
+ }
}
- currentHead->scriptIdx = -1;
+ return ret;
+}
- return 0;
+/*! \brief Save script to savefile
+ * \param fHandle Savefile handle
+ */
+void FWScript::save(Common::OutSaveFile &fHandle) const {
+ _labels.save(fHandle);
+ _localVars.save(fHandle);
+ fHandle.writeUint16BE(_compare);
+ fHandle.writeUint16BE(_pos);
+ // data order sucks...
+ fHandle.writeUint16BE(_index);
}
-int16 endScript1(uint16 scriptIdx) {
- prcLinkedListStruct *currentHead = &objScriptList;
- prcLinkedListStruct *tempHead = currentHead;
+/*! \brief Contructor for global scripts
+ * \param script Script bytecode reference
+ * \param idx Script bytecode index
+ */
+OSScript::OSScript(const RawScript &script, int16 idx) :
+ FWScript(script, idx, new OSScriptInfo) {}
- currentHead = tempHead->next;
+/*! \brief Constructor for object scripts
+ * \param script Script bytecode reference
+ * \param idx Script bytecode index
+ */
+OSScript::OSScript(RawObjectScript &script, int16 idx) :
+ FWScript(script, idx, new OSScriptInfo) {}
- while (currentHead && currentHead->scriptIdx != scriptIdx) {
- tempHead = currentHead;
- currentHead = tempHead->next;
- }
+/*! \brief Copy constructor
+ */
+OSScript::OSScript(const OSScript &src) : FWScript(src, new OSScriptInfo) {}
- if (!currentHead) {
- return -1;
+/*! \brief Restore script state from savefile
+ * \param labels Restored script labels
+ * \param local Restored local script variables
+ * \param compare Restored last comparison result
+ * \param pos Restored script position
+ */
+void OSScript::load(const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) {
+ FWScript::load(labels, local, compare, pos);
+}
+/*! \brief Get opcode info string
+ * \param opcode Opcode to look for in opcode table
+ */
+const char *FWScriptInfo::opcodeInfo(byte opcode) const {
+ if (opcode == 0 || opcode > FWScript::_numOpcodes) {
+ return NULL;
}
- if (currentHead->scriptIdx != scriptIdx) {
- return -1;
+ if (!FWScript::_opcodeTable[opcode - 1].args) {
+ warning("Undefined opcode 0x%02X in FWScriptInfo::opcodeInfo", opcode - 1);
+ return NULL;
}
- currentHead->scriptIdx = -1;
-
- return 0;
+ return FWScript::_opcodeTable[opcode - 1].args;
}
-int16 getZoneFromPosition(byte *page, int16 x, int16 y, int16 width) {
- byte *ptr = page + (y * width) + x / 2;
- byte zoneVar;
+/*! \brief Get opcode handler pointer
+ * \param opcode Opcode to look for in opcode table
+ */
+opFunc FWScriptInfo::opcodeHandler(byte opcode) const {
+ if (opcode == 0 || opcode > FWScript::_numOpcodes) {
+ return NULL;
+ }
- if (!(x % 2)) {
- zoneVar = (*(ptr) >> 4) & 0xF;
- } else {
- zoneVar = (*(ptr)) & 0xF;
+ if (!FWScript::_opcodeTable[opcode - 1].proc) {
+ warning("Undefined opcode 0x%02X in FWScriptInfo::opcodeHandler", opcode - 1);
+ return NULL;
}
- return zoneVar;
+ return FWScript::_opcodeTable[opcode - 1].proc;
}
-int16 getZoneFromPositionRaw(byte *page, int16 x, int16 y, int16 width) {
- byte *ptr = page + (y * width) + x;
- byte zoneVar;
+/*! \brief Create new FWScript instance
+ * \param script Script bytecode
+ * \param index Bytecode index
+ */
+FWScript *FWScriptInfo::create(const RawScript &script, int16 index) const {
+ return new FWScript(script, index);
+}
- zoneVar = (*(ptr)) & 0xF;
+/*! \brief Create new FWScript instance
+ * \param script Object script bytecode
+ * \param index Bytecode index
+ */
+FWScript *FWScriptInfo::create(const RawObjectScript &script, int16 index) const {
+ return new FWScript(script, index);
+}
- return zoneVar;
+/*! \brief Load saved FWScript instance
+ * \param script Script bytecode
+ * \param index Bytecode index
+ * \param local Local variables
+ * \param labels Script labels
+ * \param compare Last compare result
+ * \param pos Position in script
+ */
+FWScript *FWScriptInfo::create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const {
+ FWScript *tmp = new FWScript(script, index);
+ assert(tmp);
+ tmp->load(labels, local, compare, pos);
+ return tmp;
}
-int16 checkCollision(int16 objIdx, int16 x, int16 y, int16 numZones, int16 zoneIdx) {
- int16 lx = objectTable[objIdx].x + x;
- int16 ly = objectTable[objIdx].y + y;
- int16 idx;
+/*! \brief Load saved FWScript instance
+ * \param script Object script bytecode
+ * \param index Bytecode index
+ * \param local Local variables
+ * \param labels Script labels
+ * \param compare Last compare result
+ * \param pos Position in script
+ */
+FWScript *FWScriptInfo::create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const {
+ FWScript *tmp = new FWScript(script, index);
+ assert(tmp);
+ tmp->load(labels, local, compare, pos);
+ return tmp;
+}
- for (int16 i = 0; i < numZones; i++) {
- idx = getZoneFromPositionRaw(page3Raw, lx + i, ly, 320);
+/*! \brief Get opcode info string
+ * \param opcode Opcode to look for in opcode table
+ */
+const char *OSScriptInfo::opcodeInfo(byte opcode) const {
+ if (opcode == 0 || opcode > OSScript::_numOpcodes) {
+ return NULL;
+ }
- assert(idx >= 0 && idx <= NUM_MAX_ZONE);
-
- if (zoneData[idx] == zoneIdx) {
- return 1;
- }
+ if (!OSScript::_opcodeTable[opcode - 1].args) {
+ warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeInfo", opcode - 1);
+ return NULL;
}
- return 0;
+ return OSScript::_opcodeTable[opcode - 1].args;
}
-uint16 compareVars(int16 a, int16 b) {
- uint16 flag = 0;
+/*! \brief Get opcode handler pointer
+ * \param opcode Opcode to look for in opcode table
+ */
+opFunc OSScriptInfo::opcodeHandler(byte opcode) const {
+ if (opcode == 0 || opcode > OSScript::_numOpcodes) {
+ return NULL;
+ }
- if (a == b) {
- flag |= kCmpEQ;
- } else if (a > b) {
- flag |= kCmpGT;
- } else if (a < b) {
- flag |= kCmpLT;
+ if (!OSScript::_opcodeTable[opcode - 1].proc) {
+ warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeHandler", opcode - 1);
+ return NULL;
}
- return flag;
+ return OSScript::_opcodeTable[opcode - 1].proc;
}
+/*! \brief Create new OSScript instance
+ * \param script Script bytecode
+ * \param index Bytecode index
+ */
+FWScript *OSScriptInfo::create(const RawScript &script, int16 index) const {
+ return new OSScript(script, index);
+}
+
+/*! \brief Create new OSScript instance
+ * \param script Object script bytecode
+ * \param index Bytecode index
+ */
+FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index) const {
+ return new OSScript(script, index);
+}
+
+/*! \brief Load saved OSScript instance
+ * \param script Script bytecode
+ * \param index Bytecode index
+ * \param local Local variables
+ * \param labels Script labels
+ * \param compare Last compare result
+ * \param pos Position in script
+ */
+FWScript *OSScriptInfo::create(const RawScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const {
+ OSScript *tmp = new OSScript(script, index);
+ assert(tmp);
+ tmp->load(labels, local, compare, pos);
+ return tmp;
+}
+
+/*! \brief Load saved OSScript instance
+ * \param script Object script bytecode
+ * \param index Bytecode index
+ * \param local Local variables
+ * \param labels Script labels
+ * \param compare Last compare result
+ * \param pos Position in script
+ */
+FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index, const ScriptVars &labels, const ScriptVars &local, uint16 compare, uint16 pos) const {
+ OSScript *tmp = new OSScript(script, index);
+ assert(tmp);
+ tmp->load(labels, local, compare, pos);
+ return tmp;
+}
+
// ------------------------------------------------------------------------
// FUTURE WARS opcodes
// ------------------------------------------------------------------------
-void o1_modifyObjectParam() {
+int FWScript::o1_modifyObjectParam() {
byte objIdx = getNextByte();
byte paramIdx = getNextByte();
int16 newValue = getNextWord();
- debugC(5, kCineDebugScript, "Line: %d: modifyObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _currentLine, objIdx, paramIdx, newValue);
+ debugC(5, kCineDebugScript, "Line: %d: modifyObjectParam(objIdx:%d,paramIdx:%d,newValue:%d)", _line, objIdx, paramIdx, newValue);
modifyObjectParam(objIdx, paramIdx, newValue);
+ return 0;
}
-void o1_getObjectParam() {
+int FWScript::o1_getObjectParam() {
byte objIdx = getNextByte();
byte paramIdx = getNextByte();
byte newValue = getNextByte();
- debugC(5, kCineDebugScript, "Line: %d: getObjectParam(objIdx:%d,paramIdx:%d,var:%d)", _currentLine, objIdx, paramIdx, newValue);
+ debugC(5, kCineDebugScript, "Line: %d: getObjectParam(objIdx:%d,paramIdx:%d,var:%d)", _line, objIdx, paramIdx, newValue);
- _currentScriptElement->localVars[newValue] = getObjectParam(objIdx, paramIdx);
+ _localVars[newValue] = getObjectParam(objIdx, paramIdx);
+ return 0;
}
-void o1_addObjectParam() {
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list