/* Secret of Mana script dumper 0.1a By KnolanCross, PO.B.R.E. Mail me at: fgmcoelho (at) yahoo (dot) com (dot) br The algorith works like this: (names within [] are variables): 1º Set the constant values, creates the array (the game table) in order to con- vert the bytes to ASCII code. 2º Jumps to the offset [p] to read the pointer 3º Increases the pointer in 2 [p+=2] and jump to this offset (in other words: jump to the next pointer) 4º Calculate the size of the string [total] by subtraction the first pointer from the second pointer. 5º Read [total] positions in the script adress of the rom; if the value is in the tables, copies the correspondig letter into the txt, otherwise copy its value in the format <$VALUE> 6º if p < 0x0909FD go to 2º step, else finishes the program. */ #include #include #define ROM_NAME "som.smc" #define DMP_FILE "dmp.txt" #define OFFSET 0x90216 typedef unsigned char byte; byte read, read1, read2; // byte a ser lido e copiado int size; // tamanho da stream FILE *rom, // arquivo de entrada *dmp; // arquivo com os dados comprimidos int main(){ // Open the files //****************************************************************************** int primeira_parte, segunda_parte, res1, res2, total, p, temp_p, i, c, global_counter; char tabela[255]; /* primeira_parte = first byte, to generate the pointer segunda_parte = second byte, to generate the pointer res1 = first pointer res2 = second pointer total = string size p = OFFSET temp_p = pointer adress i e c = for math only global_counter = number of the strings */ rom=fopen(ROM_NAME, "rb"); // open rom file if(!rom) { printf("Erro ao abrir \"%s\".", ROM_NAME); exit(1); } dmp=fopen(DMP_FILE, "w"); // creates the txt file if(!dmp) { printf("Erro ao abrir \"%s\".", DMP_FILE); exit(1); } // Generates the game table //****************************************************************************** tabela[0x7F] = 0x0A; // LF (Line Feed) tabela[0x80] = 0x20; // space c = 97; // "a" to "z" for (i=129; i<155; i=i+1) { tabela[i] = c; c++; } c = 65; for (i=155; i<180; i=i+1) // "A" to "Z" { tabela[i] = c; c++; } c = 0x30; for (i=0xB5; i<0xBF; i=i+1) { tabela[i] = c; c++; } // 80 ao BE formados tabela[0xBF] = 0x2E; // . tabela[0xC0] = 0x2C; // , tabela[0xC1] = 0x21; // ! tabela[0xC2] = 0x27; // ' tabela[0xC3] = 0x22; // " tabela[0xC4] = 0x22; // " tabela[0xC5] = 0x3A; // : tabela[0xC6] = 0x2D; // - tabela[0xC7] = 0x2A; // * tabela[0xC8] = 0x21; // ! tabela[0xC9] = 0x26; // & tabela[0xCA] = 0x3F; // ? tabela[0xCB] = 0x28; // ( tabela[0xCC] = 0x29; // ) /* Generates the first byte7 *******************************************************************************/ p = OFFSET; global_counter = 0; do{ fseek(rom, p, SEEK_SET); fread(&read, 1, 1, rom); primeira_parte = read; fread(&read, 1, 1, rom); segunda_parte = read; res1 = (segunda_parte * 0x100) + primeira_parte + 0x200; /* Generates the second *******************************************************************************/ p += 0x2; fseek(rom, p, SEEK_SET); fread(&read, 1, 1, rom); primeira_parte = read; fread(&read, 1, 1, rom); segunda_parte = read; res2 = (segunda_parte * 0x100) + primeira_parte + 0x200; // String size total = (res2 - res1) - 1; /* Read [total] bytes and write then in the output file *******************************************************************************/ temp_p = res1 + 0x90000; if (global_counter < 0x100) // This if grants that the string index { // will always have three numbers. if (global_counter < 10) { fprintf(dmp, "\n[#00%X]\n",global_counter); } else { fprintf(dmp, "\n[#0%X]\n",global_counter); } } else { fprintf(dmp, "\n[#%X]\n",global_counter); } fseek(rom, temp_p, SEEK_SET); do{ fread(&read, 1, 1, rom); if (read >= 0x7F) { if (read < 0xCD) { read = tabela[read]; fwrite(&read, 1, 1, dmp); } else { fprintf(dmp, "<$%X>",read); } // end of the else }// end of the if else { if(read < 0x10) // This if grats that the Codes will { // always have two numbers. fprintf(dmp, "<$0%X>",read); } else { fprintf(dmp, "<$%X>",read); } } // end of the else total--; }while(total >= 0); global_counter++; }while(p <= 0x0909FD); // end of the do-while fclose(rom); fclose(dmp); printf("Everithing done with success! \n"); getch(); exit(0); }