mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-29 05:03:29 +00:00
2004 lines
34 KiB
C++
2004 lines
34 KiB
C++
/* 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.
|
|
*
|
|
*/
|
|
|
|
#include "cruise/cruise.h"
|
|
#include "cruise/cruise_main.h"
|
|
#include "cruise/cell.h"
|
|
#include "cruise/sound.h"
|
|
#include "cruise/staticres.h"
|
|
|
|
#include "common/textconsole.h"
|
|
#include "common/util.h"
|
|
|
|
namespace Cruise {
|
|
|
|
uint32 Period(uint32 hz) {
|
|
return ((uint32)(100000000L / ((uint32)hz * 28L)));
|
|
}
|
|
|
|
//#define FUNCTION_DEBUG
|
|
|
|
int16 Op_LoadOverlay() {
|
|
char *pOverlayName;
|
|
char overlayName[38] = "";
|
|
int overlayLoadResult;
|
|
|
|
pOverlayName = (char *)popPtr();
|
|
|
|
if (strlen(pOverlayName) == 0)
|
|
return 0;
|
|
|
|
strcpy(overlayName, pOverlayName);
|
|
strToUpper(overlayName);
|
|
|
|
//gfxModuleData.field_84();
|
|
//gfxModuleData.field_84();
|
|
|
|
overlayLoadResult = loadOverlay(overlayName);
|
|
|
|
updateAllScriptsImports();
|
|
|
|
Common::strlcpy(nextOverlay, overlayName, sizeof(nextOverlay));
|
|
|
|
return overlayLoadResult;
|
|
}
|
|
|
|
int16 Op_Strcpy() {
|
|
char *ptr1 = (char *)popPtr();
|
|
char *ptr2 = (char *)popPtr();
|
|
|
|
while (*ptr1) {
|
|
*ptr2 = *ptr1;
|
|
|
|
ptr2++;
|
|
ptr1++;
|
|
}
|
|
|
|
*ptr2 = 0;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_Exec() {
|
|
int scriptIdx;
|
|
int ovlIdx;
|
|
uint8 *ptr;
|
|
uint8 *ptr2;
|
|
int16 popTable[200];
|
|
|
|
int numOfArgToPop = popVar();
|
|
|
|
for (int i = 0; i < numOfArgToPop; i++) {
|
|
popTable[numOfArgToPop - i - 1] = popVar();
|
|
}
|
|
|
|
scriptIdx = popVar();
|
|
ovlIdx = popVar();
|
|
|
|
if (!ovlIdx) {
|
|
ovlIdx = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
ptr = attacheNewScriptToTail(&procHead, ovlIdx, scriptIdx, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_MinusPROC);
|
|
|
|
if (!ptr)
|
|
return (0);
|
|
|
|
if (numOfArgToPop <= 0) {
|
|
return (0);
|
|
}
|
|
|
|
ptr2 = ptr;
|
|
|
|
for (int i = 0; i < numOfArgToPop; i++) {
|
|
WRITE_BE_UINT16(ptr2, popTable[i]);
|
|
ptr2 += 2;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_AddProc() {
|
|
int pop1 = popVar();
|
|
int pop2;
|
|
int overlay;
|
|
int param[160];
|
|
|
|
for (long int i = 0; i < pop1; i++) {
|
|
param[i] = popVar();
|
|
}
|
|
|
|
pop2 = popVar();
|
|
overlay = popVar();
|
|
|
|
if (!overlay)
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
|
|
if (!overlay)
|
|
return (0);
|
|
|
|
uint8* procBss = attacheNewScriptToTail(&procHead, overlay, pop2, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_PROC);
|
|
|
|
if (procBss) {
|
|
for (long int i = 0; i < pop1; i++) {
|
|
int16* ptr = (int16 *)(procBss + i * 2);
|
|
*ptr = param[i];
|
|
bigEndianShortToNative(ptr);
|
|
}
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_Narrator() {
|
|
int pop1 = popVar();
|
|
int pop2 = popVar();
|
|
|
|
if (!pop2)
|
|
pop2 = currentScriptPtr->overlayNumber;
|
|
|
|
narratorOvl = pop2;
|
|
narratorIdx = pop1;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_GetMouseX() {
|
|
int16 dummy;
|
|
int16 mouseX;
|
|
int16 mouseY;
|
|
int16 mouseButton;
|
|
|
|
getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);
|
|
|
|
return (mouseX);
|
|
}
|
|
|
|
int16 Op_GetMouseY() {
|
|
int16 dummy;
|
|
int16 mouseX;
|
|
int16 mouseY;
|
|
int16 mouseButton;
|
|
|
|
getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);
|
|
|
|
return (mouseY);
|
|
}
|
|
|
|
int16 Op_Random() {
|
|
int var = popVar();
|
|
|
|
if (var < 2) {
|
|
return (0);
|
|
}
|
|
|
|
return (_vm->_rnd.getRandomNumber(var - 1));
|
|
}
|
|
|
|
int16 Op_PlayFX() {
|
|
int volume = popVar();
|
|
|
|
#if 0
|
|
int speed = popVar();
|
|
int channelNum = popVar();
|
|
#else
|
|
popVar();
|
|
popVar();
|
|
#endif
|
|
|
|
int sampleNum = popVar();
|
|
|
|
if ((sampleNum >= 0) && (sampleNum < NUM_FILE_ENTRIES) && (filesDatabase[sampleNum].subData.ptr)) {
|
|
#if 0
|
|
if (speed == -1)
|
|
speed = filesDatabase[sampleNum].subData.transparency;
|
|
#endif
|
|
|
|
_vm->sound().playSound(filesDatabase[sampleNum].subData.ptr,
|
|
filesDatabase[sampleNum].width, volume);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_LoopFX() {
|
|
int volume = popVar();
|
|
|
|
#if 0
|
|
int speed = popVar();
|
|
int channelNum = popVar();
|
|
#else
|
|
popVar();
|
|
popVar();
|
|
#endif
|
|
|
|
int sampleNum = popVar();
|
|
|
|
if ((sampleNum >= 0) && (sampleNum < NUM_FILE_ENTRIES) && (filesDatabase[sampleNum].subData.ptr)) {
|
|
|
|
#if 0
|
|
if (speed == -1)
|
|
speed = filesDatabase[sampleNum].subData.transparency;
|
|
#endif
|
|
|
|
_vm->sound().playSound(filesDatabase[sampleNum].subData.ptr,
|
|
filesDatabase[sampleNum].width, volume);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_StopFX() {
|
|
int channelNum = popVar();
|
|
|
|
if (channelNum == -1) {
|
|
_vm->sound().stopChannel(0);
|
|
_vm->sound().stopChannel(1);
|
|
_vm->sound().stopChannel(2);
|
|
_vm->sound().stopChannel(3);
|
|
} else {
|
|
_vm->sound().stopChannel(channelNum);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FreqFX() {
|
|
int volume = popVar();
|
|
int freq2 = popVar();
|
|
int channelNum = popVar();
|
|
int sampleNum = popVar();
|
|
|
|
if ((sampleNum >= 0) && (sampleNum < NUM_FILE_ENTRIES) && (filesDatabase[sampleNum].subData.ptr)) {
|
|
int freq = Period(freq2 * 1000);
|
|
|
|
_vm->sound().startNote(channelNum, volume, freq);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_FreeCT() {
|
|
freeCTP();
|
|
return (0);
|
|
}
|
|
|
|
void freeObjectList(cellStruct *pListHead) {
|
|
int var_2 = 0;
|
|
cellStruct *pCurrent = pListHead->next;
|
|
|
|
while (pCurrent) {
|
|
cellStruct *pNext = pCurrent->next;
|
|
|
|
if (pCurrent->freeze == 0) {
|
|
if (pCurrent->gfxPtr)
|
|
freeGfx(pCurrent->gfxPtr);
|
|
MemFree(pCurrent);
|
|
}
|
|
|
|
var_2 = 1;
|
|
|
|
pCurrent = pNext;
|
|
}
|
|
|
|
if (var_2) {
|
|
resetPtr(pListHead);
|
|
}
|
|
}
|
|
|
|
int16 Op_FreeCell() {
|
|
freeObjectList(&cellHead);
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_freeBackgroundInscrustList() {
|
|
freeBackgroundIncrustList(&backgroundIncrustHead);
|
|
return (0);
|
|
}
|
|
|
|
|
|
int16 Op_UnmergeBackgroundIncrust() {
|
|
int obj = popVar();
|
|
int ovl = popVar();
|
|
|
|
if (!ovl) {
|
|
ovl = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
unmergeBackgroundIncrust(&backgroundIncrustHead, ovl, obj);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_FreePreload() {
|
|
// TODO: See if this is needed
|
|
debug(1, "Op_FreePreload not implemented");
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_RemoveMessage() {
|
|
int idx;
|
|
int overlay;
|
|
|
|
idx = popVar();
|
|
overlay = popVar();
|
|
|
|
if (!overlay) {
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
removeCell(&cellHead, overlay, idx, 5, masterScreen);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_FindSet() {
|
|
char *ptr = (char *) popPtr();
|
|
if (!ptr)
|
|
return -1;
|
|
|
|
char name[36] = "";
|
|
Common::strlcpy(name, ptr, sizeof(name));
|
|
strToUpper(name);
|
|
|
|
for (int i = 0; i < NUM_FILE_ENTRIES; i++) {
|
|
if (!strcmp(name, filesDatabase[i].subData.name)) {
|
|
return (i);
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int16 Op_RemoveFrame() {
|
|
int count = popVar();
|
|
int start = popVar();
|
|
|
|
resetFileEntryRange(start, count);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_comment() {
|
|
char *var;
|
|
|
|
var = (char *)popPtr();
|
|
|
|
debug(1, "COMMENT: \"%s\"", var);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_RemoveProc() {
|
|
int idx;
|
|
int overlay;
|
|
|
|
idx = popVar();
|
|
overlay = popVar();
|
|
|
|
if (!overlay) {
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
removeScript(overlay, idx, &procHead);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_FreeOverlay() {
|
|
char localName[36] = "";
|
|
char *namePtr;
|
|
|
|
namePtr = (char *) popPtr();
|
|
Common::strlcpy(localName, namePtr, sizeof(localName));
|
|
|
|
if (localName[0]) {
|
|
strToUpper(localName);
|
|
releaseOverlay((char *)localName);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FindProc() {
|
|
char name[36] = "";
|
|
|
|
char *ptr = (char *)popPtr();
|
|
Common::strlcpy(name, ptr, sizeof(name));
|
|
int param = getProcParam(popVar(), 20, name);
|
|
|
|
return param;
|
|
}
|
|
|
|
int16 Op_GetRingWord() {
|
|
// Original method had a ringed queue allowing this method to return words one at a time.
|
|
// But it never seemed to be used; no entries were ever added to the list
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_KillMenu() {
|
|
// Free menus, if active
|
|
if (menuTable[0]) {
|
|
freeMenu(menuTable[0]);
|
|
menuTable[0] = NULL;
|
|
currentActiveMenu = -1;
|
|
}
|
|
|
|
if (menuTable[1]) {
|
|
freeMenu(menuTable[1]);
|
|
menuTable[1] = NULL;
|
|
currentActiveMenu = -1;
|
|
}
|
|
|
|
// Free the message list
|
|
// if (linkedMsgList) freeMsgList(linkedMsgList);
|
|
linkedMsgList = NULL;
|
|
linkedRelation = NULL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_UserMenu() {
|
|
int oldValue = playerMenuEnabled;
|
|
playerMenuEnabled = popVar();
|
|
|
|
return oldValue;
|
|
}
|
|
|
|
int16 Op_UserOn() {
|
|
int oldValue = userEnabled;
|
|
int newValue = popVar();
|
|
|
|
if (newValue != -1) {
|
|
userEnabled = newValue;
|
|
}
|
|
|
|
return oldValue;
|
|
}
|
|
|
|
int16 Op_Display() {
|
|
int oldValue = displayOn;
|
|
int newValue = popVar();
|
|
|
|
if (newValue != -1) {
|
|
displayOn = newValue;
|
|
}
|
|
|
|
return oldValue;
|
|
}
|
|
|
|
int16 Op_FreezeParent() {
|
|
if (currentScriptPtr->var1A == 20) {
|
|
changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &procHead, -1, 9997);
|
|
} else if (currentScriptPtr->var1A == 30) {
|
|
changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &relHead, -1, 9997);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_LoadBackground() {
|
|
int result = 0;
|
|
char bgName[36] = "";
|
|
char *ptr;
|
|
int bgIdx;
|
|
|
|
ptr = (char *) popPtr();
|
|
|
|
Common::strlcpy(bgName, ptr, sizeof(bgName));
|
|
|
|
bgIdx = popVar();
|
|
|
|
if (bgIdx >= 0 || bgIdx < NBSCREENS) {
|
|
strToUpper(bgName);
|
|
|
|
gfxModuleData_gfxWaitVSync();
|
|
gfxModuleData_gfxWaitVSync();
|
|
|
|
result = loadBackground(bgName, bgIdx);
|
|
|
|
gfxModuleData_addDirtyRect(Common::Rect(0, 0, 320, 200));
|
|
}
|
|
|
|
changeCursor(CURSOR_NORMAL);
|
|
|
|
return result;
|
|
}
|
|
|
|
int16 Op_FrameExist() {
|
|
int param;
|
|
|
|
param = popVar();
|
|
|
|
if (param < 0 || param > 255) {
|
|
return 0;
|
|
}
|
|
|
|
if (filesDatabase[param].subData.ptr) {
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_LoadFrame() {
|
|
int param1;
|
|
int param2;
|
|
int param3;
|
|
|
|
char name[36] = "";
|
|
char *ptr = (char *) popPtr();
|
|
Common::strlcpy(name, ptr, sizeof(name));
|
|
|
|
param1 = popVar();
|
|
param2 = popVar();
|
|
param3 = popVar();
|
|
|
|
if (param3 >= 0 || param3 < NUM_FILE_ENTRIES) {
|
|
strToUpper(name);
|
|
|
|
gfxModuleData_gfxWaitVSync();
|
|
gfxModuleData_gfxWaitVSync();
|
|
|
|
lastAni[0] = 0;
|
|
|
|
loadFileRange(name, param2, param3, param1);
|
|
|
|
lastAni[0] = 0;
|
|
}
|
|
|
|
changeCursor(CURSOR_NORMAL);
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_LoadAbs() {
|
|
int result = 0;
|
|
|
|
char *ptr = (char *) popPtr();
|
|
int slot = popVar();
|
|
|
|
if ((slot >= 0) && (slot < NUM_FILE_ENTRIES)) {
|
|
char name[36] = "";
|
|
Common::strlcpy(name, ptr, sizeof(name));
|
|
strToUpper(name);
|
|
|
|
gfxModuleData_gfxWaitVSync();
|
|
gfxModuleData_gfxWaitVSync();
|
|
|
|
result = loadFullBundle(name, slot);
|
|
}
|
|
|
|
changeCursor(CURSOR_NORMAL);
|
|
return result;
|
|
}
|
|
|
|
int16 Op_InitializeState() {
|
|
int param1 = popVar();
|
|
int objIdx = popVar();
|
|
int ovlIdx = popVar();
|
|
|
|
if (!ovlIdx)
|
|
ovlIdx = currentScriptPtr->overlayNumber;
|
|
|
|
#ifdef FUNCTION_DEBUG
|
|
debug(1, "Init %s state to %d", getObjectName(objIdx, overlayTable[ovlIdx].ovlData->arrayNameObj), param1);
|
|
#endif
|
|
|
|
objInit(ovlIdx, objIdx, param1);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int16 Op_GetlowMemory() {
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_AniDir() {
|
|
int type = popVar();
|
|
int objIdx = popVar();
|
|
int ovlIdx = popVar();
|
|
|
|
if (!ovlIdx)
|
|
ovlIdx = currentScriptPtr->overlayNumber;
|
|
|
|
actorStruct *pActor = findActor(&actorHead, ovlIdx, objIdx, type);
|
|
if (pActor)
|
|
return pActor->startDirection;
|
|
|
|
return -1;
|
|
}
|
|
|
|
int16 Op_FadeOut() {
|
|
for (long int i = 0; i < 256; i += 32) {
|
|
for (long int j = 0; j < 256; j++) {
|
|
int offsetTable[3];
|
|
offsetTable[0] = -32;
|
|
offsetTable[1] = -32;
|
|
offsetTable[2] = -32;
|
|
calcRGB(&workpal[3*j], &workpal[3*j], offsetTable);
|
|
}
|
|
gfxModuleData_setPal256(workpal);
|
|
gfxModuleData_flipScreen();
|
|
}
|
|
|
|
memset(globalScreen, 0, 320 * 200);
|
|
flip();
|
|
|
|
fadeFlag = 1;
|
|
PCFadeFlag = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 isOverlayLoaded(const char * name) {
|
|
int16 i;
|
|
|
|
for (i = 1; i < numOfLoadedOverlay; i++) {
|
|
if (!strcmp(overlayTable[i].overlayName, name) && overlayTable[i].alreadyLoaded) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FindOverlay() {
|
|
char name[36] = "";
|
|
char *ptr;
|
|
|
|
ptr = (char *) popPtr();
|
|
Common::strlcpy(name, ptr, sizeof(name));
|
|
strToUpper(name);
|
|
|
|
return (isOverlayLoaded(name));
|
|
}
|
|
|
|
int16 Op_WriteObject() {
|
|
int16 returnParam;
|
|
|
|
int16 param1 = popVar();
|
|
int16 param2 = popVar();
|
|
int16 param3 = popVar();
|
|
int16 param4 = popVar();
|
|
|
|
getSingleObjectParam(param4, param3, param2, &returnParam);
|
|
setObjectPosition(param4, param3, param2, param1);
|
|
|
|
return returnParam;
|
|
}
|
|
|
|
int16 Op_ReadObject() {
|
|
int16 returnParam;
|
|
|
|
int member = popVar();
|
|
int obj = popVar();
|
|
int ovl = popVar();
|
|
|
|
getSingleObjectParam(ovl, obj, member, &returnParam);
|
|
|
|
return returnParam;
|
|
}
|
|
|
|
int16 Op_FadeIn() {
|
|
doFade = 1;
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_GetMouseButton() {
|
|
int16 dummy;
|
|
int16 mouseX;
|
|
int16 mouseY;
|
|
int16 mouseButton;
|
|
|
|
getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY);
|
|
|
|
return mouseButton;
|
|
}
|
|
|
|
int16 Op_AddCell() {
|
|
int16 objType = popVar();
|
|
int16 objIdx = popVar();
|
|
int16 overlayIdx = popVar();
|
|
|
|
if (!overlayIdx)
|
|
overlayIdx = currentScriptPtr->overlayNumber;
|
|
|
|
addCell(&cellHead, overlayIdx, objIdx, objType, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_AddBackgroundIncrust() {
|
|
|
|
int16 objType = popVar();
|
|
int16 objIdx = popVar();
|
|
int16 overlayIdx = popVar();
|
|
|
|
if (!overlayIdx)
|
|
overlayIdx = currentScriptPtr->overlayNumber;
|
|
|
|
addBackgroundIncrust(overlayIdx, objIdx, &backgroundIncrustHead, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, masterScreen, objType);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_RemoveCell() {
|
|
int objType = popVar();
|
|
int objectIdx = popVar();
|
|
int ovlNumber = popVar();
|
|
|
|
if (!ovlNumber) {
|
|
ovlNumber = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
removeCell(&cellHead, ovlNumber, objectIdx, objType, masterScreen);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 fontFileIndex = -1;
|
|
|
|
int16 Op_SetFont() {
|
|
fontFileIndex = popVar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_UnfreezeParent() {
|
|
if (currentScriptPtr->var1A == 0x14) {
|
|
changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &procHead, -1, 0);
|
|
} else if (currentScriptPtr->var1A == 0x1E) {
|
|
changeScriptParamInList(currentScriptPtr->var18, currentScriptPtr->var16, &relHead, -1, 0);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_ProtectionFlag() {
|
|
int16 temp = protectionCode;
|
|
int16 newVar;
|
|
|
|
newVar = popVar();
|
|
if (newVar != -1) {
|
|
protectionCode = newVar;
|
|
}
|
|
|
|
return temp;
|
|
}
|
|
|
|
int16 Op_ClearScreen() {
|
|
int bgIdx = popVar();
|
|
|
|
if ((bgIdx >= 0) && (bgIdx < NBSCREENS) && (backgroundScreens[bgIdx])) {
|
|
memset(backgroundScreens[bgIdx], 0, 320 * 200);
|
|
backgroundChanged[bgIdx] = true;
|
|
strcpy(backgroundTable[0].name, "");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_AddMessage() {
|
|
int16 color = popVar();
|
|
int16 var_2 = popVar();
|
|
int16 var_4 = popVar();
|
|
int16 var_6 = popVar();
|
|
int16 var_8 = popVar();
|
|
int16 overlayIdx = popVar();
|
|
|
|
if (!overlayIdx)
|
|
overlayIdx = currentScriptPtr->overlayNumber;
|
|
|
|
if (color == -1) {
|
|
color = findHighColor();
|
|
} else {
|
|
if (CVTLoaded) {
|
|
color = cvtPalette[color];
|
|
}
|
|
}
|
|
|
|
createTextObject(&cellHead, overlayIdx, var_8, var_6, var_4, var_2, color, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_Preload() {
|
|
popPtr();
|
|
popVar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_LoadCt() {
|
|
return initCt((const char *)popPtr());
|
|
}
|
|
|
|
int16 Op_EndAnim() {
|
|
int param1 = popVar();
|
|
int param2 = popVar();
|
|
int overlay = popVar();
|
|
|
|
if (!overlay)
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
|
|
return isAnimFinished(overlay, param2, &actorHead, param1);
|
|
}
|
|
|
|
int16 Op_Protect() {
|
|
popPtr();
|
|
popVar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_AutoCell() {
|
|
cellStruct *pObject;
|
|
|
|
int signal = popVar();
|
|
int loop = popVar();
|
|
int wait = popVar();
|
|
int animStep = popVar();
|
|
int end = popVar();
|
|
int start = popVar();
|
|
int type = popVar();
|
|
int change = popVar();
|
|
int obj = popVar();
|
|
int overlay = popVar();
|
|
|
|
if (!overlay)
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
|
|
pObject = addCell(&cellHead, overlay, obj, 4, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type);
|
|
|
|
if (!pObject)
|
|
return 0;
|
|
|
|
pObject->animSignal = signal;
|
|
pObject->animLoop = loop;
|
|
pObject->animWait = wait;
|
|
pObject->animStep = animStep;
|
|
pObject->animEnd = end;
|
|
pObject->animStart = start;
|
|
pObject->animType = type;
|
|
pObject->animChange = change;
|
|
|
|
if (type) {
|
|
if (currentScriptPtr->type == scriptType_PROC) {
|
|
changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &procHead, -1, 9996);
|
|
} else if (currentScriptPtr->type == scriptType_REL) {
|
|
changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &relHead, -1, 9996);
|
|
}
|
|
}
|
|
|
|
if (change == 5) {
|
|
objInit(pObject->overlay, pObject->idx, start);
|
|
} else {
|
|
setObjectPosition(pObject->overlay, pObject->idx, pObject->animChange, start);
|
|
}
|
|
|
|
if (wait < 0) {
|
|
objectParamsQuery params;
|
|
|
|
getMultipleObjectParam(overlay, obj, ¶ms);
|
|
pObject->animCounter = params.state2 - 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_Sizeof() {
|
|
objectParamsQuery params;
|
|
int index = popVar();
|
|
int overlay = popVar();
|
|
|
|
if (!overlay)
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
|
|
getMultipleObjectParam(overlay, index, ¶ms);
|
|
|
|
return params.nbState - 1;
|
|
}
|
|
|
|
int16 Op_SetActiveBackground() {
|
|
int currentPlane = masterScreen;
|
|
int newPlane = popVar();
|
|
|
|
if (newPlane >= 0 && newPlane < NBSCREENS) {
|
|
if (backgroundScreens[newPlane]) {
|
|
masterScreen = newPlane;
|
|
backgroundChanged[newPlane] = true;
|
|
switchPal = 1;
|
|
}
|
|
}
|
|
|
|
return currentPlane;
|
|
}
|
|
|
|
int16 Op_RemoveBackground() {
|
|
int backgroundIdx = popVar();
|
|
|
|
if (backgroundIdx > 0 && backgroundIdx < 8) {
|
|
if (backgroundScreens[backgroundIdx])
|
|
MemFree(backgroundScreens[backgroundIdx]);
|
|
|
|
if (masterScreen == backgroundIdx) {
|
|
masterScreen = 0;
|
|
backgroundChanged[0] = true;
|
|
}
|
|
|
|
strcpy(backgroundTable[backgroundIdx].name, "");
|
|
} else {
|
|
strcpy(backgroundTable[0].name, "");
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int vblLimit;
|
|
|
|
int16 Op_VBL() {
|
|
vblLimit = popVar();
|
|
return 0;
|
|
}
|
|
|
|
int op7BVar = 0;
|
|
|
|
int16 Op_Sec() {
|
|
int di = popVar();
|
|
int si = 1 - op7BVar;
|
|
int sign;
|
|
|
|
if (di) {
|
|
sign = di / (ABS(di));
|
|
} else {
|
|
sign = 0;
|
|
}
|
|
|
|
op7BVar = -sign;
|
|
|
|
return si;
|
|
}
|
|
|
|
int16 Op_RemoveBackgroundIncrust() {
|
|
int idx = popVar();
|
|
int overlay = popVar();
|
|
|
|
if (!overlay) {
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
removeBackgroundIncrust(overlay, idx, &backgroundIncrustHead);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_SetColor() {
|
|
int colorB = popVar();
|
|
int colorG = popVar();
|
|
int colorR = popVar();
|
|
int endIdx = popVar();
|
|
int startIdx = popVar();
|
|
|
|
#define convertRatio 36.571428571428571428571428571429
|
|
|
|
for (int i = startIdx; i <= endIdx; i++) {
|
|
int offsetTable[3];
|
|
|
|
offsetTable[0] = (int)(colorR * convertRatio);
|
|
offsetTable[1] = (int)(colorG * convertRatio);
|
|
offsetTable[2] = (int)(colorB * convertRatio);
|
|
|
|
if (CVTLoaded) {
|
|
int colorIdx = cvtPalette[i];
|
|
calcRGB(&palScreen[masterScreen][3*colorIdx], &workpal[3*colorIdx], offsetTable);
|
|
} else {
|
|
calcRGB(&palScreen[masterScreen][3*i], &workpal[3*i], offsetTable);
|
|
}
|
|
}
|
|
|
|
gfxModuleData_setPalEntries(workpal, 0, 32);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_Inventory() {
|
|
int si = var41;
|
|
|
|
var41 = popVar();
|
|
|
|
return si;
|
|
}
|
|
|
|
int16 Op_RemoveOverlay() {
|
|
int overlayIdx;
|
|
|
|
overlayIdx = popVar();
|
|
|
|
if (strlen(overlayTable[overlayIdx].overlayName)) {
|
|
releaseOverlay(overlayTable[overlayIdx].overlayName);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_ComputeLine() {
|
|
int y2 = popVar();
|
|
int x2 = popVar();
|
|
int y1 = popVar();
|
|
int x1 = popVar();
|
|
|
|
point* pDest = (point *)popPtr();
|
|
|
|
int maxValue = cor_droite(x1, y1, x2, y2, pDest);
|
|
|
|
flipGen(pDest, maxValue * 4);
|
|
|
|
return maxValue;
|
|
}
|
|
|
|
int16 Op_FindMsg() {
|
|
int si = popVar();
|
|
popVar();
|
|
|
|
return si;
|
|
}
|
|
|
|
int16 Op_SetZoom() {
|
|
var46 = popVar();
|
|
var45 = popVar();
|
|
var42 = popVar();
|
|
var39 = popVar();
|
|
return 0;
|
|
}
|
|
|
|
int16 computeZoom(int param) {
|
|
return (((param - var46) * (var39 - var42)) / (var45 - var46)) + var42;
|
|
}
|
|
|
|
int16 subOp23(int param1, int param2) {
|
|
return (param1 * param2) >> 8;
|
|
}
|
|
|
|
int16 Op_GetStep() {
|
|
int si = popVar();
|
|
int dx = popVar();
|
|
|
|
return subOp23(dx, si);
|
|
}
|
|
|
|
int16 Op_GetZoom() {
|
|
return (computeZoom(popVar()));
|
|
}
|
|
|
|
actorStruct *addAnimation(actorStruct * pHead, int overlay, int objIdx, int param, int param2) {
|
|
actorStruct *pPrevious = pHead;
|
|
actorStruct *pCurrent = pHead->next;
|
|
|
|
// go to the end of the list
|
|
while (pCurrent) {
|
|
pPrevious = pCurrent;
|
|
pCurrent = pPrevious->next;
|
|
}
|
|
|
|
actorStruct *pNewElement = (actorStruct *) MemAlloc(sizeof(actorStruct));
|
|
if (!pNewElement)
|
|
return NULL;
|
|
|
|
memset(pNewElement, 0, sizeof(actorStruct));
|
|
pNewElement->next = pPrevious->next;
|
|
pPrevious->next = pNewElement;
|
|
|
|
if (!pCurrent) {
|
|
pCurrent = pHead;
|
|
}
|
|
|
|
pNewElement->prev = pCurrent->prev;
|
|
pCurrent->prev = pNewElement;
|
|
|
|
pNewElement->idx = objIdx;
|
|
pNewElement->type = param2;
|
|
pNewElement->pathId = -1;
|
|
pNewElement->overlayNumber = overlay;
|
|
pNewElement->startDirection = param;
|
|
pNewElement->nextDirection = -1;
|
|
pNewElement->stepX = 5;
|
|
pNewElement->stepY = 2;
|
|
pNewElement->phase = ANIM_PHASE_WAIT;
|
|
pNewElement->flag = 0;
|
|
pNewElement->freeze = 0;
|
|
|
|
return pNewElement;
|
|
}
|
|
|
|
int removeAnimation(actorStruct * pHead, int overlay, int objIdx, int objType) {
|
|
actorStruct* pl;
|
|
actorStruct* pl2;
|
|
actorStruct* pl3;
|
|
actorStruct* pl4;
|
|
|
|
int dir = 0;
|
|
|
|
pl = pHead;
|
|
pl2 = pl;
|
|
pl = pl2->next;
|
|
|
|
while (pl) {
|
|
pl2 = pl;
|
|
|
|
if (((pl->overlayNumber == overlay) || (overlay == -1)) &&
|
|
((pl->idx == objIdx) || (objIdx == -1)) &&
|
|
((pl->type == objType) || (objType == -1))) {
|
|
pl->type = -1;
|
|
}
|
|
|
|
pl = pl2->next;
|
|
}
|
|
|
|
pl = pHead;
|
|
pl2 = pl;
|
|
pl = pl2->next;
|
|
|
|
while (pl) {
|
|
if (pl->type == -1) {
|
|
pl4 = pl->next;
|
|
pl2->next = pl4;
|
|
pl3 = pl4;
|
|
|
|
if (pl3 == NULL)
|
|
pl3 = pHead;
|
|
|
|
pl3->prev = pl->prev;
|
|
|
|
dir = pl->startDirection;
|
|
|
|
if (pl->pathId >= 0)
|
|
freePerso(pl->pathId);
|
|
|
|
MemFree(pl);
|
|
pl = pl4;
|
|
} else {
|
|
pl2 = pl;
|
|
pl = pl2->next;
|
|
}
|
|
}
|
|
|
|
return dir;
|
|
}
|
|
|
|
int flag_obstacle; // numPolyBis
|
|
|
|
// add animation
|
|
int16 Op_AddAnimation() {
|
|
int stepY = popVar();
|
|
int stepX = popVar();
|
|
int direction = popVar();
|
|
int start = popVar();
|
|
int type = popVar();
|
|
int obj = popVar();
|
|
int overlay = popVar();
|
|
|
|
if (!overlay) {
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
if (direction >= 0 && direction <= 3) {
|
|
actorStruct *si;
|
|
|
|
si = addAnimation(&actorHead, overlay, obj, direction, type);
|
|
|
|
if (si) {
|
|
objectParamsQuery params;
|
|
|
|
getMultipleObjectParam(overlay, obj, ¶ms);
|
|
|
|
si->x = params.X;
|
|
si->y = params.Y;
|
|
si->x_dest = -1;
|
|
si->y_dest = -1;
|
|
si->endDirection = -1;
|
|
si->start = start;
|
|
si->stepX = stepX;
|
|
si->stepY = stepY;
|
|
|
|
int newFrame = ABS(actor_end[direction][0]) - 1;
|
|
|
|
int zoom = computeZoom(params.Y);
|
|
|
|
if (actor_end[direction][0] < 0) {
|
|
zoom = -zoom;
|
|
}
|
|
|
|
getPixel(params.X, params.Y);
|
|
|
|
setObjectPosition(overlay, obj, 3, newFrame + start);
|
|
setObjectPosition(overlay, obj, 4, zoom);
|
|
setObjectPosition(overlay, obj, 5, numPoly);
|
|
|
|
animationStart = false;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_RemoveAnimation() {
|
|
int objType = popVar();
|
|
int objIdx = popVar();
|
|
int ovlIdx = popVar();
|
|
|
|
if (!ovlIdx) {
|
|
ovlIdx = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
return removeAnimation(&actorHead, ovlIdx, objIdx, objType);
|
|
}
|
|
|
|
int16 Op_regenerateBackgroundIncrust() {
|
|
regenerateBackgroundIncrust(&backgroundIncrustHead);
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_SetStringColors() {
|
|
// TODO: here ignore if low color mode
|
|
|
|
subColor = (uint8) popVar();
|
|
itemColor = (uint8) popVar();
|
|
selectColor = (uint8) popVar();
|
|
titleColor = (uint8) popVar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_XClick() {
|
|
int x = popVar();
|
|
|
|
if (x != -1) {
|
|
aniX = x;
|
|
animationStart = true;
|
|
}
|
|
|
|
return aniX;
|
|
}
|
|
|
|
int16 Op_YClick() {
|
|
int y = popVar();
|
|
|
|
if (y != -1) {
|
|
aniY = y;
|
|
animationStart = true;
|
|
}
|
|
|
|
return aniY;
|
|
}
|
|
|
|
int16 Op_GetPixel() {
|
|
int x = popVar();
|
|
int y = popVar();
|
|
|
|
getPixel(x, y);
|
|
return numPoly;
|
|
}
|
|
|
|
int16 Op_TrackAnim() { // setup actor position
|
|
actorStruct *pActor;
|
|
|
|
int var0 = popVar();
|
|
int actorY = popVar();
|
|
int actorX = popVar();
|
|
int var1 = popVar();
|
|
int var2 = popVar();
|
|
int overlay = popVar();
|
|
|
|
if (!overlay) {
|
|
overlay = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
pActor = findActor(&actorHead, overlay, var2, var1);
|
|
|
|
if (!pActor) {
|
|
return 1;
|
|
}
|
|
|
|
animationStart = false;
|
|
|
|
pActor->x_dest = actorX;
|
|
pActor->y_dest = actorY;
|
|
pActor->flag = 1;
|
|
pActor->endDirection = var0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_BgName() {
|
|
char* bgName = (char *)popPtr();
|
|
int bgIdx = popVar();
|
|
|
|
if ((bgIdx >= 0) && (bgIdx < NBSCREENS) && bgName) {
|
|
strcpy(bgName, backgroundTable[bgIdx].name);
|
|
|
|
if (strlen(bgName))
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_LoadSong() {
|
|
const char *ptr = (const char *)popPtr();
|
|
char buffer[33];
|
|
|
|
Common::strlcpy(buffer, ptr, sizeof(buffer));
|
|
strToUpper(buffer);
|
|
_vm->sound().loadMusic(buffer);
|
|
|
|
changeCursor(CURSOR_NORMAL);
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_PlaySong() {
|
|
if (_vm->sound().songLoaded() && !_vm->sound().songPlayed())
|
|
_vm->sound().playMusic();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_StopSong() {
|
|
if (_vm->sound().isPlaying())
|
|
_vm->sound().stopMusic();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_RestoreSong() {
|
|
// Used in the original to restore the contents of a song. Doesn't seem to be used,
|
|
// since the backup buffer it uses is never set
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_SongSize() {
|
|
int oldSize;
|
|
if (_vm->sound().songLoaded()) {
|
|
oldSize = _vm->sound().numOrders();
|
|
|
|
int size = popVar();
|
|
if ((size >= 1) && (size < 128))
|
|
_vm->sound().setNumOrders(size);
|
|
} else
|
|
oldSize = 0;
|
|
|
|
return oldSize;
|
|
}
|
|
|
|
int16 Op_SetPattern() {
|
|
int value = popVar();
|
|
int offset = popVar();
|
|
|
|
if (_vm->sound().songLoaded()) {
|
|
_vm->sound().setPattern(offset, value);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FadeSong() {
|
|
_vm->sound().fadeSong();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FreeSong() {
|
|
_vm->sound().stopMusic();
|
|
_vm->sound().removeMusic();
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_SongLoop() {
|
|
bool oldLooping = _vm->sound().musicLooping();
|
|
_vm->sound().musicLoop(popVar() != 0);
|
|
|
|
return oldLooping;
|
|
}
|
|
|
|
int16 Op_SongPlayed() {
|
|
return _vm->sound().songPlayed();
|
|
}
|
|
|
|
void setVar49Value(int value) {
|
|
flagCt = value;
|
|
}
|
|
|
|
int16 Op_CTOn() {
|
|
setVar49Value(1);
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_CTOff() {
|
|
setVar49Value(0);
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FreezeOverlay() {
|
|
//int var0;
|
|
//int var1;
|
|
int temp;
|
|
|
|
int var0 = popVar();
|
|
int var1 = popVar();
|
|
|
|
if (!var1) {
|
|
var1 = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
temp = overlayTable[var1].executeScripts;
|
|
overlayTable[var1].executeScripts = var0;
|
|
|
|
return temp;
|
|
}
|
|
|
|
int16 Op_FreezeCell() {
|
|
int newFreezz = popVar();
|
|
int oldFreeze = popVar();
|
|
int backgroundPlante = popVar();
|
|
int objType = popVar();
|
|
int objIdx = popVar();
|
|
int overlayIdx = popVar();
|
|
|
|
if (!overlayIdx) {
|
|
overlayIdx = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
freezeCell(&cellHead, overlayIdx, objIdx, objType, backgroundPlante, oldFreeze, newFreezz);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void Op_60Sub(int overlayIdx, actorStruct * pActorHead, int _var0, int _var1, int _var2, int _var3) {
|
|
actorStruct *pActor = findActor(pActorHead, overlayIdx, _var0, _var3);
|
|
|
|
if (pActor) {
|
|
if ((pActor->freeze == _var2) || (_var2 == -1)) {
|
|
pActor->freeze = _var1;
|
|
}
|
|
}
|
|
}
|
|
|
|
int16 Op_FreezeAni() {
|
|
/*
|
|
* int var0;
|
|
* int var1;
|
|
* int var2;
|
|
* int var3;
|
|
* int var4;
|
|
*/
|
|
|
|
int var0 = popVar();
|
|
int var1 = popVar();
|
|
int var2 = popVar();
|
|
int var3 = popVar();
|
|
int var4 = popVar();
|
|
|
|
if (!var4) {
|
|
var4 = currentScriptPtr->overlayNumber;
|
|
}
|
|
|
|
Op_60Sub(var4, &actorHead, var3, var0, var1, var2);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_Itoa() {
|
|
int nbp = popVar();
|
|
int param[160];
|
|
char txt[40];
|
|
|
|
for (int i = 0; i < 160; ++i)
|
|
param[i] = 0;
|
|
|
|
for (int i = nbp - 1; i >= 0; i--)
|
|
param[i] = popVar();
|
|
|
|
int val = popVar();
|
|
char* pDest = (char *)popPtr();
|
|
|
|
if (!nbp)
|
|
sprintf(txt, "%d", val);
|
|
else {
|
|
char format[30];
|
|
char nbf[20];
|
|
strcpy(format, "%");
|
|
sprintf(nbf, "%d", param[0]);
|
|
strcat(format, nbf);
|
|
strcat(format, "d");
|
|
sprintf(txt, format, val);
|
|
}
|
|
|
|
for (int i = 0; txt[i]; i++)
|
|
*(pDest++) = txt[i];
|
|
*(pDest++) = '\0';
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_Strcat() {
|
|
char *pSource = (char *)popPtr();
|
|
char *pDest = (char *)popPtr();
|
|
|
|
while (*pDest)
|
|
pDest++;
|
|
|
|
while (*pSource)
|
|
*(pDest++) = *(pSource++);
|
|
*(pDest++) = '\0';
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_FindSymbol() {
|
|
int var0 = popVar();
|
|
char *ptr = (char *)popPtr();
|
|
int var1 = popVar();
|
|
|
|
if (!var1)
|
|
var1 = currentScriptPtr->overlayNumber;
|
|
|
|
return getProcParam(var1, var0, ptr);
|
|
}
|
|
|
|
int16 Op_FindObject() {
|
|
char var_26[36];
|
|
char *ptr = (char *)popPtr();
|
|
int overlayIdx;
|
|
|
|
var_26[0] = 0;
|
|
|
|
if (ptr) {
|
|
Common::strlcpy(var_26, ptr, sizeof(var_26));
|
|
}
|
|
|
|
overlayIdx = popVar();
|
|
|
|
if (!overlayIdx)
|
|
overlayIdx = currentScriptPtr->overlayNumber;
|
|
|
|
return getProcParam(overlayIdx, 40, var_26);
|
|
}
|
|
|
|
int16 Op_SetObjectAtNode() {
|
|
int16 node = popVar();
|
|
int16 obj = popVar();
|
|
int16 ovl = popVar();
|
|
|
|
if (!ovl)
|
|
ovl = currentScriptPtr->overlayNumber;
|
|
|
|
int nodeInfo[2];
|
|
|
|
if (!getNode(nodeInfo, node)) {
|
|
setObjectPosition(ovl, obj, 0, nodeInfo[0]);
|
|
setObjectPosition(ovl, obj, 1, nodeInfo[1]);
|
|
setObjectPosition(ovl, obj, 2, nodeInfo[1]);
|
|
setObjectPosition(ovl, obj, 4, computeZoom(nodeInfo[1]));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_GetNodeX() {
|
|
int16 node = popVar();
|
|
|
|
int nodeInfo[2];
|
|
|
|
int result = getNode(nodeInfo, node);
|
|
|
|
assert(result == 0);
|
|
|
|
return nodeInfo[0];
|
|
}
|
|
|
|
int16 Op_GetNodeY() {
|
|
int16 node = popVar();
|
|
|
|
int nodeInfo[2];
|
|
|
|
int result = getNode(nodeInfo, node);
|
|
|
|
assert(result == 0);
|
|
|
|
return nodeInfo[1];
|
|
}
|
|
|
|
int16 Op_SetVolume() {
|
|
int oldVolume = _vm->sound().getVolume();
|
|
int newVolume = popVar();
|
|
|
|
if (newVolume > 63) newVolume = 63;
|
|
if (newVolume >= 0) {
|
|
int volume = 63 - newVolume;
|
|
_vm->sound().setVolume(volume);
|
|
}
|
|
|
|
return oldVolume >> 2;
|
|
}
|
|
|
|
int16 Op_SongExist() {
|
|
const char *songName = (char *)popPtr();
|
|
|
|
if (songName) {
|
|
char name[33];
|
|
Common::strlcpy(name, songName, sizeof(name));
|
|
strToUpper(name);
|
|
|
|
if (!strcmp(_vm->sound().musicName(), name))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_TrackPos() {
|
|
// This function returns a variable that never seems to change from 0
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_SetNodeState() {
|
|
int16 state = popVar();
|
|
int16 node = popVar();
|
|
|
|
return setNodeState(node, state);
|
|
}
|
|
|
|
int16 Op_SetNodeColor() {
|
|
int16 color = popVar();
|
|
int16 node = popVar();
|
|
|
|
return setNodeColor(node, color);
|
|
}
|
|
|
|
int16 Op_SetXDial() {
|
|
int16 old = xdial;
|
|
xdial = popVar();
|
|
|
|
return old;
|
|
}
|
|
|
|
int16 Op_DialogOn() {
|
|
dialogueObj = popVar();
|
|
dialogueOvl = popVar();
|
|
|
|
if (dialogueOvl == 0)
|
|
dialogueOvl = currentScriptPtr->overlayNumber;
|
|
|
|
dialogueEnabled = true;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_DialogOff() {
|
|
dialogueEnabled = false;
|
|
|
|
objectReset();
|
|
|
|
if (menuTable[0]) {
|
|
freeMenu(menuTable[0]);
|
|
menuTable[0] = NULL;
|
|
changeCursor(CURSOR_NORMAL);
|
|
currentActiveMenu = -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_LinkObjects() {
|
|
int type = popVar();
|
|
int obj2 = popVar();
|
|
int ovl2 = popVar();
|
|
int obj = popVar();
|
|
int ovl = popVar();
|
|
|
|
if (!ovl)
|
|
ovl = currentScriptPtr->overlayNumber;
|
|
if (!ovl2)
|
|
ovl2 = currentScriptPtr->overlayNumber;
|
|
|
|
linkCell(&cellHead, ovl, obj, type, ovl2, obj2);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_UserClick() {
|
|
sysKey = popVar();
|
|
sysY = popVar();
|
|
sysX = popVar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_XMenuItem() {
|
|
int index = popVar();
|
|
int count = 0;
|
|
|
|
if (!menuTable[0] || (menuTable[0]->numElements == 0))
|
|
return 0;
|
|
|
|
menuElementStruct *p = menuTable[0]->ptrNextElement;
|
|
|
|
while (p) {
|
|
if (count == index)
|
|
return p->x + 1;
|
|
|
|
++count;
|
|
p = p->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_YMenuItem() {
|
|
int index = popVar();
|
|
int count = 0;
|
|
|
|
if (!menuTable[0] || (menuTable[0]->numElements == 0))
|
|
return 0;
|
|
|
|
menuElementStruct *p = menuTable[0]->ptrNextElement;
|
|
|
|
while (p) {
|
|
if (count == index)
|
|
return p->y + 1;
|
|
|
|
++count;
|
|
p = p->next;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int16 Op_Menu() {
|
|
return (int16)(menuTable[0] != NULL);
|
|
}
|
|
|
|
int16 Op_AutoControl() {
|
|
int oldValue = automaticMode;
|
|
int newValue = popVar();
|
|
|
|
if (newValue >= 0) {
|
|
automaticMode = newValue;
|
|
activeMouse = newValue;
|
|
}
|
|
|
|
return oldValue;
|
|
}
|
|
|
|
int16 Op_MouseMove() {
|
|
int16 handle, button;
|
|
Common::Point pt;
|
|
|
|
getMouseStatus(&handle, &pt.x, &button, &pt.y);
|
|
|
|
// x/y parameters aren't used
|
|
popVar();
|
|
popVar();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_MouseEnd() {
|
|
if (automoveInc < automoveMax)
|
|
return (int16)false;
|
|
|
|
return (int16)true;
|
|
}
|
|
|
|
int16 Op_MsgExist() {
|
|
return isMessage;
|
|
}
|
|
|
|
int16 Op_UserDelay() {
|
|
int delay = popVar();
|
|
|
|
if (delay >= 0) {
|
|
userDelay = delay;
|
|
}
|
|
|
|
return userDelay;
|
|
}
|
|
|
|
int16 Op_ThemeReset() {
|
|
objectReset();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int16 Op_UserWait() {
|
|
userWait = true;
|
|
if (currentScriptPtr->type == scriptType_PROC) {
|
|
changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &procHead, -1, 9999);
|
|
} else if (currentScriptPtr->type == scriptType_REL) {
|
|
changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &relHead, -1, 9999);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
opcodeFunction opcodeTablePtr[] = {
|
|
NULL, // 0x00
|
|
Op_FadeIn,
|
|
Op_FadeOut,
|
|
Op_LoadBackground,
|
|
Op_LoadAbs,
|
|
Op_AddCell,
|
|
Op_AddProc,
|
|
Op_InitializeState,
|
|
Op_RemoveCell,
|
|
Op_FreeCell,
|
|
Op_RemoveProc,
|
|
Op_RemoveFrame,
|
|
Op_LoadOverlay,
|
|
Op_SetColor,
|
|
Op_PlayFX,
|
|
NULL, // used to be debug
|
|
|
|
Op_FreeOverlay, // 0x10
|
|
Op_FindOverlay,
|
|
NULL, // used to be exec debug
|
|
Op_AddMessage,
|
|
Op_RemoveMessage,
|
|
Op_UserWait,
|
|
Op_FreezeCell,
|
|
Op_LoadCt,
|
|
Op_AddAnimation,
|
|
Op_RemoveAnimation,
|
|
Op_SetZoom,
|
|
Op_SetObjectAtNode,
|
|
Op_SetNodeState,
|
|
Op_SetNodeColor,
|
|
Op_TrackAnim,
|
|
Op_GetNodeX,
|
|
|
|
Op_GetNodeY, // 0x20
|
|
Op_EndAnim,
|
|
Op_GetZoom,
|
|
Op_GetStep,
|
|
Op_SetStringColors,
|
|
Op_XClick,
|
|
Op_YClick,
|
|
Op_GetPixel,
|
|
Op_UserOn,
|
|
Op_FreeCT,
|
|
Op_FindObject,
|
|
Op_FindProc,
|
|
Op_WriteObject,
|
|
Op_ReadObject,
|
|
Op_RemoveOverlay,
|
|
Op_AddBackgroundIncrust,
|
|
|
|
Op_RemoveBackgroundIncrust, // 0x30
|
|
Op_UnmergeBackgroundIncrust,
|
|
Op_freeBackgroundInscrustList,
|
|
Op_DialogOn,
|
|
Op_DialogOff,
|
|
Op_UserDelay,
|
|
Op_ThemeReset,
|
|
Op_Narrator,
|
|
Op_RemoveBackground,
|
|
Op_SetActiveBackground,
|
|
Op_CTOn,
|
|
Op_CTOff,
|
|
Op_Random,
|
|
Op_LoadSong,
|
|
Op_FadeSong,
|
|
Op_PlaySong,
|
|
|
|
Op_FreeSong, // 0x40
|
|
Op_FrameExist,
|
|
Op_SetVolume,
|
|
Op_SongExist,
|
|
Op_TrackPos,
|
|
Op_StopSong,
|
|
Op_RestoreSong,
|
|
Op_SongSize,
|
|
Op_SetPattern,
|
|
Op_SongLoop,
|
|
Op_SongPlayed,
|
|
Op_LinkObjects,
|
|
Op_UserClick,
|
|
Op_XMenuItem,
|
|
Op_YMenuItem,
|
|
Op_Menu,
|
|
|
|
Op_AutoControl, // 0x50
|
|
Op_MouseMove,
|
|
Op_MouseEnd,
|
|
Op_MsgExist,
|
|
Op_SetFont,
|
|
NULL, // MergeMsg
|
|
Op_Display,
|
|
Op_GetMouseX,
|
|
Op_GetMouseY,
|
|
Op_GetMouseButton,
|
|
Op_FindSet,
|
|
Op_regenerateBackgroundIncrust,
|
|
Op_BgName,
|
|
Op_LoopFX,
|
|
Op_StopFX,
|
|
Op_FreqFX,
|
|
|
|
Op_FreezeAni, // 0x60
|
|
Op_FindMsg,
|
|
Op_FreezeParent,
|
|
Op_UnfreezeParent,
|
|
Op_Exec,
|
|
Op_AutoCell,
|
|
Op_Sizeof,
|
|
Op_Preload,
|
|
Op_FreePreload,
|
|
NULL, // DeletePreload
|
|
Op_VBL,
|
|
Op_LoadFrame,
|
|
Op_FreezeOverlay,
|
|
Op_Strcpy,
|
|
Op_Strcat,
|
|
Op_Itoa,
|
|
|
|
Op_comment, // 0x70
|
|
Op_ComputeLine,
|
|
Op_FindSymbol,
|
|
Op_SetXDial,
|
|
Op_GetlowMemory,
|
|
Op_AniDir,
|
|
Op_Protect,
|
|
Op_ClearScreen,
|
|
Op_Inventory,
|
|
Op_UserMenu,
|
|
Op_GetRingWord,
|
|
Op_Sec,
|
|
Op_ProtectionFlag,
|
|
Op_KillMenu,
|
|
};
|
|
|
|
int32 opcodeType8() {
|
|
int opcode = getByteFromScript();
|
|
|
|
if (!opcode)
|
|
return (-21);
|
|
|
|
if (opcode > 0x100)
|
|
return (-21);
|
|
|
|
if (opcode < ARRAYSIZE(opcodeTablePtr) && opcodeTablePtr[opcode]) {
|
|
pushVar(opcodeTablePtr[opcode]());
|
|
return (0);
|
|
} else {
|
|
warning("Unsupported opcode %d in opcode type 8", opcode);
|
|
pushVar(0);
|
|
// exit(1);
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} // End of namespace Cruise
|