diff --git a/src/aindump/aindump.c b/src/aindump/aindump.c index 2da53dc..63f4506 100644 --- a/src/aindump/aindump.c +++ b/src/aindump/aindump.c @@ -42,10 +42,12 @@ static void usage(void) puts(" -S, --structures Dump structures section"); puts(" -m, --messages Dump messages section"); puts(" -l, --libraries Dump libraries section"); - puts(" --function-types Dump function type section"); + puts(" --function-types Dump function types section"); + puts(" --delegates Dump delegate types section"); puts(" --global-group-names Dump global group names section"); puts(" -e, --enums Dump enums section"); puts(" -A, --audit Audit AIN file for xsystem4 compatibility"); + puts(" -d, --decrypt Dump decrypted AIN file"); //puts(" -j, --json Dump to JSON format"); // TODO } @@ -80,19 +82,38 @@ static void print_arglist(FILE *f, struct ain *ain, struct ain_variable *args, i fputc(')', f); } +static void print_varlist(FILE *f, struct ain *ain, struct ain_variable *vars, int nr_vars) +{ + if (!nr_vars) { + fputc(';', f); + return; + } + + for (int i = 0; i < nr_vars; i++) { + if (i > 0) + fputc(',', f); + fputc(' ', f); + print_sjis(f, ain_strtype(ain, vars[i].data_type, vars[i].struct_type)); + fputc(' ', f); + print_sjis(f, vars[i].name); + } + fputc(';', f); +} + static void print_function(FILE *out, struct ain *ain, struct ain_function *f) { print_sjis(out, ain_strtype(ain, f->data_type, f->struct_type)); fputc(' ', out); print_sjis(out, f->name); print_arglist(out, ain, f->vars, f->nr_args); + print_varlist(out, ain, f->vars+f->nr_args, f->nr_vars - f->nr_args); fputc('\n', out); } static void ain_dump_functions(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_functions; i++) { - fprintf(f, "0x%x:\t", i); + fprintf(f, "/* 0x%08x */\t", i); print_function(f, ain, &ain->functions[i]); } } @@ -131,6 +152,7 @@ static void print_structure(FILE *f, struct ain *ain, struct ain_struct *s) static void ain_dump_structures(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_structures; i++) { + fprintf(f, "//0x%08x:\n", i); print_structure(f, ain, &ain->structures[i]); } } @@ -138,8 +160,8 @@ static void ain_dump_structures(FILE *f, struct ain *ain) static void ain_dump_messages(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_messages; i++) { + fprintf(f, "0x%08x:\t", i); print_sjis(f, ain->messages[i]->text); - //fprintf(f, "\n---\n"); } } @@ -173,24 +195,29 @@ static void ain_dump_libraries(FILE *out, struct ain *ain) static void ain_dump_strings(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_strings; i++) { + fprintf(f, "0x%08x:\t", i); print_sjis(f, ain->strings[i]->text); - //fprintf(f, "\n---\n"); + fputc('\n', f); } } static void ain_dump_filenames(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_filenames; i++) { + fprintf(f, "0x%08x:\t", i); print_sjis(f, ain->filenames[i]); fputc('\n', f); } } -static void ain_dump_functypes(FILE *f, struct ain *ain) +static void ain_dump_functypes(FILE *f, struct ain *ain, bool delegates) { - for (int i = 0; i < ain->nr_function_types; i++) { - struct ain_function_type *t = &ain->function_types[i]; - fprintf(f, "functype "); + struct ain_function_type *types = delegates ? ain->delegates : ain->function_types; + int n = delegates ? ain->nr_delegates : ain->nr_function_types; + for (int i = 0; i < n; i++) { + fprintf(f, "/* 0x%08x */\t", i); + struct ain_function_type *t = &types[i]; + fprintf(f, delegates ? "delegate " : "functype "); print_sjis(f, ain_strtype(ain, t->data_type, t->struct_type)); fputc(' ', f); print_sjis(f, t->name); @@ -202,6 +229,7 @@ static void ain_dump_functypes(FILE *f, struct ain *ain) static void ain_dump_global_group_names(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_global_groups; i++) { + fprintf(f, "0x%08x:\t", i); print_sjis(f, ain->global_group_names[i]); fputc('\n', f); } @@ -210,6 +238,7 @@ static void ain_dump_global_group_names(FILE *f, struct ain *ain) static void ain_dump_enums(FILE *f, struct ain *ain) { for (int i = 0; i < ain->nr_enums; i++) { + fprintf(f, "0x%08x:\t", i); print_sjis(f, ain->enums[i]); fputc('\n', f); } @@ -273,6 +302,7 @@ int main(int argc, char *argv[]) bool dump_strings = false; bool dump_filenames = false; bool dump_functypes = false; + bool dump_delegates = false; bool dump_global_group_names = false; bool dump_enums = false; bool audit = false; @@ -296,6 +326,7 @@ int main(int argc, char *argv[]) { "strings", no_argument, 0, 's' }, { "filenames", no_argument, 0, 'F' }, { "function-types", no_argument, 0, 't' }, + { "delegates", no_argument, 0, 'D' }, { "global-group-names", no_argument, 0, 'r' }, { "enums", no_argument, 0, 'e' }, { "audit", no_argument, 0, 'A' }, @@ -346,6 +377,9 @@ int main(int argc, char *argv[]) case 't': dump_functypes = true; break; + case 'D': + dump_delegates = true; + break; case 'G': dump_global_group_names = true; break; @@ -396,7 +430,9 @@ int main(int argc, char *argv[]) if (dump_structures) ain_dump_structures(output, ain); if (dump_functypes) - ain_dump_functypes(output, ain); + ain_dump_functypes(output, ain, false); + if (dump_delegates) + ain_dump_functypes(output, ain, true); if (dump_global_group_names) ain_dump_global_group_names(output, ain); if (dump_globals) diff --git a/src/aindump/dasm.c b/src/aindump/dasm.c index 04b34a2..0f1f046 100644 --- a/src/aindump/dasm.c +++ b/src/aindump/dasm.c @@ -164,6 +164,11 @@ static void print_argument(struct dasm_state *dasm, int32_t arg, enum instructio DASM_ERROR(dasm, "Invalid function number: %d", arg); print_sjis(dasm, ain->functions[arg].name); break; + case T_DLG: + if (arg < 0 || arg >= ain->nr_delegates) + DASM_ERROR(dasm, "Invalid delegate number: %d", arg); + print_sjis(dasm, ain->delegates[arg].name); + break; case T_STRING: if (arg < 0 || arg >= ain->nr_strings) DASM_ERROR(dasm, "Invalid string number: %d", arg); @@ -214,7 +219,7 @@ static void print_argument(struct dasm_state *dasm, int32_t arg, enum instructio print_sjis(dasm, ain->filenames[arg]); break; default: - fprintf(dasm->out, ""); + fprintf(dasm->out, "", type); break; } } @@ -278,6 +283,20 @@ static char *genlabel(size_t addr) return strdup(name); } +static void generate_labels(struct dasm_state *dasm) +{ + for (dasm->addr = 0; dasm->addr < dasm->ain->code_size;) { + const struct instruction *instr = get_instruction(dasm); + for (int i = 0; i < instr->nr_args; i++) { + if (instr->args[i] != T_ADDR) + continue; + int32_t arg = LittleEndian_getDW(dasm->ain->code, dasm->addr + 2 + i*4); + add_label(genlabel(arg), arg); + } + dasm->addr += instruction_width(instr->opcode); + } +} + void disassemble_ain(FILE *out, struct ain *ain, bool raw) { struct dasm_state dasm = { @@ -288,23 +307,8 @@ void disassemble_ain(FILE *out, struct ain *ain, bool raw) .raw = raw }; - if (!raw) { - // first pass to generate labels - for (dasm.addr = 0; dasm.addr < dasm.ain->code_size;) { - const struct instruction *instr = get_instruction(&dasm); - switch (instr->opcode) { - case JUMP: - case IFZ: - case IFNZ: { - int32_t arg = LittleEndian_getDW(dasm.ain->code, dasm.addr + 2); - add_label(genlabel(arg), arg); - break; - } - default: break; - } - dasm.addr += instruction_width(instr->opcode); - } - } + if (!raw) + generate_labels(&dasm); for (dasm.addr = 0; dasm.addr < dasm.ain->code_size;) { const struct instruction *instr = get_instruction(&dasm);