1 /* ScummVM Tools
2 *
3 * ScummVM Tools is the legal property of its developers, whose
4 * names are too numerous to list here. Please refer to the
5 * COPYRIGHT 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 /* Scumm Script Disassembler (version 2-5 scripts) */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27
28 #include "descumm.h"
29
30 #include "common/util.h"
31
32 /*
33 Similar to the code that detects "head" while loops like this:
34 while(Condition) {
35 }
36 add code to detect tail while loops, i.e. something of the kind
37 do {
38 } while(Condition);
39 In V2-V5, those are the most frequent type of loops (and in V6-V8 they
40 sometimes occur, too).
41
42 However, implementing this might be quite tricky, and require us to refactor the
43 code, because unlike a "head if/while", we don't know we are inside a loop until its
44 end. This means a problem for indention, and when outputing the initial "do {".
45 To solve this, we could implement some sort of look ahead; but that would be very
46 complicated, because essentially we have to perform full parsing of the data anyway.
47 Instead of doing multiple look aheads, one could also do a 2 pass descumming:
48 In pass 1, we find all jump statement, and identify all jump targets. From this data
49 we can work backwards to detect all loops (and also if/else/elsif).
50 Yet another approach would be to not emit any lines until we fully descummed the script.
51 Instead, we keep each line in a line buffer, with indention but with an associated
52 "indention" variable. When we discover a do/while loop, we can then insert a "do {"
53 line and increase the indention of all intermediate lines. However this approach
54 needs a lot of memory, and won't output anything until the script is fully descummed,
55 which is annoying when debugging descumm.
56
57 */
58
59 enum TokenType {
60 TOK_BYTE = 1,
61 TOK_WORD = 2,
62 TOK_VAR = 3,
63 TOK_LIST = 4,
64 TOK_ASCII = 5,
65 TOK_CHAR = 6
66 };
67
68
69 #define A1B (TOK_BYTE<<0)
70 #define A1W (TOK_WORD<<0)
71 #define A1V (TOK_VAR<<0)
72 #define A1LIST (TOK_LIST<<0)
73 #define A1ASCII (TOK_ASCII<<0)
74
75 #define A2B (TOK_BYTE<<4)
76 #define A2W (TOK_WORD<<4)
77 #define A2V (TOK_VAR<<4)
78 #define A2LIST (TOK_LIST<<4)
79 #define A2ASCII (TOK_ASCII<<4)
80
81 #define A3B (TOK_BYTE<<8)
82 #define A3W (TOK_WORD<<8)
83 #define A3V (TOK_VAR<<8)
84 #define A3LIST (TOK_LIST<<8)
85 #define A3ASCII (TOK_ASCII<<8)
86 #define A3CHAR (TOK_CHAR<<8)
87
88 #define A4B (TOK_BYTE<<12)
89 #define A4W (TOK_WORD<<12)
90 #define A4V (TOK_VAR<<12)
91 #define A4LIST (TOK_LIST<<12)
92 #define A4ASCII (TOK_ASCII<<12)
93 #define A4CHAR (TOK_CHAR<<12)
94
95 #define A5ASCII (TOK_ASCII<<16)
96
97 #define ATO (1<<31)
98 #define ANOLASTPAREN (1<<30)
99 #define ANOFIRSTPAREN (1<<29)
100 #define ASTARTCOMMA (1<<28)
101 #define AVARSTORE (1<<27)
102 #define ANOENDSEMICOLON (1<<26)
103 #define ATOWITHLASTPAREN (1<<25)
104
105
106 void emit_if(char *buf, char *condition);
107
108
109 const char *var_names0[] = {
110 /* 0 */
111 "VAR_EGO",
112 "VAR_RESULT",
113 "VAR_CAMERA_POS_X",
114 "VAR_HAVE_MSG",
115 /* 4 */
116 "VAR_ROOM",
117 "VAR_ACTIVE_ACTOR",
118 "VAR_OVERRIDE",
119 NULL,
120 /* 8 */
121 "VAR_IS_SOUND_RUNNING",
122 "VAR_ACTIVE_VERB",
123 "VAR_CHARCOUNT",
124 NULL
125 };
126
127 const char *var_names2[] = {
128 /* 0 */
129 "VAR_EGO",
130 "VAR_RESULT",
131 "VAR_CAMERA_POS_X",
132 "VAR_HAVE_MSG",
133 /* 4 */
134 "VAR_ROOM",
135 "VAR_OVERRIDE",
136 "VAR_MACHINE_SPEED",
137 "VAR_CHARCOUNT",
138 /* 8 */
139 "VAR_ACTIVE_VERB",
140 "VAR_ACTIVE_OBJECT1",
141 "VAR_ACTIVE_OBJECT2",
142 "VAR_NUM_ACTOR",
143 /* 12 */
144 "VAR_CURRENT_LIGHTS",
145 "VAR_CURRENTDRIVE",
146 NULL,
147 NULL,
148 /* 16 */
149 NULL,
150 "VAR_MUSIC_TIMER",
151 "VAR_VERB_ALLOWED",
152 "VAR_ACTOR_RANGE_MIN",
153 /* 20 */
154 "VAR_ACTOR_RANGE_MAX",
155 NULL,
156 NULL,
157 "VAR_CAMERA_MIN_X",
158 /* 24 */
159 "VAR_CAMERA_MAX_X",
160 "VAR_TIMER_NEXT",
161 "VAR_SENTENCE_VERB",
162 "VAR_SENTENCE_OBJECT1",
163 /* 28 */
164 "VAR_SENTENCE_OBJECT2",
165 "VAR_SENTENCE_PREPOSITION",
166 "VAR_VIRT_MOUSE_X",
167 "VAR_VIRT_MOUSE_Y",
168 /* 32 */
169 "VAR_CLICK_AREA",
170 "VAR_CLICK_VERB",
171 NULL,
172 "VAR_CLICK_OBJECT",
173 /* 36 */
174 "VAR_ROOM_RESOURCE",
175 "VAR_LAST_SOUND",
176 "VAR_BACKUP_VERB",
177 "VAR_KEYPRESS",
178 /* 40 */
179 "VAR_CUTSCENEEXIT_KEY",
180 "VAR_TALK_ACTOR",
181 NULL,
182 NULL
183 };
184
185 const char *var_names3[] = {
186 /* 0 */
187 "VAR_RESULT",
188 "VAR_EGO",
189 "VAR_CAMERA_POS_X",
190 "VAR_HAVE_MSG",
191 /* 4 */
192 "VAR_ROOM",
193 "VAR_OVERRIDE",
194 "VAR_MACHINE_SPEED",
195 "VAR_ME",
196 /* 8 */
197 "VAR_NUM_ACTOR",
198 "VAR_CURRENT_LIGHTS",
199 "VAR_CURRENTDRIVE",
200 "VAR_TMR_1",
201 /* 12 */
202 "VAR_TMR_2",
203 "VAR_TMR_3",
204 "VAR_MUSIC_TIMER",
205 "VAR_ACTOR_RANGE_MIN",
206 /* 16 */
207 "VAR_ACTOR_RANGE_MAX",
208 "VAR_CAMERA_MIN_X",
209 "VAR_CAMERA_MAX_X",
210 "VAR_TIMER_NEXT",
211 /* 20 */
212 "VAR_VIRT_MOUSE_X",
213 "VAR_VIRT_MOUSE_Y",
214 "VAR_ROOM_RESOURCE",
215 "VAR_LAST_SOUND",
216 /* 24 */
217 "VAR_CUTSCENEEXIT_KEY",
218 "VAR_TALK_ACTOR",
219 "VAR_CAMERA_FAST_X",
220 NULL,
221 /* 28 */
222 "VAR_ENTRY_SCRIPT",
223 "VAR_ENTRY_SCRIPT2",
224 "VAR_EXIT_SCRIPT",
225 "VAR_EXIT_SCRIPT2",
226 /* 32 */
227 "VAR_VERB_SCRIPT",
228 "VAR_SENTENCE_SCRIPT",
229 "VAR_INVENTORY_SCRIPT",
230 "VAR_CUTSCENE_START_SCRIPT",
231 /* 36 */
232 "VAR_CUTSCENE_END_SCRIPT",
233 "VAR_CHARINC",
234 "VAR_WALKTO_OBJ",
235 NULL,
236 /* 40 */
237 NULL,
238 NULL,
239 "VAR_RESTART_KEY",
240 "VAR_PAUSE_KEY",
241 /* 44 */
242 "VAR_MOUSE_X",
243 "VAR_MOUSE_Y",
244 "VAR_TIMER",
245 "VAR_TIMER_TOTAL",
246 /* 48 */
247 "VAR_SOUNDCARD",
248 "VAR_VIDEOMODE",
249 NULL,
250 NULL
251 };
252
253 const char *var_names4[] = {
254 /* 0 */
255 "VAR_RESULT",
256 "VAR_EGO",
257 "VAR_CAMERA_POS_X",
258 "VAR_HAVE_MSG",
259 /* 4 */
260 "VAR_ROOM",
261 "VAR_OVERRIDE",
262 "VAR_MACHINE_SPEED",
263 "VAR_ME",
264 /* 8 */
265 "VAR_NUM_ACTOR",
266 "VAR_CURRENT_LIGHTS",
267 "VAR_CURRENTDRIVE",
268 "VAR_TMR_1",
269 /* 12 */
270 "VAR_TMR_2",
271 "VAR_TMR_3",
272 "VAR_MUSIC_TIMER",
273 "VAR_ACTOR_RANGE_MIN",
274 /* 16 */
275 "VAR_ACTOR_RANGE_MAX",
276 "VAR_CAMERA_MIN_X",
277 "VAR_CAMERA_MAX_X",
278 "VAR_TIMER_NEXT",
279 /* 20 */
280 "VAR_VIRT_MOUSE_X",
281 "VAR_VIRT_MOUSE_Y",
282 "VAR_ROOM_RESOURCE",
283 "VAR_LAST_SOUND",
284 /* 24 */
285 "VAR_CUTSCENEEXIT_KEY",
286 "VAR_TALK_ACTOR",
287 "VAR_CAMERA_FAST_X",
288 "VAR_SCROLL_SCRIPT",
289 /* 28 */
290 "VAR_ENTRY_SCRIPT",
291 "VAR_ENTRY_SCRIPT2",
292 "VAR_EXIT_SCRIPT",
293 "VAR_EXIT_SCRIPT2",
294 /* 32 */
295 "VAR_VERB_SCRIPT",
296 "VAR_SENTENCE_SCRIPT",
297 "VAR_INVENTORY_SCRIPT",
298 "VAR_CUTSCENE_START_SCRIPT",
299 /* 36 */
300 "VAR_CUTSCENE_END_SCRIPT",
301 "VAR_CHARINC",
302 "VAR_WALKTO_OBJ",
303 "VAR_DEBUGMODE",
304 /* 40 */
305 "VAR_HEAPSPACE",
306 NULL,
307 "VAR_RESTART_KEY",
308 "VAR_PAUSE_KEY",
309 /* 44 */
310 "VAR_MOUSE_X",
311 "VAR_MOUSE_Y",
312 "VAR_TIMER",
313 "VAR_TIMER_TOTAL",
314 /* 48 */
315 "VAR_SOUNDCARD",
316 "VAR_VIDEOMODE",
317 "VAR_MAINMENU_KEY",
318 "VAR_FIXEDDISK",
319 /* 52 */
320 "VAR_CURSORSTATE",
321 "VAR_USERPUT",
322 "VAR_V5_TALK_STRING_Y",
323 /* Loom CD specific */
324 NULL,
325 /* 56 */
326 NULL,
327 NULL,
328 NULL,
329 NULL,
330 /* 60 */
331 "VAR_NOSUBTITLES",
332 NULL,
333 NULL,
334 NULL,
335 /* 64 */
336 "VAR_SOUNDPARAM",
337 "VAR_SOUNDPARAM2",
338 "VAR_SOUNDPARAM3",
339 NULL
340 };
341
342 const char *var_names5[] = {
343 /* 0 */
344 "VAR_RESULT",
345 "VAR_EGO",
346 "VAR_CAMERA_POS_X",
347 "VAR_HAVE_MSG",
348 /* 4 */
349 "VAR_ROOM",
350 "VAR_OVERRIDE",
351 "VAR_MACHINE_SPEED",
352 "VAR_ME",
353 /* 8 */
354 "VAR_NUM_ACTOR",
355 "VAR_CURRENT_LIGHTS",
356 "VAR_CURRENTDRIVE",
357 "VAR_TMR_1",
358 /* 12 */
359 "VAR_TMR_2",
360 "VAR_TMR_3",
361 "VAR_MUSIC_TIMER",
362 "VAR_ACTOR_RANGE_MIN",
363 /* 16 */
364 "VAR_ACTOR_RANGE_MAX",
365 "VAR_CAMERA_MIN_X",
366 "VAR_CAMERA_MAX_X",
367 "VAR_TIMER_NEXT",
368 /* 20 */
369 "VAR_VIRT_MOUSE_X",
370 "VAR_VIRT_MOUSE_Y",
371 "VAR_ROOM_RESOURCE",
372 "VAR_LAST_SOUND",
373 /* 24 */
374 "VAR_CUTSCENEEXIT_KEY",
375 "VAR_TALK_ACTOR",
376 "VAR_CAMERA_FAST_X",
377 "VAR_SCROLL_SCRIPT",
378 /* 28 */
379 "VAR_ENTRY_SCRIPT",
380 "VAR_ENTRY_SCRIPT2",
381 "VAR_EXIT_SCRIPT",
382 "VAR_EXIT_SCRIPT2",
383 /* 32 */
384 "VAR_VERB_SCRIPT",
385 "VAR_SENTENCE_SCRIPT",
386 "VAR_INVENTORY_SCRIPT",
387 "VAR_CUTSCENE_START_SCRIPT",
388 /* 36 */
389 "VAR_CUTSCENE_END_SCRIPT",
390 "VAR_CHARINC",
391 "VAR_WALKTO_OBJ",
392 "VAR_DEBUGMODE",
393 /* 40 */
394 "VAR_HEAPSPACE",
395 NULL,
396 "VAR_RESTART_KEY",
397 "VAR_PAUSE_KEY",
398 /* 44 */
399 "VAR_MOUSE_X",
400 "VAR_MOUSE_Y",
401 "VAR_TIMER",
402 "VAR_TIMER_TOTAL",
403 /* 48 */
404 "VAR_SOUNDCARD",
405 "VAR_VIDEOMODE",
406 "VAR_MAINMENU_KEY",
407 "VAR_FIXEDDISK",
408 /* 52 */
409 "VAR_CURSORSTATE",
410 "VAR_USERPUT",
411 NULL,
412 NULL,
413 /* 56 */
414 "VAR_SOUNDRESULT",
415 "VAR_TALKSTOP_KEY",
416 NULL,
417 "VAR_FADE_DELAY",
418 /* 60 */
419 "VAR_NOSUBTITLES",
420 NULL,
421 NULL,
422 NULL,
423 /* 64 */
424 "VAR_SOUNDPARAM",
425 "VAR_SOUNDPARAM2",
426 "VAR_SOUNDPARAM3",
427 "VAR_INPUTMODE",
428 /* 68 */
429 "VAR_MEMORY_PERFORMANCE",
430 "VAR_VIDEO_PERFORMANCE",
431 "VAR_ROOM_FLAG",
432 "VAR_GAME_LOADED",
433 /* 72 */
434 "VAR_NEW_ROOM",
435 NULL,
436 NULL,
437 NULL,
438 /* 76 */
439 NULL,
440 NULL,
441 NULL,
442 NULL
443 };
444
445
get_num_string(int i)446 const char *get_num_string(int i) {
447 const char *s;
448
449 if (i & 0x8000) { /* Bit var */
450 i &= 0xFFF;
451 if (i >= 0x800)
452 s = "??Bit??";
453 else
454 s = "Bit";
455 } else if (i & 0x4000) {
456 i &= g_options.IndyFlag ? 0xF : 0xFFF;
457 if (i > 0x10)
458 s = "??Local??";
459 else
460 s = "Local";
461 } else {
462 i &= 0xFFF;
463 if (i >= 0x320)
464 s = "??Var??";
465 else
466 s = "Var";
467 }
468
469 if (g_options.haltOnError && (s[0] == '?')) {
470 error("%s out of range, was %d", s, i);
471 }
472
473 return s;
474 }
475
476
get_var(char * buf)477 char *get_var(char *buf) {
478 int i;
479
480 if (g_options.scriptVersion <= 2)
481 i = get_byte();
482 else
483 i = (uint16)get_word();
484
485 assert(i >= 0);
486
487 if (g_options.scriptVersion >= 5 &&
488 i < ARRAYSIZE(var_names5) && var_names5[i]) {
489 buf += sprintf(buf, "%s", var_names5[i]);
490 return buf;
491 } else if (g_options.scriptVersion >= 4 &&
492 i < ARRAYSIZE(var_names4) && var_names4[i]) {
493 buf += sprintf(buf, "%s", var_names4[i]);
494 return buf;
495 } else if (g_options.scriptVersion >= 3 &&
496 i < ARRAYSIZE(var_names3) && var_names3[i]) {
497 buf += sprintf(buf, "%s", var_names3[i]);
498 return buf;
499 } else if (g_options.scriptVersion >= 1 &&
500 i < ARRAYSIZE(var_names2) && var_names2[i]) {
501 buf += sprintf(buf, "%s", var_names2[i]);
502 return buf;
503 } else if (g_options.scriptVersion == 0 &&
504 i < ARRAYSIZE(var_names0) && var_names0[i]) {
505 buf += sprintf(buf, "%s", var_names0[i]);
506 return buf;
507 } else if (g_options.scriptVersion <= 2 && g_options.ZakFlag && (i == 234 || i == 235)) {
508 buf += sprintf(buf, (i == 234) ? "ZERO" : "ONE");
509 return buf;
510 } else if ((i & 0x8000) && (g_options.GF_UNBLOCKED || g_options.ZakFlag))
511 buf += sprintf(buf, "Var[%d Bit %d", (i & 0x0FFF) >> 4, i & 0x000F);
512 else
513 buf += sprintf(buf, "%s[%d", get_num_string(i), i & 0xFFF);
514
515 if (i & 0x2000) {
516 int j = get_word();
517 if (j & 0x2000) {
518 j ^= 0x2000;
519 sprintf(buf, " + %s[%d]", get_num_string(j), j & 0xFFF);
520 } else
521 sprintf(buf, " + %d", j & 0xFFF);
522 }
523 strcat(buf, "]");
524
525 return strchr(buf, 0);
526
527 }
528
get_var_or_word(char * buf,char condition)529 char *get_var_or_word(char *buf, char condition) {
530 if (condition)
531 get_var(buf);
532 else
533 sprintf(buf, "%d", get_word());
534 return strchr(buf, 0);
535 }
536
get_var_or_byte(char * buf,char condition)537 char *get_var_or_byte(char *buf, char condition) {
538 if (condition)
539 get_var(buf);
540 else
541 sprintf(buf, "%d", get_byte());
542 return strchr(buf, 0);
543 }
544
get_list(char * buf)545 char *get_list(char *buf) {
546 int i;
547 int j = 0;
548 bool first = true;
549
550 buf = strecpy(buf, "[");
551 do {
552 i = get_byte();
553 if (i == 0xFF)
554 break;
555 if (!first)
556 buf = strecpy(buf, ",");
557 first = false;
558 buf = get_var_or_word(buf, i & 0x80);
559 j++;
560 if (j > 16) {
561 printf("ERROR: too many variables in argument list!\n");
562 if (g_options.haltOnError)
563 exit(1);
564 break;
565 }
566 } while (1);
567
568 return strecpy(buf, "]");
569 }
570
571
add_a_tok(char * buf,int type)572 char *add_a_tok(char *buf, int type) {
573 switch (type) {
574 case TOK_BYTE:
575 buf += sprintf(buf, "%d", get_byte());
576 break;
577 case TOK_WORD:
578 buf += sprintf(buf, "%d", get_word());
579 break;
580 case TOK_VAR:
581 buf = get_var(buf);
582 break;
583 case TOK_LIST:
584 buf = get_list(buf);
585 break;
586 case TOK_ASCII:
587 buf = get_string(buf);
588 break;
589 case TOK_CHAR:
590 error("this code seems to be dead");
591 buf = put_ascii(buf, get_byte());
592 break;
593 }
594 return buf;
595 }
596
do_tok(char * buf,const char * text,int args)597 char *do_tok(char *buf, const char *text, int args) {
598 char *buforg = buf;
599
600
601 if (args & AVARSTORE) {
602 buf = get_var(buf);
603 buf = strecpy(buf, " = ");
604 }
605
606 if (text)
607 buf = strecpy(buf, text);
608
609 if (!(args & ANOFIRSTPAREN))
610 buf = strecpy(buf, "(");
611
612 if (args & ASTARTCOMMA)
613 buf = strecpy(buf, ",");
614
615 if (args & 0xF) {
616 buf = add_a_tok(buf, args & 0xF);
617 if (args & 0xF0) {
618 buf = add_a_tok(strecpy(buf, ","), (args >> 4) & 0xF);
619 if (args & 0xF00) {
620 buf = add_a_tok(strecpy(buf, ","), (args >> 8) & 0xF);
621 if (args & 0xF000) {
622 buf = add_a_tok(strecpy(buf, ","), (args >> 12) & 0xF);
623 if (args & 0xF0000)
624 buf = add_a_tok(strecpy(buf, ","), (args >> 16) & 0xF);
625 }
626 }
627 }
628 }
629
630 if (args & ATO) {
631 char tmp[256];
632 if (args & ATOWITHLASTPAREN) {
633 buf = strecpy(buf, ")");
634 }
635 strcpy(tmp, buforg);
636 emit_if(buforg, tmp);
637 } else {
638 if (!(args & ANOLASTPAREN)) {
639 buf = strecpy(buf, ")");
640 }
641 if (!(args & ANOENDSEMICOLON) && buf[(strlen(buf) - 1)] != ';') {
642 buf = strecpy(buf, ";");
643 }
644 }
645
646 return strchr(buf, 0);
647 }
648
do_decodeparsestring_v2(char * buf,byte opcode)649 void do_decodeparsestring_v2(char *buf, byte opcode) {
650 byte c;
651 bool flag;
652
653 while ((c = get_byte())) {
654 flag = (c & 0x80) != 0;
655 c &= 0x7f;
656
657 if (c < 8) {
658 buf += sprintf(buf, "\\x%.2X", (int)c);
659 if (c > 3) {
660 buf += sprintf(buf, "\\x%.2X", (int)get_byte());
661 }
662 } else {
663 if (c == '\\' || c == '"') // backslash is the escape character
664 *buf++ = '\\';
665 }
666 *buf++ = c;
667 if (flag)
668 *buf++ = ' ';
669 }
670 *buf = 0;
671 }
672
do_actorops_v12(char * buf,byte opcode)673 void do_actorops_v12(char *buf, byte opcode) {
674 buf = strecpy(buf, "ActorOps(");
675 buf = get_var_or_byte(buf, opcode & 0x80);
676 buf = strecpy(buf, ",[");
677
678 char arg[256];
679 get_var_or_byte(arg, opcode & 0x40);
680
681 int subop = get_byte();
682 switch(subop) {
683 case 1:
684 buf += sprintf(buf, "Sound(%s)", arg);
685 break;
686 case 2:
687 if (g_options.scriptVersion == 1)
688 buf += sprintf(buf, "Color(%s)", arg);
689 else
690 buf += sprintf(buf, "Color(%d, %s)", get_byte(), arg);
691 break;
692 case 3:
693 buf = do_tok(buf, "Name", A1ASCII | ANOENDSEMICOLON);
694 break;
695 case 4:
696 buf += sprintf(buf, "Costume(%s)", arg);
697 break;
698 case 5:
699 buf += sprintf(buf, "TalkColor(%s)", arg);
700 break;
701 default:
702 error("do_actorops_v12: unknown subop %d", subop);
703 }
704 strecpy(buf, "]);");
705 }
706
do_actorops(char * buf,byte opcode)707 void do_actorops(char *buf, byte opcode) {
708 static const byte convertTable[20] =
709 { 1, 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20 };
710
711 char first = 1;
712
713 buf = do_tok(buf, "ActorOps", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
714
715 buf = strecpy(buf, ",[");
716
717 do {
718 opcode = get_byte();
719 if (opcode == 0xFF)
720 break;
721 if (!first)
722 buf = strecpy(buf, ",");
723 first = 0;
724
725 // FIXME - this really should be a check for GF_SMALL_HEADER instead!
726 if (g_options.scriptVersion < 5)
727 opcode = (opcode & 0xE0) | convertTable[(opcode & 0x1F) - 1];
728
729 switch (opcode & 0x1F) {
730 case 0x00:
731 buf = do_tok(buf, "Unknown", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
732 break;
733 case 0x01:
734 buf = do_tok(buf, "Costume", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
735 break;
736 case 0x02:
737 buf = do_tok(buf, "WalkSpeed", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
738 break;
739 case 0x03:
740 buf = do_tok(buf, "Sound", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
741 break;
742 case 0x04:
743 buf = do_tok(buf, "WalkAnimNr", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
744 break;
745 case 0x05:
746 buf =
747 do_tok(buf, "TalkAnimNr", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
748 break;
749 case 0x06:
750 buf = do_tok(buf, "StandAnimNr", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
751 break;
752 case 0x07:
753 buf =
754 do_tok(buf, "Nothing",
755 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
756 ((opcode & 0x20) ? A3V : A3B) | ANOENDSEMICOLON);
757 break;
758 case 0x08:
759 buf = do_tok(buf, "Init", ANOENDSEMICOLON);
760 break;
761 case 0x09:
762 buf = do_tok(buf, "Elevation", ((opcode & 0x80) ? A1V : A1W) | ANOENDSEMICOLON);
763 break;
764 case 0x0A:
765 buf = do_tok(buf, "DefaultAnims", ANOENDSEMICOLON);
766 break;
767 case 0x0B:
768 buf = do_tok(buf, "Palette", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
769 break;
770 case 0x0C:
771 buf = do_tok(buf, "TalkColor", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
772 break;
773 case 0x0D:
774 buf = do_tok(buf, "Name", A1ASCII | ANOENDSEMICOLON);
775 break;
776 case 0x0E:
777 buf = do_tok(buf, "InitAnimNr", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
778 break;
779 // case 0x0F: buf=do_tok(buf, "PaletteList", A1LIST); break;
780 case 0x10:
781 buf = do_tok(buf, "Width", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
782 break;
783 case 0x11:
784 if (g_options.scriptVersion == 5)
785 buf = do_tok(buf, "Scale", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
786 else
787 buf = do_tok(buf, "Scale", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
788 break;
789 case 0x12:
790 buf = do_tok(buf, "NeverZClip", ANOENDSEMICOLON);
791 break;
792 case 0x13:
793 buf = do_tok(buf, "SetZClip", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
794 break;
795 case 0x14:
796 buf = do_tok(buf, "IgnoreBoxes", ANOENDSEMICOLON);
797 break;
798 case 0x15:
799 buf = do_tok(buf, "FollowBoxes", ANOENDSEMICOLON);
800 break;
801 case 0x16:
802 buf = do_tok(buf, "AnimSpeed", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
803 break;
804 case 0x17:
805 buf=do_tok(buf, "ShadowMode", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
806 break;
807 default:
808 buf += sprintf(buf, "Unknown%.2X()", opcode);
809 }
810 } while (1);
811
812 strecpy(buf, "]);");
813
814 }
815
816 static int g_numInExprStack;
817 static char *g_exprStack[256];
818
pushExprStack(char * s)819 void pushExprStack(char *s) {
820 assert(g_numInExprStack < 256);
821 g_exprStack[g_numInExprStack++] = strdup(s);
822 }
823
popExprStack(char * buf)824 char *popExprStack(char *buf) {
825 char *s;
826
827 if (g_numInExprStack <= 0) {
828 printf("Expression stack is empty!\n");
829 exit(0);
830 }
831
832 s = g_exprStack[--g_numInExprStack];
833 buf = strecpy(buf, s);
834 free(s);
835 return buf;
836 }
837
838
do_expr_code(char * buf)839 void do_expr_code(char *buf) {
840 int i;
841 const char *s;
842 char *buf2;
843
844 char tmp[256];
845
846 buf = strecpy(buf, "Exprmode ");
847 buf = get_var(buf);
848 buf = strecpy(buf, " = ");
849
850 g_numInExprStack = 0;
851
852 do {
853 i = get_byte();
854 if (i == 0xFF)
855 break;
856 switch (i & 0x1F) {
857 case 0x1:
858 get_var_or_word(buf, i & 0x80);
859 pushExprStack(buf);
860 break;
861
862 case 0x2:
863 s = " + ";
864 goto do_oper;
865
866 case 0x3:
867 s = " - ";
868 goto do_oper;
869
870 case 0x4:
871 s = " * ";
872 goto do_oper;
873
874 case 0x5:
875 s = " / ";
876 do_oper:;
877 buf2 = strecpy(buf, "(");
878 popExprStack(tmp);
879 buf2 = popExprStack(buf2);
880 buf2 = strecpy(buf2, s);
881 buf2 = strecpy(buf2, tmp);
882 strecpy(buf2, ")");
883 pushExprStack(buf);
884 break;
885
886 case 0x6:
887 buf2 = strecpy(buf, "<");
888 if (g_options.scriptVersion <= 2)
889 next_line_V12(buf2);
890 else
891 next_line_V345(buf2);
892 if (buf2[(strlen(buf2) - 1)] == ';') {
893 buf2[(strlen(buf2) - 1)] = 0;
894 }
895 strecpy(strchr(buf2, 0), ">");
896 pushExprStack(buf);
897 break;
898
899 default:
900 printf("Warning, Invalid expression code %.2X\n", i);
901 }
902
903 } while (1);
904
905 strcpy(popExprStack(buf), ";");
906 }
907
908
do_load_code_to_string(char * buf,byte opcode)909 void do_load_code_to_string(char *buf, byte opcode) {
910
911 buf = strchr(strcpy(buf, "PutCodeInString("), 0);
912 buf = get_var_or_byte(buf, opcode & 0x80);
913 buf = strchr(strcpy(buf, ", "), 0);
914 buf = get_string(buf);
915 strcpy(buf, ");");
916 }
917
do_resource_v2(char * buf,byte opcode)918 void do_resource_v2(char *buf, byte opcode) {
919 const char *resTypes[] = {
920 "UnkResType0",
921 "UnkResType1",
922 "Costume",
923 "Room",
924 "UnkResType4",
925 "Script",
926 "Sound"
927 };
928 char resid[256];
929 int subop;
930
931 get_var_or_byte(resid, opcode & 0x80);
932 subop = get_byte();
933
934 int type = subop >> 4;
935
936 if (((subop & 0x0F) == 0) || ((subop & 0x0F) == 1)) {
937 if (subop & 1)
938 buf += sprintf(buf, "load");
939 else
940 buf += sprintf(buf, "nuke");
941 assert(0 <= type && type < ARRAYSIZE(resTypes));
942 buf += sprintf(buf, "%s", resTypes[type]);
943 buf += sprintf(buf, "(%s)", resid);
944 } else {
945 if (subop & 1)
946 buf += sprintf(buf, "lock");
947 else
948 buf += sprintf(buf, "unlock");
949 assert(0 <= type && type < ARRAYSIZE(resTypes));
950 buf += sprintf(buf, "%s", resTypes[type]);
951 buf += sprintf(buf, "(%s)", resid);
952 }
953 }
954
do_resource(char * buf,byte opco)955 void do_resource(char *buf, byte opco) {
956 char opcode = get_byte();
957 int subop;
958 if (g_options.scriptVersion != 5)
959 subop = opcode & 0x3F; // FIXME - actually this should only be done for Zak256
960 else
961 subop = opcode & 0x1F;
962
963 buf += sprintf(buf, "Resource.");
964
965 switch (subop) {
966 case 0x1:
967 do_tok(buf, "loadScript", ((opcode & 0x80) ? A1V : A1B));
968 break;
969 case 0x2:
970 do_tok(buf, "loadSound", ((opcode & 0x80) ? A1V : A1B));
971 break;
972 case 0x3:
973 do_tok(buf, "loadCostume", ((opcode & 0x80) ? A1V : A1B));
974 break;
975 case 0x4:
976 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
977 break;
978 case 0x5:
979 do_tok(buf, "nukeScript", ((opcode & 0x80) ? A1V : A1B));
980 break;
981 case 0x6:
982 do_tok(buf, "nukeSound", ((opcode & 0x80) ? A1V : A1B));
983 break;
984 case 0x7:
985 do_tok(buf, "nukeCostume", ((opcode & 0x80) ? A1V : A1B));
986 break;
987 case 0x8:
988 do_tok(buf, "nukeRoom", ((opcode & 0x80) ? A1V : A1B));
989 break;
990 case 0x9:
991 do_tok(buf, "lockScript", ((opcode & 0x80) ? A1V : A1B));
992 break;
993 case 0xA:
994 do_tok(buf, "lockSound", ((opcode & 0x80) ? A1V : A1B));
995 break;
996 case 0xB:
997 do_tok(buf, "lockCostume", ((opcode & 0x80) ? A1V : A1B));
998 break;
999 case 0xC:
1000 do_tok(buf, "lockRoom", ((opcode & 0x80) ? A1V : A1B));
1001 break;
1002 case 0xD:
1003 do_tok(buf, "unlockScript", ((opcode & 0x80) ? A1V : A1B));
1004 break;
1005 case 0xE:
1006 do_tok(buf, "unlockSound", ((opcode & 0x80) ? A1V : A1B));
1007 break;
1008 case 0xF:
1009 do_tok(buf, "unlockCostume", ((opcode & 0x80) ? A1V : A1B));
1010 break;
1011 case 0x10:
1012 do_tok(buf, "unlockRoom", ((opcode & 0x80) ? A1V : A1B));
1013 break;
1014 case 0x11:
1015 do_tok(buf, "clearHeap", 0);
1016 break;
1017 case 0x12:
1018 do_tok(buf, "loadCharset", ((opcode & 0x80) ? A1V : A1B));
1019 break;
1020 case 0x13:
1021 do_tok(buf, "nukeCharset", ((opcode & 0x80) ? A1V : A1B));
1022 break;
1023 case 0x14:
1024 do_tok(buf, "loadFlObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
1025 break;
1026
1027 case 0x22 + 1:
1028 do_tok(buf, "setCDVolume", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1029 break;
1030 case 0x23 + 1:
1031 do_tok(buf, "setSoundLoudness", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
1032 break;
1033 case 0x24 + 1:
1034 do_tok(buf, "setSoundPitch", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1035 break;
1036
1037
1038 default:
1039 error("do_resource: unhandled subop %d\n", subop);
1040 break;
1041 }
1042
1043 }
1044
do_pseudoRoom(char * buf)1045 void do_pseudoRoom(char *buf) {
1046 int j, i = get_byte();
1047
1048 buf += sprintf(buf, "PseudoRoom(%d", i);
1049
1050 do {
1051 j = get_byte();
1052 if (!j)
1053 break;
1054
1055 if (j & 128)
1056 buf += sprintf(buf, ",%d", j & 127);
1057 else
1058 buf = strecpy(buf, ",IG");
1059 } while (1);
1060
1061 strcpy(buf, ");");
1062 }
1063
do_room_ops(char * buf)1064 void do_room_ops(char *buf) {
1065 int opcode = get_byte();
1066
1067 //buf+=sprintf(buf, "SubCode33%.2X", opcode);
1068
1069 switch (opcode & 0x1F) {
1070 case 0x01:
1071 do_tok(buf, "RoomScroll", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
1072 break;
1073 case 0x02:
1074 do_tok(buf, "RoomColor", 0);
1075 break;
1076 case 0x03:
1077 do_tok(buf, "SetScreen", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
1078 break;
1079 case 0x04:
1080 buf =
1081 do_tok(buf, "SetPalColor",
1082 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) |
1083 ((opcode & 0x20) ? A3V : A3W) | ANOLASTPAREN | ANOENDSEMICOLON);
1084 opcode = get_byte();
1085 buf = do_tok(buf, NULL, ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B));
1086 break;
1087 case 0x05:
1088 do_tok(buf, "ShakeOn", 0);
1089 break;
1090 case 0x06:
1091 do_tok(buf, "ShakeOff", 0);
1092 break;
1093 case 0x07:
1094 // Possibly unused, but changed to match ScummVM anyway
1095 //do_tok(buf, "Unused", 0);
1096 buf = do_tok(buf, "SetRoomScale",
1097 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1098 ANOLASTPAREN | ANOENDSEMICOLON);
1099 opcode = get_byte();
1100 buf = do_tok(buf, NULL,
1101 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1102 ASTARTCOMMA | ANOFIRSTPAREN | ANOLASTPAREN | ANOENDSEMICOLON);
1103 opcode = get_byte();
1104 buf = do_tok(buf, NULL,
1105 ((opcode & 0x40) ? A2V : A2B) | // apparently it uses the param 2 bit
1106 ASTARTCOMMA | ANOFIRSTPAREN);
1107 break;
1108 case 0x08:
1109 buf =
1110 do_tok(buf, "RoomIntensity",
1111 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1112 ((opcode & 0x20) ? A3V : A3B));
1113 break;
1114 case 0x09:
1115 buf = do_tok(buf, "saveLoad", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1116 break;
1117 case 0x0A:
1118 buf = do_tok(buf, "screenEffect", ((opcode & 0x80) ? A1V : A1W));
1119 break;
1120 case 0x0B:
1121 buf =
1122 do_tok(buf, "setRGBRoomIntensity",
1123 ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ?
1124 A2V : A2W) |
1125 ((opcode & 0x20) ? A3V : A3W));
1126 opcode = get_byte();
1127 buf =
1128 do_tok(buf, NULL,
1129 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1130 ((opcode & 0x40) ? A2V : A2B));
1131 break;
1132
1133 case 0x0C:
1134 buf =
1135 do_tok(buf, "setRoomShadow",
1136 ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ?
1137 A2V : A2W) |
1138 ((opcode & 0x20) ? A3V : A3W));
1139 opcode = get_byte();
1140 buf =
1141 do_tok(buf, NULL,
1142 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1143 ((opcode & 0x40) ? A2V : A2B));
1144 break;
1145
1146 case 0x0D:
1147 do_tok(buf, "saveString", ((opcode & 0x80) ? A1V : A1B) | A2ASCII);
1148 break;
1149 case 0x0E:
1150 do_tok(buf, "loadString", ((opcode & 0x80) ? A1V : A1B) | A2ASCII);
1151 break;
1152
1153 case 0x0F:
1154 buf = do_tok(buf, "palManipulate", ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1B));
1155 opcode = get_byte();
1156 buf =
1157 do_tok(buf, NULL,
1158 ASTARTCOMMA | ANOFIRSTPAREN | ANOLASTPAREN | ANOENDSEMICOLON | ((opcode & 0x80) ?
1159 A1V : A1B) |
1160 ((opcode & 0x40) ? A2V : A2B));
1161 opcode = get_byte();
1162 buf = do_tok(buf, NULL, ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B));
1163 break;
1164
1165 case 0x10:
1166 do_tok(buf, "colorCycleDelay", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1167 break;
1168
1169 default:
1170 strcpy(buf, "Unknown??");
1171 }
1172 }
1173
do_room_ops_old(char * buf,byte opcode)1174 void do_room_ops_old(char *buf, byte opcode) {
1175 char a[256];
1176 char b[256];
1177
1178 if (g_options.scriptVersion <= 2) {
1179 get_var_or_byte(a, (opcode & 0x80));
1180 get_var_or_byte(b, (opcode & 0x40));
1181 } else if (g_options.scriptVersion == 3) {
1182 get_var_or_word(a, (opcode & 0x80));
1183 get_var_or_word(b, (opcode & 0x40));
1184 }
1185
1186 opcode = get_byte();
1187 switch (opcode & 0x1F) {
1188 case 0x01:
1189 if (g_options.scriptVersion > 3) {
1190 get_var_or_word(a, (opcode & 0x80));
1191 get_var_or_word(b, (opcode & 0x40));
1192 }
1193 buf = strecpy(buf, "RoomScroll(");
1194 buf = strecpy(buf, a);
1195 buf = strecpy(buf, ",");
1196 buf = strecpy(buf, b);
1197 buf = strecpy(buf, ")");
1198 break;
1199 case 0x02:
1200 if (g_options.scriptVersion > 3) {
1201 get_var_or_word(a, (opcode & 0x80));
1202 get_var_or_word(b, (opcode & 0x40));
1203 }
1204 buf = strecpy(buf, "RoomColor(");
1205 buf = strecpy(buf, a);
1206 buf = strecpy(buf, ",");
1207 buf = strecpy(buf, b);
1208 buf = strecpy(buf, ")");
1209 break;
1210 case 0x03:
1211 if (g_options.scriptVersion > 3) {
1212 get_var_or_word(a, (opcode & 0x80));
1213 get_var_or_word(b, (opcode & 0x40));
1214 }
1215 buf = strecpy(buf, "SetScreen(");
1216 buf = strecpy(buf, a);
1217 buf = strecpy(buf, ",");
1218 buf = strecpy(buf, b);
1219 buf = strecpy(buf, ")");
1220 break;
1221 case 0x04:
1222 if (g_options.scriptVersion > 3) {
1223 get_var_or_word(a, (opcode & 0x80));
1224 get_var_or_word(b, (opcode & 0x40));
1225 }
1226 buf = strecpy(buf, "SetPalColor(");
1227 buf = strecpy(buf, a);
1228 buf = strecpy(buf, ",");
1229 buf = strecpy(buf, b);
1230 buf = strecpy(buf, ")");
1231 break;
1232 case 0x05:
1233 do_tok(buf, "ShakeOn", 0);
1234 break;
1235 case 0x06:
1236 do_tok(buf, "ShakeOff", 0);
1237 break;
1238 default:
1239 error("do_room_ops_old: unknown subop %d", opcode & 0x1F);
1240 }
1241 }
1242
do_cursor_command(char * buf)1243 void do_cursor_command(char *buf) {
1244 int opcode = get_byte();
1245
1246 switch (opcode & 0x1f) {
1247 case 0x01:
1248 do_tok(buf, "CursorShow", 0);
1249 break;
1250 case 0x02:
1251 do_tok(buf, "CursorHide", 0);
1252 break;
1253 case 0x03:
1254 do_tok(buf, "UserputOn", 0);
1255 break;
1256 case 0x04:
1257 do_tok(buf, "UserputOff", 0);
1258 break;
1259 case 0x05:
1260 do_tok(buf, "CursorSoftOn", 0);
1261 break;
1262 case 0x06:
1263 do_tok(buf, "CursorSoftOff", 0);
1264 break;
1265 case 0x07:
1266 do_tok(buf, "UserputSoftOn", 0);
1267 break;
1268 case 0x08:
1269 do_tok(buf, "UserputSoftOff", 0);
1270 break;
1271
1272 case 0x0A:
1273 do_tok(buf, "SetCursorImg", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1274 break;
1275 case 0x0B:
1276 do_tok(buf, "SetCursorHotspot",
1277 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
1278 ((opcode & 0x20) ? A3V : A3B));
1279 break;
1280 case 0x0C:
1281 do_tok(buf, "InitCursor", ((opcode & 0x80) ? A1V : A1B));
1282 break;
1283 case 0x0D:
1284 do_tok(buf, "InitCharset", ((opcode & 0x80) ? A1V : A1B));
1285 break;
1286
1287 case 0x0E:
1288 if (g_options.scriptVersion == 3)
1289 do_tok(buf, "LoadCharset", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1290 else
1291 do_tok(buf, "CursorCommand", A1LIST);
1292 break;
1293 default:
1294 sprintf(buf, "UnknownCursorCommand%.2X", opcode);
1295 }
1296 }
1297
do_verbops_v2(char * buf,byte opcode)1298 void do_verbops_v2(char *buf, byte opcode) {
1299 int subop = get_byte();
1300
1301 buf = do_tok(buf, "VerbOps", ANOLASTPAREN | ANOENDSEMICOLON);
1302 switch (subop) {
1303 case 0:
1304 buf = do_tok(buf, "Delete", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1305 break;
1306 case 0xFF:
1307 buf = do_tok(buf, "State", A1B | A2B | ANOENDSEMICOLON);
1308 break;
1309 default:
1310 buf += sprintf(buf, "New-%d", subop);
1311 buf = do_tok(buf, "", A1B | A2B | ((opcode & 0x80) ? A3V : A3B) | A4B | A5ASCII | ANOENDSEMICOLON);
1312 }
1313 strecpy(buf, ");");
1314 }
1315
do_verbops(char * buf,byte opcode)1316 void do_verbops(char *buf, byte opcode) {
1317 char first = 1;
1318
1319 buf = do_tok(buf, "VerbOps", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
1320 buf = strecpy(buf, ",[");
1321
1322 do {
1323 opcode = get_byte();
1324 if (opcode == 0xFF)
1325 break;
1326 if (!first)
1327 buf = strecpy(buf, ",");
1328 first = 0;
1329 switch (opcode & 0x1F) {
1330 case 0x1:
1331 buf = do_tok(buf, "Image", (opcode & 0x80) ? A1V : A1W | ANOENDSEMICOLON);
1332 break;
1333 case 0x2:
1334 buf = do_tok(buf, "Text", A1ASCII | ANOENDSEMICOLON);
1335 break;
1336 case 0x3:
1337 buf = do_tok(buf, "Color", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1338 break;
1339 case 0x4:
1340 buf = do_tok(buf, "HiColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1341 break;
1342 case 0x5:
1343 buf = do_tok(buf, "SetXY", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1344 break;
1345 case 0x6:
1346 buf = do_tok(buf, "On", ANOENDSEMICOLON);
1347 break;
1348 case 0x7:
1349 buf = do_tok(buf, "Off", ANOENDSEMICOLON);
1350 break;
1351 case 0x8:
1352 buf = do_tok(buf, "Delete", ANOENDSEMICOLON);
1353 break;
1354 case 0x9:
1355 buf = do_tok(buf, "New", ANOENDSEMICOLON);
1356 break;
1357 case 0x10:
1358 buf = do_tok(buf, "DimColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1359 break;
1360 case 0x11:
1361 buf = do_tok(buf, "Dim", ANOENDSEMICOLON);
1362 break;
1363 case 0x12:
1364 buf = do_tok(buf, "Key", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1365 break;
1366 case 0x13:
1367 buf = do_tok(buf, "Center", ANOENDSEMICOLON);
1368 break;
1369 case 0x14:
1370 buf = do_tok(buf, "SetToString", (opcode & 0x80) ? A1V : A1W | ANOENDSEMICOLON);
1371 break;
1372 case 0x16:
1373 buf =
1374 do_tok(buf, "SetToObject", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOENDSEMICOLON);
1375 break;
1376 case 0x17:
1377 buf = do_tok(buf, "BackColor", (opcode & 0x80) ? A1V : A1B | ANOENDSEMICOLON);
1378 break;
1379 default:
1380 buf += sprintf(buf, "Invalid%.2X()", opcode);
1381 }
1382
1383 } while (1);
1384 strecpy(buf, "]);");
1385 }
1386
do_print_ego(char * buf,byte opcode)1387 void do_print_ego(char *buf, byte opcode) {
1388 char first = 1;
1389
1390 if (opcode == 0xD8) {
1391 buf = strecpy(buf, "printEgo([");
1392 } else {
1393 buf = do_tok(buf, "print", ((opcode & 0x80) ? A1V : A1B) | ANOLASTPAREN | ANOENDSEMICOLON);
1394 buf = strecpy(buf, ",[");
1395 }
1396
1397 do {
1398 opcode = get_byte();
1399 if (opcode == 0xFF)
1400 break;
1401
1402 if (!first)
1403 buf = strecpy(buf, ",");
1404 first = 0;
1405
1406 switch (opcode & 0x1f) {
1407 case 0x0:
1408 buf = do_tok(buf, "Pos", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1409 break;
1410 case 0x1:
1411 buf = do_tok(buf, "Color", ((opcode & 0x80) ? A1V : A1B) | ANOENDSEMICOLON);
1412 break;
1413 case 0x2:
1414 buf = do_tok(buf, "Clipped", ((opcode & 0x80) ? A1V : A1W) | ANOENDSEMICOLON);
1415 break;
1416 case 0x3:
1417 buf = do_tok(buf, "RestoreBG", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1418 break;
1419 case 0x4:
1420 buf = do_tok(buf, "Center", ANOENDSEMICOLON);
1421 break;
1422 case 0x6:
1423 if (g_options.GF_UNBLOCKED)
1424 buf = do_tok(buf, "Height", ((opcode & 0x80) ? A1V: A1W) | ANOENDSEMICOLON);
1425 else
1426 buf = do_tok(buf, "Left", ANOENDSEMICOLON);
1427 break;
1428 case 0x7:
1429 buf = do_tok(buf, "Overhead", ANOENDSEMICOLON);
1430 break;
1431 case 0x8:
1432 buf = do_tok(buf, "PlayCDTrack", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOENDSEMICOLON);
1433 break;
1434 case 0xF:{
1435 buf = strecpy(buf, "Text(");
1436 buf = get_string(buf);
1437 buf = strecpy(buf, ")");
1438 }
1439 goto exit_proc;
1440 default:
1441 buf += sprintf(buf, "Unknown%.2X()", opcode);
1442 goto exit_proc;
1443 }
1444 } while (1);
1445
1446 exit_proc:;
1447 buf = strecpy(buf, "]);");
1448
1449 }
1450
do_unconditional_jump(char * buf)1451 void do_unconditional_jump(char *buf) {
1452 int offset = get_word();
1453 int cur = get_curoffs();
1454 int to = cur + offset;
1455
1456 if (offset == 0) {
1457 sprintf(buf, "/* goto %.4X; */", to);
1458 } else if (!g_options.dontOutputElse && maybeAddElse(cur, to)) {
1459 pendingElse = true;
1460 pendingElseTo = to;
1461 pendingElseOffs = cur;
1462 pendingElseOpcode = g_jump_opcode;
1463 pendingElseIndent = g_blockStack.size();
1464 buf[0] = 0;
1465 } else {
1466 if (!g_blockStack.empty() && !g_options.dontOutputWhile) {
1467 Block p = g_blockStack.top();
1468 if (p.isWhile && cur == (int)p.to)
1469 return; // A 'while' ends here.
1470 }
1471 sprintf(buf, "goto %.4X;", to);
1472 }
1473 }
1474
emit_if(char * buf,char * condition)1475 void emit_if(char *buf, char *condition) {
1476 int offset = get_word();
1477 int cur = get_curoffs();
1478 int to = cur + offset;
1479
1480 if (!g_options.dontOutputElseif && pendingElse) {
1481 if (maybeAddElseIf(cur, pendingElseTo, to)) {
1482 pendingElse = false;
1483 haveElse = true;
1484 buf = strecpy(buf, "} else if (");
1485 buf = strecpy(buf, condition);
1486 sprintf(buf, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1487 return;
1488 }
1489 }
1490
1491 if (!g_options.dontOutputIfs && maybeAddIf(cur, to)) {
1492 if (!g_options.dontOutputWhile && g_blockStack.top().isWhile) {
1493 buf = strecpy(buf, "while (");
1494 } else
1495 buf = strecpy(buf, "if (");
1496 buf = strecpy(buf, condition);
1497 sprintf(buf, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1498 return;
1499 }
1500
1501 // buf = strecpy(buf, negate ? "if (" : "unless (");
1502 buf = strecpy(buf, "unless (");
1503 buf = strecpy(buf, condition);
1504 sprintf(buf, ") goto %.4X;", to);
1505 }
1506
do_if_code(char * buf,byte opcode)1507 void do_if_code(char *buf, byte opcode) {
1508 char var[256];
1509 char tmp[256], tmp2[256];
1510 int txt;
1511
1512 const char *cmp_texts[8] = {
1513 " >= ", " < ", " <= ", " > ", " == ", " != ", "!", "",
1514 };
1515
1516 var[0] = 0;
1517 if (opcode != 0x28 && opcode != 0xA8)
1518 get_var(var);
1519
1520 switch (opcode & 0x7F) {
1521 case 0x38:
1522 txt = 0;
1523 break; /* lessOrEqual */
1524 case 0x04:
1525 txt = 2;
1526 break; /* isGreaterEqual */
1527 case 0x08:
1528 txt = 5;
1529 break; /* isNotEqual */
1530 case 0x48:
1531 txt = 4;
1532 break; /* isEqual */
1533 case 0x78:
1534 txt = 1;
1535 break; /* isGreater */
1536 case 0x44:
1537 txt = 3;
1538 break; /* isLess */
1539 case 0x28:
1540 txt = opcode & 128 ? 7 : 6;
1541 break;
1542 default:
1543 /* Exit, this should never happen, only if my code is buggy */
1544 error("Unknown IF code %x", opcode);
1545 }
1546
1547 if (opcode == 0x28 || opcode == 0xA8) {
1548 get_var(tmp2);
1549 } else {
1550 if (g_options.scriptVersion == 0)
1551 get_var_or_byte(tmp2, opcode & 0x80);
1552 else
1553 get_var_or_word(tmp2, opcode & 0x80);
1554 }
1555
1556 sprintf(tmp, "%s%s%s", var, cmp_texts[txt], tmp2);
1557 emit_if(buf, tmp);
1558 }
1559
do_if_active_object(char * buf,byte opcode)1560 void do_if_active_object(char *buf, byte opcode) {
1561 char tmp[256];
1562
1563 int obj = get_byte();
1564 if (opcode & 0x80)
1565 obj |= 0x100;
1566
1567 sprintf(tmp, "activeObject2 == %d", obj);
1568
1569 emit_if(buf, tmp);
1570 }
1571
do_walk_actor_to_object(char * buf,byte opcode)1572 void do_walk_actor_to_object(char *buf, byte opcode) {
1573
1574 buf += sprintf(buf, "walkActorToObject(");
1575 buf = add_a_tok(buf, (opcode & 0x80) ? A1V : A1B);
1576
1577 int obj = get_byte();
1578 if (opcode & 0x40)
1579 obj |= 0x100;
1580
1581 sprintf(buf, ",%d);", obj);
1582 }
1583
do_put_actor_at_object(char * buf,byte opcode)1584 void do_put_actor_at_object(char *buf, byte opcode) {
1585
1586 buf += sprintf(buf, "putActorAtObject(");
1587 buf = add_a_tok(buf, (opcode & 0x80) ? A1V : A1B);
1588
1589 int obj = get_byte();
1590 if (opcode & 0x40)
1591 obj |= 0x100;
1592
1593 sprintf(buf, ",%d);", obj);
1594 }
1595
do_sentence(char * buf,byte opcode)1596 void do_sentence(char *buf, byte opcode) {
1597 int verb = get_byte();
1598 int obj1 = get_byte();
1599 int obj2 = get_byte();
1600
1601 // Not _cmdObject / _cmdObject2
1602 if (obj1 != 0xFF && obj1 != 0xFE) {
1603 if(opcode & 0x80)
1604 obj1 |= 0x100;
1605 }
1606 // Not _cmdObject / _cmdObject2
1607 if (obj2 != 0xFF && obj2 != 0xFE) {
1608 if (opcode & 0x40)
1609 obj2 |= 0x100;
1610 }
1611
1612 sprintf(buf, "doSentence(%d,%d,%d);", verb, obj1, obj2);
1613 }
1614
1615
do_set_object_name(char * buf,byte opcode)1616 void do_set_object_name(char *buf, byte opcode) {
1617 int obj = get_byte();
1618
1619 if (opcode & 0x40)
1620 obj |= 0x100;
1621
1622 buf += sprintf(buf, "setObjectName(%d,", obj);
1623 buf = add_a_tok(buf, A1B | A1ASCII);
1624
1625 sprintf(buf, ");");
1626 }
1627
do_if_state_code(char * buf,byte opcode)1628 void do_if_state_code(char *buf, byte opcode) {
1629 char var[256];
1630 char tmp[256], tmp2[256];
1631 byte neg;
1632 int state = 0;
1633
1634 var[0] = 0;
1635 if (g_options.scriptVersion == 0) {
1636 if (opcode & 0x40)
1637 sprintf(var, "activeObject");
1638 else
1639 sprintf(var, "%d", get_byte());
1640 } else {
1641 get_var_or_word(var, opcode & 0x80);
1642 }
1643
1644 if (g_options.scriptVersion > 2) {
1645 switch (opcode & 0x2F) {
1646 case 0x0f:
1647 neg = 0;
1648 break;
1649 case 0x2f:
1650 neg = 1;
1651 break;
1652 default:
1653 /* Exit, this should never happen, only if my code is buggy */
1654 error("Unknown IF code %x", opcode);
1655 }
1656
1657 get_var_or_byte(tmp2, opcode & 0x40);
1658 } else {
1659 if (g_options.scriptVersion == 0) {
1660 switch (opcode) {
1661 case 0x7f:
1662 case 0xbf:
1663 state = 2;
1664 neg = 1;
1665 break;
1666 case 0x9f:
1667 case 0xdf:
1668 state = 4;
1669 neg = 1;
1670 break;
1671 case 0xaf:
1672 case 0xef:
1673 state = 8;
1674 neg = 1;
1675 break;
1676 case 0x3f:
1677 case 0xff:
1678 state = 2;
1679 neg = 0;
1680 break;
1681 case 0x1f:
1682 case 0x5f:
1683 state = 4;
1684 neg = 0;
1685 break;
1686 case 0x2f:
1687 case 0x6f:
1688 state = 8;
1689 neg = 0;
1690 break;
1691 default:
1692 /* Exit, this should never happen, only if my code is buggy */
1693 error("Unknown IF code %x", opcode);
1694 }
1695 } else {
1696 switch (opcode) {
1697 case 0x3f:
1698 case 0xbf:
1699 state = 1;
1700 neg = 1;
1701 break;
1702 case 0x5f:
1703 case 0xdf:
1704 state = 2;
1705 neg = 1;
1706 break;
1707 case 0x2f:
1708 case 0xaf:
1709 state = 4;
1710 neg = 1;
1711 break;
1712 case 0x0f:
1713 case 0x8f:
1714 state = 8;
1715 neg = 1;
1716 break;
1717 case 0x7f:
1718 case 0xff:
1719 state = 1;
1720 neg = 0;
1721 break;
1722 case 0x1f:
1723 case 0x9f:
1724 state = 2;
1725 neg = 0;
1726 break;
1727 case 0x6f:
1728 case 0xef:
1729 state = 4;
1730 neg = 0;
1731 break;
1732 case 0x4f:
1733 case 0xcf:
1734 state = 8;
1735 neg = 0;
1736 break;
1737 default:
1738 /* Exit, this should never happen, only if my code is buggy */
1739 error("Unknown IF code %x", opcode);
1740 }
1741 }
1742 }
1743
1744 if (g_options.scriptVersion > 2)
1745 sprintf(tmp, "getState(%s)%s%s", var, neg ? " != " : " == ", tmp2);
1746 else
1747 sprintf(tmp, "%sgetState%02d(%s)", neg ? "!" : "", state, var);
1748 emit_if(buf, tmp);
1749 }
1750
do_varset_code(char * buf,byte opcode)1751 void do_varset_code(char *buf, byte opcode) {
1752 const char *s;
1753
1754 if ((g_options.scriptVersion <= 2)
1755 && ((opcode & 0x7F) == 0x0A
1756 || (opcode & 0x7F) == 0x2A
1757 || (opcode & 0x7F) == 0x6A)) {
1758
1759 int i = get_byte();
1760 buf += sprintf(buf, "Var[Var[%d]]", i);
1761 } else
1762 buf = get_var(buf);
1763
1764 switch (opcode & 0x7F) {
1765 case 0x0A:
1766 case 0x1A:
1767 case 0x2C:
1768 s = " = ";
1769 break; /* move */
1770 case 0x1B:
1771 s = " *= ";
1772 break; /* mul */
1773 case 0x3A:
1774 case 0x6A:
1775 s = " -= ";
1776 break; /* sub */
1777 case 0x57:
1778 s = " |= ";
1779 break; /* or */
1780 case 0x2A:
1781 case 0x5A:
1782 s = " += ";
1783 break; /* add */
1784 case 0x5B:
1785 s = " /= ";
1786 break; /* divide */
1787 case 0x17:
1788 s = " &= ";
1789 break; /* and */
1790 case 0x46:
1791 if (opcode & 128)
1792 s = "--";
1793 else
1794 s = "++";
1795 break; /* increment & decrement */
1796 default:
1797 /* Exit, this should never happen, only if my code is buggy */
1798 error("Unknown VARSET code %x", opcode);
1799 }
1800
1801 buf = strecpy(buf, s);
1802
1803
1804 if ((g_options.scriptVersion <= 2) && (opcode & 0x7F) == 0x2C) { /* assignVarByte */
1805 sprintf(buf, "%d", get_byte());
1806 buf = strchr(buf, 0);
1807 } else if ((opcode & 0x7F) != 0x46) { /* increment or decrement */
1808 if (g_options.scriptVersion == 0)
1809 buf = get_var_or_byte(buf, opcode & 0x80);
1810 else
1811 buf = get_var_or_word(buf, opcode & 0x80);
1812 }
1813 strecpy(buf, ";");
1814 }
1815
do_matrix_ops(char * buf,byte opcode)1816 void do_matrix_ops(char *buf, byte opcode) {
1817 opcode = get_byte();
1818
1819 switch (opcode & 0x1F) {
1820 case 0x1:
1821 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1822 break;
1823 case 0x2:
1824 do_tok(buf, "setBoxScale", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1825 break;
1826 case 0x3:
1827 do_tok(buf, "SetBoxSlot", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1828 break;
1829 case 0x4:
1830 do_tok(buf, "createBoxMatrix", 0);
1831 break;
1832 default:
1833 sprintf(buf, "SetBoxUnknown%.2X;", opcode);
1834 }
1835 }
1836
next_line_V12(char * buf)1837 void next_line_V12(char *buf) {
1838 byte opcode = get_byte();
1839
1840 switch (opcode) {
1841
1842 case 0x58:
1843 do_tok(buf, "beginOverride", 0);
1844 break;
1845 case 0x52:
1846 case 0xD2:
1847 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
1848 break;
1849 case 0x15:
1850 case 0x55:
1851 case 0x95:
1852 case 0xD5:
1853 do_tok(buf, "actorFromPos",
1854 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | AVARSTORE);
1855 break;
1856 case 0x13:
1857 case 0x53:
1858 case 0x93:
1859 case 0xD3:
1860 // actorSet
1861 do_actorops_v12(buf, opcode);
1862 break;
1863
1864 case 0x2A:
1865 case 0xAA:
1866 // addDirect
1867 case 0x3A:
1868 case 0xBA:
1869 //subtract
1870 case 0x6A:
1871 case 0xEA:
1872 //subDirect
1873 case 0x0A:
1874 case 0x8A:
1875 // assignVarWordDirect
1876 case 0x1A:
1877 case 0x5A:
1878 case 0x9A:
1879 case 0xDA:
1880 do_varset_code(buf, opcode);
1881 break;
1882
1883 case 0x11:
1884 case 0x51:
1885 case 0x91:
1886 case 0xD1:
1887 // animateActor
1888 do_tok(buf, "animateActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
1889 break;
1890 case 0x2C:
1891 // assignVarByte
1892 do_varset_code(buf, opcode);
1893 break;
1894 case 0x80:
1895 do_tok(buf, "breakHere", 0);
1896 break;
1897 case 0x4A:
1898 case 0xCA:
1899 do_tok(buf, "chainScript", ((opcode & 0x80) ? A1V : A1B));
1900 break;
1901
1902 case 0x60:
1903 case 0xE0:
1904 //do_tok(buf, "cursorCommand", ((opcode & 0x80) ? A1V : A1W));
1905 if (opcode & 0x80) {
1906 char tmp[256];
1907 get_var(tmp);
1908 buf += sprintf(buf, "cursorCommand(Hi(%s), Lo(%s));", tmp, tmp);
1909 } else {
1910 int val = get_word();
1911 buf += sprintf(buf, "cursorCommand(%d, %d);", (val >> 8) & 0xFF, val & 0xFF);
1912 }
1913
1914 break;
1915 case 0x40:
1916 sprintf(buf, "cutscene();");
1917 break;
1918 case 0xC0:
1919 sprintf(buf, "endCutscene();");
1920 break;
1921
1922 case 0x46:
1923 case 0xC6:
1924 // increment / decrement
1925 do_varset_code(buf, opcode);
1926 break;
1927
1928 case 0x2E: {
1929 //delay
1930 int d = get_byte();
1931 d |= get_byte() << 8;
1932 d |= get_byte() << 16;
1933 d = 0xFFFFFF - d;
1934 sprintf(buf, "delay(%d);", d);
1935 break;
1936 }
1937
1938 case 0x2B:
1939 do_tok(buf, "delayVariable", A1V);
1940 break;
1941
1942 case 0x19:
1943 case 0x39:
1944 case 0x59:
1945 case 0x79:
1946 case 0x99:
1947 case 0xB9:
1948 case 0xD9:
1949 case 0xF9:{
1950 buf = strecpy(buf, "doSentence(");
1951 if (!(opcode & 0x80) && *g_scriptCurPos == 0xFC) {
1952 strcpy(buf, "STOP);");
1953 g_scriptCurPos++;
1954 } else if (!(opcode & 0x80) && *g_scriptCurPos == 0xFB) {
1955 strcpy(buf, "RESET);");
1956 g_scriptCurPos++;
1957 } else {
1958 do_tok(buf, "",
1959 ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
1960 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3W) | A4B);
1961 }
1962 }
1963 break;
1964
1965 case 0x05:
1966 case 0x25:
1967 case 0x45:
1968 case 0x65:
1969 case 0x85:
1970 case 0xA5:
1971 case 0xC5:
1972 case 0xE5:
1973 //drawObject
1974 buf = do_tok(buf, "drawObject",
1975 ((opcode & 0x80) ? A1V : A1W) |
1976 ((opcode & 0x40) ? A2V : A2B) |
1977 ((opcode & 0x20) ? A3V : A3B));
1978 break;
1979 case 0xAC:
1980 //drawSentence
1981 do_tok(buf, "drawSentence", 0);
1982 break;
1983 case 0x5C:
1984 case 0x6B:
1985 case 0x6E:
1986 case 0xAB:
1987 case 0xDC:
1988 case 0xEB:
1989 case 0xEE:
1990 //dummy
1991 sprintf(buf, "dummy(%.2X);", opcode);
1992
1993 break;
1994
1995 case 0x09:
1996 case 0x49:
1997 case 0x89:
1998 case 0xC9:
1999 do_tok(buf, "faceActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2000 break;
2001 case 0x35:
2002 case 0x75:
2003 case 0xB5:
2004 case 0xF5:
2005 do_tok(buf, "findObject",
2006 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2007 break;
2008 case 0x71:
2009 case 0xF1:
2010 do_tok(buf, "getActorCostume", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2011 break;
2012 case 0x06:
2013 case 0x86:
2014 do_tok(buf, "getActorElevation", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2015 break;
2016 case 0x63:
2017 case 0xE3:
2018 do_tok(buf, "getActorFacing", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2019 break;
2020 case 0x56:
2021 case 0xD6:
2022 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2023 break;
2024 case 0x03:
2025 case 0x83:
2026 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2027 break;
2028 case 0x7B:
2029 case 0xFB:
2030 do_tok(buf, "getActorWalkBox", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2031 break;
2032 case 0x43:
2033 case 0xC3:
2034 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2035 break;
2036
2037 case 0x23:
2038 case 0xA3:
2039 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2040 break;
2041
2042 case 0x31:
2043 case 0xB1:
2044 do_tok(buf, "getBitVar", AVARSTORE | A1W | ((opcode & 0x80) ? A2V : A2B));
2045 break;
2046
2047 case 0x1B:
2048 case 0x5B:
2049 case 0x9B:
2050 case 0xDB:
2051 do_tok(buf, "setBitVar", A1W | ((opcode & 0x80) ? A2V : A2B) | ((opcode & 0x40) ? A3V : A3B));
2052 break;
2053
2054 case 0x66:
2055 case 0xE6:
2056 do_tok(buf, "getClosestObjActor", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2057 break;
2058
2059 case 0x34:
2060 case 0x74:
2061 case 0xB4:
2062 case 0xF4:
2063 do_tok(buf, "getDist",
2064 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
2065 break;
2066 case 0x10:
2067 case 0x90:
2068 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2069 break;
2070 case 0x6C:
2071 case 0xEC:
2072 do_tok(buf, "getObjPreposition", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
2073 break;
2074 case 0x16:
2075 case 0x96:
2076 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2077 break;
2078
2079 case 0x1D:
2080 case 0x5D:
2081 case 0x9D:
2082 case 0xDD:
2083 //ifClassOfIs
2084 do_tok(buf, "classOfIs", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ATO | ATOWITHLASTPAREN);
2085 break;
2086
2087 case 0x3F:
2088 case 0xBF:
2089 //ifNotState01
2090 case 0x5F:
2091 case 0xDF:
2092 //ifNotState02
2093 case 0x2F:
2094 case 0xAF:
2095 //ifNotState04
2096 case 0x0F:
2097 case 0x8F:
2098 //ifNotState08
2099 case 0x7F:
2100 case 0xFF:
2101 //ifState01
2102 case 0x1F:
2103 case 0x9F:
2104 //ifState02
2105 case 0x6F:
2106 case 0xEF:
2107 //ifState04
2108 case 0x4F:
2109 case 0xCF:
2110 //ifState08
2111 do_if_state_code(buf, opcode);
2112 break;
2113
2114 case 0x48:
2115 case 0xC8:
2116 //isEqual
2117 case 0x78:
2118 case 0xF8:
2119 //isGreater
2120 case 0x04:
2121 case 0x84:
2122 //isGreaterEqual
2123 case 0x44:
2124 case 0xC4:
2125 //isLess
2126 case 0x08:
2127 case 0x88:
2128 //isNotEqual
2129 case 0x38:
2130 case 0xB8:
2131 //lessOrEqual
2132 case 0x28:
2133 //equalZero
2134 case 0xA8:
2135 //notEqualZero
2136 do_if_code(buf, opcode);
2137 break;
2138
2139 case 0x68:
2140 case 0xE8:
2141 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2142 break;
2143 case 0x7C:
2144 case 0xFC:
2145 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2146 break;
2147
2148 case 0x18:
2149 do_unconditional_jump(buf);
2150 break;
2151
2152 case 0x70:
2153 case 0xF0:
2154 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B) | A2B | A3B);
2155 break;
2156 case 0x72:
2157 case 0xF2:
2158 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
2159 break;
2160
2161 case 0x24:
2162 case 0x64:
2163 case 0xA4:
2164 case 0xE4:
2165 //loadRoomWithEgo
2166 buf =
2167 do_tok(buf, "loadRoomWithEgo",
2168 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOLASTPAREN | ANOENDSEMICOLON);
2169 do_tok(buf, NULL, A1B | A2B | ANOFIRSTPAREN | ASTARTCOMMA);
2170 break;
2171
2172 case 0x30:
2173 case 0xB0:
2174 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | A2B);
2175 break;
2176
2177 case 0x12:
2178 case 0x92:
2179 //panCameraTo
2180 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1B));
2181 break;
2182 case 0x50:
2183 case 0xD0:
2184 //pickupObject
2185 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W));
2186 break;
2187 case 0x14:
2188 case 0x94:
2189 // print
2190 buf += sprintf(buf, "print(");
2191 buf = get_var_or_byte(buf, (opcode & 0x80));
2192 buf += sprintf(buf, ",\"");
2193 do_decodeparsestring_v2(buf, opcode);
2194 strcat(buf, "\");");
2195 break;
2196 case 0xD8:
2197 //printEgo
2198 buf += sprintf(buf, "printEgo(\"");
2199 do_decodeparsestring_v2(buf, opcode);
2200 strcat(buf, "\");");
2201 break;
2202
2203 case 0xCC:
2204 // pseudoRoom
2205 do_pseudoRoom(buf);
2206 break;
2207 case 0x01:
2208 case 0x21:
2209 case 0x41:
2210 case 0x61:
2211 case 0x81:
2212 case 0xA1:
2213 case 0xC1:
2214 case 0xE1:
2215 do_tok(buf, "putActor",
2216 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
2217 ((opcode & 0x20) ? A3V : A3B));
2218 break;
2219 case 0x0E:
2220 case 0x4E:
2221 case 0x8E:
2222 case 0xCE:
2223 //putActorAtObject
2224 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) );
2225 break;
2226 case 0x2D:
2227 case 0x6D:
2228 case 0xAD:
2229 case 0xED:
2230 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2231 break;
2232 case 0x0C:
2233 case 0x8C:
2234 //resourceRoutines
2235 do_resource_v2(buf, opcode);
2236 break;
2237 case 0x98:
2238 do_tok(buf, "restart", 0);
2239 break;
2240
2241 case 0x33:
2242 case 0x73:
2243 case 0xB3:
2244 case 0xF3:
2245 do_room_ops_old(buf, opcode);
2246 break;
2247
2248 case 0x22:
2249 case 0xA2:
2250 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2251 break;
2252
2253 case 0x3D:
2254 case 0x7D:
2255 case 0xBD:
2256 case 0xFD:
2257 do_tok(buf, "setActorElevation", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2258 break;
2259
2260 case 0x32:
2261 case 0xB2:
2262 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1B));
2263 break;
2264
2265 case 0x54:
2266 case 0xD4:
2267 do_tok(buf, "setObjectName", ((opcode & 0x80) ? A1V : A1W) | A2ASCII);
2268 break;
2269
2270 case 0x0B:
2271 case 0x4B:
2272 case 0x8B:
2273 case 0xCB:
2274 do_tok(buf, "setObjPreposition", ((opcode & 0x80) ? A1V : A1W) | A2B);
2275 break;
2276 case 0x29:
2277 case 0x69:
2278 case 0xA9:
2279 case 0xE9:
2280 //setOwnerOf
2281 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
2282 break;
2283
2284 case 0x77:
2285 case 0xF7:
2286 // clearState01
2287 do_tok(buf, "clearState01", ((opcode & 0x80) ? A1V : A1W));
2288 break;
2289 case 0x17:
2290 case 0x97:
2291 // clearState02
2292 do_tok(buf, "clearState02", ((opcode & 0x80) ? A1V : A1W));
2293 break;
2294 case 0x67:
2295 case 0xE7:
2296 // clearState04
2297 do_tok(buf, "clearState04", ((opcode & 0x80) ? A1V : A1W));
2298 break;
2299 case 0x47:
2300 case 0xC7:
2301 // clearState08
2302 do_tok(buf, "clearState08", ((opcode & 0x80) ? A1V : A1W));
2303 break;
2304
2305 case 0x37:
2306 case 0xB7:
2307 //setState01
2308 do_tok(buf, "setState01", ((opcode & 0x80) ? A1V : A1W));
2309 break;
2310 case 0x57:
2311 case 0xD7:
2312 //setState02
2313 do_tok(buf, "setState02", ((opcode & 0x80) ? A1V : A1W));
2314 break;
2315 case 0x27:
2316 case 0xA7:
2317 //setState04
2318 do_tok(buf, "setState04", ((opcode & 0x80) ? A1V : A1W));
2319 break;
2320 case 0x07:
2321 case 0x87:
2322 //setState08
2323 do_tok(buf, "setState08", ((opcode & 0x80) ? A1V : A1W));
2324 break;
2325
2326 case 0x26:
2327 case 0xA6: {
2328 int i;
2329 char first = 1;
2330
2331 buf = do_tok(buf, "setVarRange", A1V | ANOLASTPAREN | ANOENDSEMICOLON);
2332 i = get_byte();
2333
2334 buf += sprintf(buf, ",%d,[", i);
2335
2336 while (i > 0) {
2337 if (!first)
2338 buf = strecpy(buf, ",");
2339 first = 0;
2340
2341 buf += sprintf(buf, "%d", (opcode & 0x80) ? get_word() : get_byte());
2342 i--;
2343 }
2344
2345 strcpy(buf, "]);");
2346
2347 }
2348 break;
2349
2350 case 0x02:
2351 case 0x82:
2352 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
2353 break;
2354 case 0x42:
2355 case 0xC2:
2356 //startScript
2357 do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B));
2358 break;
2359
2360 case 0x1C:
2361 case 0x9C:
2362 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
2363 break;
2364
2365 case 0x20:
2366 do_tok(buf, "stopMusic", 0);
2367 break;
2368 case 0x00:
2369 case 0xA0:
2370 do_tok(buf, "stopObjectCode", 0);
2371 break;
2372 case 0x62:
2373 case 0xE2:
2374 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
2375 break;
2376
2377 case 0x3C:
2378 case 0xBC:
2379 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
2380 break;
2381
2382 case 0x7A:
2383 case 0xFA:
2384 // verbOps
2385 do_verbops_v2(buf, opcode);
2386 break;
2387
2388 case 0x3B:
2389 case 0xBB:
2390 do_tok(buf, "waitForActor", ((opcode & 0x80) ? A1V : A1B));
2391 break;
2392
2393 case 0x4C:
2394 do_tok(buf, "waitForSentence", 0);
2395 break;
2396
2397 case 0xAE:
2398 do_tok(buf, "waitForMessage", 0);
2399 break;
2400 case 0x1E:
2401 case 0x3E:
2402 case 0x5E:
2403 case 0x7E:
2404 case 0x9E:
2405 case 0xBE:
2406 case 0xDE:
2407 case 0xFE:
2408 do_tok(buf, "walkActorTo",
2409 ((opcode & 0x80) ? A1V : A1B) |
2410 ((opcode & 0x40) ? A2V : A2B) |
2411 ((opcode & 0x20) ? A3V : A3B));
2412 break;
2413
2414 case 0x0D:
2415 case 0x4D:
2416 case 0x8D:
2417 case 0xCD:
2418 do_tok(buf, "walkActorToActor",
2419 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2420 break;
2421 case 0x36:
2422 case 0x76:
2423 case 0xB6:
2424 case 0xF6:
2425 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
2426 break;
2427
2428 default:
2429 error("Unknown opcode %.2X", opcode);
2430 }
2431 }
2432
next_line_V0(char * buf)2433 void next_line_V0(char *buf) {
2434 byte opcode = get_byte();
2435
2436 switch (opcode) {
2437 case 0x05:
2438 case 0x09:
2439 case 0x0A:
2440 case 0x19:
2441 case 0x23:
2442 case 0x2C:
2443 case 0x35:
2444 case 0x39:
2445 case 0x3B:
2446 case 0x45:
2447 case 0x49:
2448 case 0x59:
2449 case 0x63:
2450 case 0x65:
2451 case 0x6A:
2452 case 0x6C:
2453 case 0x79:
2454 case 0x7A:
2455 case 0x7B:
2456 case 0x80:
2457 case 0x82:
2458 case 0x85:
2459 case 0x89:
2460 case 0x8A:
2461 case 0x8D:
2462 case 0x96:
2463 case 0x99:
2464 case 0xA3:
2465 case 0xA6:
2466 case 0xAA:
2467 case 0xAC:
2468 case 0xB5:
2469 case 0xB9:
2470 case 0xBB:
2471 case 0xC5:
2472 case 0xC9:
2473 case 0xD8:
2474 case 0xD9:
2475 case 0xE3:
2476 case 0xE6:
2477 case 0xEA:
2478 case 0xEC:
2479 case 0xF5:
2480 case 0xF9:
2481 case 0xFA:
2482 case 0xFB:
2483 do_tok(buf, "stopCurrentScript", 0);
2484 break;
2485
2486 case 0x67:
2487 case 0xE7:
2488 do_tok(buf, "getActorFacing", AVARSTORE | A1B | ((opcode & 0x80) ? A2V : A2B));
2489 break;
2490
2491 case 0x31:
2492 case 0x71:
2493 case 0xB1:
2494 case 0xF1:
2495 do_tok(buf, "getBitVar", AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2496 break;
2497
2498 case 0x1D:
2499 case 0x3D:
2500 case 0x5D:
2501 case 0x7D:
2502 case 0x9D:
2503 case 0xBD:
2504 case 0xDD:
2505 case 0xFD:
2506 do_tok(buf, "setBitVar", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ((opcode & 0x20) ? A3V : A3B));
2507 break;
2508
2509 case 0x1B:
2510 case 0x5B:
2511 case 0x9B:
2512 case 0xDB:
2513 do_tok(buf, "getActorBitVar", AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2514 break;
2515
2516 case 0x0B:
2517 case 0x2B:
2518 case 0x4B:
2519 case 0x6B:
2520 case 0x8B:
2521 case 0xAB:
2522 case 0xCB:
2523 case 0xEB:
2524 do_tok(buf, "setActorBitVar", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | ((opcode & 0x20) ? A3V : A3B));
2525 break;
2526
2527 case 0x58:
2528 do_tok(buf, "beginOverride", 0);
2529 get_byte();
2530 get_byte();
2531 get_byte();
2532 break;
2533 case 0x52:
2534 case 0xD2:
2535 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
2536 break;
2537 case 0x95:
2538 case 0xD5:
2539 do_tok(buf, "actorFromPos",
2540 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | AVARSTORE);
2541 break;
2542 case 0x15:
2543 case 0x55:
2544 do_tok(buf, "walkActorToActor",
2545 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2546 break; /* arg1=actor, arg2=actor */
2547 case 0x13:
2548 do_tok(buf, "lockCostume", A1B);
2549 break;
2550 case 0x4D:
2551 do_tok(buf, "lockRoom", A1B);
2552 break;
2553 case 0xCD:
2554 do_tok(buf, "unlockRoom", A1B);
2555 break;
2556 case 0x93:
2557 do_tok(buf, "unlockCostume", A1B);
2558 break;
2559 case 0x1A:
2560 case 0x9a:
2561 //move
2562 case 0x5A:
2563 case 0xDA:
2564 //add;
2565 case 0x3A:
2566 case 0xBA:
2567 //subtract
2568 do_varset_code(buf, opcode);
2569 break;
2570
2571 case 0x11:
2572 case 0x51:
2573 case 0x91:
2574 case 0xD1:
2575 buf = do_tok(buf, "animateActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
2576 break;
2577 case 0x10:
2578 do_tok(buf, "breakHere", 0);
2579 break;
2580 case 0x4A:
2581 case 0xCA:
2582 do_tok(buf, "loadRoom_c64", ((opcode & 0x80) ? A1V : A1B));
2583 break;
2584
2585 case 0x60:
2586 case 0xE0:
2587 //cursorCommand
2588 do_tok(buf, "cursorCommand", ((opcode & 0x80) ? A1V : A1B));
2589 break;
2590 case 0x40:
2591 do_tok(buf, "cutscene", 0);
2592 break;
2593 case 0xC0:
2594 do_tok(buf, "endCutscene", 0);
2595 break;
2596
2597 case 0x46:
2598 case 0xC6:
2599 // increment / decrement
2600 do_varset_code(buf, opcode);
2601 break;
2602
2603 case 0x2A: {
2604 //delay
2605 int d = get_byte();
2606 d |= get_byte() << 8;
2607 d |= get_byte() << 16;
2608 d = 0xFFFFFF - d;
2609 sprintf(buf, "delay(%d);", d);
2610 break;
2611 }
2612
2613 case 0x50:
2614 case 0x72:
2615 case 0xD0:
2616 case 0xF2:
2617 do_tok(buf, "nop", 0);
2618 break;
2619 case 0x14:
2620 case 0x94:
2621 // print
2622 buf += sprintf(buf, "print(");
2623 buf = get_var_or_byte(buf, (opcode & 0x80));
2624 buf += sprintf(buf, ",\"");
2625 do_decodeparsestring_v2(buf, opcode);
2626 strcat(buf, "\");");
2627 break;
2628 case 0x75:
2629 //printEgo
2630 buf += sprintf(buf, "printEgo(\"");
2631 do_decodeparsestring_v2(buf, opcode);
2632 strcat(buf, "\");");
2633 break;
2634 case 0x2E:
2635 case 0xAE:
2636 // print_c64
2637 buf += sprintf(buf, "print_c64(");
2638 buf = get_var_or_byte(buf, (opcode & 0x80));
2639 buf += sprintf(buf, ",\"");
2640 do_decodeparsestring_v2(buf, opcode);
2641 strcat(buf, "\");");
2642 break;
2643 case 0x0D:
2644 //printEgo_c64
2645 buf += sprintf(buf, "printEgo_c64(\"");
2646 do_decodeparsestring_v2(buf, opcode);
2647 strcat(buf, "\");");
2648 break;
2649
2650 case 0x2D:
2651 case 0x6D:
2652 case 0xAD:
2653 case 0xED:
2654 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2655 break;
2656 case 0xE5:
2657 do_tok(buf, "loadRoomWithEgo", A1B | A2B);
2658 break;
2659 case 0x6E:
2660 do_tok(buf, "screenPrepare", 0);
2661 break;
2662 case 0xEE:
2663 //dummy
2664 sprintf(buf, "dummy%.2X();", opcode);
2665 break;
2666
2667 case 0x86:
2668 do_tok(buf, "bad", 0);
2669 break;
2670 case 0x56:
2671 case 0xD6:
2672 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2673 break;
2674 case 0x03:
2675 case 0x43:
2676 case 0x83:
2677 case 0xC3:
2678 do_sentence(buf, opcode);
2679 break;
2680 case 0x07:
2681 case 0x87:
2682 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2683 break;
2684 case 0x47:
2685 case 0xC7:
2686 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2687 break;
2688
2689 case 0x27:
2690 case 0xA7:
2691 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2692 break;
2693
2694 case 0x26:
2695 do_tok(buf, "getClosestObjActor7", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2696 break;
2697 case 0x66:
2698 do_tok(buf, "getClosestObjActor25", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2699 break;
2700
2701 case 0x06:
2702 case 0x34:
2703 case 0x74:
2704 case 0xB4:
2705 case 0xF4:
2706 do_tok(buf, "getDist",
2707 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2708 break;
2709 case 0x90:
2710 do_tok(buf, "pickupObject", A1B);
2711 break;
2712 case 0x16:
2713 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2714 break;
2715
2716 case 0x0f:
2717 case 0x4f:
2718 do_tok(buf, "clearState02", ((opcode & 0x40) ? 0 : A1B));
2719 break;
2720 case 0x37:
2721 case 0x77:
2722 do_tok(buf, "clearState04", ((opcode & 0x40) ? 0 : A1B));
2723 break;
2724 case 0x17:
2725 case 0x57:
2726 do_tok(buf, "clearState08", ((opcode & 0x40) ? 0 : A1B));
2727 break;
2728 case 0x8f:
2729 case 0xcf:
2730 do_tok(buf, "setState02", ((opcode & 0x40) ? 0 : A1B));
2731 break;
2732 case 0xb7:
2733 case 0xf7:
2734 do_tok(buf, "setState04", ((opcode & 0x40) ? 0 : A1B));
2735 break;
2736 case 0x97:
2737 case 0xd7:
2738 do_tok(buf, "setState08", ((opcode & 0x40) ? 0 : A1B));
2739 break;
2740
2741 case 0x3f:
2742 case 0xff:
2743 //ifState02;
2744 case 0x1f:
2745 case 0x5f:
2746 //ifState04;
2747 case 0x2f:
2748 case 0x6f:
2749 //ifState08;
2750 case 0x7f:
2751 case 0xbf:
2752 //ifNotState02;
2753 case 0x9f:
2754 case 0xdf:
2755 //ifNotState04;
2756 case 0xaf:
2757 case 0xef:
2758 //ifNotState08;
2759 do_if_state_code(buf, opcode);
2760 break;
2761
2762 case 0x48:
2763 case 0xC8:
2764 //isEqual
2765 case 0x78:
2766 case 0xF8:
2767 //isGreater
2768 case 0x04:
2769 case 0x84:
2770 //isGreaterEqual
2771 case 0x44:
2772 case 0xC4:
2773 //isLess
2774 case 0x08:
2775 case 0x88:
2776 //isNotEqual
2777 case 0x38:
2778 case 0xB8:
2779 //lessOrEqual
2780 case 0x28:
2781 //equalZero
2782 case 0xA8:
2783 //notEqualZero
2784 do_if_code(buf, opcode);
2785 break;
2786
2787 case 0x68:
2788 case 0xE8:
2789 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2790 break;
2791 case 0x7C:
2792 case 0xFC:
2793 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2794 break;
2795
2796 case 0x53:
2797 do_tok(buf, "lockSound", A1B);
2798 break;
2799
2800 case 0xD3:
2801 do_tok(buf, "unlockSound", A1B);
2802 break;
2803
2804 case 0x18:
2805 do_unconditional_jump(buf);
2806 break;
2807
2808 case 0x70:
2809 case 0xF0:
2810 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B));
2811 break;
2812 case 0x25:
2813 case 0xA5:
2814 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
2815 break;
2816
2817 case 0x24:
2818 case 0xA4:
2819 do_tok(buf, "unknown2", A1B);
2820 break;
2821 case 0x64:
2822 case 0xE4:
2823 do_if_active_object(buf, opcode);
2824 break;
2825
2826 case 0x30:
2827 case 0xB0:
2828 do_tok(buf, "loadCostume", ((opcode & 0x80) ? A1V : A1B));
2829 break;
2830
2831 case 0x12:
2832 case 0x92:
2833 //panCameraTo
2834 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1B));
2835 break;
2836
2837 case 0x01:
2838 case 0x21:
2839 case 0x41:
2840 case 0x61:
2841 case 0x81:
2842 case 0xA1:
2843 case 0xC1:
2844 case 0xE1:
2845 do_tok(buf, "putActor",
2846 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
2847 ((opcode & 0x20) ? A3V : A3B));
2848 break;
2849 case 0x4E:
2850 case 0xCE:
2851 case 0x0E:
2852 case 0x8E:
2853 do_put_actor_at_object(buf, opcode);
2854 break;
2855 case 0x0C:
2856 case 0x8C:
2857 do_tok(buf, "loadSound", A1B);
2858 break;
2859 case 0x98:
2860 do_tok(buf, "restart", 0);
2861 break;
2862
2863 case 0x33:
2864 do_tok(buf, "lockScript", A1B);
2865 break;
2866 case 0xB3:
2867 do_tok(buf, "unlockScript", A1B);
2868 break;
2869 case 0x73:
2870 case 0xF3:
2871 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2872 break;
2873
2874 case 0x22:
2875 case 0xA2:
2876 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2877 break;
2878
2879 case 0x32:
2880 case 0xB2:
2881 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1B));
2882 break;
2883
2884 case 0x54:
2885 case 0xD4:
2886 do_set_object_name(buf, opcode);
2887 break;
2888
2889 case 0x29:
2890 case 0x69:
2891 case 0xA9:
2892 case 0xE9:
2893 //setOwnerOf
2894 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
2895 break;
2896
2897 case 0x02:
2898 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
2899 break;
2900 case 0x42:
2901 case 0xC2:
2902 //startScript
2903 do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B));
2904 break;
2905
2906 case 0x1C:
2907 case 0x5C:
2908 case 0x9C:
2909 case 0xDC:
2910 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
2911 break;
2912
2913 case 0x20:
2914 do_tok(buf, "stopMusic", 0);
2915 break;
2916 case 0x00:
2917 case 0xA0:
2918 do_tok(buf, "stopObjectCode", 0);
2919 break;
2920 case 0x62:
2921 case 0xE2:
2922 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
2923 break;
2924
2925 case 0x3C:
2926 case 0xBC:
2927 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
2928 break;
2929
2930 case 0x4C:
2931 case 0xCC:
2932 do_tok(buf, "loadScript", ((opcode & 0x80) ? A1V : A1B));
2933 break;
2934
2935 case 0x1E:
2936 case 0x3E:
2937 case 0x5E:
2938 case 0x7E:
2939 case 0x9E:
2940 case 0xBE:
2941 case 0xDE:
2942 case 0xFE:
2943 do_tok(buf, "walkActorTo",
2944 ((opcode & 0x80) ? A1V : A1B) |
2945 ((opcode & 0x40) ? A2V : A2B) |
2946 ((opcode & 0x20) ? A3V : A3B));
2947 break;
2948
2949 case 0x36:
2950 case 0xB6:
2951 case 0x76:
2952 case 0xF6:
2953 do_walk_actor_to_object(buf, opcode);
2954 break;
2955
2956 default:
2957 error("Unknown opcode %.2X", opcode);
2958 }
2959 }
2960
next_line_V345(char * buf)2961 void next_line_V345(char *buf) {
2962 byte opcode = get_byte();
2963
2964 switch (opcode) {
2965
2966 case 0x00:
2967 case 0xA0:
2968 do_tok(buf, "stopObjectCode", 0);
2969 break;
2970
2971 case 0x01:
2972 case 0x21:
2973 case 0x41:
2974 case 0x61:
2975 case 0x81:
2976 case 0xA1:
2977 case 0xC1:
2978 case 0xE1:
2979 do_tok(buf, "putActor",
2980 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) |
2981 ((opcode & 0x20) ? A3V : A3W));
2982 break;
2983
2984 case 0x15:
2985 case 0x55:
2986 case 0x95:
2987 case 0xD5:
2988 do_tok(buf, "actorFromPos",
2989 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | AVARSTORE);
2990 break;
2991
2992 case 0x03:
2993 case 0x83:
2994 do_tok(buf, "getActorRoom", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
2995 break;
2996
2997
2998 case 0x38:
2999 case 0xB8:
3000 case 0x04:
3001 case 0x84:
3002 case 0x08:
3003 case 0x88:
3004 case 0x48:
3005 case 0xC8:
3006 case 0x44:
3007 case 0xC4:
3008 case 0x78:
3009 case 0xF8:
3010 case 0x28:
3011 case 0xA8:
3012 do_if_code(buf, opcode);
3013 break;
3014
3015 case 0x05:
3016 case 0x45:
3017 case 0x85:
3018 case 0xC5:
3019 if (g_options.scriptVersion == 5) {
3020 buf = do_tok(buf, "drawObject", ((opcode & 0x80) ? A1V : A1W) | ANOLASTPAREN | ANOENDSEMICOLON);
3021 opcode = get_byte();
3022 switch (opcode & 0x1F) {
3023 case 1:
3024 do_tok(buf, "setXY",
3025 ASTARTCOMMA | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W) |
3026 ((opcode & 0x40) ? A2V : A2W));
3027 break;
3028 case 2:
3029 do_tok(buf, "setImage", ASTARTCOMMA | ANOENDSEMICOLON | ((opcode & 0x80) ? A1V : A1W));
3030 break;
3031 }
3032 strcat(buf, ");");
3033
3034 } else {
3035 buf = do_tok(buf, "drawObject",
3036 ((opcode & 0x80) ? A1V : A1W) |
3037 ((opcode & 0x40) ? A2V : A2W) |
3038 ((opcode & 0x20) ? A3V : A3W));
3039 }
3040 break;
3041
3042 case 0x25:
3043 case 0x65:
3044 case 0xA5:
3045 case 0xE5:
3046 if (g_options.scriptVersion == 5) {
3047 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3048 } else {
3049 buf = do_tok(buf, "drawObject",
3050 ((opcode & 0x80) ? A1V : A1W) |
3051 ((opcode & 0x40) ? A2V : A2W) |
3052 ((opcode & 0x20) ? A3V : A3W));
3053 }
3054 break;
3055
3056 case 0x06:
3057 case 0x86:
3058 do_tok(buf, "getActorElevation", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3059 break;
3060
3061 case 0x07:
3062 case 0x47:
3063 case 0x87:
3064 case 0xC7:
3065 do_tok(buf, "setState", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3066 break;
3067
3068 case 0x09:
3069 case 0x49:
3070 case 0x89:
3071 case 0xC9:
3072 do_tok(buf, "faceActor", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3073 break;
3074
3075 case 0x0A:
3076 case 0x8A:
3077 case 0x2A:
3078 case 0xAA:
3079 case 0x4A:
3080 case 0xCA:
3081 case 0x6A:
3082 case 0xEA:
3083 buf = do_tok(buf, "startScript", ((opcode & 0x80) ? A1V : A1B) | A2LIST | ANOLASTPAREN | ANOENDSEMICOLON);
3084 if (opcode & 0x20) { // freeze resistant
3085 buf += sprintf(buf, ",F");
3086 }
3087 if (opcode & 0x40) { // recursive
3088 buf += sprintf(buf, ",R");
3089 }
3090 buf += sprintf(buf, ");");
3091 break;
3092
3093 case 0x0B:
3094 case 0x4B:
3095 case 0x8B:
3096 case 0xCB:
3097 do_tok(buf, "getVerbEntryPoint",
3098 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
3099 break;
3100
3101 case 0x0c:
3102 case 0x8C:
3103 do_resource(buf, opcode);
3104 break;
3105
3106 case 0x0D:
3107 case 0x4D:
3108 case 0x8D:
3109 case 0xCD:
3110 do_tok(buf, "walkActorToActor",
3111 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) | A3B);
3112 break; /* arg1=actor, arg2=actor */
3113
3114 case 0x0F:
3115 case 0x8F:
3116 if (g_options.scriptVersion == 5) {
3117 do_tok(buf, "getObjectState", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3118 break;
3119 }
3120 // fall through
3121 case 0x2F:
3122 case 0x4F:
3123 case 0x6F:
3124 case 0xAF:
3125 case 0xCF:
3126 case 0xEF:
3127 do_if_state_code(buf, opcode);
3128 break;
3129
3130 case 0x10:
3131 case 0x90:
3132 do_tok(buf, "getObjectOwner", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3133 break;
3134
3135
3136 case 0x14:
3137 case 0xD8:
3138 case 0x94:
3139 do_print_ego(buf, opcode);
3140 break;
3141
3142 case 0x17:
3143 case 0x97:
3144 case 0x1A:
3145 case 0x9A:
3146 case 0x1B:
3147 case 0x9B:
3148 case 0x3A:
3149 case 0xBA:
3150 case 0x46:
3151 case 0x57:
3152 case 0xD7:
3153 case 0x5A:
3154 case 0xDA:
3155 case 0x5B:
3156 case 0xDB:
3157 case 0xC6:
3158 do_varset_code(buf, opcode);
3159 break;
3160
3161 case 0x18:
3162 do_unconditional_jump(buf);
3163 break;
3164
3165 case 0x1D:
3166 case 0x9D:
3167 do_tok(buf, "classOfIs", ((opcode & 0x80) ? A1V : A1W) | A2LIST | ATO | ATOWITHLASTPAREN);
3168 break; /* arg1=object; vararg=classes to test; arg3=jumpoffs */
3169
3170 case 0x1E:
3171 case 0x3E:
3172 case 0x5E:
3173 case 0x7E:
3174 case 0x9E:
3175 case 0xBE:
3176 case 0xDE:
3177 case 0xFE:
3178 do_tok(buf, "walkActorTo",
3179 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W) |
3180 ((opcode & 0x20) ? A3V : A3W));
3181 break;
3182
3183 case 0x24:
3184 case 0x64:
3185 case 0xA4:
3186 case 0xE4:
3187 buf =
3188 do_tok(buf, "loadRoomWithEgo",
3189 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | ANOLASTPAREN | ANOENDSEMICOLON);
3190 do_tok(buf, NULL, A1W | A2W | ANOFIRSTPAREN | ASTARTCOMMA);
3191 break;
3192
3193 case 0x2C:
3194 do_cursor_command(buf);
3195 break;
3196
3197 case 0x40:
3198 do_tok(buf, "cutscene", A1LIST);
3199 break;
3200
3201 case 0x42:
3202 case 0xC2:
3203 do_tok(buf, "chainScript", ((opcode & 0x80) ? A1V : A1B) | A2LIST);
3204 break;
3205
3206 case 0x56:
3207 case 0xD6:
3208 do_tok(buf, "getActorMoving", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3209 break;
3210 case 0x72:
3211 case 0xF2:
3212 do_tok(buf, "loadRoom", ((opcode & 0x80) ? A1V : A1B));
3213 break;
3214
3215 case 0x63:
3216 case 0xE3:
3217 do_tok(buf, "getActorFacing", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3218 break;
3219
3220 case 0x66:
3221 case 0xE6:
3222 do_tok(buf, "getClosestObjActor", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3223 break;
3224
3225 case 0x6C:
3226 case 0xEC:
3227 do_tok(buf, "getActorWidth", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3228 break;
3229
3230 case 0x71:
3231 case 0xF1:
3232 do_tok(buf, "getActorCostume", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3233 break;
3234
3235 case 0x3B:
3236 case 0xBB:
3237 if (g_options.IndyFlag)
3238 do_tok(buf, "waitForActor", ((opcode & 0x80) ? A1V : A1B));
3239 else
3240 do_tok(buf, "getActorScale", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3241 break;
3242
3243 case 0xAE:{
3244 if (g_options.IndyFlag)
3245 opcode = 2;
3246 else
3247 opcode = get_byte();
3248
3249 switch (opcode) {
3250 case 0x01:
3251 case 0x81:
3252 do_tok(buf, "WaitForActor", ((opcode & 0x80) ? A1V : A1B));
3253 break;
3254 case 0x02:
3255 do_tok(buf, "WaitForMessage", 0);
3256 break;
3257 case 0x03:
3258 do_tok(buf, "WaitForCamera", 0);
3259 break;
3260 case 0x04:
3261 do_tok(buf, "WaitForSentence", 0);
3262 break;
3263 default:
3264 do_tok(buf, "UnknownWait", 0);
3265 }
3266 }
3267 break;
3268
3269
3270 case 0x34:
3271 case 0x74:
3272 case 0xB4:
3273 case 0xF4:
3274 do_tok(buf, "getDist",
3275 AVARSTORE | ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W));
3276 break;
3277
3278
3279 case 0x36:
3280 case 0x76:
3281 case 0xB6:
3282 case 0xF6:
3283 do_tok(buf, "walkActorToObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3284 break;
3285
3286 case 0x37:
3287 case 0x77:
3288 case 0xB7:
3289 case 0xF7:
3290 do_tok(buf, "startObject",
3291 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B) | A3LIST);
3292 break;
3293
3294 case 0x19:
3295 case 0x39:
3296 case 0x59:
3297 case 0x79:
3298 case 0x99:
3299 case 0xB9:
3300 case 0xD9:
3301 case 0xF9:{
3302 buf = strecpy(buf, "doSentence(");
3303 // FIXME: this is not exactly what ScummVM does...
3304 if (!(opcode & 0x80) && (*g_scriptCurPos == 0xFE)) {
3305 strcpy(buf, "STOP);");
3306 g_scriptCurPos++;
3307 } else {
3308 do_tok(buf, "",
3309 ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1B) |
3310 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3W));
3311 }
3312 }
3313 break;
3314
3315
3316 case 0x62:
3317 case 0xE2:
3318 do_tok(buf, "stopScript", ((opcode & 0x80) ? A1V : A1B));
3319 break;
3320
3321 case 0xAC:
3322 do_expr_code(buf);
3323 break;
3324
3325 case 0x11:
3326 case 0x51:
3327 case 0x91:
3328 case 0xD1:
3329 do_tok(buf, "animateCostume", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3330 break;
3331
3332 case 0x80:
3333 do_tok(buf, "breakHere", 0);
3334 break;
3335
3336 case 0xc0:
3337 do_tok(buf, "endCutscene", 0);
3338 break;
3339
3340 case 0x27:{ /* String management subcode */
3341 switch ((opcode = get_byte()) & 0x1F) {
3342 case 0x01:
3343 do_load_code_to_string(buf, opcode);
3344 break;
3345 case 0x02:
3346 do_tok(buf, "CopyString", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3347 break;
3348 case 0x03:
3349 do_tok(buf, "SetStringChar",
3350 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
3351 ((opcode & 0x20) ? A3V : A3B));
3352 break; /* string(arg1)[arg2] = arg3 */
3353 case 0x04:
3354 do_tok(buf, "GetStringChar",
3355 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3356 break; /* arg1 = string(arg2)[arg3] */
3357 case 0x05:
3358 do_tok(buf, "CreateString", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3359 break; /* arg1=index, arg2=size */
3360 default:
3361 do_tok(buf, "StringFuncUnknown", 0);
3362 }
3363 }
3364 break;
3365
3366 case 0x13:
3367 case 0x53:
3368 case 0x93:
3369 case 0xD3:
3370 do_actorops(buf, opcode);
3371 break;
3372
3373 case 0x20:
3374 do_tok(buf, "stopMusic", 0);
3375 break;
3376
3377 case 0x70:
3378 case 0xF0:
3379 buf = do_tok(buf, "lights", ((opcode & 0x80) ? A1V : A1B) | A2B | A3B);
3380 break;
3381
3382 case 0x3F:
3383 case 0x7F:
3384 case 0xBF:
3385 case 0xFF:
3386 buf =
3387 do_tok(buf, "drawBox",
3388 ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2W) | ANOLASTPAREN | ANOENDSEMICOLON);
3389 opcode = get_byte();
3390 do_tok(buf, NULL,
3391 ASTARTCOMMA | ANOFIRSTPAREN | ((opcode & 0x80) ? A1V : A1W) |
3392 ((opcode & 0x40) ? A2V : A2W) | ((opcode & 0x20) ? A3V : A3B));
3393 break;
3394
3395
3396 case 0x02:
3397 case 0x82:
3398 if (g_options.ZakFlag)
3399 do_tok(buf, "startMusic", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3400 else
3401 do_tok(buf, "startMusic", ((opcode & 0x80) ? A1V : A1B));
3402 break;
3403
3404 case 0xCC:
3405 do_pseudoRoom(buf);
3406 break;
3407
3408 case 0x33:
3409 case 0x73:
3410 case 0xB3:
3411 case 0xF3:
3412 if (g_options.scriptVersion == 5)
3413 do_room_ops(buf);
3414 else
3415 do_room_ops_old(buf, opcode);
3416 break;
3417
3418 case 0x68:
3419 case 0xE8:
3420 do_tok(buf, "isScriptRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3421 break;
3422
3423 case 0x2E:{
3424 int d;
3425 d = get_byte();
3426 d |= get_byte() << 8;
3427 d |= get_byte() << 16;
3428 sprintf(buf, "delay(%d);", d);
3429 break;
3430 }
3431
3432 case 0x29:
3433 case 0x69:
3434 case 0xA9:
3435 case 0xE9:
3436 do_tok(buf, "setOwnerOf", ((opcode & 0x80) ? A1V : A1W) | ((opcode & 0x40) ? A2V : A2B));
3437 break;
3438
3439 case 0x52:
3440 case 0xD2:
3441 do_tok(buf, "actorFollowCamera", ((opcode & 0x80) ? A1V : A1B));
3442 break;
3443
3444 case 0x58:{
3445 int d;
3446 d = get_byte();
3447 if (d != 0)
3448 sprintf(buf, "beginOverride();");
3449 else
3450 sprintf(buf, "endOverride();");
3451 break;
3452 }
3453
3454 case 0x1C:
3455 case 0x9C:
3456 do_tok(buf, "startSound", ((opcode & 0x80) ? A1V : A1B));
3457 break;
3458
3459 case 0x4C:
3460 if (g_options.scriptVersion <= 3)
3461 do_tok(buf, "waitForSentence", 0);
3462 else
3463 do_tok(buf, "soundKludge", A1LIST);
3464 break;
3465
3466 case 0x3C:
3467 case 0xBC:
3468 do_tok(buf, "stopSound", ((opcode & 0x80) ? A1V : A1B));
3469 break;
3470
3471 case 0x98:
3472 do_tok(buf, "systemOps", A1B);
3473 break;
3474
3475 case 0x7B:
3476 case 0xFB:
3477 do_tok(buf, "getActorWalkBox", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3478 break;
3479
3480 case 0x43:
3481 case 0xC3:
3482 if (g_options.IndyFlag)
3483 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3484 else
3485 do_tok(buf, "getActorX", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3486 break;
3487
3488 case 0x23:
3489 case 0xA3:
3490 if (g_options.IndyFlag)
3491 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3492 else
3493 do_tok(buf, "getActorY", AVARSTORE | ((opcode & 0x80) ? A1V : A1W));
3494 break;
3495
3496 case 0x7A:
3497 case 0xFA:
3498 do_verbops(buf, opcode);
3499 break;
3500
3501 case 0x2D:
3502 case 0x6D:
3503 case 0xAD:
3504 case 0xED:
3505 do_tok(buf, "putActorInRoom", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3506 break;
3507
3508 case 0x54:
3509 case 0xD4:
3510 do_tok(buf, "setObjectName", ((opcode & 0x80) ? A1V : A1W) | A2ASCII);
3511 break;
3512
3513 case 0x5D:
3514 case 0xDD:
3515 do_tok(buf, "setClass", ((opcode & 0x80) ? A1V : A1W) | A2LIST);
3516 break;
3517
3518 case 0x35:
3519 case 0x75:
3520 case 0xB5:
3521 case 0xF5:
3522 do_tok(buf, "findObject",
3523 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3524 break;
3525
3526 case 0x26:
3527 case 0xA6:{
3528 int i;
3529 char first = 1;
3530
3531 buf = do_tok(buf, "setVarRange", A1V | ANOLASTPAREN | ANOENDSEMICOLON);
3532 i = get_byte();
3533
3534 buf += sprintf(buf, ",%d,[", i);
3535
3536 while (i > 0) {
3537 if (!first)
3538 buf = strecpy(buf, ",");
3539 first = 0;
3540
3541 buf += sprintf(buf, "%d", (opcode & 0x80) ? get_word() : get_byte());
3542 i--;
3543 }
3544
3545 strcpy(buf, "]);");
3546
3547 }
3548 break;
3549
3550 case 0x16:
3551 case 0x96:
3552 do_tok(buf, "getRandomNr", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3553 break;
3554
3555 case 0x2B:
3556 do_tok(buf, "delayVariable", A1V);
3557 break;
3558
3559 case 0x0E:
3560 case 0x4E:
3561 case 0x8E:
3562 case 0xCE:
3563 do_tok(buf, "putActorAtObject", ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2W));
3564 break;
3565
3566 case 0x12:
3567 case 0x92:
3568 do_tok(buf, "panCameraTo", ((opcode & 0x80) ? A1V : A1W));
3569 break;
3570
3571 case 0x32:
3572 case 0xB2:
3573 do_tok(buf, "setCameraAt", ((opcode & 0x80) ? A1V : A1W));
3574 break;
3575
3576 case 0x30:
3577 case 0xB0:
3578 if (g_options.scriptVersion == 3)
3579 do_tok(buf, "setBoxFlags", ((opcode & 0x80) ? A1V : A1B) | A2B);
3580 else
3581 do_matrix_ops(buf, opcode);
3582 break;
3583
3584 case 0x7C:
3585 case 0xFC:
3586 do_tok(buf, "isSoundRunning", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3587 break;
3588
3589 case 0x31:
3590 case 0xB1:
3591 do_tok(buf, "getInventoryCount", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3592 break;
3593
3594 case 0x1f:
3595 case 0x5f:
3596 case 0x9f:
3597 case 0xdf:
3598 do_tok(buf, "isActorInBox",
3599 ATO | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3600 break;
3601
3602 case 0x22:
3603 case 0xA2:
3604 if (g_options.scriptVersion == 5)
3605 do_tok(buf, "getAnimCounter", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3606 else
3607 do_tok(buf, "saveLoadGame", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3608 break;
3609
3610 case 0x3d:
3611 case 0x7d:
3612 case 0xBD:
3613 case 0xFD:
3614 do_tok(buf, "findInventory",
3615 AVARSTORE | ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B));
3616 break;
3617
3618 case 0xAB:{
3619 int code;
3620 opcode = get_byte();
3621 code =
3622 ((opcode & 0x80) ? A1V : A1B) | ((opcode & 0x40) ? A2V : A2B) |
3623 ((opcode & 0x20) ? A3V : A3B);
3624 switch (opcode & 0x1F) {
3625 case 0x01:
3626 do_tok(buf, "saveVerbs", code);
3627 break;
3628 case 0x02:
3629 do_tok(buf, "restoreVerbs", code);
3630 break;
3631 case 0x03:
3632 do_tok(buf, "deleteVerbs", code);
3633 break;
3634 default:
3635 error("opcode 0xAB: Unhandled subop %d", opcode & 0x1F);
3636 }
3637 }
3638 break;
3639
3640 case 0x60:
3641 case 0xE0:
3642 do_tok(buf, "freezeScripts", ((opcode & 0x80) ? A1V : A1B));
3643 break;
3644
3645 case 0x6E:
3646 case 0xEE:
3647 do_tok(buf, "stopObjectScript", ((opcode & 0x80) ? A1V : A1W));
3648 break;
3649
3650 // dodgy?
3651 case 0x5C:{
3652 case 0xDC:
3653 int d = get_byte();
3654 if ((d & 0x1F) == 3)
3655 do_tok(buf, "oldRoomEffect-set", ((opcode & 0x80) ? A1V : A1W));
3656 else
3657 do_tok(buf, "oldRoomEffect-fadein", ((opcode & 0x80) ? A1V : A1W));
3658 break;
3659 }
3660
3661 case 0x50:
3662 case 0xD0:
3663 do_tok(buf, "pickupObject", ((opcode & 0x80) ? A1V : A1W));
3664 break;
3665
3666 case 0xA7:
3667 if (g_options.scriptVersion == 5) {
3668 sprintf(buf, "dummy(%.2X);", opcode);
3669 } else {
3670 int d = get_byte();
3671 buf += sprintf(buf, "saveLoadVars(");
3672 if (d == 1) {
3673 buf += sprintf(buf, "Save");
3674 } else {
3675 buf += sprintf(buf, "Load");
3676 }
3677 while ((d = get_byte()) != 0) {
3678 switch (d & 0x1F) {
3679 case 0x01:
3680 buf += sprintf(buf, ", VarRange(");
3681 buf = get_var(buf);
3682 buf += sprintf(buf, ",");
3683 buf = get_var(buf);
3684 buf += sprintf(buf, ")");
3685 break;
3686 case 0x02:
3687 buf += sprintf(buf, ", StringRange(");
3688 buf = get_var_or_byte(buf, (d & 0x80));
3689 buf += sprintf(buf, ",");
3690 buf = get_var_or_byte(buf, (d & 0x40));
3691 buf += sprintf(buf, ")");
3692 break;
3693 case 0x03:
3694 buf += sprintf(buf, ", Open(");
3695 buf = get_string(buf);
3696 buf += sprintf(buf, ")");
3697 break;
3698 case 0x04:
3699 buf += sprintf(buf, ", Append)");
3700 return;
3701 case 0x1F:
3702 buf += sprintf(buf, ", Close)");
3703 return;
3704 }
3705 }
3706 buf += sprintf(buf, ");");
3707 }
3708 break;
3709
3710 case 0x67:
3711 case 0xE7:
3712 do_tok(buf, "getStringWidth", AVARSTORE | ((opcode & 0x80) ? A1V : A1B));
3713 break;
3714
3715 case 0x6B:
3716 do_tok(buf, "debug", ((opcode & 0x80) ? A1V : A1W));
3717 break;
3718
3719 default:
3720 if (g_options.haltOnError) {
3721 error("Unknown opcode %.2X", opcode);
3722 }
3723 sprintf(buf, "ERROR: Unknown opcode %.2X!", opcode);
3724 }
3725 }
3726