Tuple *psf2_tuple(const char *filename, VFSFile *file) { Tuple *t; corlett_t *c; void *buf; int64_t sz; vfs_file_get_contents (filename, & buf, & sz); if (!buf) return NULL; if (corlett_decode(buf, sz, NULL, NULL, &c) != AO_SUCCESS) return NULL; t = tuple_new_from_filename(filename); tuple_set_int(t, FIELD_LENGTH, NULL, c->inf_length ? psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade) : -1); tuple_set_str(t, FIELD_ARTIST, NULL, c->inf_artist); tuple_set_str(t, FIELD_ALBUM, NULL, c->inf_game); tuple_set_str(t, -1, "game", c->inf_game); tuple_set_str(t, FIELD_TITLE, NULL, c->inf_title); tuple_set_str(t, FIELD_COPYRIGHT, NULL, c->inf_copy); tuple_set_str(t, FIELD_QUALITY, NULL, _("sequenced")); tuple_set_str(t, FIELD_CODEC, NULL, "PlayStation 1/2 Audio"); tuple_set_str(t, -1, "console", "PlayStation 1/2"); free(c); free(buf); return t; }
s32 ssf_start(u8 *buffer, u32 length, int m68k_core, int sndcore, char* filename) { u8 *file, *lib_decoded, *lib_raw_file; u32 offset, lengthMS, fadeMS; u64 file_len, lib_len, lib_raw_length; corlett_t *lib; char *libfile; int i; M68KInit(m68k_core); ScspInit(sndcore); // clear Saturn work RAM before we start scribbling in it memset((void *)SoundRam, 0, 0x80000); // Decode the current SSF if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS) { return AO_FAIL; } #if DEBUG_LOADER printf("%d bytes decoded\n", file_len); #endif // Get the library file, if any for (i=0; i<9; i++) { libfile = i ? c->libaux[i-1] : c->lib; if (libfile[0] != 0) { u64 tmp_length; char libfile_path[2048] = { 0 }; if (!get_lib_file(filename, libfile, libfile_path)) return AO_FAIL; #if DEBUG_LOADER printf("Loading library: %s\n", c->lib); #endif if (ao_get_lib(libfile_path, &lib_raw_file, &tmp_length) != AO_SUCCESS) { return AO_FAIL; } lib_raw_length = tmp_length; if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS) { free(lib_raw_file); free(file); return AO_FAIL; } // Free up raw file free(lib_raw_file); // patch the file into ram offset = lib_decoded[0] | lib_decoded[1]<<8 | lib_decoded[2]<<16 | lib_decoded[3]<<24; // guard against invalid data if ((offset + (lib_len-4)) > 0x7ffff) { lib_len = 0x80000-offset+4; } memcpy(&SoundRam[offset], lib_decoded+4, lib_len-4); // Dispose the corlett structure for the lib - we don't use it free(lib); } } // now patch the file into RAM over the libraries offset = file[3]<<24 | file[2]<<16 | file[1]<<8 | file[0]; // guard against invalid data if ((offset + (file_len-4)) > 0x7ffff) { file_len = 0x80000-offset+4; } memcpy(&SoundRam[offset], file+4, file_len-4); free(file); // Finally, set psfby tag strcpy(psfby, "n/a"); if (c) { for (i = 0; i < MAX_UNKNOWN_TAGS; i++) { if (!strcasecmp(c->tag_name[i], "psfby")) strcpy(psfby, c->tag_data[i]); } } #if DEBUG_LOADER && 1 { FILE *f; f = fopen("satram.bin", "wb"); fwrite(sat_ram, 512*1024, 1, f); fclose(f); } #endif // now flip everything (this makes sense because he's using starscream) for (i = 0; i < 512*1024; i+=2) { u8 temp; temp = SoundRam[i]; SoundRam[i] = SoundRam[i+1]; SoundRam[i+1] = temp; } M68KStart (); // now figure out the time in samples for the length/fade lengthMS = psfTimeToMS(c->inf_length); fadeMS = psfTimeToMS(c->inf_fade); total_samples = 0; if (lengthMS == 0) { lengthMS = ~0; } if (lengthMS == ~0) { decaybegin = lengthMS; } else { lengthMS = (lengthMS * 441) / 10; fadeMS = (fadeMS * 441) / 10; decaybegin = lengthMS; decayend = lengthMS + fadeMS; } return AO_SUCCESS; }
int32 dsf_start(uint8 *buffer, uint32 length) { uint8 *file, *lib_decoded, *lib_raw_file; uint32 offset, plength, lengthMS, fadeMS; uint64 file_len, lib_len, lib_raw_length; corlett_t *lib; char *libfile; int i; // clear Dreamcast work RAM before we start scribbling in it memset(dc_ram, 0, 8*1024*1024); // Decode the current SSF if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS) { return AO_FAIL; } #if DEBUG_LOADER printf("%d bytes decoded\n", file_len); #endif // Get the library file, if any for (i=0; i<9; i++) { libfile = i ? c->libaux[i-1] : c->lib; if (libfile[0] != 0) { uint64 tmp_length; #if DEBUG_LOADER printf("Loading library: %s\n", c->lib); #endif if (ao_get_lib(libfile, &lib_raw_file, &tmp_length) != AO_SUCCESS) { return AO_FAIL; } lib_raw_length = tmp_length; if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS) { free(lib_raw_file); return AO_FAIL; } // Free up raw file free(lib_raw_file); // patch the file into ram offset = lib_decoded[0] | lib_decoded[1]<<8 | lib_decoded[2]<<16 | lib_decoded[3]<<24; memcpy(&dc_ram[offset], lib_decoded+4, lib_len-4); // Dispose the corlett structure for the lib - we don't use it free(lib); } } // now patch the file into RAM over the libraries offset = file[3]<<24 | file[2]<<16 | file[1]<<8 | file[0]; memcpy(&dc_ram[offset], file+4, file_len-4); free(file); // Finally, set psfby/ssfby tag strcpy(psfby, "n/a"); if (c) { for (i = 0; i < MAX_UNKNOWN_TAGS; i++) { if ((!strcasecmp(c->tag_name[i], "psfby")) || (!strcasecmp(c->tag_name[i], "ssfby"))) strcpy(psfby, c->tag_data[i]); } } #if DEBUG_LOADER && 1 { FILE *f; f = fopen("dcram.bin", "wb"); fwrite(dc_ram, 2*1024*1024, 1, f); fclose(f); } #endif #if DK_CORE ARM7_Init(); #else arm7_init(0, 45000000, NULL, NULL); arm7_reset(); #endif dc_hw_init(); // now figure out the time in samples for the length/fade lengthMS = psfTimeToMS(c->inf_length); fadeMS = psfTimeToMS(c->inf_fade); total_samples = 0; if (lengthMS == 0) { lengthMS = ~0; } if (lengthMS == ~0) { decaybegin = lengthMS; } else { lengthMS = (lengthMS * 441) / 10; fadeMS = (fadeMS * 441) / 10; decaybegin = lengthMS; decayend = lengthMS + fadeMS; } return AO_SUCCESS; }
void *qsf_start(const char *path, uint8 *buffer, uint32 length) { qsf_synth_t *s = malloc (sizeof (qsf_synth_t)); memset (s, 0, sizeof (qsf_synth_t)); uint8 *file = NULL, *lib_decoded = NULL, *lib_raw_file = NULL; uint64 file_len, lib_len, lib_raw_length; corlett_t *lib; s->z80 = z80_init(); s->z80->userdata = s; s->Z80ROM = malloc(512*1024); s->QSamples = malloc(8*1024*1024); s->skey1 = s->skey2 = 0; s->akey = 0; s->xkey = 0; s->cur_bank = 0; // Decode the current QSF if (corlett_decode(buffer, length, &file, &file_len, &s->c) != AO_SUCCESS) { return AO_FAIL; } // Get the library file if (s->c->lib[0] != 0) { uint64 tmp_length; char libpath[PATH_MAX]; ao_getlibpath (path, s->c->lib, libpath, sizeof (libpath)); #if DEBUG_LOADER printf("Loading library: %s\n", libpath); #endif if (ao_get_lib(libpath, &lib_raw_file, &tmp_length) != AO_SUCCESS) { free (file); qsf_stop (s); return NULL; } lib_raw_length = tmp_length; if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS) { free(lib_raw_file); free (file); qsf_stop (s); return NULL; } // Free up raw file free(lib_raw_file); // use the contents qsf_walktags(s, lib_decoded, lib_decoded+lib_len); // Dispose the corlett structure for the lib - we don't use it free(lib); if (lib_decoded) { free (lib_decoded); lib_decoded = NULL; } } // now patch the file into RAM OVER the libraries qsf_walktags(s, file, file+file_len); free(file); if ((s->skey1 != 0) && (s->skey2 != 0)) { #if DEBUG_LOADER printf("Decoding Kabuki: skey1 %08x skey2 %08x akey %04x xkey %02x\n", skey1, skey2, akey, xkey); #endif s->uses_kabuki = 1; cps1_decode((unsigned char *)s->Z80ROM, s->skey1, s->skey2, s->akey, s->xkey); } // set qsfby tag strcpy(s->qsfby, "n/a"); if (s->c) { int i; for (i = 0; i < MAX_UNKNOWN_TAGS; i++) { if (!strcasecmp(s->c->tag_name[i], "qsfby")) { strcpy(s->qsfby, s->c->tag_data[i]); } } } memcpy (s->initRAM, s->RAM, 0x1000); memcpy (s->initRAM2, s->RAM2, 0x1000); if (s->z80) { z80_reset(s->z80, NULL); z80_set_irq_callback(s->z80, qsf_irq_cb); } qsintf.sample_rom = s->QSamples; s->qs = qsound_sh_start(&qsintf); s->samples_to_next_tick = samples_per_tick; return s; }
int32 psf_start(uint8 *buffer, uint32 length) { uint8 *file, *lib_decoded, *lib_raw_file, *alib_decoded; uint32 offset, plength, PC, SP, GP, lengthMS, fadeMS; uint64 file_len, lib_len, lib_raw_length, alib_len; corlett_t *lib; int i; union cpuinfo mipsinfo; // clear PSX work RAM before we start scribbling in it memset(psx_ram, 0, 2*1024*1024); // printf("Length = %d\n", length); // Decode the current GSF if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS) { return AO_FAIL; } // printf("file_len %d reserve %d\n", file_len, c->res_size); // check for PSX EXE signature if (strncmp((char *)file, "PS-X EXE", 8)) { return AO_FAIL; } #if DEBUG_LOADER offset = file[0x18] | file[0x19]<<8 | file[0x1a]<<16 | file[0x1b]<<24; printf("Text section start: %x\n", offset); offset = file[0x1c] | file[0x1d]<<8 | file[0x1e]<<16 | file[0x1f]<<24; printf("Text section size: %x\n", offset); printf("Region: [%s]\n", &file[0x4c]); printf("refresh: [%s]\n", c->inf_refresh); #endif if (c->inf_refresh[0] == '5') { psf_refresh = 50; } if (c->inf_refresh[0] == '6') { psf_refresh = 60; } PC = file[0x10] | file[0x11]<<8 | file[0x12]<<16 | file[0x13]<<24; GP = file[0x14] | file[0x15]<<8 | file[0x16]<<16 | file[0x17]<<24; SP = file[0x30] | file[0x31]<<8 | file[0x32]<<16 | file[0x33]<<24; #if DEBUG_LOADER printf("Top level: PC %x GP %x SP %x\n", PC, GP, SP); #endif // Get the library file, if any if (c->lib[0] != 0) { uint64 tmp_length; #if DEBUG_LOADER printf("Loading library: %s\n", c->lib); #endif if (ao_get_lib(c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS) { return AO_FAIL; } lib_raw_length = tmp_length; if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS) { free(lib_raw_file); return AO_FAIL; } // Free up raw file free(lib_raw_file); if (strncmp((char *)lib_decoded, "PS-X EXE", 8)) { printf("Major error! PSF was OK, but referenced library is not!\n"); free(lib); return AO_FAIL; } #if DEBUG_LOADER offset = lib_decoded[0x18] | lib_decoded[0x19]<<8 | lib_decoded[0x1a]<<16 | lib_decoded[0x1b]<<24; printf("Text section start: %x\n", offset); offset = lib_decoded[0x1c] | lib_decoded[0x1d]<<8 | lib_decoded[0x1e]<<16 | lib_decoded[0x1f]<<24; printf("Text section size: %x\n", offset); printf("Region: [%s]\n", &lib_decoded[0x4c]); printf("refresh: [%s]\n", lib->inf_refresh); #endif // if the original file had no refresh tag, give the lib a shot if (psf_refresh == -1) { if (lib->inf_refresh[0] == '5') { psf_refresh = 50; } if (lib->inf_refresh[0] == '6') { psf_refresh = 60; } } PC = lib_decoded[0x10] | lib_decoded[0x11]<<8 | lib_decoded[0x12]<<16 | lib_decoded[0x13]<<24; GP = lib_decoded[0x14] | lib_decoded[0x15]<<8 | lib_decoded[0x16]<<16 | lib_decoded[0x17]<<24; SP = lib_decoded[0x30] | lib_decoded[0x31]<<8 | lib_decoded[0x32]<<16 | lib_decoded[0x33]<<24; #if DEBUG_LOADER printf("Library: PC %x GP %x SP %x\n", PC, GP, SP); #endif // now patch the file into RAM offset = lib_decoded[0x18] | lib_decoded[0x19]<<8 | lib_decoded[0x1a]<<16 | lib_decoded[0x1b]<<24; offset &= 0x3fffffff; // kill any MIPS cache segment indicators plength = lib_decoded[0x1c] | lib_decoded[0x1d]<<8 | lib_decoded[0x1e]<<16 | lib_decoded[0x1f]<<24; #if DEBUG_LOADER printf("library offset: %x plength: %d\n", offset, plength); #endif memcpy(&psx_ram[offset/4], lib_decoded+2048, plength); // Dispose the corlett structure for the lib - we don't use it free(lib); } // now patch the main file into RAM OVER the libraries (but not the aux lib) offset = file[0x18] | file[0x19]<<8 | file[0x1a]<<16 | file[0x1b]<<24; offset &= 0x3fffffff; // kill any MIPS cache segment indicators plength = file[0x1c] | file[0x1d]<<8 | file[0x1e]<<16 | file[0x1f]<<24; // Philosoma has an illegal "plength". *sigh* if (plength > (file_len-2048)) { plength = file_len-2048; } memcpy(&psx_ram[offset/4], file+2048, plength); // load any auxiliary libraries now for (i = 0; i < 8; i++) { if (c->libaux[i][0] != 0) { uint64 tmp_length; #if DEBUG_LOADER printf("Loading aux library: %s\n", c->libaux[i]); #endif if (ao_get_lib(c->libaux[i], &lib_raw_file, &tmp_length) != AO_SUCCESS) { return AO_FAIL; } lib_raw_length = tmp_length; if (corlett_decode(lib_raw_file, lib_raw_length, &alib_decoded, &alib_len, &lib) != AO_SUCCESS) { free(lib_raw_file); return AO_FAIL; } // Free up raw file free(lib_raw_file); if (strncmp((char *)alib_decoded, "PS-X EXE", 8)) { printf("Major error! PSF was OK, but referenced library is not!\n"); free(lib); return AO_FAIL; } #if DEBUG_LOADER offset = alib_decoded[0x18] | alib_decoded[0x19]<<8 | alib_decoded[0x1a]<<16 | alib_decoded[0x1b]<<24; printf("Text section start: %x\n", offset); offset = alib_decoded[0x1c] | alib_decoded[0x1d]<<8 | alib_decoded[0x1e]<<16 | alib_decoded[0x1f]<<24; printf("Text section size: %x\n", offset); printf("Region: [%s]\n", &alib_decoded[0x4c]); #endif // now patch the file into RAM offset = alib_decoded[0x18] | alib_decoded[0x19]<<8 | alib_decoded[0x1a]<<16 | alib_decoded[0x1b]<<24; offset &= 0x3fffffff; // kill any MIPS cache segment indicators plength = alib_decoded[0x1c] | alib_decoded[0x1d]<<8 | alib_decoded[0x1e]<<16 | alib_decoded[0x1f]<<24; memcpy(&psx_ram[offset/4], alib_decoded+2048, plength); // Dispose the corlett structure for the lib - we don't use it free(lib); } } free(file); // free(lib_decoded); // Finally, set psfby tag strcpy(psfby, "n/a"); if (c) { int i; for (i = 0; i < MAX_UNKNOWN_TAGS; i++) { if (!strcasecmp(c->tag_name[i], "psfby")) strcpy(psfby, c->tag_data[i]); } } mips_init(); mips_reset(NULL); // set the initial PC, SP, GP #if DEBUG_LOADER printf("Initial PC %x, GP %x, SP %x\n", PC, GP, SP); printf("Refresh = %d\n", psf_refresh); #endif mipsinfo.i = PC; mips_set_info(CPUINFO_INT_PC, &mipsinfo); // set some reasonable default for the stack if (SP == 0) { SP = 0x801fff00; } mipsinfo.i = SP; mips_set_info(CPUINFO_INT_REGISTER + MIPS_R29, &mipsinfo); mips_set_info(CPUINFO_INT_REGISTER + MIPS_R30, &mipsinfo); mipsinfo.i = GP; mips_set_info(CPUINFO_INT_REGISTER + MIPS_R28, &mipsinfo); #if DEBUG_LOADER && 1 { FILE *f; f = fopen("psxram.bin", "wb"); fwrite(psx_ram, 2*1024*1024, 1, f); fclose(f); } #endif psx_hw_init(); SPUinit(); SPUopen(); lengthMS = psfTimeToMS(c->inf_length); fadeMS = psfTimeToMS(c->inf_fade); #if DEBUG_LOADER printf("length %d fade %d\n", lengthMS, fadeMS); #endif if (lengthMS == 0) { lengthMS = ~0; } setlength(lengthMS, fadeMS); // patch illegal Chocobo Dungeon 2 code - CaitSith2 put a jump in the delay slot from a BNE // and rely on Highly Experimental's buggy-ass CPU to rescue them. Verified on real hardware // that the initial code is wrong. if (c->inf_game) { if (!strcmp(c->inf_game, "Chocobo Dungeon 2")) { if (psx_ram[0xbc090/4] == LE32(0x0802f040)) { psx_ram[0xbc090/4] = LE32(0); psx_ram[0xbc094/4] = LE32(0x0802f040); psx_ram[0xbc098/4] = LE32(0); } } } // psx_ram[0x118b8/4] = LE32(0); // crash 2 hack // backup the initial state for restart memcpy(initial_ram, psx_ram, 2*1024*1024); memcpy(initial_scratch, psx_scratch, 0x400); initialPC = PC; initialGP = GP; initialSP = SP; mips_execute(5000); return AO_SUCCESS; }
int32 qsf_start(uint8 *buffer, uint32 length) { uint8 *file, *lib_decoded, *lib_raw_file; uint64 file_len, lib_len, lib_raw_length; corlett_t *lib; z80_init(); Z80ROM = malloc(512*1024); QSamples = malloc(8*1024*1024); skey1 = skey2 = 0; akey = 0; xkey = 0; cur_bank = 0; memset(RAM, 0, 0x1000); memset(RAM2, 0, 0x1000); // Decode the current QSF if (corlett_decode(buffer, length, &file, &file_len, &c) != AO_SUCCESS) { return AO_FAIL; } // Get the library file if (c->lib[0] != 0) { uint64 tmp_length; #if DEBUG_LOADER printf("Loading library: %s\n", c->lib); #endif if (ao_get_lib(c->lib, &lib_raw_file, &tmp_length) != AO_SUCCESS) { return AO_FAIL; } lib_raw_length = tmp_length; if (corlett_decode(lib_raw_file, lib_raw_length, &lib_decoded, &lib_len, &lib) != AO_SUCCESS) { free(lib_raw_file); return AO_FAIL; } // Free up raw file free(lib_raw_file); // use the contents qsf_walktags(lib_decoded, lib_decoded+lib_len); // Dispose the corlett structure for the lib - we don't use it free(lib); } // now patch the file into RAM OVER the libraries qsf_walktags(file, file+file_len); free(file); if ((skey1 != 0) && (skey2 != 0)) { #if DEBUG_LOADER printf("Decoding Kabuki: skey1 %08x skey2 %08x akey %04x xkey %02x\n", skey1, skey2, akey, xkey); #endif uses_kabuki = 1; cps1_decode((unsigned char *)Z80ROM, skey1, skey2, akey, xkey); } // set qsfby tag strcpy(qsfby, "n/a"); if (c) { int i; for (i = 0; i < MAX_UNKNOWN_TAGS; i++) { if (!strcasecmp(c->tag_name[i], "qsfby")) { strcpy(qsfby, c->tag_data[i]); } } } z80_reset(NULL); z80_set_irq_callback(qsf_irq_cb); qsintf.sample_rom = QSamples; qsound_sh_start(&qsintf); return AO_SUCCESS; }
// load and set up a 2sf file int read_in_file(char *name) { FILE *file; uint32 filesig; uint8 *filedata; uint64 file_len; unsigned int size; struct stat st; c = NULL; file = fopen(name, "rb"); if (!file) { RED(); printf("ERROR: could not open file %s\n", name); NORMAL(); return -1; } // get the length of the file by using fstat fstat(fileno(file), &st); if (st.st_size > UINT_MAX) { fclose(file); RED(); printf("ERROR: file size of %zu bytes is larger than maximum supported value of %u\n", st.st_size, UINT_MAX); NORMAL(); return -1; } size = (unsigned int) st.st_size; buffer = malloc((size_t) size); if (!buffer) { fclose(file); RED(); printf("ERROR: could not allocate %d bytes of memory\n", size); NORMAL(); return -1; } // read the file fread(buffer, size, 1, file); fclose(file); // init our *SF engine so we can get tags if (corlett_decode(buffer, size, &filedata, &file_len, &c) != AO_SUCCESS) { RED(); printf("ERROR: Tag format unreadable in file "); MAGENTA(); printf("%s\n", name); NORMAL(); return -1; } free(filedata); // we don't use this if (xsf_start(buffer, size) != XSF_TRUE) { RED(); printf("ERROR: vio2sf failed to load file \n"); MAGENTA(); printf("%s\n", name); NORMAL(); return -1; } return 0; }