void LoadState(void) { FILE *st=NULL; char *fname; if(geniestage==1) { FCEU_DispMessage("Cannot load FCS in GG screen."); return; } fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); st=fopen(fname,"rb"); free(fname); if (st) { FCEUSS_LoadFP(st, 0); fclose(st); } else { FCEU_DispMessage("State %d load error (no file).",CurrentState); SaveStateStatus[CurrentState]=0; } }
void FCEUSS_Save(char *fname) { FILE *st=NULL; char *fn; if(geniestage==1) { FCEU_DispMessage("Cannot save FCS in GG screen."); return; } if(fname) st=FCEUD_UTF8fopen(fname, "wb"); else { st=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0),"wb"); free(fn); } if(st == NULL) { FCEU_DispMessage("State %d save error.",CurrentState); return; } FCEUSS_SaveFP(st); SaveStateStatus[CurrentState]=1; fclose(st); FCEU_DispMessage("State %d saved.",CurrentState); }
void FCEUSS_Save(char *fname) { MEM_TYPE *st = NULL; char *fn; if (geniestage == 1) { FCEU_DispMessage("Cannot save FCS in GG screen."); return; } #ifdef HAVE_MEMSTREAM st = memstream_open(1); #else if (fname) st = FCEUD_UTF8fopen(fname, "wb"); else { st = FCEUD_UTF8fopen(fn = FCEU_MakeFName(FCEUMKF_STATE, CurrentState, 0), "wb"); free(fn); } if (st == NULL) { FCEU_DispMessage("State %d save error.", CurrentState); return; } #endif FCEUSS_SaveFP(st); SaveStateStatus[CurrentState] = 1; fclose(st); #ifndef HAVE_MEMSTREAM FCEU_DispMessage("State %d saved.", CurrentState); #endif }
static void ReallySnap(void) { int x=SaveSnapshot(); if(!x) FCEU_DispMessage("Error saving screen snapshot.",0); else FCEU_DispMessage("Screen snapshot %d saved.",0,x-1); }
void SaveState(void) { FILE *st=NULL; char *fname; TempAddrT=TempAddr; RefreshAddrT=RefreshAddr; if(geniestage==1) { FCEU_DispMessage("Cannot save FCS in GG screen."); return; } fname = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,0); st=fopen(fname,"wb"); free(fname); if(st!=NULL) { static uint32 totalsize; static uint8 header[16]="FCS"; memset(header+4,0,13); header[3]=VERSION_NUMERIC; fwrite(header,1,16,st); #ifdef ASM_6502 asmcpu_pack(); #endif totalsize=WriteStateChunk(st,1,SFCPU); totalsize+=WriteStateChunk(st,2,SFCPUC); totalsize+=WriteStateChunk(st,3,FCEUPPU_STATEINFO); totalsize+=WriteStateChunk(st,4,FCEUCTRL_STATEINFO); totalsize+=WriteStateChunk(st,5,SFSND); if(SPreSave) SPreSave(); totalsize+=WriteStateChunk(st,0x10,SFMDATA); if(SPostSave) SPostSave(); fseek(st,4,SEEK_SET); write32(totalsize,st); SaveStateStatus[CurrentState]=1; fclose(st); #ifdef GP2X sync(); #endif FCEU_DispMessage("State %d saved.",CurrentState); } else FCEU_DispMessage("State %d save error.",CurrentState); }
/** * Toggles the sound on or off. */ void FCEUD_SoundToggle(void) { if (s_mute) { int soundvolume; g_config->getOption("SDL.SoundVolume", &soundvolume); s_mute = 0; FCEUI_SetSoundVolume(soundvolume); FCEU_DispMessage("Sound mute off.", 0); } else { s_mute = 1; FCEUI_SetSoundVolume(0); FCEU_DispMessage("Sound mute on.", 0); } }
void FCEUD_SoundToggle(void) { if(mute) { mute=0; FCEUI_SetSoundVolume(soundvolume); FCEU_DispMessage("Sound mute off."); } else { mute=1; FCEUI_SetSoundVolume(0); FCEU_DispMessage("Sound mute on."); } }
/** * Set the emulation speed throttling to a specific value. */ void FCEUD_SetEmulationSpeed(int cmd) { MaxSpeed = false; switch(cmd) { case EMUSPEED_SLOWEST: g_fpsScale = Slowest; break; case EMUSPEED_SLOWER: DecreaseEmulationSpeed(); break; case EMUSPEED_NORMAL: g_fpsScale = Normal; break; case EMUSPEED_FASTER: IncreaseEmulationSpeed(); break; case EMUSPEED_FASTEST: g_fpsScale = Fastest; MaxSpeed = true; break; default: return; } RefreshThrottleFPS(); FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0); }
/** * Adjust the volume either down (-1), up (1), or to the default (0). * Unmutes if mute was active before. */ void FCEUD_SoundVolumeAdjust(int n) { int soundvolume; g_config->getOption("SDL.SoundVolume", &soundvolume); switch (n) { case -1: soundvolume -= 10; if (soundvolume < 0) { soundvolume = 0; } break; case 0: soundvolume = 100; break; case 1: soundvolume += 10; if (soundvolume > 150) { soundvolume = 150; } break; } s_mute = 0; FCEUI_SetSoundVolume(soundvolume); g_config->setOption("SDL.SoundVolume", soundvolume); FCEU_DispMessage("Sound volume %d.", soundvolume); }
int FCEUSS_LoadFP(FILE *st, int make_backup) { int x; if(st!=NULL) { uint8 header[16]; fread(&header,1,16,st); if(memcmp(header,"FCS",3)) { fseek(st,0,SEEK_SET); if(!LoadStateOld(st)) goto lerror; goto okload; } stateversion=header[3]; if(stateversion<53) FixOldSaveStateSFreq(); x=ReadStateChunks(st); if(GameStateRestore) GameStateRestore(header[3]); if(x) { okload: TempAddr=TempAddrT; RefreshAddr=RefreshAddrT; SaveStateStatus[CurrentState]=1; FCEU_DispMessage("State %d loaded.",CurrentState); SaveStateStatus[CurrentState]=1; } else { SaveStateStatus[CurrentState]=1; FCEU_DispMessage("Error(s) reading state %d!",CurrentState); } } else { lerror: FCEU_DispMessage("State %d load error.",CurrentState); SaveStateStatus[CurrentState]=0; return 0; } return 1; }
void FCEUI_SelectState(int w) { if(w == -1) { StateShow = 0; return; } FCEUI_SelectMovie(-1); CurrentState=w; StateShow=180; FCEU_DispMessage("-select state-"); }
static void StopPlayback(void) { if(suppressMovieStop) return; resetDMCacc=movieSyncHackOn=0; fclose(slots[-1 - current]); current=0; FCEU_DispMessage("Movie playback stopped."); }
/** * Set the emulation speed throttling to the next entry in the speed table. */ void IncreaseEmulationSpeed(void) { g_fpsScale *= LOGMUL; if(g_fpsScale > Fastest) g_fpsScale = Fastest; RefreshThrottleFPS(); FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0); }
/** * Set the emulation speed throttling to the previous entry in the speed table. */ void DecreaseEmulationSpeed(void) { g_fpsScale /= LOGMUL; if(g_fpsScale < Slowest) g_fpsScale = Slowest; RefreshThrottleFPS(); FCEU_DispMessage("emulation speed %.1f%%",0, g_fpsScale*100.0); }
int FCEUSS_Load(char *fname) { MEM_TYPE *st; char *fn; #ifdef HAVE_MEMSTREAM st = memstream_open(0); #else if (geniestage == 1) { FCEU_DispMessage("Cannot load FCS in GG screen."); return(0); } if (fname) st = FCEUD_UTF8fopen(fname, "rb"); else { st = FCEUD_UTF8fopen(fn = FCEU_MakeFName(FCEUMKF_STATE, CurrentState, fname), "rb"); free(fn); } if (st == NULL) { FCEU_DispMessage("State %d load error.", CurrentState); SaveStateStatus[CurrentState] = 0; return(0); } #endif if (FCEUSS_LoadFP(st)) { #ifndef HAVE_MEMSTREAM SaveStateStatus[CurrentState] = 1; FCEU_DispMessage("State %d loaded.", CurrentState); #endif SaveStateStatus[CurrentState] = 1; fclose(st); return(1); } else { SaveStateStatus[CurrentState] = 1; #ifndef HAVE_MEMSTREAM FCEU_DispMessage("Error(s) reading state %d!", CurrentState); #endif fclose(st); return(0); } }
int FCEUSS_Load(char *fname) { FILE *st; char *fn; if(geniestage==1) { FCEU_DispMessage("Cannot load FCS in GG screen."); return(0); } if(fname) st=FCEUD_UTF8fopen(fname, "rb"); else { st=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_STATE,CurrentState,fname),"rb"); free(fn); } if(st == NULL) { FCEU_DispMessage("State %d load error.",CurrentState); SaveStateStatus[CurrentState]=0; return(0); } if(FCEUSS_LoadFP(st)) { SaveStateStatus[CurrentState]=1; FCEU_DispMessage("State %d loaded.",CurrentState); SaveStateStatus[CurrentState]=1; fclose(st); return(1); } else { SaveStateStatus[CurrentState]=1; FCEU_DispMessage("Error(s) reading state %d!",CurrentState); fclose(st); return(0); } }
void FCEUD_SoundVolumeAdjust(int adjust) { switch(adjust) { case -1: soundvolume-=50; if(soundvolume<0) soundvolume=0; break; //lower volume case 0: soundvolume=1024; break; case 1: soundvolume+=50; if(soundvolume>1024) soundvolume=1024; break; //raise volume } FCEUI_SetSoundVolume(soundvolume); FCEU_DispMessage("Sound volume %d.", soundvolume); }
void FCEUI_AviEnd() { if(!avi_file) return; // Don't display if we're just starting another segment if(avi_file->tBytes <= 2097152000) FCEU_DispMessage("AVI recording ended.",0); avi_destroy(&avi_file); }
void FCEU_FDSInsert(void) { if(TotalSides==0) { FCEU_DispMessage("Not FDS; can't eject disk.",0); return; } if(InDisk==255) { FCEU_DispMessage("Disk %d Side %s Inserted",0,SelectDisk>>1,(SelectDisk&1)?"B":"A"); InDisk=SelectDisk; }
void FCEU_FDSInsert(void) { if (FCEUI_EmulationPaused()) EmulationPaused |= 2; if (FCEUMOV_Mode(MOVIEMODE_RECORD)) FCEUMOV_AddCommand(FCEUNPCMD_FDSINSERT); if (TotalSides == 0) { FCEU_DispMessage("Not FDS; can't eject disk.", 0); return; } if (InDisk == 255) { FCEU_DispMessage("Disk %d Side %s Inserted", 0, SelectDisk >> 1, (SelectDisk & 1) ? "B" : "A"); InDisk = SelectDisk; } else {
static void StopRecording(void) { if(suppressMovieStop) return; resetDMCacc=movieSyncHackOn=0; DoEncode(0,0,1); /* Write a dummy timestamp value so that the movie will keep "playing" after user input has stopped. */ // finish header FlushHeader(); // FIXME: truncate movie to length // ftruncate(); fclose(slots[current - 1]); MovieStatus[current - 1] = 1; current=0; FCEU_DispMessage("Movie recording stopped."); }
void SaveState(const char *fname) { MEMFILE *st=NULL; TempAddrT=TempAddr; RefreshAddrT=RefreshAddr; if(geniestage==1) { FCEU_DispMessage("Cannot save FCS in GG screen."); return; } st=mem_fopen_write(fname); if(st!=NULL) { static uint32 totalsize; static uint8 header[16]="FCS"; memset(header+4,0,13); header[3]=VERSION_NUMERIC; mem_fwrite(header,1,16,st); #ifdef ASM_6502 asmcpu_pack(); #endif totalsize=WriteStateChunk(st,1,SFCPU); totalsize+=WriteStateChunk(st,2,SFCPUC); totalsize+=WriteStateChunk(st,3,FCEUPPU_STATEINFO); totalsize+=WriteStateChunk(st,4,FCEUCTRL_STATEINFO); totalsize+=WriteStateChunk(st,5,SFSND); if(SPreSave) SPreSave(); totalsize+=WriteStateChunk(st,0x10,SFMDATA); if(SPostSave) SPostSave(); mem_fseek(st,4,SEEK_SET); mem_write32(totalsize,st); SaveStateStatus[CurrentState]=1; mem_fclose(st); } }
void LoadState(const char *fname) { MEMFILE *st=NULL; if(geniestage==1) { // FCEU_DispMessage("Cannot load FCS in GG screen."); return; } st=mem_fopen_read(fname); if (st) { FCEUSS_LoadFP(st, 0); mem_fclose(st); } else { FCEU_DispMessage("State %d load error (no file).",CurrentState); SaveStateStatus[CurrentState]=0; } }
int FCEUD_NetworkConnect(void) { struct sockaddr_in sockin; struct hostent *phostentb; unsigned long hadr; int TSocket, tcpopt, error; int netdivisor; // get any required configuration variables int port, localPlayers; std::string server, username, password, key; server = "192.168.0.12"; username = "******"; password = ""; key = ""; port = 4046; localPlayers = 2; // only initialize if remote server is specified if(!server.size()) { return 0; } XNetStartupParams xnsp; memset(&xnsp, 0, sizeof(xnsp)); xnsp.cfgSizeOfStruct = sizeof(XNetStartupParams); xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY; xnsp.cfgSockDefaultRecvBufsizeInK = 16; // default = 16 xnsp.cfgSockDefaultSendBufsizeInK = 16; // default = 16 INT iResult = XNetStartup( &xnsp ); WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD( 2, 2 ); WSAStartup( wVersionRequested, &wsaData ); TSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(TSocket < 0) { DWORD err = GetLastError(); char* s = "Error creating stream socket."; puts(s); FCEU_DispMessage(s,0); FCEUD_NetworkClose(); return 0; } // try to setup TCP_NODELAY to avoid network jitters tcpopt = 1; error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, (char*)&tcpopt, sizeof(int)); if(error) { puts("Nodelay fail"); } memset(&sockin, 0, sizeof(sockin)); sockin.sin_family = AF_INET; hadr = inet_addr(server.c_str()); if(hadr != INADDR_NONE) { sockin.sin_addr.s_addr = hadr; } else { #if 0 //marche pas puts("*** Looking up host name..."); //phostentb = gethostbyname(server.c_str()); if(!phostentb) { puts("Error getting host network information."); FCEU_DispMessage("Error getting host info",0); closesocket(TSocket); FCEUD_NetworkClose(); return(0); } memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length); #endif } sockin.sin_port = htons(port); puts("*** Connecting to remote host..."); error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin)); if(error < 0) { puts("Error connecting to remote host."); FCEU_DispMessage("Error connecting to server",0); closesocket(TSocket); FCEUD_NetworkClose(); return 0; } s_Socket = TSocket; puts("*** Sending initialization data to server..."); uint8 *sendbuf; uint8 buf[5]; uint32 sblen; sblen = 4 + 16 + 16 + 64 + 1 + username.size(); sendbuf = (uint8 *)malloc(sblen); memset(sendbuf, 0, sblen); // XXX soules - should use htons instead of en32() from above! //uint32 data = htons(sblen - 4); //memcpy(sendbuf, &data, sizeof(data)); en32(sendbuf, sblen - 4); if(key.size()) { struct md5_context md5; uint8 md5out[16]; md5_starts(&md5); md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16); md5_update(&md5, (uint8 *)key.c_str(), key.size()); md5_finish(&md5, md5out); memcpy(sendbuf + 4, md5out, 16); } else { memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16); } if(password.size()) { struct md5_context md5; uint8 md5out[16]; md5_starts(&md5); md5_update(&md5, (uint8 *)password.c_str(), password.size()); md5_finish(&md5, md5out); memcpy(sendbuf + 4 + 16, md5out, 16); } memset(sendbuf + 4 + 16 + 16, 0, 64); sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers; if(username.size()) { memcpy(sendbuf + 4 + 16 + 16 + 64 + 1, username.c_str(), username.size()); } send(s_Socket, (char*)sendbuf, sblen, 0); free(sendbuf); recv(s_Socket, (char*)buf, 1, 0); netdivisor = buf[0]; puts("*** Connection established."); FCEU_DispMessage("Connection established.",0); FCEUDnetplay = 1; FCEUI_NetplayStart(localPlayers, netdivisor); return 1; }
void NetplayUpdate(uint8 *joyp) { static uint8 buf[5]; /* 4 play states, + command/extra byte */ static uint8 joypb[4]; memcpy(joypb,joyp,4); /* This shouldn't happen, but just in case. 0xFF is used as a command escape elsewhere. */ if(joypb[0] == 0xFF) joypb[0] = 0xF; #ifdef NETWORK if(!netdcount) if(!FCEUD_SendData(joypb,numlocal)) { NetError(); return; } if(!netdcount) do { if(!FCEUD_RecvData(buf,5)) { NetError(); return; } switch(buf[4]) { default: FCEU_DoSimpleCommand(buf[4]);break; case FCEUNPCMD_TEXT: { uint8 *tbuf; uint32 len = FCEU_de32lsb(buf); if(len > 100000) // Insanity check! { NetError(); return; } tbuf = malloc(len + 1); tbuf[len] = 0; if(!FCEUD_RecvData(tbuf, len)) { NetError(); free(tbuf); return; } FCEUD_NetplayText(tbuf); free(tbuf); } break; case FCEUNPCMD_SAVESTATE: { char *fn; FILE *fp; /* Send the cheats first, then the save state, since there might be a frame or two in between the two sendfile commands on the server side. */ fn = FCEU_MakeFName(FCEUMKF_CHEAT,0,0); //if(! FCEUNET_SendFile(FCEUNPCMD_LOADCHEATS,fn); // { // free(fn); // return; // } free(fn); if(!FCEUnetplay) return; fn = FCEU_MakeFName(FCEUMKF_NPTEMP,0,0); fp = fopen(fn, "wb"); if(FCEUSS_SaveFP(fp)) { fclose(fp); if(!FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn)) { unlink(fn); free(fn); return; } unlink(fn); free(fn); } else { fclose(fp); FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy? Now!"); unlink(fn); free(fn); return; } } break; case FCEUNPCMD_LOADCHEATS: { FILE *fp = FetchFile(FCEU_de32lsb(buf)); if(!fp) return; FCEU_FlushGameCheats(0,1); FCEU_LoadGameCheats(fp); } break; case FCEUNPCMD_LOADSTATE: { FILE *fp = FetchFile(FCEU_de32lsb(buf)); if(!fp) return; if(FCEUSS_LoadFP(fp)) { fclose(fp); FCEU_DispMessage("Remote state loaded."); } else FCEUD_PrintError("File error. (K)ill, (M)aim, (D)estroy?"); } break; } } while(buf[4]); #endif netdcount=(netdcount+1)%netdivisor; memcpy(netjoy,buf,4); *(uint32 *)joyp=*(uint32 *)netjoy; }
int FCEUD_NetworkConnect(void) { struct sockaddr_in sockin; struct hostent *phostentb; unsigned long hadr; int TSocket, tcpopt, error; int netdivisor; // get any required configuration variables int port, localPlayers; std::string server, username, password, key; g_config->getOption("SDL.NetworkIP", &server); g_config->getOption("SDL.NetworkUsername", &username); g_config->getOption("SDL.NetworkPassword", &password); g_config->getOption("SDL.NetworkGameKey", &key); g_config->getOption("SDL.NetworkPort", &port); g_config->getOption("SDL.NetworkPlayers", &localPlayers); g_config->setOption("SDL.NetworkIP", ""); g_config->setOption("SDL.NetworkPassword", ""); g_config->setOption("SDL.NetworkGameKey", ""); // only initialize if remote server is specified if(!server.size()) { return 0; } TSocket = socket(AF_INET, SOCK_STREAM, 0); if(TSocket < 0) { char* s = "Error creating stream socket."; puts(s); FCEU_DispMessage(s,0); FCEUD_NetworkClose(); return 0; } // try to setup TCP_NODELAY to avoid network jitters tcpopt = 1; #ifdef BEOS error = setsockopt(TSocket, SOL_SOCKET, TCP_NODELAY, &tcpopt, sizeof(int)); #elif WIN32 error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, (char*)&tcpopt, sizeof(int)); #else error = setsockopt(TSocket, SOL_TCP, TCP_NODELAY, &tcpopt, sizeof(int)); #endif if(error) { puts("Nodelay fail"); } memset(&sockin, 0, sizeof(sockin)); sockin.sin_family = AF_INET; hadr = inet_addr(server.c_str()); if(hadr != INADDR_NONE) { sockin.sin_addr.s_addr = hadr; } else { puts("*** Looking up host name..."); phostentb = gethostbyname(server.c_str()); if(!phostentb) { puts("Error getting host network information."); FCEU_DispMessage("Error getting host info",0); close(TSocket); FCEUD_NetworkClose(); return(0); } memcpy(&sockin.sin_addr, phostentb->h_addr, phostentb->h_length); } sockin.sin_port = htons(port); puts("*** Connecting to remote host..."); error = connect(TSocket, (struct sockaddr *)&sockin, sizeof(sockin)); if(error < 0) { puts("Error connecting to remote host."); FCEU_DispMessage("Error connecting to server",0); close(TSocket); FCEUD_NetworkClose(); return 0; } s_Socket = TSocket; puts("*** Sending initialization data to server..."); uint8 *sendbuf; uint8 buf[5]; uint32 sblen; sblen = 4 + 16 + 16 + 64 + 1 + username.size(); sendbuf = (uint8 *)FCEU_dmalloc(sblen); memset(sendbuf, 0, sblen); // XXX soules - should use htons instead of en32() from above! //uint32 data = htons(sblen - 4); //memcpy(sendbuf, &data, sizeof(data)); en32(sendbuf, sblen - 4); if(key.size()) { struct md5_context md5; uint8 md5out[16]; md5_starts(&md5); md5_update(&md5, (uint8*)&GameInfo->MD5.data, 16); md5_update(&md5, (uint8 *)key.c_str(), key.size()); md5_finish(&md5, md5out); memcpy(sendbuf + 4, md5out, 16); } else { memcpy(sendbuf + 4, (uint8*)&GameInfo->MD5.data, 16); } if(password.size()) { struct md5_context md5; uint8 md5out[16]; md5_starts(&md5); md5_update(&md5, (uint8 *)password.c_str(), password.size()); md5_finish(&md5, md5out); memcpy(sendbuf + 4 + 16, md5out, 16); } memset(sendbuf + 4 + 16 + 16, 0, 64); sendbuf[4 + 16 + 16 + 64] = (uint8)localPlayers; if(username.size()) { memcpy(sendbuf + 4 + 16 + 16 + 64 + 1, username.c_str(), username.size()); } #ifdef WIN32 send(s_Socket, (char*)sendbuf, sblen, 0); #else send(s_Socket, sendbuf, sblen, 0); #endif FCEU_dfree(sendbuf); #ifdef WIN32 recv(s_Socket, (char*)buf, 1, 0); #else recv(s_Socket, buf, 1, MSG_WAITALL); #endif netdivisor = buf[0]; puts("*** Connection established."); FCEU_DispMessage("Connection established.",0); FCEUDnetplay = 1; FCEUI_NetplayStart(localPlayers, netdivisor); return 1; }
void FCEU_PutImage(void) { if(dosnapsave==2) //Save screenshot as, currently only flagged & run by the Win32 build. //TODO SDL: implement this? { char nameo[512]; strcpy(nameo,FCEUI_GetSnapshotAsName().c_str()); if (nameo[0]) { SaveSnapshot(nameo); FCEU_DispMessage("Snapshot Saved.",0); } dosnapsave=0; } if(GameInfo->type==GIT_NSF) { DrawNSF(XBuf); //Save snapshot after NSF screen is drawn. Why would we want to do it before? if(dosnapsave==1) { ReallySnap(); dosnapsave=0; } } else { //Save backbuffer before overlay stuff is written. if(!FCEUI_EmulationPaused()) memcpy(XBackBuf, XBuf, 256*256); //Some messages need to be displayed before the avi is dumped DrawMessage(true); #ifdef _S9XLUA_H // Lua gui should draw before the avi is dumped. FCEU_LuaGui(XBuf); #endif //Save snapshot if(dosnapsave==1) { ReallySnap(); dosnapsave=0; } if (!FCEUI_AviEnableHUDrecording()) snapAVI(); if(GameInfo->type==GIT_VSUNI) FCEU_VSUniDraw(XBuf); FCEU_DrawSaveStates(XBuf); FCEU_DrawMovies(XBuf); FCEU_DrawLagCounter(XBuf); FCEU_DrawNTSCControlBars(XBuf); FCEU_DrawRecordingStatus(XBuf); ShowFPS(); } if(FCEUD_ShouldDrawInputAids()) FCEU_DrawInput(XBuf); //Fancy input display code if(input_display) { extern uint32 JSAutoHeld; uint32 held; int controller, c, ci, color; int i, j; uint32 on = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0x90:0xA7; //Standard, or Gray depending on movie mode uint32 oni = 0xA0; //Color for immediate keyboard buttons uint32 blend = 0xB6; //Blend of immiate and last held buttons uint32 ahold = 0x87; //Auto hold uint32 off = 0xCF; uint8 *t = XBuf+(FSettings.LastSLine-9)*256 + 20; //mbg merge 7/17/06 changed t to uint8* if(input_display > 4) input_display = 4; for(controller = 0; controller < input_display; controller++, t += 56) { for(i = 0; i < 34;i++) for(j = 0; j <9 ; j++) t[i+j*256] = (t[i+j*256] & 0x30) | 0xC1; for(i = 3; i < 6; i++) for(j = 3; j< 6; j++) t[i+j*256] = 0xCF; c = cur_input_display >> (controller * 8); // This doesn't work in anything except windows for now. // It doesn't get set anywhere in other ports. #if defined(WIN32) && !defined(DINGUX) if (!oldInputDisplay) ci = FCEUMOV_Mode(MOVIEMODE_PLAY) ? 0:GetGamepadPressedImmediate() >> (controller * 8); else ci = 0; if (!oldInputDisplay && !FCEUMOV_Mode(MOVIEMODE_PLAY)) held = (JSAutoHeld >> (controller * 8)); else held = 0; #else // Put other port info here ci = 0; held = 0; #endif //adelikat: I apologize to anyone who ever sifts through this color assignment //A if (held&1) { //If auto-hold if (!(ci&1) ) color = ahold; else color = (c&1) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&1) color = (ci&1) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&1) ? oni : off; } for(i=0; i < 4; i++) { for(j = 0; j < 4; j++) { if(i%3==0 && j %3 == 0) continue; t[30+4*256+i+j*256] = color; } } //B if (held&2) { //If auto-hold if (!(ci&2) ) color = ahold; else color = (c&2) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&2) color = (ci&2) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&2) ? oni : off; } for(i=0; i < 4; i++) { for(j = 0; j < 4; j++) { if(i%3==0 && j %3 == 0) continue; t[24+4*256+i+j*256] = color; } } //Select if (held&4) { //If auto-hold if (!(ci&4) ) color = ahold; else color = (c&4) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&4) color = (ci&4) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&4) ? oni : off; } for(i = 0; i < 4; i++) { t[11+5*256+i] = color; t[11+6*256+i] = color; } //Start if (held&8) { //If auto-hold if (!(ci&8) ) color = ahold; else color = (c&8) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&8) color = (ci&8) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&8) ? oni : off; } for(i = 0; i < 4; i++) { t[17+5*256+i] = color; t[17+6*256+i] = color; } //Up if (held&16) { //If auto-hold if (!(ci&16) ) color = ahold; else color = (c&16) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&16) color = (ci&16) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&16) ? oni : off; } for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { t[3+i+256*j] = color; } } //Down if (held&32) { //If auto-hold if (!(ci&32) ) color = ahold; else color = (c&32) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&32) color = (ci&32) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&32) ? oni : off; } for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { t[3+i+256*j+6*256] = color; } } //Left if (held&64) { //If auto-hold if (!(ci&64) ) color = ahold; else color = (c&64) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&64) color = (ci&64) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&64) ? oni : off; } for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { t[3*256+i+256*j] = color; } } //Right if (held&128) { //If auto-hold if (!(ci&128) ) color = ahold; else color = (c&128) ? on : off; //If the button is pressed down (immediate) that negates auto hold, however it is only off if the previous frame the button wasn't pressed! } else { if (c&128) color = (ci&128) ? blend : on; //If immedaite buttons are pressed and they match the previous frame, blend the colors else color = (ci&128) ? oni : off; } for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { t[6+3*256+i+256*j] = color; } } }
static void NetError(void) { FCEU_DispMessage("Network error/connection lost!",0); FCEUD_NetworkClose(); }
int FCEUI_AviBegin(const char* fname) { FCEUI_AviEnd(); struct VideoSystemInfo vsi; BITMAPINFOHEADER bi; int is_pal; is_pal=FCEUI_GetCurrentVidSystem(&vsi.start_scanline, &vsi.end_scanline); vsi.fps = FCEUI_GetDesiredFPS();//is_pal ? 50 : 60; vsi.end_scanline++; memset(&bi, 0, sizeof(bi)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biPlanes = 1; bi.biBitCount = 24; bi.biWidth = VIDEO_WIDTH; bi.biHeight = vsi.end_scanline-vsi.start_scanline; bi.biSizeImage = 3 * bi.biWidth * bi.biHeight; //mbg 6/27/08 -- this was originally labeled as hacky.. WAVEFORMATEX wf; wf.cbSize = sizeof(WAVEFORMATEX); wf.nAvgBytesPerSec = soundrate * 2; wf.nBlockAlign = 2; wf.nChannels = 1; wf.nSamplesPerSec = soundrate; wf.wBitsPerSample = 16; wf.wFormatTag = WAVE_FORMAT_PCM; saved_avi_ext[0]='\0'; //mbg 8/10/08 - decide whether there will be sound in this movie //if this is a new movie.. if(!avi_file) { if(FSettings.SndRate) use_sound = true; else use_sound = false; } //mbg 8/10/08 - if there is no sound in this movie, then dont open the audio stream WAVEFORMATEX* pwf = &wf; if(!use_sound) pwf = 0; if(!avi_open(fname, &bi, pwf, &vsi)) { saved_avi_fname[0]='\0'; return 0; } // Don't display at file splits if(!avi_segnum) FCEU_DispMessage("AVI recording started.",0); strncpy(saved_cur_avi_fnameandext,fname,MAX_PATH); strncpy(saved_avi_fname,fname,MAX_PATH); char* dot = strrchr(saved_avi_fname, '.'); if(dot && dot > strrchr(saved_avi_fname, '/') && dot > strrchr(saved_avi_fname, '\\')) { strcpy(saved_avi_ext,dot); dot[0]='\0'; } return 1; }
void UpdateGamepad(bool snes) { if(FCEUMOV_Mode(MOVIEMODE_PLAY)) return; int JS=0; if(FCEUMOV_Mode(MOVIEMODE_RECORD)) AutoFire(); for(int wg=0;wg<4;wg++) { int wgs = wg; if(snes) { JS = 0; wgs = 0; for(int x=0;x<12;x++) if(DTestButton(&GamePadConfig[wg][x])) JS|=(1<<x)<<(wgs<<3); //printf("%d %d\n",wg,JS); //useful debugging } else { for(int x=0;x<8;x++) if(DTestButton(&GamePadConfig[wg][x])) JS|=(1<<x)<<(wgs<<3); } // Check if U+D/L+R is disabled //TODO: how does this affect snes pads? if(!allowUDLR) { for(int x=0;x<32;x+=8) { if((JS & (0xC0<<x) ) == (0xC0<<x) ) JS&=~(0xC0<<x); if((JS & (0x30<<x) ) == (0x30<<x) ) JS&=~(0x30<<x); } } // if(rapidAlternator) if(!snes) { for(int x=0;x<2;x++) if(DTestButton(&GamePadConfig[wg][8+x])) JS|=((1<<x)<<(wgs<<3))*(rapidAlternator^(x*DesynchAutoFire)); } if(snes) { snespad_return[wg] = JS; //printf("%d %d\n",wg,JS); } } if(autoHoldOn) { if(autoHoldRefire) { autoHoldRefire--; if(!autoHoldRefire) JSAutoHeldAffected = 0; } for(int wg=0;wg<4;wg++) for(int x=0;x<8;x++) if(DTestButton(&GamePadConfig[wg][x])) { if(!autoHoldRefire || !(JSAutoHeldAffected&(1<<x)<<(wg<<3))) { JSAutoHeld^=(1<<x)<<(wg<<3); JSAutoHeldAffected|=(1<<x)<<(wg<<3); autoHoldRefire = 192; } } char inputstr [41]; int disppos=38; { uint32 c = JSAutoHeld; sprintf(inputstr, "1%c%c%c%c%c%c%c%c 2%c%c%c%c%c%c%c%c\n3%c%c%c%c%c%c%c%c 4%c%c%c%c%c%c%c%c", (c&0x40)?'<':' ', (c&0x10)?'^':' ', (c&0x80)?'>':' ', (c&0x20)?'v':' ', (c&0x01)?'A':' ', (c&0x02)?'B':' ', (c&0x08)?'S':' ', (c&0x04)?'s':' ', (c&0x4000)?'<':' ', (c&0x1000)?'^':' ', (c&0x8000)?'>':' ', (c&0x2000)?'v':' ', (c&0x0100)?'A':' ', (c&0x0200)?'B':' ', (c&0x0800)?'S':' ', (c&0x0400)?'s':' ', (c&0x400000)?'<':' ', (c&0x100000)?'^':' ', (c&0x800000)?'>':' ', (c&0x200000)?'v':' ', (c&0x010000)?'A':' ', (c&0x020000)?'B':' ', (c&0x080000)?'S':' ', (c&0x040000)?'s':' ', (c&0x40000000)?'<':' ', (c&0x10000000)?'^':' ', (c&0x80000000)?'>':' ', (c&0x20000000)?'v':' ', (c&0x01000000)?'A':' ', (c&0x02000000)?'B':' ', (c&0x08000000)?'S':' ', (c&0x04000000)?'s':' '); if(!(c&0xffffff00)) { inputstr[9] = '\0'; disppos = 30; } else if(!(c&0xffff0000)) { inputstr[19] = '\0'; disppos = 30; } else if(!(c&0xff000000)) { inputstr[30] = '\0'; } } FCEU_DispMessage("Held:\n%s", disppos, inputstr); } else { JSAutoHeldAffected = 0; autoHoldRefire = 0; } if(autoHoldReset) { FCEU_DispMessage("Held: ",30); JSAutoHeld = 0; JSAutoHeldAffected = 0; autoHoldRefire = 0; } // apply auto-hold if(JSAutoHeld) JS ^= JSAutoHeld; if(!snes) JSreturn=JS; }