From 0f34d709e463c6e79495a1f5cb07be78c7bc4dee Mon Sep 17 00:00:00 2001 From: Mauro Vietri Date: Tue, 30 May 2023 11:44:04 -0300 Subject: [PATCH] Added support for saving screenshot of game using a user-defined shortcut --- makefile | 10 ++- skeleton/BASE/README.txt | 4 + .../SYSTEM/rg35xx/paks/MinUI.pak/launch.sh | 1 + src/common/defines.h | 1 + src/minarch/minarch.c | 84 ++++++++++++++----- 5 files changed, 77 insertions(+), 23 deletions(-) diff --git a/makefile b/makefile index 1674a7f..2173986 100644 --- a/makefile +++ b/makefile @@ -19,6 +19,10 @@ RELEASE_BASE=FinUI-$(RELEASE_TIME)b RELEASE_DOT!=find ./releases/. -regex ".*/$(RELEASE_BASE)-[0-9]+-base\.zip" -printf '.' | wc -m RELEASE_NAME=$(RELEASE_BASE)-$(RELEASE_DOT) +ifeq (,$(BUILD_HASH)) +BUILD_HASH="devRelease" +endif + # TODO: this needs to consider the different platforms, eg. rootfs.ext2 should only be copied in rg35xx-toolchain all: lib sys all-cores tools bundle readmes zip report @@ -102,14 +106,14 @@ zip: cd ./build/PAYLOAD && zip -r MinUI.zip .system mv ./build/PAYLOAD/MinUI.zip ./build/BASE - cd ./build/BASE && zip -r ../../releases/$(RELEASE_NAME)-base.zip Bios Roms Saves dmenu.bin MinUI.zip README.txt INSTALL.txt SHORTCUTS.txt - cd ./build/EXTRAS && zip -r ../../releases/$(RELEASE_NAME)-extras.zip Bios Emus Roms Saves Tools README.txt + cd ./build/BASE && zip -r ../../releases/$(RELEASE_NAME)-base.zip Bios Roms Saves Screenshots dmenu.bin MinUI.zip README.txt INSTALL.txt SHORTCUTS.txt + cd ./build/EXTRAS && zip -r ../../releases/$(RELEASE_NAME)-extras.zip Bios Emus Roms Saves Screenshots Tools README.txt rm -fr ./build/FULL mkdir ./build/FULL cp -fR ./build/BASE/* ./build/FULL/ cp -fR ./build/EXTRAS/* ./build/FULL/ - cd ./build/FULL && zip -r ../../releases/$(RELEASE_NAME)-full.zip Bios Emus Roms Saves Tools dmenu.bin MinUI.zip INSTALL.txt SHORTCUTS.txt + cd ./build/FULL && zip -r ../../releases/$(RELEASE_NAME)-full.zip Bios Emus Roms Saves Screenshots Tools dmenu.bin MinUI.zip INSTALL.txt SHORTCUTS.txt echo "$(RELEASE_NAME)" > ./build/latest.txt diff --git a/skeleton/BASE/README.txt b/skeleton/BASE/README.txt index c7ce596..02761e2 100644 --- a/skeleton/BASE/README.txt +++ b/skeleton/BASE/README.txt @@ -68,6 +68,10 @@ Reduce/increase brightness: MENU + VOLUME UP or VOLUME DOWN +Add/remove Favorites (from menu): + + SELECT + The remaining emulation shortcuts are all user defined. ---------------------------------------- diff --git a/skeleton/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh b/skeleton/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh index 0eaae24..bf76d21 100755 --- a/skeleton/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh +++ b/skeleton/SYSTEM/rg35xx/paks/MinUI.pak/launch.sh @@ -7,6 +7,7 @@ export SYSTEM_PATH="$SDCARD_PATH/.system/rg35xx" export CORES_PATH="$SYSTEM_PATH/cores" export USERDATA_PATH="$SDCARD_PATH/.userdata/rg35xx" export LOGS_PATH="$USERDATA_PATH/logs" +export SCREENSHOTS_PATH="$SDCARD_PATH/Screenshots" ####################################### diff --git a/src/common/defines.h b/src/common/defines.h index 8af98ad..a2b61b7 100644 --- a/src/common/defines.h +++ b/src/common/defines.h @@ -60,6 +60,7 @@ #define FAUX_FAVORITE_PATH SDCARD_PATH "/Favorites" #define COLLECTIONS_PATH SDCARD_PATH "/Collections" #define BATTERY_PATH SDCARD_PATH "/battery.txt" +#define SCREENSHOTS_PATH SDCARD_PATH "/Screenshots" #define LAST_PATH "/tmp/last.txt" // transient #define CHANGE_DISC_PATH "/tmp/change_disc.txt" diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index 74f73fd..d9eb371 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -435,6 +435,24 @@ static void SRAM_write(void) { /////////////////////////////////////// +static void Downsample(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch) { + uint32_t ox = 0; + uint32_t oy = 0; + uint32_t ix = (w<<16) / FIXED_WIDTH; + uint32_t iy = (h<<16) / FIXED_HEIGHT; + + for (int y=0; y>16) * pitch; + uint16_t* restrict dst_row = (void*)dst + y * dst_pitch; + for (int x=0; x>16)); + dst_row += 1; + ox += ix; + } + ox = 0; + oy += iy; + } +} static int state_slot = 0; static void State_getPath(char* filename) { sprintf(filename, "%s/%s.st%i", core.config_dir, game.name, state_slot); @@ -531,6 +549,46 @@ static void State_resume(void) { State_read(); state_slot = last_state_slot; } +static void Take_screenshot(void) { + char bmp_path[256]; + char screenshot_dir[256]; + + sprintf(screenshot_dir, SCREENSHOTS_PATH); + mkdir(screenshot_dir, 0755); + + SDL_Surface* backing = GFX_getBufferCopy(); + SDL_Surface* snapshot = SDL_CreateRGBSurface(SDL_SWSURFACE, FIXED_WIDTH,FIXED_HEIGHT,FIXED_DEPTH,0,0,0,0); + + if (backing->w==FIXED_WIDTH && backing->h==FIXED_HEIGHT) { + SDL_BlitSurface(backing, NULL, snapshot, NULL); + } + else { + Downsample(backing->pixels,snapshot->pixels,backing->w,backing->h,backing->pitch,snapshot->pitch); + } + + // Get the current date and time for the screenshot filename + time_t currentTime = time(NULL); + struct tm* timeinfo = localtime(¤tTime); + int day = timeinfo->tm_mday; + int month = timeinfo->tm_mon + 1; + int year = timeinfo->tm_year + 1900; + + int hours = timeinfo->tm_hour; + int minutes = timeinfo->tm_min; + int seconds = timeinfo->tm_sec; + + // Convert hours and minutes to strings + char timeStr[16]; + snprintf(timeStr, sizeof(timeStr), "%04d%02d%02d_%02d%02d%02d", year, month, day, hours, minutes, seconds); + sprintf(bmp_path, "%s/%s.bmp", screenshot_dir, timeStr); + + SDL_RWops* out = SDL_RWFromFile(bmp_path, "wb"); + + SDL_SaveBMP_RW(snapshot, out, 1); + + SDL_FreeSurface(snapshot); + SDL_FreeSurface(backing); +} /////////////////////////////// @@ -608,6 +666,7 @@ enum { SHORTCUT_TOGGLE_SCANLINES, SHORTCUT_TOGGLE_FF, SHORTCUT_HOLD_FF, + SHORTCUT_TAKE_SCREENSHOT, SHORTCUT_COUNT, }; @@ -847,6 +906,7 @@ static struct Config { [SHORTCUT_TOGGLE_SCANLINES] = {"Toggle Scanlines", -1, BTN_ID_NONE, 0}, [SHORTCUT_TOGGLE_FF] = {"Toggle FF", -1, BTN_ID_NONE, 0}, [SHORTCUT_HOLD_FF] = {"Hold FF", -1, BTN_ID_NONE, 0}, + [SHORTCUT_TAKE_SCREENSHOT] = {"Take Screenshot", -1, BTN_ID_NONE, 0}, {NULL} }, }; @@ -1431,6 +1491,9 @@ static void input_poll_callback(void) { Config_syncFrontend(FE_OPT_SCANLINES, !show_scanlines); } break; + case SHORTCUT_TAKE_SCREENSHOT: + Take_screenshot(); + break; default: break; } @@ -3815,25 +3878,6 @@ static int Menu_options(MenuList* list) { return 0; } -static void downsample(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch) { - uint32_t ox = 0; - uint32_t oy = 0; - uint32_t ix = (w<<16) / FIXED_WIDTH; - uint32_t iy = (h<<16) / FIXED_HEIGHT; - - for (int y=0; y>16) * pitch; - uint16_t* restrict dst_row = (void*)dst + y * dst_pitch; - for (int x=0; x>16)); - dst_row += 1; - ox += ix; - } - ox = 0; - oy += iy; - } -} - static void Menu_loop(void) { // current screen is on the previous buffer @@ -3845,7 +3889,7 @@ static void Menu_loop(void) { SDL_BlitSurface(backing, NULL, snapshot, NULL); } else { - downsample(backing->pixels,snapshot->pixels,backing->w,backing->h,backing->pitch,snapshot->pitch); + Downsample(backing->pixels,snapshot->pixels,backing->w,backing->h,backing->pitch,snapshot->pitch); } int target_w = FIXED_WIDTH; // 640 * 480 / 720 rounded up to nearest 8