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 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); }
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); }
u32 sal_VideoInit(u32 bpp, u32 color, u32 refreshRate) { SDL_ShowCursor(0); if (mScreen) { if (mBpp == bpp) { return SAL_OK; } SDL_VideoQuit(); mScreen=NULL; } mBpp=bpp; mRefreshRate=refreshRate; //Set up the screen mScreen = SDL_SetVideoMode( SAL_SCREEN_WIDTH, SAL_SCREEN_HEIGHT, bpp, SDL_HWSURFACE | SDL_DOUBLEBUF); //If there was an error in setting up the screen if( mScreen == NULL ) { sal_LastErrorSet("SDL_SetVideoMode failed"); return SAL_ERROR; } // lock surface if needed if (SDL_MUSTLOCK(mScreen)) { if (SDL_LockSurface(mScreen) < 0) { sal_LastErrorSet("unable to lock surface"); return SAL_ERROR; } } sal_VideoClear(color); sal_VideoFlip(1); return SAL_OK; }
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; }
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; }