2022-05-19 01:51:26 -07:00
|
|
|
#include "interpreter_lib.h"
|
|
|
|
|
|
|
|
#include "color.h"
|
|
|
|
#include "core.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "dialog.h"
|
|
|
|
#include "interpreter_extra.h"
|
|
|
|
#include "memory_manager.h"
|
|
|
|
#include "nevs.h"
|
2022-06-19 21:56:00 -07:00
|
|
|
#include "sound.h"
|
2022-05-19 01:51:26 -07:00
|
|
|
#include "widget.h"
|
|
|
|
|
2022-06-19 21:56:00 -07:00
|
|
|
#define INTERPRETER_SOUNDS_LENGTH (32)
|
|
|
|
#define INTERPRETER_KEY_HANDLER_ENTRIES_LENGTH (256)
|
|
|
|
|
|
|
|
typedef struct InterpreterKeyHandlerEntry {
|
|
|
|
Program* program;
|
|
|
|
int proc;
|
|
|
|
} InterpreterKeyHandlerEntry;
|
|
|
|
|
|
|
|
static void opFormat(Program* program);
|
|
|
|
static void opPrint(Program* program);
|
|
|
|
static void opPrintRect(Program* program);
|
|
|
|
static void opSetMovieFlags(Program* program);
|
|
|
|
static void opStopMovie(Program* program);
|
|
|
|
static void opAddRegionProc(Program* program);
|
|
|
|
static void opAddRegionRightProc(Program* program);
|
|
|
|
static void opSayStart(Program* program);
|
|
|
|
static void opDeleteRegion(Program* program);
|
|
|
|
static void opCheckRegion(Program* program);
|
|
|
|
static void opSayStartPos(Program* program);
|
|
|
|
static void opSayReplyTitle(Program* program);
|
|
|
|
static void opSayGoToReply(Program* program);
|
|
|
|
static void opSayGetLastPos(Program* program);
|
|
|
|
static void opSayQuit(Program* program);
|
|
|
|
static void opSayMessageTimeout(Program* program);
|
|
|
|
static void opAddButtonFlag(Program* program);
|
|
|
|
static void opAddRegionFlag(Program* program);
|
|
|
|
static void opAddButtonProc(Program* program);
|
|
|
|
static void opAddButtonRightProc(Program* program);
|
|
|
|
static void opShowWin(Program* program);
|
|
|
|
static void opDeleteButton(Program* program);
|
|
|
|
static void opHideMouse(Program* program);
|
|
|
|
static void opShowMouse(Program* program);
|
|
|
|
static void opSetGlobalMouseFunc(Program* Program);
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
static void opSayReplyFlags(Program* program);
|
|
|
|
static void opSayOptionFlags(Program* program);
|
|
|
|
static void opSayBorder(Program* program);
|
|
|
|
static void opSaySetSpacing(Program* program);
|
|
|
|
static void opSayRestart(Program* program);
|
|
|
|
static void interpreterSoundCallback(void* userData, int a2);
|
|
|
|
static int interpreterSoundDelete(int a1);
|
|
|
|
static int interpreterSoundPlay(char* fileName, int mode);
|
|
|
|
static int interpreterSoundPause(int value);
|
|
|
|
static int interpreterSoundRewind(int value);
|
|
|
|
static int interpreterSoundResume(int value);
|
|
|
|
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);
|
|
|
|
static bool _intLibDoInput(int key);
|
|
|
|
|
2022-05-19 01:51:26 -07:00
|
|
|
// 0x59D5D0
|
2022-06-19 22:44:27 -07:00
|
|
|
static Sound* gInterpreterSounds[INTERPRETER_SOUNDS_LENGTH];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59D950
|
2022-06-19 22:44:27 -07:00
|
|
|
static InterpreterKeyHandlerEntry gInterpreterKeyHandlerEntries[INTERPRETER_KEY_HANDLER_ENTRIES_LENGTH];
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E154
|
2022-06-19 22:44:27 -07:00
|
|
|
static int gIntepreterAnyKeyHandlerProc;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// Number of entries in _callbacks.
|
|
|
|
//
|
|
|
|
// 0x59E158
|
2022-06-19 22:44:27 -07:00
|
|
|
static int _numCallbacks;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E15C
|
2022-06-19 22:44:27 -07:00
|
|
|
static Program* gInterpreterAnyKeyHandlerProgram;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E160
|
2022-06-19 22:44:27 -07:00
|
|
|
static OFF_59E160* _callbacks;
|
2022-05-19 01:51:26 -07:00
|
|
|
|
|
|
|
// 0x59E164
|
2022-06-19 22:44:27 -07:00
|
|
|
static int _sayStartingPosition;
|
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
|
|
|
{
|
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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) {
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// printrect
|
|
|
|
// 0x461F1C
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opPrintRect(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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-05 01:00:55 -07:00
|
|
|
switch (value.opcode & 0xF7FF) {
|
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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
const char* regionName = programStackPopString(program);;
|
2022-05-19 01:51:26 -07:00
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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-05-19 01:51:26 -07:00
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// saystart
|
|
|
|
// 0x4633E4
|
2022-06-19 21:56:00 -07:00
|
|
|
static void opSayStart(Program* program)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
_sayStartingPosition = 0;
|
|
|
|
|
|
|
|
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-05 01:00:55 -07:00
|
|
|
_sayStartingPosition = 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-05 01:00:55 -07:00
|
|
|
if ((value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
|
|
|
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-05 01:00:55 -07:00
|
|
|
if ((value.opcode & 0xF7FF) == VALUE_TYPE_STRING) {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05 01:00:55 -07:00
|
|
|
if ((value.opcode & 0xF7FF) == 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
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05-19 01:51:26 -07:00
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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-05-19 01:51:26 -07:00
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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
|
|
|
{
|
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
_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-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 delete button");
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
_selectWindowID(program->field_84);
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
programFatalError("Error deleting button");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
const char* v1 = programStackPopString(program);
|
|
|
|
_nevs_addevent(v1, program, proc, 0);
|
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);
|
|
|
|
const char* v1 = programStackPopString(program);
|
|
|
|
_nevs_addevent(v1, program, proc, 1);
|
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) {
|
|
|
|
gIntepreterAnyKeyHandlerProc = proc;
|
|
|
|
gInterpreterAnyKeyHandlerProgram = program;
|
|
|
|
} else {
|
|
|
|
if (key > INTERPRETER_KEY_HANDLER_ENTRIES_LENGTH - 1) {
|
|
|
|
programFatalError("Key out of range");
|
|
|
|
}
|
|
|
|
|
|
|
|
gInterpreterKeyHandlerEntries[key].program = program;
|
|
|
|
gInterpreterKeyHandlerEntries[key].proc = proc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
|
|
|
gIntepreterAnyKeyHandlerProc = 0;
|
|
|
|
gInterpreterAnyKeyHandlerProgram = NULL;
|
|
|
|
} else {
|
|
|
|
if (key > INTERPRETER_KEY_HANDLER_ENTRIES_LENGTH - 1) {
|
|
|
|
programFatalError("Key out of range");
|
|
|
|
}
|
|
|
|
|
|
|
|
gInterpreterKeyHandlerEntries[key].program = NULL;
|
|
|
|
gInterpreterKeyHandlerEntries[key].proc = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
if (!widgetSetFont(data)) {
|
|
|
|
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
|
|
|
|
|
|
|
if (!widgetSetTextFlags(data)) {
|
|
|
|
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-07-05 01:00:55 -07:00
|
|
|
if (((value[arg].opcode & 0xF7FF) != VALUE_TYPE_FLOAT && (value[arg].opcode & 0xF7FF) != VALUE_TYPE_INT)
|
|
|
|
|| value[arg].floatValue == 0.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
|
|
|
|
|
|
|
if (!widgetSetTextColor(r, g, b)) {
|
|
|
|
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-07-05 01:00:55 -07:00
|
|
|
if (((value[arg].opcode & 0xF7FF) != VALUE_TYPE_FLOAT && (value[arg].opcode & 0xF7FF) != VALUE_TYPE_INT)
|
|
|
|
|| value[arg].floatValue == 0.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-07-05 01:00:55 -07:00
|
|
|
if (((value[arg].opcode & 0xF7FF) != VALUE_TYPE_FLOAT && (value[arg].opcode & 0xF7FF) != VALUE_TYPE_INT)
|
|
|
|
|| value[arg].floatValue == 0.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-07-05 01:00:55 -07:00
|
|
|
if (((value[arg].opcode & 0xF7FF) != VALUE_TYPE_FLOAT && (value[arg].opcode & 0xF7FF) != VALUE_TYPE_INT)
|
|
|
|
|| value[arg].floatValue == 0.0) {
|
|
|
|
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
|
|
|
|
|
|
|
if (!widgetSetHighlightColor(r, g, b)) {
|
|
|
|
programFatalError("Error setting text highlight color");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-06-19 21:56:00 -07:00
|
|
|
static void interpreterSoundCallback(void* userData, int a2)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (a2 == 1) {
|
|
|
|
Sound** sound = (Sound**)userData;
|
|
|
|
*sound = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466070
|
2022-06-19 21:56:00 -07:00
|
|
|
static int interpreterSoundDelete(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;
|
|
|
|
Sound* sound = gInterpreterSounds[index];
|
|
|
|
if (sound == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (soundIsPlaying(sound)) {
|
|
|
|
soundStop(sound);
|
|
|
|
}
|
|
|
|
|
|
|
|
soundDelete(sound);
|
|
|
|
|
|
|
|
gInterpreterSounds[index] = NULL;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466110
|
2022-06-19 21:56:00 -07:00
|
|
|
static int interpreterSoundPlay(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;
|
|
|
|
for (index = 0; index < INTERPRETER_SOUNDS_LENGTH; index++) {
|
|
|
|
if (gInterpreterSounds[index] == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index == INTERPRETER_SOUNDS_LENGTH) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sound* sound = gInterpreterSounds[index] = soundAllocate(v3, v5);
|
|
|
|
if (sound == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
soundSetCallback(sound, interpreterSoundCallback, &(gInterpreterSounds[index]));
|
|
|
|
|
|
|
|
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);
|
|
|
|
gInterpreterSounds[index] = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x46655C
|
2022-06-19 21:56:00 -07:00
|
|
|
static int interpreterSoundPause(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;
|
|
|
|
Sound* sound = gInterpreterSounds[index];
|
|
|
|
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-06-19 21:56:00 -07:00
|
|
|
static int interpreterSoundRewind(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;
|
|
|
|
Sound* sound = gInterpreterSounds[index];
|
|
|
|
if (sound == NULL) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!soundIsPlaying(sound)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
soundStop(sound);
|
|
|
|
|
|
|
|
return soundPlay(sound) == SOUND_NO_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x46662C
|
2022-06-19 21:56:00 -07:00
|
|
|
static int interpreterSoundResume(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;
|
|
|
|
Sound* sound = gInterpreterSounds[index];
|
|
|
|
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
|
|
|
{
|
|
|
|
// TODO: Incomplete.
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05-19 01:51:26 -07:00
|
|
|
interpreterSoundPause(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05-19 01:51:26 -07:00
|
|
|
interpreterSoundResume(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05-19 01:51:26 -07:00
|
|
|
interpreterSoundPause(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05-19 01:51:26 -07:00
|
|
|
interpreterSoundRewind(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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-05-19 01:51:26 -07:00
|
|
|
interpreterSoundDelete(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
|
void _updateIntLib()
|
|
|
|
{
|
|
|
|
_nevs_update();
|
|
|
|
_intExtraRemoveProgramReferences_();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x4669A0
|
|
|
|
void _intlibClose()
|
|
|
|
{
|
|
|
|
_dialogClose();
|
|
|
|
_intExtraClose_();
|
|
|
|
|
|
|
|
for (int index = 0; index < INTERPRETER_SOUNDS_LENGTH; index++) {
|
|
|
|
if (gInterpreterSounds[index] != NULL) {
|
|
|
|
interpreterSoundDelete(index | 0xA0000000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_nevs_close();
|
|
|
|
|
|
|
|
if (_callbacks != NULL) {
|
|
|
|
internal_free_safe(_callbacks, __FILE__, __LINE__); // "..\\int\\INTLIB.C", 1976
|
|
|
|
_callbacks = NULL;
|
|
|
|
_numCallbacks = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466A04
|
2022-06-19 21:56:00 -07:00
|
|
|
static bool _intLibDoInput(int key)
|
2022-05-19 01:51:26 -07:00
|
|
|
{
|
|
|
|
if (key < 0 || key >= INTERPRETER_KEY_HANDLER_ENTRIES_LENGTH) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gInterpreterAnyKeyHandlerProgram != NULL) {
|
|
|
|
if (gIntepreterAnyKeyHandlerProc != 0) {
|
|
|
|
_executeProc(gInterpreterAnyKeyHandlerProgram, gIntepreterAnyKeyHandlerProc);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
InterpreterKeyHandlerEntry* entry = &(gInterpreterKeyHandlerEntries[key]);
|
|
|
|
if (entry->program == NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->proc != 0) {
|
|
|
|
_executeProc(entry->program, entry->proc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466A70
|
|
|
|
void _initIntlib()
|
|
|
|
{
|
|
|
|
// TODO: Incomplete.
|
|
|
|
_nevs_initonce();
|
|
|
|
_initIntExtra();
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x466F6C
|
|
|
|
void _interpretRegisterProgramDeleteCallback(OFF_59E160 fn)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
for (index = 0; index < _numCallbacks; index++) {
|
|
|
|
if (_callbacks[index] == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index == _numCallbacks) {
|
|
|
|
if (_callbacks != NULL) {
|
2022-05-21 08:22:03 -07:00
|
|
|
_callbacks = (OFF_59E160*)internal_realloc_safe(_callbacks, sizeof(*_callbacks) * (_numCallbacks + 1), __FILE__, __LINE__); // ..\\int\\INTLIB.C, 2110
|
2022-05-19 01:51:26 -07:00
|
|
|
} else {
|
2022-05-21 08:22:03 -07:00
|
|
|
_callbacks = (OFF_59E160*)internal_malloc_safe(sizeof(*_callbacks), __FILE__, __LINE__); // ..\\int\\INTLIB.C, 2112
|
2022-05-19 01:51:26 -07:00
|
|
|
}
|
|
|
|
_numCallbacks++;
|
|
|
|
}
|
|
|
|
|
|
|
|
_callbacks[index] = fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 0x467040
|
|
|
|
void _removeProgramReferences_(Program* program)
|
|
|
|
{
|
|
|
|
for (int index = 0; index < INTERPRETER_KEY_HANDLER_ENTRIES_LENGTH; index++) {
|
|
|
|
if (program == gInterpreterKeyHandlerEntries[index].program) {
|
|
|
|
gInterpreterKeyHandlerEntries[index].program = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_intExtraRemoveProgramReferences_();
|
|
|
|
|
|
|
|
for (int index = 0; index < _numCallbacks; index++) {
|
|
|
|
OFF_59E160 fn = _callbacks[index];
|
|
|
|
if (fn != NULL) {
|
|
|
|
fn(program);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|