diff options
Diffstat (limited to 'engines/sci/tools/scidisasm.cpp')
-rw-r--r-- | engines/sci/tools/scidisasm.cpp | 987 |
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); -} |