aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/tools/scidisasm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/tools/scidisasm.cpp')
-rw-r--r--engines/sci/tools/scidisasm.cpp987
1 files changed, 0 insertions, 987 deletions
diff --git a/engines/sci/tools/scidisasm.cpp b/engines/sci/tools/scidisasm.cpp
deleted file mode 100644
index 39ea7f9c41..0000000000
--- a/engines/sci/tools/scidisasm.cpp
+++ /dev/null
@@ -1,987 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#define MALLOC_DEBUG
-
-#include <sciresource.h>
-#include <engine.h>
-#include <console.h>
-#include <versions.h>
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#endif /* HAVE_GETOPT_H */
-
-static int hexdump = 0;
-static int opcode_size = 0;
-static int verbose = 0;
-
-static resource_mgr_t *resmgr;
-
-#ifdef HAVE_GETOPT_LONG
-static struct option options[] = {
- {"version", no_argument, 0, 256},
- {"help", no_argument, 0, 'h'},
- {"hexdump", no_argument, &hexdump, 1},
- {"opcode-size", no_argument, &opcode_size, 1},
- {"verbose", no_argument, &verbose, 1},
- {"gamedir", required_argument, 0, 'd'},
- {0, 0, 0, 0}
-};
-#endif /* HAVE_GETOPT_LONG */
-
-#define SCI_ASSUME_VERSION SCI_VERSION_FTU_NEW_SCRIPT_HEADER
-
-typedef struct name_s {
- int offset;
- char *name;
- int class_no;
- struct name_s *next;
-} name_t;
-
-typedef struct area_s {
- int start_offset;
- int end_offset;
- void *data;
- struct area_s *next;
-} area_t;
-
-enum area_type { area_said, area_string, area_object, area_last };
-
-typedef struct script_state_s {
- int script_no;
- name_t *names;
- area_t *areas [area_last];
-
- struct script_state_s *next;
-} script_state_t;
-
-typedef struct disasm_state_s {
- char **snames;
- int selector_count;
- opcode *opcodes;
- int kernel_names_nr;
- char **kernel_names;
- word_t **words;
- int word_count;
-
- char **class_names;
- int *class_selector_count;
- short **class_selectors;
- int class_count;
- int old_header;
-
- script_state_t *scripts;
-} disasm_state_t;
-
-void
-disassemble_script(disasm_state_t *d, int res_no, int pass_no);
-
-script_state_t *
-find_script_state(disasm_state_t *d, int script_no);
-
-void
-script_free_names(script_state_t *s);
-
-void
-script_add_name(script_state_t *s, int aoffset, char *aname, int aclass_no);
-
-char *
-script_find_name(script_state_t *s, int offset, int *class_no);
-
-void
-script_add_area(script_state_t *s, int start_offset, int end_offset, int type, void *data);
-
-void
-script_free_areas(script_state_t *s);
-
-int
-script_get_area_type(script_state_t *s, int offset, void **pdata);
-
-void
-disasm_init(disasm_state_t *d);
-
-void
-disasm_free_state(disasm_state_t *d);
-
-int main(int argc, char** argv) {
- int i;
- char outfilename [256];
- int optindex = 0;
- int c;
- disasm_state_t disasm_state;
- char *gamedir = NULL;
- int res_version = SCI_VERSION_AUTODETECT;
-
-#ifdef HAVE_GETOPT_LONG
- while ((c = getopt_long(argc, argv, "vhxr:d:", options, &optindex)) > -1) {
-#else /* !HAVE_GETOPT_H */
- while ((c = getopt(argc, argv, "vhxr:d:")) > -1) {
-#endif /* !HAVE_GETOPT_H */
-
- switch (c) {
- case 256:
- printf("scidisasm ("PACKAGE") "VERSION"\n");
- printf("This program is copyright (C) 1999 Christoph Reichenbach.\n"
- "It comes WITHOUT WARRANTY of any kind.\n"
- "This is free software, released under the GNU General Public License.\n");
- exit(0);
-
- case 'h':
- printf("Usage: scidisasm\n"
- "\nAvailable options:\n"
- " --version Prints the version number\n"
- " --help -h Displays this help message\n"
- " --gamedir <dir> -d<dir> Read game resources from dir\n"
- " --hexdump -x Hex dump all script resources\n"
- " --verbose Print additional disassembly information\n"
- " --opcode-size Print opcode size postfixes\n");
- exit(0);
-
- case 'd':
- if (gamedir) sci_free(gamedir);
- gamedir = sci_strdup(optarg);
- break;
-
- case 'r':
- res_version = atoi(optarg);
- break;
-
- case 0: /* getopt_long already did this for us */
- case '?':
- /* getopt_long already printed an error message. */
- break;
-
- default:
- return -1;
- }
- }
-
- if (gamedir)
- if (chdir(gamedir)) {
- printf("Error changing to game directory '%s'\n", gamedir);
- exit(1);
- }
-
- printf("Loading resources...\n");
- if (!(resmgr = scir_new_resource_manager(sci_getcwd(), res_version,
- 1, 1024 * 128))) {
- fprintf(stderr, "Could not find any resources; quitting.\n");
- exit(1);
- }
-
- disasm_init(&disasm_state);
-
- script_adjust_opcode_formats(resmgr->sci_version);
-
- printf("Performing first pass...\n");
- for (i = 0; i < resmgr->resources_nr; i++)
- if (resmgr->resources[i].type == sci_script)
- disassemble_script(&disasm_state,
- resmgr->resources[i].number, 1);
-
- printf("Performing second pass...\n");
- for (i = 0; i < resmgr->resources_nr; i++)
- if (resmgr->resources[i].type == sci_script) {
- sprintf(outfilename, "%03d.script",
- resmgr->resources[i].number);
- open_console_file(outfilename);
- disassemble_script(&disasm_state,
- resmgr->resources[i].number, 2);
- }
-
- close_console_file();
- disasm_free_state(&disasm_state);
-
- free(resmgr->resource_path);
- scir_free_resource_manager(resmgr);
- return 0;
-}
-
-/* -- General operations on disasm_state_t ------------------------------- */
-
-void
-disasm_init(disasm_state_t *d) {
- d->snames = vocabulary_get_snames(resmgr, &d->selector_count, SCI_ASSUME_VERSION);
- d->opcodes = vocabulary_get_opcodes(resmgr);
- d->kernel_names = vocabulary_get_knames(resmgr, &d->kernel_names_nr);
- d->words = vocab_get_words(resmgr, &d->word_count);
- d->scripts = NULL;
- d->old_header = 0;
-
- d->class_count = vocabulary_get_class_count(resmgr);
- d->class_names = (char **) sci_malloc(d->class_count * sizeof(char *));
- memset(d->class_names, 0, d->class_count * sizeof(char *));
- d->class_selector_count = (int *) sci_malloc(d->class_count * sizeof(int));
- memset(d->class_selector_count, 0, d->class_count * sizeof(int));
- d->class_selectors = (short **) sci_malloc(d->class_count * sizeof(short *));
- memset(d->class_selectors, 0, d->class_count * sizeof(short *));
-}
-
-void
-disasm_free_state(disasm_state_t *d) {
- script_state_t *s, *next_script;
- int i;
-
- s = d->scripts;
- while (s) {
- next_script = s->next;
- script_free_names(s);
- script_free_areas(s);
- s = next_script;
- }
-
- for (i = 0; i < d->class_count; i++) {
- if (d->class_names [i]) sci_free(d->class_names [i]);
- if (d->class_selectors [i]) sci_free(d->class_selectors [i]);
- }
-
- free(d->class_names);
- free(d->class_selectors);
- free(d->class_selector_count);
-
- vocabulary_free_snames(d->snames);
- vocabulary_free_opcodes(d->opcodes);
- vocabulary_free_knames(d->kernel_names);
- vocab_free_words(d->words, d->word_count);
-}
-
-script_state_t *
-find_script_state(disasm_state_t *d, int script_no) {
- script_state_t *s;
-
- for (s = d->scripts; s; s = s->next)
- if (s->script_no == script_no) return s;
-
- s = (script_state_t *) sci_malloc(sizeof(script_state_t));
- memset(s, 0, sizeof(script_state_t));
- s->script_no = script_no;
- s->next = d->scripts;
-
- d->scripts = s;
- return s;
-}
-
-/* -- Name table operations ---------------------------------------------- */
-
-void
-script_free_names(script_state_t *s) {
- name_t *p = s->names, *next_name;
-
- while (p) {
- next_name = p->next;
- free(p->name);
- free(p);
- p = next_name;
- }
-
- s->names = NULL;
-}
-
-void
-script_add_name(script_state_t *s, int aoffset, char *aname, int aclass_no) {
- name_t *p;
- char *name = script_find_name(s, aoffset, NULL);
- if (name) return;
-
- p = (name_t *) sci_malloc(sizeof(name_t));
- p->offset = aoffset;
- p->name = sci_strdup(aname);
- p->class_no = aclass_no;
- p->next = s->names;
- s->names = p;
-}
-
-char *
-script_find_name(script_state_t *s, int offset, int *aclass_no) {
- name_t *p;
-
- for (p = s->names; p; p = p->next)
- if (p->offset == offset) {
- if (aclass_no && p->class_no != -2) *aclass_no = p->class_no;
- return p->name;
- }
-
- return NULL;
-}
-
-/* -- Area table operations ---------------------------------------------- */
-
-void
-script_add_area(script_state_t *s, int start_offset, int end_offset, int type, void *data) {
- area_t *area;
-
- area = (area_t *) sci_malloc(sizeof(area_t));
- area->start_offset = start_offset;
- area->end_offset = end_offset;
- area->data = data;
- area->next = s->areas [type];
-
- s->areas [type] = area;
-}
-
-void
-script_free_areas(script_state_t *s) {
- int i;
-
- for (i = 0; i < area_last; i++) {
- area_t *area = s->areas [i], *next_area;
- while (area) {
- next_area = area->next;
- free(area);
- area = next_area;
- }
- }
-}
-
-int
-script_get_area_type(script_state_t *s, int offset, void **pdata) {
- int i;
-
- for (i = 0; i < area_last; i++) {
- area_t *area = s->areas [i];
- while (area) {
- if (area->start_offset <= offset && area->end_offset >= offset) {
- if (pdata != NULL) *pdata = area->data;
- return i;
- }
- area = area->next;
- }
- }
-
- return -1;
-}
-
-char *
-get_selector_name(disasm_state_t *d, int selector) {
- static char selector_name [256];
-
- if (d->snames && selector >= 0 && selector < d->selector_count)
- return d->snames [selector];
- else {
- sprintf(selector_name, "unknown_sel_%X", selector);
- return selector_name;
- }
-}
-
-const char *
-get_class_name(disasm_state_t *d, int class_no) {
- static char class_name [256];
-
- if (class_no == -1)
- return "<none>";
- else if (class_no >= 0 && class_no < d->class_count && d->class_names [class_no])
- return d->class_names [class_no];
- else {
- sprintf(class_name, "class_%d", class_no);
- return class_name;
- }
-}
-
-/* -- Code to dump individual script block types ------------------------- */
-
-static void
-script_dump_object(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- int selectors, overloads, selectorsize;
- int species = getInt16(data + 8 + seeker);
- int superclass = getInt16(data + 10 + seeker);
- int namepos = getInt16(data + 14 + seeker);
- int i = 0;
- short sel;
- const char *name;
- char buf [256];
- short *sels;
-
- selectors = (selectorsize = getInt16(data + seeker + 6));
- name = namepos ? ((const char *)data + namepos) : "<unknown>";
-
- if (pass_no == 1)
- script_add_area(s, seeker, seeker + objsize - 1, area_object, strdup(name));
-
- if (pass_no == 2) {
- sciprintf(".object\n");
- sciprintf("Name: %s\n", name);
- sciprintf("Superclass: %s [%x]\n", get_class_name(d, superclass), superclass);
- sciprintf("Species: %s [%x]\n", get_class_name(d, species), species);
-
- sciprintf("-info-:%x\n", getInt16(data + 12 + seeker) & 0xffff);
-
- sciprintf("Function area offset: %x\n", getInt16(data + seeker + 4));
- sciprintf("Selectors [%x]:\n", selectors);
- }
-
- seeker += 8;
-
- if (species < d->class_count)
- sels = d->class_selectors [species];
- else
- sels = NULL;
-
- while (selectors--) {
- if (pass_no == 2) {
- sel = getInt16(data + seeker) & 0xffff;
- if (sels && (sels [i] >= 0) && (sels[i] < d->selector_count)) {
- sciprintf(" [#%03x] %s = 0x%x\n", i, d->snames [sels [i]], sel);
- i++;
- } else
- sciprintf(" [#%03x] <unknown> = 0x%x\n", i++, sel);
- }
-
- seeker += 2;
- }
-
- selectors = overloads = getInt16(data + seeker);
-
- if (pass_no == 2)
- sciprintf("Overloaded functions: %x\n", overloads);
-
- seeker += 2;
-
- while (overloads--) {
- word selector = getInt16(data + (seeker)) & 0xffff;
- if (d->old_header) selector >>= 1;
-
- if (pass_no == 1) {
- sprintf(buf, "%s::%s", name, get_selector_name(d, selector));
- script_add_name(s, getInt16(data + seeker + selectors*2 + 2), buf, species);
- } else {
- sciprintf(" [%03x] %s: @", selector, get_selector_name(d, selector));
- sciprintf("%04x\n", getInt16(data + seeker + selectors*2 + 2));
- }
-
- seeker += 2;
- }
-}
-
-static void
-script_dump_class(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- word selectors, overloads, selectorsize;
- int species = getInt16(data + 8 + seeker);
- int superclass = getInt16(data + 10 + seeker);
- int namepos = getInt16(data + 14 + seeker);
- const char *name;
- char buf [256];
- int i;
-
- name = namepos ? ((const char *)data + namepos) : "<unknown>";
- selectors = (selectorsize = getInt16(data + seeker + 6));
-
- if (pass_no == 1) {
- if (species >= 0 && species < d->class_count) {
- if (!namepos) {
- sprintf(buf, "class_%d", species);
- d->class_names [species] = sci_strdup(buf);
- } else
- d->class_names [species] = sci_strdup(name);
-
- d->class_selector_count [species] = selectors;
- d->class_selectors [species] = (short *) sci_malloc(sizeof(short) * selectors);
- }
- }
-
- if (pass_no == 2) {
- sciprintf(".class\n");
- sciprintf("Name: %s\n", name);
- sciprintf("Superclass: %s [%x]\n", get_class_name(d, superclass), superclass);
- sciprintf("Species: %x\n", species);
- sciprintf("-info-:%x\n", getInt16(data + 12 + seeker) & 0xffff);
-
- sciprintf("Function area offset: %x\n", getInt16(data + seeker + 4));
- sciprintf("Selectors [%x]:\n", selectors);
- }
-
- seeker += 8;
- selectorsize <<= 1;
-
- for (i = 0; i < selectors; i++) {
- word selector = 0xffff & getInt16(data + (seeker) + selectorsize);
- if (d->old_header) selector >>= 1;
-
- if (pass_no == 1) {
- if (species >= 0 && species < d->class_count)
- d->class_selectors [species][i] = selector;
- } else
- sciprintf(" [%03x] %s = 0x%x\n", selector, get_selector_name(d, selector),
- getInt16(data + seeker) & 0xffff);
-
- seeker += 2;
- }
-
- seeker += selectorsize;
-
- selectors = overloads = getInt16(data + seeker);
-
- sciprintf("Overloaded functions: %x\n", overloads);
-
- seeker += 2;
-
- while (overloads--) {
- word selector = getInt16(data + (seeker)) & 0xffff;
- if (d->old_header) selector >>= 1;
-
- if (pass_no == 1) {
- sprintf(buf, "%s::%s", name, get_selector_name(d, selector));
- script_add_name(s, getInt16(data + seeker + selectors*2 + 2) & 0xffff, buf, species);
- } else {
- sciprintf(" [%03x] %s: @", selector & 0xffff, get_selector_name(d, selector));
- sciprintf("%04x\n", getInt16(data + seeker + selectors*2 + 2) & 0xffff);
- }
-
- seeker += 2;
- }
-}
-
-static int
-script_dump_said_string(disasm_state_t *d, unsigned char *data, int seeker) {
- while (1) {
- unsigned short nextitem = (unsigned char) data [seeker++];
- if (nextitem == 0xFF) return seeker;
-
- if (nextitem >= 0xF0) {
- switch (nextitem) {
- case 0xf0:
- sciprintf(", ");
- break;
- case 0xf1:
- sciprintf("& ");
- break;
- case 0xf2:
- sciprintf("/ ");
- break;
- case 0xf3:
- sciprintf("( ");
- break;
- case 0xf4:
- sciprintf(") ");
- break;
- case 0xf5:
- sciprintf("[ ");
- break;
- case 0xf6:
- sciprintf("] ");
- break;
- case 0xf7:
- sciprintf("# ");
- break;
- case 0xf8:
- sciprintf("< ");
- break;
- case 0xf9:
- sciprintf("> ");
- break;
- }
- } else {
- nextitem = nextitem << 8 | (unsigned char) data [seeker++];
- sciprintf("%s ", vocab_get_any_group_word(nextitem, d->words, d->word_count));
- if (verbose)
- sciprintf("[%03x] ", nextitem);
- }
- }
-}
-
-static void
-script_dump_said(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- int _seeker = seeker + objsize - 4;
-
- if (pass_no == 1) {
- script_add_area(s, seeker, seeker + objsize - 1, area_said, NULL);
- return;
- }
-
- sciprintf(".said\n");
-
- while (seeker < _seeker - 1) {
- sciprintf("%04x: ", seeker);
- seeker = script_dump_said_string(d, data, seeker);
- sciprintf("\n");
- }
-}
-
-static void
-script_dump_synonyms(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- int _seeker = seeker + objsize - 4;
-
- sciprintf("Synonyms:\n");
- while (seeker < _seeker) {
- int search = getInt16(data + seeker);
- int replace = getInt16(data + seeker + 2);
- seeker += 4;
- if (search < 0) break;
- sciprintf("%s[%03x] ==> %s[%03x]\n",
- vocab_get_any_group_word(search, d->words, d->word_count), search,
- vocab_get_any_group_word(replace, d->words, d->word_count), replace);
- }
-}
-
-static void
-script_dump_strings(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- int endptr = seeker + objsize - 4;
-
- if (pass_no == 1) {
- script_add_area(s, seeker, seeker + objsize - 1, area_string, NULL);
- return;
- }
-
- sciprintf(".strings\n");
- while (data [seeker] && seeker < endptr) {
- sciprintf("%04x: %s\n", seeker, data + seeker);
- seeker += strlen((char *) data + seeker) + 1;
- }
-}
-
-static void
-script_dump_exports(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- byte *pexport = (byte *)(data + seeker);
- word export_count = getUInt16(pexport);
- int i;
- char buf [256];
-
- pexport += 2;
-
- if (pass_no == 2) sciprintf(".exports\n");
-
- for (i = 0; i < export_count; i++) {
- if (pass_no == 1) {
- guint16 offset = getUInt16(pexport);
- sprintf(buf, "exp_%02X", i);
- script_add_name(s, offset, buf, -1);
- } else
- sciprintf("%02X: %04X\n", i, *pexport);
- pexport += 2;
- }
-}
-
-/* -- The disassembly code ----------------------------------------------- */
-
-static void
-script_disassemble_code(disasm_state_t *d, script_state_t *s,
- unsigned char *data, int seeker, int objsize, int pass_no) {
- int endptr = seeker + objsize - 4;
- int i = 0;
- int cur_class = -1;
- word dest;
- void *area_data;
- char buf [256];
- char *dest_name;
-
- if (pass_no == 2) sciprintf(".code\n");
-
- while (seeker < endptr - 1) {
- unsigned char opsize = data [seeker];
- unsigned char opcode = opsize >> 1;
- word param_value;
- char *name;
-
- opsize &= 1; /* byte if true, word if false */
-
- if (pass_no == 2) {
- name = script_find_name(s, seeker, &cur_class);
- if (name) sciprintf(" %s:\n", name);
- sciprintf("%04X: ", seeker);
- sciprintf("%s", d->opcodes[opcode].name);
- if (opcode_size && formats[opcode][0])
- sciprintf(".%c", opsize ? 'b' : 'w');
- sciprintf("\t");
- }
-
- seeker++;
-
- for (i = 0; formats[opcode][i]; i++)
-
- switch (formats[opcode][i]) {
-
- case Script_Invalid:
- if (pass_no == 2) sciprintf("-Invalid operation-");
- break;
-
- case Script_SByte:
- case Script_Byte:
- if (pass_no == 2) sciprintf(" %02x", data[seeker]);
- seeker++;
- break;
-
- case Script_Word:
- case Script_SWord:
- if (pass_no == 2)
- sciprintf(" %04x", 0xffff & (data[seeker] | (data[seeker+1] << 8)));
- seeker += 2;
- break;
-
- case Script_SVariable:
- case Script_Variable:
- case Script_Global:
- case Script_Local:
- case Script_Temp:
- case Script_Param:
- case Script_SRelative:
- case Script_Property:
- case Script_Offset:
- if (opsize)
- param_value = data [seeker++];
- else {
- param_value = 0xffff & (data[seeker] | (data[seeker+1] << 8));
- seeker += 2;
- }
-
- if (pass_no == 1) {
- if (opcode == op_jmp || opcode == op_bt || opcode == op_bnt) {
- dest = seeker + (short) param_value;
- sprintf(buf, "lbl_%04X", dest);
- script_add_name(s, dest, buf, -2);
- }
- } else if (pass_no == 2)
- switch (formats[opcode][i]) {
-
- case Script_SVariable:
- case Script_Variable:
- if (opcode == op_callk) {
- sciprintf(" #%s", (param_value < d->kernel_names_nr)
- ? d->kernel_names[param_value] : "<invalid>");
- if (verbose) sciprintf("[%x]", param_value);
- } else if (opcode == op_class || (opcode == op_super && i == 0)) {
- sciprintf(" %s", (d->class_names && param_value < d->class_count)
- ? d->class_names[param_value] : "<invalid>");
- if (verbose) sciprintf("[%x]", param_value);
- } else sciprintf(opsize ? " %02x" : " %04x", param_value);
-
- if (opcode == op_pushi && param_value > 0 && param_value < d->selector_count)
- sciprintf("\t\t; selector <%s>", d->snames [param_value]);
-
- break;
-
- case Script_Global:
- sciprintf(" global_%d", param_value);
- break;
-
- case Script_Local:
- sciprintf(" local_%d", param_value);
- break;
-
- case Script_Temp:
- sciprintf(" temp_%d", param_value);
- break;
-
- case Script_Param:
- sciprintf(" param_%d", param_value);
- break;
-
- case Script_Offset:
- dest = (short) param_value;
- dest_name = script_find_name(s, dest, NULL);
- if (dest_name)
- sciprintf(" %s", dest_name);
- else
- sciprintf(" %04x", dest);
-
- if (verbose)
- sciprintf(opsize ? " [%02x] " : " [%04x] ", param_value);
-
- if (opcode == op_lofsa || opcode == op_lofss) {
- int atype = script_get_area_type(s, dest, &area_data);
- if (atype == area_string) {
- strncpy(buf, (char *) &data [dest], sizeof(buf) - 1);
- buf [sizeof(buf)-1] = 0;
- if (strlen(buf) > 40) {
- buf [40] = 0;
- strcat(buf, "...");
- }
- sciprintf("\t\t; \"%s\"", buf);
- } else if (atype == area_said) {
- sciprintf("\t\t; said \"");
- script_dump_said_string(d, data, dest);
- sciprintf("\"\n");
- } else if (atype == area_object)
- sciprintf("\t\t; object <%s>", area_data);
- }
- break;
-
- case Script_SRelative:
- dest = seeker + (short) param_value;
- dest_name = script_find_name(s, dest, NULL);
- if (dest_name)
- sciprintf(" %s", dest_name);
- else
- sciprintf(" %04x", dest);
-
- if (verbose)
- sciprintf(opsize ? " [%02x] " : " [%04x] ", param_value);
-
- if (opcode == op_lofsa || opcode == op_lofss) {
- int atype = script_get_area_type(s, dest, &area_data);
- if (atype == area_string) {
- strncpy(buf, (char *) &data [dest], sizeof(buf) - 1);
- buf [sizeof(buf)-1] = 0;
- if (strlen(buf) > 40) {
- buf [40] = 0;
- strcat(buf, "...");
- }
- sciprintf("\t\t; \"%s\"", buf);
- } else if (atype == area_said) {
- sciprintf("\t\t; said \"");
- script_dump_said_string(d, data, dest);
- sciprintf("\"\n");
- } else if (atype == area_object)
- sciprintf("\t\t; object <%s>", area_data);
- }
- break;
-
- case Script_Property:
- if (cur_class != -1 && param_value / 2 < d->class_selector_count [cur_class]) {
- sciprintf(" %s", get_selector_name(d, d->class_selectors [cur_class][param_value/2]));
- if (verbose) sciprintf("[%x]", param_value);
- } else
- sciprintf(opsize ? " %02x" : " %04x", param_value);
-
- break;
-
- case Script_End:
- if (pass_no == 2) sciprintf("\n");
- break;
-
- default:
- sciprintf("Unexpected opcode format %d\n", (formats[opcode][i]));
- }
-
- default:
- break;
- }
- if (pass_no == 2) sciprintf("\n");
-
- }
-
-}
-
-void
-disassemble_script_pass(disasm_state_t *d, script_state_t *s,
- resource_t *script, int pass_no) {
- int _seeker = 0;
- word id = getInt16(script->data);
-
- if (id > 15) {
- if (pass_no == 2) sciprintf("; Old script header detected\n");
- d->old_header = 1;
- }
-
- if (d->old_header) _seeker = 2;
-
- while (_seeker < script->size) {
- int objtype = getInt16(script->data + _seeker);
- int objsize;
- int seeker = _seeker + 4;
-
- if (!objtype) return;
-
- if (pass_no == 2)
- sciprintf("\n");
-
- objsize = getInt16(script->data + _seeker + 2);
-
- if (pass_no == 2) {
- sciprintf("; Obj type #%x, offset 0x%x, size 0x%x:\n", objtype, _seeker, objsize);
- if (hexdump) sci_hexdump(script->data + seeker, objsize - 4, seeker);
- }
-
- _seeker += objsize;
-
- switch (objtype) {
- case sci_obj_object:
- script_dump_object(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_code:
- script_disassemble_code(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_synonyms:
- script_dump_synonyms(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_said:
- script_dump_said(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_strings:
- script_dump_strings(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_class:
- script_dump_class(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_exports:
- script_dump_exports(d, s, script->data, seeker, objsize, pass_no);
- break;
-
- case sci_obj_pointers:
- if (pass_no == 2) {
- sciprintf("Pointers\n");
- sci_hexdump(script->data + seeker, objsize - 4, seeker);
- };
- break;
-
- case sci_obj_preload_text:
- if (pass_no == 2) {
- sciprintf("The script has a preloaded text resource\n");
- };
- break;
-
- case sci_obj_localvars:
- if (pass_no == 2) {
- sciprintf("Local vars\n");
- sci_hexdump(script->data + seeker, objsize - 4, seeker);
- };
- break;
-
- default:
- sciprintf("Unsupported %d!\n", objtype);
- return;
- }
- }
-
- sciprintf("Script ends without terminator\n");
-}
-
-void
-disassemble_script(disasm_state_t *d, int res_no, int pass_no) {
- resource_t *script = scir_find_resource(resmgr, sci_script, res_no, 0);
- script_state_t *s = find_script_state(d, res_no);
-
- if (!script) {
- sciprintf("Script not found!\n");
- return;
- }
-
- disassemble_script_pass(d, s, script, pass_no);
-}