1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "glk/agt/agility.h"
24
25 namespace Glk {
26 namespace AGT {
27
dbgprintf(const char * fmt,...)28 void dbgprintf(const char *fmt, ...) {
29 va_list vp;
30 char buff[300];
31
32 va_start(vp, fmt);
33 vsprintf(buff, fmt, vp);
34 va_end(vp);
35
36 debugout(buff);
37 }
38
39
print_msg(descr_ptr dptr)40 static void print_msg(descr_ptr dptr) {
41 int j;
42 descr_line *txt;
43
44 txt = read_descr(dptr.start, dptr.size);
45 if (txt != NULL) {
46 for (j = 0; txt[j] != NULL; j++) {
47 dbgprintf("\n");
48 debugout(txt[j]);
49 }
50 }
51 free_descr(txt);
52 }
53
54
getname(int inum)55 static char *getname(int inum)
56 /* Name should be 20 chars or less */
57 {
58 if (inum == 0) return rstrdup("* 0 *");
59 return objname(inum);
60 }
61
62
63 extern integer dobj, iobj, actor;
64
print_special_obj(int i)65 void print_special_obj(int i)
66 /* This is called by the disassembler in agtdbg.c */
67 /* i=0 NOUN, 1 OBJECT, 2 NAME */
68 {
69 int dval;
70 char *s;
71 switch (i) {
72 case 0:
73 dval = dobj;
74 dbgprintf("NOUN");
75 break;
76 case 1:
77 dval = iobj;
78 dbgprintf("OBJECT");
79 break;
80 case 2:
81 dval = actor;
82 dbgprintf("NAME");
83 break;
84 default:
85 dval = 0; /* Silence compiler warnings. */
86 fatal("INTERNAL ERROR: Invalid *dval* in print_special_obj.");
87 }
88 if (dbgflagptr == NULL)
89 /* This determines whether we are linked with agtout or agil */
90 return;
91 s = getname(dval);
92 dbgprintf("(%d:%s)", dval, s);
93 rfree(s);
94 }
95
96 #define printval(str,index,ptr) {dbgprintf("[%s%d",str,index);\
97 if (ptr==NULL) dbgprintf("]");\
98 else dbgprintf("=%ld]",(long)ptr[index]);}
99
argout(int dtype,int dval,int optype)100 int argout(int dtype, int dval, int optype) {
101 char *s;
102
103 if (dtype & AGT_VAR) dtype = AGT_VAR;
104
105 if ((optype & 3) == 1) /* variable */
106 dtype = AGT_VAR;
107 if (optype & 2) { /* NOUN or OBJECT */
108 if (dtype >= 64 && dtype != AGT_NUM)
109 dbgprintf("ILL:");
110 if (optype == 2)
111 print_special_obj(0); /* NOUN */
112 else
113 print_special_obj(1); /* OBJECT */
114 return 0;
115 }
116
117 if (!interp_arg)
118 dbgprintf("%d", dval);
119 else {
120 if (dtype < 64) {
121 if (dval == -1)
122 print_special_obj(2); /* NAME */
123 else {
124 s = getname(dval);
125 if (dtype & (AGT_ITEM | AGT_CREAT | AGT_SELF | AGT_WORN))
126 dbgprintf("<%d:%s>", dval, s);
127 else
128 dbgprintf("{%d:%s}", dval, s);
129 rfree(s);
130 }
131 } else if ((dtype & AGT_VAR) != 0) {
132 if (dval == -1)
133 print_tos();
134 else
135 printval("Var", dval, dbgvarptr);
136 } else switch (dtype) {
137 case AGT_TIME:
138 dbgprintf("%2d:%2d", dval / 100, dval % 100);
139 break;
140 case AGT_NUM: /* Numeric */
141 dbgprintf("%d", dval);
142 break;
143 case AGT_FLAG: /* Flag */
144 printval("Flg", dval, dbgflagptr);
145 break;
146 case AGT_ROOMFLAG: /* Roomflag */
147 dbgprintf("RoomFlag%d", dval);
148 break;
149 case AGT_QUEST: /* Question */
150 if (dval <= MaxQuestion && dval >= 1 && question != NULL) {
151 dbgprintf("\nQ%d:%s\n", dval, question[dval - 1]);
152 dbgprintf("[A:%s]", answer[dval - 1]);
153 } else if (quest_ptr != NULL) {
154 dbgprintf("\nQ%d: ", dval);
155 print_msg(quest_ptr[dval - 1]);
156 dbgprintf("[A:");
157 print_msg(ans_ptr[dval - 1]);
158 }
159 break;
160 case AGT_MSG: /* Message */
161 if (dval > last_message || dval < 1 || msg_ptr == NULL)
162 dbgprintf("ILLEGAL MESSAGE");
163 else {
164 dbgprintf("(Msg%d)", dval);
165 if (!dbg_nomsg)
166 print_msg(msg_ptr[dval - 1]);
167 }
168 break;
169 case AGT_ERR: /* Message */
170 if (dval > NUM_ERR || dval < 1 || err_ptr == NULL)
171 dbgprintf("ILLEGAL MESSAGE");
172 else {
173 dbgprintf("(Std%d)", dval);
174 if (!dbg_nomsg)
175 print_msg(err_ptr[dval - 1]);
176 }
177 break;
178 case AGT_STR: /* String */
179 if (dval - 1 >= MAX_USTR || userstr == NULL)
180 dbgprintf("ILLEGAL STRING");
181 else
182 dbgprintf("\nStr%d:%s", dval, userstr[dval]);
183 break;
184 case AGT_CNT: /* Counter */
185 printval("Cnt", dval, dbgcntptr);
186 break;
187 case AGT_DIR: /* Direction */
188 if (dval >= 1 && dval <= 13)
189 dbgprintf("%s", exitname[dval - 1]);
190 else dbgprintf("ILL_DIR(%d)", dval);
191 break;
192 case AGT_SUB: /* Subroutine */
193 dbgprintf("Subroutine %d", dval);
194 break;
195 case AGT_PIC: /* Picture */
196 case AGT_PIX:
197 dbgprintf("Picture #%d", dval);
198 break;
199 case AGT_FONT: /* Font */
200 dbgprintf("Font #%d", dval);
201 break;
202 case AGT_SONG: /* Song */
203 dbgprintf("Song #%d", dval);
204 break;
205 case AGT_OBJFLAG:
206 dbgprintf("ObjFlag%d", dval);
207 break;
208 case AGT_OBJPROP:
209 dbgprintf("ObjProp%d", dval);
210 break;
211 case AGT_ATTR:
212 if (dval < 0 || dval >= NUM_ATTR)
213 dbgprintf("UnkownAttr%d", dval);
214 else
215 dbgprintf("%s", attrlist[dval].name);
216 break;
217 case AGT_PROP:
218 if (dval < 0 || dval >= NUM_PROP)
219 dbgprintf("UnknownProp%d", dval);
220 else
221 dbgprintf("%s", proplist[dval].name);
222 break;
223 case AGT_EXIT:
224 if (dval >= exitmsg_base)
225 argout(AGT_MSG, dval - exitmsg_base, 0);
226 else
227 argout(AGT_ROOM, dval, 0);
228 break;
229 default:
230 dbgprintf("?+%d", dval);
231 }
232 }
233 return 1;
234 }
235
236
debug_newline(integer op,rbool first_nl)237 void debug_newline(integer op, rbool first_nl) {
238 rbool early_nl;
239
240 if (!dbg_nomsg) return;
241 early_nl = (op == 1008 || op == 1027 || op == 1083 || op == 1105
242 || (op >= 1126 && op <= 1131));
243 if (early_nl == first_nl)
244 debugout("\n");
245 }
246
247
debug_cmd_out(int ip,integer op,int arg1,int arg2,int optype)248 void debug_cmd_out(int ip, integer op, int arg1, int arg2, int optype) {
249 int j;
250 const opdef *opdata;
251 rbool save_dbg_nomsg;
252
253 dbgprintf(" %2d:", ip);
254 save_dbg_nomsg = 0; /* Just to silence compiler warnings. */
255
256 opdata = get_opdef(op);
257 if (opdata == &illegal_def)
258 dbgprintf("ILLEGAL %d\n", op);
259 else {
260 if (op >= END_ACT) dbgprintf("!"); /* "Terminal" Actions */
261 else if (op <= MAX_COND) dbgprintf("?"); /* Condition */
262 if (op == 1063) { /* RandomMessage needs special handling */
263 save_dbg_nomsg = dbg_nomsg;
264 dbg_nomsg = 1;
265 }
266 dbgprintf("%s", opdata->opcode);
267 for (j = 0; j < opdata->argnum; j++) {
268 dbgprintf("\t");
269 argout(j == 0 ? opdata->arg1 : opdata->arg2 , j == 0 ? arg1 : arg2,
270 optype >> 2);
271 optype <<= 2;
272 }
273 if (op == 1063)
274 dbg_nomsg = save_dbg_nomsg;
275 }
276 debug_newline(op, 1);
277 }
278
279
debug_head(int i)280 void debug_head(int i) {
281 int v, w, a;
282
283 v = verb_code(command[i].verbcmd);
284 if (v >= BASE_VERB && v < BASE_VERB + DUMB_VERB && syntbl[synlist[v]] != 0)
285 w = syntbl[synlist[v]];
286 else w = command[i].verbcmd;
287 if (command[i].actor > 0) {
288 dbgprintf("CMD %d: ", i);
289 a = command[i].actor;
290 } else {
291 dbgprintf("REDIR: ");
292 a = -command[i].actor;
293 }
294
295 if (a == 2)
296 dbgprintf("anybody, ");
297 else if (a > 2) {
298 char *name;
299 name = objname(a);
300 name[0] = toupper(name[0]);
301 dbgprintf("%s, ", name);
302 rfree(name);
303 }
304
305 dbgprintf("%s ", w == 0 ? "any" : dict[w]);
306 if (command[i].noun_adj != 0)
307 dbgprintf("%s ", gdict(command[i].noun_adj));
308 dbgprintf("%s %s ", gdict(command[i].nouncmd),
309 (ver == 3) ? gdict(command[i].prep) : "->");
310 if (command[i].obj_adj != 0)
311 dbgprintf("%s ", gdict(command[i].obj_adj));
312 dbgprintf("%s\n", gdict(command[i].objcmd));
313
314 }
315
316 } // End of namespace AGT
317 } // End of namespace Glk
318