void GameViewer::Refresh() { Emu.GetVFS().Init(m_path); LoadGames(); LoadPSF(); ShowData(); Emu.GetVFS().UnMountAll(); }
PSFINFO *sexy_getpsfinfo(char *path) { PSFINFO *ret; if(!(ret=LoadPSF(path,0,1))) return(0); if(ret->stop==~0) ret->fade=0; ret->length=ret->stop+ret->fade; return(ret); }
PSFINFO *sexy_load(char *path,const char *pathDir,int loop_infinite) { PSFINFO *ret; if( psxInit() < 0 ) return(0); psxReset(); sexySPUinit(); sexySPUopen(); if(!(ret=LoadPSF(path,0,0,pathDir))) { psxShutdown(); return(0); } strcpy(save_path,path); strcpy(save_pathDir,pathDir); // Taken from aosdk's eng_psf.c file ... // 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 (ret->game) { if (!strcmp(ret->game, "Chocobo Dungeon 2")) { if (psxMu32(0xbc090) == (0x0802f040)) { psxMemWrite32(0xbc090, 0); psxMemWrite32(0xbc094, 0x0802f040); psxMemWrite32(0xbc098, 0); } } } if(ret->stop==~0) { ret->fade=10000; // Infinity ? limit to 3 minutes ret->stop=170000; } if (loop_infinite) { ret->stop=~0; } sexysetlength(ret->stop,ret->fade); ret->length=ret->stop+ret->fade; return(ret); }
PSFINFO *sexy_load(char *path) { PSFINFO *ret; psxInit(); psxReset(); SPUinit(); SPUopen(); if(!(ret=LoadPSF(path,0,0))) { psxShutdown(); return(0); } if(ret->stop==~0) ret->fade=0; // Infinity+anything is still infinity...or is it? SPUsetlength(ret->stop,ret->fade); ret->length=ret->stop+ret->fade; return(ret); }
void GameViewer::Refresh() { LoadGames(); LoadPSF(); ShowData(); }
static PSFINFO *LoadPSF(char *path, int level, int type) // Type==1 for just info load. { FILE *fp; EXE_HEADER tmpHead; char *in,*out=0; u8 head[4]; u32 reserved; u32 complen; u32 crc32; uLongf outlen; PSFINFO *psfi; PSFINFO *tmpi; //printf("Loading: %s\n",path); if(!(fp=fopen(path,"rb"))) { return(0); } fread(head,1,4,fp); if(memcmp(head,"PSF\x01",4)) return(0); psfi=malloc(sizeof(PSFINFO)); memset(psfi,0,sizeof(PSFINFO)); psfi->stop=~0; psfi->fade=0; fread(&reserved,1,4,fp); fread(&complen,1,4,fp); complen=BFLIP32(complen); fread(&crc32,1,4,fp); crc32=BFLIP32(crc32); fseek(fp,reserved,SEEK_CUR); if(type) fseek(fp,complen,SEEK_CUR); else { in=malloc(complen); out=malloc(1024*1024*2+0x800); fread(in,1,complen,fp); outlen=1024*1024*2; uncompress(out,&outlen,in,complen); free(in); memcpy(&tmpHead,out,sizeof(EXE_HEADER)); psxRegs.pc = BFLIP32(tmpHead.pc0); psxRegs.GPR.n.gp = BFLIP32(tmpHead.gp0); psxRegs.GPR.n.sp = BFLIP32(tmpHead.S_addr); if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00; if(level) { LoadPSXMem(BFLIP32(tmpHead.t_addr),BFLIP32(tmpHead.t_size),out+0x800); free(out); } } { u8 tagdata[5]; if(fread(tagdata,1,5,fp)==5) { if(!memcmp(tagdata,"[TAG]",5)) { char linebuf[1024]; while(fgets(linebuf,1024,fp)>0) { int x; char *key=0,*value=0; if(!GetKeyVal(linebuf,&key,&value)) { if(key) free(key); if(value) free(value); continue; } AddKV(&psfi->tags,key,value); if(!level) { static char *yoinks[8]={"title","artist","game","year","genre", "copyright","psfby","comment"}; char **yoinks2[8]={&psfi->title,&psfi->artist,&psfi->game,&psfi->year,&psfi->genre, &psfi->copyright,&psfi->psfby,&psfi->comment}; for(x=0;x<8;x++) if(!strcasecmp(key,yoinks[x])) *yoinks2[x]=value; if(!strcasecmp(key,"length")) psfi->stop=TimeToMS(value); else if(!strcasecmp(key,"fade")) psfi->fade=TimeToMS(value); } if(!strcasecmp(key,"_lib") && !type) { char *tmpfn; /* Load file name "value" from the directory specified in the full path(directory + file name) "path" */ tmpfn=findFileIgnoreCase(path,value); if(!(tmpi=LoadPSF(tmpfn,level+1,0))) { //free(key); //free(value); // key and value will be freed by FreeTags(psfi->tags) free(tmpfn); if(!level) free(out); fclose(fp); FreeTags(psfi->tags); free(psfi); return(0); } FreeTags(tmpi->tags); free(tmpi); free(tmpfn); } } } } } fclose(fp); /* Now, if we're at level 0(main PSF), load the main executable, and any libN stuff */ if(!level && !type) { LoadPSXMem(BFLIP32(tmpHead.t_addr),BFLIP32(tmpHead.t_size),out+0x800); free(out); } if(!type) /* Load libN */ { LIBNCACHE *cache; PSFTAG *tag; unsigned int libncount=0; unsigned int cur=0; tag=psfi->tags; while(tag) { if(!strncasecmp(tag->key,"_lib",4) && tag->key[4]) libncount++; tag=tag->next; } if(libncount) { cache=malloc(sizeof(LIBNCACHE)*libncount); tag=psfi->tags; while(tag) { if(!strncasecmp(tag->key,"_lib",4) && tag->key[4]) { cache[cur].num=atoi(&tag->key[4]); cache[cur].value=tag->value; cur++; } tag=tag->next; } qsort(cache, libncount, sizeof(LIBNCACHE), ccomp); for(cur=0;cur<libncount;cur++) { u32 ba[3]; char *tmpfn; if(cache[cur].num < 2) continue; ba[0]=psxRegs.pc; ba[1]=psxRegs.GPR.n.gp; ba[2]=psxRegs.GPR.n.sp; /* Load file name "value" from the directory specified in the full path(directory + file name) "path" */ tmpfn=findFileIgnoreCase(path,cache[cur].value); if(!(tmpi=LoadPSF(tmpfn,level+1,0))) { //free(key); //free(value); //free(tmpfn); //fclose(fp); //return(0); } free(tmpfn); FreeTags(tmpi->tags); free(tmpi); psxRegs.pc=ba[0]; psxRegs.GPR.n.gp=ba[1]; psxRegs.GPR.n.sp=ba[2]; } free(cache); } // if(libncount) } // if(!type) return(psfi); }
static PSFINFO *LoadPSF(char *path, int level, int type,const char *pathDir) // Type==1 for just info load. { FILE *fp; u8 *in,*out=0; u8 head[4]; u32 reserved; u32 complen; u32 crc32; uLongf outlen; PSFINFO *psfi=NULL; PSFINFO *tmpi=NULL; u32 offset, plength; sexypsf_missing_psflib=0; #ifdef DEBUG fprintf(stderr, "Searching (%s)\n", path); #endif fp=fopen(path,"rb"); if(!fp) return 0; fread(head,1,4,fp); if(memcmp(head,"PSF\x01",4)) return(0); psfi=malloc(sizeof(PSFINFO)); if( psfi == NULL ) return(0); memset(psfi,0,sizeof(PSFINFO)); psfi->stop=~0; psfi->fade=0; fread(&reserved,1,4,fp); fread(&complen,1,4,fp); complen=BFLIP32(complen); fread(&crc32,1,4,fp); crc32=BFLIP32(crc32); #ifdef DEBUG fprintf(stderr, "CRC32 = 0x%x\n", crc32); #endif fseek(fp,reserved,SEEK_CUR); if(type) fseek(fp,complen,SEEK_CUR); else { in=malloc(complen); if( !in ) return(0); out=malloc(1024*1024*2+0x800); if( !out ) { free(in); return(0); } fread(in,1,complen,fp); outlen=1024*1024*2; uncompress(out,&outlen,in,complen); free(in); psxRegs->pc = out[0x10] | out[0x11]<<8 | out[0x12]<<16 | out[0x13]<<24; psxRegs->GPR.n.gp = out[0x14] | out[0x15]<<8 | out[0x16]<<16 | out[0x17]<<24; psxRegs->GPR.n.sp = out[0x30] | out[0x31]<<8 | out[0x32]<<16 | out[0x33]<<24; if (psxRegs->GPR.n.sp == 0) psxRegs->GPR.n.sp = 0x801fff00; #ifdef DEBUG fprintf(stderr, "%d Level: PC %x GP %x SP %x\n", level, psxRegs->pc, psxRegs->GPR.n.gp, psxRegs->GPR.n.sp); #endif if(level) { offset = out[0x18] | out[0x19]<<8 | out[0x1a]<<16 | out[0x1b]<<24; offset &= 0x3fffffff; // kill any MIPS cache segment indicators plength = out[0x1c] | out[0x1d]<<8 | out[0x1e]<<16 | out[0x1f]<<24; #ifdef DEBUG fprintf(stderr, "%d Level: offset %x plength: %d [%d]\n", level, offset, plength, plength); #endif LoadPSXMem(offset,plength,(char*)out+0x800); free(out); // I don't really know how does this // work, but apparently it breaks the // loop that makes ff6 and ct to take // several seconds to start ... if( crc32 == 0xEFDE8EEE || crc32 == 0x545D9F65 ) psxMemWrite32(0x5A66C, 0); // Same as above for Popolocrois if( crc32 == 0xF535726 ) psxMemWrite32(0x5A990, 0); } } { u8 tagdata[5]; if(fread(tagdata,1,5,fp)==5) { if(!memcmp(tagdata,"[TAG]",5)) { char linebuf[1024]; while(fgets(linebuf,1024,fp)>0) { int x; char *key=0,*value=0; if(!GetKeyVal(linebuf,&key,&value)) { if(key) free(key); if(value) free(value); continue; } AddKV(&psfi->tags,key,value); if(!level) { static char *yoinks[8]={"title","artist","game","year","genre", "copyright","psfby","comment"}; char **yoinks2[8]={&psfi->title,&psfi->artist,&psfi->game,&psfi->year,&psfi->genre, &psfi->copyright,&psfi->psfby,&psfi->comment}; for(x=0;x<8;x++) if(!strcasecmp(key,yoinks[x])) *yoinks2[x]=value; if(!strcasecmp(key,"length")) psfi->stop=TimeToMS(value); else if(!strcasecmp(key,"fade")) psfi->fade=TimeToMS(value); } if(!strcasecmp(key,"_lib") && !type) { char *tmpfn; /* Load file name "value" from the directory specified in the full path(directory + file name) "path" */ //printf("yo %s\nya %s\nyu%s\n",path,value,pathDir); tmpfn=GetFileWithBase(path,value,pathDir); //printf("ru: %s\n",tmpfn); if(!(tmpi=LoadPSF(tmpfn,level+1,0,pathDir))) { //free(key); //free(value); sexypsf_missing_psflib=1; strcpy(sexypsf_psflib_str,value); free(tmpfn); if(!level) free(out); fclose(fp); FreeTags(psfi->tags); free(psfi); return(0); } FreeTags(tmpi->tags); free(tmpi); free(tmpfn); } } } } } fclose(fp); /* Now, if we're at level 0(main PSF), load the main executable, and any libN stuff */ if(!level && !type) { offset = out[0x18] | out[0x19]<<8 | out[0x1a]<<16 | out[0x1b]<<24; offset &= 0x3fffffff; // kill any MIPS cache segment indicators plength = out[0x1c] | out[0x1d]<<8 | out[0x1e]<<16 | out[0x1f]<<24; // TODO - investigate: should i just make // plength = outlen-0x800? // Philosoma has an illegal "plength". *sigh* if (plength > (outlen-0x800)) { plength = outlen-0x800; } if( psfi->game ) { // Suikoden Tenmei has an illegal "plength". *sigh sigh* if( !strncmp(psfi->game, "Suikoden: Tenmei no Chikai", 26) ) { plength = outlen-0x800; } // Einhänder has an illegal "plength". *sigh sigh sigh* if( !strncmp(psfi->game, "Einhänder", 9) ) { plength = outlen-0x800; } } #ifdef DEBUG fprintf(stderr, "%d Level: offset %x plength: %d [%d]\n", level, offset, plength, outlen-2048); #endif LoadPSXMem(offset,plength,(char*)out+0x800); free(out); } if(!type) /* Load libN */{ LIBNCACHE *cache; PSFTAG *tag; unsigned int libncount=0; unsigned int cur=0; tag=psfi->tags; while(tag) { if(!strncasecmp(tag->key,"_lib",4) && tag->key[4]) libncount++; tag=tag->next; } if(libncount) { cache=malloc(sizeof(LIBNCACHE)*libncount); tag=psfi->tags; while(tag) { if(!strncasecmp(tag->key,"_lib",4) && tag->key[4]) { cache[cur].num=atoi(&tag->key[4]); cache[cur].value=tag->value; cur++; } tag=tag->next; } qsort(cache, libncount, sizeof(LIBNCACHE), ccomp); for(cur=0;cur<libncount;cur++) { u32 ba[3]; char *tmpfn; if(cache[cur].num < 2) continue; ba[0]=psxRegs->pc; ba[1]=psxRegs->GPR.n.gp; ba[2]=psxRegs->GPR.n.sp; /* Load file name "value" from the directory specified in the full path(directory + file name) "path" */ tmpfn=GetFileWithBase(path,cache[cur].value,pathDir); if(!(tmpi=LoadPSF(tmpfn,level+1,0,pathDir))) { //free(key); //free(value); //free(tmpfn); //fclose(fp); //return(0); } else { FreeTags(tmpi->tags); free(tmpi); } free(tmpfn); psxRegs->pc=ba[0]; psxRegs->GPR.n.gp=ba[1]; psxRegs->GPR.n.sp=ba[2]; } free(cache); } // if(libncount) } // if(!type) return(psfi); }