2022-05-19 01:51:26 -07:00
|
|
|
#include "interpreter_lib.h"
|
|
|
|
|
|
|
|
#include "color.h"
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "datafile.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "debug.h"
|
|
|
|
#include "dialog.h"
|
2022-10-04 23:23:27 -07:00
|
|
|
#include "input.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "interpreter_extra.h"
|
|
|
|
#include "memory_manager.h"
|
2022-10-03 02:41:33 -07:00
|
|
|
#include "mouse.h"
|
2022-10-05 00:35:05 -07:00
|
|
|
#include "mouse_manager.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "nevs.h"
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "select_file_list.h"
|
2022-06-19 21:56:00 -07:00
|
|
|
#include "sound.h"
|
2022-10-05 00:35:05 -07:00
|
|
|
#include "svga.h"
|
2022-07-29 06:04:05 -07:00
|
|
|
#include "text_font.h"
|
|
|
|
#include "window.h"
|
|
|
|
#include "window_manager_private.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-23 05:43:44 -07:00
|
|
|
namespace fallout {
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
#define INT_LIB_SOUNDS_CAPACITY (32)
|
|
|
|
#define INT_LIB_KEY_HANDLERS_CAPACITY (256)
|
2022-06-19 21:56:00 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
typedef struct IntLibKeyHandlerEntry {
|
2022-06-19 21:56:00 -07:00
|
|
|
Program* program;
|
|
|
|
int proc;
|
2022-07-29 06:04:05 -07:00
|
|
|
} IntLibKeyHandlerEntry;
|
2022-06-19 21:56:00 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opFillWin3x3(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opFormat(Program* program);
|
|
|
|
static void opPrint(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSelectFileList(Program* program);
|
|
|
|
static void opTokenize(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opPrintRect(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSelect(Program* program);
|
|
|
|
static void opDisplay(Program* program);
|
|
|
|
static void opDisplayRaw(Program* program);
|
2022-09-01 08:41:37 -07:00
|
|
|
static void _interpretFadePaletteBK(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration, bool shouldProcessBk);
|
|
|
|
static void interpretFadePalette(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration);
|
|
|
|
static int intlibGetFadeIn();
|
|
|
|
static void interpretFadeOut(float duration);
|
|
|
|
static void interpretFadeIn(float duration);
|
|
|
|
static void interpretFadeOutNoBK(float duration);
|
|
|
|
static void interpretFadeInNoBK(float duration);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opFadeIn(Program* program);
|
|
|
|
static void opFadeOut(Program* program);
|
|
|
|
static int intLibCheckMovie(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetMovieFlags(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opPlayMovie(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opStopMovie(Program* program);
|
|
|
|
static void opAddRegionProc(Program* program);
|
|
|
|
static void opAddRegionRightProc(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opCreateWin(Program* program);
|
|
|
|
static void opResizeWin(Program* program);
|
|
|
|
static void opScaleWin(Program* program);
|
|
|
|
static void opDeleteWin(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayStart(Program* program);
|
|
|
|
static void opDeleteRegion(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opActivateRegion(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opCheckRegion(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opAddRegion(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayStartPos(Program* program);
|
|
|
|
static void opSayReplyTitle(Program* program);
|
|
|
|
static void opSayGoToReply(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSayReply(Program* program);
|
|
|
|
static void opSayOption(Program* program);
|
|
|
|
static int intLibCheckDialog(Program* program);
|
|
|
|
static void opSayEnd(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayGetLastPos(Program* program);
|
|
|
|
static void opSayQuit(Program* program);
|
2022-09-01 08:41:37 -07:00
|
|
|
static int getTimeOut();
|
|
|
|
static void setTimeOut(int value);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayMessageTimeout(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSayMessage(Program* program);
|
|
|
|
static void opGotoXY(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddButtonFlag(Program* program);
|
|
|
|
static void opAddRegionFlag(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opAddButton(Program* program);
|
|
|
|
static void opAddButtonText(Program* program);
|
|
|
|
static void opAddButtonGfx(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddButtonProc(Program* program);
|
|
|
|
static void opAddButtonRightProc(Program* program);
|
|
|
|
static void opShowWin(Program* program);
|
|
|
|
static void opDeleteButton(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opFillWin(Program* program);
|
|
|
|
static void opFillRect(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opHideMouse(Program* program);
|
|
|
|
static void opShowMouse(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opMouseShape(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetGlobalMouseFunc(Program* Program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opDisplayGfx(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opLoadPaletteTable(Program* program);
|
|
|
|
static void opAddNamedEvent(Program* program);
|
|
|
|
static void opAddNamedHandler(Program* program);
|
|
|
|
static void opClearNamed(Program* program);
|
|
|
|
static void opSignalNamed(Program* program);
|
|
|
|
static void opAddKey(Program* program);
|
|
|
|
static void opDeleteKey(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opRefreshMouse(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetFont(Program* program);
|
|
|
|
static void opSetTextFlags(Program* program);
|
|
|
|
static void opSetTextColor(Program* program);
|
|
|
|
static void opSayOptionColor(Program* program);
|
|
|
|
static void opSayReplyColor(Program* program);
|
|
|
|
static void opSetHighlightColor(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSayReplyWindow(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayReplyFlags(Program* program);
|
|
|
|
static void opSayOptionFlags(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSayOptionWindow(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayBorder(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void opSayScrollUp(Program* program);
|
|
|
|
static void opSayScrollDown(Program* program);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSaySetSpacing(Program* program);
|
|
|
|
static void opSayRestart(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static void intLibSoundCallback(void* userData, int a2);
|
|
|
|
static int intLibSoundDelete(int value);
|
|
|
|
static int intLibSoundPlay(char* fileName, int mode);
|
|
|
|
static int intLibSoundPause(int value);
|
|
|
|
static int intLibSoundRewind(int value);
|
|
|
|
static int intLibSoundResume(int value);
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundPlay(Program* program);
|
|
|
|
static void opSoundPause(Program* program);
|
|
|
|
static void opSoundResume(Program* program);
|
|
|
|
static void opSoundStop(Program* program);
|
|
|
|
static void opSoundRewind(Program* program);
|
|
|
|
static void opSoundDelete(Program* program);
|
|
|
|
static void opSetOneOptPause(Program* program);
|
2022-07-29 06:04:05 -07:00
|
|
|
static bool intLibDoInput(int key);
|
2022-06-19 21:56:00 -07:00
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x59D5D0
|
2022-07-29 06:04:05 -07:00
|
|
|
static Sound* gIntLibSounds[INT_LIB_SOUNDS_CAPACITY];
|
|
|
|
|
|
|
|
// 0x59D650
|
|
|
|
static unsigned char gIntLibFadePalette[256 * 3];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59D950
|
2022-07-29 06:04:05 -07:00
|
|
|
static IntLibKeyHandlerEntry gIntLibKeyHandlerEntries[INT_LIB_KEY_HANDLERS_CAPACITY];
|
|
|
|
|
|
|
|
// 0x59E150
|
|
|
|
static bool gIntLibIsPaletteFaded;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E154
|
2022-07-29 06:04:05 -07:00
|
|
|
static int gIntLibGenericKeyHandlerProc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E158
|
2022-07-29 06:04:05 -07:00
|
|
|
static int gIntLibProgramDeleteCallbacksLength;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E15C
|
2022-07-29 06:04:05 -07:00
|
|
|
static Program* gIntLibGenericKeyHandlerProgram;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E160
|
2022-07-29 06:04:05 -07:00
|
|
|
static IntLibProgramDeleteCallback** gIntLibProgramDeleteCallbacks;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E164
|
2022-07-29 06:04:05 -07:00
|
|
|
static int gIntLibSayStartingPosition;
|
|
|
|
|
|
|
|
// 0x59E168
|
|
|
|
static char gIntLibPlayMovieFileName[100];
|
|
|
|
|
|
|
|
// 0x59E1CC
|
|
|
|
static char gIntLibPlayMovieRectFileName[100];
|
|
|
|
|
|
|
|
// fillwin3x3
|
|
|
|
// 0x461780
|
|
|
|
void opFillWin3x3(Program* program)
|
|
|
|
{
|
|
|
|
char* fileName = programStackPopString(program);
|
|
|
|
char* mangledFileName = _interpretMangleName(fileName);
|
|
|
|
|
|
|
|
int imageWidth;
|
|
|
|
int imageHeight;
|
|
|
|
unsigned char* imageData = datafileRead(mangledFileName, &imageWidth, &imageHeight);
|
|
|
|
if (imageData == NULL) {
|
|
|
|
programFatalError("cannot load 3x3 file '%s'", mangledFileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
int windowHeight = _windowHeight();
|
|
|
|
int windowWidth = _windowWidth();
|
|
|
|
unsigned char* windowBuffer = _windowGetBuffer();
|
|
|
|
_fillBuf3x3(imageData,
|
|
|
|
imageWidth,
|
|
|
|
imageHeight,
|
|
|
|
windowBuffer,
|
|
|
|
windowWidth,
|
|
|
|
windowHeight);
|
|
|
|
|
|
|
|
internal_free_safe(imageData, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 94
|
|
|
|
}
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// format
|
|
|
|
// 0x461850
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opFormat(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int textAlignment = programStackPopInteger(program);
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* string = programStackPopString(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (!_windowFormatMessage(string, x, y, width, height, textAlignment)) {
|
|
|
|
programFatalError("Error formatting message\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// print
|
|
|
|
// 0x461A5C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opPrint(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
switch (value.opcode & VALUE_TYPE_MASK) {
|
2022-05-19 01:51:26 -07:00
|
|
|
case VALUE_TYPE_STRING:
|
2022-07-05 01:00:55 -07:00
|
|
|
_interpretOutput("%s", programGetString(program, value.opcode, value.integerValue));
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
case VALUE_TYPE_FLOAT:
|
2022-07-05 01:00:55 -07:00
|
|
|
_interpretOutput("%.5f", value.floatValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
case VALUE_TYPE_INT:
|
2022-07-05 01:00:55 -07:00
|
|
|
_interpretOutput("%d", value.integerValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// selectfilelist
|
|
|
|
// 0x461B10
|
|
|
|
void opSelectFileList(Program* program)
|
|
|
|
{
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
char* pattern = programStackPopString(program);
|
|
|
|
char* title = programStackPopString(program);
|
|
|
|
|
|
|
|
int fileListLength;
|
|
|
|
char** fileList = _getFileList(_interpretMangleName(pattern), &fileListLength);
|
|
|
|
if (fileList != NULL && fileListLength != 0) {
|
|
|
|
int selectedIndex = _win_list_select(title,
|
|
|
|
fileList,
|
|
|
|
fileListLength,
|
|
|
|
NULL,
|
|
|
|
320 - fontGetStringWidth(title) / 2,
|
|
|
|
200,
|
|
|
|
_colorTable[0x7FFF] | 0x10000);
|
|
|
|
|
|
|
|
if (selectedIndex != -1) {
|
|
|
|
programStackPushString(program, fileList[selectedIndex]);
|
|
|
|
} else {
|
|
|
|
programStackPushInteger(program, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
_freeFileList(fileList);
|
|
|
|
} else {
|
|
|
|
programStackPushInteger(program, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tokenize
|
|
|
|
// 0x461CA0
|
|
|
|
void opTokenize(Program* program)
|
|
|
|
{
|
|
|
|
int ch = programStackPopInteger(program);
|
|
|
|
|
|
|
|
ProgramValue prevValue = programStackPopValue(program);
|
|
|
|
|
|
|
|
char* prev = NULL;
|
|
|
|
if ((prevValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (prevValue.integerValue != 0) {
|
|
|
|
programFatalError("Error, invalid arg 2 to tokenize. (only accept 0 for int value)");
|
|
|
|
}
|
|
|
|
} else if ((prevValue.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
prev = programGetString(program, prevValue.opcode, prevValue.integerValue);
|
|
|
|
} else {
|
|
|
|
programFatalError("Error, invalid arg 2 to tokenize. (string)");
|
|
|
|
}
|
|
|
|
|
|
|
|
char* string = programStackPopString(program);
|
|
|
|
char* temp = NULL;
|
|
|
|
|
|
|
|
if (prev != NULL) {
|
|
|
|
char* start = strstr(string, prev);
|
|
|
|
if (start != NULL) {
|
|
|
|
start += strlen(prev);
|
|
|
|
while (*start != ch && *start != '\0') {
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*start == ch) {
|
|
|
|
int length = 0;
|
|
|
|
char* end = start + 1;
|
|
|
|
while (*end != ch && *end != '\0') {
|
|
|
|
end++;
|
|
|
|
length++;
|
|
|
|
}
|
|
|
|
|
|
|
|
temp = (char*)internal_calloc_safe(1, length + 1, __FILE__, __LINE__); // "..\\int\\INTLIB.C, 230
|
|
|
|
strncpy(temp, start, length);
|
|
|
|
programStackPushString(program, temp);
|
|
|
|
} else {
|
|
|
|
programStackPushInteger(program, 0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
int length = 0;
|
|
|
|
char* end = string;
|
|
|
|
while (*end != ch && *end != '\0') {
|
|
|
|
end++;
|
|
|
|
length++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (string != NULL) {
|
|
|
|
temp = (char*)internal_calloc_safe(1, length + 1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 248
|
|
|
|
strncpy(temp, string, length);
|
|
|
|
programStackPushString(program, temp);
|
|
|
|
} else {
|
|
|
|
programStackPushInteger(program, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (temp != NULL) {
|
|
|
|
internal_free_safe(temp, __FILE__, __LINE__); // "..\\int\\INTLIB.C" , 260
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// printrect
|
|
|
|
// 0x461F1C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opPrintRect(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
if (v1 > 2) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Invalid arg 3 given to printrect, expecting int");
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
int v2 = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
char string[80];
|
2022-07-29 06:04:05 -07:00
|
|
|
switch (value.opcode & VALUE_TYPE_MASK) {
|
2022-05-19 01:51:26 -07:00
|
|
|
case VALUE_TYPE_STRING:
|
2022-07-05 01:00:55 -07:00
|
|
|
sprintf(string, "%s", programGetString(program, value.opcode, value.integerValue));
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
case VALUE_TYPE_FLOAT:
|
2022-07-05 01:00:55 -07:00
|
|
|
sprintf(string, "%.5f", value.floatValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
case VALUE_TYPE_INT:
|
2022-07-05 01:00:55 -07:00
|
|
|
sprintf(string, "%d", value.integerValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if (!_windowPrintRect(string, v2, v1)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error in printrect");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// 0x46209C
|
|
|
|
void opSelect(Program* program)
|
|
|
|
{
|
|
|
|
const char* windowName = programStackPopString(program);
|
|
|
|
int win = _pushWindow(windowName);
|
|
|
|
if (win == -1) {
|
|
|
|
programFatalError("Error selecing window %s\n", windowName);
|
|
|
|
}
|
|
|
|
|
|
|
|
program->windowId = win;
|
|
|
|
|
|
|
|
_interpretOutputFunc(_windowOutput);
|
|
|
|
}
|
|
|
|
|
|
|
|
// display
|
|
|
|
// 0x46213C
|
|
|
|
void opDisplay(Program* program)
|
|
|
|
{
|
|
|
|
char* fileName = programStackPopString(program);
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
char* mangledFileName = _interpretMangleName(fileName);
|
|
|
|
_displayFile(mangledFileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
// displayraw
|
|
|
|
// 0x4621B4
|
|
|
|
void opDisplayRaw(Program* program)
|
|
|
|
{
|
|
|
|
char* fileName = programStackPopString(program);
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
char* mangledFileName = _interpretMangleName(fileName);
|
|
|
|
_displayFileRaw(mangledFileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x46222C
|
2022-09-01 08:41:37 -07:00
|
|
|
static void _interpretFadePaletteBK(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration, int shouldProcessBk)
|
|
|
|
{
|
|
|
|
unsigned int time;
|
|
|
|
unsigned int previousTime;
|
|
|
|
unsigned int delta;
|
|
|
|
int step;
|
|
|
|
int steps;
|
|
|
|
int index;
|
|
|
|
unsigned char palette[256 * 3];
|
|
|
|
|
2022-10-05 00:11:47 -07:00
|
|
|
time = getTicks();
|
2022-09-01 08:41:37 -07:00
|
|
|
previousTime = time;
|
|
|
|
steps = (int)duration;
|
|
|
|
step = 0;
|
|
|
|
delta = 0;
|
|
|
|
|
2022-11-10 12:43:18 -08:00
|
|
|
// TODO: Check if it needs throttling.
|
2022-09-01 08:41:37 -07:00
|
|
|
if (duration != 0.0) {
|
|
|
|
while (step < steps) {
|
|
|
|
if (delta != 0) {
|
|
|
|
for (index = 0; index < 768; index++) {
|
|
|
|
palette[index] = oldPalette[index] - (oldPalette[index] - newPalette[index]) * step / steps;
|
|
|
|
}
|
|
|
|
|
|
|
|
_setSystemPalette(palette);
|
2022-11-10 12:43:18 -08:00
|
|
|
renderPresent();
|
2022-09-01 08:41:37 -07:00
|
|
|
|
|
|
|
previousTime = time;
|
|
|
|
step += delta;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldProcessBk) {
|
|
|
|
_process_bk();
|
|
|
|
}
|
|
|
|
|
2022-10-05 00:11:47 -07:00
|
|
|
time = getTicks();
|
2022-09-01 08:41:37 -07:00
|
|
|
delta = time - previousTime;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_setSystemPalette(newPalette);
|
2022-11-10 12:43:18 -08:00
|
|
|
renderPresent();
|
2022-09-01 08:41:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x462330
|
|
|
|
static void interpretFadePalette(unsigned char* oldPalette, unsigned char* newPalette, int a3, float duration)
|
|
|
|
{
|
|
|
|
_interpretFadePaletteBK(oldPalette, newPalette, a3, duration, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
static int intlibGetFadeIn()
|
2022-07-29 06:04:05 -07:00
|
|
|
{
|
2022-09-01 08:41:37 -07:00
|
|
|
return gIntLibIsPaletteFaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Inlined.
|
|
|
|
//
|
|
|
|
// 0x462348
|
|
|
|
static void interpretFadeOut(float duration)
|
|
|
|
{
|
|
|
|
int cursorWasHidden;
|
|
|
|
|
|
|
|
cursorWasHidden = cursorIsHidden();
|
|
|
|
mouseHideCursor();
|
|
|
|
|
|
|
|
_interpretFadePaletteBK(_getSystemPalette(), gIntLibFadePalette, 64, duration, 1);
|
|
|
|
|
|
|
|
if (!cursorWasHidden) {
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Inlined.
|
|
|
|
//
|
|
|
|
// 0x462380
|
|
|
|
static void interpretFadeIn(float duration)
|
|
|
|
{
|
|
|
|
_interpretFadePaletteBK(gIntLibFadePalette, _cmap, 64, duration, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x4623A4
|
|
|
|
static void interpretFadeOutNoBK(float duration)
|
|
|
|
{
|
|
|
|
int cursorWasHidden;
|
|
|
|
|
|
|
|
cursorWasHidden = cursorIsHidden();
|
|
|
|
mouseHideCursor();
|
|
|
|
|
|
|
|
_interpretFadePaletteBK(_getSystemPalette(), gIntLibFadePalette, 64, duration, 0);
|
|
|
|
|
|
|
|
if (!cursorWasHidden) {
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x4623DC
|
|
|
|
static void interpretFadeInNoBK(float duration)
|
|
|
|
{
|
|
|
|
_interpretFadePaletteBK(gIntLibFadePalette, _cmap, 64, duration, 0);
|
2022-07-29 06:04:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// fadein
|
|
|
|
// 0x462400
|
|
|
|
void opFadeIn(Program* program)
|
|
|
|
{
|
|
|
|
int data = programStackPopInteger(program);
|
|
|
|
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
_setSystemPalette(gIntLibFadePalette);
|
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
// NOTE: Uninline.
|
|
|
|
interpretFadeIn((float)data);
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibIsPaletteFaded = true;
|
|
|
|
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// fadeout
|
|
|
|
// 0x4624B4
|
|
|
|
void opFadeOut(Program* program)
|
|
|
|
{
|
|
|
|
int data = programStackPopInteger(program);
|
|
|
|
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
bool cursorWasHidden = cursorIsHidden();
|
|
|
|
mouseHideCursor();
|
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
// NOTE: Uninline.
|
|
|
|
interpretFadeOut((float)data);
|
2022-07-29 06:04:05 -07:00
|
|
|
|
|
|
|
if (!cursorWasHidden) {
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
gIntLibIsPaletteFaded = false;
|
|
|
|
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x462570
|
|
|
|
int intLibCheckMovie(Program* program)
|
|
|
|
{
|
|
|
|
if (_dialogGetDialogDepth() > 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return _windowMoviePlaying();
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// movieflags
|
|
|
|
// 0x462584
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetMovieFlags(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (!_windowSetMovieFlags(data)) {
|
|
|
|
programFatalError("Error setting movie flags\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// playmovie
|
|
|
|
// 0x4625D0
|
|
|
|
void opPlayMovie(Program* program)
|
|
|
|
{
|
|
|
|
char* movieFileName = programStackPopString(program);
|
|
|
|
|
|
|
|
strcpy(gIntLibPlayMovieFileName, movieFileName);
|
|
|
|
|
|
|
|
if (strrchr(gIntLibPlayMovieFileName, '.') == NULL) {
|
|
|
|
strcat(gIntLibPlayMovieFileName, ".mve");
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
program->flags |= PROGRAM_IS_WAITING;
|
|
|
|
program->checkWaitFunc = intLibCheckMovie;
|
2022-07-29 06:04:05 -07:00
|
|
|
|
|
|
|
char* mangledFileName = _interpretMangleName(gIntLibPlayMovieFileName);
|
|
|
|
if (!_windowPlayMovie(mangledFileName)) {
|
|
|
|
programFatalError("Error playing movie");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// playmovierect
|
|
|
|
// 0x4626C4
|
|
|
|
void opPlayMovieRect(Program* program)
|
|
|
|
{
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* movieFileName = programStackPopString(program);
|
|
|
|
|
|
|
|
strcpy(gIntLibPlayMovieRectFileName, movieFileName);
|
|
|
|
|
|
|
|
if (strrchr(gIntLibPlayMovieRectFileName, '.') == NULL) {
|
|
|
|
strcat(gIntLibPlayMovieRectFileName, ".mve");
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
program->checkWaitFunc = intLibCheckMovie;
|
|
|
|
program->flags |= PROGRAM_IS_WAITING;
|
2022-07-29 06:04:05 -07:00
|
|
|
|
|
|
|
char* mangledFileName = _interpretMangleName(gIntLibPlayMovieRectFileName);
|
|
|
|
if (!_windowPlayMovieRect(mangledFileName, x, y, width, height)) {
|
|
|
|
programFatalError("Error playing movie");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// stopmovie
|
|
|
|
// 0x46287C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opStopMovie(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
_windowStopMovie();
|
|
|
|
program->flags |= PROGRAM_FLAG_0x40;
|
|
|
|
}
|
|
|
|
|
|
|
|
// deleteregion
|
|
|
|
// 0x462890
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opDeleteRegion(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
switch (value.opcode & 0xF7FF) {
|
|
|
|
case VALUE_TYPE_STRING:
|
|
|
|
break;
|
|
|
|
case VALUE_TYPE_INT:
|
|
|
|
if (value.integerValue == -1) {
|
|
|
|
break;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-07-05 01:00:55 -07:00
|
|
|
// FALLTHROUGH
|
|
|
|
default:
|
|
|
|
programFatalError("Invalid type given to deleteregion");
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
const char* regionName = value.integerValue != -1 ? programGetString(program, value.opcode, value.integerValue) : NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
_windowDeleteRegion(regionName);
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// activateregion
|
|
|
|
// 0x462924
|
|
|
|
void opActivateRegion(Program* program)
|
|
|
|
{
|
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
char* regionName = programStackPopString(program);
|
|
|
|
|
|
|
|
_windowActivateRegion(regionName, v1);
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// checkregion
|
|
|
|
// 0x4629A0
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opCheckRegion(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
const char* regionName = programStackPopString(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
bool regionExists = _windowCheckRegionExists(regionName);
|
2022-07-05 01:00:55 -07:00
|
|
|
programStackPushInteger(program, regionExists);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// addregion
|
|
|
|
// 0x462A1C
|
|
|
|
void opAddRegion(Program* program)
|
|
|
|
{
|
|
|
|
int args = programStackPopInteger(program);
|
|
|
|
|
|
|
|
if (args < 2) {
|
|
|
|
programFatalError("addregion call without enough points!");
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
_windowStartRegion(args / 2);
|
|
|
|
|
|
|
|
while (args >= 2) {
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
y = (y * _windowGetYres() + 479) / 480;
|
|
|
|
x = (x * _windowGetXres() + 639) / 640;
|
|
|
|
args -= 2;
|
|
|
|
|
|
|
|
_windowAddRegionPoint(x, y, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args == 0) {
|
|
|
|
programFatalError("Unnamed regions not allowed\n");
|
|
|
|
_windowEndRegion();
|
|
|
|
} else {
|
|
|
|
const char* regionName = programStackPopString(program);
|
|
|
|
_windowAddRegionName(regionName);
|
|
|
|
_windowEndRegion();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// addregionproc
|
|
|
|
// 0x462C10
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddRegionProc(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
int v2 = programStackPopInteger(program);
|
|
|
|
int v3 = programStackPopInteger(program);
|
|
|
|
int v4 = programStackPopInteger(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
const char* regionName = programStackPopString(program);
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if (!_windowAddRegionProc(regionName, program, v4, v3, v2, v1)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting procedures to region %s\n", regionName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// addregionrightproc
|
|
|
|
// 0x462DDC
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddRegionRightProc(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
int v2 = programStackPopInteger(program);
|
|
|
|
const char* regionName = programStackPopString(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if (!_windowAddRegionRightProc(regionName, program, v2, v1)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("ErrorError setting right button procedures to region %s\n", regionName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// createwin
|
|
|
|
// 0x462F08
|
|
|
|
void opCreateWin(Program* program)
|
|
|
|
{
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* windowName = programStackPopString(program);
|
|
|
|
|
|
|
|
x = (x * _windowGetXres() + 639) / 640;
|
|
|
|
y = (y * _windowGetYres() + 479) / 480;
|
|
|
|
width = (width * _windowGetXres() + 639) / 640;
|
|
|
|
height = (height * _windowGetYres() + 479) / 480;
|
|
|
|
|
|
|
|
if (_createWindow(windowName, x, y, width, height, _colorTable[0], 0) == -1) {
|
|
|
|
programFatalError("Couldn't create window.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// resizewin
|
|
|
|
// 0x46308C
|
|
|
|
void opResizeWin(Program* program)
|
|
|
|
{
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* windowName = programStackPopString(program);
|
|
|
|
|
|
|
|
x = (x * _windowGetXres() + 639) / 640;
|
|
|
|
y = (y * _windowGetYres() + 479) / 480;
|
|
|
|
width = (width * _windowGetXres() + 639) / 640;
|
|
|
|
height = (height * _windowGetYres() + 479) / 480;
|
|
|
|
|
|
|
|
if (sub_4B7AC4(windowName, x, y, width, height) == -1) {
|
|
|
|
programFatalError("Couldn't resize window.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// scalewin
|
|
|
|
// 0x463204
|
|
|
|
void opScaleWin(Program* program)
|
|
|
|
{
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* windowName = programStackPopString(program);
|
|
|
|
|
|
|
|
x = (x * _windowGetXres() + 639) / 640;
|
|
|
|
y = (y * _windowGetYres() + 479) / 480;
|
|
|
|
width = (width * _windowGetXres() + 639) / 640;
|
|
|
|
height = (height * _windowGetYres() + 479) / 480;
|
|
|
|
|
|
|
|
if (sub_4B7E7C(windowName, x, y, width, height) == -1) {
|
|
|
|
programFatalError("Couldn't scale window.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// deletewin
|
|
|
|
// 0x46337C
|
|
|
|
void opDeleteWin(Program* program)
|
|
|
|
{
|
|
|
|
char* windowName = programStackPopString(program);
|
|
|
|
|
|
|
|
if (!_deleteWindow(windowName)) {
|
|
|
|
programFatalError("Error deleting window %s\n", windowName);
|
|
|
|
}
|
|
|
|
|
|
|
|
program->windowId = _popWindow();
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// saystart
|
|
|
|
// 0x4633E4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayStart(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibSayStartingPosition = 0;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
int rc = _dialogStart(program);
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
programFatalError("Error starting dialog.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// saystartpos
|
|
|
|
// 0x463430
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayStartPos(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibSayStartingPosition = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
int rc = _dialogStart(program);
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
if (rc != 0) {
|
|
|
|
programFatalError("Error starting dialog.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayreplytitle
|
|
|
|
// 0x46349C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayReplyTitle(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
char* string = NULL;
|
2022-07-29 06:04:05 -07:00
|
|
|
if ((value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
2022-07-05 01:00:55 -07:00
|
|
|
string = programGetString(program, value.opcode, value.integerValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dialogSetReplyTitle(string) != 0) {
|
|
|
|
programFatalError("Error setting title.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// saygotoreply
|
|
|
|
// 0x463510
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayGoToReply(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
char* string = NULL;
|
2022-07-29 06:04:05 -07:00
|
|
|
if ((value.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
2022-07-05 01:00:55 -07:00
|
|
|
string = programGetString(program, value.opcode, value.integerValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_dialogGotoReply(string) != 0) {
|
|
|
|
programFatalError("Error during goto, couldn't find reply target %s", string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// sayreply
|
|
|
|
// 0x463584
|
|
|
|
void opSayReply(Program* program)
|
|
|
|
{
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
ProgramValue v3 = programStackPopValue(program);
|
|
|
|
ProgramValue v2 = programStackPopValue(program);
|
|
|
|
|
|
|
|
const char* v1;
|
|
|
|
if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v2.opcode, v2.integerValue);
|
|
|
|
} else {
|
|
|
|
v1 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
const char* v2 = programGetString(program, v3.opcode, v3.integerValue);
|
|
|
|
if (_dialogOption(v1, v2) != 0) {
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
programFatalError("Error setting option.");
|
|
|
|
}
|
|
|
|
} else if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (_dialogOptionProc(v1, v3.integerValue) != 0) {
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
programFatalError("Error setting option.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
programFatalError("Invalid arg 2 to sayOption");
|
|
|
|
}
|
|
|
|
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayoption
|
|
|
|
void opSayOption(Program* program)
|
|
|
|
{
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
ProgramValue v3 = programStackPopValue(program);
|
|
|
|
ProgramValue v4 = programStackPopValue(program);
|
|
|
|
|
|
|
|
const char* v1;
|
|
|
|
if ((v4.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v4.opcode, v4.integerValue);
|
|
|
|
} else {
|
|
|
|
v1 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* v2;
|
|
|
|
if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v2 = programGetString(program, v3.opcode, v3.integerValue);
|
|
|
|
} else {
|
|
|
|
v2 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_dialogReply(v1, v2) != 0) {
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
programFatalError("Error setting option.");
|
|
|
|
}
|
|
|
|
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x46378C
|
|
|
|
int intLibCheckDialog(Program* program)
|
|
|
|
{
|
|
|
|
program->flags |= PROGRAM_FLAG_0x40;
|
|
|
|
return _dialogGetDialogDepth() != -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4637A4
|
|
|
|
void opSayEnd(Program* program)
|
|
|
|
{
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
int rc = sub_431088(gIntLibSayStartingPosition);
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
if (rc == -2) {
|
2022-09-01 08:41:37 -07:00
|
|
|
program->checkWaitFunc = intLibCheckDialog;
|
|
|
|
program->flags |= PROGRAM_IS_WAITING;
|
2022-07-29 06:04:05 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// saygetlastpos
|
|
|
|
// 0x4637EC
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayGetLastPos(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int value = _dialogGetExitPoint();
|
2022-07-05 01:00:55 -07:00
|
|
|
programStackPushInteger(program, value);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// sayquit
|
|
|
|
// 0x463810
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayQuit(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (_dialogQuit() != 0) {
|
|
|
|
programFatalError("Error quitting option.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x463828
|
|
|
|
static int getTimeOut()
|
|
|
|
{
|
|
|
|
return _TimeOut;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: Unused.
|
|
|
|
//
|
|
|
|
// 0x463830
|
|
|
|
static void setTimeOut(int value)
|
|
|
|
{
|
|
|
|
_TimeOut = value;
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// saymessagetimeout
|
|
|
|
// 0x463838
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayMessageTimeout(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// TODO: What the hell is this?
|
2022-07-29 06:04:05 -07:00
|
|
|
if ((value.opcode & VALUE_TYPE_MASK) == 0x4000) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("sayMsgTimeout: invalid var type passed.");
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
_TimeOut = value.integerValue;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// saymessage
|
|
|
|
// 0x463890
|
|
|
|
void opSayMessage(Program* program)
|
|
|
|
{
|
|
|
|
program->flags |= PROGRAM_FLAG_0x20;
|
|
|
|
|
|
|
|
ProgramValue v3 = programStackPopValue(program);
|
|
|
|
ProgramValue v4 = programStackPopValue(program);
|
|
|
|
|
|
|
|
const char* v1;
|
|
|
|
if ((v4.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v4.opcode, v4.integerValue);
|
|
|
|
} else {
|
|
|
|
v1 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* v2;
|
|
|
|
if ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v2 = programGetString(program, v3.opcode, v3.integerValue);
|
|
|
|
} else {
|
|
|
|
v2 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sub_430FD4(v1, v2, _TimeOut) != 0) {
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
programFatalError("Error setting option.");
|
|
|
|
}
|
|
|
|
|
|
|
|
program->flags &= ~PROGRAM_FLAG_0x20;
|
|
|
|
}
|
|
|
|
|
|
|
|
// gotoxy
|
|
|
|
// 0x463980
|
|
|
|
void opGotoXY(Program* program)
|
|
|
|
{
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
_windowGotoXY(x, y);
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// addbuttonflag
|
|
|
|
// 0x463A38
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddButtonFlag(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int flag = programStackPopInteger(program);
|
|
|
|
const char* buttonName = programStackPopString(program);
|
|
|
|
if (!_windowSetButtonFlag(buttonName, flag)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
// NOTE: Original code calls programGetString one more time with the
|
|
|
|
// same params.
|
|
|
|
programFatalError("Error setting flag on button %s", buttonName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// addregionflag
|
|
|
|
// 0x463B10
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddRegionFlag(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int flag = programStackPopInteger(program);
|
|
|
|
const char* regionName = programStackPopString(program);
|
|
|
|
if (!_windowSetRegionFlag(regionName, flag)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
// NOTE: Original code calls programGetString one more time with the
|
|
|
|
// same params.
|
|
|
|
programFatalError("Error setting flag on region %s", regionName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// addbutton
|
|
|
|
// 0x463BE8
|
|
|
|
void opAddButton(Program* program)
|
|
|
|
{
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* buttonName = programStackPopString(program);
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
height = (height * _windowGetYres() + 479) / 480;
|
|
|
|
width = (width * _windowGetXres() + 639) / 640;
|
|
|
|
y = (y * _windowGetYres() + 479) / 480;
|
|
|
|
x = (x * _windowGetXres() + 639) / 640;
|
|
|
|
|
|
|
|
_windowAddButton(buttonName, x, y, width, height, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// addbuttontext
|
|
|
|
// 0x463DF4
|
|
|
|
void opAddButtonText(Program* program)
|
|
|
|
{
|
|
|
|
const char* text = programStackPopString(program);
|
|
|
|
const char* buttonName = programStackPopString(program);
|
|
|
|
|
|
|
|
if (!_windowAddButtonText(buttonName, text)) {
|
|
|
|
programFatalError("Error setting text to button %s\n", buttonName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// addbuttongfx
|
|
|
|
// 0x463EEC
|
|
|
|
void opAddButtonGfx(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue v1 = programStackPopValue(program);
|
|
|
|
ProgramValue v2 = programStackPopValue(program);
|
|
|
|
ProgramValue v3 = programStackPopValue(program);
|
|
|
|
char* buttonName = programStackPopString(program);
|
|
|
|
|
|
|
|
if (((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING || ((v3.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v3.integerValue == 0))
|
|
|
|
|| ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING || ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v2.integerValue == 0))
|
|
|
|
|| ((v1.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING || ((v1.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v1.integerValue == 0))) {
|
|
|
|
char* pressedFileName = _interpretMangleName(programGetString(program, v3.opcode, v3.integerValue));
|
|
|
|
char* normalFileName = _interpretMangleName(programGetString(program, v2.opcode, v2.integerValue));
|
|
|
|
char* hoverFileName = _interpretMangleName(programGetString(program, v1.opcode, v1.integerValue));
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
if (!_windowAddButtonGfx(buttonName, pressedFileName, normalFileName, hoverFileName)) {
|
|
|
|
programFatalError("Error setting graphics to button %s\n", buttonName);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
programFatalError("Invalid filename given to addbuttongfx");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// addbuttonproc
|
|
|
|
// 0x4640DC
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddButtonProc(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
int v2 = programStackPopInteger(program);
|
|
|
|
int v3 = programStackPopInteger(program);
|
|
|
|
int v4 = programStackPopInteger(program);
|
|
|
|
const char* buttonName = programStackPopString(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if (!_windowAddButtonProc(buttonName, program, v4, v3, v2, v1)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting procedures to button %s\n", buttonName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// addbuttonrightproc
|
|
|
|
// 0x4642A8
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddButtonRightProc(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
int v2 = programStackPopInteger(program);
|
|
|
|
const char* regionName = programStackPopString(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if (!_windowAddRegionRightProc(regionName, program, v2, v1)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting right button procedures to button %s\n", regionName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// showwin
|
|
|
|
// 0x4643D4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opShowWin(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
_windowDraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
// deletebutton
|
|
|
|
// 0x4643E4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opDeleteButton(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
switch (value.opcode & VALUE_TYPE_MASK) {
|
2022-07-05 01:00:55 -07:00
|
|
|
case VALUE_TYPE_STRING:
|
|
|
|
break;
|
|
|
|
case VALUE_TYPE_INT:
|
|
|
|
if (value.integerValue == -1) {
|
|
|
|
break;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-07-05 01:00:55 -07:00
|
|
|
// FALLTHROUGH
|
|
|
|
default:
|
|
|
|
programFatalError("Invalid type given to delete button");
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
_selectWindowID(program->windowId);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if ((value.opcode & 0xF7FF) == VALUE_TYPE_INT) {
|
2022-05-19 01:51:26 -07:00
|
|
|
if (_windowDeleteButton(NULL)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
2022-07-05 01:00:55 -07:00
|
|
|
const char* buttonName = programGetString(program, value.opcode, value.integerValue);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (_windowDeleteButton(buttonName)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2022-07-29 06:04:05 -07:00
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error deleting button");
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// fillwin
|
|
|
|
// 0x46449C
|
|
|
|
void opFillWin(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue b = programStackPopValue(program);
|
|
|
|
ProgramValue g = programStackPopValue(program);
|
|
|
|
ProgramValue r = programStackPopValue(program);
|
|
|
|
|
|
|
|
if ((r.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT) {
|
|
|
|
if ((r.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (r.integerValue == 1) {
|
|
|
|
r.floatValue = 1.0;
|
|
|
|
} else if (r.integerValue != 0) {
|
|
|
|
programFatalError("Invalid red value given to fillwin");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((g.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT) {
|
|
|
|
if ((g.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (g.integerValue == 1) {
|
|
|
|
g.floatValue = 1.0;
|
|
|
|
} else if (g.integerValue != 0) {
|
|
|
|
programFatalError("Invalid green value given to fillwin");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((b.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT) {
|
|
|
|
if ((b.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (b.integerValue == 1) {
|
|
|
|
b.floatValue = 1.0;
|
|
|
|
} else if (b.integerValue != 0) {
|
|
|
|
programFatalError("Invalid blue value given to fillwin");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
_windowFill(r.floatValue, g.floatValue, b.floatValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
// fillrect
|
|
|
|
// 0x4645FC
|
|
|
|
void opFillRect(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue b = programStackPopValue(program);
|
|
|
|
ProgramValue g = programStackPopValue(program);
|
|
|
|
ProgramValue r = programStackPopValue(program);
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
if ((r.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT) {
|
|
|
|
if ((r.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (r.integerValue == 1) {
|
|
|
|
r.floatValue = 1.0;
|
|
|
|
} else if (r.integerValue != 0) {
|
|
|
|
programFatalError("Invalid red value given to fillwin");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((g.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT) {
|
|
|
|
if ((g.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (g.integerValue == 1) {
|
|
|
|
g.floatValue = 1.0;
|
|
|
|
} else if (g.integerValue != 0) {
|
|
|
|
programFatalError("Invalid green value given to fillwin");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((b.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT) {
|
|
|
|
if ((b.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (b.integerValue == 1) {
|
|
|
|
b.floatValue = 1.0;
|
|
|
|
} else if (b.integerValue != 0) {
|
|
|
|
programFatalError("Invalid blue value given to fillwin");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->windowId);
|
|
|
|
|
|
|
|
_windowFillRect(x, y, width, height, r.floatValue, g.floatValue, b.floatValue);
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// hidemouse
|
|
|
|
// 0x46489C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opHideMouse(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
mouseHideCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
// showmouse
|
|
|
|
// 0x4648A4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opShowMouse(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
mouseShowCursor();
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// mouseshape
|
|
|
|
// 0x4648AC
|
|
|
|
void opMouseShape(Program* program)
|
|
|
|
{
|
|
|
|
int v1 = programStackPopInteger(program);
|
|
|
|
int v2 = programStackPopInteger(program);
|
|
|
|
char* fileName = programStackPopString(program);
|
|
|
|
|
|
|
|
if (!mouseManagerSetMouseShape(fileName, v2, v1)) {
|
|
|
|
programFatalError("Error loading mouse shape.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// setglobalmousefunc
|
|
|
|
// 0x4649C4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetGlobalMouseFunc(Program* Program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
programFatalError("setglobalmousefunc not defined");
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// displaygfx
|
|
|
|
// 0x4649D4
|
|
|
|
void opDisplayGfx(Program* program)
|
|
|
|
{
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
char* fileName = programStackPopString(program);
|
|
|
|
|
|
|
|
char* mangledFileName = _interpretMangleName(fileName);
|
|
|
|
_windowDisplay(mangledFileName, x, y, width, height);
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// loadpalettetable
|
|
|
|
// 0x464ADC
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opLoadPaletteTable(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
char* path = programStackPopString(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (!colorPaletteLoad(path)) {
|
|
|
|
programFatalError(_colorError());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// addnamedevent
|
|
|
|
// 0x464B54
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddNamedEvent(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int proc = programStackPopInteger(program);
|
2022-07-06 04:59:54 -07:00
|
|
|
const char* name = programStackPopString(program);
|
|
|
|
_nevs_addevent(name, program, proc, NEVS_TYPE_EVENT);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// addnamedhandler
|
|
|
|
// 0x464BE8
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddNamedHandler(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int proc = programStackPopInteger(program);
|
2022-07-06 04:59:54 -07:00
|
|
|
const char* name = programStackPopString(program);
|
|
|
|
_nevs_addevent(name, program, proc, NEVS_TYPE_HANDLER);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// clearnamed
|
|
|
|
// 0x464C80
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opClearNamed(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
char* string = programStackPopString(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
_nevs_clearevent(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
// signalnamed
|
|
|
|
// 0x464CE4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSignalNamed(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
char* str = programStackPopString(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
_nevs_signal(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
// addkey
|
|
|
|
// 0x464D48
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opAddKey(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int proc = programStackPopInteger(program);
|
|
|
|
int key = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (key == -1) {
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibGenericKeyHandlerProc = proc;
|
|
|
|
gIntLibGenericKeyHandlerProgram = program;
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-07-29 06:04:05 -07:00
|
|
|
if (key > INT_LIB_KEY_HANDLERS_CAPACITY - 1) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Key out of range");
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibKeyHandlerEntries[key].program = program;
|
|
|
|
gIntLibKeyHandlerEntries[key].proc = proc;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// deletekey
|
|
|
|
// 0x464E24
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opDeleteKey(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int key = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (key == -1) {
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibGenericKeyHandlerProc = 0;
|
|
|
|
gIntLibGenericKeyHandlerProgram = NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-07-29 06:04:05 -07:00
|
|
|
if (key > INT_LIB_KEY_HANDLERS_CAPACITY - 1) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Key out of range");
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibKeyHandlerEntries[key].program = NULL;
|
|
|
|
gIntLibKeyHandlerEntries[key].proc = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// refreshmouse
|
|
|
|
// 0x464EB0
|
|
|
|
void opRefreshMouse(Program* program)
|
|
|
|
{
|
|
|
|
int data = programStackPopInteger(program);
|
|
|
|
|
|
|
|
if (!_windowRefreshRegions()) {
|
|
|
|
_executeProc(program, data);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// setfont
|
|
|
|
// 0x464F18
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetFont(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
if (!windowSetFont(data)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting font");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// setflags
|
|
|
|
// 0x464F84
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetTextFlags(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
if (!windowSetTextFlags(data)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting text flags");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// settextcolor
|
|
|
|
// 0x464FF0
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetTextColor(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value[3];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// NOTE: Original code does not use loops.
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-07-05 01:00:55 -07:00
|
|
|
value[arg] = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-10-28 00:35:22 -07:00
|
|
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
|
|
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
|
|
|
&& value[arg].integerValue != 0) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Invalid type given to settextcolor");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
float r = value[2].floatValue;
|
|
|
|
float g = value[1].floatValue;
|
|
|
|
float b = value[0].floatValue;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
if (!windowSetTextColor(r, g, b)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting text color");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayoptioncolor
|
|
|
|
// 0x465140
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayOptionColor(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value[3];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// NOTE: Original code does not use loops.
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-07-05 01:00:55 -07:00
|
|
|
value[arg] = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-10-28 00:35:22 -07:00
|
|
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
|
|
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
|
|
|
&& value[arg].integerValue != 0) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Invalid type given to sayoptioncolor");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
float r = value[2].floatValue;
|
|
|
|
float g = value[1].floatValue;
|
|
|
|
float b = value[0].floatValue;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (dialogSetOptionColor(r, g, b)) {
|
|
|
|
programFatalError("Error setting option color");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayreplycolor
|
|
|
|
// 0x465290
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayReplyColor(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value[3];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// NOTE: Original code does not use loops.
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-07-05 01:00:55 -07:00
|
|
|
value[arg] = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-10-28 00:35:22 -07:00
|
|
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
|
|
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
|
|
|
&& value[arg].integerValue != 0) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Invalid type given to sayreplycolor");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
float r = value[2].floatValue;
|
|
|
|
float g = value[1].floatValue;
|
|
|
|
float b = value[0].floatValue;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (dialogSetReplyColor(r, g, b) != 0) {
|
|
|
|
programFatalError("Error setting reply color");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sethighlightcolor
|
|
|
|
// 0x4653E0
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetHighlightColor(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
ProgramValue value[3];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// NOTE: Original code does not use loops.
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-07-05 01:00:55 -07:00
|
|
|
value[arg] = programStackPopValue(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for (int arg = 0; arg < 3; arg++) {
|
2022-10-28 00:35:22 -07:00
|
|
|
if ((value[arg].opcode & VALUE_TYPE_MASK) != VALUE_TYPE_FLOAT
|
|
|
|
&& (value[arg].opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT
|
|
|
|
&& value[arg].integerValue != 0) {
|
2022-07-05 01:00:55 -07:00
|
|
|
programFatalError("Invalid type given to sayreplycolor");
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
float r = value[2].floatValue;
|
|
|
|
float g = value[1].floatValue;
|
|
|
|
float b = value[0].floatValue;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-09-01 08:41:37 -07:00
|
|
|
if (!windowSetHighlightColor(r, g, b)) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting text highlight color");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// sayreplywindow
|
|
|
|
// 0x465530
|
|
|
|
void opSayReplyWindow(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue v2 = programStackPopValue(program);
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
char* v1;
|
|
|
|
if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v2.opcode, v2.integerValue);
|
|
|
|
v1 = _interpretMangleName(v1);
|
|
|
|
v1 = strdup_safe(v1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1510
|
|
|
|
} else if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v2.integerValue == 0) {
|
|
|
|
v1 = NULL;
|
|
|
|
} else {
|
|
|
|
programFatalError("Invalid arg 5 given to sayreplywindow");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dialogSetReplyWindow(x, y, width, height, v1) != 0) {
|
|
|
|
programFatalError("Error setting reply window");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// sayreplyflags
|
|
|
|
// 0x465688
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayReplyFlags(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (!_dialogSetOptionFlags(data)) {
|
|
|
|
programFatalError("Error setting reply flags");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayoptionflags
|
|
|
|
// 0x4656F4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayOptionFlags(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (!_dialogSetOptionFlags(data)) {
|
|
|
|
programFatalError("Error setting option flags");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// sayoptionwindow
|
|
|
|
// 0x465760
|
|
|
|
void opSayOptionWindow(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue v2 = programStackPopValue(program);
|
|
|
|
int height = programStackPopInteger(program);
|
|
|
|
int width = programStackPopInteger(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
char* v1;
|
|
|
|
if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v2.opcode, v2.integerValue);
|
|
|
|
v1 = _interpretMangleName(v1);
|
|
|
|
v1 = strdup_safe(v1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1556
|
|
|
|
} else if ((v2.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v2.integerValue == 0) {
|
|
|
|
v1 = NULL;
|
|
|
|
} else {
|
|
|
|
programFatalError("Invalid arg 5 given to sayoptionwindow");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dialogSetOptionWindow(x, y, width, height, v1) != 0) {
|
|
|
|
programFatalError("Error setting option window");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// sayborder
|
|
|
|
// 0x4658B8
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayBorder(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-05 01:00:55 -07:00
|
|
|
if (dialogSetBorder(x, y) != 0) {
|
2022-05-19 01:51:26 -07:00
|
|
|
programFatalError("Error setting dialog border");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
// sayscrollup
|
|
|
|
// 0x465978
|
|
|
|
void opSayScrollUp(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue v6 = programStackPopValue(program);
|
|
|
|
ProgramValue v7 = programStackPopValue(program);
|
|
|
|
ProgramValue v8 = programStackPopValue(program);
|
|
|
|
ProgramValue v9 = programStackPopValue(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
char* v1 = NULL;
|
|
|
|
char* v2 = NULL;
|
|
|
|
char* v3 = NULL;
|
|
|
|
char* v4 = NULL;
|
|
|
|
int v5 = 0;
|
|
|
|
|
|
|
|
if ((v6.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (v6.integerValue != -1 && v6.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 4 given to sayscrollup");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (v6.integerValue == -1) {
|
|
|
|
v5 = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((v6.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING) {
|
|
|
|
programFatalError("Invalid arg 4 given to sayscrollup");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v7.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING && (v7.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v7.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 3 given to sayscrollup");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v8.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING && (v8.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v8.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 2 given to sayscrollup");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v9.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING && (v9.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v9.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 1 given to sayscrollup");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v9.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v9.opcode, v9.integerValue);
|
|
|
|
v1 = _interpretMangleName(v1);
|
|
|
|
v1 = strdup_safe(v1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1611
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v8.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v2 = programGetString(program, v8.opcode, v8.integerValue);
|
|
|
|
v2 = _interpretMangleName(v2);
|
|
|
|
v2 = strdup_safe(v2, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1613
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v7.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v3 = programGetString(program, v7.opcode, v7.integerValue);
|
|
|
|
v3 = _interpretMangleName(v3);
|
|
|
|
v3 = strdup_safe(v3, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1615
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v6.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v4 = programGetString(program, v6.opcode, v6.integerValue);
|
|
|
|
v4 = _interpretMangleName(v4);
|
|
|
|
v4 = strdup_safe(v4, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1617
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_dialogSetScrollUp(x, y, v1, v2, v3, v4, v5) != 0) {
|
|
|
|
programFatalError("Error setting scroll up");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayscrolldown
|
|
|
|
// 0x465CAC
|
|
|
|
void opSayScrollDown(Program* program)
|
|
|
|
{
|
|
|
|
ProgramValue v6 = programStackPopValue(program);
|
|
|
|
ProgramValue v7 = programStackPopValue(program);
|
|
|
|
ProgramValue v8 = programStackPopValue(program);
|
|
|
|
ProgramValue v9 = programStackPopValue(program);
|
|
|
|
int y = programStackPopInteger(program);
|
|
|
|
int x = programStackPopInteger(program);
|
|
|
|
|
|
|
|
char* v1 = NULL;
|
|
|
|
char* v2 = NULL;
|
|
|
|
char* v3 = NULL;
|
|
|
|
char* v4 = NULL;
|
|
|
|
int v5 = 0;
|
|
|
|
|
|
|
|
if ((v6.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT) {
|
|
|
|
if (v6.integerValue != -1 && v6.integerValue != 0) {
|
|
|
|
// FIXME: Wrong function name, should be sayscrolldown.
|
|
|
|
programFatalError("Invalid arg 4 given to sayscrollup");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (v6.integerValue == -1) {
|
|
|
|
v5 = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((v6.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING) {
|
|
|
|
// FIXME: Wrong function name, should be sayscrolldown.
|
|
|
|
programFatalError("Invalid arg 4 given to sayscrollup");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v7.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING && (v7.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v7.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 3 given to sayscrolldown");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v8.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING && (v8.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v8.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 2 given to sayscrolldown");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v9.opcode & VALUE_TYPE_MASK) != VALUE_TYPE_STRING && (v9.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_INT && v9.integerValue != 0) {
|
|
|
|
programFatalError("Invalid arg 1 given to sayscrolldown");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v9.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v1 = programGetString(program, v9.opcode, v9.integerValue);
|
|
|
|
v1 = _interpretMangleName(v1);
|
|
|
|
v1 = strdup_safe(v1, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1652
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v8.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v2 = programGetString(program, v8.opcode, v8.integerValue);
|
|
|
|
v2 = _interpretMangleName(v2);
|
|
|
|
v2 = strdup_safe(v2, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1654
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v7.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v3 = programGetString(program, v7.opcode, v7.integerValue);
|
|
|
|
v3 = _interpretMangleName(v3);
|
|
|
|
v3 = strdup_safe(v3, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1656
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((v6.opcode & VALUE_TYPE_MASK) == VALUE_TYPE_STRING) {
|
|
|
|
v4 = programGetString(program, v6.opcode, v6.integerValue);
|
|
|
|
v4 = _interpretMangleName(v4);
|
|
|
|
v4 = strdup_safe(v4, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1658
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_dialogSetScrollDown(x, y, v1, v2, v3, v4, v5) != 0) {
|
|
|
|
programFatalError("Error setting scroll down");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// saysetspacing
|
|
|
|
// 0x465FE0
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSaySetSpacing(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (dialogSetOptionSpacing(data) != 0) {
|
|
|
|
programFatalError("Error setting option spacing");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// sayrestart
|
|
|
|
// 0x46604C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayRestart(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (_dialogRestart() != 0) {
|
|
|
|
programFatalError("Error restarting option");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466064
|
2022-07-29 06:04:05 -07:00
|
|
|
static void intLibSoundCallback(void* userData, int a2)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (a2 == 1) {
|
|
|
|
Sound** sound = (Sound**)userData;
|
|
|
|
*sound = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466070
|
2022-07-29 06:04:05 -07:00
|
|
|
static int intLibSoundDelete(int value)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (value == -1) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value & 0xA0000000) == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = value & ~0xA0000000;
|
2022-07-29 06:04:05 -07:00
|
|
|
Sound* sound = gIntLibSounds[index];
|
2022-05-19 01:51:26 -07:00
|
|
|
if (sound == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (soundIsPlaying(sound)) {
|
|
|
|
soundStop(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
soundDelete(sound);
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibSounds[index] = NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466110
|
2022-07-29 06:04:05 -07:00
|
|
|
static int intLibSoundPlay(char* fileName, int mode)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int v3 = 1;
|
|
|
|
int v5 = 0;
|
|
|
|
|
|
|
|
if (mode & 0x01) {
|
|
|
|
// looping
|
|
|
|
v5 |= 0x20;
|
|
|
|
} else {
|
|
|
|
v3 = 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode & 0x02) {
|
|
|
|
v5 |= 0x08;
|
|
|
|
} else {
|
|
|
|
v5 |= 0x10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode & 0x0100) {
|
|
|
|
// memory
|
|
|
|
v3 &= ~0x03;
|
|
|
|
v3 |= 0x01;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode & 0x0200) {
|
|
|
|
// streamed
|
|
|
|
v3 &= ~0x03;
|
|
|
|
v3 |= 0x02;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index;
|
2022-07-29 06:04:05 -07:00
|
|
|
for (index = 0; index < INT_LIB_SOUNDS_CAPACITY; index++) {
|
|
|
|
if (gIntLibSounds[index] == NULL) {
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
if (index == INT_LIB_SOUNDS_CAPACITY) {
|
2022-05-19 01:51:26 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
Sound* sound = gIntLibSounds[index] = soundAllocate(v3, v5);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (sound == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
soundSetCallback(sound, intLibSoundCallback, &(gIntLibSounds[index]));
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (mode & 0x01) {
|
|
|
|
soundSetLooping(sound, 0xFFFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode & 0x1000) {
|
|
|
|
// mono
|
|
|
|
soundSetChannels(sound, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode & 0x2000) {
|
|
|
|
// stereo
|
|
|
|
soundSetChannels(sound, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
int rc = soundLoad(sound, fileName);
|
|
|
|
if (rc != SOUND_NO_ERROR) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = soundPlay(sound);
|
|
|
|
|
|
|
|
// TODO: Maybe wrong.
|
|
|
|
switch (rc) {
|
|
|
|
case SOUND_NO_DEVICE:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NO_DEVICE");
|
|
|
|
goto err;
|
|
|
|
case SOUND_NOT_INITIALIZED:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NOT_INITIALIZED");
|
|
|
|
goto err;
|
|
|
|
case SOUND_NO_SOUND:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NO_SOUND");
|
|
|
|
goto err;
|
|
|
|
case SOUND_FUNCTION_NOT_SUPPORTED:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_FUNC_NOT_SUPPORTED");
|
|
|
|
goto err;
|
|
|
|
case SOUND_NO_BUFFERS_AVAILABLE:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NO_BUFFERS_AVAILABLE");
|
|
|
|
goto err;
|
|
|
|
case SOUND_FILE_NOT_FOUND:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_FILE_NOT_FOUND");
|
|
|
|
goto err;
|
|
|
|
case SOUND_ALREADY_PLAYING:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_ALREADY_PLAYING");
|
|
|
|
goto err;
|
|
|
|
case SOUND_NOT_PLAYING:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NOT_PLAYING");
|
|
|
|
goto err;
|
|
|
|
case SOUND_ALREADY_PAUSED:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_ALREADY_PAUSED");
|
|
|
|
goto err;
|
|
|
|
case SOUND_NOT_PAUSED:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NOT_PAUSED");
|
|
|
|
goto err;
|
|
|
|
case SOUND_INVALID_HANDLE:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_INVALID_HANDLE");
|
|
|
|
goto err;
|
|
|
|
case SOUND_NO_MEMORY_AVAILABLE:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_NO_MEMORY");
|
|
|
|
goto err;
|
|
|
|
case SOUND_UNKNOWN_ERROR:
|
|
|
|
debugPrint("soundPlay error: %s\n", "SOUND_ERROR");
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return index | 0xA0000000;
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
|
|
|
soundDelete(sound);
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibSounds[index] = NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x46655C
|
2022-07-29 06:04:05 -07:00
|
|
|
static int intLibSoundPause(int value)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (value == -1) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value & 0xA0000000) == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = value & ~0xA0000000;
|
2022-07-29 06:04:05 -07:00
|
|
|
Sound* sound = gIntLibSounds[index];
|
2022-05-19 01:51:26 -07:00
|
|
|
if (sound == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rc;
|
|
|
|
if (_soundType(sound, 0x01)) {
|
|
|
|
rc = soundStop(sound);
|
|
|
|
} else {
|
|
|
|
rc = soundPause(sound);
|
|
|
|
}
|
|
|
|
return rc == SOUND_NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4665C8
|
2022-07-29 06:04:05 -07:00
|
|
|
static int intLibSoundRewind(int value)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (value == -1) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value & 0xA0000000) == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = value & ~0xA0000000;
|
2022-07-29 06:04:05 -07:00
|
|
|
Sound* sound = gIntLibSounds[index];
|
2022-05-19 01:51:26 -07:00
|
|
|
if (sound == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!soundIsPlaying(sound)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
soundStop(sound);
|
|
|
|
|
|
|
|
return soundPlay(sound) == SOUND_NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x46662C
|
2022-07-29 06:04:05 -07:00
|
|
|
static int intLibSoundResume(int value)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (value == -1) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value & 0xA0000000) == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = value & ~0xA0000000;
|
2022-07-29 06:04:05 -07:00
|
|
|
Sound* sound = gIntLibSounds[index];
|
2022-05-19 01:51:26 -07:00
|
|
|
if (sound == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int rc;
|
|
|
|
if (_soundType(sound, 0x01)) {
|
|
|
|
rc = soundPlay(sound);
|
|
|
|
} else {
|
|
|
|
rc = soundResume(sound);
|
|
|
|
}
|
|
|
|
return rc == SOUND_NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// soundplay
|
|
|
|
// 0x466698
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundPlay(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
int flags = programStackPopInteger(program);
|
|
|
|
char* fileName = programStackPopString(program);
|
|
|
|
|
|
|
|
char* mangledFileName = _interpretMangleName(fileName);
|
|
|
|
int rc = intLibSoundPlay(mangledFileName, flags);
|
|
|
|
|
|
|
|
programStackPushInteger(program, rc);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// soundpause
|
|
|
|
// 0x466768
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundPause(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
intLibSoundPause(data);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// soundresume
|
|
|
|
// 0x4667C0
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundResume(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
intLibSoundResume(data);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// soundstop
|
|
|
|
// 0x466818
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundStop(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
intLibSoundPause(data);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// soundrewind
|
|
|
|
// 0x466870
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundRewind(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
intLibSoundRewind(data);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// sounddelete
|
|
|
|
// 0x4668C8
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSoundDelete(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-07-29 06:04:05 -07:00
|
|
|
intLibSoundDelete(data);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetOneOptPause
|
|
|
|
// 0x466920
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSetOneOptPause(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-05 01:00:55 -07:00
|
|
|
int data = programStackPopInteger(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if ((_dialogGetMediaFlag() & 8) == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((_dialogGetMediaFlag() & 8) != 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_dialogToggleMediaFlag(8);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466994
|
2022-07-29 06:04:05 -07:00
|
|
|
void intLibUpdate()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
_nevs_update();
|
2022-07-29 06:04:05 -07:00
|
|
|
intExtraUpdate();
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4669A0
|
2022-07-29 06:04:05 -07:00
|
|
|
void intLibExit()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
_dialogClose();
|
|
|
|
_intExtraClose_();
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
for (int index = 0; index < INT_LIB_SOUNDS_CAPACITY; index++) {
|
|
|
|
if (gIntLibSounds[index] != NULL) {
|
|
|
|
intLibSoundDelete(index | 0xA0000000);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_nevs_close();
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
if (gIntLibProgramDeleteCallbacks != NULL) {
|
|
|
|
internal_free_safe(gIntLibProgramDeleteCallbacks, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1976
|
|
|
|
gIntLibProgramDeleteCallbacks = NULL;
|
|
|
|
gIntLibProgramDeleteCallbacksLength = 0;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466A04
|
2022-07-29 06:04:05 -07:00
|
|
|
static bool intLibDoInput(int key)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
if (key < 0 || key >= INT_LIB_KEY_HANDLERS_CAPACITY) {
|
2022-05-19 01:51:26 -07:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
if (gIntLibGenericKeyHandlerProgram != NULL) {
|
|
|
|
if (gIntLibGenericKeyHandlerProc != 0) {
|
|
|
|
_executeProc(gIntLibGenericKeyHandlerProgram, gIntLibGenericKeyHandlerProc);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
IntLibKeyHandlerEntry* entry = &(gIntLibKeyHandlerEntries[key]);
|
2022-05-19 01:51:26 -07:00
|
|
|
if (entry->program == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->proc != 0) {
|
|
|
|
_executeProc(entry->program, entry->proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466A70
|
2022-07-29 06:04:05 -07:00
|
|
|
void intLibInit()
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
_windowAddInputFunc(intLibDoInput);
|
|
|
|
|
|
|
|
interpreterRegisterOpcode(0x806A, opFillWin3x3);
|
|
|
|
interpreterRegisterOpcode(0x808C, opDeleteButton);
|
|
|
|
interpreterRegisterOpcode(0x8086, opAddButton);
|
|
|
|
interpreterRegisterOpcode(0x8088, opAddButtonFlag);
|
|
|
|
interpreterRegisterOpcode(0x8087, opAddButtonText);
|
|
|
|
interpreterRegisterOpcode(0x8089, opAddButtonGfx);
|
|
|
|
interpreterRegisterOpcode(0x808A, opAddButtonProc);
|
|
|
|
interpreterRegisterOpcode(0x808B, opAddButtonRightProc);
|
|
|
|
interpreterRegisterOpcode(0x8067, opShowWin);
|
|
|
|
interpreterRegisterOpcode(0x8068, opFillWin);
|
|
|
|
interpreterRegisterOpcode(0x8069, opFillRect);
|
|
|
|
interpreterRegisterOpcode(0x8072, opPrint);
|
|
|
|
interpreterRegisterOpcode(0x8073, opFormat);
|
|
|
|
interpreterRegisterOpcode(0x8074, opPrintRect);
|
|
|
|
interpreterRegisterOpcode(0x8075, opSetFont);
|
|
|
|
interpreterRegisterOpcode(0x8076, opSetTextFlags);
|
|
|
|
interpreterRegisterOpcode(0x8077, opSetTextColor);
|
|
|
|
interpreterRegisterOpcode(0x8078, opSetHighlightColor);
|
|
|
|
interpreterRegisterOpcode(0x8064, opSelect);
|
|
|
|
interpreterRegisterOpcode(0x806B, opDisplay);
|
|
|
|
interpreterRegisterOpcode(0x806D, opDisplayRaw);
|
|
|
|
interpreterRegisterOpcode(0x806C, opDisplayGfx);
|
|
|
|
interpreterRegisterOpcode(0x806F, opFadeIn);
|
|
|
|
interpreterRegisterOpcode(0x8070, opFadeOut);
|
|
|
|
interpreterRegisterOpcode(0x807A, opPlayMovie);
|
|
|
|
interpreterRegisterOpcode(0x807B, opSetMovieFlags);
|
|
|
|
interpreterRegisterOpcode(0x807C, opPlayMovieRect);
|
|
|
|
interpreterRegisterOpcode(0x8079, opStopMovie);
|
|
|
|
interpreterRegisterOpcode(0x807F, opAddRegion);
|
|
|
|
interpreterRegisterOpcode(0x8080, opAddRegionFlag);
|
|
|
|
interpreterRegisterOpcode(0x8081, opAddRegionProc);
|
|
|
|
interpreterRegisterOpcode(0x8082, opAddRegionRightProc);
|
|
|
|
interpreterRegisterOpcode(0x8083, opDeleteRegion);
|
|
|
|
interpreterRegisterOpcode(0x8084, opActivateRegion);
|
|
|
|
interpreterRegisterOpcode(0x8085, opCheckRegion);
|
|
|
|
interpreterRegisterOpcode(0x8062, opCreateWin);
|
|
|
|
interpreterRegisterOpcode(0x8063, opDeleteWin);
|
|
|
|
interpreterRegisterOpcode(0x8065, opResizeWin);
|
|
|
|
interpreterRegisterOpcode(0x8066, opScaleWin);
|
|
|
|
interpreterRegisterOpcode(0x804E, opSayStart);
|
|
|
|
interpreterRegisterOpcode(0x804F, opSayStartPos);
|
|
|
|
interpreterRegisterOpcode(0x8050, opSayReplyTitle);
|
|
|
|
interpreterRegisterOpcode(0x8051, opSayGoToReply);
|
|
|
|
interpreterRegisterOpcode(0x8053, opSayReply);
|
|
|
|
interpreterRegisterOpcode(0x8052, opSayOption);
|
|
|
|
interpreterRegisterOpcode(0x804D, opSayEnd);
|
|
|
|
interpreterRegisterOpcode(0x804C, opSayQuit);
|
|
|
|
interpreterRegisterOpcode(0x8054, opSayMessage);
|
|
|
|
interpreterRegisterOpcode(0x8055, opSayReplyWindow);
|
|
|
|
interpreterRegisterOpcode(0x8056, opSayOptionWindow);
|
|
|
|
interpreterRegisterOpcode(0x805F, opSayReplyFlags);
|
|
|
|
interpreterRegisterOpcode(0x8060, opSayOptionFlags);
|
|
|
|
interpreterRegisterOpcode(0x8057, opSayBorder);
|
|
|
|
interpreterRegisterOpcode(0x8058, opSayScrollUp);
|
|
|
|
interpreterRegisterOpcode(0x8059, opSayScrollDown);
|
|
|
|
interpreterRegisterOpcode(0x805A, opSaySetSpacing);
|
|
|
|
interpreterRegisterOpcode(0x805B, opSayOptionColor);
|
|
|
|
interpreterRegisterOpcode(0x805C, opSayReplyColor);
|
|
|
|
interpreterRegisterOpcode(0x805D, opSayRestart);
|
|
|
|
interpreterRegisterOpcode(0x805E, opSayGetLastPos);
|
|
|
|
interpreterRegisterOpcode(0x8061, opSayMessageTimeout);
|
|
|
|
interpreterRegisterOpcode(0x8071, opGotoXY);
|
|
|
|
interpreterRegisterOpcode(0x808D, opHideMouse);
|
|
|
|
interpreterRegisterOpcode(0x808E, opShowMouse);
|
|
|
|
interpreterRegisterOpcode(0x8090, opRefreshMouse);
|
|
|
|
interpreterRegisterOpcode(0x808F, opMouseShape);
|
|
|
|
interpreterRegisterOpcode(0x8091, opSetGlobalMouseFunc);
|
|
|
|
interpreterRegisterOpcode(0x806E, opLoadPaletteTable);
|
|
|
|
interpreterRegisterOpcode(0x8092, opAddNamedEvent);
|
|
|
|
interpreterRegisterOpcode(0x8093, opAddNamedHandler);
|
|
|
|
interpreterRegisterOpcode(0x8094, opClearNamed);
|
|
|
|
interpreterRegisterOpcode(0x8095, opSignalNamed);
|
|
|
|
interpreterRegisterOpcode(0x8096, opAddKey);
|
|
|
|
interpreterRegisterOpcode(0x8097, opDeleteKey);
|
|
|
|
interpreterRegisterOpcode(0x8098, opSoundPlay);
|
|
|
|
interpreterRegisterOpcode(0x8099, opSoundPause);
|
|
|
|
interpreterRegisterOpcode(0x809A, opSoundResume);
|
|
|
|
interpreterRegisterOpcode(0x809B, opSoundStop);
|
|
|
|
interpreterRegisterOpcode(0x809C, opSoundRewind);
|
|
|
|
interpreterRegisterOpcode(0x809D, opSoundDelete);
|
|
|
|
interpreterRegisterOpcode(0x809E, opSetOneOptPause);
|
|
|
|
interpreterRegisterOpcode(0x809F, opSelectFileList);
|
|
|
|
interpreterRegisterOpcode(0x80A0, opTokenize);
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
_nevs_initonce();
|
|
|
|
_initIntExtra();
|
2022-07-29 06:04:05 -07:00
|
|
|
dialogInit();
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466F6C
|
2022-07-29 06:04:05 -07:00
|
|
|
void intLibRegisterProgramDeleteCallback(IntLibProgramDeleteCallback* callback)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
int index;
|
2022-07-29 06:04:05 -07:00
|
|
|
for (index = 0; index < gIntLibProgramDeleteCallbacksLength; index++) {
|
|
|
|
if (gIntLibProgramDeleteCallbacks[index] == NULL) {
|
2022-05-19 01:51:26 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
if (index == gIntLibProgramDeleteCallbacksLength) {
|
|
|
|
if (gIntLibProgramDeleteCallbacks != NULL) {
|
|
|
|
gIntLibProgramDeleteCallbacks = (IntLibProgramDeleteCallback**)internal_realloc_safe(gIntLibProgramDeleteCallbacks, sizeof(*gIntLibProgramDeleteCallbacks) * (gIntLibProgramDeleteCallbacksLength + 1), __FILE__, __LINE__); // ..\\int\\INTLIB.C, 2110
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibProgramDeleteCallbacks = (IntLibProgramDeleteCallback**)internal_malloc_safe(sizeof(*gIntLibProgramDeleteCallbacks), __FILE__, __LINE__); // ..\\int\\INTLIB.C, 2112
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibProgramDeleteCallbacksLength++;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
gIntLibProgramDeleteCallbacks[index] = callback;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// 0x467040
|
2022-07-29 06:04:05 -07:00
|
|
|
void intLibRemoveProgramReferences(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
2022-07-29 06:04:05 -07:00
|
|
|
for (int index = 0; index < INT_LIB_KEY_HANDLERS_CAPACITY; index++) {
|
|
|
|
if (program == gIntLibKeyHandlerEntries[index].program) {
|
|
|
|
gIntLibKeyHandlerEntries[index].program = NULL;
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
intExtraRemoveProgramReferences(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
|
2022-07-29 06:04:05 -07:00
|
|
|
for (int index = 0; index < gIntLibProgramDeleteCallbacksLength; index++) {
|
|
|
|
IntLibProgramDeleteCallback* callback = gIntLibProgramDeleteCallbacks[index];
|
|
|
|
if (callback != NULL) {
|
|
|
|
callback(program);
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-23 05:43:44 -07:00
|
|
|
|
|
|
|
} // namespace fallout
|