Initial commit
This commit is contained in:
316
engines/glk/agt/disassemble.cpp
Normal file
316
engines/glk/agt/disassemble.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "glk/agt/agility.h"
|
||||
|
||||
namespace Glk {
|
||||
namespace AGT {
|
||||
|
||||
void dbgprintf(const char *fmt, ...) {
|
||||
va_list vp;
|
||||
char buff[300];
|
||||
|
||||
va_start(vp, fmt);
|
||||
Common::vsprintf_s(buff, fmt, vp);
|
||||
va_end(vp);
|
||||
|
||||
debugout(buff);
|
||||
}
|
||||
|
||||
|
||||
static void print_msg(descr_ptr dptr) {
|
||||
int j;
|
||||
descr_line *txt;
|
||||
|
||||
txt = read_descr(dptr.start, dptr.size);
|
||||
if (txt != nullptr) {
|
||||
for (j = 0; txt[j] != nullptr; j++) {
|
||||
dbgprintf("\n");
|
||||
debugout(txt[j]);
|
||||
}
|
||||
}
|
||||
free_descr(txt);
|
||||
}
|
||||
|
||||
|
||||
static char *getname(int inum)
|
||||
/* Name should be 20 chars or less */
|
||||
{
|
||||
if (inum == 0) return rstrdup("* 0 *");
|
||||
return objname(inum);
|
||||
}
|
||||
|
||||
|
||||
extern integer dobj, iobj, actor;
|
||||
|
||||
void print_special_obj(int i)
|
||||
/* This is called by the disassembler in agtdbg.c */
|
||||
/* i=0 NOUN, 1 OBJECT, 2 NAME */
|
||||
{
|
||||
int dval;
|
||||
char *s;
|
||||
switch (i) {
|
||||
case 0:
|
||||
dval = dobj;
|
||||
dbgprintf("NOUN");
|
||||
break;
|
||||
case 1:
|
||||
dval = iobj;
|
||||
dbgprintf("OBJECT");
|
||||
break;
|
||||
case 2:
|
||||
dval = actor;
|
||||
dbgprintf("NAME");
|
||||
break;
|
||||
default:
|
||||
dval = 0; /* Silence compiler warnings. */
|
||||
fatal("INTERNAL ERROR: Invalid *dval* in print_special_obj.");
|
||||
}
|
||||
if (dbgflagptr == nullptr)
|
||||
/* This determines whether we are linked with agtout or agil */
|
||||
return;
|
||||
s = getname(dval);
|
||||
dbgprintf("(%d:%s)", dval, s);
|
||||
rfree(s);
|
||||
}
|
||||
|
||||
#define printval(str,index,ptr) {dbgprintf("[%s%d",str,index);\
|
||||
if (ptr==NULL) dbgprintf("]");\
|
||||
else dbgprintf("=%ld]",(long)ptr[index]);}
|
||||
|
||||
int argout(int dtype, int dval, int optype) {
|
||||
char *s;
|
||||
|
||||
if (dtype & AGT_VAR) dtype = AGT_VAR;
|
||||
|
||||
if ((optype & 3) == 1) /* variable */
|
||||
dtype = AGT_VAR;
|
||||
if (optype & 2) { /* NOUN or OBJECT */
|
||||
if (dtype >= 64 && dtype != AGT_NUM)
|
||||
dbgprintf("ILL:");
|
||||
if (optype == 2)
|
||||
print_special_obj(0); /* NOUN */
|
||||
else
|
||||
print_special_obj(1); /* OBJECT */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!interp_arg)
|
||||
dbgprintf("%d", dval);
|
||||
else {
|
||||
if (dtype < 64) {
|
||||
if (dval == -1)
|
||||
print_special_obj(2); /* NAME */
|
||||
else {
|
||||
s = getname(dval);
|
||||
if (dtype & (AGT_ITEM | AGT_CREAT | AGT_SELF | AGT_WORN))
|
||||
dbgprintf("<%d:%s>", dval, s);
|
||||
else
|
||||
dbgprintf("{%d:%s}", dval, s);
|
||||
rfree(s);
|
||||
}
|
||||
} else if ((dtype & AGT_VAR) != 0) {
|
||||
if (dval == -1)
|
||||
print_tos();
|
||||
else
|
||||
printval("Var", dval, dbgvarptr);
|
||||
} else switch (dtype) {
|
||||
case AGT_TIME:
|
||||
dbgprintf("%2d:%2d", dval / 100, dval % 100);
|
||||
break;
|
||||
case AGT_NUM: /* Numeric */
|
||||
dbgprintf("%d", dval);
|
||||
break;
|
||||
case AGT_FLAG: /* Flag */
|
||||
printval("Flg", dval, dbgflagptr);
|
||||
break;
|
||||
case AGT_ROOMFLAG: /* Roomflag */
|
||||
dbgprintf("RoomFlag%d", dval);
|
||||
break;
|
||||
case AGT_QUEST: /* Question */
|
||||
if (dval <= MaxQuestion && dval >= 1 && question != nullptr) {
|
||||
dbgprintf("\nQ%d:%s\n", dval, question[dval - 1]);
|
||||
dbgprintf("[A:%s]", answer[dval - 1]);
|
||||
} else if (quest_ptr != nullptr) {
|
||||
dbgprintf("\nQ%d: ", dval);
|
||||
print_msg(quest_ptr[dval - 1]);
|
||||
dbgprintf("[A:");
|
||||
print_msg(ans_ptr[dval - 1]);
|
||||
}
|
||||
break;
|
||||
case AGT_MSG: /* Message */
|
||||
if (dval > last_message || dval < 1 || msg_ptr == nullptr)
|
||||
dbgprintf("ILLEGAL MESSAGE");
|
||||
else {
|
||||
dbgprintf("(Msg%d)", dval);
|
||||
if (!dbg_nomsg)
|
||||
print_msg(msg_ptr[dval - 1]);
|
||||
}
|
||||
break;
|
||||
case AGT_ERR: /* Message */
|
||||
if (dval > NUM_ERR || dval < 1 || err_ptr == nullptr)
|
||||
dbgprintf("ILLEGAL MESSAGE");
|
||||
else {
|
||||
dbgprintf("(Std%d)", dval);
|
||||
if (!dbg_nomsg)
|
||||
print_msg(err_ptr[dval - 1]);
|
||||
}
|
||||
break;
|
||||
case AGT_STR: /* String */
|
||||
if (dval - 1 >= MAX_USTR || userstr == nullptr)
|
||||
dbgprintf("ILLEGAL STRING");
|
||||
else
|
||||
dbgprintf("\nStr%d:%s", dval, userstr[dval]);
|
||||
break;
|
||||
case AGT_CNT: /* Counter */
|
||||
printval("Cnt", dval, dbgcntptr);
|
||||
break;
|
||||
case AGT_DIR: /* Direction */
|
||||
if (dval >= 1 && dval <= 13)
|
||||
dbgprintf("%s", exitname[dval - 1]);
|
||||
else dbgprintf("ILL_DIR(%d)", dval);
|
||||
break;
|
||||
case AGT_SUB: /* Subroutine */
|
||||
dbgprintf("Subroutine %d", dval);
|
||||
break;
|
||||
case AGT_PIC: /* Picture */
|
||||
case AGT_PIX:
|
||||
dbgprintf("Picture #%d", dval);
|
||||
break;
|
||||
case AGT_FONT: /* Font */
|
||||
dbgprintf("Font #%d", dval);
|
||||
break;
|
||||
case AGT_SONG: /* Song */
|
||||
dbgprintf("Song #%d", dval);
|
||||
break;
|
||||
case AGT_OBJFLAG:
|
||||
dbgprintf("ObjFlag%d", dval);
|
||||
break;
|
||||
case AGT_OBJPROP:
|
||||
dbgprintf("ObjProp%d", dval);
|
||||
break;
|
||||
case AGT_ATTR:
|
||||
if (dval < 0 || dval >= NUM_ATTR)
|
||||
dbgprintf("UnkownAttr%d", dval);
|
||||
else
|
||||
dbgprintf("%s", attrlist[dval].name);
|
||||
break;
|
||||
case AGT_PROP:
|
||||
if (dval < 0 || dval >= NUM_PROP)
|
||||
dbgprintf("UnknownProp%d", dval);
|
||||
else
|
||||
dbgprintf("%s", proplist[dval].name);
|
||||
break;
|
||||
case AGT_EXIT:
|
||||
if (dval >= exitmsg_base)
|
||||
argout(AGT_MSG, dval - exitmsg_base, 0);
|
||||
else
|
||||
argout(AGT_ROOM, dval, 0);
|
||||
break;
|
||||
default:
|
||||
dbgprintf("?+%d", dval);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void debug_newline(integer op, rbool first_nl) {
|
||||
rbool early_nl;
|
||||
|
||||
if (!dbg_nomsg) return;
|
||||
early_nl = (op == 1008 || op == 1027 || op == 1083 || op == 1105
|
||||
|| (op >= 1126 && op <= 1131));
|
||||
if (early_nl == first_nl)
|
||||
debugout("\n");
|
||||
}
|
||||
|
||||
|
||||
void debug_cmd_out(int ip, integer op, int arg1, int arg2, int optype) {
|
||||
int j;
|
||||
const opdef *opdata;
|
||||
rbool save_dbg_nomsg;
|
||||
|
||||
dbgprintf(" %2d:", ip);
|
||||
save_dbg_nomsg = 0; /* Just to silence compiler warnings. */
|
||||
|
||||
opdata = get_opdef(op);
|
||||
if (opdata == &illegal_def)
|
||||
dbgprintf("ILLEGAL %d\n", op);
|
||||
else {
|
||||
if (op >= END_ACT) dbgprintf("!"); /* "Terminal" Actions */
|
||||
else if (op <= MAX_COND) dbgprintf("?"); /* Condition */
|
||||
if (op == 1063) { /* RandomMessage needs special handling */
|
||||
save_dbg_nomsg = dbg_nomsg;
|
||||
dbg_nomsg = 1;
|
||||
}
|
||||
dbgprintf("%s", opdata->opcode);
|
||||
for (j = 0; j < opdata->argnum; j++) {
|
||||
dbgprintf("\t");
|
||||
argout(j == 0 ? opdata->arg1 : opdata->arg2 , j == 0 ? arg1 : arg2,
|
||||
optype >> 2);
|
||||
optype <<= 2;
|
||||
}
|
||||
if (op == 1063)
|
||||
dbg_nomsg = save_dbg_nomsg;
|
||||
}
|
||||
debug_newline(op, 1);
|
||||
}
|
||||
|
||||
|
||||
void debug_head(int i) {
|
||||
int v, w, a;
|
||||
|
||||
v = verb_code(command[i].verbcmd);
|
||||
if (v >= BASE_VERB && v < BASE_VERB + DUMB_VERB && syntbl[synlist[v]] != 0)
|
||||
w = syntbl[synlist[v]];
|
||||
else w = command[i].verbcmd;
|
||||
if (command[i].actor > 0) {
|
||||
dbgprintf("CMD %d: ", i);
|
||||
a = command[i].actor;
|
||||
} else {
|
||||
dbgprintf("REDIR: ");
|
||||
a = -command[i].actor;
|
||||
}
|
||||
|
||||
if (a == 2)
|
||||
dbgprintf("anybody, ");
|
||||
else if (a > 2) {
|
||||
char *name;
|
||||
name = objname(a);
|
||||
name[0] = toupper(name[0]);
|
||||
dbgprintf("%s, ", name);
|
||||
rfree(name);
|
||||
}
|
||||
|
||||
dbgprintf("%s ", w == 0 ? "any" : dict[w]);
|
||||
if (command[i].noun_adj != 0)
|
||||
dbgprintf("%s ", gdict(command[i].noun_adj));
|
||||
dbgprintf("%s %s ", gdict(command[i].nouncmd),
|
||||
(ver == 3) ? gdict(command[i].prep) : "->");
|
||||
if (command[i].obj_adj != 0)
|
||||
dbgprintf("%s ", gdict(command[i].obj_adj));
|
||||
dbgprintf("%s\n", gdict(command[i].objcmd));
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace AGT
|
||||
} // End of namespace Glk
|
||||
Reference in New Issue
Block a user