s32 MenuMessageBox(const char *message1, const char *message2, const char *message3, enum MENU_MESSAGE_BOX_MODE mode) { s32 select=0; s32 subaction=-1; u32 keys=0; sal_InputIgnore(); while(subaction==-1) { keys=sal_InputPollRepeat(); if (keys & SAL_INPUT_UP) { select=SAL_OK; // Up } if (keys & SAL_INPUT_DOWN) { select=SAL_ERROR; // Down } if ((keys&INP_BUTTON_MENU_SELECT) || (keys&INP_BUTTON_MENU_CANCEL)) { subaction=select; } PrintTitle("Message Box"); sal_VideoPrint(8,50,message1,SAL_RGB(31,31,31)); sal_VideoPrint(8,60,message2,SAL_RGB(31,31,31)); sal_VideoPrint(8,70,message3,SAL_RGB(31,31,31)); switch(mode) { case MENU_MESSAGE_BOX_MODE_YESNO: // yes no input if(select==SAL_OK) { PrintBar(120-4); sal_VideoPrint(8,120,"YES",SAL_RGB(31,31,31)); sal_VideoPrint(8,140,"NO",SAL_RGB(31,31,31)); } else { PrintBar(140-4); sal_VideoPrint(8,120,"YES",SAL_RGB(31,31,31)); sal_VideoPrint(8,140,"NO",SAL_RGB(31,31,31)); } break; case MENU_MESSAGE_BOX_MODE_PAUSE: PrintBar(120-4); sal_VideoPrint(8,120,"Press button to continue",SAL_RGB(31,31,31)); break; case MENU_MESSAGE_BOX_MODE_MSG: subaction=SAL_OK; break; } sal_VideoFlip(1); } sal_InputIgnore(); return(subaction); }
bool8_32 S9xDeinitUpdate (int Width, int Height, bool8_32) { if(mInMenu) return TRUE; u32 newTimer; if (mMenuOptions.showFps) { mFps++; newTimer=sal_TimerRead(); if(newTimer-mLastTimer>Memory.ROMFramesPerSecond) { mLastTimer=newTimer; sprintf(mFpsDisplay,"FPS: %d / %d", mFps, Memory.ROMFramesPerSecond); mFps=0; } sal_VideoDrawRect(0,0,13*8,8,SAL_RGB(0,0,0)); sal_VideoPrint(0,0,mFpsDisplay,SAL_RGB(31,31,31)); } if(mVolumeDisplayTimer>0) { sal_VideoDrawRect(100,0,8*8,8,SAL_RGB(0,0,0)); sal_VideoPrint(100,0,mVolumeDisplay,SAL_RGB(31,31,31)); } if(mQuickStateTimer>0) { sal_VideoDrawRect(200,0,8*8,8,SAL_RGB(0,0,0)); sal_VideoPrint(200,0,mQuickStateDisplay,SAL_RGB(31,31,31)); } sal_VideoFlip(0); }
s32 UpdateRomCache() { s8 filename[SAL_MAX_PATH]; PrintTitle("CRC Lookup"); sal_VideoPrint(8,120,"Saving cache to disk...",SAL_RGB(31,31,31)); sal_VideoFlip(1); strcpy(filename,mRomDir); sal_DirectoryCombine(filename,"romcache.dat"); sal_FileSave(filename, (u8*)&mRomList[0], sizeof(struct SAL_DIRECTORY_ENTRY)*(mRomCount)); return SAL_OK; }
s32 SaveMenuOptions(const char *path, const char *filename, const char *ext, const char *optionsmem, s32 maxSize, s32 showMessage) { s8 fullFilename[SAL_MAX_PATH]; s8 _filename[SAL_MAX_PATH]; s8 _ext[SAL_MAX_PATH]; s8 _path[SAL_MAX_PATH]; if (showMessage) { PrintTitle(""); sal_VideoPrint(8,120,"Saving...",SAL_RGB(31,31,31)); sal_VideoFlip(1); } sal_DirectorySplitFilename(filename, _path, _filename, _ext); sprintf(fullFilename,"%s%s%s.%s",path,SAL_DIR_SEP,_filename,ext); return sal_FileSave(fullFilename,(u8*)optionsmem,maxSize); }
s32 DeleteMenuOptions(const char *path, const char *filename, const char *ext, s32 showMessage) { s8 fullFilename[SAL_MAX_PATH]; s8 _filename[SAL_MAX_PATH]; s8 _ext[SAL_MAX_PATH]; s8 _path[SAL_MAX_PATH]; if (showMessage) { PrintTitle(""); sal_VideoPrint(8,120,"Deleting...",SAL_RGB(31,31,31)); sal_VideoFlip(1); } sal_DirectorySplitFilename(filename, _path, _filename, _ext); sprintf(fullFilename,"%s%s%s.%s",path,SAL_DIR_SEP,_filename,ext); sal_FileDelete(fullFilename); return SAL_OK; }
static s32 SaveStateSelect(s32 mode) { s8 text[128]; s32 action=11; s32 saveno=0; u32 keys=0; u16 *pixTo,*pixFrom; if(mRomName[0]==0) { // no rom loaded // display error message and exit return(0); } // Allow the emulator to back out of loading a saved state for previewing. SaveStateTemp(); ScanSaveStates(mRomName); sal_InputIgnore(); while (action!=0&&action!=100) { keys=sal_InputPollRepeat(); if(keys&SAL_INPUT_UP) {saveno--; action=1;} if(keys&SAL_INPUT_DOWN) {saveno++; action=1;} if(saveno<-1) saveno=9; if(saveno>9) saveno=-1; if(keys&INP_BUTTON_MENU_CANCEL) action=0; // exit else if((keys&INP_BUTTON_MENU_SELECT)&&(saveno==-1)) action=0; // exit else if((keys&INP_BUTTON_MENU_SELECT)&&(mode==0)&&((action==2)||(action==5))) action=6; // pre-save mode else if((keys&INP_BUTTON_MENU_SELECT)&&(mode==1)&&(action==5)) action=8; // pre-load mode else if((keys&INP_BUTTON_MENU_SELECT)&&(mode==2)&&(action==5)) { if(MenuMessageBox("Are you sure you want to delete","this save?","",MENU_MESSAGE_BOX_MODE_YESNO)==SAL_OK) action=13; //delete slot with no preview } else if((keys&INP_BUTTON_MENU_PREVIEW_SAVESTATE)&&(action==12)) action=3; // preview slot mode else if((keys&INP_BUTTON_MENU_SELECT)&&(mode==1)&&(action==12)) action=8; //load slot with no preview else if((keys&INP_BUTTON_MENU_SELECT)&&(mode==0)&&(action==12)) action=6; //save slot with no preview else if((keys&INP_BUTTON_MENU_SELECT)&&(mode==2)&&(action==12)) { if(MenuMessageBox("Are you sure you want to delete","this save?","",MENU_MESSAGE_BOX_MODE_YESNO)==SAL_OK) action=13; //delete slot with no preview } PrintTitle("Save States"); sal_VideoPrint(36,4,"UP/DOWN to choose a slot",SAL_RGB(31,8,8)); if(saveno==-1) { if(action!=10&&action!=0) { action=10; } } else { sal_VideoDrawRect(0, 16, 262, 16, SAL_RGB(22,0,0)); sprintf(text,"SLOT %d",saveno); sal_VideoPrint(107,20,text,SAL_RGB(31,31,31)); } switch(action) { case 1: //sal_VideoPrint(112,145-36,14,"Checking....",(unsigned short)SAL_RGB(31,31,31)); break; case 2: sal_VideoPrint(115,145-36,"FREE",SAL_RGB(31,31,31)); break; case 3: sal_VideoPrint(75,145-36,"Previewing...",SAL_RGB(31,31,31)); break; case 4: sal_VideoPrint(59,145-36,"Previewing failed",SAL_RGB(31,8,8)); break; case 5: { u32 DestWidth = 205, DestHeight = 154; sal_VideoBitmapScale(0, 0, SNES_WIDTH, SNES_HEIGHT, DestWidth, DestHeight, SAL_SCREEN_WIDTH - DestWidth, &mTempFb[0], (u16*)sal_VideoGetBuffer()+(SAL_SCREEN_WIDTH*(((202 + 16) - DestHeight)/2))+((262 - DestWidth)/2)); sal_VideoDrawRect(0, 186, 262, 16, SAL_RGB(22,0,0)); if(mode==1) sal_VideoPrint((262-(strlen(MENU_TEXT_LOAD_SAVESTATE)<<3))>>1,190,MENU_TEXT_LOAD_SAVESTATE,SAL_RGB(31,31,31)); else if(mode==0) sal_VideoPrint((262-(strlen(MENU_TEXT_OVERWRITE_SAVESTATE)<<3))>>1,190,MENU_TEXT_OVERWRITE_SAVESTATE,SAL_RGB(31,31,31)); else if(mode==2) sal_VideoPrint((262-(strlen(MENU_TEXT_DELETE_SAVESTATE)<<3))>>1,190,MENU_TEXT_DELETE_SAVESTATE,SAL_RGB(31,31,31)); break; } case 6: sal_VideoPrint(95,145-36,"Saving...",SAL_RGB(31,31,31)); break; case 7: sal_VideoPrint(95,145-36,"Saving failed",SAL_RGB(31,8,8)); break; case 8: sal_VideoPrint(87,145-36,"Loading...",SAL_RGB(31,31,31)); break; case 9: sal_VideoPrint(87,145-36,"Loading failed",SAL_RGB(31,8,8)); break; case 10: PrintBar(145-36-4); sal_VideoPrint(75,145-36,"Return to menu",SAL_RGB(31,31,31)); break; case 12: sal_VideoPrint(95,145-36,"Slot used",SAL_RGB(31,31,31)); sal_VideoPrint((262-(strlen(MENU_TEXT_PREVIEW_SAVESTATE)<<3))>>1,165,MENU_TEXT_PREVIEW_SAVESTATE,SAL_RGB(31,31,31)); if(mode==1) sal_VideoPrint((262-(strlen(MENU_TEXT_LOAD_SAVESTATE)<<3))>>1,175,MENU_TEXT_LOAD_SAVESTATE,SAL_RGB(31,31,31)); else if(mode==0) sal_VideoPrint((262-(strlen(MENU_TEXT_OVERWRITE_SAVESTATE)<<3))>>1,175,MENU_TEXT_OVERWRITE_SAVESTATE,SAL_RGB(31,31,31));
s32 FileSelect() { s8 text[SAL_MAX_PATH]; s8 previewPath[SAL_MAX_PATH]; s8 previousRom[SAL_MAX_PATH]; u16 romPreview[262 * 186]; bool8 havePreview = FALSE; s32 action=0; s32 smooth=0; u16 color=0; s32 i=0; s32 focus=ROM_SELECTOR_DEFAULT_FOCUS; s32 menuExit=0; s32 scanstart=0,scanend=0; u32 keys=0; s32 size=0, check=SAL_OK; previousRom[0] = '\0'; if (FileScan() != SAL_OK) { strcpy(mRomDir, sal_DirectoryGetUser()); if (FileScan() != SAL_OK) { MenuMessageBox("Home directory inaccessible","","",MENU_MESSAGE_BOX_MODE_PAUSE); mRomCount=ROM_SELECTOR_DEFAULT_FOCUS; menuExit = 1; return 0; } } focus = LoadLastSelectedRomPos(); //try to load a saved position in the romlist smooth=focus<<8; sal_InputIgnore(); while (menuExit==0) { keys=sal_InputPollRepeat(); if (keys & INP_BUTTON_MENU_SELECT) { switch(focus) { case ROM_SELECTOR_SAVE_DEFAULT_DIR: //Save default directory DelLastSelectedRomPos(); //delete any previously saved position in the romlist SaveMenuOptions(mSystemDir, DEFAULT_ROM_DIR_FILENAME, DEFAULT_ROM_DIR_EXT, mRomDir, strlen(mRomDir), 1); break; case ROM_SELECTOR_MAIN_MENU: //Return to menu action=0; menuExit=1; break; case ROM_SELECTOR_DEFAULT_FOCUS: //blank space - do nothing break; default: // normal file or dir selected if (mRomList[focus].type == SAL_FILE_TYPE_DIRECTORY) { //Check for special directory names "." and ".." if (sal_StringCompare(mRomList[focus].filename,".") == 0) { //goto root directory } else if (sal_StringCompare(mRomList[focus].filename,"..") == 0) { // up a directory //Remove a directory from RomPath and rescan //Code below will never let you go further up than \SD Card\ on the Gizmondo //This is by design. sal_DirectoryGetParent(mRomDir); FileScan(); focus=ROM_SELECTOR_DEFAULT_FOCUS; // default menu to non menu item // just to stop directory scan being started smooth=focus<<8; sal_InputIgnore(); break; } else { //go to sub directory sal_DirectoryCombine(mRomDir,mRomList[focus].filename); FileScan(); focus=ROM_SELECTOR_DEFAULT_FOCUS; // default menu to non menu item // just to stop directory scan being started smooth=focus<<8; } } else { // user has selected a rom, so load it SaveLastSelectedRomPos(focus); // save the current position in the romlist strcpy(mRomName, mRomDir); sal_DirectoryCombine(mRomName,mRomList[focus].filename); mQuickSavePresent=0; // reset any quick saves action=1; menuExit=1; } sal_InputIgnore(); break; } } else if (keys & INP_BUTTON_MENU_CANCEL) { sal_InputWaitForRelease(); action=0; menuExit=1; } else if ((keys & (SAL_INPUT_UP | SAL_INPUT_DOWN)) && (keys & (SAL_INPUT_UP | SAL_INPUT_DOWN)) != (SAL_INPUT_UP | SAL_INPUT_DOWN)) { if (keys & SAL_INPUT_UP) focus--; // Up else if (keys & SAL_INPUT_DOWN) focus++; // Down } else if ((keys & (SAL_INPUT_LEFT | SAL_INPUT_RIGHT)) && (keys & (SAL_INPUT_LEFT | SAL_INPUT_RIGHT)) != (SAL_INPUT_LEFT | SAL_INPUT_RIGHT)) { if (keys & SAL_INPUT_LEFT) focus-=12; else if (keys & SAL_INPUT_RIGHT) focus+=12; if (focus>mRomCount-1) focus=mRomCount-1; else if (focus<0) focus=0; smooth=(focus<<8)-1; } if (focus>mRomCount-1) { focus=0; smooth=(focus<<8)-1; } else if (focus<0) { focus=mRomCount-1; smooth=(focus<<8)-1; } // Draw screen: PrintTitle("ROM selection"); if (strcmp(mRomList[focus].displayName, previousRom) != 0) { char dummy[SAL_MAX_PATH], fileNameNoExt[SAL_MAX_PATH]; sal_DirectorySplitFilename(mRomList[focus].filename, dummy, fileNameNoExt, dummy); sprintf(previewPath, "%s/previews/%s.%s", sal_DirectoryGetHome(), fileNameNoExt, "png"); strcpy(previousRom, mRomList[focus].displayName); havePreview = sal_ImageLoad(previewPath, &romPreview, 262, 186) != SAL_ERROR; if (havePreview) { sal_VideoBitmapDim(romPreview, 262 * 186); } } if (havePreview) { sal_ImageDraw(romPreview, 262, 186, 0, 16); } smooth=smooth*7+(focus<<8); smooth>>=3; scanstart=focus-15; if (scanstart<0) scanstart=0; scanend = focus+15; if (scanend>mRomCount) scanend=mRomCount; for (i=scanstart;i<scanend;i++) { s32 x=0,y=0; y=(i<<4)-(smooth>>4); x=0; y+=112 - 28; if (y<=48 - 28 || y>=232 - 36) continue; if (i==focus) { color=SAL_RGB(31,31,31); PrintBar(y-4); } else { color=SAL_RGB(31,31,31); } // Draw Directory icon if current entry is a directory if(mRomList[i].type == SAL_FILE_TYPE_DIRECTORY) { sprintf(text,"<%s>",mRomList[i].displayName); sal_VideoPrint(x,y,text,color); } else { sal_VideoPrint(x,y,mRomList[i].displayName,color); } } sal_VideoPrint(0,4,mRomDir,SAL_RGB(31,8,8)); sal_VideoFlip(1); usleep(10000); } sal_InputIgnore(); freeRomLists(); return action; }
int FileScan() { s32 itemCount=0, fileCount=0, dirCount=0; s32 x,a,b,startIndex=ROM_SELECTOR_DEFAULT_FOCUS+1; s8 text[50]; s8 filename[SAL_MAX_PATH]; s8 path[SAL_MAX_PATH]; s8 ext[SAL_MAX_PATH]; struct SAL_DIR d; freeRomLists(); #if 0 PrintTitle("File Scan"); sal_VideoPrint(8,120,"Scanning Directory...",SAL_RGB(31,31,31)); sal_VideoFlip(1); #endif if(sal_DirectoryGetItemCount(mRomDir,&itemCount)==SAL_ERROR) { return SAL_ERROR; } mRomCount=ROM_SELECTOR_ROM_START+itemCount; mRomList=(SAL_DIRECTORY_ENTRY*)malloc(sizeof(struct SAL_DIRECTORY_ENTRY)*mRomCount); //was there enough memory? if(mRomList == NULL) { MenuMessageBox("Could not allocate memory","Too many files","",MENU_MESSAGE_BOX_MODE_PAUSE); //not enough memory - try the minimum mRomList=(SAL_DIRECTORY_ENTRY*)malloc(sizeof(struct SAL_DIRECTORY_ENTRY)*ROM_SELECTOR_ROM_START); mRomCount=ROM_SELECTOR_ROM_START; if (mRomList == NULL) { //still no joy MenuMessageBox("Dude, I'm really broken now","Restart system","never do this again",MENU_MESSAGE_BOX_MODE_PAUSE); mRomCount = -1; return SAL_ERROR; } } //Add default items DefaultRomListItems(); if (itemCount>0) { if (sal_DirectoryOpen(mRomDir, &d)==SAL_OK) { //Dir opened, now stream out details x=0; while(sal_DirectoryRead(&d, &mRomList[x+startIndex])==SAL_OK) { //Dir entry read #if 0 PrintTitle("File Scan"); sprintf(text,"Fetched item %d of %d",x, itemCount-1); sal_VideoPrint(8,120,text,SAL_RGB(31,31,31)); PrintBar(228-4); sal_VideoPrint(0,228,mRomDir,SAL_RGB(0,0,0)); sal_VideoFlip(1); #endif if (mRomList[x+startIndex].type == SAL_FILE_TYPE_FILE) { sal_DirectorySplitFilename(mRomList[x+startIndex].filename,path,filename,ext); if( sal_StringCompare(ext,"zip") == 0 || sal_StringCompare(ext,"smc") == 0 || sal_StringCompare(ext,"sfc") == 0 || sal_StringCompare(ext,"fig") == 0 /* Super WildCard dump */ || sal_StringCompare(ext,"swc") == 0 /* Super WildCard dump */) { fileCount++; x++; } } else { dirCount++; x++; } } mRomCount=ROM_SELECTOR_ROM_START+dirCount+fileCount; sal_DirectoryClose(&d); } else { return SAL_ERROR; } #if 0 PrintTitle("File Scan"); sal_VideoPrint(8,120,"Sorting items...",SAL_RGB(31,31,31)); sal_VideoFlip(1); #endif int lowIndex=0; //Put all directory entries at the top for(a=startIndex;a<startIndex+dirCount;a++) { if (mRomList[a].type == SAL_FILE_TYPE_FILE) { for(b=a+1;b<mRomCount;b++) { if (mRomList[b].type == SAL_FILE_TYPE_DIRECTORY) { SwapDirectoryEntry(&mRomList[a],&mRomList[b]); break; } } } } //Now sort directory entries for(a=startIndex;a<startIndex+dirCount;a++) { lowIndex=a; for(b=a+1;b<startIndex+dirCount;b++) { if (sal_StringCompare(mRomList[b].displayName, mRomList[lowIndex].displayName) < 0) { //this index is lower lowIndex=b; } } //lowIndex should index next lowest value SwapDirectoryEntry(&mRomList[lowIndex],&mRomList[a]); } //Now sort file entries for(a=startIndex+dirCount;a<mRomCount;a++) { lowIndex=a; for(b=a+1;b<mRomCount;b++) { if (sal_StringCompare(mRomList[b].displayName, mRomList[lowIndex].displayName) < 0) { //this index is lower lowIndex=b; } } //lowIndex should index next lowest value SwapDirectoryEntry(&mRomList[lowIndex],&mRomList[a]); } } return SAL_OK; }
bool8_32 S9xDeinitUpdate (int Width, int Height, bool8_32) { if(mInMenu) return TRUE; // After returning from the menu, clear the background of 3 frames. // This prevents remnants of the menu from appearing. if (mFramesCleared < 3) { sal_VideoClear(0); mFramesCleared++; } // If the height changed from 224 to 239, or from 239 to 224, // possibly change the resolution. bool PAL = !!(Memory.FillRAM[0x2133] & 4); if (PAL != LastPAL) { sal_VideoSetPAL(mMenuOptions.fullScreen, PAL); LastPAL = PAL; } switch (mMenuOptions.fullScreen) { case 0: /* No scaling */ case 3: /* Hardware scaling */ { u32 h = PAL ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT; u32 y, pitch = sal_VideoGetPitch(); u8 *src = (u8*) IntermediateScreen, *dst = (u8*) sal_VideoGetBuffer() + ((sal_VideoGetWidth() - SNES_WIDTH) / 2) * sizeof(u16) + ((sal_VideoGetHeight() - h) / 2) * pitch; for (y = 0; y < h; y++) { memcpy(dst, src, SNES_WIDTH * sizeof(u16)); src += SNES_WIDTH * sizeof(u16); dst += pitch; } break; } case 1: /* Fast software scaling */ if (PAL) { upscale_256x240_to_320x240((uint32_t*) sal_VideoGetBuffer(), (uint32_t*) IntermediateScreen, SNES_WIDTH); } else { upscale_p((uint32_t*) sal_VideoGetBuffer(), (uint32_t*) IntermediateScreen, SNES_WIDTH); } break; case 2: /* Smooth software scaling */ if (PAL) { upscale_256x240_to_320x240_bilinearish((uint32_t*) sal_VideoGetBuffer() + 160, (uint32_t*) IntermediateScreen, SNES_WIDTH); } else { upscale_256x224_to_320x240_bilinearish((uint32_t*) sal_VideoGetBuffer() + 160, (uint32_t*) IntermediateScreen, SNES_WIDTH); } break; } u32 newTimer; if (mMenuOptions.showFps) { mFps++; newTimer=sal_TimerRead(); if(newTimer-mLastTimer>Memory.ROMFramesPerSecond) { mLastTimer=newTimer; sprintf(mFpsDisplay,"%2d/%2d", mFps, Memory.ROMFramesPerSecond); mFps=0; } sal_VideoDrawRect(0,0,5*8,8,SAL_RGB(0,0,0)); sal_VideoPrint(0,0,mFpsDisplay,SAL_RGB(31,31,31)); } if(mVolumeDisplayTimer>0) { sal_VideoDrawRect(100,0,8*8,8,SAL_RGB(0,0,0)); sal_VideoPrint(100,0,mVolumeDisplay,SAL_RGB(31,31,31)); } if(mQuickStateTimer>0) { sal_VideoDrawRect(200,0,8*8,8,SAL_RGB(0,0,0)); sal_VideoPrint(200,0,mQuickStateDisplay,SAL_RGB(31,31,31)); } sal_VideoFlip(0); }
int mainEntry(int argc, char* argv[]) { int ref = 0; s32 event=EVENT_NONE; sal_Init(); sal_VideoInit(16,SAL_RGB(0,0,0),Memory.ROMFramesPerSecond); mRomName[0]=0; if (argc >= 2) strcpy(mRomName, argv[1]); // Record ROM name MenuInit(sal_DirectoryGetHome(), &mMenuOptions); if(SnesInit() == SAL_ERROR) { sal_Reset(); return 0; } while(1) { mInMenu=1; event=MenuRun(mRomName); mInMenu=0; if(event==EVENT_LOAD_ROM) { if(mTempState) free(mTempState); mTempState=NULL; if(SnesRomLoad() == SAL_ERROR) { MenuMessageBox("Failed to load rom",mRomName,"Press any button to continue", MENU_MESSAGE_BOX_MODE_PAUSE); sal_Reset(); return 0; } else { event=EVENT_RUN_ROM; } } if(event==EVENT_RESET_ROM) { S9xReset(); event=EVENT_RUN_ROM; } if(event==EVENT_RUN_ROM) { if(mMenuOptions.fullScreen) { sal_VideoSetScaling(SNES_WIDTH,SNES_HEIGHT); } if(mMenuOptions.transparency) Settings.Transparency = TRUE; else Settings.Transparency = FALSE; sal_AudioSetVolume(mMenuOptions.volume,mMenuOptions.volume); sal_CpuSpeedSet(mMenuOptions.cpuSpeed); sal_VideoClear(0); sal_VideoFlip(1); sal_VideoClear(0); sal_VideoFlip(1); if(mMenuOptions.soundEnabled) RunSound(); else RunNoSound(); event=EVENT_NONE; } if(event==EVENT_EXIT_APP) break; } if(mTempState) free(mTempState); mTempState=NULL; S9xGraphicsDeinit(); S9xDeinitAPU(); Memory.Deinit(); free(GFX.SubZBuffer); free(GFX.ZBuffer); free(GFX.SubScreen); GFX.SubZBuffer=NULL; GFX.ZBuffer=NULL; GFX.SubScreen=NULL; sal_Reset(); return 0; }