Added support for saving screenshot of game using a user-defined shortcut

This commit is contained in:
Mauro Vietri 2023-05-30 11:44:04 -03:00
parent 14ba4e0d91
commit 0f34d709e4
5 changed files with 77 additions and 23 deletions

View file

@ -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_DOT!=find ./releases/. -regex ".*/$(RELEASE_BASE)-[0-9]+-base\.zip" -printf '.' | wc -m
RELEASE_NAME=$(RELEASE_BASE)-$(RELEASE_DOT) 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 # 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 all: lib sys all-cores tools bundle readmes zip report
@ -102,14 +106,14 @@ zip:
cd ./build/PAYLOAD && zip -r MinUI.zip .system cd ./build/PAYLOAD && zip -r MinUI.zip .system
mv ./build/PAYLOAD/MinUI.zip ./build/BASE 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/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 Tools README.txt cd ./build/EXTRAS && zip -r ../../releases/$(RELEASE_NAME)-extras.zip Bios Emus Roms Saves Screenshots Tools README.txt
rm -fr ./build/FULL rm -fr ./build/FULL
mkdir ./build/FULL mkdir ./build/FULL
cp -fR ./build/BASE/* ./build/FULL/ cp -fR ./build/BASE/* ./build/FULL/
cp -fR ./build/EXTRAS/* ./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 echo "$(RELEASE_NAME)" > ./build/latest.txt

View file

@ -68,6 +68,10 @@ Reduce/increase brightness:
MENU + VOLUME UP or VOLUME DOWN MENU + VOLUME UP or VOLUME DOWN
Add/remove Favorites (from menu):
SELECT
The remaining emulation shortcuts are all user defined. The remaining emulation shortcuts are all user defined.
---------------------------------------- ----------------------------------------

View file

@ -7,6 +7,7 @@ export SYSTEM_PATH="$SDCARD_PATH/.system/rg35xx"
export CORES_PATH="$SYSTEM_PATH/cores" export CORES_PATH="$SYSTEM_PATH/cores"
export USERDATA_PATH="$SDCARD_PATH/.userdata/rg35xx" export USERDATA_PATH="$SDCARD_PATH/.userdata/rg35xx"
export LOGS_PATH="$USERDATA_PATH/logs" export LOGS_PATH="$USERDATA_PATH/logs"
export SCREENSHOTS_PATH="$SDCARD_PATH/Screenshots"
####################################### #######################################

View file

@ -60,6 +60,7 @@
#define FAUX_FAVORITE_PATH SDCARD_PATH "/Favorites" #define FAUX_FAVORITE_PATH SDCARD_PATH "/Favorites"
#define COLLECTIONS_PATH SDCARD_PATH "/Collections" #define COLLECTIONS_PATH SDCARD_PATH "/Collections"
#define BATTERY_PATH SDCARD_PATH "/battery.txt" #define BATTERY_PATH SDCARD_PATH "/battery.txt"
#define SCREENSHOTS_PATH SDCARD_PATH "/Screenshots"
#define LAST_PATH "/tmp/last.txt" // transient #define LAST_PATH "/tmp/last.txt" // transient
#define CHANGE_DISC_PATH "/tmp/change_disc.txt" #define CHANGE_DISC_PATH "/tmp/change_disc.txt"

View file

@ -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<FIXED_HEIGHT; y++) {
uint16_t* restrict src_row = (void*)src + (oy>>16) * pitch;
uint16_t* restrict dst_row = (void*)dst + y * dst_pitch;
for (int x=0; x<FIXED_WIDTH; x++) {
*dst_row = *(src_row + (ox>>16));
dst_row += 1;
ox += ix;
}
ox = 0;
oy += iy;
}
}
static int state_slot = 0; static int state_slot = 0;
static void State_getPath(char* filename) { static void State_getPath(char* filename) {
sprintf(filename, "%s/%s.st%i", core.config_dir, game.name, state_slot); 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_read();
state_slot = last_state_slot; 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(&currentTime);
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_SCANLINES,
SHORTCUT_TOGGLE_FF, SHORTCUT_TOGGLE_FF,
SHORTCUT_HOLD_FF, SHORTCUT_HOLD_FF,
SHORTCUT_TAKE_SCREENSHOT,
SHORTCUT_COUNT, SHORTCUT_COUNT,
}; };
@ -847,6 +906,7 @@ static struct Config {
[SHORTCUT_TOGGLE_SCANLINES] = {"Toggle Scanlines", -1, BTN_ID_NONE, 0}, [SHORTCUT_TOGGLE_SCANLINES] = {"Toggle Scanlines", -1, BTN_ID_NONE, 0},
[SHORTCUT_TOGGLE_FF] = {"Toggle FF", -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_HOLD_FF] = {"Hold FF", -1, BTN_ID_NONE, 0},
[SHORTCUT_TAKE_SCREENSHOT] = {"Take Screenshot", -1, BTN_ID_NONE, 0},
{NULL} {NULL}
}, },
}; };
@ -1431,6 +1491,9 @@ static void input_poll_callback(void) {
Config_syncFrontend(FE_OPT_SCANLINES, !show_scanlines); Config_syncFrontend(FE_OPT_SCANLINES, !show_scanlines);
} }
break; break;
case SHORTCUT_TAKE_SCREENSHOT:
Take_screenshot();
break;
default: break; default: break;
} }
@ -3815,25 +3878,6 @@ static int Menu_options(MenuList* list) {
return 0; 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<FIXED_HEIGHT; y++) {
uint16_t* restrict src_row = (void*)src + (oy>>16) * pitch;
uint16_t* restrict dst_row = (void*)dst + y * dst_pitch;
for (int x=0; x<FIXED_WIDTH; x++) {
*dst_row = *(src_row + (ox>>16));
dst_row += 1;
ox += ix;
}
ox = 0;
oy += iy;
}
}
static void Menu_loop(void) { static void Menu_loop(void) {
// current screen is on the previous buffer // current screen is on the previous buffer
@ -3845,7 +3889,7 @@ static void Menu_loop(void) {
SDL_BlitSurface(backing, NULL, snapshot, NULL); SDL_BlitSurface(backing, NULL, snapshot, NULL);
} }
else { 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 int target_w = FIXED_WIDTH; // 640 * 480 / 720 rounded up to nearest 8