/** * Closes a game. Frees memory, and deinitializes the drivers. */ int CloseGame() { std::string filename; if(!isloaded) { return(0); } int state_to_save; g_config->getOption("SDL.AutoSaveState", &state_to_save); if (state_to_save < 10 && state_to_save >= 0){ FCEUI_SelectState(state_to_save, 0); FCEUI_SaveState(NULL, false); } FCEUI_CloseGame(); DriverKill(); isloaded = 0; GameInfo = 0; g_config->getOption("SDL.Sound.RecordFile", &filename); if(filename.size()) { FCEUI_EndWaveRecord(); } InputUserActiveFix(); return(1); }
int main(int argc, char *argv[]) { int size; int curarg; uint8 *buf; Interface = SexyAL_Init(0); DriverTypes = Interface->EnumerateTypes(Interface); puts("\n*** Festalon v"FESTALON_VERSION); if(argc<=1) { printf("\tUsage: %s [options] file1.nsf file2.nsf ... fileN.nsf\n\n",argv[0]); puts("\tExample Options:"); puts("\t -rate 44100\t\tSet playback rate to 44100Hz(default: 48000Hz)."); puts("\t -quality 1\t\tSet quality to 1, the highest(the lowestis 0; default: 0)."); puts("\t -volume 200\t\tSet volume to 200%(default: 100%)."); puts("\t -buffering 100\t\tSet desired buffering level to 100 milliseconds(default: 100)."); puts("\t -lowpass 1\t\tTurn on lowpass filter(default: 0)."); puts("\t -lowpasscorner 8000\tSet lowpass corner frequency(at which the response is about -3dB) to 8000Hz(default: 10000Hz)."); puts("\t -lowpassorder 2\tSet lowpass filter order to 2(default: 2)."); puts("\t -record filename.wav\tRecords audio in MS PCM format. An existing file won't be overwritten."); puts("\t\t\t\tWhen playing multiple files, only the first opened file will have its music recorded."); puts("\t -ao x\t\t\tSelect output type/driver. Valid choices are:"); { int x = 0; while(DriverTypes[x].name) { printf("\t\t\t\t %s - %s",DriverTypes[x].short_name,DriverTypes[x].name); if(!x) printf("\t(*Default*)"); puts(""); x++; } } puts("\t -aodevice id\t\tSelect output device by id. The default is \"NULL\", which opens the default/preferred device."); puts("\t\t\t\t Try \"-aodevice help\" to see the list of devices."); Interface->Destroy(Interface); return(-1); } curarg = ParseArguments(argc, argv, TODArgs); if(-1 == (CurDriverIndex = FindCurDriver(DriverTypes, Config.ao))) return(-1); if(Config.aodevice) { if(!strcmp(Config.aodevice,"help")) { SexyAL_enumdevice *devices = Interface->EnumerateDevices(Interface, DriverTypes[CurDriverIndex].type); if(!devices) { printf("\tNo predefined output devices are available with this driver type.\n"); return(-1); } printf("\tOutput devices(ID, name) for \"%s\":\n",DriverTypes[CurDriverIndex].name); while(devices->next) { printf("\t %s, %s\n",devices->id,devices->name); devices = devices->next; } return(-1); } } if(Config.quality != 0 && Config.quality != 1) Config.quality = 0; tcgetattr(0,&oldtio); newtio=oldtio; newtio.c_lflag&=~(ICANON|ECHO); signal(SIGTERM,siggo); signal(SIGINT,siggo); tcsetattr(0,TCSANOW,&newtio); sa = fcntl(fileno(stdin), F_GETFL); fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); for(;curarg < argc && !eexit; curarg++) //while(argc-->1 && !eexit) { FILE *fp; printf("\nLoading %s... ",argv[curarg]); if(!(fp=fopen(argv[curarg],"rb"))) {printf("Error opening file: %s\n",strerror(errno));continue;} fseek(fp,0,SEEK_END); size=ftell(fp); fseek(fp,0,SEEK_SET); buf=malloc(size); fread(buf,1,size,fp); fclose(fp); if(!(Player=FESTAI_Load(buf,size) )) { puts("Error loading file!"); free(buf); continue; } free(buf); puts(""); memset(&format, 0, sizeof(format)); memset(&buffering, 0, sizeof(buffering)); format.sampformat = SEXYAL_FMT_PCMFLOAT; format.channels = Player->OutChannels; format.rate = Config.rate; buffering.fragsizems = 10; // Granularity. buffering.ms = Config.buffering; printf(" Using \"%s\" audio driver:",DriverTypes[CurDriverIndex].name); if(!(Output=Interface->Open(Interface,Config.aodevice,&format,&buffering, DriverTypes[CurDriverIndex].type))) { puts("Error opening sound device."); continue; //return(-1); } putchar('\n'); printf(" Playback Rate:\t%dHz\n",format.rate); printf(" Output Channels:\t%d\n",format.channels); printf(" Output Format:\t"); if(format.sampformat == SEXYAL_FMT_PCMFLOAT) puts("\t32-bit Floating Point"); else { if(format.sampformat&0x1) printf("Signed, "); else printf("Unsigned, "); printf("%d bits\n",(format.sampformat >> 4) << 3); } printf(" Estimated Latency:\t%d ms\n",buffering.latency * 1000 / format.rate); FESTAI_SetSound(Player, format.rate, Config.quality); if(WRFilename) { if(!FCEUI_BeginWaveRecord(format.rate,Player->OutChannels,WRFilename)) { free(WRFilename); WRFilename = 0; } } //printf("%d:%d\n",buffering.fragsize, buffering.fragcount); format.sampformat=SEXYAL_FMT_PCMFLOAT; format.channels=Player->OutChannels; format.byteorder=0; Output->SetConvert(Output,&format); Config.volume = FESTAI_SetVolume(Player, Config.volume); FESTAI_Disable(Player, disabled); poosh(); puts(""); ShowInfo(); if(!FESTAI_SetLowpass(Player, Config.lowpass, Config.lowpasscorner, Config.lowpassorder)) { puts(" Error activating lowpass filter!"); } else if(Config.lowpass) printf(" Lowpass filter on. Corner frequency: %dHz, Order: %d\n",Config.lowpasscorner,Config.lowpassorder); current=FESTAI_SongControl(Player,0,0); lastms = ~0; frames_written = 0; puts("\n\n"); ShowStatus(1,1); //#define TICKEROO #ifdef TICKEROO static uint64 last_tick,total_ticks,total; total = 0; total_ticks = 0; #endif while(!eexit) { static char t[3]={0,0,0}; int len; float *buf; ShowStatus(0,0); if(paused) { usleep(10); } else { #ifdef TICKEROO last_tick=getticks(); #endif buf=FESTAI_Emulate(Player, &len); #ifdef TICKEROO total_ticks += getticks() - last_tick; total += len; #endif if(WRFilename) FCEU_WriteWaveData(buf, len); frames_written += len; Output->Write(Output,buf,len); #ifdef TICKEROO if(total >= 100000/2) { printf("%8f\n", (double)total*1000000/total_ticks); rmode(); exit(1); } #endif } while(read(fileno(stdin),&t[0],1)>=0) { static char kcc[20] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')'}; int x; for(x=0; x<20; x++) if(kcc[x] == t[0]) { disabled^=1<<x; FESTAI_Disable(Player,disabled); poosh(); ShowStatus(0,1); break; } if(t[2]==27 && t[1]==91) switch(t[0]) { case 65:current=FESTAI_SongControl(Player,10,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; case 66:current=FESTAI_SongControl(Player,-10,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; case 67:current=FESTAI_SongControl(Player,1,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; case 68:current=FESTAI_SongControl(Player,-1,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; } else switch(tolower(t[0])) { case 10: lastms = ~0;frames_written=0;poosh();current=FESTAI_SongControl(Player, 0,0);ShowStatus(1,1);break; case '`': poosh();break; case 'a': Config.volume-=25; Config.volume = FESTAI_SetVolume(Player, Config.volume);poosh();ShowStatus(0,1);break; case 's': Config.volume+=25; Config.volume = FESTAI_SetVolume(Player, Config.volume);poosh();ShowStatus(0,1);break; case '_': case '-': Config.volume--; FESTAI_SetVolume(Player,Config.volume);poosh();ShowStatus(0,1);break; case '+': case '=': Config.volume++; FESTAI_SetVolume(Player,Config.volume);poosh();ShowStatus(0,1);break; case 'p': TogglePause();break; case 'q': goto exito; /* Alternate song selection keys. Especially needed for DOS port. */ case '\'':current=FESTAI_SongControl(Player,10,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; case ';':current=FESTAI_SongControl(Player,-10,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; case '.':current=FESTAI_SongControl(Player,1,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; case ',':current=FESTAI_SongControl(Player,-1,0);poosh(); lastms = ~0;frames_written=0;ShowStatus(1,1);break; } t[2]=t[1]; t[1]=t[0]; } } exito: if(WRFilename) { FCEUI_EndWaveRecord(); free(WRFilename); WRFilename = 0; } poosh(); FESTAI_Close(Player); if(Output) Output->Close(Output); Output = 0; } rmode(); free(DriverTypes); if(Interface) Interface->Destroy(Interface); return(0); }