scummvm/saga/sdebug.cpp
Eugene Sandulenko 51b5acfc9c Move SCENE_* to class.
svn-id: r14463
2004-08-04 20:28:57 +00:00

524 lines
10 KiB
C++

/* 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$
*
*/
// Scripting module simple thread debugging support
#include "saga/saga.h"
#include "saga/gfx.h"
#include "saga/console_mod.h"
#include "saga/text.h"
#include "saga/scene.h"
#include "saga/font.h"
#include "saga/script.h"
#include "saga/sthread.h"
namespace Saga {
#define SD_DISPLAY_LEN 128
#define SD_ADDTXT( x ) strncat( disp_buf, x, SD_DISPLAY_LEN );
int SDEBUG_PrintInstr(R_SCRIPT_THREAD *thread) {
R_TEXTLIST_ENTRY tl_e;
char tmp_buf[80] = { 0 };
static char disp_buf[SD_DISPLAY_LEN] = { 0 };
int in_char;
// int op_offset;
int n_switch;
int i;
R_SCENE_INFO si;
_vm->_scene->getInfo(&si);
disp_buf[0] = 0;
if (_vm->_script->_dbg_txtentry != NULL) {
_vm->textDeleteEntry(si.text_list, _vm->_script->_dbg_txtentry);
_vm->_script->_dbg_txtentry = NULL;
}
tl_e.color = 1;
tl_e.effect_color = 0;
tl_e.text_x = 2;
tl_e.text_y = 20;
tl_e.font_id = SMALL_FONT_ID;
tl_e.flags = FONT_OUTLINE;
tl_e.string = disp_buf;
tl_e.display = 1;
MemoryReadStream readS(_vm->_script->currentScript()->bytecode->bytecode_p
+ thread->i_offset,
_vm->_script->currentScript()->bytecode->bytecode_len
- thread->i_offset);
in_char = readS.readByte();
sprintf(tmp_buf, "%04lX | %02X | ", thread->i_offset, in_char);
strncat(disp_buf, tmp_buf, SD_DISPLAY_LEN);
switch (in_char) {
// Align
case 0x01:
SD_ADDTXT("ALGN |");
break;
// Push nothing
case 0x02:
SD_ADDTXT("PSHN |");
break;
// Pop nothing
case 0x03:
SD_ADDTXT("POPN |");
break;
// Push false (0)
case 0x04:
SD_ADDTXT("PSHF |");
break;
// Push true (1)
case 0x05:
SD_ADDTXT("PSHT |");
break;
// Push word (dialogue string index)
case 0x08:
{
int param;
SD_ADDTXT("PSHD | ");
param = readS.readUint16LE();
sprintf(tmp_buf, "%02X", param);
SD_ADDTXT(tmp_buf);
/*
if(( param >= 0 ) && ( param < diag_list->n_dialogue )) {
printf(" ; \"%.*s\"", R_SCRIPT_STRINGLIMIT, diag_list->str[param] );
}
else {
printf(" ; Invalid dialogue string.\n" );
}
*/
}
break;
// Push word
case 0x06:
{
int param;
SD_ADDTXT("PUSH | ");
param = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param);
SD_ADDTXT(tmp_buf);
}
break;
// Test flag
case 0x0B:
{
int param1;
int param2;
SD_ADDTXT("TSTF | ");
param1 = readS.readByte();
param2 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X", param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
// Get word
case 0x0C:
{
int param1;
int param2;
SD_ADDTXT("GETW | ");
param1 = readS.readByte();
param2 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X", param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
// Modify flag
case 0x0F:
{
int param1;
int param2;
SD_ADDTXT("MODF | ");
param1 = readS.readByte();
param2 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X", param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
// Put word
case 0x10:
{
int param1;
int param2;
SD_ADDTXT("PUTW | ");
param1 = readS.readByte();
param2 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X", param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
// Modify flag and pop
case 0x13:
{
int param1;
int param2;
SD_ADDTXT("MDFP | ");
param1 = readS.readByte();
param2 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X", param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
// Put word and pop
case 0x14:
{
int param1;
int param2;
SD_ADDTXT("PTWP | ");
param1 = readS.readByte();
param2 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X", param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
// Call subscript ?
case 0x17:
{
int param1;
int param2;
int param3;
SD_ADDTXT("GOSB | ");
param1 = readS.readByte();
param2 = readS.readByte();
param3 = readS.readUint16LE();
sprintf(tmp_buf, "%02X %02X %04X", param1, param2, param3);
SD_ADDTXT(tmp_buf);
}
break;
// Call function
case 0x19:
case 0x18:
{
int func_num;
int param;
SD_ADDTXT("CALL | ");
func_num = readS.readByte();
sprintf(tmp_buf, "%02X ", func_num);
SD_ADDTXT(tmp_buf);
param = readS.readUint16LE();
sprintf(tmp_buf, "%04X ", param);
SD_ADDTXT(tmp_buf);
}
break;
// Begin subscript
case 0x1A:
{
int param;
SD_ADDTXT("ENTR | ");
param = readS.readUint16LE();
sprintf(tmp_buf, "%04X ", param);
SD_ADDTXT(tmp_buf);
/*
for( i = 0 ; i < script_list->n_scripts ; i++ ) {
if( op_offset == script_list->scripts[i].offset ) {
printf("; Entrypoint \"%s\".", script_list->scriptl_p + script_list->scripts[i].name_offset );
break;
}
}
*/
}
break;
case 0x1B:
SD_ADDTXT("??? ");
break;
// End subscript
case 0x1C:
SD_ADDTXT("EXIT |");
break;
// Unconditional jump
case 0x1D:
{
int param1;
SD_ADDTXT("JMP | ");
param1 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param1);
SD_ADDTXT(tmp_buf);
}
break;
// Jump if nonzero + POP
case 0x1E:
{
int param1;
SD_ADDTXT("JNZP | ");
param1 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param1);
SD_ADDTXT(tmp_buf);
}
break;
// Jump if zero + POP
case 0x1F:
{
int param1;
SD_ADDTXT("JZP | ");
param1 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param1);
SD_ADDTXT(tmp_buf);
}
break;
// Jump if nonzero
case 0x20:
{
int param1;
SD_ADDTXT("JNZ | ");
param1 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param1);
SD_ADDTXT(tmp_buf);
}
break;
// Jump if zero
case 0x21:
{
int param1;
SD_ADDTXT("JZ | ");
param1 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param1);
SD_ADDTXT(tmp_buf);
}
break;
// Switch
case 0x22:
{
int switch_num;
int switch_jmp;
int default_jmp;
SD_ADDTXT("SWCH | ");
n_switch = readS.readUint16LE();
sprintf(tmp_buf, "%02X\n", n_switch);
SD_ADDTXT(tmp_buf);
for (i = 0; i < n_switch; i++) {
switch_num = readS.readUint16LE();
switch_jmp = readS.readUint16LE();
// printf( R_TAB "CASE %04X, %04X\n", switch_num, switch_jmp);
}
default_jmp = readS.readUint16LE();
//printf( R_TAB "DEF %04X", default_jmp);
}
break;
// Random branch
case 0x24:
{
int n_switch2;
int switch_num;
int switch_jmp;
SD_ADDTXT("RJMP | ");
// Ignored?
readS.readUint16LE();
n_switch2 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", n_switch2);
SD_ADDTXT(tmp_buf);
for (i = 0; i < n_switch2; i++) {
//printf("\n");
switch_num = readS.readUint16LE();
switch_jmp = readS.readUint16LE();
//printf( R_TAB "WEIGHT %04X, %04X", switch_num, switch_jmp);
}
}
break;
case 0x25:
SD_ADDTXT("NEG |");
break;
case 0x26:
SD_ADDTXT("TSTZ |");
break;
case 0x27:
SD_ADDTXT("NOT |");
break;
case 0x28:
SD_ADDTXT("??? ");
readS.readByte();
readS.readUint16LE();
break;
case 0x29:
SD_ADDTXT("??? ");
readS.readByte();
readS.readUint16LE();
break;
case 0x2A:
SD_ADDTXT("??? ");
readS.readByte();
readS.readUint16LE();
break;
case 0x2B:
SD_ADDTXT("??? ");
readS.readByte();
readS.readUint16LE();
break;
// Addition
case 0x2C:
SD_ADDTXT("ADD |");
break;
// Subtraction
case 0x2D:
SD_ADDTXT("SUB |");
break;
// Integer multiplication
case 0x2E:
SD_ADDTXT("MULT |");
break;
// Integer division
case 0x2F:
SD_ADDTXT("DIV |");
break;
// Modulus
case 0x30:
SD_ADDTXT("MOD |");
break;
// Test equality
case 0x33:
SD_ADDTXT("EQU |");
break;
// Test inequality
case 0x34:
SD_ADDTXT("NEQU |");
break;
// Test Greater-than
case 0x35:
SD_ADDTXT("GRT |");
break;
// Test Less-than
case 0x36:
SD_ADDTXT("LST |");
break;
// Test Greater-than or Equal to
case 0x37:
SD_ADDTXT("GRTE |");
break;
// Test Less-than or Equal to
case 0x38:
SD_ADDTXT("LSTE |");
break;
case 0x3F:
SD_ADDTXT("SHR |");
break;
case 0x40:
SD_ADDTXT("SHL |");
break;
case 0x41:
SD_ADDTXT("AND |");
break;
case 0x42:
SD_ADDTXT("OR |");
break;
case 0x43:
SD_ADDTXT("XOR |");
break;
case 0x44:
SD_ADDTXT("LAND |");
break;
case 0x45:
SD_ADDTXT("LOR |");
break;
case 0x46:
SD_ADDTXT("LXOR |");
break;
case 0x53:
{
int n_voices;
int param1;
int param2;
SD_ADDTXT("DLGP | ");
n_voices = readS.readByte();
param1 = readS.readUint16LE();
param2 = readS.readByte();
// ignored ?
readS.readUint16LE();
sprintf(tmp_buf, "%02X %04X %02X", n_voices, param1, param2);
SD_ADDTXT(tmp_buf);
}
break;
case 0x54:
SD_ADDTXT("DLGS |");
break;
case 0x55:
SD_ADDTXT("DLGX |");
break;
case 0x56:
{
int param1;
int param2;
int param3;
SD_ADDTXT("DLGO | ");
param1 = readS.readByte();
param2 = readS.readByte();
sprintf(tmp_buf, "%02X %02X ", param1, param2);
SD_ADDTXT(tmp_buf);
if (param2 > 0) {
param3 = readS.readUint16LE();
sprintf(tmp_buf, "%04X", param3);
SD_ADDTXT(tmp_buf);
}
}
break;
case 0x57:
{
int param1;
int param2;
int param3;
SD_ADDTXT("JMPS | ");
param1 = readS.readUint16LE();
param2 = readS.readUint16LE();
param3 = readS.readByte();
sprintf(tmp_buf, "%04X %04X %02X", param1, param2, param3);
SD_ADDTXT(tmp_buf);
}
break;
default:
sprintf(tmp_buf, "Invalid opcode.\n");
SD_ADDTXT(tmp_buf);
break;
}
_vm->_script->_dbg_txtentry = _vm->textAddEntry(si.text_list, &tl_e);
_vm->textSetDisplay(_vm->_script->_dbg_txtentry, 1);
return R_SUCCESS;
}
} // End of namespace Saga