From f3d340fb0ce72b9db59b8c701153bc82b595f75e Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Mon, 12 Apr 2004 21:40:49 +0000 Subject: WIP for SAGA engine. o text formatting is not consistent with rules, just indent utility is too dumb for that o it does not use OSystem, i.e. it runs on direct SDL calls o it may not even compile on your box o if you enable it, expect zillions of warnings o no sound Now it runs ITE intro as reinherit did svn-id: r13564 --- saga/sthread.cpp | 1120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1120 insertions(+) create mode 100644 saga/sthread.cpp (limited to 'saga/sthread.cpp') diff --git a/saga/sthread.cpp b/saga/sthread.cpp new file mode 100644 index 0000000000..04407a1eec --- /dev/null +++ b/saga/sthread.cpp @@ -0,0 +1,1120 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 The ScummVM project + * + * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ +/* + + Description: + + Scripting module thread management component + + Notes: +*/ + +#include "reinherit.h" + +#include "yslib.h" + +#include + +/* + * Uses the following modules: +\*--------------------------------------------------------------------------*/ +#include "actor_mod.h" +#include "console_mod.h" +#include "text_mod.h" + +/* + * Begin module component +\*--------------------------------------------------------------------------*/ +#include "script.h" +#include "script_mod.h" + +#include "sdata.h" +#include "sstack.h" +#include "sthread.h" +#include "sfuncs.h" + +namespace Saga { + +R_SCRIPT_THREAD *STHREAD_Create(void) +{ + YS_DL_NODE *new_node; + R_SCRIPT_THREAD *new_thread; + + int result; + + if (!ScriptModule.initialized) { + + return NULL; + } + + new_thread = (R_SCRIPT_THREAD *)calloc(1, sizeof *new_thread); + if (new_thread == NULL) { + return NULL; + } + + result = SSTACK_Create(&(new_thread->stack), + R_DEF_THREAD_STACKSIZE, STACK_GROW); + + if (result != STACK_SUCCESS) { + return NULL; + } + + new_node = ys_dll_add_head(ScriptModule.thread_list, + new_thread, sizeof *new_thread); + + free(new_thread); + + return (R_SCRIPT_THREAD *)ys_dll_get_data(new_node); + +} + +int STHREAD_Destroy(R_SCRIPT_THREAD * thread) +{ + if (thread == NULL) { + return R_FAILURE; + } + + SSTACK_Destroy(thread->stack); + + return R_SUCCESS; +} + +int STHREAD_ExecThreads(int msec) +{ + YS_DL_NODE *walk_p; + R_SCRIPT_THREAD *thread; + + if (!ScriptModule.initialized) { + + return R_FAILURE; + } + + for (walk_p = ys_dll_head(ScriptModule.thread_list); + walk_p != NULL; walk_p = ys_dll_next(walk_p)) { + + thread = (R_SCRIPT_THREAD *)ys_dll_get_data(walk_p); + + if (thread->executing) { + + STHREAD_Run(thread, STHREAD_DEF_INSTR_COUNT, msec); + } + } + + return R_SUCCESS; +} + +int STHREAD_SetEntrypoint(R_SCRIPT_THREAD * thread, int ep_num) +{ + + R_SCRIPT_BYTECODE *bytecode; + int max_entrypoint; + + assert(ScriptModule.initialized); + + bytecode = ScriptModule.current_script->bytecode; + max_entrypoint = bytecode->n_entrypoints; + + if ((ep_num < 0) || (ep_num >= max_entrypoint)) { + return R_FAILURE; + } + + thread->ep_num = ep_num; + thread->ep_offset = bytecode->entrypoints[ep_num].offset; + + return R_SUCCESS; +} + +int STHREAD_Execute(R_SCRIPT_THREAD * thread, int ep_num) +{ + + assert(ScriptModule.initialized); + + if ((ScriptModule.current_script == NULL) || + (!ScriptModule.current_script->loaded)) { + + return R_FAILURE; + } + + STHREAD_SetEntrypoint(thread, ep_num); + + thread->i_offset = thread->ep_offset; + thread->executing = 1; + + return R_SUCCESS; +} + +unsigned char *GetReadPtr(R_SCRIPT_THREAD * thread) +{ + + return ScriptModule.current_script->bytecode->bytecode_p + + thread->i_offset; +} + +unsigned long GetReadOffset(const uchar * read_p) +{ + + return (unsigned long)(read_p - (unsigned char *) + ScriptModule.current_script->bytecode->bytecode_p); +} + +int STHREAD_HoldSem(R_SEMAPHORE * sem) +{ + if (sem == NULL) { + return R_FAILURE; + } + + sem->hold_count++; + + return R_SUCCESS; +} + +int STHREAD_ReleaseSem(R_SEMAPHORE * sem) +{ + if (sem == NULL) { + return R_FAILURE; + } + + sem->hold_count--; + if (sem->hold_count < 0) { + sem->hold_count = 0; + } + + return R_SUCCESS; +} + +int STHREAD_DebugStep(void) +{ + + if (ScriptModule.dbg_singlestep) { + ScriptModule.dbg_dostep = 1; + } + + return R_SUCCESS; +} + +int STHREAD_Run(R_SCRIPT_THREAD * thread, int instr_limit, int msec) +{ + + int instr_count; + + const uchar *read_p; + ulong saved_offset; + + SDataWord_T param1; + SDataWord_T param2; + + long iparam1; + long iparam2; + long iresult; + + SDataWord_T data; + + int debug_print = 0; + int n_buf; + int bitstate; + + int result; + int in_char; + int i; + + int unhandled = 0; + + /* Handle debug single-stepping */ + if ((thread == ScriptModule.dbg_thread) && ScriptModule.dbg_singlestep) { + + if (ScriptModule.dbg_dostep) { + + debug_print = 1; + + thread->sleep_time = 0; + instr_limit = 1; + ScriptModule.dbg_dostep = 0; + } else { + + return R_SUCCESS; + } + } + + for (instr_count = 0; instr_count < instr_limit; instr_count++) { + + if ((!thread->executing) || (thread->sem.hold_count)) { + break; + } + + thread->sleep_time -= msec; + if (thread->sleep_time < 0) { + thread->sleep_time = 0; + } + + if (thread->sleep_time) { + break; + } + + saved_offset = thread->i_offset; +#if 0 + R_printf(R_STDOUT, "Executing thread offset: %lu", + thread->i_offset); +#endif + read_p = GetReadPtr(thread); + + in_char = ys_read_u8(read_p, &read_p); + + switch (in_char) { + + /* Align (ALGN) */ + case 0x01: + break; + + /*-------------------------------------------------------------*\ + * STACK INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* Push nothing (PSHN) */ + case 0x02: + + SSTACK_PushNull(thread->stack); + + break; + + /* Pop nothing (POPN) */ + case 0x03: + + SSTACK_Pop(thread->stack, NULL); + + break; + + /* Push false (PSHF) */ + case 0x04: + + SSTACK_Push(thread->stack, 0); + + break; + + /* Push true (PSHT) */ + case 0x05: + + SSTACK_Push(thread->stack, 1); + + break; + + /* Push word (PUSH) */ + case 0x06: + + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + SSTACK_Push(thread->stack, param1); + + break; + + /* Push word (PSHD) (dialogue string index) */ + case 0x08: + + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + SSTACK_Push(thread->stack, param1); + + break; + + /*-------------------------------------------------------------*\ + * DATA INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* Test flag (TSTF) */ + case 0x0B: + + n_buf = *read_p++; + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + + SDATA_GetBit(n_buf, param1, &bitstate); + SSTACK_Push(thread->stack, bitstate); + + break; + + /* Get word (GETW) */ + case 0x0C: + + n_buf = *read_p++; + param1 = ys_read_u16_le(read_p, &read_p); + + SDATA_GetWord(n_buf, param1, &data); + SSTACK_Push(thread->stack, data); + + break; + + /* Modify flag (MODF) */ + case 0x0F: + + n_buf = *read_p++; + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + + bitstate = SDATA_ReadWordU(param1); + + SSTACK_Top(thread->stack, &data); + + if (bitstate) { + SDATA_SetBit(n_buf, data, 1); + } else { + SDATA_SetBit(n_buf, data, 0); + } + + break; + + /* Put word (PUTW) */ + case 0x10: + + n_buf = *read_p++; + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + + SSTACK_Top(thread->stack, &data); + SDATA_PutWord(n_buf, param1, data); + + break; + + /* Modify flag and pop (MDFP) */ + case 0x13: + + n_buf = *read_p++; + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + + SSTACK_Pop(thread->stack, ¶m1); + + bitstate = SDATA_ReadWordU(param1); + + if (bitstate) { + SDATA_SetBit(n_buf, param1, 1); + } else { + SDATA_SetBit(n_buf, param1, 0); + } + + break; + + /* Put word and pop (PTWP) */ + case 0x14: + + n_buf = *read_p++; + param1 = (SDataWord_T) ys_read_u16_le(read_p, &read_p); + + SSTACK_Top(thread->stack, &data); + SDATA_PutWord(n_buf, param1, data); + + break; + + /*-------------------------------------------------------------*\ + * CONTROL INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (GOSB): Call subscript ? */ + case 0x17: + { + + int temp; + int temp2; + + temp = *read_p++; + temp2 = *read_p++; + + param1 = + (SDataWord_T) ys_read_u16_le(read_p, + &read_p); + data = GetReadOffset(read_p); + + /*SSTACK_Push( thread->stack, (SDataWord_T)temp ); */ + SSTACK_Push(thread->stack, data); + + thread->i_offset = (unsigned long)param1; + } + break; + + /* (CALL): Call function */ + case 0x19: + case 0x18: + { + int n_args; + uint func_num; + int result; + + SFunc_T sfunc; + + n_args = ys_read_u8(read_p, &read_p); + func_num = ys_read_u16_le(read_p, &read_p); + + if (func_num >= R_SFUNC_NUM) { + + CON_Print(S_ERROR_PREFIX + "Invalid script function number: (%X)\n", + func_num); + + thread->executing = 0; + break; + } + + sfunc = SFuncList[func_num].sfunc_fp; + + if (sfunc == NULL) { + + CON_Print(S_WARN_PREFIX + "%X: Undefined script function number: (%X)\n", + thread->i_offset, func_num); + + CON_Print(S_WARN_PREFIX + "Removing %d operand(s) from stack.\n", + n_args); + + for (i = 0; i < n_args; i++) { + + SSTACK_Pop(thread->stack, + NULL); + } + } else { + + result = sfunc(thread); + + if (result != R_SUCCESS) { + CON_Print(S_WARN_PREFIX + "%X: Script function %d failed.\n", + thread->i_offset, + func_num); + } + } + + } + break; + + /* (ENTR) Enter the dragon */ + case 0x1A: + + param1 = ys_read_u16_le(read_p, &read_p); + + break; + + /* (?) Unknown */ + case 0x1B: + + unhandled = 1; + break; + + /* (EXIT) End subscript */ + case 0x1C: + + result = SSTACK_Pop(thread->stack, &data); + + if (result != STACK_SUCCESS) { + + CON_Print("Script execution complete."); + thread->executing = 0; + } else { + + thread->i_offset = data; + } + break; + + /*-------------------------------------------------------------*\ + * BRANCH INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (JMP): Unconditional jump */ + case 0x1D: + + param1 = ys_read_u16_le(read_p, &read_p); + thread->i_offset = (unsigned long)param1; + + break; + + /* (JNZP): Jump if nonzero + POP */ + case 0x1E: + + param1 = ys_read_u16_le(read_p, &read_p); + + SSTACK_Pop(thread->stack, &data); + if (data) { + thread->i_offset = (unsigned long)param1; + } + + break; + + /* (JZP): Jump if zero + POP */ + case 0x1F: + + param1 = ys_read_u16_le(read_p, &read_p); + + SSTACK_Pop(thread->stack, &data); + if (!data) { + thread->i_offset = (unsigned long)param1; + } + + break; + + /* (JNZ): Jump if nonzero */ + case 0x20: + + param1 = ys_read_u16_le(read_p, &read_p); + + SSTACK_Top(thread->stack, &data); + if (data) { + thread->i_offset = (unsigned long)param1; + } + + break; + + /* (JZ): Jump if zero */ + case 0x21: + + param1 = ys_read_u16_le(read_p, &read_p); + + SSTACK_Top(thread->stack, &data); + if (!data) { + thread->i_offset = (unsigned long)param1; + } + + break; + + /* (JMPR): Relative jump */ + case 0x57: + + /* ignored? */ + ys_read_u16_le(read_p, &read_p); + ys_read_u16_le(read_p, &read_p); + + iparam1 = (long)*read_p++; + + thread->i_offset += iparam1; + break; + + /* (SWCH): Switch */ + case 0x22: + { + + int n_switch; + unsigned int switch_num; + unsigned int switch_jmp; + unsigned int default_jmp; + int case_found = 0; + + SSTACK_Pop(thread->stack, &data); + + n_switch = ys_read_u16_le(read_p, &read_p); + + for (i = 0; i < n_switch; i++) { + + switch_num = + ys_read_u16_le(read_p, &read_p); + switch_jmp = + ys_read_u16_le(read_p, &read_p); + + /* Found the specified case */ + if (data == (SDataWord_T) switch_num) { + + thread->i_offset = switch_jmp; + case_found = 1; + break; + } + } + + /* Jump to default case */ + if (!case_found) { + + default_jmp = + ys_read_u16_le(read_p, &read_p); + thread->i_offset = default_jmp; + } + + } + break; + + /* (RJMP): Random branch */ + case 0x24: + { + int n_branch; + unsigned int branch_wt; + unsigned int branch_jmp; + + int rand_sel = 0; + int branch_found = 0; + + /* Ignored? */ + ys_read_u16_le(read_p, &read_p); + + n_branch = ys_read_u16_le(read_p, &read_p); + + for (i = 0; i < n_branch; i++) { + + branch_wt = + ys_read_u16_le(read_p, &read_p); + branch_jmp = + ys_read_u16_le(read_p, &read_p); + + if (rand_sel == i) { + + thread->i_offset = branch_jmp; + branch_found = 1; + break; + } + } + + if (!branch_found) { + CON_Print(S_ERROR_PREFIX + "%X: Random jump target out of " + "bounds.", thread->i_offset); + } + + } + break; + + /*-------------------------------------------------------------*\ + * MISC. INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (NEG) Negate stack by 2's complement */ + case 0x25: + + SSTACK_Pop(thread->stack, &data); + data = ~data; + data++; + SSTACK_Push(thread->stack, data); + + break; + + /* (TSTZ) Test for zero */ + case 0x26: + + SSTACK_Pop(thread->stack, &data); + data = data ? 0 : 1; + SSTACK_Push(thread->stack, data); + + break; + + /* (NOT) Binary not */ + case 0x27: + + SSTACK_Pop(thread->stack, &data); + data = ~data; + SSTACK_Push(thread->stack, data); + + break; + + /* (?) */ + case 0x28: + unhandled = 1; + printf("??? "); + read_p++; + ys_read_u16_le(read_p, &read_p); + break; + + /* (?) */ + case 0x29: + unhandled = 1; + printf("??? "); + read_p++; + ys_read_u16_le(read_p, &read_p); + break; + + /* (?) */ + case 0x2A: + unhandled = 1; + printf("??? "); + read_p++; + ys_read_u16_le(read_p, &read_p); + break; + + /* (?) */ + case 0x2B: + unhandled = 1; + printf("??? "); + read_p++; + ys_read_u16_le(read_p, &read_p); + break; + + /*-------------------------------------------------------------*\ + * ARITHMETIC INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (ADD): Addition */ + case 0x2C: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + iresult = iparam1 + iparam2; + + SSTACK_Push(thread->stack, (SDataWord_T) iresult); + break; + + /* (SUB): Subtraction */ + case 0x2D: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + iresult = iparam1 - iparam2; + + SSTACK_Push(thread->stack, (SDataWord_T) iresult); + break; + + /* (MULT): Integer multiplication */ + case 0x2E: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + iresult = iparam1 * iparam2; + + SSTACK_Push(thread->stack, (SDataWord_T) iresult); + break; + + /* (DIB): Integer division */ + case 0x2F: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + iresult = iparam1 / iparam2; + + SSTACK_Push(thread->stack, (SDataWord_T) iresult); + break; + + /* (MOD) Modulus */ + case 0x30: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + iresult = iparam1 % iparam2; + + SSTACK_Push(thread->stack, (SDataWord_T) iresult); + break; + + /* (EQU) Test equality */ + case 0x33: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + data = (iparam1 == iparam2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (NEQU) Test inequality */ + case 0x34: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + data = (iparam1 != iparam2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (GRT) Test Greater-than */ + case 0x35: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + data = (iparam1 > iparam2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (LST) Test Less-than */ + case 0x36: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + data = (iparam1 < iparam2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (GRTE) Test Greater-than or Equal to */ + case 0x37: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + data = (iparam1 >= iparam2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (LSTE) Test Less-than or Equal to */ + case 0x38: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + iparam2 = (long)param2; + iparam1 = (long)param1; + + data = (iparam1 <= iparam2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (SHR): Arithmetic binary shift right */ + case 0x3F: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + iparam2 = (long)param2; + + /* Preserve most significant bit */ + data = + (0x01 << ((sizeof param1 * CHAR_BIT) - + 1)) & param1; + + for (i = 0; i < (int)iparam2; i++) { + param1 >>= 1; + param1 |= data; + } + + SSTACK_Push(thread->stack, param1); + break; + + /*-------------------------------------------------------------*\ + * BITWISE INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (SHL) Binary shift left */ + case 0x40: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + param1 <<= param2; + + SSTACK_Push(thread->stack, param1); + break; + + /* (AND) Binary AND */ + case 0x41: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + param1 &= param2; + + SSTACK_Push(thread->stack, param1); + break; + + /* (OR) Binary OR */ + case 0x42: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + param1 |= param2; + + SSTACK_Push(thread->stack, param1); + break; + + /* (XOR) Binary XOR */ + case 0x43: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + param1 ^= param2; + + SSTACK_Push(thread->stack, param1); + break; + + /*-------------------------------------------------------------*\ + * BOOLEAN LOGIC INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (LAND): Logical AND */ + case 0x44: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + data = (param1 && param2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (LOR): Logical OR */ + case 0x45: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + data = (param1 || param2) ? 1 : 0; + + SSTACK_Push(thread->stack, data); + break; + + /* (LXOR): Logical XOR */ + case 0x46: + + SSTACK_Pop(thread->stack, ¶m2); + SSTACK_Pop(thread->stack, ¶m1); + + data = ((param1) ? !(param2) : !!(param2)); + + SSTACK_Push(thread->stack, data); + break; + + /*-------------------------------------------------------------*\ + * GAME INSTRUCTIONS + \*-------------------------------------------------------------*/ + + /* (DLGP): Play Character Dialogue */ + case 0x53: + { + int n_voices; + int a_index; + int voice_rn; + + n_voices = *read_p++; + param1 = + (SDataWord_T) ys_read_u16_le(read_p, + &read_p); + + /* ignored ? */ + *read_p++; + ys_read_u16_le(read_p, &read_p); + + a_index = ACTOR_GetActorIndex(param1); + + if (a_index < 0) { + CON_Print(S_WARN_PREFIX + "%X: DLGP Actor id not found.", + thread->i_offset); + } + + for (i = 0; i < n_voices; i++) { + + SSTACK_Pop(thread->stack, &data); + + if (a_index < 0) + continue; + + if (!ScriptModule.voice_lut_present) { + voice_rn = -1; + } else { + voice_rn = + ScriptModule. + current_script->voice-> + voices[data]; + } + + ACTOR_Speak(a_index, + ScriptModule.current_script->diag-> + str[data], voice_rn, &thread->sem); + + } + + } + break; + + /* (DLGS): Initialize dialogue interface */ + case 0x54: + break; + + /* (DLGX): Run dialogue interface */ + case 0x55: + break; + + /* (DLGO): Add a dialogue option to interface */ + case 0x56: + { + int param1; + int param2; + int param3; + + printf("DLGO | "); + param1 = *read_p++; + param2 = *read_p++; + + printf("%02X %02X ", param1, param2); + + if (param2 > 0) { + param3 = + ys_read_u16_le(read_p, &read_p); + + printf("%04X", param3); + } + } + break; + + /*-------------------------------------------------------------*\ + * End instruction list + \*-------------------------------------------------------------*/ + + default: + + CON_Print(S_ERROR_PREFIX + "%X: Invalid opcode encountered: " "(%X).\n", + thread->i_offset, in_char); + thread->executing = 0; + + break; + + } /* end switch( in_char ) */ + + /* Set instruction offset only if a previous instruction didn't + * branch */ + if (saved_offset == thread->i_offset) { + + thread->i_offset = GetReadOffset(read_p); + } + + if (unhandled) { + + CON_Print(S_ERROR_PREFIX "%X: Unhandled opcode.\n", + thread->i_offset); + thread->executing = 0; + } + + if (thread->executing && debug_print) { + SDEBUG_PrintInstr(thread); + } + + } + + return R_SUCCESS; +} + +} // End of namespace Saga + -- cgit v1.2.3