diff --git a/source/filebrowser.cpp b/source/filebrowser.cpp index 37bfac7..88b2a08 100644 --- a/source/filebrowser.cpp +++ b/source/filebrowser.cpp @@ -43,7 +43,8 @@ BROWSERINFO browser; BROWSERENTRY * browserList = NULL; // list of files/folders in browser static char szpath[MAXPATHLEN]; -static bool inSz = false; +char szname[MAXPATHLEN]; +bool inSz = false; unsigned long SNESROMSize = 0; bool loadingFile = false; @@ -218,6 +219,8 @@ int UpdateDirName() /* remove last subdirectory name */ size = strlen(browser.dir) - size - 1; + strncpy(GCSettings.LastFileLoaded, &browser.dir[size], strlen(browser.dir) - size - 1); //set as loaded file the previous dir + GCSettings.LastFileLoaded[strlen(browser.dir) - size - 1] = 0; browser.dir[size] = 0; } @@ -431,12 +434,11 @@ void StripExt(char* returnstring, char * inputstring) ***************************************************************************/ int BrowserLoadSz() { - char filepath[MAXPATHLEN]; - memset(filepath, 0, MAXPATHLEN); - - // we'll store the 7z filepath for extraction later - if(!MakeFilePath(szpath, FILE_ROM)) - return 0; + memset(szpath, 0, MAXPATHLEN); + strncpy(szpath, browser.dir, strlen(browser.dir) - 1); + + strncpy(szname, strrchr(szpath, '/') + 1, strrchr(szpath, '.') - strrchr(szpath, '/')); + *strrchr(szname, '.') = '\0'; int szfiles = SzParse(szpath); if(szfiles) @@ -506,7 +508,7 @@ int BrowserLoadFile() // store the filename (w/o ext) - used for sram/freeze naming StripExt(Memory.ROMFilename, browserList[browser.selIndex].filename); - strcpy(loadedFile, browserList[browser.selIndex].filename); + snprintf(GCSettings.LastFileLoaded, MAXPATHLEN, "%s", browserList[browser.selIndex].filename); SNESROMSize = 0; S9xDeleteCheats(); @@ -548,15 +550,25 @@ int BrowserChangeFolder() SzClose(); } - if(!UpdateDirName()) + if(!UpdateDirName()) return -1; - HaltParseThread(); // halt parsing + HaltParseThread(); CleanupPath(browser.dir); - ResetBrowser(); // reset browser + ResetBrowser(); if(browser.dir[0] != 0) - ParseDirectory(); + { + if(strstr(browser.dir, ".7z")) + { + BrowserLoadSz(); + } + else + { + ParseDirectory(true, true); + } + FindAndSelectLastLoadedFile(); + } if(browser.numEntries == 0) { diff --git a/source/filebrowser.h b/source/filebrowser.h index 8ceefa3..5065a48 100644 --- a/source/filebrowser.h +++ b/source/filebrowser.h @@ -58,6 +58,8 @@ enum extern unsigned long SNESROMSize; extern bool loadingFile; +extern char szname[MAXPATHLEN]; +extern bool inSz; bool MakeFilePath(char filepath[], int type, char * filename = NULL, int filenum = -2); int UpdateDirName(); diff --git a/source/fileop.cpp b/source/fileop.cpp index 9c09f3c..0dff7e9 100644 --- a/source/fileop.cpp +++ b/source/fileop.cpp @@ -492,6 +492,40 @@ bool GetFileSize(int i) return true; } +void FindAndSelectLastLoadedFile () +{ + int indexFound = -1; + + for(int j=1; j < browser.numEntries; j++) + { + if(strcmp(browserList[j].filename, GCSettings.LastFileLoaded) == 0) + { + indexFound = j; + break; + } + } + + // move to this file + if(indexFound > 0) + { + if(indexFound >= FILE_PAGESIZE) + { + int newIndex = (floor(indexFound/(float)FILE_PAGESIZE)) * FILE_PAGESIZE; + + if(newIndex + FILE_PAGESIZE > browser.numEntries) + newIndex = browser.numEntries - FILE_PAGESIZE; + + if(newIndex < 0) + newIndex = 0; + + browser.pageIndex = newIndex; + } + browser.selIndex = indexFound; + } + + selectLoadedFile = 2; // selecting done +} + static bool ParseDirEntries() { if(!dir) @@ -576,40 +610,7 @@ static bool ParseDirEntries() { closedir(dir); // close directory dir = NULL; - - // try to find and select the last loaded file - if(selectLoadedFile == 1 && !parseHalt && loadedFile[0] != 0 && browser.dir[0] != 0) - { - int indexFound = -1; - - for(int j=1; j < browser.numEntries; j++) - { - if(strcmp(browserList[j].filename, loadedFile) == 0) - { - indexFound = j; - break; - } - } - - // move to this file - if(indexFound > 0) - { - if(indexFound >= FILE_PAGESIZE) - { - int newIndex = (floor(indexFound/(float)FILE_PAGESIZE)) * FILE_PAGESIZE; - - if(newIndex + FILE_PAGESIZE > browser.numEntries) - newIndex = browser.numEntries - FILE_PAGESIZE; - - if(newIndex < 0) - newIndex = 0; - - browser.pageIndex = newIndex; - } - browser.selIndex = indexFound; - } - selectLoadedFile = 2; // selecting done - } + return false; // no more entries } return true; // more entries diff --git a/source/fileop.h b/source/fileop.h index 58a765b..8bd7454 100644 --- a/source/fileop.h +++ b/source/fileop.h @@ -35,6 +35,7 @@ bool ChangeInterface(int device, bool silent); bool ChangeInterface(char * filepath, bool silent); void CreateAppPath(char * origpath); bool GetFileSize(int i); +void FindAndSelectLastLoadedFile(); int ParseDirectory(bool waitParse = false, bool filter = true); void AllocSaveBuffer(); void FreeSaveBuffer(); diff --git a/source/gcunzip.cpp b/source/gcunzip.cpp index c97a7ce..01562d6 100644 --- a/source/gcunzip.cpp +++ b/source/gcunzip.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include "snes9xgx.h" #include "fileop.h" @@ -355,6 +356,7 @@ void SzClose() SzArDbExFree(&SzDb, SzAllocImp.Free); } + /**************************************************************************** * SzParse * @@ -369,14 +371,15 @@ int SzParse(char * filepath) int device; - if(!FindDevice(browser.dir, &device) || !GetFileSize(browser.selIndex)) + struct stat filestat; + if(stat(filepath, &filestat) < 0) + return 0; + unsigned int filelen = filestat.st_size; + + if(!FindDevice(filepath, &device) || !filelen) return 0; int nbfiles = 0; - - // save the length/offset of this file - unsigned int filelen = browserList[browser.selIndex].length; - // setup archive stream SzArchiveStream.offset = 0; SzArchiveStream.len = filelen; @@ -425,7 +428,7 @@ int SzParse(char * filepath) // add '..' folder in case the user wants exit the 7z AddBrowserEntry(); - + sprintf(browserList[0].filename, ".."); sprintf(browserList[0].displayname, "Up One Level"); browserList[0].isdir = 1; browserList[0].length = filelen; @@ -454,6 +457,12 @@ int SzParse(char * filepath) // parse information about this file to the file list structure snprintf(browserList[SzJ].filename, MAXJOLIET, "%s", SzF->Name); StripExt(browserList[SzJ].displayname, browserList[SzJ].filename); + char* strPos = strstr(browserList[SzJ].displayname, szname); + if(strPos) + { + snprintf(browserList[SzJ].displayname, MAXJOLIET, "%s", strPos + strlen(szname)); + } + browserList[SzJ].length = SzF->Size; // filesize browserList[SzJ].isdir = 0; // only files will be displayed (-> no flags) browserList[SzJ].filenum = SzI; // the extraction function identifies the file with this number diff --git a/source/gui/gui.h b/source/gui/gui.h index 779e6cb..b786a2f 100644 --- a/source/gui/gui.h +++ b/source/gui/gui.h @@ -240,7 +240,7 @@ class GuiElement //!Constructor GuiElement(); //!Destructor - ~GuiElement(); + virtual ~GuiElement(); //!Set the element's parent //!\param e Pointer to parent element void SetParent(GuiElement * e); diff --git a/source/menu.cpp b/source/menu.cpp index 24fa8ce..db7419b 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -49,6 +49,16 @@ extern SCheatData Cheat; static GuiImageData * pointer[4]; #endif +#ifdef HW_RVL + #include "mem2.h" + + #define MEM_ALLOC(A) (u8*)mem2_malloc(A) + #define MEM_DEALLOC(A) mem2_free(A) +#else + #define MEM_ALLOC(A) (u8*)memalign(32, A) + #define MEM_DEALLOC(A) free(A) +#endif + static GuiTrigger * trigA = NULL; static GuiTrigger * trig2 = NULL; @@ -311,7 +321,7 @@ UpdateGUI (void *arg) for(i = 0; i <= 255; i += 15) { mainWindow->Draw(); - Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0, 0, 0, i},1); + Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0, 0, 0, (u8)i},1); Menu_Render(); } ExitApp(); @@ -963,8 +973,15 @@ static int MenuGameSelection() buttonWindow.Append(&exitBtn); GuiFileBrowser gameBrowser(424, 268); - gameBrowser.SetPosition(50, 98); + gameBrowser.SetPosition(10, 98); ResetBrowser(); + + GuiImage preview; + preview.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); + preview.SetPosition(-10, 0); + u8* imgBuffer = MEM_ALLOC(512 * 512 * 4); + int previousBrowserIndex = -1; + char screenshotPath[MAXJOLIET + 1]; HaltGui(); btnLogo->SetAlignment(ALIGN_RIGHT, ALIGN_TOP); @@ -972,6 +989,7 @@ static int MenuGameSelection() mainWindow->Append(&titleTxt); mainWindow->Append(&gameBrowser); mainWindow->Append(&buttonWindow); + mainWindow->Append(&preview); ResumeGui(); #ifdef HW_RVL @@ -985,6 +1003,7 @@ static int MenuGameSelection() gameBrowser.ResetState(); gameBrowser.fileList[0]->SetState(STATE_SELECTED); gameBrowser.TriggerUpdate(); + titleTxt.SetText(inSz ? szname : "Choose Game"); while(menu == MENU_NONE) { @@ -1004,25 +1023,29 @@ static int MenuGameSelection() if(gameBrowser.fileList[i]->GetState() == STATE_CLICKED) { gameBrowser.fileList[i]->ResetState(); + // check corresponding browser entry if(browserList[browser.selIndex].isdir || IsSz()) - { - if(IsSz()) - res = BrowserLoadSz(); - else - res = BrowserChangeFolder(); - + { + HaltGui(); + res = BrowserChangeFolder(); if(res) { gameBrowser.ResetState(); gameBrowser.fileList[0]->SetState(STATE_SELECTED); gameBrowser.TriggerUpdate(); + previousBrowserIndex = -1; } else { menu = MENU_GAMESELECTION; break; } + + + titleTxt.SetText(inSz ? szname : "Choose Game"); + + ResumeGui(); } else { @@ -1030,6 +1053,7 @@ static int MenuGameSelection() ShutoffRumble(); #endif mainWindow->SetState(STATE_DISABLED); + SavePrefs(SILENT); if(BrowserLoadFile()) menu = MENU_EXIT; else @@ -1037,6 +1061,33 @@ static int MenuGameSelection() } } } + + //update game screenshot + if(previousBrowserIndex != browser.selIndex) + { + previousBrowserIndex = browser.selIndex; + snprintf(screenshotPath, MAXJOLIET, "%s%s/%s.png", pathPrefix[GCSettings.LoadMethod], GCSettings.ScreenshotsFolder, browserList[browser.selIndex].displayname); + + AllocSaveBuffer(); + int width, height; + if(LoadFile(screenshotPath, SILENT)) + { + if(DecodePNG(savebuffer, &width, &height, imgBuffer, 512, 512)) + { + preview.SetImage(imgBuffer, width, height); + preview.SetScale(180.0f / width); + } + else + { + preview.SetImage(NULL, 0, 0); + } + } + else + { + preview.SetImage(NULL, 0, 0); + } + FreeSaveBuffer(); + } if(settingsBtn.GetState() == STATE_CLICKED) menu = MENU_SETTINGS; @@ -1050,6 +1101,8 @@ static int MenuGameSelection() mainWindow->Remove(&titleTxt); mainWindow->Remove(&buttonWindow); mainWindow->Remove(&gameBrowser); + mainWindow->Remove(&preview); + MEM_DEALLOC(imgBuffer); return menu; } @@ -3288,6 +3341,7 @@ static int MenuSettingsFile() sprintf(options.name[i++], "Load Folder"); sprintf(options.name[i++], "Save Folder"); sprintf(options.name[i++], "Cheats Folder"); + sprintf(options.name[i++], "Screenshots Folder"); sprintf(options.name[i++], "Auto Load"); sprintf(options.name[i++], "Auto Save"); options.length = i; @@ -3359,14 +3413,18 @@ static int MenuSettingsFile() case 4: OnScreenKeyboard(GCSettings.CheatFolder, MAXPATHLEN); break; - + case 5: + OnScreenKeyboard(GCSettings.ScreenshotsFolder, MAXPATHLEN); + break; + + case 6: GCSettings.AutoLoad++; if (GCSettings.AutoLoad > 2) GCSettings.AutoLoad = 0; break; - case 6: + case 7: GCSettings.AutoSave++; if (GCSettings.AutoSave > 3) GCSettings.AutoSave = 0; @@ -3432,15 +3490,16 @@ static int MenuSettingsFile() snprintf (options.value[2], 35, "%s", GCSettings.LoadFolder); snprintf (options.value[3], 35, "%s", GCSettings.SaveFolder); snprintf (options.value[4], 35, "%s", GCSettings.CheatFolder); + snprintf (options.value[5], 35, "%s", GCSettings.ScreenshotsFolder); - if (GCSettings.AutoLoad == 0) sprintf (options.value[5],"Off"); - else if (GCSettings.AutoLoad == 1) sprintf (options.value[5],"SRAM"); - else if (GCSettings.AutoLoad == 2) sprintf (options.value[5],"Snapshot"); + if (GCSettings.AutoLoad == 0) sprintf (options.value[6],"Off"); + else if (GCSettings.AutoLoad == 1) sprintf (options.value[6],"SRAM"); + else if (GCSettings.AutoLoad == 2) sprintf (options.value[6],"Snapshot"); - if (GCSettings.AutoSave == 0) sprintf (options.value[6],"Off"); - else if (GCSettings.AutoSave == 1) sprintf (options.value[6],"SRAM"); - else if (GCSettings.AutoSave == 2) sprintf (options.value[6],"Snapshot"); - else if (GCSettings.AutoSave == 3) sprintf (options.value[6],"Both"); + if (GCSettings.AutoSave == 0) sprintf (options.value[7],"Off"); + else if (GCSettings.AutoSave == 1) sprintf (options.value[7],"SRAM"); + else if (GCSettings.AutoSave == 2) sprintf (options.value[7],"Snapshot"); + else if (GCSettings.AutoSave == 3) sprintf (options.value[7],"Both"); optionBrowser.TriggerUpdate(); } diff --git a/source/preferences.cpp b/source/preferences.cpp index 77601c5..93527c5 100644 --- a/source/preferences.cpp +++ b/source/preferences.cpp @@ -123,8 +123,10 @@ preparePrefsData () createXMLSetting("LoadMethod", "Load Method", toStr(GCSettings.LoadMethod)); createXMLSetting("SaveMethod", "Save Method", toStr(GCSettings.SaveMethod)); createXMLSetting("LoadFolder", "Load Folder", GCSettings.LoadFolder); + createXMLSetting("LastFileLoaded", "Last File Loaded", GCSettings.LastFileLoaded); createXMLSetting("SaveFolder", "Save Folder", GCSettings.SaveFolder); createXMLSetting("CheatFolder", "Cheats Folder", GCSettings.CheatFolder); + createXMLSetting("ScreenshotsFolder", "Screenshots Folder", GCSettings.ScreenshotsFolder); createXMLSection("Network", "Network Settings"); @@ -297,8 +299,10 @@ decodePrefsData () loadXMLSetting(&GCSettings.LoadMethod, "LoadMethod"); loadXMLSetting(&GCSettings.SaveMethod, "SaveMethod"); loadXMLSetting(GCSettings.LoadFolder, "LoadFolder", sizeof(GCSettings.LoadFolder)); + loadXMLSetting(GCSettings.LastFileLoaded, "LastFileLoaded", sizeof(GCSettings.LastFileLoaded)); loadXMLSetting(GCSettings.SaveFolder, "SaveFolder", sizeof(GCSettings.SaveFolder)); loadXMLSetting(GCSettings.CheatFolder, "CheatFolder", sizeof(GCSettings.CheatFolder)); + loadXMLSetting(GCSettings.ScreenshotsFolder, "ScreenshotsFolder", sizeof(GCSettings.ScreenshotsFolder)); // Network Settings @@ -399,6 +403,7 @@ DefaultSettings () sprintf (GCSettings.LoadFolder, "%s/roms", APPFOLDER); // Path to game files sprintf (GCSettings.SaveFolder, "%s/saves", APPFOLDER); // Path to save files sprintf (GCSettings.CheatFolder, "%s/cheats", APPFOLDER); // Path to cheat files + sprintf (GCSettings.ScreenshotsFolder, "%s/screenshots", APPFOLDER); // Path to cheat files GCSettings.AutoLoad = 1; GCSettings.AutoSave = 1; @@ -647,6 +652,9 @@ bool LoadPrefs() if(strcmp(GCSettings.CheatFolder, "snes9x/cheats") == 0) sprintf(GCSettings.CheatFolder, "snes9xgx/cheats"); + + if(strcmp(GCSettings.ScreenshotsFolder, "snes9x/screenshots") == 0) + sprintf(GCSettings.ScreenshotsFolder, "snes9xgx/screenshots"); ResetText(); return prefFound; diff --git a/source/snes9xgx.cpp b/source/snes9xgx.cpp index 77da56d..c5be16d 100644 --- a/source/snes9xgx.cpp +++ b/source/snes9xgx.cpp @@ -53,7 +53,6 @@ int ShutdownRequested = 0; int ResetRequested = 0; int ExitRequested = 0; char appPath[1024] = { 0 }; -char loadedFile[1024] = { 0 }; static int currentMode; extern "C" { diff --git a/source/snes9xgx.h b/source/snes9xgx.h index b1489ee..086b151 100644 --- a/source/snes9xgx.h +++ b/source/snes9xgx.h @@ -85,9 +85,11 @@ struct SGCSettings{ int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB) int SaveMethod; // For SRAM, Freeze, Prefs: Auto, SD, USB, SMB char LoadFolder[MAXPATHLEN]; // Path to game files + char LastFileLoaded[MAXPATHLEN]; //Last file loaded filename char SaveFolder[MAXPATHLEN]; // Path to save files char CheatFolder[MAXPATHLEN]; // Path to cheat files - + char ScreenshotsFolder[MAXPATHLEN]; //Path to screenshots files + char smbip[80]; char smbuser[20]; char smbpwd[20]; @@ -121,7 +123,6 @@ extern int ConfigRequested; extern int ShutdownRequested; extern int ExitRequested; extern char appPath[]; -extern char loadedFile[]; extern FreeTypeGX *fontSystem[]; #endif diff --git a/source/utils/pngu.c b/source/utils/pngu.c index 127017d..52ff7d9 100644 --- a/source/utils/pngu.c +++ b/source/utils/pngu.c @@ -311,7 +311,7 @@ static int pngu_decode (IMGCTX ctx, u32 width, u32 height, u32 stripAlpha) return PNGU_INVALID_WIDTH_OR_HEIGHT; // Check if color type is supported by PNGU - if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_PALETTE) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_UNKNOWN) ) + if (ctx->prop.imgColorType == PNGU_COLOR_TYPE_UNKNOWN) return PNGU_UNSUPPORTED_COLOR_TYPE; // Scale 16 bit samples to 8 bit @@ -329,6 +329,10 @@ static int pngu_decode (IMGCTX ctx, u32 width, u32 height, u32 stripAlpha) // Transform grayscale images to RGB if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) ) png_set_gray_to_rgb (ctx->png_ptr); + + // Transform palette images to RGB + if (ctx->prop.imgColorType == PNGU_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(ctx->png_ptr); // Flush transformations png_read_update_info (ctx->png_ptr, ctx->info_ptr);