int extract_main() { int result; if (safemode::init()) { staterr("failed to initialize safemode graphics"); return 1; } result = introduction(); #ifdef __SDLSHIM__ if (result == SDLK_BTN1) #else if (result == SDLK_ESCAPE) #endif { stat("Breaking out"); return 1; } result = extract_do(); if (!result) conclusion(); result = 0; #if 1 if (pxt_LoadSoundFX(pxt_dir, sndcache, NUM_SOUNDS)) { print("Error: pxt_LoadSoundFX"); result = 1; safemode::close(); return result; } if (load_drumtable(pxt_dir)) { print("Error: load_drumtable"); result = 1; safemode::close(); return result; } #endif safemode::close(); return result; }
static int extract_do(void) { FILE *fp; clear(); moveto(SM_UPPER_THIRD); print("= Extracting Files ="); fp = fileopen(filename, "rb"); if (!fp) { moveto(SM_CENTER); print("cannot find executable %s", filename); print(""); print(""); print("Please put it and it's \"data\" directory"); print("into the same folder as this program."); run_until_key(); return 1; } if (extract_pxt(fp)) return 1; if (extract_files(fp)) return 1; if (extract_stages(fp)) return 1; //findfiles(fp); //exit(1); clearstatus(); fclose(fp); return 0; }
int conclusion() { moveto(SM_MIDUPPER_Y); print("Success!"); print(""); print("You can now remove the Doukutsu.exe file"); print("if you like, as it isn't needed anymore."); print("Please leave the \"data\" directory though."); print(""); #if 0 print("Once you get to the title screen, you may want"); print("to adjust your resolution by pressing F3."); print(""); print("Press any key to begin"); #else print("And now Create cache"); print("Press any key"); #endif return run_until_key(); }
int introduction() { clear(); moveto(SM_UPPER_THIRD); print("I need to extract some game data"); print("before I can start up for the first time."); print(""); print("Before beginning, you should have the Aeon Genesis"); print("English translation of version 1.0.0.6, and drop"); print("Doukutsu.exe and it's \"data\" directory into the same"); print("folder as the \"nx\" program you just ran."); print(""); #ifdef __SDLSHIM__ print("If you haven't done that yet, please press BTN1 now"); #else print("If you haven't done that yet, please press ESCAPE now"); #endif print("and come back in a moment. Otherwise, you can"); print("press any other key to start the extraction."); return run_until_key(); }
bool extract_pxt(FILE *fp) { struct { union { int intvalue; double fpvalue; } values[50]; } chan[4]; int s, c, i; for(s=0;;s++) { if (!snd[s].id) break; char outfilename[MAXPATHLEN]; sprintf(outfilename, "pxt/fx%02x.pxt", snd[s].id); status("[ %s ]", outfilename); #ifndef __MINGW32__ mkdir("pxt", 0755); #else mkdir("pxt"); #endif FILE *fpo = fileopen(outfilename, "wb"); if (!fpo) { status("failed to open %s", outfilename); return 1; } fseek(fp, snd[s].offset, SEEK_SET); memset(chan, 0, sizeof(chan)); // load data for(c=0;c<snd[s].nchanl;c++) { for(i=0;fields[i].name;i++) { if (fields[i].is_integer) { chan[c].values[i].intvalue = fgetl(fp); } else { chan[c].values[i].fpvalue = fgetfloat(fp); } } // skip padding between sections if (fgetl(fp) != 0) { status("PXT out of sync"); return 1; } } // write human-readable section for(c=0;c<4;c++) { for(i=0;fields[i].name;i++) { if (fields[i].is_integer) fprintf(fpo, "%s:%d\r\n", fields[i].name, chan[c].values[i].intvalue); else fprintf(fpo, "%s:%.2f\r\n", fields[i].name, chan[c].values[i].fpvalue); } fprintf(fpo, "\r\n"); } // write machine-readable section for(c=0;c<4;c++) { fprintf(fpo, "{"); for(i=0;fields[i].name;i++) { const char *suffix = (fields[i+1].name == NULL) ? "},\r\n" : ","; if (fields[i].is_integer) fprintf(fpo, "%d%s", chan[c].values[i].intvalue, suffix); else fprintf(fpo, "%.2f%s", chan[c].values[i].fpvalue, suffix); } } fclose(fpo); } return 0; }
bool extract_files(FILE *exefp) { uint8_t *buffer; uint8_t *file; uint32_t length; uint32_t crc; bool check_crc = true; bool first_crc_failure = true; buffer = (uint8_t *)malloc(MAX_FILE_SIZE); crc_init(); for(int i=0;;i++) { const char *outfilename = files[i].filename; if (!outfilename) break; status("[ %s ]", outfilename); // initialize header if any file = buffer; length = files[i].length; if (files[i].header) { memcpy(buffer, files[i].header, HEADER_LEN); file += HEADER_LEN; length += HEADER_LEN; } // read data from exe fseek(exefp, files[i].offset, SEEK_SET); fread(file, files[i].length, 1, exefp); if (check_crc) { crc = crc_calc(file, files[i].length); if (crc != files[i].crc) { status("File '%s' failed CRC check.", outfilename); print(""); #ifndef __SDLSHIM__ print("[I]gnore"); print("Ignore [A]ll"); print("[S]top"); #define IGNORE_BTN SDLK_i #define IGNORE_ALL_BTN SDLK_a #define STOP_BTN SDLK_s #else print("B1 - Ignore"); print("B2 - Ignore All"); print("B3 - Stop"); #define IGNORE_BTN SDLK_BTN1 #define IGNORE_ALL_BTN SDLK_BTN2 #define STOP_BTN SDLK_BTN3 #endif for(;;) { switch(run_until_key(first_crc_failure)) { case IGNORE_BTN: break; case IGNORE_ALL_BTN: check_crc = false; break; #ifndef __SDLSHIM__ case SDLK_ESCAPE: #endif case STOP_BTN: { free(buffer); return 1; } default: continue; } break; } first_crc_failure = false; } } // write out the file createdir(outfilename); FILE *fp = fileopen(outfilename, "wb"); if (!fp) { status("Failed to open '%s' for writing.", outfilename); free(buffer); return 1; } fwrite(buffer, length, 1, fp); fclose(fp); } free(buffer); return 0; }