1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 
24 #include "common/debug.h"
25 #include "common/util.h"
26 
27 #include "sky/debug.h"
28 #include "sky/grid.h"
29 #include "sky/logic.h"
30 #include "sky/mouse.h"
31 #include "sky/screen.h"
32 #include "sky/sky.h"
33 #include "sky/struc.h"
34 #include "sky/compact.h"
35 
36 namespace Sky {
37 
38 static const char *const logic_table_names[] = {
39 	"return",
40 	"Logic::script",
41 	"Logic::auto_route",
42 	"Logic::ar_anim",
43 	"Logic::ar_turn",
44 	"Logic::alt",
45 	"Logic::anim",
46 	"Logic::turn",
47 	"Logic::cursor",
48 	"Logic::talk",
49 	"Logic::listen",
50 	"Logic::stopped",
51 	"Logic::choose",
52 	"Logic::frames",
53 	"Logic::pause",
54 	"Logic::wait_sync",
55 	"Logic::simple_anim"
56 };
57 
58 static const char opcode_par[] = {
59 	1,
60 	0,
61 	1,
62 	0,
63 	0,
64 	1,
65 	1,
66 	0,
67 	0,
68 	1,
69 	0,
70 	2,
71 	0,
72 	0,
73 	1,
74 	1,
75 	1,
76 	0,
77 	1,
78 	0,
79 	0
80 };
81 
82 static const char *const opcodes[] = {
83 	"push_variable",
84 	"less_than",
85 	"push_number",
86 	"not_equal",
87 	"if_and",
88 	"skip_zero",
89 	"pop_var",
90 	"minus",
91 	"plus",
92 	"skip_always",
93 	"if_or",
94 	"call_mcode",
95 	"more_than",
96 	"script_exit",
97 	"switch",
98 	"push_offset",
99 	"pop_offset",
100 	"is_equal",
101 	"skip_nz",
102 	"script_exit",
103 	"restart_script"
104 };
105 
106 static const char *const mcodes[] = {
107 	"fn_cache_chip",
108 	"fn_cache_fast",
109 	"fn_draw_screen",
110 	"fn_ar",
111 	"fn_ar_animate",
112 	"fn_idle",
113 	"fn_interact",
114 	"fn_start_sub",
115 	"fn_they_start_sub",
116 	"fn_assign_base",
117 	"fn_disk_mouse",
118 	"fn_normal_mouse",
119 	"fn_blank_mouse",
120 	"fn_cross_mouse",
121 	"fn_cursor_right",
122 	"fn_cursor_left",
123 	"fn_cursor_down",
124 	"fn_open_hand",
125 	"fn_close_hand",
126 	"fn_get_to",
127 	"fn_set_to_stand",
128 	"fn_turn_to",
129 	"fn_arrived",
130 	"fn_leaving",
131 	"fn_set_alternate",
132 	"fn_alt_set_alternate",
133 	"fn_kill_id",
134 	"fn_no_human",
135 	"fn_add_human",
136 	"fn_add_buttons",
137 	"fn_no_buttons",
138 	"fn_set_stop",
139 	"fn_clear_stop",
140 	"fn_pointer_text",
141 	"fn_quit",
142 	"fn_speak_me",
143 	"fn_speak_me_dir",
144 	"fn_speak_wait",
145 	"fn_speak_wait_dir",
146 	"fn_chooser",
147 	"fn_highlight",
148 	"fn_text_kill",
149 	"fn_stop_mode",
150 	"fn_we_wait",
151 	"fn_send_sync",
152 	"fn_send_fast_sync",
153 	"fn_send_request",
154 	"fn_clear_request",
155 	"fn_check_request",
156 	"fn_start_menu",
157 	"fn_unhighlight",
158 	"fn_face_id",
159 	"fn_foreground",
160 	"fn_background",
161 	"fn_new_background",
162 	"fn_sort",
163 	"fn_no_sprite_engine",
164 	"fn_no_sprites_a6",
165 	"fn_reset_id",
166 	"fn_toggle_grid",
167 	"fn_pause",
168 	"fn_run_anim_mod",
169 	"fn_simple_mod",
170 	"fn_run_frames",
171 	"fn_await_sync",
172 	"fn_inc_mega_set",
173 	"fn_dec_mega_set",
174 	"fn_set_mega_set",
175 	"fn_move_items",
176 	"fn_new_list",
177 	"fn_ask_this",
178 	"fn_random",
179 	"fn_person_here",
180 	"fn_toggle_mouse",
181 	"fn_mouse_on",
182 	"fn_mouse_off",
183 	"fn_fetch_x",
184 	"fn_fetch_y",
185 	"fn_test_list",
186 	"fn_fetch_place",
187 	"fn_custom_joey",
188 	"fn_set_palette",
189 	"fn_text_module",
190 	"fn_change_name",
191 	"fn_mini_load",
192 	"fn_flush_buffers",
193 	"fn_flush_chip",
194 	"fn_save_coods",
195 	"fn_plot_grid",
196 	"fn_remove_grid",
197 	"fn_eyeball",
198 	"fn_cursor_up",
199 	"fn_leave_section",
200 	"fn_enter_section",
201 	"fn_restore_game",
202 	"fn_restart_game",
203 	"fn_new_swing_seq",
204 	"fn_wait_swing_end",
205 	"fn_skip_intro_code",
206 	"fn_blank_screen",
207 	"fn_print_credit",
208 	"fn_look_at",
209 	"fn_linc_text_module",
210 	"fn_text_kill2",
211 	"fn_set_font",
212 	"fn_start_fx",
213 	"fn_stop_fx",
214 	"fn_start_music",
215 	"fn_stop_music",
216 	"fn_fade_down",
217 	"fn_fade_up",
218 	"fn_quit_to_dos",
219 	"fn_pause_fx",
220 	"fn_un_pause_fx",
221 	"fn_printf"
222 };
223 
224 static const char *const scriptVars[] = {
225 	"result",
226 	"screen",
227 	"logic_list_no",
228 	"safe_logic_list",
229 	"low_list_no",
230 	"high_list_no",
231 	"mouse_list_no",
232 	"safe_mouse_list",
233 	"draw_list_no",
234 	"second_draw_list",
235 	"do_not_use",
236 	"music_module",
237 	"cur_id",
238 	"mouse_status",
239 	"mouse_stop",
240 	"button",
241 	"but_repeat",
242 	"special_item",
243 	"get_off",
244 	"safe_click",
245 	"click_id",
246 	"player_id",
247 	"cursor_id",
248 	"pointer_pen",
249 	"last_pal",
250 	"safex",
251 	"safey",
252 	"player_x",
253 	"player_y",
254 	"player_mood",
255 	"player_screen",
256 	"old_x",
257 	"old_y",
258 	"joey_x",
259 	"joey_y",
260 	"joey_list",
261 	"flag",
262 	"hit_id",
263 	"player_target",
264 	"joey_target",
265 	"mega_target",
266 	"layer_0_id",
267 	"layer_1_id",
268 	"layer_2_id",
269 	"layer_3_id",
270 	"grid_1_id",
271 	"grid_2_id",
272 	"grid_3_id",
273 	"stop_grid",
274 	"text_rate",
275 	"text_speed",
276 	"the_chosen_one",
277 	"chosen_anim",
278 	"text1",
279 	"anim1",
280 	"text2",
281 	"anim2",
282 	"text3",
283 	"anim3",
284 	"text4",
285 	"anim4",
286 	"text5",
287 	"anim5",
288 	"text6",
289 	"anim6",
290 	"text7",
291 	"anim7",
292 	"text8",
293 	"anim8",
294 	"o0",
295 	"o1",
296 	"o2",
297 	"o3",
298 	"o4",
299 	"o5",
300 	"o6",
301 	"o7",
302 	"o8",
303 	"o9",
304 	"o10",
305 	"o11",
306 	"o12",
307 	"o13",
308 	"o14",
309 	"o15",
310 	"o16",
311 	"o17",
312 	"o18",
313 	"o19",
314 	"o20",
315 	"o21",
316 	"o22",
317 	"o23",
318 	"o24",
319 	"o25",
320 	"o26",
321 	"o27",
322 	"o28",
323 	"o29",
324 	"first_icon",
325 	"menu_length",
326 	"scroll_offset",
327 	"menu",
328 	"object_held",
329 	"icon_lit",
330 	"at_sign",
331 	"fire_exit_flag",
332 	"small_door_flag",
333 	"jobs_greet",
334 	"lamb_greet",
335 	"knob_flag",
336 	"lazer_flag",
337 	"cupb_flag",
338 	"jobs_loop",
339 	"done_something",
340 	"rnd",
341 	"jobs_text",
342 	"jobs_loc1",
343 	"jobs_loc2",
344 	"jobs_loc3",
345 	"id_talking",
346 	"alarm",
347 	"alarm_count",
348 	"clearing_alarm",
349 	"jobs_friend",
350 	"joey_born",
351 	"joey_text",
352 	"joey_peeved",
353 	"knows_linc",
354 	"linc_overmann",
355 	"reich_entry",
356 	"seen_lock",
357 	"wshop_text",
358 	"knows_firedoor",
359 	"knows_furnace",
360 	"jobs_got_spanner",
361 	"jobs_got_sandwich",
362 	"jobs_firedoor",
363 	"knows_transporter",
364 	"joey_loc1",
365 	"joey_loc2",
366 	"joey_loc3",
367 	"joey_screen",
368 	"cur_section",
369 	"old_section",
370 	"joey_section",
371 	"lamb_section",
372 	"knows_overmann",
373 	"jobs_overmann",
374 	"jobs_seen_joey",
375 	"anita_text",
376 	"anit_loc1",
377 	"anit_loc2",
378 	"anit_loc3",
379 	"lamb_friend",
380 	"lamb_sick",
381 	"lamb_crawly",
382 	"lamb_loc1",
383 	"lamb_loc2",
384 	"lamb_loc3",
385 	"lamb_got_spanner",
386 	"lamb_text",
387 	"knows_auditor",
388 	"lamb_security",
389 	"lamb_auditor",
390 	"fore_text",
391 	"transporter_alive",
392 	"anita_friend",
393 	"anita_stop",
394 	"anita_count",
395 	"knows_security",
396 	"fore_loc1",
397 	"fore_loc2",
398 	"fore_loc3",
399 	"fore_friend",
400 	"knows_dlinc",
401 	"seen_lift",
402 	"player_sound",
403 	"guard_linc",
404 	"guard_text",
405 	"guar_loc1",
406 	"guar_loc2",
407 	"guar_loc3",
408 	"guard_talk",
409 	"lamb_out",
410 	"guard_warning",
411 	"wshp_loc1",
412 	"wshp_loc2",
413 	"wshp_loc3",
414 	"jobs_linc",
415 	"knows_port",
416 	"jobs_port",
417 	"joey_overmann",
418 	"joey_count",
419 	"knows_pipes",
420 	"knows_hobart",
421 	"fore_hobart",
422 	"fore_overmann",
423 	"anit_text",
424 	"seen_eye",
425 	"anita_dlinc",
426 	"seen_dis_lift",
427 	"lamb_move_anita",
428 	"lamb_stat",
429 	"machine_stops",
430 	"guard_stat",
431 	"guard_hobart",
432 	"gordon_text",
433 	"gord_loc1",
434 	"gord_loc2",
435 	"gord_loc3",
436 	"lamb_hobart",
437 	"anita_loc1",
438 	"anita_loc2",
439 	"anita_loc3",
440 	"knows_elders",
441 	"anita_elders",
442 	"anita_overmann",
443 	"stay_here",
444 	"joey_pause",
445 	"knows_break_in",
446 	"joey_break_in",
447 	"joey_lift",
448 	"stair_talk",
449 	"blown_top",
450 	"tamper_flag",
451 	"knows_reich",
452 	"gordon_reich",
453 	"open_panel",
454 	"panel_count",
455 	"wreck_text",
456 	"press_button",
457 	"touch_count",
458 	"gordon_overmann",
459 	"lamb_reich",
460 	"exit_stores",
461 	"henri_text",
462 	"henr_loc1",
463 	"henr_loc2",
464 	"henr_loc3",
465 	"got_sponsor",
466 	"used_deodorant",
467 	"lob_dad_text",
468 	"lob_son_text",
469 	"scan_talk",
470 	"dady_loc1",
471 	"dady_loc2",
472 	"dady_loc3",
473 	"samm_loc1",
474 	"samm_loc2",
475 	"samm_loc3",
476 	"dirty_card",
477 	"wrek_loc1",
478 	"wrek_loc2",
479 	"wrek_loc3",
480 	"crushed_nuts",
481 	"got_port",
482 	"anita_port",
483 	"got_jammer",
484 	"knows_anita",
485 	"anita_hobart",
486 	"local_count",
487 	"lamb_joey",
488 	"stop_store",
489 	"knows_suit",
490 	"joey_box",
491 	"asked_box",
492 	"shell_count",
493 	"got_cable",
494 	"local_flag",
495 	"search_flag",
496 	"rad_count",
497 	"rad_text",
498 	"radm_loc1",
499 	"radm_loc2",
500 	"radm_loc3",
501 	"gordon_off",
502 	"knows_jobsworth",
503 	"rad_back_flag",
504 	"lamb_lift",
505 	"knows_cat",
506 	"lamb_screwed",
507 	"tour_flag",
508 	"foreman_reactor",
509 	"foreman_anita",
510 	"burke_text",
511 	"burk_loc1",
512 	"burk_loc2",
513 	"burk_loc3",
514 	"burke_anchor",
515 	"jason_text",
516 	"jaso_loc1",
517 	"jaso_loc2",
518 	"helg_loc2",
519 	"say_to_helga",
520 	"interest_count",
521 	"anchor_text",
522 	"anchor_overmann",
523 	"anch_loc1",
524 	"anch_loc2",
525 	"anch_loc3",
526 	"anchor_count",
527 	"lamb_anchor",
528 	"anchor_port",
529 	"knows_stephen",
530 	"knows_ghoul",
531 	"anchor_talk",
532 	"joey_hook",
533 	"joey_done_dir",
534 	"bios_loc1",
535 	"bios_loc2",
536 	"bios_loc3",
537 	"got_hook",
538 	"anchor_anita",
539 	"trev_loc1",
540 	"trev_loc2",
541 	"trev_loc3",
542 	"trevor_text",
543 	"trev_text",
544 	"trev_overmann",
545 	"lamb_smell",
546 	"art_flag",
547 	"trev_computer",
548 	"helga_text",
549 	"helg_loc1",
550 	"helg_loc3",
551 	"bios_loc4",
552 	"gallagher_text",
553 	"gall_loc1",
554 	"gall_loc2",
555 	"gall_loc3",
556 	"warn_lamb",
557 	"open_apts",
558 	"store_count",
559 	"foreman_auditor",
560 	"frozen_assets",
561 	"read_report",
562 	"seen_holo",
563 	"knows_subway",
564 	"exit_flag",
565 	"father_text",
566 	"lamb_fix",
567 	"read_briefing",
568 	"seen_shaft",
569 	"knows_mother",
570 	"console_type",
571 	"hatch_selected",
572 	"seen_walters",
573 	"joey_fallen",
574 	"jbel_loc1",
575 	"lbel_loc1",
576 	"lbel_loc2",
577 	"jobsworth_speech",
578 	"jobs_alert",
579 	"jobs_alarmed_ref",
580 	"safe_joey_recycle",
581 	"safe_joey_sss",
582 	"safe_joey_mission",
583 	"safe_trans_mission",
584 	"safe_slot_mission",
585 	"safe_corner_mission",
586 	"safe_joey_logic",
587 	"safe_gordon_speech",
588 	"safe_button_mission",
589 	"safe_dad_speech",
590 	"safe_son_speech",
591 	"safe_skorl_speech",
592 	"safe_uchar_speech",
593 	"safe_wreck_speech",
594 	"safe_anita_speech",
595 	"safe_lamb_speech",
596 	"safe_foreman_speech",
597 	"joey_42_mission",
598 	"joey_junction_mission",
599 	"safe_welder_mission",
600 	"safe_joey_weld",
601 	"safe_radman_speech",
602 	"safe_link_7_29",
603 	"safe_link_29_7",
604 	"safe_lamb_to_3",
605 	"safe_lamb_to_2",
606 	"safe_burke_speech",
607 	"safe_burke_1",
608 	"safe_burke_2",
609 	"safe_dr_1",
610 	"safe_body_speech",
611 	"joey_bell",
612 	"safe_anchor_speech",
613 	"safe_anchor",
614 	"safe_pc_mission",
615 	"safe_hook_mission",
616 	"safe_trevor_speech",
617 	"joey_fact",
618 	"safe_helga_speech",
619 	"helga_mission",
620 	"gal_bel_speech",
621 	"safe_glass_mission",
622 	"safe_lamb_fact_return",
623 	"lamb_part_2",
624 	"safe_lamb_bell_return",
625 	"safe_lamb_bell",
626 	"safe_cable_mission",
627 	"safe_foster_tour",
628 	"safe_lamb_tour",
629 	"safe_foreman_logic",
630 	"safe_lamb_leave",
631 	"safe_lamb_3",
632 	"safe_lamb_2",
633 	"into_linc",
634 	"out_10",
635 	"out_74",
636 	"safe_link_28_31",
637 	"safe_link_31_28",
638 	"safe_exit_linc",
639 	"safe_end_game",
640 	"which_linc",
641 	"lift_moving",
642 	"lift_on_screen",
643 	"barrel_on_screen",
644 	"convey_on_screen",
645 	"shades_searched",
646 	"joey_wiz",
647 	"slot_slotted",
648 	"motor_flag",
649 	"panel_flag",
650 	"switch_flag",
651 	"steam_flag",
652 	"steam_fx_no",
653 	"factory_flag",
654 	"power_door_open",
655 	"left_skull_flag",
656 	"right_skull_flag",
657 	"monitor_watching",
658 	"left_lever_flag",
659 	"right_lever_flag",
660 	"lobby_door_flag",
661 	"weld_stop",
662 	"cog_flag",
663 	"sensor_flag",
664 	"look_through",
665 	"welder_nut_flag",
666 	"s7_lift_flag",
667 	"s29_lift_flag",
668 	"whos_at_lift_7",
669 	"whos_at_lift_29",
670 	"lift_power",
671 	"whats_joey",
672 	"seen_box",
673 	"seen_welder",
674 	"flap_flag",
675 	"s15_floor",
676 	"foreman_friend",
677 	"locker1_flag",
678 	"locker2_flag",
679 	"locker3_flag",
680 	"whats_in_locker",
681 	"knows_radsuit",
682 	"radman_anita",
683 	"at_anita",
684 	"coat_flag",
685 	"dressed_as",
686 	"s14_take",
687 	"reactor_door_flag",
688 	"joey_in_lift",
689 	"chair_27_flag",
690 	"at_body_flag",
691 	"at_gas_flag",
692 	"anchor_seated",
693 	"door_23_jam",
694 	"door_20_jam",
695 	"reich_door_flag",
696 	"reich_door_jam",
697 	"lamb_door_flag",
698 	"lamb_door_jam",
699 	"pillow_flag",
700 	"cat_food_flag",
701 	"helga_up",
702 	"got_magazine",
703 	"trevs_doing",
704 	"card_status",
705 	"card_fix",
706 	"lamb_gallager",
707 	"locker_11_flag",
708 	"ever_opened",
709 	"linc_10_flag",
710 	"chair_10_flag",
711 	"skorl_flag",
712 	"lift_pause",
713 	"lift_in_use",
714 	"gordon_back",
715 	"furnace_door_flag",
716 	"whos_with_gall",
717 	"read_news",
718 	"whos_at_lift_28",
719 	"s28_lift_flag",
720 	"mission_state",
721 	"anita_flag",
722 	"card_used",
723 	"gordon_catch",
724 	"car_flag",
725 	"first_jobs",
726 	"jobs_removed",
727 	"menu_id",
728 	"tonys_tour_flag",
729 	"joey_foster_phase",
730 	"start_info_window",
731 	"ref_slab_on",
732 	"ref_up_mouse",
733 	"ref_down_mouse",
734 	"ref_left_mouse",
735 	"ref_right_mouse",
736 	"ref_disconnect_foster",
737 	"k0",
738 	"k1",
739 	"k2",
740 	"k3",
741 	"k4",
742 	"k5",
743 	"k6",
744 	"k7",
745 	"k8",
746 	"k9",
747 	"k10",
748 	"k11",
749 	"k12",
750 	"k13",
751 	"k14",
752 	"k15",
753 	"k16",
754 	"k17",
755 	"k18",
756 	"k19",
757 	"k20",
758 	"k21",
759 	"k22",
760 	"k23",
761 	"k24",
762 	"k25",
763 	"k26",
764 	"k27",
765 	"k28",
766 	"k29",
767 	"a0",
768 	"a1",
769 	"a2",
770 	"a3",
771 	"a4",
772 	"a5",
773 	"a6",
774 	"a7",
775 	"a8",
776 	"a9",
777 	"a10",
778 	"a11",
779 	"a12",
780 	"a13",
781 	"a14",
782 	"a15",
783 	"a16",
784 	"a17",
785 	"a18",
786 	"a19",
787 	"a20",
788 	"a21",
789 	"a22",
790 	"a23",
791 	"a24",
792 	"a25",
793 	"a26",
794 	"a27",
795 	"a28",
796 	"a29",
797 	"g0",
798 	"g1",
799 	"g2",
800 	"g3",
801 	"g4",
802 	"g5",
803 	"g6",
804 	"g7",
805 	"g8",
806 	"g9",
807 	"g10",
808 	"g11",
809 	"g12",
810 	"g13",
811 	"g14",
812 	"g15",
813 	"g16",
814 	"g17",
815 	"g18",
816 	"g19",
817 	"g20",
818 	"g21",
819 	"g22",
820 	"g23",
821 	"g24",
822 	"g25",
823 	"g26",
824 	"g27",
825 	"g28",
826 	"g29",
827 	"window_subject",
828 	"file_text",
829 	"size_text",
830 	"auth_text",
831 	"note_text",
832 	"id_head_compact",
833 	"id_file_compact",
834 	"id_size_compact",
835 	"id_auth_compact",
836 	"id_note_compact",
837 	"pal_no",
838 	"strikes",
839 	"char_set_number",
840 	"eye90_blinded",
841 	"zap90",
842 	"eye90_frame",
843 	"eye91_blinded",
844 	"zap91",
845 	"eye91_frame",
846 	"bag_open",
847 	"bridge_a_on",
848 	"bridge_b_on",
849 	"bridge_c_on",
850 	"bridge_d_on",
851 	"bridge_e_on",
852 	"bridge_f_on",
853 	"bridge_g_on",
854 	"bridge_h_on",
855 	"green_slab",
856 	"red_slab",
857 	"foster_slab",
858 	"circle_slab",
859 	"slab1_mouse",
860 	"slab2_mouse",
861 	"slab3_mouse",
862 	"slab4_mouse",
863 	"slab5_mouse",
864 	"at_guardian",
865 	"guardian_there",
866 	"crystal_shattered",
867 	"virus_taken",
868 	"fs_command",
869 	"enter_digits",
870 	"next_page",
871 	"linc_digit_0",
872 	"linc_digit_1",
873 	"linc_digit_2",
874 	"linc_digit_3",
875 	"linc_digit_4",
876 	"linc_digit_5",
877 	"linc_digit_6",
878 	"linc_digit_7",
879 	"linc_digit_8",
880 	"linc_digit_9",
881 	"ref_std_on",
882 	"ref_std_exit_left_on",
883 	"ref_std_exit_right_on",
884 	"ref_advisor_188",
885 	"ref_shout_action",
886 	"ref_mega_click",
887 	"ref_mega_action",
888 	"ref_walter_speech",
889 	"ref_joey_medic",
890 	"ref_joey_med_logic",
891 	"ref_joey_med_mission72",
892 	"ref_ken_logic",
893 	"ref_ken_speech",
894 	"ref_ken_mission_hand",
895 	"ref_sc70_iris_opened",
896 	"ref_sc70_iris_closed",
897 	"ref_foster_enter_boardroom",
898 	"ref_father_speech",
899 	"ref_foster_enter_new_boardroom",
900 	"ref_hobbins_speech",
901 	"ref_sc82_jobs_sss",
902 	"brickwork",
903 	"door_67_68_flag",
904 	"crowbar_in_clot",
905 	"clot_ruptured",
906 	"clot_repaired",
907 	"walt_text",
908 	"walt_loc1",
909 	"walt_loc2",
910 	"walt_loc3",
911 	"walt_count",
912 	"medic_text",
913 	"seen_room_72",
914 	"seen_tap",
915 	"joey_med_seen72",
916 	"seen_secure_door",
917 	"ask_secure_door",
918 	"sc70_iris_flag",
919 	"sc70_iris_frame",
920 	"foster_on_sc70_iris",
921 	"sc70_grill_flag",
922 	"sc71_charging_flag",
923 	"sc72_slime_flag",
924 	"sc72_witness_sees_foster",
925 	"sc72_witness_killed",
926 	"sc73_gallagher_killed",
927 	"sc73_removed_board",
928 	"sc73_searched_corpse",
929 	"door_73_75_flag",
930 	"sc74_sitting_flag",
931 	"sc75_crashed_flag",
932 	"sc75_tissue_infected",
933 	"sc75_tongs_flag",
934 	"sc76_cabinet1_flag",
935 	"sc76_cabinet2_flag",
936 	"sc76_cabinet3_flag",
937 	"sc76_board_flag",
938 	"sc76_ken_prog_flag",
939 	"sc76_and2_up_flag",
940 	"ken_text",
941 	"ken_door_flag",
942 	"sc77_foster_hand_flag",
943 	"sc77_ken_hand_flag",
944 	"door_77_78_flag",
945 	"sc80_exit_flag",
946 	"ref_danielle_speech",
947 	"ref_danielle_go_home",
948 	"ref_spunky_go_home",
949 	"ref_henri_speech",
950 	"ref_buzzer_speech",
951 	"ref_foster_visit_dani",
952 	"ref_danielle_logic",
953 	"ref_jukebox_speech",
954 	"ref_vincent_speech",
955 	"ref_eddie_speech",
956 	"ref_blunt_speech",
957 	"ref_dani_answer_phone",
958 	"ref_spunky_see_video",
959 	"ref_spunky_bark_at_foster",
960 	"ref_spunky_smells_food",
961 	"ref_barry_speech",
962 	"ref_colston_speech",
963 	"ref_gallagher_speech",
964 	"ref_babs_speech",
965 	"ref_chutney_speech",
966 	"ref_foster_enter_court",
967 	"dani_text",
968 	"dani_loc1",
969 	"dani_loc2",
970 	"dani_loc3",
971 	"dani_buff",
972 	"dani_huff",
973 	"mother_hobart",
974 	"foster_id_flag",
975 	"knows_spunky",
976 	"dog_fleas",
977 	"op_flag",
978 	"chat_up",
979 	"buzz_loc1",
980 	"buzz_loc2",
981 	"blunt_text",
982 	"blun_loc1",
983 	"blun_loc2",
984 	"blun_loc3",
985 	"blunt_dan_info",
986 	"vincent_text",
987 	"vinc_loc1",
988 	"vinc_loc2",
989 	"vinc_loc3",
990 	"eddie_text",
991 	"eddi_loc1",
992 	"eddi_loc2",
993 	"eddi_loc3",
994 	"knows_dandelions",
995 	"barry_text",
996 	"bazz_loc1",
997 	"bazz_loc2",
998 	"bazz_loc3",
999 	"seen_cellar_door",
1000 	"babs_text",
1001 	"babs_loc1",
1002 	"babs_loc2",
1003 	"babs_loc3",
1004 	"colston_text",
1005 	"cols_loc1",
1006 	"cols_loc2",
1007 	"cols_loc3",
1008 	"jukebox",
1009 	"knows_soaking",
1010 	"knows_complaint",
1011 	"dog_bite",
1012 	"new_prints",
1013 	"knows_virus",
1014 	"been_to_court",
1015 	"danielle_target",
1016 	"spunky_target",
1017 	"henri_forward",
1018 	"sc31_lift_flag",
1019 	"sc31_food_on_plank",
1020 	"sc31_spunky_at_plank",
1021 	"dog_in_lake",
1022 	"sc32_lift_flag",
1023 	"sc33_shed_door_flag",
1024 	"gardener_up",
1025 	"babs_x",
1026 	"babs_y",
1027 	"foster_caching",
1028 	"colston_caching",
1029 	"band_playing",
1030 	"colston_at_table",
1031 	"sc36_next_dealer",
1032 	"sc36_door_flag",
1033 	"sc37_door_flag",
1034 	"sc37_lid_loosened",
1035 	"sc37_lid_used",
1036 	"sc37_standing_on_box",
1037 	"sc37_box_broken",
1038 	"sc37_grill_state",
1039 	"got_dog_biscuits",
1040 	"sc38_video_playing",
1041 	"dani_on_phone",
1042 	"sc40_locker_1_flag",
1043 	"sc40_locker_2_flag",
1044 	"sc40_locker_3_flag",
1045 	"sc40_locker_4_flag",
1046 	"sc40_locker_5_flag",
1047 	"seen_anita_corpse",
1048 	"spunky_at_lift",
1049 	"court_text",
1050 	"blunt_knew_jobs",
1051 	"credit_1_text",
1052 	"credit_2_text",
1053 	"id_credit_1",
1054 	"id_credit_2",
1055 	"glass_stolen",
1056 	"foster_at_plank",
1057 	"foster_at_guard",
1058 	"man_talk",
1059 	"man_loc1",
1060 	"man_loc2",
1061 	"man_loc3"
1062 };
1063 
logic(uint32 logic)1064 void Debug::logic(uint32 logic) {
1065 	debug(6, "LOGIC: %s", logic_table_names[logic]);
1066 }
1067 
script(uint32 command,uint16 * scriptData)1068 void Debug::script(uint32 command, uint16 *scriptData) {
1069 	debug(6, "SCRIPT: %s", opcodes[command]);
1070 	if (command == 0 || command == 6)
1071 		debug(6, " %s", scriptVars[(*scriptData)/4]);
1072 	else {
1073 		int i;
1074 		for (i = 0; i < opcode_par[command]; i++) {
1075 			debug(6, " %d", *(scriptData + i));
1076 		}
1077 	}
1078 	debug(6, " ");	// Print an empty line as separator
1079 }
1080 
mcode(uint32 mcode,uint32 a,uint32 b,uint32 c)1081 void Debug::mcode(uint32 mcode, uint32 a, uint32 b, uint32 c) {
1082 	debug(6, "MCODE: %s(%d, %d, %d)", mcodes[mcode], a, b, c);
1083 }
1084 
1085 
1086 
1087 
Debugger(Logic * logic,Mouse * mouse,Screen * screen,SkyCompact * skyCompact)1088 Debugger::Debugger(Logic *logic, Mouse *mouse, Screen *screen, SkyCompact *skyCompact)
1089 : GUI::Debugger(), _logic(logic), _mouse(mouse), _screen(screen), _skyCompact(skyCompact), _showGrid(false) {
1090 	registerCmd("info",       WRAP_METHOD(Debugger, Cmd_Info));
1091 	registerCmd("showgrid",   WRAP_METHOD(Debugger, Cmd_ShowGrid));
1092 	registerCmd("reloadgrid", WRAP_METHOD(Debugger, Cmd_ReloadGrid));
1093 	registerCmd("compact",    WRAP_METHOD(Debugger, Cmd_ShowCompact));
1094 	registerCmd("logiccmd",   WRAP_METHOD(Debugger, Cmd_LogicCommand));
1095 	registerCmd("scriptvar",  WRAP_METHOD(Debugger, Cmd_ScriptVar));
1096 	registerCmd("section",    WRAP_METHOD(Debugger, Cmd_Section));
1097 	registerCmd("logiclist",  WRAP_METHOD(Debugger, Cmd_LogicList));
1098 }
1099 
~Debugger()1100 Debugger::~Debugger() {} // we need this here for __SYMBIAN32__
1101 
preEnter()1102 void Debugger::preEnter() {
1103 	::GUI::Debugger::preEnter();
1104 }
1105 
postEnter()1106 void Debugger::postEnter() {
1107 	::GUI::Debugger::postEnter();
1108 	_mouse->resetCursor();
1109 }
1110 
isNumeric(const char * arg)1111 static bool isNumeric(const char *arg) {
1112 	const char *str = arg;
1113 	bool retVal = true;
1114 	while (retVal && (*str != '\0')) {
1115 		retVal = Common::isDigit(*str++);
1116 	}
1117 	return retVal;
1118 }
1119 
Cmd_ShowGrid(int argc,const char ** argv)1120 bool Debugger::Cmd_ShowGrid(int argc, const char **argv) {
1121 	_showGrid = !_showGrid;
1122 	debugPrintf("Show grid: %s\n", _showGrid ? "On" : "Off");
1123 	if (!_showGrid)	_screen->forceRefresh();
1124 	return true;
1125 }
1126 
Cmd_ReloadGrid(int argc,const char ** argv)1127 bool Debugger::Cmd_ReloadGrid(int argc, const char **argv) {
1128 	_logic->_skyGrid->loadGrids();
1129 	debugPrintf("Grid reloaded\n");
1130 	return true;
1131 }
1132 
1133 static const char *const logicTypes[] = {
1134 	"(none)", "SCRIPT", "AUTOROUTE", "AR_ANIM", "AR_TURNING", "ALT", "MOD_ANIM", "TURNING", "CURSOR", "TALK", "LISTEN",
1135 	"STOPPED", "CHOOSE", "FRAMES", "PAUSE", "WAIT_SYNC", "SIMPLE MOD"
1136 };
1137 
1138 static const char *const noYes[] = { "no", "yes" };
1139 
dumpCompact(uint16 cptId)1140 void Debugger::dumpCompact(uint16 cptId) {
1141 	uint16 type, size;
1142 	char name[256];
1143 	Compact *cpt = _skyCompact->fetchCptInfo(cptId, &size, &type, name);
1144 
1145 	if (type == COMPACT) {
1146 		debugPrintf("Compact %s: id = %04X, section %d, id %d\n", name, cptId, cptId >> 12, cptId & 0xFFF);
1147 		debugPrintf("logic      : %04X: %s\n", cpt->logic, (cpt->logic <= 16) ? logicTypes[cpt->logic] : "unknown");
1148 		debugPrintf("status     : %04X\n", cpt->status);
1149 		debugPrintf("           : background  : %s\n", noYes[(cpt->status &  ST_BACKGROUND) >> 0]);
1150 		debugPrintf("           : foreground  : %s\n", noYes[(cpt->status &  ST_FOREGROUND) >> 1]);
1151 		debugPrintf("           : sort list   : %s\n", noYes[(cpt->status &        ST_SORT) >> 2]);
1152 		debugPrintf("           : recreate    : %s\n", noYes[(cpt->status &    ST_RECREATE) >> 3]);
1153 		debugPrintf("           : mouse       : %s\n", noYes[(cpt->status &       ST_MOUSE) >> 4]);
1154 		debugPrintf("           : collision   : %s\n", noYes[(cpt->status &   ST_COLLISION) >> 5]);
1155 		debugPrintf("           : logic       : %s\n", noYes[(cpt->status &       ST_LOGIC) >> 6]);
1156 		debugPrintf("           : on grid     : %s\n", noYes[(cpt->status &   ST_GRID_PLOT) >> 7]);
1157 		debugPrintf("           : ar priority : %s\n", noYes[(cpt->status & ST_AR_PRIORITY) >> 8]);
1158 		debugPrintf("sync       : %04X\n", cpt->sync);
1159 		debugPrintf("screen     : %d\n", cpt->screen);
1160 		_skyCompact->fetchCptInfo(cpt->place, NULL, NULL, name);
1161 		debugPrintf("place      : %04X: %s\n", cpt->place, name);
1162 		_skyCompact->fetchCptInfo(cpt->getToTableId, NULL, NULL, name);
1163 		debugPrintf("get to tab : %04X: %s\n", cpt->getToTableId, name);
1164 		debugPrintf("x/y        : %d/%d\n", cpt->xcood, cpt->ycood);
1165 	} else {
1166 		debugPrintf("Can't dump binary data\n");
1167 	}
1168 }
1169 
Cmd_ShowCompact(int argc,const char ** argv)1170 bool Debugger::Cmd_ShowCompact(int argc, const char **argv) {
1171 	if (argc < 2) {
1172 		debugPrintf("Example: \"%s foster\" dumps compact \"foster\"\n", argv[0]);
1173 		debugPrintf("Example: \"%s list 1\" lists all compacts from section 1\n", argv[0]);
1174 		debugPrintf("Example: \"%s list 1 all\" lists all entities from section 1\n", argv[0]);
1175 		return true;
1176 	}
1177 
1178 	if (0 == strcmp(argv[1], "list")) {
1179 		bool showAll = false;
1180 		int sectionNumber = -1;
1181 		if (argc >= 3) {
1182 			sectionNumber = atoi(argv[2]);
1183 			if (sectionNumber >= _skyCompact->giveNumDataLists()) {
1184 				debugPrintf("Section number %d does not exist\n", sectionNumber);
1185 				return true;
1186 			}
1187 			if ((argc == 4) && (scumm_stricmp(argv[3], "all") == 0))
1188 				showAll = true;
1189 		}
1190 		for (int sec = 0; sec < _skyCompact->giveNumDataLists(); sec++) {
1191 			if ((sectionNumber == -1) || (sectionNumber == sec)) {
1192 				debugPrintf("Compacts in section %d:\n", sec);
1193 				if (showAll) {
1194 					char line[256];
1195 					char *linePos = line;
1196 					for (int cpt = 0; cpt < _skyCompact->giveDataListLen(sec); cpt++) {
1197 						if (cpt != 0) {
1198 							if ((cpt % 3) == 0) {
1199 								debugPrintf("%s\n", line);
1200 								linePos = line;
1201 							} else
1202 								linePos += sprintf(linePos, ", ");
1203 						}
1204 						uint16 cptId = (uint16)((sec << 12) | cpt);
1205 						uint16 type, size;
1206 						char name[256];
1207 						_skyCompact->fetchCptInfo(cptId, &size, &type, name);
1208 						linePos += sprintf(linePos, "%04X: %10s %22s", cptId, _skyCompact->nameForType(type), name);
1209 					}
1210 					if (linePos != line)
1211 						debugPrintf("%s\n", line);
1212 				} else {
1213 					for (int cpt = 0; cpt < _skyCompact->giveDataListLen(sec); cpt++) {
1214 						uint16 cptId = (uint16)((sec << 12) | cpt);
1215 						uint16 type, size;
1216 						char name[256];
1217 						_skyCompact->fetchCptInfo(cptId, &size, &type, name);
1218 						if (type == COMPACT)
1219 							debugPrintf("%04X: %s\n", cptId, name);
1220 					}
1221 				}
1222 			}
1223 		}
1224 	} else {
1225 		uint16 cptId = _skyCompact->findCptId(argv[1]);
1226 		if (cptId == 0)
1227 			debugPrintf("Unknown compact: '%s'\n", argv[1]);
1228 		else
1229 			dumpCompact(cptId);
1230 	}
1231 	return true;
1232 }
1233 
Cmd_LogicCommand(int argc,const char ** argv)1234 bool Debugger::Cmd_LogicCommand(int argc, const char **argv) {
1235 	if (argc < 2) {
1236 		debugPrintf("Example: %s fn_printf 42\n", argv[0]);
1237 		return true;
1238 	}
1239 
1240 	int numMCodes = ARRAYSIZE(mcodes);
1241 
1242 	if (0 == strcmp(argv[1], "list")) {
1243 		for (int i = 0; i < numMCodes; ++i) {
1244 			debugPrintf("%s\n", mcodes[i]);
1245 		}
1246 		return true;
1247 	}
1248 
1249 	uint32 arg1 = 0, arg2 = 0, arg3 = 0;
1250 
1251 	switch (argc) {
1252 		case  5:
1253 			arg3 = atoi(argv[4]);
1254 			// fall through
1255 		case  4:
1256 			arg2 = atoi(argv[3]);
1257 			// fall through
1258 		case  3:
1259 			arg1 = atoi(argv[2]);
1260 			// fall through
1261 	}
1262 
1263 	for (int i = 0; i < numMCodes; ++i) {
1264 		if (0 == strcmp(mcodes[i], argv[1])) {
1265 			_logic->fnExec(i, arg1, arg2, arg3);
1266 			return true;
1267 		}
1268 	}
1269 
1270 	debugPrintf("Unknown function: '%s'\n", argv[1]);
1271 
1272 	return true;
1273 }
1274 
Cmd_Info(int argc,const char ** argv)1275 bool Debugger::Cmd_Info(int argc, const char **argv) {
1276 	debugPrintf("Beneath a Steel Sky version: 0.0%d\n", SkyEngine::_systemVars.gameVersion);
1277 	debugPrintf("Speech: %s\n", (SkyEngine::_systemVars.systemFlags & SF_ALLOW_SPEECH) ? "on" : "off");
1278 	debugPrintf("Text  : %s\n", (SkyEngine::_systemVars.systemFlags & SF_ALLOW_TEXT) ? "on" : "off");
1279 	return true;
1280 }
1281 
Cmd_ScriptVar(int argc,const char ** argv)1282 bool Debugger::Cmd_ScriptVar(int argc, const char **argv) {
1283 	if (argc < 2) {
1284 		debugPrintf("Example: %s lamb_friend <value>\n", argv[0]);
1285 		return true;
1286 	}
1287 
1288 	int numScriptVars = ARRAYSIZE(scriptVars);
1289 
1290 	if (0 == strcmp(argv[1], "list")) {
1291 		for (int i = 0; i < numScriptVars; ++i) {
1292 			debugPrintf("%s\n", scriptVars[i]);
1293 		}
1294 		return true;
1295 	}
1296 
1297 	for (int i = 0; i < numScriptVars; ++i) {
1298 		if (0 == strcmp(scriptVars[i], argv[1])) {
1299 			if (argc == 3) {
1300 				Logic::_scriptVariables[i] = atoi(argv[2]);
1301 			}
1302 			debugPrintf("%s = %d\n", argv[1], Logic::_scriptVariables[i]);
1303 
1304 			return true;
1305 		}
1306 	}
1307 
1308 	debugPrintf("Unknown ScriptVar: '%s'\n", argv[1]);
1309 
1310 	return true;
1311 }
1312 
Cmd_Section(int argc,const char ** argv)1313 bool Debugger::Cmd_Section(int argc, const char **argv) {
1314 	if (argc == 2 && isNumeric(argv[1])) {
1315 		const int baseId[] = { START_ONE, START_S6, START_29, START_SC31, START_SC66, START_SC90, START_SC81 };
1316 		int section = atoi(argv[1]);
1317 
1318 		if (section >= 0 && section <= 6) {
1319 			_logic->fnEnterSection(section == 6 ? 4 : section, 0, 0);
1320 			_logic->fnAssignBase(ID_FOSTER, baseId[section], 0);
1321 			_skyCompact->fetchCpt(ID_FOSTER)->megaSet = 0;
1322 		} else {
1323 			debugPrintf("Section %d is out of range (range: %d - %d)\n", section, 0, 6);
1324 		}
1325 	} else {
1326 		debugPrintf("Example: %s 4\n", argv[0]);
1327 	}
1328 	return true;
1329 }
1330 
Cmd_LogicList(int argc,const char ** argv)1331 bool Debugger::Cmd_LogicList(int argc, const char **argv) {
1332 	if (argc != 1)
1333 		debugPrintf("%s does not expect any parameters\n", argv[0]);
1334 
1335 	char cptName[256];
1336 	uint16 numElems, type;
1337 	uint16 *logicList = (uint16 *)_skyCompact->fetchCptInfo(Logic::_scriptVariables[LOGIC_LIST_NO], &numElems, &type, cptName);
1338 	debugPrintf("Current LogicList: %04X (%s)\n", Logic::_scriptVariables[LOGIC_LIST_NO], cptName);
1339 	while (*logicList != 0) {
1340 		if (*logicList == 0xFFFF) {
1341 			uint16 newList = logicList[1];
1342 			logicList = (uint16 *)_skyCompact->fetchCptInfo(newList, &numElems, &type, cptName);
1343 			debugPrintf("New List: %04X (%s)\n", newList, cptName);
1344 		} else {
1345 			_skyCompact->fetchCptInfo(*logicList, &numElems, &type, cptName);
1346 			debugPrintf(" Cpt %04X (%s) (%s)\n", *logicList, cptName, _skyCompact->nameForType(type));
1347 			logicList++;
1348 		}
1349 	}
1350 	return true;
1351 }
1352 
1353 } // End of namespace Sky
1354