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 6-8 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 switch/case statements have a pattern that look as follows (they were probably
34 generated by some Scumm script compiler):
35
36 push SOMETHING - the value we are switching on
37 dup - duplicate it
38 push caseA - push the first case value
39 eq - compare
40 jump if false - if not equal, jump to next case
41 kill - we entered this case - kill the switch value from the stack
42 ...
43 jump AFTER - leave this switch
44 dup
45 push caseB
46 eq
47 jump if false
48 kill
49 ...
50 jump AFTER
51 [optional: default case here ?!?]
52 AFTER:
53
54
55 Unfortunatly, in reality it is somewhat more complicated. E.g. in script 55,
56 in some cases the "jump AFTER" instead jumps into the middle of some other case.
57 Maybe they did have some sort of code optimized after all?
58
59 Anyway, the fixed key pattern here seems to be for each case:
60 dup - push - eq - jumpFalse - kill
61 And of course a push before the first of these. Note that there doesn't have
62 to be a jump before each case: after all, "fall through" is possible with C(++)
63 switch/case statements, too, so it's possible they used that in Scumm, too.
64
65 */
66
67 class StackEnt;
68
69 const char *getVarName(uint var);
70 StackEnt *pop();
71
72
73 static int dupindex = 0;
74
75
76
77 enum StackEntType {
78 seInt = 1,
79 seVar = 2,
80 seArray = 3,
81 seBinary = 4,
82 seUnary = 5,
83 seComplex = 6,
84 seStackList = 7,
85 seDup = 8,
86 seNeg = 9
87 };
88
89 enum {
90 isZero,
91 isEqual,
92 isNotEqual,
93 isGreater,
94 isLess,
95 isLessEqual,
96 isGreaterEqual,
97 operAdd,
98 operSub,
99 operMul,
100 operDiv,
101 operLand,
102 operLor,
103 operBand,
104 operBor,
105 operMod
106 };
107
108 static const char *oper_list[] = {
109 "!",
110 "==",
111 "!=",
112 ">",
113 "<",
114 "<=",
115 ">=",
116 "+",
117 "-",
118 "*",
119 "/",
120 "&&",
121 "||",
122 "&",
123 "|",
124 "%"
125 };
126
127
128
129 class StackEnt {
130 public:
131 StackEntType type;
132
133 public:
~StackEnt()134 virtual ~StackEnt() {}
135 virtual char *asText(char *where, bool wantparens = true) const = 0;
136 virtual StackEnt* dup(char *output);
137
getIntVal() const138 virtual int getIntVal() const { error("getIntVal call on StackEnt type %d", type); }
139 };
140
141 class IntStackEnt : public StackEnt {
142 int _val;
143 public:
IntStackEnt(int val)144 IntStackEnt(int val) : _val(val) { type = seInt; }
asText(char * where,bool wantparens) const145 virtual char *asText(char *where, bool wantparens) const {
146 where += sprintf(where, "%d", _val);
147 return where;
148 }
dup(char * output)149 virtual StackEnt* dup(char *output) {
150 return new IntStackEnt(_val);
151 }
getIntVal() const152 virtual int getIntVal() const { return _val; }
153 };
154
155 class VarStackEnt : public StackEnt {
156 int _var;
157 public:
VarStackEnt(int var)158 VarStackEnt(int var) : _var(var) { type = seVar; }
asText(char * where,bool wantparens=true) const159 virtual char *asText(char *where, bool wantparens = true) const {
160 int var;
161 const char *s;
162 if (g_options.scriptVersion == 8) {
163 if (!(_var & 0xF0000000)) {
164 var = _var & 0xFFFFFFF;
165 if ((s = getVarName(var)) != NULL)
166 where = strecpy(where, s);
167 else
168 where += sprintf(where, "var%d", _var & 0xFFFFFFF);
169 } else if (_var & 0x80000000) {
170 where += sprintf(where, "bitvar%d", _var & 0x7FFFFFFF);
171 } else if (_var & 0x40000000) {
172 where += sprintf(where, "localvar%d", _var & 0xFFFFFFF);
173 } else {
174 where += sprintf(where, "?var?%d", _var);
175 }
176 } else {
177 if (!(_var & 0xF000)) {
178 var = _var & 0xFFF;
179 if ((s = getVarName(var)) != NULL)
180 where = strecpy(where, s);
181 else
182 where += sprintf(where, "var%d", _var & 0xFFF);
183 } else if (_var & 0x8000) {
184 if (g_options.heVersion >= 80) {
185 where += sprintf(where, "roomvar%d", _var & 0xFFF);
186 } else {
187 where += sprintf(where, "bitvar%d", _var & 0x7FFF);
188 }
189 } else if (_var & 0x4000) {
190 where += sprintf(where, "localvar%d", _var & 0xFFF);
191 } else {
192 where += sprintf(where, "?var?%d", _var);
193 }
194 }
195 return where;
196 }
197 };
198
199 class ArrayStackEnt : public StackEnt {
200 int _idx;
201 StackEnt *_dim1;
202 StackEnt *_dim2;
203 public:
ArrayStackEnt(int idx,StackEnt * dim2,StackEnt * dim1)204 ArrayStackEnt(int idx, StackEnt *dim2, StackEnt *dim1) : _idx(idx), _dim1(dim1), _dim2(dim2) { type = seArray; }
asText(char * where,bool wantparens) const205 virtual char *asText(char *where, bool wantparens) const {
206 const char *s;
207
208 if(g_options.scriptVersion == 8 && !(_idx & 0xF0000000) &&
209 (s = getVarName(_idx & 0xFFFFFFF)) != NULL)
210 where += sprintf(where, "%s[",s);
211 else if(g_options.scriptVersion < 8 && !(_idx & 0xF000) &&
212 (s = getVarName(_idx & 0xFFF)) != NULL)
213 where += sprintf(where, "%s[",s);
214 else if(g_options.scriptVersion < 8 && g_options.heVersion >= 80 && (_idx & 0x8000))
215 where += sprintf(where, "roomarray%d[", _idx & 0xfff);
216 else if(g_options.scriptVersion < 8 && (_idx & 0x4000))
217 where += sprintf(where, "localarray%d[", _idx & 0xfff);
218 else
219 where += sprintf(where, "array%d[", _idx);
220
221 if (_dim2) {
222 where = _dim2->asText(where);
223 where = strecpy(where, "][");
224 }
225
226 where = _dim1->asText(where);
227 where = strecpy(where, "]");
228
229 return where;
230 }
231 };
232
233 class UnaryOpStackEnt : public StackEnt {
234 int _op;
235 StackEnt *_valA;
236 public:
UnaryOpStackEnt(int op,StackEnt * valA)237 UnaryOpStackEnt(int op, StackEnt *valA) : _op(op), _valA(valA) { type = seUnary; }
asText(char * where,bool wantparens) const238 virtual char *asText(char *where, bool wantparens) const {
239 where += sprintf(where, "%s", oper_list[_op]);
240 where = _valA->asText(where);
241 return where;
242 }
243 };
244
245 class BinaryOpStackEnt : public StackEnt {
246 int _op;
247 StackEnt *_valA;
248 StackEnt *_valB;
249 public:
BinaryOpStackEnt(int op,StackEnt * valA,StackEnt * valB)250 BinaryOpStackEnt(int op, StackEnt *valA, StackEnt *valB) : _op(op), _valA(valA), _valB(valB) { type = seBinary; }
asText(char * where,bool wantparens) const251 virtual char *asText(char *where, bool wantparens) const {
252 if (wantparens)
253 *where++ = '(';
254 where = _valA->asText(where);
255 where += sprintf(where, " %s ", oper_list[_op]);
256 where = _valB->asText(where);
257 if (wantparens)
258 *where++ = ')';
259 *where = 0;
260 return where;
261 }
262 };
263
264 class ComplexStackEnt : public StackEnt {
265 char *_str;
266 public:
ComplexStackEnt(const char * s)267 ComplexStackEnt(const char *s) { _str = strdup(s); type = seComplex; }
~ComplexStackEnt()268 ~ComplexStackEnt() { free(_str); }
asText(char * where,bool wantparens) const269 virtual char *asText(char *where, bool wantparens) const {
270 where = strecpy(where, _str);
271 return where;
272 }
273 };
274
275 class ListStackEnt : public StackEnt {
276 public:
277 int _size;
278 StackEnt **_list;
279 public:
ListStackEnt(StackEnt * senum)280 ListStackEnt(StackEnt *senum) {
281 type = seStackList;
282
283 _size = senum->getIntVal();
284 _list = new StackEnt* [_size];
285
286 for (int i = 0; i < _size; ++i) {
287 _list[i] = pop();
288 }
289 }
~ListStackEnt()290 ~ListStackEnt() { delete [] _list; }
asText(char * where,bool wantparens) const291 virtual char *asText(char *where, bool wantparens) const {
292 *where++ = '[';
293 for (int i = _size - 1; i >= 0; --i) {
294 where = _list[i]->asText(where);
295 if (i)
296 *where++ = ',';
297 }
298 *where++ = ']';
299 *where = 0;
300 return where;
301 }
302 };
303
304 class DupStackEnt : public StackEnt {
305 public:
306 int _idx;
307 public:
DupStackEnt(int idx)308 DupStackEnt(int idx) : _idx(idx) { type = seDup; }
asText(char * where,bool wantparens) const309 virtual char *asText(char *where, bool wantparens) const {
310 where += sprintf(where, "dup[%d]", _idx);
311 return where;
312 }
313 };
314
315 class NegStackEnt : public StackEnt {
316 StackEnt *_op;
317 public:
NegStackEnt(StackEnt * op)318 NegStackEnt(StackEnt *op) : _op(op) { type = seNeg; }
asText(char * where,bool wantparens) const319 virtual char *asText(char *where, bool wantparens) const {
320 *where++ = '!';
321 where = _op->asText(where);
322 return where;
323 }
324 };
325 #define MAX_STACK_SIZE 256
326 static StackEnt *stack[MAX_STACK_SIZE];
327 static int num_stack = 0;
328
329 const char *var_names72[] = {
330 /* 0 */
331 "VAR_KEYPRESS",
332 "VAR_DEBUGMODE",
333 "VAR_TIMER_NEXT",
334 "VAR_OVERRIDE",
335 /* 4 */
336 "VAR_WALKTO_OBJ",
337 "VAR_RANDOM_NR",
338 NULL,
339 NULL,
340 /* 8 */
341 "VAR_GAME_LOADED",
342 "VAR_EGO",
343 "VAR_NUM_ACTOR",
344 NULL,
345 /* 12 */
346 NULL,
347 "VAR_VIRT_MOUSE_X",
348 "VAR_VIRT_MOUSE_Y",
349 "VAR_MOUSE_X",
350 /* 16 */
351 "VAR_MOUSE_Y",
352 "VAR_LEFTBTN_HOLD",
353 "VAR_RIGHTBTN_HOLD",
354 "VAR_CURSORSTATE",
355 /* 20 */
356 "VAR_USERPUT",
357 "VAR_ROOM",
358 "VAR_ROOM_WIDTH",
359 "VAR_ROOM_HEIGHT",
360 /* 24 */
361 "VAR_CAMERA_POS_X",
362 "VAR_CAMERA_MIN_X",
363 "VAR_CAMERA_MAX_X",
364 "VAR_ROOM_RESOURCE",
365 /* 28 */
366 "VAR_SCROLL_SCRIPT",
367 "VAR_ENTRY_SCRIPT",
368 "VAR_ENTRY_SCRIPT2",
369 "VAR_EXIT_SCRIPT",
370 /* 32 */
371 "VAR_EXIT_SCRIPT2",
372 "VAR_VERB_SCRIPT",
373 "VAR_SENTENCE_SCRIPT",
374 "VAR_INVENTORY_SCRIPT",
375 /* 36 */
376 "VAR_CUTSCENE_START_SCRIPT",
377 "VAR_CUTSCENE_END_SCRIPT",
378 "VAR_SAVELOAD_ENTER_SCRIPT",
379 "VAR_SAVELOAD_EXIT_SCRIPT",
380 /* 40 */
381 "VAR_SAVELOAD_SCRIPT",
382 "VAR_OPTIONS_SCRIPT",
383 "VAR_RESTART_KEY",
384 "VAR_PAUSE_KEY",
385 /* 44 */
386 "VAR_CUTSCENEEXIT_KEY",
387 "VAR_TALKSTOP_KEY",
388 "VAR_HAVE_MSG",
389 "VAR_NOSUBTITLES",
390 /* 48 */
391 "VAR_CHARINC",
392 "VAR_TALK_ACTOR",
393 "VAR_LAST_SOUND",
394 "VAR_TALK_CHANNEL",
395 /* 52 */
396 "VAR_SOUND_CHANNEL",
397 NULL,
398 "VAR_SOUND_ENABLED",
399 NULL,
400 /* 56 */
401 "VAR_NUM_SOUND_CHANNELS",
402 "VAR_MEMORY_PERFORMANCE",
403 "VAR_VIDEO_PERFORMANCE",
404 "VAR_NEW_ROOM",
405 /* 60 */
406 "VAR_TMR_1",
407 "VAR_TMR_2",
408 "VAR_TMR_3",
409 "VAR_TIMEDATE_HOUR",
410 /* 64 */
411 "VAR_TIMEDATE_MINUTE",
412 "VAR_TIMEDATE_DAY",
413 "VAR_TIMEDATE_MONTH",
414 "VAR_TIMEDATE_YEAR",
415 /* 68 */
416 "VAR_NUM_ROOMS",
417 "VAR_NUM_SCRIPTS",
418 "VAR_NUM_SOUNDS",
419 "VAR_NUM_COSTUMES",
420 /* 72 */
421 "VAR_NUM_IMAGES",
422 "VAR_NUM_CHARSETS",
423 "VAR_NUM_GLOBAL_OBJS",
424 "VAR_MOUSE_STATE",
425 /* 76 */
426 "VAR_POLYGONS_ONLY",
427 NULL,
428 "VAR_PLATFORM",
429 "VAR_PLATFORM_VERSION",
430 /* 80 */
431 "VAR_CURRENT_CHARSET",
432 "VAR_HIDE_ALL_TEXT",
433 "VAR_NO_SPEECH",
434 "VAR_MOUSE_OVERRIDE",
435 /* 84 */
436 "VAR_SOUNDCODE_TMR",
437 "VAR_DEBUG_ENABLED",
438 "VAR_KEY_STATE",
439 NULL,
440 /* 88 */
441 "VAR_NUM_SOUND_CHANNELS",
442 "VAR_COLOR_DEPTH",
443 NULL,
444 "VAR_PRINTING_ENABED",
445 /* 92 */
446 "VAR_FADE_COLOR",
447 "VAR_BLACK_COLOR",
448 "VAR_WHITE_COLOR",
449 "VAR_REDRAW_ALL_ACTORS",
450 /* 96 */
451 "VAR_TIMER_1",
452 "VAR_TIMER_2",
453 "VAR_NETWORK_START_SCRIPT",
454 "VAR_NETWORK_TIMEOUT",
455 /* 100 */
456 "VAR_NETWORK_ENABLED",
457 "VAR_NETWORK_ARRAY_SCRIPT",
458 NULL,
459 "VAR_SCRIPT_CYCLE",
460 /* 104 */
461 "VAR_NUM_SCRIPT_CYCLES",
462 "VAR_NUM_SPRITE_GROUPS",
463 "VAR_NUM_SPRITES",
464 "VAR_U32_VERSION",
465 /* 108 */
466 NULL,
467 NULL,
468 NULL,
469 NULL,
470 /* 112 */
471 NULL,
472 NULL,
473 NULL,
474 NULL,
475 /* 116 */
476 "VAR_U32_ARRAY_UNK",
477 "VAR_WIZ_TCOLOR",
478 "VAR_SMACKER_ENABLED",
479 "VAR_ERROR_CODE",
480 /* 120 */
481 "VAR_RESERVED_SOUND_CHANNELS",
482 NULL,
483 "VAR_JOYSTICK_UNK1",
484 "VAR_JOYSTICK_UNK2",
485 /* 124 */
486 "VAR_JOYSTICK_DETECTED",
487 "VAR_SKIP_RESET_TALK_ACTOR",
488 "VAR_UPDATE_SCREEN_TYPE",
489 "VAR_MAIN_SCRIPT",
490 /* 128 */
491 "VAR_JOYSTICK_DISABLED",
492 "VAR_BASE_NAME",
493 "VAR_NUM_PALETTES",
494 "VAR_NUM_WINDOWS",
495 /* 132 */
496 NULL,
497 NULL,
498 NULL,
499 NULL,
500 /* 136 */
501 NULL,
502 NULL,
503 NULL,
504 "VAR_SET_SPRITE_DIFF",
505 /* 140 */
506 "VAR_BINK_ENABLED",
507 NULL,
508 NULL,
509 NULL,
510 };
511
512 const char *var_names6[] = {
513 /* 0 */
514 NULL,
515 "VAR_EGO",
516 "VAR_CAMERA_POS_X",
517 "VAR_HAVE_MSG",
518 /* 4 */
519 "VAR_ROOM",
520 "VAR_OVERRIDE",
521 "VAR_MACHINE_SPEED",
522 NULL,
523 /* 8 */
524 "VAR_NUM_ACTOR",
525 "VAR_V6_SOUNDMODE",
526 "VAR_CURRENTDRIVE",
527 "VAR_TMR_1",
528 /* 12 */
529 "VAR_TMR_2",
530 "VAR_TMR_3",
531 NULL,
532 NULL,
533 /* 16 */
534 NULL,
535 "VAR_CAMERA_MIN_X",
536 "VAR_CAMERA_MAX_X",
537 "VAR_TIMER_NEXT",
538 /* 20 */
539 "VAR_VIRT_MOUSE_X",
540 "VAR_VIRT_MOUSE_Y",
541 "VAR_ROOM_RESOURCE",
542 "VAR_LAST_SOUND",
543 /* 24 */
544 "VAR_CUTSCENEEXIT_KEY",
545 "VAR_TALK_ACTOR",
546 "VAR_CAMERA_FAST_X",
547 "VAR_SCROLL_SCRIPT",
548 /* 28 */
549 "VAR_ENTRY_SCRIPT",
550 "VAR_ENTRY_SCRIPT2",
551 "VAR_EXIT_SCRIPT",
552 "VAR_EXIT_SCRIPT2",
553 /* 32 */
554 "VAR_VERB_SCRIPT",
555 "VAR_SENTENCE_SCRIPT",
556 "VAR_INVENTORY_SCRIPT",
557 "VAR_CUTSCENE_START_SCRIPT",
558 /* 36 */
559 "VAR_CUTSCENE_END_SCRIPT",
560 "VAR_CHARINC",
561 "VAR_WALKTO_OBJ",
562 "VAR_DEBUGMODE",
563 /* 40 */
564 "VAR_HEAPSPACE",
565 "VAR_ROOM_WIDTH",
566 "VAR_RESTART_KEY",
567 "VAR_PAUSE_KEY",
568 /* 44 */
569 "VAR_MOUSE_X",
570 "VAR_MOUSE_Y",
571 "VAR_TIMER",
572 "VAR_TMR_4",
573 /* 48 */
574 NULL,
575 "VAR_VIDEOMODE",
576 "VAR_MAINMENU_KEY",
577 "VAR_FIXEDDISK",
578 /* 52 */
579 "VAR_CURSORSTATE",
580 "VAR_USERPUT",
581 "VAR_ROOM_HEIGHT",
582 NULL,
583 /* 56 */
584 "VAR_SOUNDRESULT",
585 "VAR_TALKSTOP_KEY",
586 NULL,
587 "VAR_FADE_DELAY",
588 /* 60 */
589 "VAR_NOSUBTITLES",
590 "VAR_SAVELOAD_SCRIPT",
591 "VAR_SAVELOAD_SCRIPT2",
592 NULL,
593 /* 64 */
594 "VAR_SOUNDPARAM",
595 "VAR_SOUNDPARAM2",
596 "VAR_SOUNDPARAM3",
597 "VAR_INPUTMODE",
598 /* 68 */
599 "VAR_MEMORY_PERFORMANCE",
600 "VAR_VIDEO_PERFORMANCE",
601 "VAR_ROOM_FLAG",
602 "VAR_GAME_LOADED",
603 /* 72 */
604 "VAR_NEW_ROOM",
605 NULL,
606 "VAR_LEFTBTN_DOWN",
607 "VAR_RIGHTBTN_DOWN",
608 /* 76 */
609 "VAR_V6_EMSSPACE",
610 NULL,
611 NULL,
612 NULL,
613 /* 80 */
614 NULL,
615 NULL,
616 NULL,
617 NULL,
618 /* 84 */
619 NULL,
620 NULL,
621 NULL,
622 NULL,
623 /* 88 */
624 NULL,
625 NULL,
626 "VAR_GAME_DISK_MSG",
627 "VAR_OPEN_FAILED_MSG",
628 /* 92 */
629 "VAR_READ_ERROR_MSG",
630 "VAR_PAUSE_MSG",
631 "VAR_RESTART_MSG",
632 "VAR_QUIT_MSG",
633 /* 96 */
634 "VAR_SAVE_BTN",
635 "VAR_LOAD_BTN",
636 "VAR_PLAY_BTN",
637 "VAR_CANCEL_BTN",
638 /* 100 */
639 "VAR_QUIT_BTN",
640 "VAR_OK_BTN",
641 "VAR_SAVE_DISK_MSG",
642 "VAR_ENTER_NAME_MSG",
643 /* 104 */
644 "VAR_NOT_SAVED_MSG",
645 "VAR_NOT_LOADED_MSG",
646 "VAR_SAVE_MSG",
647 "VAR_LOAD_MSG",
648 /* 108 */
649 "VAR_SAVE_MENU_TITLE",
650 "VAR_LOAD_MENU_TITLE",
651 "VAR_GUI_COLORS",
652 "VAR_DEBUG_PASSWORD",
653 /* 112 */
654 NULL,
655 NULL,
656 NULL,
657 NULL,
658 /* 116 */
659 NULL,
660 "VAR_MAIN_MENU_TITLE",
661 "VAR_RANDOM_NR",
662 "VAR_TIMEDATE_YEAR",
663 /* 120 */
664 NULL,
665 "VAR_GAME_VERSION",
666 NULL,
667 "VAR_CHARSET_MASK",
668 /* 124 */
669 NULL,
670 "VAR_TIMEDATE_HOUR",
671 "VAR_TIMEDATE_MINUTE",
672 NULL,
673 /* 128 */
674 "VAR_TIMEDATE_DAY",
675 "VAR_TIMEDATE_MONTH",
676 NULL,
677 NULL,
678 };
679
680 const char *var_names7[] = {
681 /* 0 */
682 NULL,
683 "VAR_MOUSE_X",
684 "VAR_MOUSE_Y",
685 "VAR_VIRT_MOUSE_X",
686 /* 4 */
687 "VAR_VIRT_MOUSE_Y",
688 "VAR_ROOM_WIDTH",
689 "VAR_ROOM_HEIGHT",
690 "VAR_CAMERA_POS_X",
691 /* 8 */
692 "VAR_CAMERA_POS_Y",
693 "VAR_OVERRIDE",
694 "VAR_ROOM",
695 "VAR_ROOM_RESOURCE",
696 /* 12 */
697 "VAR_TALK_ACTOR",
698 "VAR_HAVE_MSG",
699 "VAR_TIMER",
700 "VAR_TMR_4",
701 /* 16 */
702 "VAR_TIMEDATE_YEAR",
703 "VAR_TIMEDATE_MONTH",
704 "VAR_TIMEDATE_DAY",
705 "VAR_TIMEDATE_HOUR",
706 /* 20 */
707 "VAR_TIMEDATE_MINUTE",
708 "VAR_TIMEDATE_SECOND",
709 "VAR_LEFTBTN_DOWN",
710 "VAR_RIGHTBTN_DOWN",
711 /* 24 */
712 "VAR_LEFTBTN_HOLD",
713 "VAR_RIGHTBTN_HOLD",
714 "VAR_MEMORY_PERFORMANCE",
715 "VAR_VIDEO_PERFORMANCE",
716 /* 28 */
717 NULL,
718 "VAR_GAME_LOADED",
719 NULL,
720 NULL,
721 /* 32 */
722 "VAR_V6_EMSSPACE",
723 "VAR_VOICE_MODE",
724 "VAR_RANDOM_NR",
725 "VAR_NEW_ROOM",
726 /* 36 */
727 "VAR_WALKTO_OBJ",
728 "VAR_NUM_GLOBAL_OBJS",
729 "VAR_CAMERA_DEST_X",
730 "VAR_CAMERA_DEST_>",
731 /* 40 */
732 "VAR_CAMERA_FOLLOWED_ACTOR",
733 NULL,
734 NULL,
735 NULL,
736 /* 44 */
737 NULL,
738 NULL,
739 NULL,
740 NULL,
741 /* 48 */
742 NULL,
743 NULL,
744 "VAR_SCROLL_SCRIPT",
745 "VAR_ENTRY_SCRIPT",
746 /* 52 */
747 "VAR_ENTRY_SCRIPT2",
748 "VAR_EXIT_SCRIPT",
749 "VAR_EXIT_SCRIPT2",
750 "VAR_VERB_SCRIPT",
751 /* 56 */
752 "VAR_SENTENCE_SCRIPT",
753 "VAR_INVENTORY_SCRIPT",
754 "VAR_CUTSCENE_START_SCRIPT",
755 "VAR_CUTSCENE_END_SCRIPT",
756 /* 60 */
757 "VAR_SAVELOAD_SCRIPT",
758 "VAR_SAVELOAD_SCRIPT2",
759 "VAR_CUTSCENEEXIT_KEY",
760 "VAR_RESTART_KEY",
761 /* 64 */
762 "VAR_PAUSE_KEY",
763 "VAR_MAINMENU_KEY",
764 "VAR_VERSION_KEY",
765 "VAR_TALKSTOP_KEY",
766 /* 68 */
767 NULL,
768 NULL,
769 "VAR_SAVE_BTN",
770 "VAR_LOAD_BTN",
771 /* 72 */
772 "VAR_PLAY_BTN",
773 "VAR_CANCEL_BTN",
774 "VAR_QUIT_BTN",
775 "VAR_OK_BTN",
776 /* 76 */
777 "VAR_SAVE_MENU_TITLE",
778 "VAR_LOAD_MENU_TITLE",
779 "VAR_ENTER_NAME_MSG",
780 "VAR_SAVE_MSG",
781 /* 80 */
782 "VAR_LOAD_MSG",
783 "VAR_NOT_SAVED_MSG",
784 "VAR_NOT_LOADED_MSG",
785 "VAR_OPEN_FAILED_MSG",
786 /* 84 */
787 "VAR_READ_ERROR_MSG",
788 "VAR_PAUSE_MSG",
789 "VAR_RESTART_MSG",
790 "VAR_QUIT_MSG",
791 /* 88 */
792 NULL,
793 "VAR_DEBUG_PASSWORD",
794 NULL,
795 NULL,
796 /* 92 */
797 NULL,
798 NULL,
799 NULL,
800 NULL,
801 /* 96 */
802 NULL,
803 "VAR_TIMER_NEXT",
804 "VAR_TMR_1",
805 "VAR_TMR_2",
806 /* 100 */
807 "VAR_TMR_3",
808 "VAR_CAMERA_MIN_X",
809 "VAR_CAMERA_MAX_X",
810 "VAR_CAMERA_MIN_Y",
811 /* 104 */
812 "VAR_CAMERA_MAX_Y",
813 "VAR_CAMERA_THRESHOLD_X",
814 "VAR_CAMERA_THRESHOLD_Y",
815 "VAR_CAMERA_SPEED_X",
816 /* 108 */
817 "VAR_CAMERA_SPEED_Y",
818 "VAR_CAMERA_ACCEL_X",
819 "VAR_CAMERA_ACCEL_Y",
820 "VAR_EGO",
821 /* 112 */
822 "VAR_CURSORSTATE",
823 "VAR_USERPUT",
824 "VAR_DEFAULT_TALK_DELAY",
825 "VAR_CHARINC",
826 /* 116 */
827 "VAR_DEBUGMODE",
828 "VAR_FADE_DELAY",
829 NULL,
830 "VAR_CHARSET_MASK",
831 /* 120 */
832 NULL,
833 NULL,
834 NULL,
835 "VAR_VIDEONAME",
836 /* 124 */
837 NULL,
838 NULL,
839 NULL,
840 NULL,
841 /* 128 */
842 NULL,
843 NULL,
844 "VAR_STRING2DRAW",
845 "VAR_CUSTOMSCALETABLE",
846 /* 132 */
847 NULL,
848 "VAR_BLAST_ABOVE_TEXT",
849 NULL,
850 "VAR_MUSIC_BUNDLE_LOADED",
851 /* 136 */
852 "VAR_VOICE_BUNDLE_LOADED",
853 NULL,
854 };
855
856 const char *var_names8[] = {
857 /* 0 */
858 NULL,
859 "VAR_ROOM_WIDTH",
860 "VAR_ROOM_HEIGHT",
861 "VAR_MOUSE_X",
862 /* 4 */
863 "VAR_MOUSE_Y",
864 "VAR_VIRT_MOUSE_X",
865 "VAR_VIRT_MOUSE_Y",
866 "VAR_CURSORSTATE",
867 /* 8 */
868 "VAR_USERPUT",
869 "VAR_CAMERA_POS_X",
870 "VAR_CAMERA_POS_Y",
871 "VAR_CAMERA_DEST_X",
872 /* 12 */
873 "VAR_CAMERA_DEST_Y",
874 "VAR_CAMERA_FOLLOWED_ACTOR",
875 "VAR_TALK_ACTOR",
876 "VAR_HAVE_MSG",
877 /* 16 */
878 "VAR_LEFTBTN_DOWN",
879 "VAR_RIGHTBTN_DOWN",
880 "VAR_LEFTBTN_HOLD",
881 "VAR_RIGHTBTN_HOLD",
882 /* 20 */
883 NULL,
884 NULL,
885 NULL,
886 NULL,
887 /* 24 */
888 "VAR_TIMEDATE_YEAR",
889 "VAR_TIMEDATE_MONTH",
890 "VAR_TIMEDATE_DAY",
891 "VAR_TIMEDATE_HOUR",
892 /* 28 */
893 "VAR_TIMEDATE_MINUTE",
894 "VAR_TIMEDATE_SECOND",
895 "VAR_OVERRIDE",
896 "VAR_ROOM",
897 /* 32 */
898 "VAR_NEW_ROOM",
899 "VAR_WALKTO_OBJ",
900 "VAR_TIMER",
901 NULL,
902 /* 36 */
903 NULL,
904 NULL,
905 NULL,
906 "VAR_VOICE_MODE",
907 /* 40 */
908 "VAR_GAME_LOADED",
909 "VAR_LANGUAGE",
910 "VAR_CURRENTDISK",
911 NULL,
912 /* 44 */
913 NULL,
914 "VAR_MUSIC_BUNDLE_LOADED",
915 "VAR_VOICE_BUNDLE_LOADED",
916 NULL,
917 /* 48 */
918 NULL,
919 NULL,
920 "VAR_SCROLL_SCRIPT",
921 "VAR_ENTRY_SCRIPT",
922 /* 52 */
923 "VAR_ENTRY_SCRIPT2",
924 "VAR_EXIT_SCRIPT",
925 "VAR_EXIT_SCRIPT2",
926 "VAR_VERB_SCRIPT",
927 /* 56 */
928 "VAR_SENTENCE_SCRIPT",
929 "VAR_INVENTORY_SCRIPT",
930 "VAR_CUTSCENE_START_SCRIPT",
931 "VAR_CUTSCENE_END_SCRIPT",
932 /* 60 */
933 NULL,
934 NULL,
935 "VAR_CUTSCENEEXIT_KEY",
936 "VAR_RESTART_KEY",
937 /* 64 */
938 "VAR_PAUSE_KEY",
939 "VAR_MAINMENU_KEY",
940 "VAR_VERSION_KEY",
941 "VAR_TALKSTOP_KEY",
942 /* 68 */
943 NULL,
944 NULL,
945 NULL,
946 NULL,
947 /* 72 */
948 NULL,
949 NULL,
950 NULL,
951 NULL,
952 /* 76 */
953 NULL,
954 NULL,
955 NULL,
956 NULL,
957 /* 80 */
958 NULL,
959 NULL,
960 NULL,
961 NULL,
962 /* 84 */
963 NULL,
964 NULL,
965 NULL,
966 NULL,
967 /* 88 */
968 NULL,
969 NULL,
970 NULL,
971 NULL,
972 /* 92 */
973 NULL,
974 NULL,
975 NULL,
976 NULL,
977 /* 96 */
978 NULL,
979 NULL,
980 NULL,
981 NULL,
982 /* 100 */
983 NULL,
984 NULL,
985 NULL,
986 NULL,
987 /* 104 */
988 NULL,
989 NULL,
990 NULL,
991 NULL,
992 /* 108 */
993 NULL,
994 NULL,
995 NULL,
996 "VAR_CUSTOMSCALETABLE",
997 /* 112 */
998 "VAR_TIMER_NEXT",
999 "VAR_TMR_1",
1000 "VAR_TMR_2",
1001 "VAR_TMR_3",
1002 /* 116 */
1003 "VAR_CAMERA_MIN_X",
1004 "VAR_CAMERA_MAX_X",
1005 "VAR_CAMERA_MIN_Y",
1006 "VAR_CAMERA_MAX_Y",
1007 /* 120 */
1008 "VAR_CAMERA_SPEED_X",
1009 "VAR_CAMERA_SPEED_Y",
1010 "VAR_CAMERA_ACCEL_X",
1011 "VAR_CAMERA_ACCEL_Y",
1012 /* 124 */
1013 "VAR_CAMERA_THRESHOLD_X",
1014 "VAR_CAMERA_THRESHOLD_Y",
1015 "VAR_EGO",
1016 NULL,
1017 /* 128 */
1018 "VAR_DEFAULT_TALK_DELAY",
1019 "VAR_CHARINC",
1020 "VAR_DEBUGMODE",
1021 NULL,
1022 /* 132 */
1023 "VAR_KEYPRESS",
1024 "VAR_BLAST_ABOVE_TEXT",
1025 "VAR_SYNC",
1026 NULL,
1027 };
1028
getVarName(uint var)1029 const char *getVarName(uint var) {
1030 if (g_options.heVersion >= 72) {
1031 if (var >= sizeof(var_names72) / sizeof(var_names72[0]))
1032 return NULL;
1033 return var_names72[var];
1034 } else if (g_options.scriptVersion == 8) {
1035 if (var >= sizeof(var_names8) / sizeof(var_names8[0]))
1036 return NULL;
1037 return var_names8[var];
1038 } else if (g_options.scriptVersion == 7) {
1039 if (var >= sizeof(var_names7) / sizeof(var_names7[0]))
1040 return NULL;
1041 return var_names7[var];
1042 } else {
1043 if (var >= sizeof(var_names6) / sizeof(var_names6[0]))
1044 return NULL;
1045 return var_names6[var];
1046 }
1047 }
1048
se_neg(StackEnt * se)1049 StackEnt *se_neg(StackEnt *se) {
1050 return new NegStackEnt(se);
1051 }
1052
se_int(int i)1053 StackEnt *se_int(int i) {
1054 return new IntStackEnt(i);
1055 }
1056
se_var(int i)1057 StackEnt *se_var(int i) {
1058 return new VarStackEnt(i);
1059 }
1060
se_array(int i,StackEnt * dim2,StackEnt * dim1)1061 StackEnt *se_array(int i, StackEnt *dim2, StackEnt *dim1) {
1062 return new ArrayStackEnt(i, dim2, dim1);
1063 }
1064
se_oper(StackEnt * a,int op)1065 StackEnt *se_oper(StackEnt *a, int op) {
1066 return new UnaryOpStackEnt(op, a);
1067 }
1068
se_oper(StackEnt * a,int op,StackEnt * b)1069 StackEnt *se_oper(StackEnt *a, int op, StackEnt *b) {
1070 return new BinaryOpStackEnt(op, a, b);
1071 }
1072
se_complex(const char * s)1073 StackEnt *se_complex(const char *s) {
1074 return new ComplexStackEnt(s);
1075 }
1076
se_astext(StackEnt * se,char * where,bool wantparens=true)1077 char *se_astext(StackEnt *se, char *where, bool wantparens = true) {
1078 return se->asText(where, wantparens);
1079 }
1080
se_get_list()1081 StackEnt *se_get_list() {
1082 return new ListStackEnt(pop());
1083 }
1084
get_var6(char * buf)1085 char *get_var6(char *buf) {
1086 VarStackEnt tmp(get_word());
1087 return tmp.asText(buf);
1088 }
1089
invalidop(const char * cmd,int op)1090 void invalidop(const char *cmd, int op) {
1091 if (cmd)
1092 error("Unknown opcode %s:0x%x (stack count %d)", cmd, op, num_stack);
1093 else
1094 error("Unknown opcode 0x%x (stack count %d)", op, num_stack);
1095 }
1096
push(StackEnt * se)1097 void push(StackEnt *se) {
1098 assert(se);
1099 assert(num_stack < MAX_STACK_SIZE);
1100 stack[num_stack++] = se;
1101 }
1102
pop()1103 StackEnt *pop() {
1104 if (num_stack == 0) {
1105 printf("ERROR: No items on stack to pop!\n");
1106
1107 if (!g_options.haltOnError)
1108 return se_complex("**** INVALID DATA ****");
1109 exit(1);
1110 }
1111 return stack[--num_stack];
1112 }
1113
1114
kill(char * output,StackEnt * se)1115 void kill(char *output, StackEnt *se) {
1116 if (se->type != seDup) {
1117 char *e = strecpy(output, "pop(");
1118 e = se_astext(se, e);
1119 strcpy(e, ")");
1120 delete se;
1121 } else {
1122 // FIXME: Evil hack: We re-push DUPs, instead of killing
1123 // them. We do this to support switch-case constructs
1124 // (see comment at the start of this file) w/o applying a full
1125 // flow analysis (which would normally be required).
1126 push(se);
1127 }
1128 }
1129
doAssign(char * output,StackEnt * dst,StackEnt * src)1130 void doAssign(char *output, StackEnt *dst, StackEnt *src) {
1131 if (src->type == seDup && dst->type == seDup) {
1132 ((DupStackEnt *)dst)->_idx = ((DupStackEnt *)src)->_idx;
1133 return;
1134 }
1135 char *e = se_astext(dst, output);
1136 e = strecpy(e, " = ");
1137 se_astext(src, e);
1138 }
1139
dup(char * output)1140 StackEnt* StackEnt::dup(char *output) {
1141 StackEnt *dse = new DupStackEnt(++dupindex);
1142 doAssign(output, dse, this);
1143 return dse;
1144 }
1145
doAdd(char * output,StackEnt * se,int val)1146 void doAdd(char *output, StackEnt *se, int val) {
1147 char *e = se_astext(se, output);
1148 if (val == 1) {
1149 sprintf(e, "++");
1150 } else if (val == -1) {
1151 sprintf(e, "--");
1152 } else {
1153 /* SCUMM doesn't support this */
1154 sprintf(e, " += %d", val);
1155 }
1156 }
1157
dup(char * output,StackEnt * se)1158 StackEnt *dup(char *output, StackEnt *se) {
1159 return se->dup(output);
1160 }
1161
writeArray(char * output,int i,StackEnt * dim2,StackEnt * dim1,StackEnt * value)1162 void writeArray(char *output, int i, StackEnt *dim2, StackEnt *dim1, StackEnt *value) {
1163 StackEnt *array = se_array(i, dim2, dim1);
1164 doAssign(output, array, value);
1165 delete array;
1166 }
1167
writeVar(char * output,int i,StackEnt * value)1168 void writeVar(char *output, int i, StackEnt *value) {
1169 StackEnt *se = se_var(i);
1170 doAssign(output, se, value);
1171 delete se;
1172 }
1173
addArray(char * output,int i,StackEnt * dim1,int val)1174 void addArray(char *output, int i, StackEnt *dim1, int val) {
1175 StackEnt *array = se_array(i, NULL, dim1);
1176 doAdd(output, array, val);
1177 delete array;
1178 }
1179
addVar(char * output,int i,int val)1180 void addVar(char *output, int i, int val) {
1181 StackEnt *se = se_var(i);
1182 doAdd(output, se, val);
1183 delete se;
1184 }
1185
1186
se_get_string()1187 StackEnt *se_get_string() {
1188 char buf[1024];
1189 get_string(buf); // ignore returned value
1190 return se_complex(buf);
1191 }
1192
1193 int _stringLength = 1;
1194 byte _stringBuffer[4096];
1195
getScriptString()1196 void getScriptString() {
1197 byte chr;
1198
1199 while ((chr = get_byte()) != 0) {
1200 _stringBuffer[_stringLength] = chr;
1201 _stringLength++;
1202
1203 if (_stringLength >= 4096)
1204 error("String stack overflow");
1205 }
1206
1207 _stringBuffer[_stringLength] = 0;
1208 _stringLength++;
1209 }
1210
se_get_string_he()1211 StackEnt *se_get_string_he() {
1212 char buf[1024];
1213 char *e = buf;
1214
1215 byte string[1024];
1216 byte chr;
1217 int len = 1;
1218 StackEnt *value;
1219
1220 value = pop();
1221
1222 *e++ = '"';
1223 if (value->type == seInt && value->getIntVal() == -1) {
1224 if (_stringLength == 1) {
1225 *e++ = '"';
1226 *e++ = 0;
1227 return se_complex(buf);
1228 }
1229
1230 _stringLength -= 2;
1231 while ((chr = _stringBuffer[_stringLength]) != 0) {
1232 string[len++] = chr;
1233 _stringLength--;
1234 }
1235
1236 string[len] = 0;
1237 _stringLength++;
1238
1239 // Reverse string
1240 while (--len)
1241 *e++ = string[len];
1242 } else {
1243 e += sprintf(e, ":");
1244 e = value->asText(e);
1245 e += sprintf(e, ":");
1246 }
1247 *e++ = '"';
1248
1249 *e++ = 0;
1250 return se_complex(buf);
1251 }
1252
ext(char * output,const char * fmt)1253 void ext(char *output, const char *fmt) {
1254 bool wantresult;
1255 byte cmd, extcmd;
1256 const char *extstr = NULL;
1257 const char *prep = NULL;
1258 StackEnt *args[20];
1259 int numArgs = 0;
1260 char *e = (char *)output;
1261
1262 /* return the result? */
1263 wantresult = false;
1264 if (*fmt == 'r') {
1265 wantresult = true;
1266 fmt++;
1267 }
1268
1269 while ((cmd = *fmt++) != '|') {
1270 if (cmd == 'x' && !extstr) {
1271 /* Sub-op: next byte specifies which one */
1272 extstr = fmt;
1273 while (*fmt++)
1274 ;
1275 e += sprintf(e, "%s.", extstr);
1276
1277 /* extended thing */
1278 extcmd = get_byte();
1279
1280 /* locate our extended item */
1281 while ((cmd = *fmt++) != extcmd) {
1282 /* scan until we find , or \0 */
1283 while ((cmd = *fmt++) != ',') {
1284 if (cmd == 0) {
1285 invalidop(extstr, extcmd);
1286 }
1287 }
1288 }
1289 /* found a command, continue at the beginning */
1290 continue;
1291 }
1292 if (cmd == 'u' && !extstr) {
1293 /* Sub-op: next byte specifies which one */
1294 extstr = fmt;
1295 while (*fmt++)
1296 ;
1297 e += sprintf(e, "%s.", extstr);
1298
1299 /* extended thing */
1300 extcmd = pop()->getIntVal();
1301
1302 /* locate our extended item */
1303 while ((cmd = *fmt++) != extcmd) {
1304 /* scan until we find , or \0 */
1305 while ((cmd = *fmt++) != ',') {
1306 if (cmd == 0) {
1307 invalidop(extstr, extcmd);
1308 }
1309 }
1310 }
1311 /* found a command, continue at the beginning */
1312 continue;
1313 }
1314 if (cmd == 'y' && !extstr) {
1315 /* Sub-op: parameters are in a list, first element of the list specified the command */
1316 ListStackEnt *se;
1317 extstr = fmt;
1318 while (*fmt++)
1319 ;
1320 e += sprintf(e, "%s.", extstr);
1321
1322 se = new ListStackEnt(pop());
1323 args[numArgs++] = se;
1324
1325 /* extended thing */
1326 se->_size--;
1327 extcmd = (byte) se->_list[se->_size]->getIntVal();
1328
1329 /* locate our extended item */
1330 while ((cmd = *fmt++) != extcmd) {
1331 /* scan until we find , or \0 */
1332 while ((cmd = *fmt++) != ',') {
1333 if (cmd == 0) {
1334 /* End reached and command was not found: re-add the extcmd to
1335 the list and output the whole thing as "unknown".
1336 */
1337 se->_size++;
1338 fmt = "Unknown";
1339 goto output_command;
1340 }
1341 }
1342 }
1343
1344 /* found a command, continue at the beginning */
1345 continue;
1346 }
1347
1348 if (cmd == 'p') {
1349 args[numArgs++] = pop();
1350 } else if (cmd == 'z') { // = popRoomAndObj()
1351 args[numArgs++] = pop();
1352 if (g_options.scriptVersion < 7 && g_options.heVersion == 0)
1353 args[numArgs++] = pop();
1354 } else if (cmd == 'h') {
1355 if (g_options.heVersion >= 72)
1356 args[numArgs++] = se_get_string_he();
1357 } else if (cmd == 's') {
1358 args[numArgs++] = se_get_string();
1359 } else if (cmd == 'w') {
1360 args[numArgs++] = se_int(get_word());
1361 } else if (cmd == 'i') {
1362 args[numArgs++] = se_int(get_byte());
1363 } else if (cmd == 'l') {
1364 args[numArgs++] = se_get_list();
1365 } else if (cmd == 'j') {
1366 args[numArgs++] = se_int(get_word());
1367 } else if (cmd == 'v') {
1368 args[numArgs++] = se_var(get_word());
1369 } else {
1370 error("Character '%c' unknown in argument string '%s', \n", fmt, cmd);
1371 }
1372 }
1373
1374 output_command:
1375
1376 /* create a string from the arguments */
1377 if (prep)
1378 e = strecpy(e, prep);
1379 while (*fmt != 0 && *fmt != ',')
1380 *e++ = *fmt++;
1381 *e++ = '(';
1382 while (--numArgs >= 0) {
1383 e = se_astext(args[numArgs], e);
1384 if (numArgs)
1385 *e++ = ',';
1386 }
1387 *e++ = ')';
1388 *e = 0;
1389
1390 if (wantresult) {
1391 push(se_complex((char *)output));
1392 output[0] = 0;
1393 return;
1394 }
1395 }
1396
jump(char * output)1397 void jump(char *output) {
1398 int offset = get_word();
1399 int cur = get_curoffs();
1400 int to = cur + offset;
1401
1402 if (offset == 1) {
1403 // Sometimes, jumps with offset 1 occur. I used to suppress those.
1404 // But it turns out that's not quite correct in some cases. With this
1405 // code, it can sometimes happens that you get an empty 'else' branch;
1406 // but in many other cases, an otherwise hidden instruction is revealed,
1407 // or an instruction is placed into an else branch instead of being
1408 // (incorrectly) placed inside the body of the 'if' itself.
1409 sprintf(output, "/* jump %x; */", to);
1410 } else if (!g_options.dontOutputElse && maybeAddElse(cur, to)) {
1411 pendingElse = true;
1412 pendingElseTo = to;
1413 pendingElseOffs = cur;
1414 pendingElseOpcode = g_jump_opcode;
1415 pendingElseIndent = g_blockStack.size();
1416 } else {
1417 if (!g_blockStack.empty() && !g_options.dontOutputWhile) {
1418 Block p = g_blockStack.top();
1419 if (p.isWhile && cur == (int)p.to)
1420 return; // A 'while' ends here.
1421 if (!g_options.dontOutputBreaks && maybeAddBreak(cur, to)) {
1422 sprintf(output, "break");
1423 return;
1424 }
1425 }
1426 sprintf(output, "jump %x", to);
1427 }
1428 }
1429
jumpif(char * output,StackEnt * se,bool negate)1430 void jumpif(char *output, StackEnt *se, bool negate) {
1431 int offset = get_word();
1432 int cur = get_curoffs();
1433 int to = cur + offset;
1434 char *e = output;
1435
1436 if (!g_options.dontOutputElseif && pendingElse) {
1437 if (maybeAddElseIf(cur, pendingElseTo, to)) {
1438 pendingElse = false;
1439 haveElse = true;
1440 e = strecpy(e, "} else if (");
1441 e = se_astext(se, e, false);
1442 sprintf(e, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1443 return;
1444 }
1445 }
1446
1447 if (!g_options.dontOutputIfs && maybeAddIf(cur, to)) {
1448 if (!g_options.dontOutputWhile && g_blockStack.top().isWhile)
1449 e = strecpy(e, negate ? "until (" : "while (");
1450 else
1451 e = strecpy(e, negate ? "unless (" : "if (");
1452 e = se_astext(se, e, false);
1453 sprintf(e, g_options.alwaysShowOffs ? ") /*%.4X*/ {" : ") {", to);
1454 return;
1455 }
1456
1457 e = strecpy(e, negate ? "if (" : "unless (");
1458 e = se_astext(se, e);
1459 sprintf(e, ") jump %x", to);
1460 }
1461
dup_n()1462 void dup_n() {
1463 push(se_int(get_word()));
1464 ListStackEnt *list = (ListStackEnt *)se_get_list();
1465
1466 for (int i = 0; i < 2; i++)
1467 for (int j = 0; j < list->_size; j++)
1468 push(list->_list[j]);
1469 }
1470
1471
1472 #define PRINT_V100HE(name) \
1473 do { \
1474 ext(output, "x" name "\0" \
1475 "\x6pp|XY," \
1476 "\xC|center," \
1477 "\x12p|right," \
1478 "\x14p|color," \
1479 "\x15l|colors," \
1480 "\x23lps|debug," \
1481 "\x2E|left," \
1482 "\x33|mumble," \
1483 "\x38|overhead," \
1484 "\x4Ep|getText," \
1485 "\x4Fs|msg," \
1486 "\x5B|begin," \
1487 "\x5C|end" \
1488 ); \
1489 } while(0)
1490
next_line_HE_V100(char * output)1491 void next_line_HE_V100(char *output) {
1492 byte code = get_byte();
1493 StackEnt *se_a, *se_b;
1494
1495 switch (code) {
1496 case 0x0:
1497 ext(output, "x" "actorOps\0"
1498 "\x3ppp|actorSet:3:??,"
1499 "\x4p|setAnimSpeed,"
1500 "\x6pp|putActor,"
1501 "\x8|resetDrawToBackBuf,"
1502 "\x9|drawToBackBuf,"
1503 "\xEp|charset,"
1504 "\x12pppp|setClipRect,"
1505 "\x16l|setUserConditions,"
1506 "\x19p|setCostume,"
1507 "\x1B|init,"
1508 "\x20p|setHEFlag,"
1509 "\x34h|setName,"
1510 "\x35|initLittle,"
1511 "\x39pp|setPalette,"
1512 "\x3Bp|layer,"
1513 "\x3Fp|setPaletteNum,"
1514 "\x41p|setScale,"
1515 "\x46p|setShadowMode,"
1516 "\x4App|setWalkSpeed,"
1517 "\x4Ehp|setTalkieSlot,"
1518 "\x53pp|setAnimVar,"
1519 "\x57p|setAlwayZClip,"
1520 "\x59|setNeverZClip,"
1521 "\x80pppp|setActorClipRect,"
1522 "\x81p|setCurActor,"
1523 "\x82l|setSound,"
1524 "\x83p|setWidth,"
1525 "\x84|setDefAnim,"
1526 "\x85p|setElevation,"
1527 "\x86|setFollowBoxes,"
1528 "\x87|setIgnoreBoxes,"
1529 "\x88|setIgnoreTurnsOff,"
1530 "\x89|setIgnoreTurnsOn,"
1531 "\x8Ap|setInitFrame,"
1532 "\x8Bp|setStandFrame,"
1533 "\x8Cpp|setTalkFrame,"
1534 "\x8Dp|setTalkColor,"
1535 "\x8Ep|setTalkCondition,"
1536 "\x8Fpp|setTalkPos,"
1537 "\x90p|setWalkFrame");
1538 break;
1539 case 0x1:
1540 se_a = pop();
1541 se_b = pop();
1542 push(se_oper(se_b, 6 + isEqual, se_a));
1543 break;
1544 case 0x2:
1545 ext(output, "pp|faceActor");
1546 break;
1547
1548 case 0x03:
1549 ext(output, "x" "sortArray\0"
1550 "\x86pppppv|sort,");
1551 break;
1552 case 0x04:
1553 switch (get_byte()) {
1554 case 35:
1555 se_get_list();
1556 pop();
1557 se_a = se_get_string_he();
1558 writeArray(output, get_word(), NULL, se_a, se_a);
1559 break;
1560 case 77:
1561 se_a = se_get_string_he();
1562 writeArray(output, get_word(), NULL, se_a, se_a);
1563 break;
1564 case 128:
1565 se_b = se_get_list();
1566 se_a = pop();
1567 writeArray(output, get_word(), NULL, se_a, se_b);
1568 break;
1569 case 129:
1570 se_a = pop();
1571 se_b = se_get_list();
1572 writeArray(output, get_word(), NULL, se_a, se_b);
1573 break;
1574 case 130:
1575 // TODO: Add support for writeListIntoArray
1576 ext(output, "lppppv|writeListIntoArray");
1577 break;
1578 case 131:
1579 // TODO: Add support for copyArray
1580 ext(output, "ppppvppppv|copyArray");
1581 break;
1582 case 132:
1583 // TODO: Add support for math operations
1584 ext(output, "pppppppppppppvvv|mathOpsInArray");
1585 break;
1586 case 133:
1587 // TODO: Add support for writeRangeIntoArray
1588 ext(output, "ppppppv|writeRangeIntoArray");
1589 break;
1590 }
1591 break;
1592 case 0x05:
1593 se_a = pop();
1594 se_b = pop();
1595 push(se_oper(se_b, operBand, se_a));
1596 break;
1597 case 0x06:
1598 se_a = pop();
1599 se_b = pop();
1600 push(se_oper(se_b, operBor, se_a));
1601 break;
1602 case 0x07:
1603 ext(output, "|breakHere");
1604 break;
1605 case 0x08:
1606 ext(output, "p|delayFrames");
1607 break;
1608 case 0x09:
1609 ext(output, "rpp|shl");
1610 break;
1611 case 0x0A:
1612 ext(output, "rpp|shr");
1613 break;
1614 case 0x0B:
1615 ext(output, "rpp|xor");
1616 break;
1617 case 0x0C:
1618 ext(output, "p|setCameraAt");
1619 break;
1620 case 0x0D:
1621 ext(output, "p|actorFollowCamera");
1622 break;
1623 case 0x0E:
1624 ext(output, "p|loadRoom");
1625 break;
1626 case 0x0F:
1627 ext(output, "p|panCameraTo");
1628 break;
1629 case 0x10:
1630 ext(output, "ppppp|captureWizImage");
1631 break;
1632 case 0x11:
1633 ext(output, "lpi|jumpToScript");
1634 break;
1635 case 0x12:
1636 ext(output, "lp|setClass");
1637 break;
1638 case 0x13:
1639 ext(output, "p|closeFile");
1640 break;
1641 case 0x14:
1642 ext(output, "ppz|loadRoomWithEgo");
1643 break;
1644 case 0x16:
1645 ext(output, "h|createDirectory");
1646 break;
1647 case 0x17:
1648 ext(output, "x" "createSound\0"
1649 "\x0p|setId,"
1650 "\x35|reset,"
1651 "\x5C|dummy,"
1652 "\x80p|create");
1653 break;
1654 case 0x18:
1655 ext(output, "l|beginCutscene");
1656 break;
1657 case 0x19:
1658 case 0x53:
1659 kill(output, pop());
1660 break;
1661 case 0x1A:
1662 ext(output, "hp|traceStatus");
1663 break;
1664 case 0x1B:
1665 addVar(output, get_word(), -1);
1666 break;
1667 case 0x1C:
1668 addArray(output, get_word(), pop(), -1);
1669 break;
1670 case 0x1D:
1671 ext(output, "h|deleteFile");
1672 break;
1673 case 0x1E:
1674 ext(output, "x" "dim2dimArray\0"
1675 "\x29ppv|bit,"
1676 "\x2Appv|int,"
1677 "\x2Bppv|dword,"
1678 "\x2Cppv|nibble,"
1679 "\x2Dppv|byte,"
1680 "\x4Dppv|string");
1681 break;
1682 case 0x1F:
1683 ext(output, "x" "dimArray\0"
1684 "\x29pv|bit,"
1685 "\x2Apv|int,"
1686 "\x2Bpv|dword,"
1687 "\x2Cpv|nibble,"
1688 "\x2Dpv|byte,"
1689 "\x4Dpv|string,"
1690 "\x87v|nukeArray");
1691 break;
1692 case 0x20:
1693 se_a = pop();
1694 se_b = pop();
1695 push(se_oper(se_b, 9 + isEqual, se_a));
1696 break;
1697 case 0x21:
1698 ext(output, "pp|animateActor");
1699 break;
1700 case 0x22:
1701 ext(output, "pppp|doSentence");
1702 break;
1703 case 0x23:
1704 ext(output, "ppppp|drawBox");
1705 break;
1706 case 0x24:
1707 ext(output, "pppp|drawWizImage");
1708 break;
1709 case 0x25:
1710 ext(output, "pp|drawWizPolygon");
1711 break;
1712 case 0x26:
1713 ext(output, "x" "drawLine\0"
1714 "\x1pppppp|pixel,"
1715 "\x14pppppp|wizImage,"
1716 "\x28pppppp|actor");
1717 break;
1718 case 0x27:
1719 ext(output, "x" "drawObject\0"
1720 "\x6ppp|setPosition,"
1721 "\x7pppp|setup,"
1722 "\x28pp|setState");
1723 break;
1724 case 0x28:
1725 se_a = dup(output, pop());
1726 push(se_a);
1727 push(se_a);
1728 break;
1729 case 0x29:
1730 dup_n();
1731 break;
1732 case 0x2A:
1733 ext(output, "|endCutscene");
1734 break;
1735 case 0x2B:
1736 ext(output, "|stopObjectCodeA");
1737 break;
1738 case 0x2C:
1739 ext(output, "|stopObjectCodeB");
1740 break;
1741 case 0x2D:
1742 se_a = pop();
1743 se_b = pop();
1744 push(se_oper(se_b, 0 + isEqual, se_a));
1745 break;
1746 case 0x2E:
1747 ext(output, "x" "floodFill\0"
1748 "\x0p|reset,"
1749 "\x6pp|setXY,"
1750 "\x12pppp|setBoxRect,"
1751 "\x14p|setFlags,"
1752 "\x36|dummy,"
1753 "\x5C|floodFill");
1754 break;
1755 case 0x2F:
1756 ext(output, "p|freezeUnfreeze");
1757 break;
1758 case 0x30:
1759 se_a = pop();
1760 se_b = pop();
1761 push(se_oper(se_b, 5 + isEqual, se_a));
1762 break;
1763 case 0x31:
1764 ext(output, "|getDateTime");
1765 break;
1766 case 0x32:
1767 ext(output, "x" "setSpriteGroupInfo\0"
1768 "\x0p|setId,"
1769 "\x6pp|setPosition,"
1770 "\x12pppp|setBounds,"
1771 "\x26pp|misc,"
1772 "\x28p|setImage,"
1773 "\x31pp|move,"
1774 "\x34h|stringUnk,"
1775 "\x35|reset,"
1776 "\x36pp|dummy,"
1777 "\x3Bp|setPriority,"
1778 "\x3Cpp|setXYScale?,"
1779 "\x59|resetBounds");
1780 break;
1781 case 0x33:
1782 se_a = pop();
1783 se_b = pop();
1784 push(se_oper(se_b, 2 + isEqual, se_a));
1785 break;
1786 case 0x34:
1787 ext(output, "x" "resourceRoutines\0"
1788 "\xEp|setCharset,"
1789 "\x19p|setCostume,"
1790 "\x22p|setFlObject,"
1791 "\x28p|setImage,"
1792 "\x2F|loadResource,"
1793 "\x3Ep|setRoom,"
1794 "\x42p|setScript,"
1795 "\x48p|setSound,"
1796 "\x80|clearHeap,"
1797 "\x81|dummy,"
1798 "\x84|lockResource,"
1799 "\x85|nukeResource,"
1800 "\x86|setOffHeapOn,"
1801 "\x87|setOffHeapOff,"
1802 "\x88|queueResource,"
1803 "\x89|unlock");
1804 break;
1805 case 0x35:
1806 jumpif(output, pop(), true);
1807 break;
1808 case 0x36:
1809 jumpif(output, pop(), false);
1810 break;
1811 case 0x37:
1812 ext(output, "x" "wizImageOps\0"
1813 "\x0p|setImage,"
1814 "\x6pp|setPosition,"
1815 "\x7p|setSourceImage,"
1816 "\xBppppp|setCaptureRect,"
1817 "\x12pppp|setClipRect,"
1818 "\x15p|remapWizImagePal,"
1819 "\x1D|processMode1,"
1820 "\x24pppp|setRect,"
1821 "\x27p|setResDefImageHeight,"
1822 "\x2Fh|readFile,"
1823 "\x35|createWizImage,"
1824 "\x36pp|setThickLine,"
1825 "\x37ppppp|drawWizImage,"
1826 "\x39p|setPalette,"
1827 "\x3Appp|capturePolygon,"
1828 "\x40hp|writeFile,"
1829 "\x41p|setScale,"
1830 "\x43p|setFlags,"
1831 "\x44p|setupPolygon,"
1832 "\x46p|setShadow,"
1833 "\x49p|setImageState,"
1834 "\x54p|setResDefImageWidth,"
1835 "\x5C|processWizImage,"
1836 "\x80pppph|createFont,"
1837 "\x81|endFont,"
1838 "\x82pph|renderFontString,"
1839 "\x83|startFont,"
1840 "\x84pp|setPosition,"
1841 "\x85pppppppp|ellipse,"
1842 "\x86ppp|fillWizFlood,"
1843 "\x87p|setDstResNum,"
1844 "\x88ppppp|fillWizLine,"
1845 "\x89ppp|fillWizPixel,"
1846 "\x8Appppp|fillWizRect");
1847 break;
1848 case 0x38:
1849 ext(output, "rlp|isAnyOf2");
1850 break;
1851 case 0x39:
1852 addVar(output, get_word(), 1);
1853 break;
1854 case 0x3A:
1855 addArray(output, get_word(), pop(), 1);
1856 break;
1857 case 0x3B:
1858 jump(output);
1859 break;
1860 case 0x3C:
1861 ext(output, "y" "kernelSetFunctions\0"
1862 "\x1|virtScreenLoad,"
1863 "\x14|queueAuxBlock,"
1864 "\x15|pauseDrawObjects,"
1865 "\x16|resumeDrawObjects,"
1866 "\x17|clearCharsetMask,"
1867 "\x18|pauseActors,"
1868 "\x19|resumActors,"
1869 "\x1E|actorBottomClipOverride,"
1870 "\x2A|setWizImageClip,"
1871 "\x2B|setWizImageClipOff");
1872 break;
1873 case 0x3D:
1874 se_a = pop();
1875 se_b = pop();
1876 push(se_oper(se_b, 0xA + isEqual, se_a));
1877 break;
1878 case 0x3E:
1879 se_a = pop();
1880 se_b = pop();
1881 push(se_oper(se_b, 4 + isEqual, se_a));
1882 break;
1883 case 0x3F:
1884 ext(output, "p|localizeArrayToScript");
1885 break;
1886 case 0x40:
1887 push(se_array(get_word(), NULL, pop()));
1888 break;
1889 case 0x41:
1890 se_a = pop();
1891 push(se_array(get_word(), pop(), se_a));
1892 break;
1893 case 0x42:
1894 se_a = pop();
1895 se_b = pop();
1896 push(se_oper(se_b, 0xB + isEqual, se_a));
1897 break;
1898 case 0x43:
1899 se_a = pop();
1900 se_b = pop();
1901 push(se_oper(se_b, 3 + isEqual, se_a));
1902 break;
1903 case 0x44:
1904 ext(output, "rpp|mod");
1905 break;
1906 case 0x45:
1907 se_a = pop();
1908 se_b = pop();
1909 push(se_oper(se_b, 8 + isEqual, se_a));
1910 break;
1911 case 0x46:
1912 se_a = pop();
1913 se_b = pop();
1914 push(se_oper(se_b, 1 + isEqual, se_a));
1915 break;
1916 case 0x47:
1917 ext(output, "x" "dim2dim2Array\0"
1918 "\x29pppppv|bit,"
1919 "\x2Apppppv|int,"
1920 "\x2Bpppppv|dword,"
1921 "\x2Cpppppv|nibble,"
1922 "\x2Dpppppv|byte,"
1923 "\x4Dpppppv|string");
1924 break;
1925 case 0x49:
1926 ext(output, "x" "redim2dimArray\0"
1927 "\x2Appppv|int,"
1928 "\x2Bppppv|dword,"
1929 "\x2Dppppv|byte");
1930 break;
1931 case 0x4A:
1932 push(se_oper(pop(), isZero));
1933 break;
1934 case 0x4C:
1935 ext(output, "|beginOverride");
1936 break;
1937 case 0x4D:
1938 ext(output, "|endOverride");
1939 break;
1940 case 0x4E:
1941 ext(output, "|resetCutScene");
1942 break;
1943 case 0x4F:
1944 ext(output, "pp|setOwner");
1945 break;
1946 case 0x50:
1947 ext(output, "x" "paletteOps\0"
1948 "\x0p|setPaletteNum,"
1949 "\x14ppppp|setPaletteColor,"
1950 "\x19p|setPaletteFromCostume,"
1951 "\x28pp|setPaletteFromImage,"
1952 "\x35|restorePalette,"
1953 "\x39p|copyPalette,"
1954 "\x3Fpp|setPaletteFromRoom,"
1955 "\x51ppp|copyPaletteColor,"
1956 "\x5C|resetPaletteNum");
1957 break;
1958 case 0x51:
1959 ext(output, "z|pickupObject");
1960 break;
1961 case 0x52:
1962 ext(output, "x" "polygonOps\0"
1963 "\x1Cpp|polygonErase,"
1964 "\x44ppppppppp|polygonStore,"
1965 "\x45ppppppppp|polygonStore");
1966 break;
1967 case 0x54:
1968 PRINT_V100HE("printDebug");
1969 break;
1970 case 0x55:
1971 ext(output, "p|printWizImage");
1972 break;
1973 case 0x56:
1974 PRINT_V100HE("printLine");
1975 break;
1976 case 0x57:
1977 PRINT_V100HE("printSystem");
1978 break;
1979 case 0x58:
1980 PRINT_V100HE("printCursor");
1981 break;
1982 case 0x59:
1983 ext(output, "lppi|jumpToScriptUnk");
1984 break;
1985 case 0x5A:
1986 ext(output, "lppi|startScriptUnk");
1987 break;
1988 case 0x5B:
1989 ext(output, "lp|pseudoRoom");
1990 break;
1991 case 0x5C:
1992 push(se_int(get_byte()));
1993 break;
1994 case 0x5D:
1995 push(se_int(get_dword()));
1996 break;
1997 case 0x5E:
1998 getScriptString();
1999 break;
2000 case 0x5F:
2001 push(se_int(get_word()));
2002 break;
2003 case 0x60:
2004 push(se_var(get_word()));
2005 break;
2006 case 0x61:
2007 ext(output, "zp|putActorAtObject");
2008 break;
2009 case 0x62:
2010 ext(output, "pppp|putActorInXY");
2011 break;
2012 case 0x64:
2013 ext(output, "x" "redimArray\0"
2014 "\x2Appv|int,"
2015 "\x2Bppv|dword,"
2016 "\x2Dppv|byte");
2017 break;
2018 case 0x65:
2019 ext(output, "hh|renameFile");
2020 break;
2021 case 0x66:
2022 ext(output, "|stopObjectCode");
2023 break;
2024 case 0x67:
2025 ext(output, "p|localizeArrayToRoom");
2026 break;
2027 case 0x68:
2028 ext(output, "x" "roomOps\0"
2029 "\x3Fpppp|setPalColor,"
2030 "\x81pp|swapObjects,"
2031 "\x82pp|copyPalColor,"
2032 "\x83p|screenEffect,"
2033 "\x84ppp|darkenPalette,"
2034 "\x85ppppp|darkenPalette,"
2035 "\x86p|setPalette,"
2036 "\x87pp|setRoomPalette,"
2037 "\x88pp|saveLoadRoom,"
2038 "\x89hp|saveOrLoad,"
2039 "\x8App|setScreen,"
2040 "\x8Bpp|roomScroll");
2041 break;
2042 case 0x69:
2043 // This is *almost* identical to the other print opcodes, only the 'begine' subop differs
2044 ext(output, "x" "printActor\0"
2045 "\x6pp|XY,"
2046 "\xC|center,"
2047 "\x12p|right,"
2048 "\x14p|color,"
2049 "\x15l|colors,"
2050 "\x2E|left,"
2051 "\x33|mumble,"
2052 "\x38|overhead,"
2053 "\x4Ep|getText,"
2054 "\x4Fs|msg,"
2055 "\x5Bp|begin,"
2056 "\x5C|end");
2057 break;
2058 case 0x6A:
2059 PRINT_V100HE("printEgo");
2060 break;
2061 case 0x6B:
2062 ext(output, "ps|talkActor");
2063 break;
2064 case 0x6C:
2065 ext(output, "s|talkEgo");
2066 break;
2067 case 0x6E:
2068 ext(output, "ppp|seekFilePos");
2069 break;
2070 case 0x6F:
2071 ext(output, "pl|setBoxFlags");
2072 break;
2073 case 0x71:
2074 ext(output, "p|setBotSet");
2075 break;
2076 case 0x72:
2077 ext(output, "x" "setSystemMessage\0"
2078 "\x50h|titleMsg,"
2079 "\x83h|versionMsg");
2080 break;
2081 case 0x73:
2082 ext(output, "wpp|shuffle");
2083 break;
2084 case 0x74:
2085 ext(output, "p|delay");
2086 break;
2087 case 0x75:
2088 ext(output, "p|delayMinutes");
2089 break;
2090 case 0x76:
2091 ext(output, "p|delaySeconds");
2092 break;
2093 case 0x77:
2094 ext(output, "x" "soundOps\0"
2095 "\x6p|setOffset,"
2096 "\x2Fhp|loadSoundFromFile,"
2097 "\x37|setQuickStart,"
2098 "\x53ppp|setSoundVar,"
2099 "\x5C|start,"
2100 "\x80|setAppend,"
2101 "\x81p|setChannel,"
2102 "\x82p|setFrequency,"
2103 "\x83|setLoop,"
2104 "\x84p|setMusicId,"
2105 "\x85p|setPan,"
2106 "\x86p|setSoundId,"
2107 "\x87|setSoftSound,"
2108 "\x88p|setVolume");
2109 break;
2110 case 0x79:
2111 ext(output, "x" "setSpriteInfo\0"
2112 "\x0pp|setRange,"
2113 "\x2p|setAngle,"
2114 "\x3p|setAutoAnimFlag,"
2115 "\x4p|setAnimSpeed,"
2116 "\x6pp|setPosition,"
2117 "\x7p|setSourceImage,"
2118 "\x10l|setClass,"
2119 "\x20p|setEraseType,"
2120 "\x26p|setGroup,"
2121 "\x28p|setImage,"
2122 "\x30p|setMaskImage,"
2123 "\x31pp|move,"
2124 "\x34|stringUnk,"
2125 "\x35|resetSprite,"
2126 "\x36pp|setGeneralProperty,"
2127 "\x39p|setPalette,"
2128 "\x3Bp|setPriority,"
2129 "\x3Cpp|setFlags,"
2130 "\x3D|resetTables,"
2131 "\x41p|setScale,"
2132 "\x46p|setAutoShadow,"
2133 "\x49p|setImageState,"
2134 "\x4App|setDist,"
2135 "\x4Bp|setDistX,"
2136 "\x4Cp|setDistY,"
2137 "\x52p|setUpdateType,"
2138 "\x53pp|setUserValue,"
2139 "\x58p|setField84,"
2140 "\x59|clearField84");
2141 break;
2142 case 0x7A:
2143 ext(output, "pppp|stampObject");
2144 break;
2145 case 0x7B:
2146 ext(output, "lppi|startObject");
2147 break;
2148 case 0x7C:
2149 ext(output, "lpi|startScript");
2150 break;
2151 case 0x7D:
2152 ext(output, "lp|startScriptQuick");
2153 break;
2154 case 0x7E:
2155 ext(output, "pp|setState");
2156 break;
2157 case 0x7F:
2158 ext(output, "p|stopObjectScript");
2159 break;
2160 case 0x80:
2161 ext(output, "p|stopScript");
2162 break;
2163 case 0x81:
2164 ext(output, "|stopSentence");
2165 break;
2166 case 0x82:
2167 ext(output, "p|stopSound");
2168 break;
2169 case 0x83:
2170 ext(output, "|stopTalking");
2171 break;
2172 case 0x84:
2173 writeVar(output, get_word(), pop());
2174 break;
2175 case 0x85:
2176 se_a = pop();
2177 writeArray(output, get_word(), NULL, pop(), se_a);
2178 break;
2179 case 0x86:
2180 se_a = pop();
2181 se_b = pop();
2182 writeArray(output, get_word(), pop(), se_b, se_a);
2183 break;
2184 case 0x87:
2185 se_a = pop();
2186 se_b = pop();
2187 push(se_oper(se_b, 7 + isEqual, se_a));
2188 break;
2189 case 0x88:
2190 ext(output, "x" "systemOps\0"
2191 "\x3D|restart,"
2192 "\x80|clearDrawQueue,"
2193 "\x84|confirmShutDown,"
2194 "\x85|shutDown,"
2195 "\x86|startGame,"
2196 "\x87|startExec,"
2197 "\x88|copyVirtBuf");
2198 break;
2199 case 0x89:
2200 ext(output, "x" "windowOps\0"
2201 "\x0p|case0,"
2202 "\x6pp|case6,"
2203 "\x11p|case17,"
2204 "\x27p|case39,"
2205 "\x28p|case40,"
2206 "\x31pp|case49,"
2207 "\x35|case53,"
2208 "\x42p|case66,"
2209 "\x43p|case67,"
2210 "\x47p|case71,"
2211 "\x50h|case80,"
2212 "\x54p|case84,"
2213 "\x5C|case92");
2214 break;
2215 case 0x8A:
2216 ext(output, "pi|setTimer");
2217 break;
2218 case 0x8B:
2219 ext(output, "x" "cursorCommand\0"
2220 "\xEp|initCharset,"
2221 "\xFl|charsetColors,"
2222 "\x80z|setCursorImg,"
2223 "\x81z|setCursorImg,"
2224 "\x82zp|setCursorImgWithPal,"
2225 "\x86|cursorOn,"
2226 "\x87|cursorOff,"
2227 "\x88|softCursorOn,"
2228 "\x89|softCursorOff,"
2229 "\x8B|userPutOn,"
2230 "\x8C|userPutOff,"
2231 "\x8D|softUserputOn,"
2232 "\x8E|softUserputOff");
2233
2234 break;
2235 case 0x8C:
2236 ext(output, "x" "videoOps\0"
2237 "\x0p|setUnk2,"
2238 "\x13|setStatus,"
2239 "\x28p|setWizResNumX,"
2240 "\x2Fh|setFilename,"
2241 "\x43p|setFlags,"
2242 "\x5C|playOrStopVideo,");
2243 break;
2244 case 0x8D:
2245 ext(output, "x" "wait\0"
2246 "\x80pj|waitForActor,"
2247 "\x81|waitForCamera,"
2248 "\x82|waitForMessage,"
2249 "\x83|waitForSentence");
2250 break;
2251 case 0x8E:
2252 ext(output, "ppp|walkActorToObj");
2253 break;
2254 case 0x8F:
2255 ext(output, "ppp|walkActorTo");
2256 break;
2257 case 0x90:
2258 ext(output, "x" "writeFile\0"
2259 "\x5ppi|writeArrayToFile,"
2260 "\x2App|writeWord,"
2261 "\x2Bpp|writeDWord,"
2262 "\x2Dpp|writeByte");
2263 break;
2264 case 0x91:
2265 ext(output, "x" "writeINI\0"
2266 "\x2Bph|number,"
2267 "\x4Dhh|string");
2268 break;
2269 case 0x92:
2270 ext(output, "x" "writeConfigFile\0"
2271 "\x2Bphhh|number,"
2272 "\x4Dhhhh|string");
2273 break;
2274 case 0x93:
2275 ext(output, "rp|abs");
2276 break;
2277 case 0x94:
2278 ext(output, "rp|getActorWalkBox");
2279 break;
2280 case 0x95:
2281 ext(output, "rp|getActorCostume");
2282 break;
2283 case 0x96:
2284 ext(output, "rp|getActorElevation");
2285 break;
2286 case 0x97:
2287 ext(output, "rp|getObjectDir");
2288 break;
2289 case 0x98:
2290 ext(output, "rp|getActorMoving");
2291 break;
2292 case 0x99:
2293 ext(output, "rppp|getActorData");
2294 break;
2295 case 0x9A:
2296 ext(output, "rp|getActorRoom");
2297 break;
2298 case 0x9B:
2299 ext(output, "rp|getActorScaleX");
2300 break;
2301 case 0x9C:
2302 ext(output, "rpp|getAnimateVariable");
2303 break;
2304 case 0x9D:
2305 ext(output, "rp|getActorWidth");
2306 break;
2307 case 0x9E:
2308 ext(output, "rp|objectX");
2309 break;
2310 case 0x9F:
2311 ext(output, "rp|objectY");
2312 break;
2313 case 0xA0:
2314 ext(output, "rpp|atan2");
2315 break;
2316 case 0xA1:
2317 ext(output, "rpppp|getSegmentAngle");
2318 break;
2319 case 0xA2:
2320 ext(output, "rp|getActorAnimProgress");
2321 break;
2322 case 0xA3:
2323 ext(output, "rx" "getDistanceBetweenPoints\0"
2324 "\x17pppp|case17,"
2325 "\x18pppppp|case18");
2326 break;
2327 case 0xA4:
2328 ext(output, "rlp|ifClassOfIs");
2329 break;
2330 case 0xA6:
2331 ext(output, "rppp|cond");
2332 break;
2333 case 0xA7:
2334 ext(output, "rp|cos");
2335 break;
2336 case 0xA8:
2337 // Backyard Baseball 2003 / Basketball / Football 2002
2338 if (g_options.heVersion == 101) {
2339 ext(output, "rh|debugInput");
2340 } else {
2341 // All other games
2342 switch (get_byte()) {
2343 case 0:
2344 ext(output, "h|debugInput: case 0");
2345 break;
2346 case 26:
2347 ext(output, "p|debugInput: case 26");
2348 break;
2349 case 27:
2350 ext(output, "h|debugInput: case 27");
2351 break;
2352 case 80:
2353 ext(output, "h|debugInput: case 80");
2354 break;
2355 case 92:
2356 ext(output, "r|debugInput: case 92");
2357 break;
2358 }
2359 }
2360 break;
2361 case 0xA9:
2362 ext(output, "rh|getFileSize");
2363 break;
2364 case 0xAA:
2365 ext(output, "rpp|getActorFromXY");
2366 break;
2367 case 0xAB:
2368 ext(output, "rp|findAllObjects");
2369 break;
2370 case 0xAC:
2371 ext(output, "rlp|findAllObjectsWithClassOf");
2372 break;
2373
2374 case 0xAE:
2375 ext(output, "rpp|findInventory");
2376 break;
2377 case 0xAF:
2378 ext(output, "rpp|findObject");
2379 break;
2380 case 0xB0:
2381 ext(output, "rlpp|findObjectWithClassOf");
2382 break;
2383 case 0xB1:
2384 ext(output, "rpp|polygonHit");
2385 break;
2386 case 0xB2:
2387 ext(output, "rwwpppppppp|getLinesIntersectionPoint");
2388 break;
2389 case 0xB3:
2390 ext(output, "rx" "fontUnk\0"
2391 "\x0|case0,"
2392 "\x3Cpp|case60");
2393 break;
2394 case 0xB4:
2395 ext(output, "r|getNumFreeArrays");
2396 break;
2397 case 0xB5:
2398 ext(output, "rx" "getArrayDimSize\0"
2399 "\x1v|dim1size,"
2400 "\x2v|dim2size,"
2401 "\x3v|dim1size,"
2402 "\x4v|dim1start,"
2403 "\x5v|dim1end,"
2404 "\x6v|dim2start,"
2405 "\x7v|dim2end");
2406 break;
2407 case 0xB6:
2408 ext(output, "rx" "isResourceLoaded\0"
2409 "\x19p|costume,"
2410 "\x28p|image,"
2411 "\x3Ep|room,"
2412 "\x42p|script,"
2413 "\x48p|sound");
2414 break;
2415 case 0xB7:
2416 ext(output, "rx" "getResourceSize\0"
2417 "\x19p|costume,"
2418 "\x28p|image,"
2419 "\x3Ep|roomImage,"
2420 "\x42p|script,"
2421 "\x48p|sound");
2422 break;
2423 case 0xB8:
2424 ext(output, "rx" "getSpriteGroupInfo\0"
2425 "\x5p|getSpriteArray,"
2426 "\x28p|getDstResNum,"
2427 "\x36pp|dummy,"
2428 "\x3Bp|getPriority,"
2429 "\x3Cpp|getXYScale?,"
2430 "\x55p|getPositionX,"
2431 "\x56p|getPositionY");
2432 break;
2433 case 0xB9:
2434 ext(output, "rx" "getHeap\0"
2435 "\x82|freeSpace,"
2436 "\x83|largestBlockSize");
2437 break;
2438 case 0xBA:
2439 ext(output, "rx" "getWizData\0"
2440 "\x14pppp|pixelColor,"
2441 "\x1Ap|imageCount,"
2442 "\x21pppp|isPixelNonTransparentnumber,"
2443 "\x27pp|height,"
2444 "\x36ppp|block,"
2445 "\x54pp|width,"
2446 "\x55pp|imageSpotX,"
2447 "\x56pp|imageSpotY,"
2448 "\x83php|case131,"
2449 "\x84pppppp|histogram");
2450 break;
2451 case 0xBB:
2452 ext(output, "rpp|isActorInBox");
2453 break;
2454 case 0xBC:
2455 ext(output, "rlp|isAnyOf");
2456 break;
2457 case 0xBD:
2458 ext(output, "rp|getInventoryCount");
2459 break;
2460 case 0xBE:
2461 ext(output, "ry" "kernelGetFunctions\0"
2462 "\x1|virtScreenSave"
2463 );
2464 break;
2465 case 0xBF:
2466 ext(output, "rpp|max");
2467 break;
2468 case 0xC0:
2469 ext(output, "rpp|min");
2470 break;
2471 case 0xC1:
2472 ext(output, "rp|getObjectX");
2473 break;
2474 case 0xC2:
2475 ext(output, "rp|getObjectY");
2476 break;
2477 case 0xC3:
2478 ext(output, "rp|isRoomScriptRunning");
2479 break;
2480 case 0xC4:
2481 ext(output, "rx" "getObjectData\0"
2482 "\x20|getWidth,"
2483 "\x21|getHeight,"
2484 "\x24|getImageCount,"
2485 "\x26|getX,"
2486 "\x27|getY,"
2487 "\x34|getState,"
2488 "\x39p|setId,"
2489 "\x8Bp|dummy");
2490 break;
2491 case 0xC5:
2492 ext(output, "rph|openFile");
2493 break;
2494 case 0xC6:
2495 ext(output, "rllp|getPolygonOverlap");
2496 break;
2497 case 0xC7:
2498 ext(output, "rp|getOwner");
2499 break;
2500 case 0xC8:
2501 ext(output, "rx" "getPaletteData\0"
2502 "\xDpp|get16BitColorComponent,"
2503 "\x14pp|getColor,"
2504 "\x21pppppp|getSimilarColor,"
2505 "\x35ppp|get16BitColor,"
2506 "\x49ppp|getColorCompontent");
2507 break;
2508 case 0xC9:
2509 ext(output, "rlp|pickOneOf");
2510 break;
2511 case 0xCA:
2512 ext(output, "rplp|pickOneOfDefault");
2513 break;
2514 case 0xCB:
2515 ext(output, "rlw|pickVarRandom");
2516 break;
2517 case 0xCC:
2518 ext(output, "rx" "getPixel\0"
2519 "\x8pp|foreground,"
2520 "\x9pp|background");
2521 break;
2522 case 0xCD:
2523 ext(output, "rpp|getDistObjObj");
2524 break;
2525 case 0xCE:
2526 ext(output, "rppp|getDistObjPt");
2527 break;
2528 case 0xCF:
2529 ext(output, "rpppp|getDistPtPt");
2530 break;
2531 case 0xD0:
2532 ext(output, "rp|getRandomNumber");
2533 break;
2534 case 0xD1:
2535 ext(output, "rpp|getRandomNumberRange");
2536 break;
2537 case 0xD3:
2538 ext(output, "rx" "readFile\0"
2539 "\x5ppi|readArrayFromFile,"
2540 "\x2Ap|readWord,"
2541 "\x2Bp|readDWord,"
2542 "\x2Dp|readByte");
2543 break;
2544 case 0xD4:
2545 ext(output, "rx" "readINI\0"
2546 "\x2Bh|number,"
2547 "\x4Dh|string");
2548 break;
2549 case 0xD5:
2550 ext(output, "rx" "readConfigFile\0"
2551 "\x2Bhhh|number,"
2552 "\x4Dhhh|string");
2553 break;
2554 case 0xD6:
2555 ext(output, "rp|isScriptRunning");
2556 break;
2557 case 0xD7:
2558 ext(output, "rp|sin");
2559 break;
2560 case 0xD8:
2561 ext(output, "rp|getSoundPosition");
2562 break;
2563 case 0xD9:
2564 ext(output, "rp|isSoundRunning");
2565 break;
2566 case 0xDA:
2567 ext(output, "rpp|getSoundVar");
2568 break;
2569 case 0xDB:
2570 ext(output, "rx" "getSpriteInfo\0"
2571 "\x3p|getFlagAutoAnim,"
2572 "\x4p|getAnimSpeed,"
2573 "\x7p|getSourceImage,"
2574 "\x10lp|getClass,"
2575 "\x1Ap|getImageStateCount,"
2576 "\x1Ep|getDisplayX,"
2577 "\x1Fp|getDisplayY,"
2578 "\x20p|getEraseType,"
2579 "\x21lpppp|findSprite,"
2580 "\x26p|getGroup,"
2581 "\x27p|getImageY,"
2582 "\x28p|getImage,"
2583 "\x30p|getMaskImage,"
2584 "\x36pp|getGeneralProperty,"
2585 "\x39p|getPalette,"
2586 "\x3Bp|getPriority,"
2587 "\x3Cpp|getFlags,"
2588 "\x41p|getScale,"
2589 "\x46p|getShadow,"
2590 "\x49p|getImageState,"
2591 "\x4Bp|getDistX,"
2592 "\x4Cp|getDistY,"
2593 "\x52p|getUpdateType,"
2594 "\x53pp|getUserValue,"
2595 "\x54p|getImageX,"
2596 "\x55p|getPosX,"
2597 "\x56p|getPosY");
2598 break;
2599 case 0xDC:
2600 ext(output, "rp|sqrt");
2601 break;
2602 case 0xDD:
2603 // TODO: this loads another script which does something like
2604 // stack altering and then finishes (usually with opcode 0xBD).
2605 // When stack is changed, further disassembly is wrong.
2606 // This is widely used in HE games.
2607 // As there are cases when called script does not alter the
2608 // stack, it's not correct to use "rlpp|..." here
2609 ext(output, "lpp|startObjectQuick");
2610 break;
2611 case 0xDE:
2612 ext(output, "lp|startScriptQuick2");
2613 break;
2614 case 0xDF:
2615 ext(output, "rp|getState");
2616 break;
2617 case 0xE0:
2618 ext(output, "rpp|compareString");
2619 break;
2620 case 0xE1:
2621 ext(output, "rp|copyString");
2622 break;
2623 case 0xE2:
2624 ext(output, "rppp|appendString");
2625 break;
2626 case 0xE3:
2627 ext(output, "rpp|concatString");
2628 break;
2629 case 0xE4:
2630 ext(output, "rp|getStringLen");
2631 break;
2632 case 0xE5:
2633 ext(output, "rppp|getStringLenForWidth");
2634 break;
2635 case 0xE6:
2636 ext(output, "rp|stringToInt");
2637 break;
2638 case 0xE7:
2639 ext(output, "rpppp|getCharIndexInString");
2640 break;
2641 case 0xE8:
2642 ext(output, "rppp|getStringWidth");
2643 break;
2644 case 0xE9:
2645 ext(output, "rp|readFilePos");
2646 break;
2647 case 0xEA:
2648 ext(output, "ri|getTimer");
2649 break;
2650 case 0xEB:
2651 ext(output, "rpp|getVerbEntrypoint");
2652 break;
2653 case 0xEC:
2654 ext(output, "rx" "getVideoData\0"
2655 "\x1Ap|frameCount,"
2656 "\x27p|height,"
2657 "\x28p|imageNum,"
2658 "\x36pp|statistics,"
2659 "\x49p|curFrame,"
2660 "\x54p|width");
2661 break;
2662 default:
2663 invalidop(NULL, code);
2664 break;
2665 }
2666 }
2667
2668 #define PRINT_V7HE(name) \
2669 do { \
2670 ext(output, "x" name "\0" \
2671 "\x41pp|XY," \
2672 "\x42p|color," \
2673 "\x43p|right," \
2674 "\x45|center," \
2675 "\x47|left," \
2676 "\x48|overhead," \
2677 "\x4A|mumble," \
2678 "\x4Bs|msg," \
2679 "\xF9l|colors," \
2680 "\xC2lps|debug," \
2681 "\xE1p|getText," \
2682 "\xFE|begin," \
2683 "\xFF|end" \
2684 ); \
2685 } while(0)
2686
next_line_HE_V72(char * output)2687 void next_line_HE_V72(char *output) {
2688 byte code = get_byte();
2689 StackEnt *se_a, *se_b;
2690
2691 switch (code) {
2692 case 0x0:
2693 push(se_int(get_byte()));
2694 break;
2695 case 0x1:
2696 push(se_int(get_word()));
2697 break;
2698 case 0x2:
2699 push(se_int(get_dword()));
2700 break;
2701 case 0x3:
2702 push(se_var(get_word()));
2703 break;
2704 case 0x4:
2705 getScriptString();
2706 break;
2707 case 0x7:
2708 push(se_array(get_word(), NULL, pop()));
2709 break;
2710 case 0xA: // HE90+
2711 dup_n();
2712 break;
2713 case 0xB:
2714 se_a = pop();
2715 push(se_array(get_word(), pop(), se_a));
2716 break;
2717 case 0xC:
2718 se_a = dup(output, pop());
2719 push(se_a);
2720 push(se_a);
2721 break;
2722 case 0xD:
2723 push(se_oper(pop(), isZero));
2724 break;
2725 case 0xE:
2726 case 0xF:
2727 case 0x10:
2728 case 0x11:
2729 case 0x12:
2730 case 0x13:
2731 case 0x14:
2732 case 0x15:
2733 case 0x16:
2734 case 0x17:
2735 case 0x18:
2736 case 0x19:
2737 se_a = pop();
2738 se_b = pop();
2739 push(se_oper(se_b, (code - 0xE) + isEqual, se_a));
2740 break;
2741 case 0x1A:
2742 case 0xA7:
2743 kill(output, pop());
2744 break;
2745 case 0x1B:
2746 ext(output, "rlp|isAnyOf2");
2747 break;
2748 case 0x1C: // HE90+
2749 ext(output, "x" "wizImageOps\0"
2750 "\x20p|setResDefImageWidth,"
2751 "\x21p|setResDefImageHeight,"
2752 "\x30|processMode1,"
2753 "\x31h|readFile,"
2754 "\x32hp|writeFile,"
2755 "\x33ppppp|setCaptureRect,"
2756 "\x34p|setImageState,"
2757 "\x35p|setAngle,"
2758 "\x36p|setFlags,"
2759 "\x38ppppp|drawWizImage,"
2760 "\x39p|setImage,"
2761 "\x3Ep|setSourceImage,"
2762 "\x41pp|setPosition,"
2763 "\x42pp|remapPalette,"
2764 "\x43pppp|setClipRect,"
2765 "\x56p|setPalette,"
2766 "\x5Cp|setScale,"
2767 "\x62p|setShadow,"
2768 "\x83ppp|capturePolygon,"
2769 "\x85ppppp|fillWizRect,"
2770 "\x86ppppp|fillWizLine,"
2771 "\x87ppp|fillWizPixel,"
2772 "\x88ppp|fillWizFlood,"
2773 "\x89p|setDstResNum,"
2774 "\x8Bpp|setThickLine,"
2775 "\x8D|startFont,"
2776 "\x8Epppph|createFont,"
2777 "\x8Fpph|renderFontString,"
2778 "\x9App|setPosition,"
2779 "\xBDpppppppp|ellipse,"
2780 "\xC4|endFont,"
2781 "\xD9|createWizImage,"
2782 "\xF6p|setupPolygon,"
2783 "\xF9pp|remapPalette,"
2784 "\xFF|processWizImage");
2785 break;
2786 case 0x1D: // HE90+
2787 ext(output, "rpp|min");
2788 break;
2789 case 0x1E: // HE90+
2790 ext(output, "rpp|max");
2791 break;
2792 case 0x1F: // HE90+
2793 ext(output, "rp|sin");
2794 break;
2795 case 0x20: // HE90+
2796 ext(output, "rp|cos");
2797 break;
2798 case 0x21: // HE90+
2799 ext(output, "rp|sqrt");
2800 break;
2801 case 0x22: // HE90+
2802 ext(output, "rpp|atan2");
2803 break;
2804 case 0x23: // HE90+
2805 ext(output, "rpppp|getSegmentAngle");
2806 break;
2807 case 0x24: // HE90+
2808 ext(output, "rx" "getDistanceBetweenPoints\0"
2809 "\x1Cpppp|case28,"
2810 "\x1Dpppppp|case29");
2811 break;
2812 case 0x25: // HE90+
2813 if (g_options.heVersion >= 99) {
2814 ext(output, "rx" "getSpriteInfo\0"
2815 "\x1Ep|getPosX,"
2816 "\x1Fp|getPosY,"
2817 "\x20p|getImageX,"
2818 "\x21p|getImageY,"
2819 "\x22p|getDistX,"
2820 "\x23p|getDistY,"
2821 "\x24p|getImageStateCount,"
2822 "\x25p|getGroup,"
2823 "\x26p|getDisplayX,"
2824 "\x27p|getDisplayY,"
2825 "\x2App|getFlags,"
2826 "\x2Bp|getPriority,"
2827 "\x2Dlpppp|findSprite,"
2828 "\x34p|getImageState,"
2829 "\x3Ep|getSourceImage,"
2830 "\x3Fp|getImage,"
2831 "\x44p|getEraseType,"
2832 "\x52p|getFlagAutoAnim,"
2833 "\x56p|getPalette,"
2834 "\x5Cp|getScale,"
2835 "\x61p|getAnimSpeed,"
2836 "\x62p|getShadow,"
2837 "\x7Cp|getUpdateType,"
2838 "\x7Dlp|getClass,"
2839 "\x8Bpp|getGeneralProperty,"
2840 "\x8Cp|getMaskImage,"
2841 "\xC6pp|getUserValue");
2842 } else if (g_options.heVersion >= 98) {
2843 ext(output, "rx" "getSpriteInfo\0"
2844 "\x1Ep|getPosX,"
2845 "\x1Fp|getPosY,"
2846 "\x20p|getImageX,"
2847 "\x21p|getImageY,"
2848 "\x22p|getDistX,"
2849 "\x23p|getDistY,"
2850 "\x24p|getImageStateCount,"
2851 "\x25p|getGroup,"
2852 "\x26p|getDisplayX,"
2853 "\x27p|getDisplayY,"
2854 "\x2App|getFlags,"
2855 "\x2Bp|getPriority,"
2856 "\x2Dpppp|findSprite,"
2857 "\x34p|getImageState,"
2858 "\x3Ep|getSourceImage,"
2859 "\x3Fp|getImage,"
2860 "\x44p|getEraseType,"
2861 "\x52p|getFlagAutoAnim,"
2862 "\x56p|getPalette,"
2863 "\x5Cp|getScale,"
2864 "\x61p|getAnimSpeed,"
2865 "\x62p|getShadow,"
2866 "\x7Cp|getUpdateType,"
2867 "\x7Dlp|getClass,"
2868 "\x8Bpp|getGeneralProperty,"
2869 "\x8Cp|getMaskImage,"
2870 "\xC6pp|getUserValue");
2871 } else {
2872 ext(output, "rx" "getSpriteInfo\0"
2873 "\x1Ep|getPosX,"
2874 "\x1Fp|getPosY,"
2875 "\x20p|getImageX,"
2876 "\x21p|getImageY,"
2877 "\x22p|getDistX,"
2878 "\x23p|getDistY,"
2879 "\x24p|getImageStateCount,"
2880 "\x25p|getGroup,"
2881 "\x26p|getDisplayX,"
2882 "\x27p|getDisplayY,"
2883 "\x2App|getFlags,"
2884 "\x2Bp|getPriority,"
2885 "\x2Dppp|findSprite,"
2886 "\x34p|getImageState,"
2887 "\x3Ep|getSourceImage,"
2888 "\x3Fp|getImage,"
2889 "\x44p|getEraseType,"
2890 "\x52p|getFlagAutoAnim,"
2891 "\x56p|getPalette,"
2892 "\x5Cp|getScale,"
2893 "\x61p|getAnimSpeed,"
2894 "\x62p|getShadow,"
2895 "\x7Cp|getUpdateType,"
2896 "\x7Dlp|getClass,"
2897 "\x8Bpp|getGeneralProperty,"
2898 "\x8Cp|getMaskImage,"
2899 "\xC6pp|getUserValue");
2900 }
2901 break;
2902 case 0x26: // HE90+
2903 if (g_options.heVersion >= 99) {
2904 ext(output, "x" "setSpriteInfo\0"
2905 "\x22p|setDistX,"
2906 "\x23p|setDistY,"
2907 "\x25p|setGroup,"
2908 "\x2App|setFlags,"
2909 "\x2Bp|setPriority,"
2910 "\x2Cpp|move,"
2911 "\x34p|setImageState,"
2912 "\x35p|setAngle,"
2913 "\x39pp|setRange,"
2914 "\x3Ep|setSourceImage,"
2915 "\x3Fp|setImage,"
2916 "\x41pp|setPosition,"
2917 "\x44p|setEraseType,"
2918 "\x4Dpp|setDist,"
2919 "\x52p|setAutoAnimFlag,"
2920 "\x56p|setPalette,"
2921 "\x5Cp|setScale,"
2922 "\x61p|setAnimSpeed,"
2923 "\x62p|setAutoShadow,"
2924 "\x7Cp|setUpdateType,"
2925 "\x7Dl|setClass,"
2926 "\x8Bpp|setGeneralProperty,"
2927 "\x8Cp|setMaskImage,"
2928 "\x9E|resetTables,"
2929 "\xC6pp|setUserValue,"
2930 "\xD9|resetSprite");
2931 } else {
2932 ext(output, "x" "setSpriteInfo\0"
2933 "\x22p|setDistX,"
2934 "\x23p|setDistY,"
2935 "\x25p|setGroup,"
2936 "\x2App|setFlags,"
2937 "\x2Bp|setPriority,"
2938 "\x2Cpp|move,"
2939 "\x34p|setImageState,"
2940 "\x35p|setAngle,"
2941 "\x39p|setRange,"
2942 "\x3Ep|setSourceImage,"
2943 "\x3Fp|setImage,"
2944 "\x41pp|setPosition,"
2945 "\x44p|setEraseType,"
2946 "\x4Dpp|setDist,"
2947 "\x52p|setAutoAnimFlag,"
2948 "\x56p|setPalette,"
2949 "\x5Cp|setScale,"
2950 "\x61p|setAnimSpeed,"
2951 "\x62p|setAutoShadow,"
2952 "\x7Cp|setUpdateType,"
2953 "\x7Dl|setClass,"
2954 "\x8Bpp|setGeneralProperty,"
2955 "\x8Cp|setMaskImage,"
2956 "\x9E|resetTables,"
2957 "\xC6pp|setUserValue,"
2958 "\xD9|resetSprite");
2959 }
2960 break;
2961 case 0x27: // HE90+
2962 ext(output, "rx" "getSpriteGroupInfo\0"
2963 "\x8p|getSpriteArray,"
2964 "\x1Ep|getPositionX,"
2965 "\x1Fp|getPositionY,"
2966 "\x2App|getXYScale?,"
2967 "\x2Bp|getPriority,"
2968 "\x3Fp|getDstResNum,"
2969 "\x8Bpp|dummy");
2970 break;
2971 case 0x28: // HE90+
2972 ext(output, "x" "setSpriteGroupInfo\0"
2973 "\x25pp|misc,"
2974 "\x2App|setXYScale?,"
2975 "\x2Bp|setPriority,"
2976 "\x2Cpp|move,"
2977 "\x39p|setId,"
2978 "\x3Fp|setImage,"
2979 "\x41pp|setPosition,"
2980 "\x43pppp|setBounds,"
2981 "\x5D|resetBounds,"
2982 "\xD9|reset");
2983 break;
2984 case 0x29: // HE90+
2985 ext(output, "rx" "getWizData\0"
2986 "\x1Epp|imageSpotX,"
2987 "\x1Fpp|imageSpotY,"
2988 "\x20pp|width,"
2989 "\x21pp|height,"
2990 "\x24p|imageCount,"
2991 "\x2Dpppp|isPixelNonTransparentnumber,"
2992 "\x42pppp|pixelColor,"
2993 "\x82pppppp|histogram,"
2994 "\x8Dphp|case141");
2995 break;
2996 case 0x2A: // HE90+
2997 ext(output, "rppp|getActorData");
2998 break;
2999 case 0x2B: // HE90+
3000 ext(output, "lppi|startScriptUnk");
3001 break;
3002 case 0x2C: // HE90+
3003 ext(output, "lppi|jumpToScriptUnk");
3004 break;
3005 case 0x2D: // HE90+
3006 ext(output, "x" "videoOps\0"
3007 "\x31h|setFilename,"
3008 "\x36p|setFlags,"
3009 "\x39p|setUnk2,"
3010 "\x3Fp|setWizResNumX,"
3011 "\xA5|setStatus,"
3012 "\xFF|playOrStopVideo,");
3013 break;
3014 case 0x2E: // HE95+
3015 ext(output, "rx" "getVideoData\0"
3016 "\x20p|width,"
3017 "\x21p|height,"
3018 "\x24p|frameCount,"
3019 "\x34p|curFrame,"
3020 "\x3Fp|imageNum,"
3021 "\x8Bpp|statistics");
3022 break;
3023 case 0x2F: // HE90+
3024 ext(output, "x" "floodFill\0"
3025 "\x36p|dummy,"
3026 "\x39|reset,"
3027 "\x41pp|setXY,"
3028 "\x42p|setFlags,"
3029 "\x43pppp|setBoxRect,"
3030 "\xFF|floodFill");
3031 break;
3032 case 0x30: // HE90+
3033 ext(output, "rpp|mod");
3034 break;
3035 case 0x31: // HE90+
3036 ext(output, "rpp|shl");
3037 break;
3038 case 0x32: // HE90+
3039 ext(output, "rpp|shr");
3040 break;
3041 case 0x33: // HE90+
3042 ext(output, "rpp|xor");
3043 break;
3044 case 0x34:
3045 ext(output, "rlp|findAllObjectsWithClassOf");
3046 break;
3047 case 0x35: // HE90+
3048 ext(output, "rllp|getPolygonOverlap");
3049 break;
3050 case 0x36: // HE90+
3051 ext(output, "rppp|cond");
3052 break;
3053 case 0x37: // HE90+
3054 ext(output, "x" "dim2dim2Array\0"
3055 "\x2pppppv|bit,"
3056 "\x3pppppv|nibble,"
3057 "\x4pppppv|byte,"
3058 "\x5pppppv|int,"
3059 "\x6pppppv|dword,"
3060 "\x7pppppv|string");
3061 break;
3062 case 0x38: // HE90+
3063 ext(output, "x" "redim2dimArray\0"
3064 "\x4ppppv|byte,"
3065 "\x5ppppv|int,"
3066 "\x6ppppv|dword");
3067 break;
3068 case 0x39: // HE90+
3069 ext(output, "rwwpppppppp|getLinesIntersectionPoint");
3070 break;
3071 case 0x3A: // HE90+
3072 ext(output, "x" "sortArray\0"
3073 "\x81pppppv|sort,");
3074 break;
3075 case 0x43:
3076 writeVar(output, get_word(), pop());
3077 break;
3078 case 0x44: // HE90+
3079 ext(output, "rx" "getObjectData\0"
3080 "\x20|getWidth,"
3081 "\x21|getHeight,"
3082 "\x24|getImageCount,"
3083 "\x26|getX,"
3084 "\x27|getY,"
3085 "\x34|getState,"
3086 "\x39p|setId,"
3087 "\x8Bp|dummy");
3088 break;
3089 case 0x45: // HE80+
3090 ext(output, "x" "createSound\0"
3091 "\x1Bp|create,"
3092 "\xD9|reset,"
3093 "\xE8p|setId,"
3094 "\xFF|dummy");
3095 break;
3096 case 0x46: // HE80+
3097 ext(output, "rh|getFileSize");
3098 break;
3099 case 0x47:
3100 se_a = pop();
3101 writeArray(output, get_word(), NULL, pop(), se_a);
3102 break;
3103 case 0x48: // HE80+
3104 ext(output, "rp|stringToInt");
3105 break;
3106 case 0x49: // HE80+
3107 ext(output, "rpp|getSoundVar");
3108 break;
3109 case 0x4A: // HE80+
3110 ext(output, "p|localizeArrayToRoom");
3111 break;
3112 case 0x4B:
3113 se_a = pop();
3114 se_b = pop();
3115 writeArray(output, get_word(), pop(), se_b, se_a);
3116 break;
3117 case 0x4D: // HE80+
3118 ext(output, "rx" "readConfigFile\0"
3119 "\x6hhh|number,"
3120 "\x7hhh|string");
3121 break;
3122 case 0x4E: // HE80+
3123 ext(output, "x" "writeConfigFile\0"
3124 "\x6phhh|number,"
3125 "\x7hhhh|string");
3126 break;
3127 case 0x4F:
3128 addVar(output, get_word(), 1);
3129 break;
3130 case 0x50:
3131 ext(output, "|resetCutScene");
3132 break;
3133 case 0x51:
3134 ext(output, "rx" "getHeap\0"
3135 "\xb|freeSpace,"
3136 "\xc|largestBlockSize");
3137 break;
3138 case 0x52:
3139 ext(output, "rlpp|findObjectWithClassOf");
3140 break;
3141 case 0x53:
3142 addArray(output, get_word(), pop(), 1);
3143 break;
3144 case 0x54:
3145 ext(output, "rp|objectX");
3146 break;
3147 case 0x55:
3148 ext(output, "rp|objectY");
3149 break;
3150 case 0x56:
3151 ext(output, "ppppp|captureWizImage");
3152 break;
3153 case 0x57:
3154 addVar(output, get_word(), -1);
3155 break;
3156 case 0x58:
3157 ext(output, "ri|getTimer");
3158 break;
3159 case 0x59:
3160 ext(output, "pi|setTimer");
3161 break;
3162 case 0x5A:
3163 ext(output, "rp|getSoundPosition");
3164 break;
3165 case 0x5B:
3166 addArray(output, get_word(), pop(), -1);
3167 break;
3168 case 0x5C:
3169 jumpif(output, pop(), true);
3170 break;
3171 case 0x5D:
3172 jumpif(output, pop(), false);
3173 break;
3174 case 0x5E:
3175 ext(output, "lpi|startScript");
3176 break;
3177 case 0x5F:
3178 ext(output, "lp|startScriptQuick");
3179 break;
3180 case 0x60:
3181 ext(output, "lppi|startObject");
3182 break;
3183 case 0x61:
3184 ext(output, "x" "drawObject\0"
3185 "\x3Epppp|setup,"
3186 "\x3Fpp|setState,"
3187 "\x41ppp|setPosition,");
3188 break;
3189 case 0x62:
3190 ext(output, "p|printWizImage");
3191 break;
3192 case 0x63:
3193 ext(output, "rx" "getArrayDimSize\0"
3194 "\x1v|dim1size,"
3195 "\x2v|dim2size,"
3196 "\x3v|dim1size,"
3197 "\x4v|dim1start,"
3198 "\x5v|dim1end,"
3199 "\x6v|dim2start,"
3200 "\x7v|dim2end,");
3201 break;
3202 case 0x64:
3203 ext(output, "r|getNumFreeArrays");
3204 break;
3205 case 0x65:
3206 ext(output, "|stopObjectCodeA");
3207 break;
3208 case 0x66:
3209 ext(output, "|stopObjectCodeB");
3210 break;
3211 case 0x67:
3212 ext(output, "|endCutscene");
3213 break;
3214 case 0x68:
3215 ext(output, "l|beginCutscene");
3216 break;
3217 case 0x69:
3218 if (g_options.heVersion >= 80) {
3219 ext(output, "x" "windowOps\0"
3220 "\x2Cpp|case44,"
3221 "\x39p|case57,"
3222 "\x3Ap|case58,"
3223 "\x3Bp|case59,"
3224 "\x3Fp|case63,"
3225 "\x41pp|case65,"
3226 "\xD9|case217,"
3227 "\xF3h|case243,"
3228 "\xFF|case255");
3229 } else {
3230 ext(output, "|stopMusic");
3231 }
3232 break;
3233 case 0x6A:
3234 ext(output, "p|freezeUnfreeze");
3235 break;
3236 case 0x6B:
3237 ext(output, "x" "cursorCommand\0"
3238 "\x13z|setCursorImg,"
3239 "\x14z|setCursorImg,"
3240 "\x3Czp|setCursorImgWithPal,"
3241 "\x90|cursorOn,"
3242 "\x91|cursorOff,"
3243 "\x92|userPutOn,"
3244 "\x93|userPutOff,"
3245 "\x94|softCursorOn,"
3246 "\x95|softCursorOff,"
3247 "\x96|softUserputOn,"
3248 "\x97|softUserputOff,"
3249 "\x99z|setCursorImg,"
3250 "\x9App|setCursorHotspot,"
3251 "\x9Cp|initCharset,"
3252 "\x9Dl|charsetColors,"
3253 "\xD6p|makeCursorColorTransparent");
3254 break;
3255 case 0x6C:
3256 ext(output, "|breakHere");
3257 break;
3258 case 0x6D:
3259 ext(output, "rlp|ifClassOfIs");
3260 break;
3261 case 0x6E:
3262 ext(output, "lp|setClass");
3263 break;
3264 case 0x6F:
3265 ext(output, "rp|getState");
3266 break;
3267 case 0x70:
3268 ext(output, "pp|setState");
3269 break;
3270 case 0x71:
3271 ext(output, "pp|setOwner");
3272 break;
3273 case 0x72:
3274 ext(output, "rp|getOwner");
3275 break;
3276 case 0x73:
3277 jump(output);
3278 break;
3279 case 0x74:
3280 ext(output, "x" "soundOps\0"
3281 "\x9|setSoftSound,"
3282 "\x17ppp|setSoundVar,"
3283 "\x19pp|setVolume,"
3284 "\x38|setQuickStart,"
3285 "\xA4|setAppend,"
3286 "\xDE|dummy,"
3287 "\xE0p|setFrequency,"
3288 "\xE6p|setChannel,"
3289 "\xE7p|setOffset,"
3290 "\xE8p|setSoundId,"
3291 "\xF5|setLoop,"
3292 "\xFF|start");
3293 break;
3294 case 0x75:
3295 ext(output, "p|stopSound");
3296 break;
3297 case 0x76:
3298 ext(output, "p|startMusic");
3299 break;
3300 case 0x77:
3301 ext(output, "p|stopObjectScript");
3302 break;
3303 case 0x78:
3304 ext(output, "p|panCameraTo");
3305 break;
3306 case 0x79:
3307 ext(output, "p|actorFollowCamera");
3308 break;
3309 case 0x7A:
3310 ext(output, "p|setCameraAt");
3311 break;
3312 case 0x7B:
3313 ext(output, "p|loadRoom");
3314 break;
3315 case 0x7C:
3316 ext(output, "p|stopScript");
3317 break;
3318 case 0x7D:
3319 ext(output, "ppp|walkActorToObj");
3320 break;
3321 case 0x7E:
3322 ext(output, "ppp|walkActorTo");
3323 break;
3324 case 0x7F:
3325 ext(output, "pppp|putActorInXY");
3326 break;
3327 case 0x80:
3328 ext(output, "zp|putActorAtObject");
3329 break;
3330 case 0x81:
3331 ext(output, "pp|faceActor");
3332 break;
3333 case 0x82:
3334 ext(output, "pp|animateActor");
3335 break;
3336 case 0x83:
3337 ext(output, "pppp|doSentence");
3338 break;
3339 case 0x84:
3340 ext(output, "z|pickupObject");
3341 break;
3342 case 0x85:
3343 ext(output, "ppz|loadRoomWithEgo");
3344 break;
3345 case 0x87:
3346 ext(output, "rp|getRandomNumber");
3347 break;
3348 case 0x88:
3349 ext(output, "rpp|getRandomNumberRange");
3350 break;
3351 case 0x8A:
3352 ext(output, "rp|getActorMoving");
3353 break;
3354 case 0x8B:
3355 ext(output, "rp|isScriptRunning");
3356 break;
3357 case 0x8C:
3358 ext(output, "rp|getActorRoom");
3359 break;
3360 case 0x8D:
3361 ext(output, "rp|getObjectX");
3362 break;
3363 case 0x8E:
3364 ext(output, "rp|getObjectY");
3365 break;
3366 case 0x8F:
3367 ext(output, "rp|getObjectDir");
3368 break;
3369 case 0x90:
3370 ext(output, "rp|getActorWalkBox");
3371 break;
3372 case 0x91:
3373 ext(output, "rp|getActorCostume");
3374 break;
3375 case 0x92:
3376 ext(output, "rpp|findInventory");
3377 break;
3378 case 0x93:
3379 ext(output, "rp|getInventoryCount");
3380 break;
3381 case 0x94:
3382 if (g_options.heVersion >= 90) {
3383 ext(output, "rx" "getPaletteData\0"
3384 "\x2Dpppppp|getSimilarColor,"
3385 "\x34ppp|getColorCompontent,"
3386 "\x42pp|getColor,"
3387 "\x84pp|get16BitColorComponent,"
3388 "\xD9ppp|get16BitColor");
3389 } else {
3390 ext(output, "rpp|getVerbFromXY");
3391 }
3392 break;
3393 case 0x95:
3394 ext(output, "|beginOverride");
3395 break;
3396 case 0x96:
3397 ext(output, "|endOverride");
3398 break;
3399 case 0x97:
3400 ext(output, "ps|setObjectName");
3401 break;
3402 case 0x98:
3403 ext(output, "rp|isSoundRunning");
3404 break;
3405 case 0x99:
3406 ext(output, "pl|setBoxFlags");
3407 break;
3408 case 0x9B:
3409 ext(output, "x" "resourceRoutines\0"
3410 "\x64p|loadScript,"
3411 "\x65p|loadSound,"
3412 "\x66p|loadCostume,"
3413 "\x67p|loadRoom,"
3414 "\x68p|nukeScript,"
3415 "\x69p|nukeSound,"
3416 "\x6Ap|nukeCostume,"
3417 "\x6Bp|nukeRoom,"
3418 "\x6Cp|lockScript,"
3419 "\x6Dp|lockSound,"
3420 "\x6Ep|lockCostume,"
3421 "\x6Fp|lockRoom,"
3422 "\x70p|unlockScript,"
3423 "\x71p|unlockSound,"
3424 "\x72p|unlockCostume,"
3425 "\x73p|unlockRoom,"
3426 "\x74|clearHeap,"
3427 "\x75p|loadCharset,"
3428 "\x76p|nukeCharset,"
3429 "\x77z|loadFlObject,"
3430 "\x78p|queueloadScript,"
3431 "\x79p|queueloadSound,"
3432 "\x7Ap|queueloadCostume,"
3433 "\x7Bp|queueloadRoomImage,"
3434 "\x9fp|unlockImage,"
3435 "\xc0p|nukeImage,"
3436 "\xc9p|loadImage,"
3437 "\xcap|lockImage,"
3438 "\xcbp|queueloadImage,"
3439 "\xe9p|lockFlObject,"
3440 "\xebp|unlockFlObject,"
3441 "\xef|dummy");
3442 break;
3443 case 0x9C:
3444 ext(output, "x" "roomOps\0"
3445 "\xACpp|roomScroll,"
3446 "\xAEpp|setScreen,"
3447 "\xAFpppp|setPalColor,"
3448 "\xB0|shakeOn,"
3449 "\xB1|shakeOff,"
3450 "\xB3ppp|darkenPalette,"
3451 "\xB4pp|saveLoadRoom,"
3452 "\xB5p|screenEffect,"
3453 "\xB6ppppp|darkenPalette,"
3454 "\xB7ppppp|setupShadowPalette,"
3455 "\xBApppp|palManipulate,"
3456 "\xBBpp|colorCycleDelay,"
3457 "\xD5p|setPalette,"
3458 "\xDCpp|copyPalColor,"
3459 "\xDDhp|saveOrLoad,"
3460 "\xEApp|swapObjects,"
3461 "\xECpp|setRoomPalette");
3462 break;
3463 case 0x9D:
3464 ext(output, "x" "actorOps\0"
3465 "\x15l|setUserConditions,"
3466 "\x18p|setTalkCondition,"
3467 "\x2Bp|layer,"
3468 "\xC5p|setCurActor,"
3469 "\x40pppp|setClipRect,"
3470 "\x41pp|putActor,"
3471 "\x43pppp|setActorClipRect,"
3472 "\x44p|setHEFlag,"
3473 "\x4Cp|setCostume,"
3474 "\x4Dpp|setWalkSpeed,"
3475 "\x4El|setSound,"
3476 "\x4Fp|setWalkFrame,"
3477 "\x50pp|setTalkFrame,"
3478 "\x51p|setStandFrame,"
3479 "\x52ppp|actorSet:82:??,"
3480 "\x53|init,"
3481 "\x54p|setElevation,"
3482 "\x55|setDefAnim,"
3483 "\x56pp|setPalette,"
3484 "\x57p|setTalkColor,"
3485 "\x58h|setName,"
3486 "\x59p|setInitFrame,"
3487 "\x5Bp|setWidth,"
3488 "\x5Cp|setScale,"
3489 "\x5D|setNeverZClip,"
3490 "\x5Ep|setAlwayZClip,"
3491 "\x5F|setIgnoreBoxes,"
3492 "\x60|setFollowBoxes,"
3493 "\x61p|setAnimSpeed,"
3494 "\x62p|setShadowMode,"
3495 "\x63pp|setTalkPos,"
3496 "\x8Bpp|case139,"
3497 "\x9Cp|charset,"
3498 "\xAFp|setPaletteNum,"
3499 "\xC6pp|setAnimVar,"
3500 "\xD7|setIgnoreTurnsOn,"
3501 "\xD8|setIgnoreTurnsOff,"
3502 "\xD9|initLittle,"
3503 "\xDA|drawToBackBuf,"
3504 "\xE1hp|setTalkieSlot");
3505 break;
3506 case 0x9E:
3507 if (g_options.heVersion >= 90) {
3508 ext(output, "x" "paletteOps\0"
3509 "\x39p|setPaletteNum,"
3510 "\x3Fpp|setPaletteFromImage,"
3511 "\x42ppppp|setPaletteColor,"
3512 "\x46ppp|copyPaletteColor,"
3513 "\x4Cp|setPaletteFromCostume,"
3514 "\x56p|copyPalette,"
3515 "\xAFpp|setPaletteFromRoom,"
3516 "\xD9|restorePalette,"
3517 "\xFF|resetPaletteNum");
3518 } else {
3519 ext(output, "x" "verbOps\0"
3520 "\xC4p|setCurVerb,"
3521 "\x7Cp|loadImg,"
3522 "\x7Dh|loadString,"
3523 "\x7Ep|setColor,"
3524 "\x7Fp|setHiColor,"
3525 "\x80pp|setXY,"
3526 "\x81|setOn,"
3527 "\x82|setOff,"
3528 "\x83p|kill,"
3529 "\x84|init,"
3530 "\x85p|setDimColor,"
3531 "\x86|setDimmed,"
3532 "\x87p|setKey,"
3533 "\x88|setCenter,"
3534 "\x89p|setToString,"
3535 "\x8Bpp|setToObject,"
3536 "\x8Cp|setBkColor,"
3537 "\xFF|redraw");
3538 }
3539 break;
3540 case 0x9F:
3541 ext(output, "rpp|getActorFromXY");
3542 break;
3543 case 0xA0:
3544 ext(output, "rpp|findObject");
3545 break;
3546 case 0xA1:
3547 ext(output, "lp|pseudoRoom");
3548 break;
3549 case 0xA2:
3550 ext(output, "rp|getActorElevation");
3551 break;
3552 case 0xA3:
3553 ext(output, "rpp|getVerbEntrypoint");
3554 break;
3555 case 0xA4:
3556 switch (get_byte()) {
3557 case 7:
3558 se_a = se_get_string_he();
3559 writeArray(output, get_word(), NULL, se_a, se_a);
3560 break;
3561 case 126:
3562 // TODO: Add support for writeListIntoArray
3563 ext(output, "lppppv|writeListIntoArray");
3564 break;
3565 case 127:
3566 // TODO: Add support for copyArray
3567 ext(output, "ppppvppppv|copyArray");
3568 break;
3569 case 128:
3570 // TODO: Add support for writeRangeIntoArray
3571 ext(output, "ppppppv|writeRangeIntoArray");
3572 break;
3573 case 138:
3574 // TODO: Add support for math operations
3575 ext(output, "pppppppppppppvvv|mathOpsInArray");
3576 break;
3577 case 194:
3578 se_get_list();
3579 pop();
3580 se_a = se_get_string_he();
3581 writeArray(output, get_word(), NULL, se_a, se_a);
3582 break;
3583 case 208:
3584 se_a = pop();
3585 se_b = se_get_list();
3586 writeArray(output, get_word(), NULL, se_a, se_b);
3587 break;
3588 case 212:
3589 se_b = se_get_list();
3590 se_a = pop();
3591 writeArray(output, get_word(), NULL, se_a, se_b);
3592 break;
3593 }
3594 break;
3595 case 0xA5:
3596 if (g_options.heVersion >= 99) {
3597 ext(output, "rx" "fontUnk\0"
3598 "\x2App|case42,"
3599 "\x39|case57");
3600 } else if (g_options.heVersion >= 80) {
3601 invalidop(NULL, code);
3602 } else {
3603 ext(output, "x" "saveRestoreVerbs\0"
3604 "\x8Dppp|saveVerbs,"
3605 "\x8Eppp|restoreVerbs,"
3606 "\x8Fppp|deleteVerbs");
3607 }
3608 break;
3609 case 0xA6:
3610 ext(output, "ppppp|drawBox");
3611 break;
3612 case 0xA8:
3613 ext(output, "rp|getActorWidth");
3614 break;
3615 case 0xA9:
3616 ext(output, "x" "wait\0"
3617 "\xA8pj|waitForActor,"
3618 "\xA9|waitForMessage,"
3619 "\xAA|waitForCamera,"
3620 "\xAB|waitForSentence");
3621 break;
3622 case 0xAA:
3623 ext(output, "rp|getActorScaleX");
3624 break;
3625 case 0xAB:
3626 if (g_options.heVersion >= 90) {
3627 ext(output, "rp|getActorAnimProgress");
3628 } else {
3629 ext(output, "rp|getActorAnimCounter1");
3630 }
3631 break;
3632 case 0xAC: // HE80+
3633 ext(output, "pp|drawWizPolygon");
3634 break;
3635 case 0xAD:
3636 ext(output, "rlp|isAnyOf");
3637 break;
3638 case 0xAE:
3639 ext(output, "x" "systemOps\0"
3640 "\x16|clearDrawQueue,"
3641 "\x1A|copyVirtBuf,"
3642 "\x9E|restart,"
3643 "\xA0|confirmShutDown,"
3644 "\xF4|shutDown,"
3645 "\xFB|startExec,"
3646 "\xFC|startGame");
3647 break;
3648 case 0xAF:
3649 ext(output, "rpp|isActorInBox");
3650 break;
3651 case 0xB0:
3652 ext(output, "p|delay");
3653 break;
3654 case 0xB1:
3655 ext(output, "p|delaySeconds");
3656 break;
3657 case 0xB2:
3658 ext(output, "p|delayMinutes");
3659 break;
3660 case 0xB3:
3661 ext(output, "|stopSentence");
3662 break;
3663 case 0xB4:
3664 PRINT_V7HE("printLine");
3665 break;
3666 case 0xB5:
3667 PRINT_V7HE("printCursor");
3668 break;
3669 case 0xB6:
3670 PRINT_V7HE("printDebug");
3671 break;
3672 case 0xB7:
3673 PRINT_V7HE("printSystem");
3674 break;
3675 case 0xB8:
3676 // This is *almost* identical to the other print opcodes, only the 'begine' subop differs
3677 ext(output, "x" "printActor\0"
3678 "\x41pp|XY,"
3679 "\x42p|color,"
3680 "\x43p|right,"
3681 "\x45|center,"
3682 "\x47|left,"
3683 "\x48|overhead,"
3684 "\x4A|mumble,"
3685 "\x4Bs|msg,"
3686 "\xE1p|getText,"
3687 "\xF9l|colors,"
3688 "\xFEp|begin,"
3689 "\xFF|end");
3690 break;
3691 case 0xB9:
3692 PRINT_V7HE("printEgo");
3693 break;
3694 case 0xBA:
3695 ext(output, "ps|talkActor");
3696 break;
3697 case 0xBB:
3698 ext(output, "s|talkEgo");
3699 break;
3700 case 0xBC:
3701 ext(output, "x" "dimArray\0"
3702 "\x2pv|bit,"
3703 "\x3pv|nibble,"
3704 "\x4pv|byte,"
3705 "\x5pv|int,"
3706 "\x6pv|dword,"
3707 "\x7pv|string,"
3708 "\xCCv|nukeArray");
3709 break;
3710 case 0xBD:
3711 ext(output, "|stopObjectCode");
3712 break;
3713 case 0xBE:
3714 // TODO: this loads another script which does something like
3715 // stack altering and then finishes (usually with opcode 0xBD).
3716 // When stack is changed, further disassembly is wrong.
3717 // This is widely used in HE games.
3718 // As there are cases when called script does not alter the
3719 // stack, it's not correct to use "rlpp|..." here
3720 ext(output, "lpp|startObjectQuick");
3721 break;
3722 case 0xBF:
3723 ext(output, "lp|startScriptQuick2");
3724 break;
3725 case 0xC0:
3726 ext(output, "x" "dim2dimArray\0"
3727 "\x2ppv|bit,"
3728 "\x3ppv|nibble,"
3729 "\x4ppv|byte,"
3730 "\x5ppv|int,"
3731 "\x6ppv|dword,"
3732 "\x7ppv|string");
3733 break;
3734 case 0xC1:
3735 ext(output, "hp|traceStatus");
3736 break;
3737 case 0xC4:
3738 ext(output, "rp|abs");
3739 break;
3740 case 0xC5:
3741 ext(output, "rpp|getDistObjObj");
3742 break;
3743 case 0xC6:
3744 ext(output, "rppp|getDistObjPt");
3745 break;
3746 case 0xC7:
3747 ext(output, "rpppp|getDistPtPt");
3748 break;
3749 case 0xC8:
3750 ext(output, "ry" "kernelGetFunctions\0"
3751 "\x1|virtScreenSave"
3752 );
3753 break;
3754 case 0xC9:
3755 ext(output, "y" "kernelSetFunctions\0"
3756 "\x1|virtScreenLoad,"
3757 "\x14|queueAuxBlock,"
3758 "\x15|pauseDrawObjects,"
3759 "\x16|resumeDrawObjects,"
3760 "\x17|clearCharsetMask,"
3761 "\x18|pauseActors,"
3762 "\x19|resumActors,"
3763 "\x1E|actorBottomClipOverride,"
3764 "\x2A|setWizImageClip,"
3765 "\x2B|setWizImageClipOff,"
3766 );
3767 break;
3768 case 0xCA:
3769 ext(output, "p|delayFrames");
3770 break;
3771 case 0xCB:
3772 ext(output, "rlp|pickOneOf");
3773 break;
3774 case 0xCC:
3775 ext(output, "rplp|pickOneOfDefault");
3776 break;
3777 case 0xCD:
3778 ext(output, "pppp|stampObject");
3779 break;
3780 case 0xCE:
3781 ext(output, "pppp|drawWizImage");
3782 break;
3783 case 0xCF:
3784 ext(output, "rh|debugInput");
3785 break;
3786 case 0xD0:
3787 ext(output, "|getDateTime");
3788 break;
3789 case 0xD1:
3790 ext(output, "|stopTalking");
3791 break;
3792 case 0xD2:
3793 ext(output, "rpp|getAnimateVariable");
3794 break;
3795 case 0xD4:
3796 ext(output, "wpp|shuffle");
3797 break;
3798 case 0xD5:
3799 ext(output, "lpi|jumpToScript");
3800 break;
3801 case 0xD6:
3802 se_a = pop();
3803 se_b = pop();
3804 push(se_oper(se_b, operBand, se_a));
3805 break;
3806 case 0xD7:
3807 se_a = pop();
3808 se_b = pop();
3809 push(se_oper(se_b, operBor, se_a));
3810 break;
3811 case 0xD8:
3812 ext(output, "rp|isRoomScriptRunning");
3813 break;
3814 case 0xD9:
3815 ext(output, "p|closeFile");
3816 break;
3817 case 0xDA:
3818 ext(output, "rph|openFile");
3819 break;
3820 case 0xDB:
3821 ext(output, "rx" "readFile\0"
3822 "\x4p|readByte,"
3823 "\x5p|readWord,"
3824 "\x6p|readDWord,"
3825 "\x8ppi|readArrayFromFile");
3826 break;
3827 case 0xDC:
3828 ext(output, "x" "writeFile\0"
3829 "\x4pp|writeByte,"
3830 "\x5pp|writeWord,"
3831 "\x6pp|writeDWord,"
3832 "\x8ppi|writeArrayToFile");
3833 break;
3834 case 0xDD:
3835 ext(output, "rp|findAllObjects");
3836 break;
3837 case 0xDE:
3838 ext(output, "h|deleteFile");
3839 break;
3840 case 0xDF:
3841 ext(output, "hh|renameFile");
3842 break;
3843 case 0xE0:
3844 ext(output, "x" "drawLine\0"
3845 "\x37pppppp|pixel,"
3846 "\x3Fpppppp|actor,"
3847 "\x42pppppp|wizImage");
3848 break;
3849 case 0xE1:
3850 ext(output, "rx" "getPixel\0"
3851 "\xDApp|background,"
3852 "\xDBpp|foreground");
3853 break;
3854 case 0xE2:
3855 ext(output, "p|localizeArrayToScript");
3856 break;
3857 case 0xE3:
3858 ext(output, "rlw|pickVarRandom");
3859 break;
3860 case 0xE4:
3861 ext(output, "p|setBotSet");
3862 break;
3863 case 0xE9:
3864 ext(output, "ppp|seekFilePos");
3865 break;
3866 case 0xEA:
3867 ext(output, "x" "redimArray\0"
3868 "\x4ppv|byte,"
3869 "\x5ppv|int,"
3870 "\x6ppv|dword");
3871 break;
3872 case 0xEB:
3873 ext(output, "rp|readFilePos");
3874 break;
3875 case 0xEC:
3876 ext(output, "rp|copyString");
3877 break;
3878 case 0xED:
3879 ext(output, "rppp|getStringWidth");
3880 break;
3881 case 0xEE:
3882 ext(output, "rp|getStringLen");
3883 break;
3884 case 0xEF:
3885 ext(output, "rppp|appendString");
3886 break;
3887 case 0xF0:
3888 ext(output, "rpp|concatString");
3889 break;
3890 case 0xF1:
3891 ext(output, "rpp|compareString");
3892 break;
3893 case 0xF2:
3894 ext(output, "rx" "isResourceLoaded\0"
3895 "\x12p|image,"
3896 "\xE2p|room,"
3897 "\xE3p|costume,"
3898 "\xE4p|sound,"
3899 "\xE5p|script");
3900 break;
3901 case 0xF3:
3902 ext(output, "rx" "readINI\0"
3903 "\x06h|number,"
3904 "\x07h|string");
3905 break;
3906 case 0xF4:
3907 ext(output, "x" "writeINI\0"
3908 "\x06ph|number,"
3909 "\x07hh|string");
3910 break;
3911 case 0xF5:
3912 ext(output, "rppp|getStringLenForWidth");
3913 break;
3914 case 0xF6:
3915 ext(output, "rpppp|getCharIndexInString");
3916 break;
3917 case 0xF8:
3918 if (g_options.heVersion >= 73) {
3919 ext(output, "rx" "getResourceSize\0"
3920 "\xDp|sound,"
3921 "\xEp|roomImage,"
3922 "\xFp|image,"
3923 "\x10p|costume,"
3924 "\x11p|script");
3925 } else {
3926 ext(output, "rp|getSoundResourceSize");
3927 }
3928 break;
3929 case 0xF9:
3930 ext(output, "h|createDirectory");
3931 break;
3932 case 0xFA:
3933 ext(output, "x" "setSystemMessage\0"
3934 "\xF0h|case240,"
3935 "\xF1h|versionMsg,"
3936 "\xF2h|case242,"
3937 "\xF3h|titleMsg");
3938 break;
3939 case 0xFB:
3940 ext(output, "x" "polygonOps\0"
3941 "\xF6ppppppppp|polygonStore,"
3942 "\xF7pp|polygonErase,"
3943 "\xF8ppppppppp|polygonStore,"
3944 );
3945 break;
3946 case 0xFC:
3947 ext(output, "rpp|polygonHit");
3948 break;
3949
3950 default:
3951 invalidop(NULL, code);
3952 break;
3953 }
3954 }
3955
3956 #define PRINT_V8(name) \
3957 do { \
3958 ext(output, \
3959 "x" name "\0" \
3960 "\xC8|baseop," \
3961 "\xC9|end," \
3962 "\xCApp|XY," \
3963 "\xCBp|color," \
3964 "\xCC|center," \
3965 "\xCDp|charset," \
3966 "\xCE|left," \
3967 "\xCF|overhead," \
3968 "\xD0|mumble," \
3969 "\xD1s|msg," \
3970 "\xD2|wrap" \
3971 ); \
3972 } while(0)
3973
3974
next_line_V8(char * output)3975 void next_line_V8(char *output) {
3976 byte code = get_byte();
3977 StackEnt *se_a, *se_b;
3978
3979 switch (code) {
3980 case 0x1:
3981 push(se_int(get_word()));
3982 break;
3983 case 0x2:
3984 push(se_var(get_word()));
3985 break;
3986 case 0x3:
3987 push(se_array(get_word(), NULL, pop()));
3988 break;
3989 case 0x4:
3990 se_a = pop();
3991 push(se_array(get_word(), pop(), se_a));
3992 break;
3993 case 0x5:
3994 se_a = dup(output, pop());
3995 push(se_a);
3996 push(se_a);
3997 break;
3998 case 0x6:
3999 kill(output, pop());
4000 break;
4001 case 0x7:
4002 push(se_oper(pop(), isZero));
4003 break;
4004 case 0x8:
4005 case 0x9:
4006 case 0xA:
4007 case 0xB:
4008 case 0xC:
4009 case 0xD:
4010 case 0xE:
4011 case 0xF:
4012 case 0x10:
4013 case 0x11:
4014 case 0x12:
4015 case 0x13:
4016 case 0x14:
4017 case 0x15:
4018 case 0x16:
4019 se_a = pop();
4020 se_b = pop();
4021 push(se_oper(se_b, (code - 0x8) + isEqual, se_a));
4022 break;
4023
4024 case 0x64:
4025 jumpif(output, pop(), true);
4026 break;
4027 case 0x65:
4028 jumpif(output, pop(), false);
4029 break;
4030 case 0x66:
4031 jump(output);
4032 break;
4033 case 0x67:
4034 ext(output, "|breakHere");
4035 break;
4036 case 0x68:
4037 ext(output, "p|delayFrames");
4038 break;
4039 case 0x69:
4040 ext(output, "x" "wait\0"
4041 "\x1Epj|waitForActor,"
4042 "\x1F|waitForMessage,"
4043 "\x20|waitForCamera,"
4044 "\x21|waitForSentence,"
4045 "\x22pj|waitUntilActorDrawn,"
4046 "\x23pj|waitUntilActorTurned,"
4047 );
4048 break;
4049 case 0x6A:
4050 ext(output, "p|delay");
4051 break;
4052 case 0x6B:
4053 ext(output, "p|delaySeconds");
4054 break;
4055 case 0x6C:
4056 ext(output, "p|delayMinutes");
4057 break;
4058 case 0x6D:
4059 writeVar(output, get_word(), pop());
4060 break;
4061 case 0x6E:
4062 addVar(output, get_word(), +1);
4063 break;
4064 case 0x6F:
4065 addVar(output, get_word(), -1);
4066 break;
4067 case 0x70:
4068 // FIXME - is this correct?!? Also, make the display nicer...
4069 ext(output, "x" "dimArray\0"
4070 "\x0Apw|dim-scummvar,"
4071 "\x0Bpw|dim-string,"
4072 "\xCAw|undim"
4073 );
4074 break;
4075 case 0x71:
4076 se_a = pop();
4077 writeArray(output, get_word(), NULL, pop(), se_a);
4078 break;
4079
4080 case 0x74:
4081 // FIXME - is this correct?!? Also, make the display nicer...
4082 ext(output, "x" "dim2dimArray\0"
4083 "\x0Appw|dim2-scummvar,"
4084 "\x0Bppw|dim2-string,"
4085 "\xCAw|undim2"
4086 );
4087 break;
4088 case 0x75:
4089 se_a = pop();
4090 se_b = pop();
4091 writeArray(output, get_word(), pop(), se_b, se_a);
4092 break;
4093 case 0x76:
4094 switch (get_byte()) {
4095 case 0x14:{
4096 int array = get_word();
4097 writeArray(output, array, NULL, pop(), se_get_string());
4098 }
4099 break;
4100 case 0x15:
4101 se_a = pop();
4102 se_b = se_get_list();
4103 writeArray(output, get_word(), NULL, se_a, se_b);
4104 break;
4105 case 0x16:
4106 se_a = pop();
4107 se_b = se_get_list();
4108 writeArray(output, get_word(), pop(), se_a, se_b);
4109 break;
4110 }
4111 break;
4112
4113 case 0x79:
4114 ext(output, "lpp|startScript");
4115 break;
4116 case 0x7A:
4117 ext(output, "lp|startScriptQuick");
4118 break;
4119 case 0x7B:
4120 ext(output, "|stopObjectCode");
4121 break;
4122 case 0x7C:
4123 ext(output, "p|stopScript");
4124 break;
4125 case 0x7D:
4126 ext(output, "lpp|jumpToScript");
4127 break;
4128 case 0x7E:
4129 ext(output, "p|return");
4130 break;
4131 case 0x7F:
4132 ext(output, "lppp|startObject");
4133 break;
4134
4135 case 0x81:
4136 ext(output, "l|beginCutscene");
4137 break;
4138 case 0x82:
4139 ext(output, "|endCutscene");
4140 break;
4141 case 0x83:
4142 ext(output, "p|freezeUnfreeze");
4143 break;
4144 case 0x84:
4145 ext(output, "|beginOverride");
4146 break;
4147 case 0x85:
4148 ext(output, "|endOverride");
4149 break;
4150 case 0x86:
4151 ext(output, "|stopSentence");
4152 break;
4153 case 0x87:
4154 ext(output, "p|debug");
4155 break;
4156 case 0x89:
4157 ext(output, "lp|setClass");
4158 break;
4159 case 0x8A:
4160 ext(output, "pp|setState");
4161 break;
4162 case 0x8B:
4163 ext(output, "pp|setOwner");
4164 break;
4165 case 0x8C:
4166 ext(output, "pp|panCameraTo");
4167 break;
4168 case 0x8D:
4169 ext(output, "p|actorFollowCamera");
4170 break;
4171 case 0x8E:
4172 ext(output, "pp|setCameraAt");
4173 break;
4174 case 0x8F:
4175 ext(output,
4176 "x" "printActor\0"
4177 "\xC8p|baseop,"
4178 "\xC9|end,"
4179 "\xCApp|XY,"
4180 "\xCBp|color,"
4181 "\xCC|center,"
4182 "\xCDp|charset,"
4183 "\xCE|left,"
4184 "\xCF|overhead,"
4185 "\xD0|mumble,"
4186 "\xD1s|msg,"
4187 "\xD2|wrap"
4188 );
4189 break;
4190 case 0x90:
4191 PRINT_V8("printEgo");
4192 break;
4193 case 0x91:
4194 ext(output, "ps|talkActor");
4195 break;
4196 case 0x92:
4197 ext(output, "s|talkEgo");
4198 break;
4199 case 0x93:
4200 PRINT_V8("printLine");
4201 break;
4202 case 0x94:
4203 PRINT_V8("printCursor");
4204 break;
4205 case 0x95:
4206 PRINT_V8("printDebug");
4207 break;
4208 case 0x96:
4209 PRINT_V8("printSystem");
4210 break;
4211 case 0x97:
4212 PRINT_V8("blastText");
4213 break;
4214 case 0x98:
4215 ext(output, "pppp|drawObject");
4216 break;
4217
4218 case 0x9C:
4219 ext(output, "x" "cursorCommand\0"
4220 "\xDC|cursorOn,"
4221 "\xDD|cursorOff,"
4222 "\xDE|userPutOn,"
4223 "\xDF|userPutOff,"
4224 "\xE0|softCursorOn,"
4225 "\xE1|softCursorOff,"
4226 "\xE2|softUserputOn,"
4227 "\xE3|softUserputOff,"
4228 "\xE4pp|setCursorImg,"
4229 "\xE5pp|setCursorHotspot,"
4230 "\xE6p|makeCursorColorTransparent,"
4231 "\xE7p|initCharset,"
4232 "\xE8l|charsetColors,"
4233 "\xE9pp|setCursorPosition");
4234 break;
4235 case 0x9D:
4236 ext(output, "p|loadRoom");
4237 break;
4238 case 0x9E:
4239 ext(output, "ppz|loadRoomWithEgo");
4240 break;
4241 case 0x9F:
4242 ext(output, "ppp|walkActorToObj");
4243 break;
4244 case 0xA0:
4245 ext(output, "ppp|walkActorTo");
4246 break;
4247 case 0xA1:
4248 ext(output, "pppp|putActorAtXY");
4249 break;
4250 case 0xA2:
4251 ext(output, "zp|putActorAtObject");
4252 break;
4253 case 0xA3:
4254 ext(output, "pp|faceActor");
4255 break;
4256 case 0xA4:
4257 ext(output, "pp|animateActor");
4258 break;
4259 case 0xA5:
4260 ext(output, "ppp|doSentence");
4261 break;
4262 case 0xA6:
4263 ext(output, "z|pickupObject");
4264 break;
4265 case 0xA7:
4266 ext(output, "pl|setBoxFlags");
4267 break;
4268 case 0xA8:
4269 ext(output, "|createBoxMatrix");
4270 break;
4271
4272 case 0xAA:
4273 ext(output, "x" "resourceRoutines\0"
4274 "\x3Cp|loadCharset,"
4275 "\x3Dp|loadCostume,"
4276 "\x3Ep|loadObject,"
4277 "\x3Fp|loadRoom,"
4278 "\x40p|loadScript,"
4279 "\x41p|loadSound,"
4280 "\x42p|lockCostume,"
4281 "\x43p|lockRoom,"
4282 "\x44p|lockScript,"
4283 "\x45p|lockSound,"
4284 "\x46p|unlockCostume,"
4285 "\x47p|unlockRoom,"
4286 "\x48p|unlockScript,"
4287 "\x49p|unlockSound,"
4288 "\x4Ap|nukeCostume,"
4289 "\x4Bp|nukeRoom,"
4290 "\x4Cp|nukeScript,"
4291 "\x4Dp|nukeSound"
4292 );
4293 break;
4294 case 0xAB:
4295 ext(output, "x" "roomOps\0"
4296 "\x52pppp|setRoomPalette,"
4297 "\x55ppp|setRoomIntensity,"
4298 "\x57p|fade,"
4299 "\x58ppppp|setRoomRBGIntensity,"
4300 "\x59pppp|transformRoom,"
4301 "\x5App|colorCycleDelay,"
4302 "\x5Bpp|copyPalette,"
4303 "\x5Cp|newPalette,"
4304 "\x5D|saveGame,"
4305 "\x5Ep|LoadGame,"
4306 "\x5Fppppp|setRoomSaturation"
4307 );
4308 break;
4309 case 0xAC:
4310 // Note: these are guesses and may partially be wrong
4311 ext(output, "x" "actorOps\0"
4312 "\x64p|setActorCostume,"
4313 "\x65pp|setActorWalkSpeed,"
4314 "\x67|setActorDefAnim,"
4315 "\x68p|setActorInitFrame,"
4316 "\x69pp|setActorTalkFrame,"
4317 "\x6Ap|setActorWalkFrame,"
4318 "\x6Bp|setActorStandFrame,"
4319 "\x6C|setActorAnimSpeed,"
4320 "\x6D|setActorDefault," // = initActorLittle ?
4321 "\x6Ep|setActorElevation,"
4322 "\x6Fpp|setActorPalette,"
4323 "\x70p|setActorTalkColor,"
4324 "\x71s|setActorName,"
4325 "\x72p|setActorWidth,"
4326 "\x73p|setActorScale,"
4327 "\x74|setActorNeverZClip,"
4328 "\x75p|setActorAlwayZClip?,"
4329 "\x76|setActorIgnoreBoxes,"
4330 "\x77|setActorFollowBoxes,"
4331 "\x78p|setShadowMode,"
4332 "\x79pp|setActorTalkPos,"
4333 "\x7Ap|setCurActor,"
4334 "\x7Bpp|setActorAnimVar,"
4335 "\x7C|setActorIgnoreTurnsOn,"
4336 "\x7D|setActorIgnoreTurnsOff,"
4337 "\x7E|newActor,"
4338 "\x7Fp|setActorLayer,"
4339 "\x80|setActorStanding,"
4340 "\x81p|setActorDirection,"
4341 "\x82p|actorTurnToDirection,"
4342 "\x83p|setActorWalkScript,"
4343 "\x84p|setTalkScript,"
4344 "\x85|freezeActor,"
4345 "\x86|unfreezeActor,"
4346 "\x87p|setActorVolume,"
4347 "\x88p|setActorFrequency,"
4348 "\x89p|setActorPan"
4349 );
4350 break;
4351 case 0xAD:
4352 ext(output, "x" "cameraOps\0"
4353 "\x32|freezeCamera,"
4354 "\x33|unfreezeCamera"
4355 );
4356 break;
4357 case 0xAE:
4358 ext(output, "x" "verbOps\0"
4359 "\x96p|verbInit,"
4360 "\x97|verbNew,"
4361 "\x98|verbDelete,"
4362 "\x99s|verbLoadString,"
4363 "\x9App|verbSetXY,"
4364 "\x9B|verbOn,"
4365 "\x9C|verbOff,"
4366 "\x9Dp|verbSetColor,"
4367 "\x9Ep|verbSetHiColor,"
4368
4369 "\xA0p|verbSetDimColor,"
4370 "\xA1|verbSetDim,"
4371 "\xA2p|verbSetKey,"
4372 "\xA3p|verbLoadImg,"
4373 "\xA4p|verbSetToString,"
4374 "\xA5|verbSetCenter,"
4375 "\xA6p|verbSetCharset,"
4376 "\xA7p|verbSetLineSpacing"
4377 );
4378 break;
4379 case 0xAF:
4380 ext(output, "p|startSound");
4381 break;
4382
4383 case 0xB1:
4384 ext(output, "p|stopSound");
4385 break;
4386 case 0xB2:
4387 ext(output, "l|soundKludge");
4388 break;
4389 case 0xB3:
4390 ext(output, "x" "systemOps\0"
4391 "\x28|restart,"
4392 "\x29|quit");
4393 break;
4394 case 0xB4:
4395 ext(output, "x" "saveRestoreVerbs\0"
4396 "\xB4ppp|saveVerbs,"
4397 "\xB5ppp|restoreVerbs,"
4398 "\xB6ppp|deleteVerbs");
4399 break;
4400 case 0xB5:
4401 ext(output, "ps|setObjectName");
4402 break;
4403 case 0xB6:
4404 ext(output, "|getDateTime");
4405 break;
4406 case 0xB7:
4407 ext(output, "ppppp|drawBox");
4408 break;
4409
4410 case 0xB9:
4411 ext(output, "s|startVideo");
4412 break;
4413 case 0xBA:
4414 ext(output, "y" "kernelSetFunctions\0"
4415 "\xB|lockObject,"
4416 "\xC|unlockObject,"
4417 "\xD|remapCostume,"
4418 "\xE|remapCostumeInsert,"
4419 "\xF|setVideoFrameRate,"
4420
4421 "\x14|setBoxScale,"
4422 "\x15|setScaleSlot,"
4423 "\x16|setBannerColors,"
4424 "\x17|setActorChoreLimbFrame,"
4425 "\x18|clearTextQueue,"
4426 "\x19|saveGameWrite,"
4427 "\x1A|saveGameRead,"
4428 "\x1B|saveGameReadName,"
4429 "\x1C|saveGameStampScreenshot,"
4430 "\x1D|setKeyScript,"
4431 "\x1E|killAllScriptsExceptCurrent,"
4432 "\x1F|stopAllVideo,"
4433 "\x20|writeRegistryValue,"
4434 "\x21|paletteSetIntensity,"
4435 "\x22|queryQuit,"
4436
4437 "\x6C|buildPaletteShadow,"
4438 "\x6D|setPaletteShadow,"
4439
4440 "\x76|blastShadowObject,"
4441 "\x77|superBlastObject"
4442 );
4443 break;
4444
4445 case 0xC8:
4446 ext(output, "rlp|startScriptQuick2");
4447 break;
4448 case 0xC9:
4449 ext(output, "lppp|startObjectQuick");
4450 break;
4451 case 0xCA:
4452 ext(output, "rlp|pickOneOf");
4453 break;
4454 case 0xCB:
4455 ext(output, "rplp|pickOneOfDefault");
4456 break;
4457
4458 case 0xCD:
4459 ext(output, "rlp|isAnyOf");
4460 break;
4461 case 0xCE:
4462 ext(output, "rp|getRandomNumber");
4463 break;
4464 case 0xCF:
4465 ext(output, "rpp|getRandomNumberRange");
4466 break;
4467 case 0xD0:
4468 ext(output, "rlp|ifClassOfIs");
4469 break;
4470 case 0xD1:
4471 ext(output, "rp|getState");
4472 break;
4473 case 0xD2:
4474 ext(output, "rp|getOwner");
4475 break;
4476 case 0xD3:
4477 ext(output, "rp|isScriptRunning");
4478 break;
4479
4480 case 0xD5:
4481 ext(output, "rp|isSoundRunning");
4482 break;
4483 case 0xD6:
4484 ext(output, "rp|abs");
4485 break;
4486
4487 case 0xD8:
4488 ext(output, "ry" "kernelGetFunctions\0"
4489 "\x73|getWalkBoxAt,"
4490 "\x74|isPointInBox,"
4491 "\xCE|getRGBSlot,"
4492 "\xD3|getKeyState,"
4493 "\xD7|getBox,"
4494 "\xD8|findBlastObject,"
4495 "\xD9|actorHit,"
4496 "\xDA|lipSyncWidth,"
4497 "\xDB|lipSyncHeight,"
4498 "\xDC|actorTalkAnimation,"
4499 "\xDD|getMasterSFXVol,"
4500 "\xDE|getMasterVoiceVol,"
4501 "\xDF|getMasterMusicVol,"
4502 "\xE0|readRegistryValue,"
4503 "\xE1|imGetMusicPosition,"
4504 "\xE2|musicLipSyncWidth,"
4505 "\xE3|musicLipSyncHeight"
4506 );
4507 break;
4508 case 0xD9:
4509 ext(output, "rpp|isActorInBox");
4510 break;
4511 case 0xDA:
4512 ext(output, "rpp|getVerbEntrypoint");
4513 break;
4514 case 0xDB:
4515 ext(output, "rpp|getActorFromXY");
4516 break;
4517 case 0xDC:
4518 ext(output, "rpp|findObject");
4519 break;
4520 case 0xDD:
4521 ext(output, "rpp|getVerbFromXY");
4522 break;
4523
4524 case 0xDF:
4525 ext(output, "rpp|findInventory");
4526 break;
4527 case 0xE0:
4528 ext(output, "rp|getInventoryCount");
4529 break;
4530 case 0xE1:
4531 ext(output, "rpp|getAnimateVariable");
4532 break;
4533 case 0xE2:
4534 ext(output, "rp|getActorRoom");
4535 break;
4536 case 0xE3:
4537 ext(output, "rp|getActorWalkBox");
4538 break;
4539 case 0xE4:
4540 ext(output, "rp|getActorMoving");
4541 break;
4542 case 0xE5:
4543 ext(output, "rp|getActorCostume");
4544 break;
4545 case 0xE6:
4546 ext(output, "rp|getActorScaleX");
4547 break;
4548 case 0xE7:
4549 ext(output, "rp|getActorLayer");
4550 break;
4551 case 0xE8:
4552 ext(output, "rp|getActorElevation");
4553 break;
4554 case 0xE9:
4555 ext(output, "rp|getActorWidth");
4556 break;
4557 case 0xEA:
4558 ext(output, "rp|getObjectDir");
4559 break;
4560 case 0xEB:
4561 ext(output, "rp|getObjectX");
4562 break;
4563 case 0xEC:
4564 ext(output, "rp|getObjectY");
4565 break;
4566 case 0xED:
4567 ext(output, "rp|getActorChore");
4568 break;
4569 case 0xEE:
4570 ext(output, "rpp|getDistObjObj");
4571 break;
4572 case 0xEF:
4573 ext(output, "rpppp|getDistPtPt");
4574 break;
4575 case 0xF0:
4576 ext(output, "rp|getObjectImageX");
4577 break;
4578 case 0xF1:
4579 ext(output, "rp|getObjectImageY");
4580 break;
4581 case 0xF2:
4582 ext(output, "rp|getObjectImageWidth");
4583 break;
4584 case 0xF3:
4585 ext(output, "rp|getObjectImageHeight");
4586 break;
4587 case 0xF4:
4588 ext(output, "rp|getVerbX");
4589 break;
4590 case 0xF5:
4591 ext(output, "rp|getVerbY");
4592 break;
4593 case 0xF6:
4594 ext(output, "rps|stringWidth");
4595 break;
4596 case 0xF7:
4597 ext(output, "rp|getActorZPlane");
4598 break;
4599
4600 default:
4601 invalidop(NULL, code);
4602 break;
4603 }
4604 }
4605
4606 #define PRINT_V67(name) \
4607 do { \
4608 ext(output, "x" name "\0" \
4609 "\x41pp|XY," \
4610 "\x42p|color," \
4611 "\x43p|right," \
4612 "\x45|center," \
4613 "\x47|left," \
4614 "\x48|overhead," \
4615 "\x4A|mumble," \
4616 "\x4Bs|msg," \
4617 "\xFE|begin," \
4618 "\xFF|end" \
4619 ); \
4620 } while(0)
4621
next_line_V67(char * output)4622 void next_line_V67(char *output) {
4623 byte code = get_byte();
4624 StackEnt *se_a, *se_b;
4625
4626 switch (code) {
4627 case 0x0:
4628 push(se_int(get_byte()));
4629 break;
4630 case 0x1:
4631 push(se_int(get_word()));
4632 break;
4633 case 0x2:
4634 push(se_var(get_byte()));
4635 break;
4636 case 0x3:
4637 push(se_var(get_word()));
4638 break;
4639 case 0x6:
4640 push(se_array(get_byte(), NULL, pop()));
4641 break;
4642 case 0x7:
4643 push(se_array(get_word(), NULL, pop()));
4644 break;
4645 case 0xA:
4646 se_a = pop();
4647 push(se_array(get_byte(), pop(), se_a));
4648 break;
4649 case 0xB:
4650 se_a = pop();
4651 push(se_array(get_word(), pop(), se_a));
4652 break;
4653 case 0xC:
4654 se_a = dup(output, pop());
4655 push(se_a);
4656 push(se_a);
4657 break;
4658 case 0xD:
4659 push(se_oper(pop(), isZero));
4660 break;
4661 case 0xE:
4662 case 0xF:
4663 case 0x10:
4664 case 0x11:
4665 case 0x12:
4666 case 0x13:
4667 case 0x14:
4668 case 0x15:
4669 case 0x16:
4670 case 0x17:
4671 case 0x18:
4672 case 0x19:
4673 se_a = pop();
4674 se_b = pop();
4675 push(se_oper(se_b, (code - 0xE) + isEqual, se_a));
4676 break;
4677 case 0x1A:
4678 case 0xA7:
4679 kill(output, pop());
4680 break;
4681 case 0x42:
4682 writeVar(output, get_byte(), pop());
4683 break;
4684 case 0x43:
4685 writeVar(output, get_word(), pop());
4686 break;
4687 case 0x46:
4688 se_a = pop();
4689 writeArray(output, get_byte(), NULL, pop(), se_a);
4690 break;
4691 case 0x47:
4692 se_a = pop();
4693 writeArray(output, get_word(), NULL, pop(), se_a);
4694 break;
4695 case 0x4A:
4696 se_a = pop();
4697 se_b = pop();
4698 writeArray(output, get_byte(), pop(), se_b, se_a);
4699 break;
4700 case 0x4B:
4701 se_a = pop();
4702 se_b = pop();
4703 writeArray(output, get_word(), pop(), se_b, se_a);
4704 break;
4705 case 0x4E:
4706 addVar(output, get_byte(), 1);
4707 break;
4708 case 0x4F:
4709 addVar(output, get_word(), 1);
4710 break;
4711 case 0x52:
4712 addArray(output, get_byte(), pop(), 1);
4713 break;
4714 case 0x53:
4715 addArray(output, get_word(), pop(), 1);
4716 break;
4717 case 0x56:
4718 addVar(output, get_byte(), -1);
4719 break;
4720 case 0x57:
4721 addVar(output, get_word(), -1);
4722 break;
4723 case 0x5A:
4724 addArray(output, get_byte(), pop(), -1);
4725 break;
4726 case 0x5B:
4727 addArray(output, get_word(), pop(), -1);
4728 break;
4729 case 0x5C:
4730 jumpif(output, pop(), true);
4731 break;
4732 case 0x5D:
4733 jumpif(output, pop(), false);
4734 break;
4735 case 0x5E:
4736 ext(output, "lpp|startScript");
4737 break;
4738 case 0x5F:
4739 ext(output, "lp|startScriptQuick");
4740 break;
4741 case 0x60:
4742 ext(output, "lppp|startObject");
4743 break;
4744 case 0x61:
4745 ext(output, "pp|drawObject");
4746 break;
4747 case 0x62:
4748 ext(output, "ppp|drawObjectAt");
4749 break;
4750 case 0x63:
4751 if (g_options.heVersion)
4752 invalidop(NULL, code);
4753 else
4754 ext(output, "ppppp|drawBlastObject");
4755 break;
4756 case 0x64:
4757 if (g_options.heVersion)
4758 invalidop(NULL, code);
4759 else
4760 ext(output, "pppp|setBlastObjectWindow");
4761 break;
4762 case 0x65:
4763 ext(output, "|stopObjectCodeA");
4764 break;
4765 case 0x66:
4766 ext(output, "|stopObjectCodeB");
4767 break;
4768 case 0x67:
4769 ext(output, "|endCutscene");
4770 break;
4771 case 0x68:
4772 ext(output, "l|beginCutscene");
4773 break;
4774 case 0x69:
4775 ext(output, "|stopMusic");
4776 break;
4777 case 0x6A:
4778 ext(output, "p|freezeUnfreeze");
4779 break;
4780 case 0x6B:
4781 ext(output, "x" "cursorCommand\0"
4782 "\x90|cursorOn,"
4783 "\x91|cursorOff,"
4784 "\x92|userPutOn,"
4785 "\x93|userPutOff,"
4786 "\x94|softCursorOn,"
4787 "\x95|softCursorOff,"
4788 "\x96|softUserputOn,"
4789 "\x97|softUserputOff,"
4790 "\x99z|setCursorImg,"
4791 "\x9App|setCursorHotspot,"
4792 "\x9Cp|initCharset,"
4793 "\x9Dl|charsetColors,"
4794 "\xD6p|makeCursorColorTransparent");
4795 break;
4796 case 0x6C:
4797 ext(output, "|breakHere");
4798 break;
4799 case 0x6D:
4800 ext(output, "rlp|ifClassOfIs");
4801 break;
4802 case 0x6E:
4803 ext(output, "lp|setClass");
4804 break;
4805 case 0x6F:
4806 ext(output, "rp|getState");
4807 break;
4808 case 0x70:
4809 ext(output, "pp|setState");
4810 break;
4811 case 0x71:
4812 ext(output, "pp|setOwner");
4813 break;
4814 case 0x72:
4815 ext(output, "rp|getOwner");
4816 break;
4817 case 0x73:
4818 jump(output);
4819 break;
4820 case 0x74:
4821 if (g_options.heVersion >= 70) {
4822 ext(output, "x" "startSound\0"
4823 "\x9|setSoundFlag4,"
4824 "\x17ppp|setSoundVar,"
4825 "\x19pp|startWithFlag8,"
4826 "\x38|setQuickStartFlag,"
4827 "\xA4|setForceQueueFlag,"
4828 "\xDE|dummy,"
4829 "\xE0p|setFrequency,"
4830 "\xE6p|setChannel,"
4831 "\xE7p|setOffset,"
4832 "\xE8p|setId,"
4833 "\xF5|setLoop,"
4834 "\xFF|start");
4835 break;
4836 } else if (g_options.heVersion) {
4837 ext(output, "pp|startSound");
4838 } else {
4839 ext(output, "p|startSound");
4840 }
4841 break;
4842 case 0x75:
4843 ext(output, "p|stopSound");
4844 break;
4845 case 0x76:
4846 ext(output, "p|startMusic");
4847 break;
4848 case 0x77:
4849 ext(output, "p|stopObjectScript");
4850 break;
4851 case 0x78:
4852 if (g_options.scriptVersion < 7)
4853 ext(output, "p|panCameraTo");
4854 else
4855 ext(output, "pp|panCameraTo");
4856 break;
4857 case 0x79:
4858 ext(output, "p|actorFollowCamera");
4859 break;
4860 case 0x7A:
4861 if (g_options.scriptVersion < 7)
4862 ext(output, "p|setCameraAt");
4863 else
4864 ext(output, "pp|setCameraAt");
4865 break;
4866 case 0x7B:
4867 ext(output, "p|loadRoom");
4868 break;
4869 case 0x7C:
4870 ext(output, "p|stopScript");
4871 break;
4872 case 0x7D:
4873 ext(output, "ppp|walkActorToObj");
4874 break;
4875 case 0x7E:
4876 ext(output, "ppp|walkActorTo");
4877 break;
4878 case 0x7F:
4879 ext(output, "pppp|putActorInXY");
4880 break;
4881 case 0x80:
4882 ext(output, "zp|putActorAtObject");
4883 break;
4884 case 0x81:
4885 ext(output, "pp|faceActor");
4886 break;
4887 case 0x82:
4888 ext(output, "pp|animateActor");
4889 break;
4890 case 0x83:
4891 ext(output, "pppp|doSentence");
4892 break;
4893 case 0x84:
4894 ext(output, "z|pickupObject");
4895 break;
4896 case 0x85:
4897 ext(output, "ppz|loadRoomWithEgo");
4898 break;
4899 case 0x87:
4900 ext(output, "rp|getRandomNumber");
4901 break;
4902 case 0x88:
4903 ext(output, "rpp|getRandomNumberRange");
4904 break;
4905 case 0x8A:
4906 ext(output, "rp|getActorMoving");
4907 break;
4908 case 0x8B:
4909 ext(output, "rp|isScriptRunning");
4910 break;
4911 case 0x8C:
4912 ext(output, "rp|getActorRoom");
4913 break;
4914 case 0x8D:
4915 ext(output, "rp|getObjectX");
4916 break;
4917 case 0x8E:
4918 ext(output, "rp|getObjectY");
4919 break;
4920 case 0x8F:
4921 ext(output, "rp|getObjectDir");
4922 break;
4923 case 0x90:
4924 ext(output, "rp|getActorWalkBox");
4925 break;
4926 case 0x91:
4927 ext(output, "rp|getActorCostume");
4928 break;
4929 case 0x92:
4930 ext(output, "rpp|findInventory");
4931 break;
4932 case 0x93:
4933 ext(output, "rp|getInventoryCount");
4934 break;
4935 case 0x94:
4936 ext(output, "rpp|getVerbFromXY");
4937 break;
4938 case 0x95:
4939 ext(output, "|beginOverride");
4940 break;
4941 case 0x96:
4942 ext(output, "|endOverride");
4943 break;
4944 case 0x97:
4945 ext(output, "ps|setObjectName");
4946 break;
4947 case 0x98:
4948 ext(output, "rp|isSoundRunning");
4949 break;
4950 case 0x99:
4951 ext(output, "pl|setBoxFlags");
4952 break;
4953 case 0x9A:
4954 if (g_options.heVersion)
4955 invalidop(NULL, code);
4956 else
4957 ext(output, "|createBoxMatrix");
4958 break;
4959 case 0x9B:
4960 if (g_options.heVersion)
4961 ext(output, "x" "resourceRoutines\0"
4962 "\x64p|loadScript,"
4963 "\x65p|loadSound,"
4964 "\x66p|loadCostume,"
4965 "\x67p|loadRoom,"
4966 "\x68p|nukeScript,"
4967 "\x69p|nukeSound,"
4968 "\x6Ap|nukeCostume,"
4969 "\x6Bp|nukeRoom,"
4970 "\x6Cp|lockScript,"
4971 "\x6Dp|lockSound,"
4972 "\x6Ep|lockCostume,"
4973 "\x6Fp|lockRoom,"
4974 "\x70p|unlockScript,"
4975 "\x71p|unlockSound,"
4976 "\x72p|unlockCostume,"
4977 "\x73p|unlockRoom,"
4978 "\x75p|loadCharset,"
4979 "\x76p|nukeCharset,"
4980 "\x77z|loadFlObject,"
4981 "\x78p|queueloadScript,"
4982 "\x79p|queueloadSound,"
4983 "\x7Ap|queueloadCostume,"
4984 "\x7Bp|queueloadRoomImage,"
4985 "\x9fp|unlockImage,"
4986 "\xc0p|nukeImage,"
4987 "\xc9p|loadImage,"
4988 "\xcap|lockImage,"
4989 "\xcbp|queueloadImage,"
4990 "\xe9p|lockFlObject,"
4991 "\xebp|unlockFlObject,"
4992 "\xef|dummy");
4993 else
4994 ext(output, "x" "resourceRoutines\0"
4995 "\x64p|loadScript,"
4996 "\x65p|loadSound,"
4997 "\x66p|loadCostume,"
4998 "\x67p|loadRoom,"
4999 "\x68p|nukeScript,"
5000 "\x69p|nukeSound,"
5001 "\x6Ap|nukeCostume,"
5002 "\x6Bp|nukeRoom,"
5003 "\x6Cp|lockScript,"
5004 "\x6Dp|lockSound,"
5005 "\x6Ep|lockCostume,"
5006 "\x6Fp|lockRoom,"
5007 "\x70p|unlockScript,"
5008 "\x71p|unlockSound,"
5009 "\x72p|unlockCostume,"
5010 "\x73p|unlockRoom,"
5011 "\x75p|loadCharset,"
5012 "\x76p|nukeCharset,"
5013 "\x77z|loadFlObject");
5014 break;
5015 case 0x9C:
5016 if (g_options.heVersion)
5017 ext(output, "x" "roomOps\0"
5018 "\xACpp|roomScroll,"
5019 "\xAEpp|setScreen,"
5020 "\xAFpppp|setPalColor,"
5021 "\xB0|shakeOn,"
5022 "\xB1|shakeOff,"
5023 "\xB3ppp|darkenPalette,"
5024 "\xB4pp|saveLoadRoom,"
5025 "\xB5p|screenEffect,"
5026 "\xB6ppppp|darkenPalette,"
5027 "\xB7ppppp|setupShadowPalette,"
5028 "\xBApppp|palManipulate,"
5029 "\xBBpp|colorCycleDelay,"
5030 "\xD5p|setPalette,"
5031 "\xDCpp|copyPalColor,"
5032 "\xDDsp|saveLoad,"
5033 "\xEApp|swapObjects,"
5034 "\xECpp|setRoomPalette");
5035 else
5036 ext(output, "x" "roomOps\0"
5037 "\xACpp|roomScroll,"
5038 "\xAEpp|setScreen,"
5039 "\xAFpppp|setPalColor,"
5040 "\xB0|shakeOn,"
5041 "\xB1|shakeOff,"
5042 "\xB3ppp|darkenPalette,"
5043 "\xB4pp|saveLoadRoom,"
5044 "\xB5p|screenEffect,"
5045 "\xB6ppppp|darkenPalette,"
5046 "\xB7ppppp|setupShadowPalette,"
5047 "\xBApppp|palManipulate,"
5048 "\xBBpp|colorCycleDelay,"
5049 "\xD5p|setPalette,"
5050 "\xDCpp|copyPalColor");
5051 break;
5052 case 0x9D:
5053 if (g_options.heVersion)
5054 ext(output, "x" "actorOps\0"
5055 "\xC5p|setCurActor,"
5056 "\x1Epppp|setClipRect,"
5057 "\x4Cp|setCostume,"
5058 "\x4Dpp|setWalkSpeed,"
5059 "\x4El|setSound,"
5060 "\x4Fp|setWalkFrame,"
5061 "\x50pp|setTalkFrame,"
5062 "\x51p|setStandFrame,"
5063 "\x52ppp|actorSet:82:??,"
5064 "\x53|init,"
5065 "\x54p|setElevation,"
5066 "\x55|setDefAnim,"
5067 "\x56pp|setPalette,"
5068 "\x57p|setTalkColor,"
5069 "\x58s|setName,"
5070 "\x59p|setInitFrame,"
5071 "\x5Bp|setWidth,"
5072 "\x5Cp|setScale,"
5073 "\x5D|setNeverZClip,"
5074 "\x5Ep|setAlwayZClip,"
5075 "\x5F|setIgnoreBoxes,"
5076 "\x60|setFollowBoxes,"
5077 "\x61p|setAnimSpeed,"
5078 "\x62p|setShadowMode,"
5079 "\x63pp|setTalkPos,"
5080 "\xC6pp|setAnimVar,"
5081 "\xD7|setIgnoreTurnsOn,"
5082 "\xD8|setIgnoreTurnsOff,"
5083 "\xD9|initLittle,"
5084 "\xDA|drawToBackBuf,"
5085 "\xE1sp|setTalkieSlot");
5086 else
5087 ext(output, "x" "actorOps\0"
5088 "\xC5p|setCurActor,"
5089 "\x4Cp|setCostume,"
5090 "\x4Dpp|setWalkSpeed,"
5091 "\x4El|setSound,"
5092 "\x4Fp|setWalkFrame,"
5093 "\x50pp|setTalkFrame,"
5094 "\x51p|setStandFrame,"
5095 "\x52ppp|actorSet:82:??,"
5096 "\x53|init,"
5097 "\x54p|setElevation,"
5098 "\x55|setDefAnim,"
5099 "\x56pp|setPalette,"
5100 "\x57p|setTalkColor,"
5101 "\x58s|setName,"
5102 "\x59p|setInitFrame,"
5103 "\x5Bp|setWidth,"
5104 "\x5Cp|setScale,"
5105 "\x5D|setNeverZClip,"
5106 "\x5Ep|setAlwayZClip,"
5107 "\x5F|setIgnoreBoxes,"
5108 "\x60|setFollowBoxes,"
5109 "\x61p|setAnimSpeed,"
5110 "\x62p|setShadowMode,"
5111 "\x63pp|setTalkPos,"
5112 "\xC6pp|setAnimVar,"
5113 "\xD7|setIgnoreTurnsOn,"
5114 "\xD8|setIgnoreTurnsOff,"
5115 "\xD9|initLittle,"
5116 "\xE1p|setAlwayZClip?,"
5117 "\xE3p|setLayer,"
5118 "\xE4p|setWalkScript,"
5119 "\xE5|setStanding,"
5120 "\xE6p|setDirection,"
5121 "\xE7p|turnToDirection,"
5122 "\xE9|freeze,"
5123 "\xEA|unfreeze,"
5124 "\xEBp|setTalkScript");
5125 break;
5126 case 0x9E:
5127 if (g_options.heVersion)
5128 ext(output, "x" "verbOps\0"
5129 "\xC4p|setCurVerb,"
5130 "\x7Cp|loadImg,"
5131 "\x7Ds|loadString,"
5132 "\x7Ep|setColor,"
5133 "\x7Fp|setHiColor,"
5134 "\x80pp|setXY,"
5135 "\x81|setOn,"
5136 "\x82|setOff,"
5137 "\x83p|kill,"
5138 "\x84|init,"
5139 "\x85p|setDimColor,"
5140 "\x86|setDimmed,"
5141 "\x87p|setKey,"
5142 "\x88|setCenter,"
5143 "\x89p|setToString,"
5144 "\x8Bpp|setToObject,"
5145 "\x8Cp|setBkColor,"
5146 "\xFF|redraw");
5147 else
5148 ext(output, "x" "verbOps\0"
5149 "\xC4p|setCurVerb,"
5150 "\x7Cp|loadImg,"
5151 "\x7Ds|loadString,"
5152 "\x7Ep|setColor,"
5153 "\x7Fp|setHiColor,"
5154 "\x80pp|setXY,"
5155 "\x81|setOn,"
5156 "\x82|setOff,"
5157 "\x83|kill,"
5158 "\x84|init,"
5159 "\x85p|setDimColor,"
5160 "\x86|setDimmed,"
5161 "\x87p|setKey,"
5162 "\x88|setCenter,"
5163 "\x89p|setToString,"
5164 "\x8Bpp|setToObject,"
5165 "\x8Cp|setBkColor,"
5166 "\xFF|redraw");
5167 break;
5168 case 0x9F:
5169 ext(output, "rpp|getActorFromXY");
5170 break;
5171 case 0xA0:
5172 ext(output, "rpp|findObject");
5173 break;
5174 case 0xA1:
5175 ext(output, "lp|pseudoRoom");
5176 break;
5177 case 0xA2:
5178 ext(output, "rp|getActorElevation");
5179 break;
5180 case 0xA3:
5181 ext(output, "rpp|getVerbEntrypoint");
5182 break;
5183 case 0xA4:
5184 switch (get_byte()) {
5185 case 205:{
5186 int array = get_word();
5187 writeArray(output, array, NULL, pop(), se_get_string());
5188 }
5189 break;
5190 case 208:
5191 se_a = pop();
5192 se_b = se_get_list();
5193 writeArray(output, get_word(), NULL, se_a, se_b);
5194 break;
5195 case 212:
5196 se_a = pop();
5197 se_b = se_get_list();
5198 writeArray(output, get_word(), pop(), se_a, se_b);
5199 break;
5200 }
5201 break;
5202 case 0xA5:
5203 ext(output, "x" "saveRestoreVerbs\0"
5204 "\x8Dppp|saveVerbs,"
5205 "\x8Eppp|restoreVerbs,"
5206 "\x8Fppp|deleteVerbs");
5207 break;
5208 case 0xA6:
5209 ext(output, "ppppp|drawBox");
5210 break;
5211 case 0xA8:
5212 ext(output, "rp|getActorWidth");
5213 break;
5214 case 0xA9:
5215 ext(output, "x" "wait\0"
5216 "\xA8pj|waitForActor,"
5217 "\xA9|waitForMessage,"
5218 "\xAA|waitForCamera,"
5219 "\xAB|waitForSentence,"
5220 "\xE2pj|waitUntilActorDrawn,"
5221 "\xE8pj|waitUntilActorTurned,"
5222 );
5223 break;
5224 case 0xAA:
5225 ext(output, "rp|getActorScaleX");
5226 break;
5227 case 0xAB:
5228 ext(output, "rp|getActorAnimCounter1");
5229 break;
5230 case 0xAC:
5231 ext(output, "l|soundKludge");
5232 break;
5233 case 0xAD:
5234 ext(output, "rlp|isAnyOf");
5235 break;
5236 case 0xAE:
5237 if (g_options.heVersion)
5238 ext(output, "x" "systemOps\0"
5239 "\x9E|restart,"
5240 "\xA0|confirmShutDown,"
5241 "\xF4|shutDown,"
5242 "\xFB|startExec,"
5243 "\xFC|startGame");
5244 else
5245 ext(output, "x" "systemOps\0"
5246 "\x9E|restartGame,"
5247 "\x9F|pauseGame,"
5248 "\xA0|shutDown");
5249 break;
5250 case 0xAF:
5251 ext(output, "rpp|isActorInBox");
5252 break;
5253 case 0xB0:
5254 ext(output, "p|delay");
5255 break;
5256 case 0xB1:
5257 ext(output, "p|delaySeconds");
5258 break;
5259 case 0xB2:
5260 ext(output, "p|delayMinutes");
5261 break;
5262 case 0xB3:
5263 ext(output, "|stopSentence");
5264 break;
5265 case 0xB4:
5266 if (g_options.heVersion)
5267 PRINT_V7HE("printLine");
5268 else
5269 PRINT_V67("printLine");
5270 break;
5271 case 0xB5:
5272 if (g_options.heVersion)
5273 PRINT_V7HE("printCursor");
5274 else
5275 PRINT_V67("printCursor");
5276 break;
5277 case 0xB6:
5278 if (g_options.heVersion)
5279 PRINT_V7HE("printDebug");
5280 else
5281 PRINT_V67("printDebug");
5282 break;
5283 case 0xB7:
5284 if (g_options.heVersion)
5285 PRINT_V7HE("printSystem");
5286 else
5287 PRINT_V67("printSystem");
5288 break;
5289 case 0xB8:
5290 // This is *almost* identical to the other print opcodes, only the 'begin' subop differs
5291 if (g_options.heVersion) {
5292 ext(output, "x" "printActor\0"
5293 "\x41pp|XY,"
5294 "\x42p|color,"
5295 "\x43p|right,"
5296 "\x45|center,"
5297 "\x47|left,"
5298 "\x48|overhead,"
5299 "\x4A|mumble,"
5300 "\x4Bs|msg,"
5301 "\xF9l|colors,"
5302 "\xC2lps|debug,"
5303 "\xE1p|getText,"
5304 "\xFEp|begin,"
5305 "\xFF|end");
5306 } else {
5307 ext(output, "x" "printActor\0"
5308 "\x41pp|XY,"
5309 "\x42p|color,"
5310 "\x43p|right,"
5311 "\x45|center,"
5312 "\x47|left,"
5313 "\x48|overhead,"
5314 "\x4A|mumble,"
5315 "\x4Bs|msg,"
5316 "\xFEp|begin,"
5317 "\xFF|end");
5318 }
5319 break;
5320 case 0xB9:
5321 if (g_options.heVersion)
5322 PRINT_V7HE("printEgo");
5323 else
5324 PRINT_V67("printEgo");
5325 break;
5326 case 0xBA:
5327 ext(output, "ps|talkActor");
5328 break;
5329 case 0xBB:
5330 ext(output, "s|talkEgo");
5331 break;
5332 case 0xBC:
5333 ext(output, "x" "dimArray\0"
5334 "\xC7pv|int,"
5335 "\xC8pv|bit,"
5336 "\xC9pv|nibble,"
5337 "\xCApv|byte,"
5338 "\xCBpv|string,"
5339 "\xCCv|nukeArray");
5340 break;
5341 case 0xBD:
5342 if (g_options.heVersion)
5343 ext(output, "|stopObjectCode");
5344 else
5345 invalidop(NULL, code);
5346 break;
5347 case 0xBE:
5348 // TODO: this loads another script which does something like
5349 // stack altering and then finishes (usually with opcode 0xBD).
5350 // When stack is changed, further disassembly is wrong.
5351 // This is widely used in HE games.
5352 // As there are cases when called script does not alter the
5353 // stack, it's not correct to use "rlpp|..." here
5354 ext(output, "lpp|startObjectQuick");
5355 break;
5356 case 0xBF:
5357 ext(output, "lp|startScriptQuick2");
5358 break;
5359 case 0xC0:
5360 ext(output, "x" "dim2dimArray\0"
5361 "\xC7ppv|int,"
5362 "\xC8ppv|bit,"
5363 "\xC9ppv|nibble,"
5364 "\xCAppv|byte,"
5365 "\xCBppv|string");
5366 break;
5367 case 0xC1:
5368 ext(output, "ps|trace");
5369 break;
5370 case 0xC4:
5371 ext(output, "rp|abs");
5372 break;
5373 case 0xC5:
5374 ext(output, "rpp|getDistObjObj");
5375 break;
5376 case 0xC6:
5377 ext(output, "rppp|getDistObjPt");
5378 break;
5379 case 0xC7:
5380 ext(output, "rpppp|getDistPtPt");
5381 break;
5382 case 0xC8:
5383 if (g_options.heVersion)
5384 ext(output, "ry" "kernelGetFunctions\0"
5385 "\x1|virtScreenSave"
5386 );
5387 else if (g_options.scriptVersion == 7)
5388 ext(output, "ry" "kernelGetFunctions\0"
5389 "\x73|getWalkBoxAt,"
5390 "\x74|isPointInBox,"
5391 "\xCE|getRGBSlot,"
5392 "\xCF|getObjectXPos,"
5393 "\xD0|getObjectYPos,"
5394 "\xD1|getObjectWidth,"
5395 "\xD2|getObjectHeight,"
5396 "\xD3|getKeyState,"
5397 "\xD4|getActorFrame,"
5398 "\xD5|getVerbXPos,"
5399 "\xD6|getVerbYPos,"
5400 "\xD7|getBoxFlags"
5401 );
5402 else
5403 ext(output, "ry" "kernelGetFunctions\0"
5404 "\x71|getPixel"
5405 );
5406 break;
5407 case 0xC9:
5408 if (g_options.heVersion)
5409 ext(output, "y" "kernelSetFunctions\0"
5410 "\x1|virtScreenLoad"
5411 );
5412 else if (g_options.scriptVersion == 7)
5413 ext(output, "y" "kernelSetFunctions\0"
5414 "\x4|grabCursor,"
5415 "\x6|startVideo,"
5416 "\xC|setCursorImg,"
5417 "\xD|remapCostume,"
5418 "\xE|remapCostumeInsert,"
5419 "\xF|setVideoFrameRate,"
5420
5421 "\x10|enqueueTextCentered,"
5422 "\x11|enqueueTextNormal,"
5423 "\x12|setMouseXY,"
5424 "\x14|setRadioChatter,"
5425
5426 "\x6B|setActorScale,"
5427 "\x6C|buildPaletteShadow,"
5428 "\x6D|setPaletteShadow,"
5429
5430 "\x72|unk114,"
5431 "\x75|freezeScripts,"
5432 "\x76|blastShadowObject,"
5433 "\x77|superBlastObject,"
5434 "\x7C|setSaveSound,"
5435 "\xD7|setSubtitles,"
5436 );
5437 else
5438 ext(output, "y" "kernelSetFunctions\0"
5439 "\x3|dummy,"
5440 "\x4|grabCursor,"
5441 "\x5|fadeOut,"
5442 "\x6|redrawScreen,"
5443 "\x8|startManiac,"
5444 "\x9|killAllScriptsExceptCurrent,"
5445 "\x68|nukeFlObjects,"
5446 "\x6B|setActorScale,"
5447 "\x6C|setupShadowPalette,"
5448 "\x6D|setupShadowPalette,"
5449 "\x6E|clearCharsetMask,"
5450 "\x6F|setActorShadowMode,"
5451 "\x70|shiftShadowPalette,"
5452 "\x72|noirMode,"
5453 "\x75|freezeScripts,"
5454 "\x77|superBlastObject,"
5455 "\x78|swapPalColors,"
5456 "\x7A|setSoundResult,"
5457 "\x7B|copyPalColor,"
5458 "\x7C|setSaveSound,"
5459 );
5460 break;
5461 case 0xCA:
5462 ext(output, "p|delayFrames");
5463 break;
5464 case 0xCB:
5465 ext(output, "rlp|pickOneOf");
5466 break;
5467 case 0xCC:
5468 ext(output, "rplp|pickOneOfDefault");
5469 break;
5470 case 0xCD:
5471 ext(output, "pppp|stampObject");
5472 break;
5473 case 0xD0:
5474 ext(output, "|getDateTime");
5475 break;
5476 case 0xD1:
5477 ext(output, "|stopTalking");
5478 break;
5479 case 0xD2:
5480 ext(output, "rpp|getAnimateVariable");
5481 break;
5482 case 0xD4:
5483 ext(output, "vpp|shuffle");
5484 break;
5485 case 0xD5:
5486 ext(output, "lpp|jumpToScript");
5487 break;
5488 case 0xD6:
5489 se_a = pop();
5490 se_b = pop();
5491 push(se_oper(se_b, operBand, se_a));
5492 break;
5493 case 0xD7:
5494 se_a = pop();
5495 se_b = pop();
5496 push(se_oper(se_b, operBor, se_a));
5497 break;
5498 case 0xD8:
5499 ext(output, "rp|isRoomScriptRunning");
5500 break;
5501 case 0xD9:
5502 if (g_options.heVersion)
5503 ext(output, "p|closeFile");
5504 else
5505 invalidop(NULL, code);
5506 break;
5507 case 0xDA:
5508 if (g_options.heVersion)
5509 ext(output, "rsp|openFile");
5510 else
5511 invalidop(NULL, code);
5512 break;
5513 case 0xDB:
5514 if (g_options.heVersion)
5515 ext(output, "rpp|readFile");
5516 else
5517 invalidop(NULL, code);
5518 break;
5519 case 0xDC:
5520 if (g_options.heVersion)
5521
5522 ext(output, "ppp|writeFile");
5523 else
5524 invalidop(NULL, code);
5525 break;
5526
5527 case 0xDD:
5528 ext(output, "rp|findAllObjects");
5529 break;
5530 case 0xDE:
5531 if (g_options.heVersion)
5532 ext(output, "s|deleteFile");
5533 else
5534 invalidop(NULL, code);
5535 break;
5536 case 0xDF:
5537 if (g_options.heVersion)
5538 ext(output, "ss|renameFile");
5539 else
5540 invalidop(NULL, code);
5541 break;
5542 case 0xE0:
5543 if (g_options.heVersion)
5544 ext(output, "x" "soundOps\0"
5545 "\xDEp|setMusicVolume,"
5546 "\xDF|dummy,"
5547 "\xE0p|setSoundFrequency");
5548 else
5549 invalidop(NULL, code);
5550 break;
5551 case 0xE1:
5552 ext(output, "rpp|getPixel");
5553 break;
5554 case 0xE2:
5555 if (g_options.heVersion)
5556 ext(output, "p|localizeArrayToScript");
5557 else
5558 invalidop(NULL, code);
5559 break;
5560 case 0xE3:
5561 ext(output, "rlw|pickVarRandom");
5562 break;
5563 case 0xE4:
5564 ext(output, "p|setBotSet");
5565 break;
5566 case 0xE9:
5567 if (g_options.heVersion)
5568 ext(output, "ppp|seekFilePos");
5569 else
5570 invalidop(NULL, code);
5571 break;
5572 case 0xEA:
5573 if (g_options.heVersion)
5574 ext(output, "x" "redimArray\0"
5575 "\xC7ppv|int,"
5576 "\xCAppv|byte");
5577 else
5578 invalidop(NULL, code);
5579 break;
5580 case 0xEB:
5581 if (g_options.heVersion)
5582 ext(output, "rp|readFilePos");
5583 else
5584 invalidop(NULL, code);
5585 break;
5586 case 0xEC:
5587 if (g_options.heVersion)
5588 invalidop(NULL, code);
5589 else
5590 ext(output, "rp|getActorLayer");
5591 break;
5592 case 0xED:
5593 if (g_options.heVersion)
5594 ext(output, "rppp|getStringWidth");
5595 else
5596 ext(output, "rp|getObjectNewDir");
5597 break;
5598 case 0xEE:
5599 if (g_options.heVersion)
5600 ext(output, "rp|getStringLen");
5601 else
5602 invalidop(NULL, code);
5603 break;
5604 case 0xEF:
5605 if (g_options.heVersion)
5606 ext(output, "rppp|appendString");
5607 else
5608 invalidop(NULL, code);
5609 break;
5610 case 0xF1:
5611 if (g_options.heVersion)
5612 ext(output, "rpp|compareString");
5613 else
5614 invalidop(NULL, code);
5615 break;
5616 case 0xF2:
5617 if (g_options.heVersion) {
5618 ext(output, "rx" "isResourceLoaded\0"
5619 "\x12p|image,"
5620 "\xE2p|room,"
5621 "\xE3p|costume,"
5622 "\xE4p|sound,"
5623 "\xE5p|script");
5624 } else {
5625 invalidop(NULL, code);
5626 }
5627 break;
5628 case 0xF3:
5629 if (g_options.heVersion) {
5630 ext(output, "ru" "readINI\0"
5631 "\x01s|number,"
5632 "\x02s|string");
5633 } else {
5634 invalidop(NULL, code);
5635 }
5636 break;
5637 case 0xF4:
5638 if (g_options.heVersion) {
5639 ext(output, "u" "writeINI\0"
5640 "\x01ps|number,"
5641 "\x02pss|string");
5642 } else {
5643 invalidop(NULL, code);
5644 }
5645 break;
5646 case 0xF5:
5647 if (g_options.heVersion)
5648 ext(output, "rppp|getStringLenForWidth");
5649 else
5650 invalidop(NULL, code);
5651 break;
5652 case 0xF6:
5653 if (g_options.heVersion)
5654 ext(output, "rpppp|getCharIndexInString");
5655 else
5656 invalidop(NULL, code);
5657 break;
5658 case 0xF7:
5659 if (g_options.heVersion)
5660 ext(output, "rpp|findBox");
5661 else
5662 invalidop(NULL, code);
5663 break;
5664 case 0xF9:
5665 if (g_options.heVersion)
5666 ext(output, "s|createDirectory");
5667 else
5668 invalidop(NULL, code);
5669 break;
5670 case 0xFA:
5671 if (g_options.heVersion) {
5672 ext(output, "x" "setSystemMessage\0"
5673 "\xF0s|unk1,"
5674 "\xF1s|versionMsg,"
5675 "\xF2s|unk3,"
5676 "\xF3s|titleMsg");
5677 } else
5678 invalidop(NULL, code);
5679 break;
5680 case 0xFB:
5681 if (g_options.heVersion)
5682 ext(output, "x" "polygonOps\0"
5683 "\xF6ppppppppp|polygonStore,"
5684 "\xF7pp|polygonErase,"
5685 "\xF8ppppppppp|polygonStore,"
5686 );
5687 else
5688 invalidop(NULL, code);
5689 break;
5690 case 0xFC:
5691 if (g_options.heVersion)
5692 ext(output, "rpp|polygonHit");
5693 else
5694 invalidop(NULL, code);
5695 break;
5696 default:
5697 invalidop(NULL, code);
5698 break;
5699 }
5700 }
5701