mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 14:51:40 +00:00
Patch #1941066: "CinE sprite overlay rewrite" courtsey of next_ghost
svn-id: r31651
This commit is contained in:
parent
54485c24c5
commit
57a9ef3a8f
@ -186,7 +186,6 @@ static const AnimDataEntry transparencyData[] = {
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
@ -102,6 +102,7 @@ void freeAnimDataRange(byte startIdx, byte numIdx);
|
||||
void loadResource(const char *animName);
|
||||
void loadAbs(const char *resourceName, uint16 idx);
|
||||
void loadResourcesFromSave(Common::InSaveFile &fHandle, bool broken);
|
||||
void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency);
|
||||
|
||||
} // End of namespace Cine
|
||||
|
||||
|
@ -50,7 +50,7 @@ byte loadCt(const char *ctName) {
|
||||
uint16 bpp = READ_BE_UINT16(ptr); ptr += 2;
|
||||
if (bpp == 8) {
|
||||
ctColorMode = 1;
|
||||
memcpy(newPalette, ptr, 256*3);
|
||||
memcpy(newPalette, ptr, 256 * 3);
|
||||
ptr += 3 * 256;
|
||||
memcpy(page3Raw, ptr, 320 * 200);
|
||||
} else {
|
||||
@ -134,13 +134,11 @@ void addBackground(const char *bgName, uint16 bgIdx) {
|
||||
|
||||
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);
|
||||
memcpy(newPalette, ptr, 256 * 3);
|
||||
ptr += 3 * 256;
|
||||
memcpy(additionalBgTable[bgIdx], ptr, 320 * 200);
|
||||
} else {
|
||||
|
@ -77,7 +77,7 @@ void addToBGList(int16 objIdx, bool addList) {
|
||||
void addSpriteFilledToBGList(int16 objIdx, bool addList) {
|
||||
int16 x = objectTable[objIdx].x;
|
||||
int16 y = objectTable[objIdx].y;
|
||||
int16 width = animDataTable[objectTable[objIdx].frame]._width;
|
||||
int16 width = animDataTable[objectTable[objIdx].frame]._realWidth;
|
||||
int16 height = animDataTable[objectTable[objIdx].frame]._height;
|
||||
const byte *data = animDataTable[objectTable[objIdx].frame].data();
|
||||
|
||||
@ -86,11 +86,11 @@ void addSpriteFilledToBGList(int16 objIdx, bool addList) {
|
||||
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);
|
||||
gfxFillSprite(data, width, height, additionalBgTable[i], x, y);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gfxFillSprite(data, width / 2, height, page2Raw, x, y);
|
||||
gfxFillSprite(data, width, height, page2Raw, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,14 +129,12 @@ void CineEngine::initialize() {
|
||||
globalScripts.clear();
|
||||
bgIncrustList.clear();
|
||||
freeAnimDataTable();
|
||||
overlayList.clear();
|
||||
messageTable.clear();
|
||||
|
||||
memset(objectTable, 0, sizeof(objectTable));
|
||||
memset(messageTable, 0, sizeof(messageTable));
|
||||
|
||||
overlayHead.next = overlayHead.previous = NULL;
|
||||
|
||||
var8 = 0;
|
||||
// bgIncrustList = NULL;
|
||||
|
||||
var2 = var3 = var4 = var5 = 0;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "cine/cine.h"
|
||||
#include "cine/bg.h"
|
||||
#include "cine/bg_list.h"
|
||||
#include "cine/various.h"
|
||||
|
||||
#include "common/endian.h"
|
||||
@ -168,7 +169,7 @@ void gfxFillSprite(const byte *spritePtr, uint16 width, uint16 height, byte *pag
|
||||
byte *destPtr = page + x + y * 320;
|
||||
destPtr += i * 320;
|
||||
|
||||
for (j = 0; j < width * 8; j++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
if (x + j >= 0 && x + j < 320 && i + y >= 0
|
||||
&& i + y < 200) {
|
||||
if (!*(spritePtr++)) {
|
||||
@ -191,7 +192,7 @@ void gfxDrawMaskedSprite(const byte *spritePtr, const byte *maskPtr, uint16 widt
|
||||
byte *destPtr = page + x + y * 320;
|
||||
destPtr += i * 320;
|
||||
|
||||
for (j = 0; j < width * 8; j++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200 && *maskPtr == 0) {
|
||||
*destPtr = *spritePtr;
|
||||
}
|
||||
@ -202,61 +203,82 @@ void gfxDrawMaskedSprite(const byte *spritePtr, const byte *maskPtr, uint16 widt
|
||||
}
|
||||
}
|
||||
|
||||
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 gfxUpdateSpriteMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *srcMask, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight) {
|
||||
int16 i, j, d, spritePitch, maskPitch;
|
||||
|
||||
width *= 8;
|
||||
maskWidth *= 8;
|
||||
|
||||
spritePitch = width;
|
||||
maskPitch = maskWidth;
|
||||
|
||||
if (maskIdx == 0) {
|
||||
memcpy(bufferSprPtr, spritePtr, spritePitch * height);
|
||||
memcpy(bufferMskPtr, spriteMskPtr, spritePitch * height);
|
||||
}
|
||||
|
||||
if (ys > ym) {
|
||||
d = ys - ym;
|
||||
maskPtr += d * maskPitch;
|
||||
// crop update area to overlapping parts of masks
|
||||
if (y > ym) {
|
||||
d = y - ym;
|
||||
srcMask += d * maskPitch;
|
||||
maskHeight -= d;
|
||||
}
|
||||
if (maskHeight <= 0) {
|
||||
return;
|
||||
}
|
||||
if (xs > xm) {
|
||||
d = xs - xm;
|
||||
maskPtr += d;
|
||||
maskWidth -= d;
|
||||
}
|
||||
if (maskWidth <= 0) {
|
||||
return;
|
||||
}
|
||||
if (ys < ym) {
|
||||
d = ym - ys;
|
||||
spriteMskPtr += d * spritePitch;
|
||||
bufferMskPtr += d * spritePitch;
|
||||
} else if (y < ym) {
|
||||
d = ym - y;
|
||||
destMask += d * spritePitch;
|
||||
height -= d;
|
||||
}
|
||||
if (height <= 0) {
|
||||
return;
|
||||
}
|
||||
if (xs < xm) {
|
||||
d = xm - xs;
|
||||
spriteMskPtr += d;
|
||||
bufferMskPtr += d;
|
||||
|
||||
if (x > xm) {
|
||||
d = x - xm;
|
||||
srcMask += d;
|
||||
maskWidth -= d;
|
||||
} else if (x < xm) {
|
||||
d = xm - x;
|
||||
destMask += d;
|
||||
width -= d;
|
||||
}
|
||||
if (width <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update mask
|
||||
for (j = 0; j < MIN(maskHeight, height); ++j) {
|
||||
for (i = 0; i < MIN(maskWidth, width); ++i) {
|
||||
bufferMskPtr[i] |= maskPtr[i] ^ 1;
|
||||
destMask[i] |= srcMask[i] ^ 1;
|
||||
}
|
||||
bufferMskPtr += spritePitch;
|
||||
maskPtr += maskPitch;
|
||||
destMask += spritePitch;
|
||||
srcMask += maskPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void gfxUpdateIncrustMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *srcMask, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight) {
|
||||
int16 i, j, d, spritePitch, maskPitch;
|
||||
|
||||
spritePitch = width;
|
||||
maskPitch = maskWidth;
|
||||
|
||||
// crop update area to overlapping parts of masks
|
||||
if (y > ym) {
|
||||
d = y - ym;
|
||||
srcMask += d * maskPitch;
|
||||
maskHeight -= d;
|
||||
} else if (y < ym) {
|
||||
d = ym - y > height ? height : ym - y;
|
||||
memset(destMask, 1, d * spritePitch);
|
||||
destMask += d * spritePitch;
|
||||
height -= d;
|
||||
}
|
||||
|
||||
if (x > xm) {
|
||||
d = x - xm;
|
||||
xm = x;
|
||||
srcMask += d;
|
||||
maskWidth -= d;
|
||||
}
|
||||
|
||||
d = xm - x;
|
||||
maskWidth += d;
|
||||
|
||||
// update mask
|
||||
for (j = 0; j < MIN(maskHeight, height); ++j) {
|
||||
for (i = 0; i < width; ++i) {
|
||||
destMask[i] |= i < d || i >= maskWidth ? 1 : srcMask[i - d];
|
||||
}
|
||||
destMask += spritePitch;
|
||||
srcMask += maskPitch;
|
||||
}
|
||||
|
||||
if (j < height) {
|
||||
memset(destMask, 1, (height - j) * spritePitch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,15 +453,19 @@ void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 h
|
||||
|
||||
void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 height,
|
||||
byte *page, int16 x, int16 y) {
|
||||
int16 i, j;
|
||||
int16 i, j, tmpWidth, tmpHeight;
|
||||
Common::List<BGIncrust>::iterator it;
|
||||
byte *mask;
|
||||
const byte *backup = maskPtr;
|
||||
|
||||
// background pass
|
||||
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++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
if ((!maskPtr || !(*maskPtr)) && (x + j >= 0
|
||||
&& x + j < 320 && i + y >= 0 && i + y < 200)) {
|
||||
*destPtr = *srcPtr;
|
||||
@ -450,6 +476,27 @@ void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 he
|
||||
maskPtr++;
|
||||
}
|
||||
}
|
||||
|
||||
maskPtr = backup;
|
||||
|
||||
// incrust pass
|
||||
for (it = bgIncrustList.begin(); it != bgIncrustList.end(); ++it) {
|
||||
tmpWidth = animDataTable[it->frame]._realWidth;
|
||||
tmpHeight = animDataTable[it->frame]._height;
|
||||
mask = (byte*)malloc(tmpWidth * tmpHeight);
|
||||
|
||||
if (it->param == 0) {
|
||||
generateMask(animDataTable[it->frame].data(), mask, tmpWidth * tmpHeight, it->part);
|
||||
gfxUpdateIncrustMask(mask, it->x, it->y, tmpWidth, tmpHeight, maskPtr, x, y, width, height);
|
||||
gfxDrawMaskedSprite(animDataTable[it->frame].data(), mask, tmpWidth, tmpHeight, page, it->x, it->y);
|
||||
} else {
|
||||
memcpy(mask, animDataTable[it->frame].data(), tmpWidth * tmpHeight);
|
||||
gfxUpdateIncrustMask(mask, it->x, it->y, tmpWidth, tmpHeight, maskPtr, x, y, width, height);
|
||||
gfxFillSprite(mask, tmpWidth, tmpHeight, page, it->x, it->y);
|
||||
}
|
||||
|
||||
free(mask);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \todo Fix rendering to prevent fadein artifacts
|
||||
|
@ -53,8 +53,7 @@ void gfxFlipPage(void);
|
||||
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(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 gfxUpdateSpriteMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *maskPtr, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight);
|
||||
|
||||
void gfxDrawLine(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page);
|
||||
void gfxDrawPlainBox(int16 x1, int16 y1, int16 x2, int16 y2, byte color);
|
||||
|
@ -189,7 +189,6 @@ void CineEngine::mainLoop(int bootScriptIdx) {
|
||||
quitFlag = 0;
|
||||
|
||||
if (_preLoad == false) {
|
||||
resetMessageHead();
|
||||
resetSeqList();
|
||||
resetBgIncrustList();
|
||||
|
||||
@ -315,7 +314,6 @@ void CineEngine::mainLoop(int bootScriptIdx) {
|
||||
|
||||
hideMouse();
|
||||
g_sound->stopMusic();
|
||||
unloadAllMasks();
|
||||
// if (g_cine->getGameType() == Cine::GType_OS) {
|
||||
// freeUnkList();
|
||||
// }
|
||||
|
@ -14,7 +14,8 @@ MODULE_OBJS = \
|
||||
part.o \
|
||||
prc.o \
|
||||
rel.o \
|
||||
script.o \
|
||||
script_fw.o \
|
||||
script_os.o \
|
||||
sound.o \
|
||||
texte.o \
|
||||
unpack.o \
|
||||
|
@ -31,45 +31,32 @@
|
||||
|
||||
namespace Cine {
|
||||
|
||||
uint16 messageCount;
|
||||
Common::StringList messageTable;
|
||||
|
||||
void loadMsg(char *pMsgName) {
|
||||
uint16 i;
|
||||
int i, count, len;
|
||||
byte *ptr, *dataPtr;
|
||||
const char *messagePtr;
|
||||
|
||||
checkDataDisk(-1);
|
||||
|
||||
messageCount = 0;
|
||||
|
||||
for (i = 0; i < NUM_MAX_MESSAGE; i++) {
|
||||
messageTable[i].len = 0;
|
||||
if (messageTable[i].ptr) {
|
||||
free(messageTable[i].ptr);
|
||||
messageTable[i].ptr = NULL;
|
||||
}
|
||||
}
|
||||
messageTable.clear();
|
||||
|
||||
ptr = dataPtr = readBundleFile(findFileInBundle(pMsgName));
|
||||
|
||||
setMouseCursor(MOUSE_CURSOR_DISK);
|
||||
|
||||
messageCount = READ_BE_UINT16(ptr); ptr += 2;
|
||||
count = READ_BE_UINT16(ptr);
|
||||
ptr += 2;
|
||||
|
||||
assert(messageCount <= NUM_MAX_MESSAGE);
|
||||
messagePtr = (const char*)(ptr + 2 * count);
|
||||
|
||||
for (i = 0; i < messageCount; i++) {
|
||||
messageTable[i].len = READ_BE_UINT16(ptr); ptr += 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < messageCount; i++) {
|
||||
if (messageTable[i].len) {
|
||||
messageTable[i].ptr = (byte *) malloc(messageTable[i].len);
|
||||
|
||||
assert(messageTable[i].ptr);
|
||||
|
||||
memcpy(messageTable[i].ptr, ptr, messageTable[i].len);
|
||||
ptr += messageTable[i].len;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
len = READ_BE_UINT16(ptr);
|
||||
ptr += 2;
|
||||
|
||||
messageTable.push_back(messagePtr);
|
||||
messagePtr += len;
|
||||
}
|
||||
|
||||
free(dataPtr);
|
||||
|
@ -26,8 +26,14 @@
|
||||
#ifndef CINE_MSG_H
|
||||
#define CINE_MSG_H
|
||||
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Cine {
|
||||
|
||||
#define NUM_MAX_MESSAGE 255
|
||||
|
||||
extern Common::StringList messageTable;
|
||||
|
||||
void loadMsg(char *pMsgName);
|
||||
|
||||
} // End of namespace Cine
|
||||
|
@ -36,27 +36,7 @@
|
||||
namespace Cine {
|
||||
|
||||
objectStruct objectTable[NUM_MAX_OBJECT];
|
||||
ScriptVars globalVars(NUM_MAX_VAR);
|
||||
overlayHeadElement overlayHead;
|
||||
|
||||
void unloadAllMasks(void) {
|
||||
overlayHeadElement *current = overlayHead.next;
|
||||
|
||||
while (current) {
|
||||
overlayHeadElement *next = current->next;
|
||||
|
||||
delete current;
|
||||
|
||||
current = next;
|
||||
}
|
||||
|
||||
resetMessageHead();
|
||||
}
|
||||
|
||||
void resetMessageHead(void) {
|
||||
overlayHead.next = NULL;
|
||||
overlayHead.previous = NULL;
|
||||
}
|
||||
Common::List<overlay> overlayList;
|
||||
|
||||
void loadObject(char *pObjectName) {
|
||||
uint16 numEntry;
|
||||
@ -100,92 +80,88 @@ void loadObject(char *pObjectName) {
|
||||
free(dataPtr);
|
||||
}
|
||||
|
||||
int8 removeOverlayElement(uint16 objIdx, uint16 param) {
|
||||
overlayHeadElement *currentHeadPtr = &overlayHead;
|
||||
overlayHeadElement *tempHead = currentHeadPtr;
|
||||
overlayHeadElement *tempPtr2;
|
||||
/*! \brief Remove overlay sprite from the list
|
||||
* \param objIdx Remove overlay associated with this object
|
||||
* \param param Remove overlay of this type
|
||||
*/
|
||||
int removeOverlay(uint16 objIdx, uint16 param) {
|
||||
Common::List<overlay>::iterator it;
|
||||
|
||||
currentHeadPtr = tempHead->next;
|
||||
|
||||
while (currentHeadPtr && (currentHeadPtr->objIdx != objIdx || currentHeadPtr->type != param)) {
|
||||
tempHead = currentHeadPtr;
|
||||
currentHeadPtr = tempHead->next;
|
||||
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
||||
if (it->objIdx == objIdx && it->type == param) {
|
||||
overlayList.erase(it);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentHeadPtr || currentHeadPtr->objIdx != objIdx || currentHeadPtr->type != param) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tempHead->next = tempPtr2 = currentHeadPtr->next;
|
||||
|
||||
if (!tempPtr2) {
|
||||
tempPtr2 = &overlayHead;
|
||||
}
|
||||
|
||||
tempPtr2->previous = currentHeadPtr->previous;
|
||||
|
||||
delete currentHeadPtr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16 freeOverlay(uint16 objIdx, uint16 param) {
|
||||
overlayHeadElement *currentHeadPtr = overlayHead.next;
|
||||
overlayHeadElement *previousPtr = &overlayHead;
|
||||
overlayHeadElement *tempPtr2;
|
||||
/*! \brief Add new overlay sprite to the list
|
||||
* \param objIdx Associate the overlay with this object
|
||||
* \param param Type of new overlay
|
||||
* \todo Why are x, y, width and color left uninitialized?
|
||||
*/
|
||||
void addOverlay(uint16 objIdx, uint16 param) {
|
||||
Common::List<overlay>::iterator it;
|
||||
overlay tmp;
|
||||
|
||||
while (currentHeadPtr && ((currentHeadPtr->objIdx != objIdx) || (currentHeadPtr->type != param))) {
|
||||
previousPtr = currentHeadPtr;
|
||||
currentHeadPtr = previousPtr->next;
|
||||
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
||||
if (objectTable[it->objIdx].mask >= objectTable[objIdx].mask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentHeadPtr || !((currentHeadPtr->objIdx == objIdx) && (currentHeadPtr->type == param))) {
|
||||
return -1;
|
||||
}
|
||||
tmp.objIdx = objIdx;
|
||||
tmp.type = param;
|
||||
|
||||
previousPtr->next = tempPtr2 = currentHeadPtr->next;
|
||||
|
||||
if (!tempPtr2) {
|
||||
tempPtr2 = &overlayHead;
|
||||
}
|
||||
|
||||
tempPtr2->previous = currentHeadPtr->previous;
|
||||
|
||||
delete currentHeadPtr;
|
||||
return 0;
|
||||
overlayList.insert(it, tmp);
|
||||
}
|
||||
|
||||
void loadOverlayElement(uint16 objIdx, uint16 param) {
|
||||
overlayHeadElement *currentHeadPtr = &overlayHead;
|
||||
overlayHeadElement *pNewElement;
|
||||
/*! \brief Add new background mask overlay
|
||||
* \param objIdx Associate the overlay with this object
|
||||
* \param param source background index
|
||||
*/
|
||||
void addGfxElementA0(int16 objIdx, int16 param) {
|
||||
Common::List<overlay>::iterator it;
|
||||
overlay tmp;
|
||||
|
||||
uint16 si = objectTable[objIdx].mask;
|
||||
|
||||
overlayHeadElement *tempHead = currentHeadPtr;
|
||||
|
||||
currentHeadPtr = tempHead->next;
|
||||
|
||||
while (currentHeadPtr && (objectTable[currentHeadPtr->objIdx].mask < si)) {
|
||||
tempHead = currentHeadPtr;
|
||||
currentHeadPtr = tempHead->next;
|
||||
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
||||
// wtf?!
|
||||
if (objectTable[it->objIdx].mask == objectTable[objIdx].mask &&
|
||||
(it->type == 2 || it->type == 3)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pNewElement = new overlayHeadElement;
|
||||
|
||||
assert(pNewElement);
|
||||
|
||||
pNewElement->next = tempHead->next;
|
||||
tempHead->next = pNewElement;
|
||||
|
||||
pNewElement->objIdx = objIdx;
|
||||
pNewElement->type = param;
|
||||
|
||||
if (!currentHeadPtr) {
|
||||
currentHeadPtr = &overlayHead;
|
||||
if (it != overlayList.end() && it->objIdx == objIdx && it->type == 20 && it->x == param) {
|
||||
return;
|
||||
}
|
||||
|
||||
pNewElement->previous = currentHeadPtr->previous;
|
||||
currentHeadPtr->previous = pNewElement;
|
||||
tmp.objIdx = objIdx;
|
||||
tmp.type = 20;
|
||||
tmp.x = param;
|
||||
tmp.y = 0;
|
||||
tmp.width = 0;
|
||||
tmp.color = 0;
|
||||
|
||||
overlayList.insert(it, tmp);
|
||||
}
|
||||
|
||||
/*! \brief Remove background mask overlay
|
||||
* \param objIdx Remove overlay associated with this object
|
||||
* \param param Remove overlay using this background
|
||||
* \todo Check that it works
|
||||
*/
|
||||
void removeGfxElementA0(int16 objIdx, int16 param) {
|
||||
Common::List<overlay>::iterator it;
|
||||
|
||||
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
||||
if (it->objIdx == objIdx && it->type == 20 && it->x == param) {
|
||||
overlayList.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4) {
|
||||
@ -194,8 +170,8 @@ void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint1
|
||||
objectTable[objIdx].mask = param3;
|
||||
objectTable[objIdx].frame = param4;
|
||||
|
||||
if (!removeOverlayElement(objIdx, 0)) {
|
||||
loadOverlayElement(objIdx, 0);
|
||||
if (removeOverlay(objIdx, 0)) {
|
||||
addOverlay(objIdx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,8 +199,8 @@ void modifyObjectParam(byte objIdx, byte paramIdx, int16 newValue) {
|
||||
case 2:
|
||||
objectTable[objIdx].mask = newValue;
|
||||
|
||||
if (!removeOverlayElement(objIdx, 0)) {
|
||||
loadOverlayElement(objIdx, 0);
|
||||
if (removeOverlay(objIdx, 0)) {
|
||||
addOverlay(objIdx, 0);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
|
@ -40,9 +40,7 @@ struct objectStruct {
|
||||
uint16 part;
|
||||
};
|
||||
|
||||
struct overlayHeadElement {
|
||||
struct overlayHeadElement *next;
|
||||
struct overlayHeadElement *previous;
|
||||
struct overlay {
|
||||
uint16 objIdx;
|
||||
uint16 type;
|
||||
int16 x;
|
||||
@ -55,22 +53,19 @@ struct overlayHeadElement {
|
||||
#define NUM_MAX_VAR 256
|
||||
|
||||
extern objectStruct objectTable[NUM_MAX_OBJECT];
|
||||
extern ScriptVars globalVars;
|
||||
|
||||
extern overlayHeadElement overlayHead;
|
||||
|
||||
void unloadAllMasks(void);
|
||||
void resetMessageHead(void);
|
||||
extern Common::List<overlay> overlayList;
|
||||
|
||||
void loadObject(char *pObjectName);
|
||||
void setupObject(byte objIdx, uint16 param1, uint16 param2, uint16 param3, uint16 param4);
|
||||
void modifyObjectParam(byte objIdx, byte paramIdx, int16 newValue);
|
||||
|
||||
void loadOverlayElement(uint16 objIdx, uint16 param);
|
||||
int8 removeOverlayElement(uint16 objIdx, uint16 param);
|
||||
void addOverlay(uint16 objIdx, uint16 param);
|
||||
int removeOverlay(uint16 objIdx, uint16 param);
|
||||
void addGfxElementA0(int16 objIdx, int16 param);
|
||||
void removeGfxElementA0(int16 objIdx, int16 param);
|
||||
|
||||
int16 getObjectParam(uint16 objIdx, uint16 paramIdx);
|
||||
int16 freeOverlay(uint16 objIdx, uint16 param);
|
||||
|
||||
void addObjectParam(byte objIdx, byte paramIdx, int16 newValue);
|
||||
void subObjectParam(byte objIdx, byte paramIdx, int16 newValue);
|
||||
|
@ -358,6 +358,7 @@ typedef Common::Array<RawObjectScriptPtr> RawObjectScriptArray;
|
||||
|
||||
extern RawScriptArray scriptTable;
|
||||
extern FWScriptInfo *scriptInfo;
|
||||
extern ScriptVars globalVars;
|
||||
|
||||
void setupOpcodes();
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* Script interpreter file
|
||||
* Future Wars script interpreter file
|
||||
*/
|
||||
|
||||
#include "common/endian.h"
|
||||
@ -38,6 +38,8 @@
|
||||
|
||||
namespace Cine {
|
||||
|
||||
ScriptVars globalVars(NUM_MAX_VAR);
|
||||
|
||||
uint16 compareVars(int16 a, int16 b);
|
||||
void palRotate(byte a, byte b, byte c);
|
||||
void removeSeq(uint16 param1, uint16 param2, uint16 param3);
|
||||
@ -161,7 +163,7 @@ const Opcode FWScript::_opcodeTable[] = {
|
||||
{ &FWScript::o1_declareFunctionName, "s" },
|
||||
{ &FWScript::o1_freePartRange, "bb" },
|
||||
{ &FWScript::o1_unloadAllMasks, "" },
|
||||
// 5C */
|
||||
/* 5C */
|
||||
{ 0, 0 },
|
||||
{ 0, 0 },
|
||||
{ 0, 0 },
|
||||
@ -204,224 +206,6 @@ const Opcode FWScript::_opcodeTable[] = {
|
||||
};
|
||||
const unsigned int FWScript::_numOpcodes = ARRAYSIZE(FWScript::_opcodeTable);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
FWScriptInfo *scriptInfo; ///< Script factory
|
||||
RawScriptArray scriptTable; ///< Table of script bytecode
|
||||
|
||||
@ -898,33 +682,6 @@ void FWScript::save(Common::OutSaveFile &fHandle) const {
|
||||
fHandle.writeUint16BE(_index);
|
||||
}
|
||||
|
||||
/*! \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) {}
|
||||
|
||||
/*! \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) {}
|
||||
|
||||
/*! \brief Copy constructor
|
||||
*/
|
||||
OSScript::OSScript(const OSScript &src) : FWScript(src, new OSScriptInfo) {}
|
||||
|
||||
/*! \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
|
||||
*/
|
||||
@ -1003,84 +760,6 @@ FWScript *FWScriptInfo::create(const RawObjectScript &script, int16 index, const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*! \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;
|
||||
}
|
||||
|
||||
if (!OSScript::_opcodeTable[opcode - 1].args) {
|
||||
warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeInfo", opcode - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return OSScript::_opcodeTable[opcode - 1].args;
|
||||
}
|
||||
|
||||
/*! \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 (!OSScript::_opcodeTable[opcode - 1].proc) {
|
||||
warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeHandler", opcode - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
// ------------------------------------------------------------------------
|
||||
@ -1375,7 +1054,7 @@ int FWScript::o1_loadMask0() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addSpriteOverlay(%d)", _line, param);
|
||||
loadOverlayElement(param, 0);
|
||||
addOverlay(param, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1383,7 +1062,8 @@ int FWScript::o1_unloadMask0() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay(%d)", _line, param);
|
||||
freeOverlay(param, 0);
|
||||
removeOverlay(param, 0);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1399,7 +1079,7 @@ int FWScript::o1_loadMask1() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addOverlay1(%d)", _line, param);
|
||||
loadOverlayElement(param, 1);
|
||||
addOverlay(param, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1407,7 +1087,7 @@ int FWScript::o1_unloadMask1() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeOverlay1(%d)", _line, param);
|
||||
freeOverlay(param, 1);
|
||||
removeOverlay(param, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1415,7 +1095,7 @@ int FWScript::o1_loadMask4() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addOverlayType4(%d)", _line, param);
|
||||
loadOverlayElement(param, 4);
|
||||
addOverlay(param, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1423,7 +1103,7 @@ int FWScript::o1_unloadMask4() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeSpriteOverlay4(%d)", _line, param);
|
||||
freeOverlay(param, 4);
|
||||
removeOverlay(param, 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1825,7 +1505,7 @@ int FWScript::o1_freePartRange() {
|
||||
|
||||
int FWScript::o1_unloadAllMasks() {
|
||||
debugC(5, kCineDebugScript, "Line: %d: unloadAllMasks()", _line);
|
||||
unloadAllMasks();
|
||||
overlayList.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2034,7 +1714,7 @@ int FWScript::o1_loadMask5() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addOverlay5(%d)", _line, param);
|
||||
loadOverlayElement(param, 5);
|
||||
addOverlay(param, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2042,534 +1722,12 @@ int FWScript::o1_unloadMask5() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: freeOverlay5(%d)", _line, param);
|
||||
freeOverlay(param, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// OPERATION STEALTH opcodes
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
int FWScript::o2_loadPart() {
|
||||
const char *param = getNextString();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _line, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_playSample() {
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
// no-op in these versions
|
||||
getNextByte();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
getNextWord();
|
||||
return 0;
|
||||
}
|
||||
return o1_playSample();
|
||||
}
|
||||
|
||||
int FWScript::o2_playSampleAlt() {
|
||||
byte num = getNextByte();
|
||||
byte channel = getNextByte();
|
||||
uint16 frequency = getNextWord();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
uint16 size = getNextWord();
|
||||
|
||||
if (size == 0xFFFF) {
|
||||
size = animDataTable[num]._width * animDataTable[num]._height;
|
||||
}
|
||||
if (animDataTable[num].data()) {
|
||||
if (g_cine->getPlatform() == Common::kPlatformPC) {
|
||||
// if speaker output is available, play sound on it
|
||||
// if it's another device, don't play anything
|
||||
// TODO: implement this, it's used in the introduction for example
|
||||
// on each letter displayed
|
||||
} else {
|
||||
g_sound->playSound(channel, frequency, animDataTable[num].data(), size, 0, 0, 63, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_addSeqListElement() {
|
||||
byte param1 = getNextByte();
|
||||
byte param2 = getNextByte();
|
||||
byte param3 = getNextByte();
|
||||
byte param4 = getNextByte();
|
||||
uint16 param5 = getNextWord();
|
||||
uint16 param6 = getNextWord();
|
||||
uint16 param7 = getNextWord();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5, param6, param7);
|
||||
addSeqListElement(param1, 0, param2, param3, param4, param5, param6, 0, param7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_removeSeq() {
|
||||
byte a = getNextByte();
|
||||
byte b = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _line, a, b);
|
||||
removeSeq(a, 0, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op81() {
|
||||
warning("STUB: o2_op81()");
|
||||
// freeUnkList();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op82() {
|
||||
byte a = getNextByte();
|
||||
byte b = getNextByte();
|
||||
uint16 c = getNextWord();
|
||||
warning("STUB: o2_op82(%x, %x, %x)", a, b, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_isSeqRunning() {
|
||||
byte a = getNextByte();
|
||||
byte b = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: OP83(%d,%d) -> TODO", _line, a, b);
|
||||
|
||||
if (isSeqRunning(a, 0, b)) {
|
||||
_compare = 1;
|
||||
} else {
|
||||
_compare = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfSupNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare == kCmpGT) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfSupEquNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare & (kCmpGT | kCmpEQ)) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfInfNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare == kCmpLT) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfInfEquNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare & (kCmpLT | kCmpEQ)) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfEquNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare == kCmpEQ) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfDiffNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare != kCmpEQ) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_startObjectScript() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _line, param);
|
||||
runObjectScript(param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_stopObjectScript() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: stopObjectScript(%d)", _line, param);
|
||||
ScriptList::iterator it = objectScripts.begin();
|
||||
|
||||
for (; it != objectScripts.end(); ++it) {
|
||||
if ((*it)->_index == param) {
|
||||
(*it)->_index = -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op8D() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
uint16 c = getNextWord();
|
||||
uint16 d = getNextWord();
|
||||
uint16 e = getNextWord();
|
||||
uint16 f = getNextWord();
|
||||
uint16 g = getNextWord();
|
||||
uint16 h = getNextWord();
|
||||
warning("STUB: o2_op8D(%x, %x, %x, %x, %x, %x, %x, %x)", a, b, c, d, e, f, g, h);
|
||||
// _currentScriptElement->compareResult = ...
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_addBackground() {
|
||||
byte param1 = getNextByte();
|
||||
const char *param2 = getNextString();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _line, param2, param1);
|
||||
addBackground(param2, param1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_removeBackground() {
|
||||
byte param = getNextByte();
|
||||
|
||||
assert(param);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param);
|
||||
|
||||
if (additionalBgTable[param]) {
|
||||
free(additionalBgTable[param]);
|
||||
additionalBgTable[param] = NULL;
|
||||
}
|
||||
|
||||
if (currentAdditionalBgIdx == param) {
|
||||
currentAdditionalBgIdx = 0;
|
||||
}
|
||||
|
||||
if (currentAdditionalBgIdx2 == param) {
|
||||
currentAdditionalBgIdx2 = 0;
|
||||
}
|
||||
|
||||
strcpy(currentBgName[param], "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_loadAbs() {
|
||||
byte param1 = getNextByte();
|
||||
const char *param2 = getNextString();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _line, param1, param2);
|
||||
loadAbs(param2, param1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_loadBg() {
|
||||
byte param = getNextByte();
|
||||
|
||||
assert(param <= 8);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param);
|
||||
|
||||
if (additionalBgTable[param]) {
|
||||
currentAdditionalBgIdx = param;
|
||||
if (param == 8) {
|
||||
newColorMode = 3;
|
||||
} else {
|
||||
newColorMode = bgColorMode + 1;
|
||||
}
|
||||
//if (_screenNeedFadeOut == 0) {
|
||||
// adBgVar1 = 1;
|
||||
//}
|
||||
fadeRequired = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_wasZoneChecked() {
|
||||
warning("STUB: o2_wasZoneChecked()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op9B() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
uint16 c = getNextWord();
|
||||
uint16 d = getNextWord();
|
||||
uint16 e = getNextWord();
|
||||
uint16 f = getNextWord();
|
||||
uint16 g = getNextWord();
|
||||
uint16 h = getNextWord();
|
||||
warning("STUB: o2_op9B(%x, %x, %x, %x, %x, %x, %x, %x)", a, b, c, d, e, f, g, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op9C() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
uint16 c = getNextWord();
|
||||
uint16 d = getNextWord();
|
||||
warning("STUB: o2_op9C(%x, %x, %x, %x)", a, b, c, d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_useBgScroll() {
|
||||
byte param = getNextByte();
|
||||
|
||||
assert(param <= 8);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param);
|
||||
|
||||
if (additionalBgTable[param]) {
|
||||
currentAdditionalBgIdx2 = param;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_setAdditionalBgVScroll() {
|
||||
byte param1 = getNextByte();
|
||||
|
||||
if (param1) {
|
||||
byte param2 = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2);
|
||||
additionalBgVScroll = _localVars[param2];
|
||||
} else {
|
||||
uint16 param2 = getNextWord();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2);
|
||||
additionalBgVScroll = param2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op9F() {
|
||||
warning("o2_op9F()");
|
||||
getNextWord();
|
||||
getNextWord();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_addGfxElementA0() {
|
||||
uint16 param1 = getNextWord();
|
||||
uint16 param2 = getNextWord();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addGfxElementA0(%d,%d)", _line, param1, param2);
|
||||
addGfxElementA0(param1, param2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_removeGfxElementA0() {
|
||||
uint16 idx = getNextWord();
|
||||
uint16 param = getNextWord();
|
||||
warning("STUB? o2_removeGfxElementA0(%x, %x)", idx, param);
|
||||
removeGfxElementA0(idx, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_opA2() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
warning("STUB: o2_opA2(%x, %x)", a, b);
|
||||
// addGfxElementA2();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_opA3() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
warning("STUB: o2_opA3(%x, %x)", a, b);
|
||||
// removeGfxElementA2();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_loadMask22() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addOverlay22(%d)", _line, param);
|
||||
loadOverlayElement(param, 22);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_unloadMask22() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _line, param);
|
||||
freeOverlay(param, 22);
|
||||
removeOverlay(param, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void addGfxElementA0(int16 param1, int16 param2) {
|
||||
overlayHeadElement *currentHead = &overlayHead;
|
||||
overlayHeadElement *tempHead = currentHead;
|
||||
overlayHeadElement *newElement;
|
||||
|
||||
currentHead = tempHead->next;
|
||||
|
||||
while (currentHead) {
|
||||
if (objectTable[currentHead->objIdx].mask == objectTable[param1].mask) {
|
||||
if (currentHead->type == 2 || currentHead->objIdx == 3) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tempHead = currentHead;
|
||||
currentHead = currentHead->next;
|
||||
}
|
||||
|
||||
if (currentHead && currentHead->objIdx == param1 && currentHead->type == 20 && currentHead->x == param2)
|
||||
return;
|
||||
|
||||
newElement = 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;
|
||||
}
|
||||
|
||||
/*! \todo Check that it works
|
||||
*/
|
||||
void removeGfxElementA0(int16 idx, int16 param) {
|
||||
overlayHeadElement *parent = &overlayHead;
|
||||
overlayHeadElement *head = overlayHead.next;
|
||||
overlayHeadElement *tmp;
|
||||
|
||||
while (head) {
|
||||
if (head->objIdx == idx && head->x == param) {
|
||||
parent->next = head->next;
|
||||
tmp = head->next ? head->next : &overlayHead;
|
||||
tmp->previous = parent;
|
||||
delete head;
|
||||
return;
|
||||
}
|
||||
|
||||
parent = head;
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 isSeqRunning(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) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void palRotate(byte a, byte b, byte c) {
|
||||
if (c == 1) {
|
||||
uint16 currentColor = c_palette[b];
|
793
engines/cine/script_os.cpp
Normal file
793
engines/cine/script_os.cpp
Normal file
@ -0,0 +1,793 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* Operation Stealth script interpreter file
|
||||
*/
|
||||
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "cine/cine.h"
|
||||
#include "cine/bg_list.h"
|
||||
#include "cine/object.h"
|
||||
#include "cine/sound.h"
|
||||
#include "cine/various.h"
|
||||
#include "cine/script.h"
|
||||
|
||||
namespace Cine {
|
||||
|
||||
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);
|
||||
|
||||
/*! \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) {}
|
||||
|
||||
/*! \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) {}
|
||||
|
||||
/*! \brief Copy constructor
|
||||
*/
|
||||
OSScript::OSScript(const OSScript &src) : FWScript(src, new OSScriptInfo) {}
|
||||
|
||||
/*! \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 *OSScriptInfo::opcodeInfo(byte opcode) const {
|
||||
if (opcode == 0 || opcode > OSScript::_numOpcodes) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!OSScript::_opcodeTable[opcode - 1].args) {
|
||||
warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeInfo", opcode - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return OSScript::_opcodeTable[opcode - 1].args;
|
||||
}
|
||||
|
||||
/*! \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 (!OSScript::_opcodeTable[opcode - 1].proc) {
|
||||
warning("Undefined opcode 0x%02X in OSScriptInfo::opcodeHandler", opcode - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// OPERATION STEALTH opcodes
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
int FWScript::o2_loadPart() {
|
||||
const char *param = getNextString();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _line, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_playSample() {
|
||||
if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) {
|
||||
// no-op in these versions
|
||||
getNextByte();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
getNextWord();
|
||||
return 0;
|
||||
}
|
||||
return o1_playSample();
|
||||
}
|
||||
|
||||
int FWScript::o2_playSampleAlt() {
|
||||
byte num = getNextByte();
|
||||
byte channel = getNextByte();
|
||||
uint16 frequency = getNextWord();
|
||||
getNextByte();
|
||||
getNextWord();
|
||||
uint16 size = getNextWord();
|
||||
|
||||
if (size == 0xFFFF) {
|
||||
size = animDataTable[num]._width * animDataTable[num]._height;
|
||||
}
|
||||
if (animDataTable[num].data()) {
|
||||
if (g_cine->getPlatform() == Common::kPlatformPC) {
|
||||
// if speaker output is available, play sound on it
|
||||
// if it's another device, don't play anything
|
||||
// TODO: implement this, it's used in the introduction for example
|
||||
// on each letter displayed
|
||||
} else {
|
||||
g_sound->playSound(channel, frequency, animDataTable[num].data(), size, 0, 0, 63, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_addSeqListElement() {
|
||||
byte param1 = getNextByte();
|
||||
byte param2 = getNextByte();
|
||||
byte param3 = getNextByte();
|
||||
byte param4 = getNextByte();
|
||||
uint16 param5 = getNextWord();
|
||||
uint16 param6 = getNextWord();
|
||||
uint16 param7 = getNextWord();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addSeqListElement(%d,%d,%d,%d,%d,%d,%d)", _line, param1, param2, param3, param4, param5, param6, param7);
|
||||
addSeqListElement(param1, 0, param2, param3, param4, param5, param6, 0, param7);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_removeSeq() {
|
||||
byte a = getNextByte();
|
||||
byte b = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeSeq(%d,%d) -> TODO", _line, a, b);
|
||||
removeSeq(a, 0, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op81() {
|
||||
warning("STUB: o2_op81()");
|
||||
// freeUnkList();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op82() {
|
||||
byte a = getNextByte();
|
||||
byte b = getNextByte();
|
||||
uint16 c = getNextWord();
|
||||
warning("STUB: o2_op82(%x, %x, %x)", a, b, c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_isSeqRunning() {
|
||||
byte a = getNextByte();
|
||||
byte b = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: OP83(%d,%d) -> TODO", _line, a, b);
|
||||
|
||||
if (isSeqRunning(a, 0, b)) {
|
||||
_compare = 1;
|
||||
} else {
|
||||
_compare = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfSupNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare == kCmpGT) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfSupEquNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare & (kCmpGT | kCmpEQ)) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(>=) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfInfNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare == kCmpLT) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfInfEquNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare & (kCmpLT | kCmpEQ)) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(<=) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfEquNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare == kCmpEQ) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(==) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo The assert may produce false positives and requires testing
|
||||
*/
|
||||
int FWScript::o2_gotoIfDiffNearest() {
|
||||
byte labelIdx = getNextByte();
|
||||
|
||||
if (_compare != kCmpEQ) {
|
||||
assert(_labels[labelIdx] != -1);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (true)", _line, labelIdx);
|
||||
_pos = _script.getLabel(*_info, labelIdx, _pos);
|
||||
} else {
|
||||
debugC(5, kCineDebugScript, "Line: %d: if(!=) goto nearest %d (false)", _line, labelIdx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_startObjectScript() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: startObjectScript(%d)", _line, param);
|
||||
runObjectScript(param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_stopObjectScript() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: stopObjectScript(%d)", _line, param);
|
||||
ScriptList::iterator it = objectScripts.begin();
|
||||
|
||||
for (; it != objectScripts.end(); ++it) {
|
||||
if ((*it)->_index == param) {
|
||||
(*it)->_index = -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op8D() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
uint16 c = getNextWord();
|
||||
uint16 d = getNextWord();
|
||||
uint16 e = getNextWord();
|
||||
uint16 f = getNextWord();
|
||||
uint16 g = getNextWord();
|
||||
uint16 h = getNextWord();
|
||||
warning("STUB: o2_op8D(%x, %x, %x, %x, %x, %x, %x, %x)", a, b, c, d, e, f, g, h);
|
||||
// _currentScriptElement->compareResult = ...
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_addBackground() {
|
||||
byte param1 = getNextByte();
|
||||
const char *param2 = getNextString();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addBackground(%s,%d)", _line, param2, param1);
|
||||
addBackground(param2, param1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_removeBackground() {
|
||||
byte param = getNextByte();
|
||||
|
||||
assert(param);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param);
|
||||
|
||||
if (additionalBgTable[param]) {
|
||||
free(additionalBgTable[param]);
|
||||
additionalBgTable[param] = NULL;
|
||||
}
|
||||
|
||||
if (currentAdditionalBgIdx == param) {
|
||||
currentAdditionalBgIdx = 0;
|
||||
}
|
||||
|
||||
if (currentAdditionalBgIdx2 == param) {
|
||||
currentAdditionalBgIdx2 = 0;
|
||||
}
|
||||
|
||||
strcpy(currentBgName[param], "");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_loadAbs() {
|
||||
byte param1 = getNextByte();
|
||||
const char *param2 = getNextString();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: loadABS(%d,%s)", _line, param1, param2);
|
||||
loadAbs(param2, param1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_loadBg() {
|
||||
byte param = getNextByte();
|
||||
|
||||
assert(param <= 8);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param);
|
||||
|
||||
if (additionalBgTable[param]) {
|
||||
currentAdditionalBgIdx = param;
|
||||
if (param == 8) {
|
||||
newColorMode = 3;
|
||||
} else {
|
||||
newColorMode = bgColorMode + 1;
|
||||
}
|
||||
//if (_screenNeedFadeOut == 0) {
|
||||
// adBgVar1 = 1;
|
||||
//}
|
||||
fadeRequired = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_wasZoneChecked() {
|
||||
warning("STUB: o2_wasZoneChecked()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op9B() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
uint16 c = getNextWord();
|
||||
uint16 d = getNextWord();
|
||||
uint16 e = getNextWord();
|
||||
uint16 f = getNextWord();
|
||||
uint16 g = getNextWord();
|
||||
uint16 h = getNextWord();
|
||||
warning("STUB: o2_op9B(%x, %x, %x, %x, %x, %x, %x, %x)", a, b, c, d, e, f, g, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op9C() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
uint16 c = getNextWord();
|
||||
uint16 d = getNextWord();
|
||||
warning("STUB: o2_op9C(%x, %x, %x, %x)", a, b, c, d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_useBgScroll() {
|
||||
byte param = getNextByte();
|
||||
|
||||
assert(param <= 8);
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param);
|
||||
|
||||
if (additionalBgTable[param]) {
|
||||
currentAdditionalBgIdx2 = param;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_setAdditionalBgVScroll() {
|
||||
byte param1 = getNextByte();
|
||||
|
||||
if (param1) {
|
||||
byte param2 = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2);
|
||||
additionalBgVScroll = _localVars[param2];
|
||||
} else {
|
||||
uint16 param2 = getNextWord();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2);
|
||||
additionalBgVScroll = param2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_op9F() {
|
||||
warning("o2_op9F()");
|
||||
getNextWord();
|
||||
getNextWord();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_addGfxElementA0() {
|
||||
uint16 param1 = getNextWord();
|
||||
uint16 param2 = getNextWord();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addGfxElementA0(%d,%d)", _line, param1, param2);
|
||||
addGfxElementA0(param1, param2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_removeGfxElementA0() {
|
||||
uint16 idx = getNextWord();
|
||||
uint16 param = getNextWord();
|
||||
warning("STUB? o2_removeGfxElementA0(%x, %x)", idx, param);
|
||||
removeGfxElementA0(idx, param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_opA2() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
warning("STUB: o2_opA2(%x, %x)", a, b);
|
||||
// addGfxElementA2();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*! \todo Implement this instruction
|
||||
*/
|
||||
int FWScript::o2_opA3() {
|
||||
uint16 a = getNextWord();
|
||||
uint16 b = getNextWord();
|
||||
warning("STUB: o2_opA3(%x, %x)", a, b);
|
||||
// removeGfxElementA2();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_loadMask22() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: addOverlay22(%d)", _line, param);
|
||||
addOverlay(param, 22);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FWScript::o2_unloadMask22() {
|
||||
byte param = getNextByte();
|
||||
|
||||
debugC(5, kCineDebugScript, "Line: %d: removeOverlay22(%d)", _line, param);
|
||||
removeOverlay(param, 22);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // End of namespace Cine
|
@ -44,7 +44,7 @@ int16 commandVar3[4];
|
||||
int16 commandVar1;
|
||||
int16 commandVar2;
|
||||
|
||||
Message messageTable[NUM_MAX_MESSAGE];
|
||||
//Message messageTable[NUM_MAX_MESSAGE];
|
||||
|
||||
uint16 var2;
|
||||
uint16 var3;
|
||||
@ -130,32 +130,16 @@ void runObjectScript(int16 entryIdx) {
|
||||
objectScripts.push_back(tmp);
|
||||
}
|
||||
|
||||
/*! \brief Add action result message to overlay list
|
||||
* \param cmd Message description
|
||||
* \todo Why are x, y, width and color left uninitialized?
|
||||
*/
|
||||
void addPlayerCommandMessage(int16 cmd) {
|
||||
overlayHeadElement *currentHeadPtr = overlayHead.next;
|
||||
overlayHeadElement *tempHead = &overlayHead;
|
||||
overlayHeadElement *pNewElement;
|
||||
overlay tmp;
|
||||
tmp.objIdx = cmd;
|
||||
tmp.type = 3;
|
||||
|
||||
while (currentHeadPtr) {
|
||||
tempHead = currentHeadPtr;
|
||||
currentHeadPtr = tempHead->next;
|
||||
}
|
||||
|
||||
pNewElement = new overlayHeadElement;
|
||||
|
||||
assert(pNewElement);
|
||||
|
||||
pNewElement->next = tempHead->next;
|
||||
tempHead->next = pNewElement;
|
||||
|
||||
pNewElement->objIdx = cmd;
|
||||
pNewElement->type = 3;
|
||||
|
||||
if (!currentHeadPtr) {
|
||||
currentHeadPtr = &overlayHead;
|
||||
}
|
||||
|
||||
pNewElement->previous = currentHeadPtr->previous;
|
||||
currentHeadPtr->previous = pNewElement;
|
||||
overlayList.push_back(tmp);
|
||||
}
|
||||
|
||||
int16 getRelEntryForObject(uint16 param1, uint16 param2, SelectedObjStruct *pSelectedObject) {
|
||||
@ -180,55 +164,64 @@ int16 getRelEntryForObject(uint16 param1, uint16 param2, SelectedObjStruct *pSel
|
||||
return found;
|
||||
}
|
||||
|
||||
/*! \brief Find index of the object under cursor
|
||||
* \param x Mouse cursor coordinate
|
||||
* \param y Mouse cursor coordinate
|
||||
* \todo Fix displaced type 1 objects
|
||||
*/
|
||||
int16 getObjectUnderCursor(uint16 x, uint16 y) {
|
||||
overlayHeadElement *currentHead = overlayHead.previous;
|
||||
Common::List<overlay>::iterator it;
|
||||
|
||||
int16 objX, objY, frame, part, threshold, height, xdif, ydif;
|
||||
int width;
|
||||
|
||||
while (currentHead) {
|
||||
if (currentHead->type < 2) {
|
||||
if (objectTable[currentHead->objIdx].name[0]) {
|
||||
objX = objectTable[currentHead->objIdx].x;
|
||||
objY = objectTable[currentHead->objIdx].y;
|
||||
|
||||
frame = ABS((int16)(objectTable[currentHead->objIdx].frame));
|
||||
|
||||
part = objectTable[currentHead->objIdx].part;
|
||||
|
||||
if (currentHead->type == 0) {
|
||||
threshold = animDataTable[frame]._var1;
|
||||
} else {
|
||||
threshold = animDataTable[frame]._width / 2;
|
||||
}
|
||||
|
||||
height = animDataTable[frame]._height;
|
||||
width = animDataTable[frame]._realWidth;
|
||||
|
||||
xdif = x - objX;
|
||||
ydif = y - objY;
|
||||
|
||||
if ((xdif >= 0) && ((threshold << 4) > xdif) && (ydif > 0) && (ydif < height)) {
|
||||
if (animDataTable[frame].data()) {
|
||||
if (g_cine->getGameType() == Cine::GType_OS) {
|
||||
if(xdif < width && (currentHead->type == 1 || animDataTable[frame].getColor(xdif, ydif) != objectTable[currentHead->objIdx].part)) {
|
||||
return currentHead->objIdx;
|
||||
}
|
||||
} else if (currentHead->type == 0) { // use generated mask
|
||||
if (gfxGetBit(x - objX, y - objY, animDataTable[frame].mask(), animDataTable[frame]._width)) {
|
||||
return currentHead->objIdx;
|
||||
}
|
||||
} else if (currentHead->type == 1) { // is mask
|
||||
if (gfxGetBit(x - objX, y - objY, animDataTable[frame].data(), animDataTable[frame]._width * 4)) {
|
||||
return currentHead->objIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// reverse_iterator would be nice
|
||||
for (it = overlayList.reverse_begin(); it != overlayList.end(); --it) {
|
||||
if (it->type >= 2 || !objectTable[it->objIdx].name[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
currentHead = currentHead->previous;
|
||||
objX = objectTable[it->objIdx].x;
|
||||
objY = objectTable[it->objIdx].y;
|
||||
|
||||
frame = ABS((int16)(objectTable[it->objIdx].frame));
|
||||
part = objectTable[it->objIdx].part;
|
||||
|
||||
if (it->type == 0) {
|
||||
threshold = animDataTable[frame]._var1;
|
||||
} else {
|
||||
threshold = animDataTable[frame]._width / 2;
|
||||
}
|
||||
|
||||
height = animDataTable[frame]._height;
|
||||
width = animDataTable[frame]._realWidth;
|
||||
|
||||
xdif = x - objX;
|
||||
ydif = y - objY;
|
||||
|
||||
if ((xdif < 0) || ((threshold << 4) <= xdif) || (ydif < 0) || (ydif >= height) || !animDataTable[frame].data()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_cine->getGameType() == Cine::GType_OS) {
|
||||
if (xdif >= width) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (it->type == 0 && animDataTable[frame].getColor(xdif, ydif) != part) {
|
||||
return it->objIdx;
|
||||
} else if (it->type == 1 && gfxGetBit(xdif, ydif, animDataTable[frame].data(), animDataTable[frame]._width * 4)) {
|
||||
return it->objIdx;
|
||||
}
|
||||
} else if (it->type == 0) { // use generated mask
|
||||
if (gfxGetBit(xdif, ydif, animDataTable[frame].mask(), animDataTable[frame]._width)) {
|
||||
return it->objIdx;
|
||||
}
|
||||
} else if (it->type == 1) { // is mask
|
||||
if (gfxGetBit(xdif, ydif, animDataTable[frame].data(), animDataTable[frame]._width * 4)) {
|
||||
return it->objIdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -285,38 +278,23 @@ void loadScriptFromSave(Common::InSaveFile *fHandle, bool isGlobal) {
|
||||
}
|
||||
}
|
||||
|
||||
void loadOverlayFromSave(Common::InSaveFile *fHandle) {
|
||||
overlayHeadElement *newElement;
|
||||
overlayHeadElement *currentHead = &overlayHead;
|
||||
overlayHeadElement *tempHead = currentHead;
|
||||
/*! \brief Restore overlay sprites from savefile
|
||||
* \param fHandle Savefile open for reading
|
||||
*/
|
||||
void loadOverlayFromSave(Common::InSaveFile &fHandle) {
|
||||
overlay tmp;
|
||||
|
||||
currentHead = tempHead->next;
|
||||
fHandle.readUint32BE();
|
||||
fHandle.readUint32BE();
|
||||
|
||||
while (currentHead) {
|
||||
tempHead = currentHead;
|
||||
currentHead = tempHead->next;
|
||||
}
|
||||
tmp.objIdx = fHandle.readUint16BE();
|
||||
tmp.type = fHandle.readUint16BE();
|
||||
tmp.x = fHandle.readSint16BE();
|
||||
tmp.y = fHandle.readSint16BE();
|
||||
tmp.width = fHandle.readSint16BE();
|
||||
tmp.color = fHandle.readSint16BE();
|
||||
|
||||
newElement = new overlayHeadElement;
|
||||
|
||||
fHandle->readUint32BE();
|
||||
fHandle->readUint32BE();
|
||||
|
||||
newElement->objIdx = fHandle->readUint16BE();
|
||||
newElement->type = fHandle->readUint16BE();
|
||||
newElement->x = fHandle->readSint16BE();
|
||||
newElement->y = fHandle->readSint16BE();
|
||||
newElement->width = fHandle->readSint16BE();
|
||||
newElement->color = fHandle->readSint16BE();
|
||||
|
||||
newElement->next = tempHead->next;
|
||||
tempHead->next = newElement;
|
||||
|
||||
if (!currentHead)
|
||||
currentHead = &overlayHead;
|
||||
|
||||
newElement->previous = currentHead->previous;
|
||||
currentHead->previous = newElement;
|
||||
overlayList.push_back(tmp);
|
||||
}
|
||||
|
||||
/*! \brief Savefile format tester
|
||||
@ -433,7 +411,7 @@ bool CineEngine::makeLoad(char *saveName) {
|
||||
|
||||
g_sound->stopMusic();
|
||||
freeAnimDataTable();
|
||||
unloadAllMasks();
|
||||
overlayList.clear();
|
||||
// if (g_cine->getGameType() == Cine::GType_OS) {
|
||||
// freeUnkList();
|
||||
// }
|
||||
@ -444,15 +422,7 @@ bool CineEngine::makeLoad(char *saveName) {
|
||||
globalScripts.clear();
|
||||
relTable.clear();
|
||||
scriptTable.clear();
|
||||
|
||||
for (i = 0; i < NUM_MAX_MESSAGE; i++) {
|
||||
messageTable[i].len = 0;
|
||||
|
||||
if (messageTable[i].ptr) {
|
||||
free(messageTable[i].ptr);
|
||||
messageTable[i].ptr = NULL;
|
||||
}
|
||||
}
|
||||
messageTable.clear();
|
||||
|
||||
for (i = 0; i < NUM_MAX_OBJECT; i++) {
|
||||
objectTable[i].part = 0;
|
||||
@ -599,7 +569,7 @@ bool CineEngine::makeLoad(char *saveName) {
|
||||
|
||||
size = fHandle->readSint16BE();
|
||||
for (i = 0; i < size; i++) {
|
||||
loadOverlayFromSave(fHandle);
|
||||
loadOverlayFromSave(*fHandle);
|
||||
}
|
||||
|
||||
loadBgIncrustFromSave(*fHandle);
|
||||
@ -722,30 +692,19 @@ void makeSave(char *saveFileName) {
|
||||
}
|
||||
|
||||
{
|
||||
int16 numScript = 0;
|
||||
overlayHeadElement *currentHead = overlayHead.next;
|
||||
Common::List<overlay>::iterator it;
|
||||
|
||||
while (currentHead) {
|
||||
numScript++;
|
||||
currentHead = currentHead->next;
|
||||
}
|
||||
fHandle->writeUint16BE(overlayList.size());
|
||||
|
||||
fHandle->writeUint16BE(numScript);
|
||||
|
||||
// actual save
|
||||
currentHead = overlayHead.next;
|
||||
|
||||
while (currentHead) {
|
||||
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
||||
fHandle->writeUint32BE(0);
|
||||
fHandle->writeUint32BE(0);
|
||||
fHandle->writeUint16BE(currentHead->objIdx);
|
||||
fHandle->writeUint16BE(currentHead->type);
|
||||
fHandle->writeSint16BE(currentHead->x);
|
||||
fHandle->writeSint16BE(currentHead->y);
|
||||
fHandle->writeSint16BE(currentHead->width);
|
||||
fHandle->writeSint16BE(currentHead->color);
|
||||
|
||||
currentHead = currentHead->next;
|
||||
fHandle->writeUint16BE(it->objIdx);
|
||||
fHandle->writeUint16BE(it->type);
|
||||
fHandle->writeSint16BE(it->x);
|
||||
fHandle->writeSint16BE(it->y);
|
||||
fHandle->writeSint16BE(it->width);
|
||||
fHandle->writeSint16BE(it->color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,30 +721,6 @@ void makeSave(char *saveFileName) {
|
||||
fHandle->writeUint16BE(it->frame);
|
||||
fHandle->writeUint16BE(it->part);
|
||||
}
|
||||
/*
|
||||
int numBgIncrustList = 0;
|
||||
BGIncrustList *bgIncrustPtr = bgIncrustList;
|
||||
|
||||
while (bgIncrustPtr) {
|
||||
numBgIncrustList++;
|
||||
bgIncrustPtr = bgIncrustPtr->next;
|
||||
}
|
||||
|
||||
fHandle->writeUint16BE(numBgIncrustList);
|
||||
bgIncrustPtr = bgIncrustList;
|
||||
while (bgIncrustPtr) {
|
||||
fHandle->writeUint32BE(0); // next
|
||||
fHandle->writeUint32BE(0); // unkPtr
|
||||
fHandle->writeUint16BE(bgIncrustPtr->objIdx);
|
||||
fHandle->writeUint16BE(bgIncrustPtr->param);
|
||||
fHandle->writeUint16BE(bgIncrustPtr->x);
|
||||
fHandle->writeUint16BE(bgIncrustPtr->y);
|
||||
fHandle->writeUint16BE(bgIncrustPtr->frame);
|
||||
fHandle->writeUint16BE(bgIncrustPtr->part);
|
||||
|
||||
bgIncrustPtr = bgIncrustPtr->next;
|
||||
}
|
||||
*/
|
||||
|
||||
delete fHandle;
|
||||
|
||||
@ -1682,52 +1617,40 @@ uint16 executePlayerInput(void) {
|
||||
return var_5E;
|
||||
}
|
||||
|
||||
void drawSprite(overlayHeadElement *currentOverlay, const byte *spritePtr,
|
||||
const byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) {
|
||||
byte *ptr = NULL;
|
||||
void drawSprite(Common::List<overlay>::iterator it, const byte *spritePtr, const byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) {
|
||||
byte *msk = NULL;
|
||||
byte i = 0;
|
||||
uint16 si = 0;
|
||||
overlayHeadElement *pCurrentOverlay = currentOverlay;
|
||||
int16 maskX, maskY, maskWidth, maskHeight;
|
||||
uint16 maskSpriteIdx;
|
||||
|
||||
msk = (byte *)malloc(width * height);
|
||||
|
||||
if (g_cine->getGameType() == Cine::GType_OS) {
|
||||
drawSpriteRaw2(spritePtr, objectTable[currentOverlay->objIdx].part, width, height, page, x, y);
|
||||
return;
|
||||
generateMask(spritePtr, msk, width * height, objectTable[it->objIdx].part);
|
||||
} else {
|
||||
memcpy(msk, maskPtr, width * height);
|
||||
}
|
||||
|
||||
while (pCurrentOverlay) {
|
||||
if (pCurrentOverlay->type == 5) {
|
||||
if (!si) {
|
||||
ptr = (byte *)malloc(width * 8 * height);
|
||||
msk = (byte *)malloc(width * 8 * height);
|
||||
si = 1;
|
||||
}
|
||||
|
||||
maskX = objectTable[pCurrentOverlay->objIdx].x;
|
||||
maskY = objectTable[pCurrentOverlay->objIdx].y;
|
||||
|
||||
maskSpriteIdx = objectTable[pCurrentOverlay->objIdx].frame;
|
||||
|
||||
maskWidth = animDataTable[maskSpriteIdx]._width / 2;
|
||||
maskHeight = animDataTable[maskSpriteIdx]._height;
|
||||
gfxUpdateSpriteMask(spritePtr, maskPtr, width, height, animDataTable[maskSpriteIdx].data(), maskWidth, maskHeight, ptr, msk, x, y, maskX, maskY, i++);
|
||||
#ifdef DEBUG_SPRITE_MASK
|
||||
gfxFillSprite(animDataTable[maskSpriteIdx].data(), maskWidth, maskHeight, page, maskX, maskY, 1);
|
||||
#endif
|
||||
for (++it; it != overlayList.end(); ++it) {
|
||||
if (it->type != 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pCurrentOverlay = pCurrentOverlay->next;
|
||||
maskX = objectTable[it->objIdx].x;
|
||||
maskY = objectTable[it->objIdx].y;
|
||||
|
||||
maskSpriteIdx = ABS((int16)(objectTable[it->objIdx].frame));
|
||||
|
||||
maskWidth = animDataTable[maskSpriteIdx]._realWidth;
|
||||
maskHeight = animDataTable[maskSpriteIdx]._height;
|
||||
gfxUpdateSpriteMask(msk, x, y, width, height, animDataTable[maskSpriteIdx].data(), maskX, maskY, maskWidth, maskHeight);
|
||||
|
||||
#ifdef DEBUG_SPRITE_MASK
|
||||
gfxFillSprite(animDataTable[maskSpriteIdx].data(), maskWidth, maskHeight, page, maskX, maskY, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (si) {
|
||||
gfxDrawMaskedSprite(ptr, msk, width, height, page, x, y);
|
||||
free(ptr);
|
||||
free(msk);
|
||||
} else {
|
||||
gfxDrawMaskedSprite(spritePtr, maskPtr, width, height, page, x, y);
|
||||
}
|
||||
gfxDrawMaskedSprite(spritePtr, msk, width, height, page, x, y);
|
||||
free(msk);
|
||||
}
|
||||
|
||||
int16 additionalBgVScroll = 0;
|
||||
@ -1824,18 +1747,15 @@ void drawMessage(const char *messagePtr, int16 x, int16 y, int16 width, int16 co
|
||||
}
|
||||
|
||||
void drawDialogueMessage(byte msgIdx, int16 x, int16 y, int16 width, int16 color) {
|
||||
const char *messagePtr = (const char *)messageTable[msgIdx].ptr;
|
||||
|
||||
if (!messagePtr) {
|
||||
freeOverlay(msgIdx, 2);
|
||||
if (msgIdx >= messageTable.size()) {
|
||||
removeOverlay(msgIdx, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
_messageLen += strlen(messagePtr);
|
||||
_messageLen += messageTable[msgIdx].size();
|
||||
drawMessage(messageTable[msgIdx].c_str(), x, y, width, color);
|
||||
|
||||
drawMessage(messagePtr, x, y, width, color);
|
||||
|
||||
freeOverlay(msgIdx, 2);
|
||||
removeOverlay(msgIdx, 2);
|
||||
}
|
||||
|
||||
void drawFailureMessage(byte cmd) {
|
||||
@ -1857,161 +1777,129 @@ void drawFailureMessage(byte cmd) {
|
||||
|
||||
drawMessage(messagePtr, x, y, width, color);
|
||||
|
||||
freeOverlay(cmd, 3);
|
||||
removeOverlay(cmd, 3);
|
||||
}
|
||||
|
||||
/*! \todo Fix Operation Stealth logo in intro (the green text after the plane
|
||||
* takes off). Each letter should slowly grow top-down, it has something to
|
||||
* do with object 10 (some mask or something)
|
||||
*/
|
||||
void drawOverlays(void) {
|
||||
uint16 partVar1, partVar2;
|
||||
uint16 width, height;
|
||||
AnimData *pPart;
|
||||
overlayHeadElement *currentOverlay, *nextOverlay;
|
||||
int16 x, y;
|
||||
objectStruct *objPtr;
|
||||
byte messageIdx;
|
||||
int16 part;
|
||||
Common::List<overlay>::iterator it;
|
||||
|
||||
backupOverlayPage();
|
||||
|
||||
_messageLen = 0;
|
||||
|
||||
currentOverlay = (&overlayHead)->next;
|
||||
for (it = overlayList.begin(); it != overlayList.end(); ++it) {
|
||||
switch (it->type) {
|
||||
case 0: // sprite
|
||||
assert(it->objIdx < NUM_MAX_OBJECT);
|
||||
|
||||
while (currentOverlay) {
|
||||
nextOverlay = currentOverlay->next;
|
||||
objPtr = &objectTable[it->objIdx];
|
||||
x = objPtr->x;
|
||||
y = objPtr->y;
|
||||
|
||||
switch (currentOverlay->type) {
|
||||
case 0: // sprite
|
||||
{
|
||||
assert(currentOverlay->objIdx <= NUM_MAX_OBJECT);
|
||||
|
||||
objPtr = &objectTable[currentOverlay->objIdx];
|
||||
|
||||
x = objPtr->x;
|
||||
y = objPtr->y;
|
||||
|
||||
if (objPtr->frame >= 0) {
|
||||
if (g_cine->getGameType() == Cine::GType_OS) {
|
||||
pPart = &animDataTable[objPtr->frame];
|
||||
|
||||
partVar1 = pPart->_var1;
|
||||
partVar2 = pPart->_height;
|
||||
|
||||
if (pPart->data()) {
|
||||
// NOTE: is the mask supposed to be in data()? Shouldn't that be mask(), like below?
|
||||
// OS sprites don't use masks, see drawSprite() -- next_ghost
|
||||
drawSprite(currentOverlay, pPart->data(), pPart->data(), partVar1, partVar2, page1Raw, x, y);
|
||||
}
|
||||
} else {
|
||||
part = objPtr->part;
|
||||
|
||||
assert(part >= 0 && part <= NUM_MAX_ANIMDATA);
|
||||
|
||||
pPart = &animDataTable[objPtr->frame];
|
||||
|
||||
partVar1 = pPart->_var1;
|
||||
partVar2 = pPart->_height;
|
||||
|
||||
if (pPart->data()) {
|
||||
drawSprite(currentOverlay, pPart->data(), pPart->mask(), partVar1, partVar2, page1Raw, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (objPtr->frame < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pPart = &animDataTable[objPtr->frame];
|
||||
width = pPart->_realWidth;
|
||||
height = pPart->_height;
|
||||
|
||||
if (!pPart->data()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// drawSprite ignores masks of Operation Stealth sprites
|
||||
drawSprite(it, pPart->data(), pPart->mask(), width, height, page1Raw, x, y);
|
||||
break;
|
||||
|
||||
case 2: // text
|
||||
{
|
||||
// gfxWaitVSync();
|
||||
// hideMouse();
|
||||
// gfxWaitVSync();
|
||||
// hideMouse();
|
||||
|
||||
messageIdx = currentOverlay->objIdx;
|
||||
x = currentOverlay->x;
|
||||
y = currentOverlay->y;
|
||||
partVar1 = currentOverlay->width;
|
||||
partVar2 = currentOverlay->color;
|
||||
messageIdx = it->objIdx;
|
||||
x = it->x;
|
||||
y = it->y;
|
||||
width = it->width;
|
||||
height = it->color;
|
||||
|
||||
blitRawScreen(page1Raw);
|
||||
blitRawScreen(page1Raw);
|
||||
|
||||
drawDialogueMessage(messageIdx, x, y, partVar1, partVar2);
|
||||
drawDialogueMessage(messageIdx, x, y, width, height);
|
||||
|
||||
// blitScreen(page0, NULL);
|
||||
// gfxRedrawMouseCursor();
|
||||
// blitScreen(page0, NULL);
|
||||
// gfxRedrawMouseCursor();
|
||||
|
||||
waitForPlayerClick = 1;
|
||||
waitForPlayerClick = 1;
|
||||
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// gfxWaitSync()
|
||||
// hideMouse();
|
||||
// gfxWaitSync()
|
||||
// hideMouse();
|
||||
|
||||
blitRawScreen(page1Raw);
|
||||
blitRawScreen(page1Raw);
|
||||
|
||||
drawFailureMessage(currentOverlay->objIdx);
|
||||
drawFailureMessage(it->objIdx);
|
||||
|
||||
// blitScreen(page0, NULL);
|
||||
// gfxRedrawMouseCursor();
|
||||
// blitScreen(page0, NULL);
|
||||
// gfxRedrawMouseCursor();
|
||||
|
||||
waitForPlayerClick = 1;
|
||||
waitForPlayerClick = 1;
|
||||
|
||||
break;
|
||||
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
assert(currentOverlay->objIdx <= NUM_MAX_OBJECT);
|
||||
assert(it->objIdx < NUM_MAX_OBJECT);
|
||||
|
||||
objPtr = &objectTable[currentOverlay->objIdx];
|
||||
objPtr = &objectTable[it->objIdx];
|
||||
x = objPtr->x;
|
||||
y = objPtr->y;
|
||||
|
||||
x = objPtr->x;
|
||||
y = objPtr->y;
|
||||
|
||||
|
||||
if (objPtr->frame >= 0) {
|
||||
part = objPtr->part;
|
||||
|
||||
assert(part >= 0 && part <= NUM_MAX_ANIMDATA);
|
||||
|
||||
pPart = &animDataTable[objPtr->frame];
|
||||
|
||||
partVar1 = pPart->_width / 2;
|
||||
partVar2 = pPart->_height;
|
||||
|
||||
if (pPart->data()) {
|
||||
gfxFillSprite(pPart->data(), partVar1, partVar2, page1Raw, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (objPtr->frame < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(objPtr->frame < NUM_MAX_ANIMDATA);
|
||||
|
||||
pPart = &animDataTable[objPtr->frame];
|
||||
|
||||
width = pPart->_realWidth;
|
||||
height = pPart->_height;
|
||||
|
||||
if (!pPart->data()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gfxFillSprite(pPart->data(), width, height, page1Raw, x, y);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
{
|
||||
assert(currentOverlay->objIdx <= NUM_MAX_OBJECT);
|
||||
assert(it->objIdx < NUM_MAX_OBJECT);
|
||||
|
||||
objPtr = &objectTable[currentOverlay->objIdx];
|
||||
objPtr = &objectTable[it->objIdx];
|
||||
x = objPtr->x;
|
||||
y = objPtr->y;
|
||||
var5 = it->x;
|
||||
|
||||
x = objPtr->x;
|
||||
y = objPtr->y;
|
||||
|
||||
var5 = currentOverlay->x;
|
||||
|
||||
if (objPtr->frame >= 0 && var5 <= 8 && additionalBgTable[var5] && animDataTable[objPtr->frame]._bpp == 1) {
|
||||
int16 x2;
|
||||
int16 y2;
|
||||
|
||||
x2 = animDataTable[objPtr->frame]._width / 2;
|
||||
y2 = animDataTable[objPtr->frame]._height;
|
||||
|
||||
if (animDataTable[objPtr->frame].data()) {
|
||||
maskBgOverlay(additionalBgTable[var5], animDataTable[objPtr->frame].data(), x2, y2, page1Raw, x, y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (objPtr->frame < 0 || var5 > 8 || !additionalBgTable[var5] || animDataTable[objPtr->frame]._bpp != 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
currentOverlay = nextOverlay;
|
||||
width = animDataTable[objPtr->frame]._realWidth;
|
||||
height = animDataTable[objPtr->frame]._height;
|
||||
|
||||
if (!animDataTable[objPtr->frame].data()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
maskBgOverlay(additionalBgTable[var5], animDataTable[objPtr->frame].data(), width, height, page1Raw, x, y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2040,8 +1928,7 @@ void checkForPendingDataLoad(void) {
|
||||
}
|
||||
|
||||
if (newObjectName[0] != 0) {
|
||||
unloadAllMasks();
|
||||
resetMessageHead();
|
||||
overlayList.clear();
|
||||
|
||||
loadObject(newObjectName);
|
||||
|
||||
@ -2071,39 +1958,49 @@ void removeExtention(char *dest, const char *source) {
|
||||
}
|
||||
|
||||
void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5) {
|
||||
overlayHeadElement *currentHead = &overlayHead;
|
||||
overlayHeadElement *tempHead = currentHead;
|
||||
overlayHeadElement *newElement;
|
||||
overlay tmp;
|
||||
|
||||
currentHead = tempHead->next;
|
||||
tmp.objIdx = param1;
|
||||
tmp.type = 2;
|
||||
tmp.x = param2;
|
||||
tmp.y = param3;
|
||||
tmp.width = param4;
|
||||
tmp.color = param5;
|
||||
|
||||
while (currentHead) {
|
||||
overlayList.push_back(tmp);
|
||||
}
|
||||
|
||||
SeqListElement seqList;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
newElement = new overlayHeadElement;
|
||||
|
||||
newElement->next = tempHead->next;
|
||||
tempHead->next = newElement;
|
||||
|
||||
newElement->objIdx = param1;
|
||||
newElement->type = 2;
|
||||
|
||||
newElement->x = param2;
|
||||
newElement->y = param3;
|
||||
newElement->width = param4;
|
||||
newElement->color = param5;
|
||||
|
||||
if (!currentHead)
|
||||
currentHead = &overlayHead;
|
||||
|
||||
newElement->previous = currentHead->previous;
|
||||
|
||||
currentHead->previous = newElement;
|
||||
if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) {
|
||||
currentHead->var4 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
SeqListElement seqList;
|
||||
uint16 isSeqRunning(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) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8) {
|
||||
SeqListElement *currentHead = &seqList;
|
||||
|
@ -42,15 +42,6 @@ void makeActionMenu(void);
|
||||
extern bool disableSystemMenu;
|
||||
extern bool inMenu;
|
||||
|
||||
struct Message {
|
||||
byte *ptr;
|
||||
uint16 len;
|
||||
};
|
||||
|
||||
#define NUM_MAX_MESSAGE 255
|
||||
|
||||
extern Message messageTable[NUM_MAX_MESSAGE];
|
||||
|
||||
struct SeqListElement {
|
||||
struct SeqListElement *next;
|
||||
int16 var4;
|
||||
@ -149,6 +140,8 @@ void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 par
|
||||
|
||||
extern int16 additionalBgVScroll;
|
||||
|
||||
void removeSeq(uint16 param1, uint16 param2, uint16 param3);
|
||||
uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3);
|
||||
void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8);
|
||||
void resetSeqList();
|
||||
void processSeqList(void);
|
||||
|
@ -144,3 +144,10 @@ bg_list.cpp
|
||||
reincrustAllBg() - removed (obsoleted by new loadResourcesFromSave() and
|
||||
loadBgIncrustFromSave() implementation)
|
||||
freeBgIncrustList() - removed (obsoleted by Common::List::clear())
|
||||
|
||||
object.cpp
|
||||
unloadAllMasks() - removed (obsoleted by Common::List::clear())
|
||||
resetMessageHead() - removed (obsoleted by Common::List)
|
||||
freeOverlay() - removed (duplicate of removeOverlay)
|
||||
removeOverlayElement() - renamed to removeOverlay
|
||||
loadOverlayElement() - renamed to addOverlay
|
||||
|
Loading…
x
Reference in New Issue
Block a user