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; }