From 550233e1845c6996e1991d5e7a9a165b2d5cc3c1 Mon Sep 17 00:00:00 2001 From: Percentnineteen Date: Sun, 20 Aug 2023 17:51:12 -0500 Subject: [PATCH 1/6] snapshots? --- src/minarch/minarch.c | 83 +++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index 6f98a98..4955e60 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -463,7 +463,47 @@ static void State_read(void) { // from picoarch if (state) free(state); if (state_file) fclose(state_file); } +typedef struct __attribute__((__packed__)) uint24_t { + uint8_t a,b,c; +} uint24_t; +static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img) { + SDL_Surface* dst_img = SDL_CreateRGBSurface(0,FIXED_WIDTH/2, FIXED_HEIGHT/2,src_img->format->BitsPerPixel,src_img->format->Rmask,src_img->format->Gmask,src_img->format->Bmask,src_img->format->Amask); + + uint8_t* src_px = src_img->pixels; + uint8_t* dst_px = dst_img->pixels; + int step = dst_img->format->BytesPerPixel; + int step2 = step * 2; + int stride = src_img->pitch; + for (int y=0; yh; y++) { + for (int x=0; xw; x++) { + switch(step) { + case 1: + *dst_px = *src_px; + break; + case 2: + *(uint16_t*)dst_px = *(uint16_t*)src_px; + break; + case 3: + *(uint24_t*)dst_px = *(uint24_t*)src_px; + break; + case 4: + *(uint32_t*)dst_px = *(uint32_t*)src_px; + break; + } + dst_px += step; + src_px += step2; + } + src_px += stride; + } + + return dst_img; +} static void State_write(void) { // from picoarch + char bmp_path[256]; + char minui_dir[256]; + char emu_name[256]; + SDL_Surface* snapshot = SDL_CreateRGBSurface(SDL_SWSURFACE, FIXED_WIDTH,FIXED_HEIGHT,FIXED_DEPTH,0,0,0,0); + size_t state_size = core.serialize_size(); if (!state_size) return; @@ -492,6 +532,14 @@ static void State_write(void) { // from picoarch goto error; } + getEmuName(game.path, emu_name); + sprintf(minui_dir, USERDATA_PATH "/.minui/%s", emu_name); + sprintf(bmp_path, "%s/%s.%d.bmp", minui_dir, game.name, state_slot); + SDL_Surface* preview = Menu_thumbnail(snapshot); + SDL_RWops* out = SDL_RWFromFile(bmp_path, "wb"); + SDL_SaveBMP_RW(preview, out, 1); + SDL_FreeSurface(preview); + error: if (state) free(state); if (state_file) fclose(state_file); @@ -2977,41 +3025,6 @@ static struct { } }; -typedef struct __attribute__((__packed__)) uint24_t { - uint8_t a,b,c; -} uint24_t; -static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img) { - SDL_Surface* dst_img = SDL_CreateRGBSurface(0,FIXED_WIDTH/2, FIXED_HEIGHT/2,src_img->format->BitsPerPixel,src_img->format->Rmask,src_img->format->Gmask,src_img->format->Bmask,src_img->format->Amask); - - uint8_t* src_px = src_img->pixels; - uint8_t* dst_px = dst_img->pixels; - int step = dst_img->format->BytesPerPixel; - int step2 = step * 2; - int stride = src_img->pitch; - for (int y=0; yh; y++) { - for (int x=0; xw; x++) { - switch(step) { - case 1: - *dst_px = *src_px; - break; - case 2: - *(uint16_t*)dst_px = *(uint16_t*)src_px; - break; - case 3: - *(uint24_t*)dst_px = *(uint24_t*)src_px; - break; - case 4: - *(uint32_t*)dst_px = *(uint32_t*)src_px; - break; - } - dst_px += step; - src_px += step2; - } - src_px += stride; - } - - return dst_img; -} void Menu_init(void) { menu.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, FIXED_WIDTH, FIXED_HEIGHT, FIXED_DEPTH, 0, 0, 0, 0); From 9c3084f31eb37adc6e81b820f0700349b23ffce0 Mon Sep 17 00:00:00 2001 From: Percentnineteen Date: Sun, 20 Aug 2023 18:47:22 -0500 Subject: [PATCH 2/6] actually save screenshot --- src/minarch/minarch.c | 46 +++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index 4955e60..6d36436 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -498,11 +498,38 @@ static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img) { return dst_img; } + +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 State_write(void) { // from picoarch char bmp_path[256]; char minui_dir[256]; char emu_name[256]; + 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); + } size_t state_size = core.serialize_size(); if (!state_size) return; @@ -3812,25 +3839,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 From f4d2010a85a91f914e83bfe6550452f5ed67d352 Mon Sep 17 00:00:00 2001 From: Percentnineteen Date: Mon, 21 Aug 2023 23:16:18 -0500 Subject: [PATCH 3/6] create the m3u save files and stuff --- src/minarch/minarch.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index 6d36436..fdba3bd 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -520,6 +520,8 @@ static void downsample(void* __restrict src, void* __restrict dst, uint32_t w, u static void State_write(void) { // from picoarch char bmp_path[256]; + char slot_path[256]; + char txt_path[256]; char minui_dir[256]; char emu_name[256]; SDL_Surface* backing = GFX_getBufferCopy(); @@ -561,11 +563,21 @@ static void State_write(void) { // from picoarch getEmuName(game.path, emu_name); sprintf(minui_dir, USERDATA_PATH "/.minui/%s", emu_name); + sprintf(slot_path, "%s/%s.txt", minui_dir, game.name); sprintf(bmp_path, "%s/%s.%d.bmp", minui_dir, game.name, state_slot); SDL_Surface* preview = Menu_thumbnail(snapshot); SDL_RWops* out = SDL_RWFromFile(bmp_path, "wb"); + + if (exists(game.m3u_path)) { + char* tmp = strrchr(game.m3u_path, '/') + 1; + sprintf(txt_path, "%s/%s.%d.txt", minui_dir, tmp, state_slot); + tmp = strrchr(game.path, '/') + 1; + putFile(txt_path, tmp); + } + SDL_SaveBMP_RW(preview, out, 1); SDL_FreeSurface(preview); + putInt(slot_path, state_slot); error: if (state) free(state); From 05ee82b238874d8f87fff5b0938bda6044f03f67 Mon Sep 17 00:00:00 2001 From: Percentnineteen Date: Tue, 22 Aug 2023 17:38:51 -0500 Subject: [PATCH 4/6] more standardization of State_write --- src/minarch/minarch.c | 81 +++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index fdba3bd..2cb69b9 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -23,6 +23,43 @@ /////////////////////////////////////// +#define MENU_ITEM_COUNT 5 +#define MENU_SLOT_COUNT 8 + +enum { + ITEM_CONT, + ITEM_SAVE, + ITEM_LOAD, + ITEM_OPTS, + ITEM_QUIT, +}; + +enum { + STATUS_CONT = 0, + STATUS_SAVE = 1, + STATUS_LOAD = 11, + STATUS_OPTS = 23, + STATUS_DISC = 24, + STATUS_QUIT = 30 +}; + +static struct { + int initialized; + SDL_Surface* overlay; + char* items[MENU_ITEM_COUNT]; + int slot; +} menu = { + .items = { + [ITEM_CONT] = "Continue", + [ITEM_SAVE] = "Save", + [ITEM_LOAD] = "Load", + [ITEM_OPTS] = "Options", + [ITEM_QUIT] = "Quit", + } +}; + +/////////////////////////////////////// + static SDL_Surface* screen; static int quit; static int show_menu; @@ -577,6 +614,8 @@ static void State_write(void) { // from picoarch SDL_SaveBMP_RW(preview, out, 1); SDL_FreeSurface(preview); + SDL_FreeSurface(backing); + SDL_FreeSurface(snapshot); putInt(slot_path, state_slot); error: @@ -3027,42 +3066,6 @@ void Core_close(void) { if (core.handle) dlclose(core.handle); } -/////////////////////////////////////// - -#define MENU_ITEM_COUNT 5 -#define MENU_SLOT_COUNT 8 - -enum { - ITEM_CONT, - ITEM_SAVE, - ITEM_LOAD, - ITEM_OPTS, - ITEM_QUIT, -}; - -enum { - STATUS_CONT = 0, - STATUS_SAVE = 1, - STATUS_LOAD = 11, - STATUS_OPTS = 23, - STATUS_DISC = 24, - STATUS_QUIT = 30 -}; - -static struct { - int initialized; - SDL_Surface* overlay; - char* items[MENU_ITEM_COUNT]; - int slot; -} menu = { - .items = { - [ITEM_CONT] = "Continue", - [ITEM_SAVE] = "Save", - [ITEM_LOAD] = "Load", - [ITEM_OPTS] = "Options", - [ITEM_QUIT] = "Quit", - } -}; void Menu_init(void) { @@ -4040,14 +4043,8 @@ static void Menu_loop(void) { status = STATUS_SAVE; SDL_Surface* preview = Menu_thumbnail(snapshot); SDL_RWops* out = SDL_RWFromFile(bmp_path, "wb"); - if (total_discs) { - char* disc_path = disc_paths[disc]; - putFile(txt_path, disc_path + strlen(base_path)); - sprintf(bmp_path, "%s/%s.%d.bmp", minui_dir, game.name, menu.slot); - } SDL_SaveBMP_RW(preview, out, 1); SDL_FreeSurface(preview); - putInt(slot_path, menu.slot); show_menu = 0; } break; From 56194a3323bd854c6f0c7afbd50e4236f5af04b2 Mon Sep 17 00:00:00 2001 From: Percentnineteen Date: Fri, 25 Aug 2023 18:11:06 -0500 Subject: [PATCH 5/6] remove extra screenshot call --- src/minarch/minarch.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index 2cb69b9..d86a566 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -555,20 +555,27 @@ static void downsample(void* __restrict src, void* __restrict dst, uint32_t w, u } } -static void State_write(void) { // from picoarch +static void State_write(SDL_Surface* calling_s) { // from picoarch char bmp_path[256]; char slot_path[256]; char txt_path[256]; char minui_dir[256]; char emu_name[256]; - 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); - } + SDL_Surface* snapshot; + SDL_Surface* backing; + if (calling_s == screen) { + backing = GFX_getBufferCopy(); + 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); + } + } + else { + snapshot = calling_s; + } size_t state_size = core.serialize_size(); if (!state_size) return; @@ -614,8 +621,10 @@ static void State_write(void) { // from picoarch SDL_SaveBMP_RW(preview, out, 1); SDL_FreeSurface(preview); - SDL_FreeSurface(backing); - SDL_FreeSurface(snapshot); + if (calling_s == screen) { + SDL_FreeSurface(backing); + SDL_FreeSurface(snapshot); + } putInt(slot_path, state_slot); error: @@ -627,7 +636,7 @@ static void State_write(void) { // from picoarch static void State_autosave(void) { int last_state_slot = state_slot; state_slot = AUTO_RESUME_SLOT; - State_write(); + State_write(screen); state_slot = last_state_slot; } static void State_resume(void) { @@ -1526,7 +1535,7 @@ static void input_poll_callback(void) { } else if (PAD_justPressed(btn)) { switch (i) { - case SHORTCUT_SAVE_STATE: State_write(); break; + case SHORTCUT_SAVE_STATE: State_write(screen); break; case SHORTCUT_LOAD_STATE: State_read(); break; case SHORTCUT_RESET_GAME: core.reset(); break; case SHORTCUT_CYCLE_SCALE: @@ -4039,12 +4048,8 @@ static void Menu_loop(void) { case ITEM_SAVE: { state_slot = menu.slot; - State_write(); + State_write(snapshot); status = STATUS_SAVE; - SDL_Surface* preview = Menu_thumbnail(snapshot); - SDL_RWops* out = SDL_RWFromFile(bmp_path, "wb"); - SDL_SaveBMP_RW(preview, out, 1); - SDL_FreeSurface(preview); show_menu = 0; } break; From 9416307d0a0a01a197dc8692da8f7a829bf23b6a Mon Sep 17 00:00:00 2001 From: Percentnineteen Date: Fri, 25 Aug 2023 22:26:05 -0500 Subject: [PATCH 6/6] revert some changes in lieu of prototypes --- src/minarch/minarch.c | 182 +++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 90 deletions(-) diff --git a/src/minarch/minarch.c b/src/minarch/minarch.c index d86a566..9e80dfe 100644 --- a/src/minarch/minarch.c +++ b/src/minarch/minarch.c @@ -23,43 +23,6 @@ /////////////////////////////////////// -#define MENU_ITEM_COUNT 5 -#define MENU_SLOT_COUNT 8 - -enum { - ITEM_CONT, - ITEM_SAVE, - ITEM_LOAD, - ITEM_OPTS, - ITEM_QUIT, -}; - -enum { - STATUS_CONT = 0, - STATUS_SAVE = 1, - STATUS_LOAD = 11, - STATUS_OPTS = 23, - STATUS_DISC = 24, - STATUS_QUIT = 30 -}; - -static struct { - int initialized; - SDL_Surface* overlay; - char* items[MENU_ITEM_COUNT]; - int slot; -} menu = { - .items = { - [ITEM_CONT] = "Continue", - [ITEM_SAVE] = "Save", - [ITEM_LOAD] = "Load", - [ITEM_OPTS] = "Options", - [ITEM_QUIT] = "Quit", - } -}; - -/////////////////////////////////////// - static SDL_Surface* screen; static int quit; static int show_menu; @@ -500,60 +463,9 @@ static void State_read(void) { // from picoarch if (state) free(state); if (state_file) fclose(state_file); } -typedef struct __attribute__((__packed__)) uint24_t { - uint8_t a,b,c; -} uint24_t; -static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img) { - SDL_Surface* dst_img = SDL_CreateRGBSurface(0,FIXED_WIDTH/2, FIXED_HEIGHT/2,src_img->format->BitsPerPixel,src_img->format->Rmask,src_img->format->Gmask,src_img->format->Bmask,src_img->format->Amask); - - uint8_t* src_px = src_img->pixels; - uint8_t* dst_px = dst_img->pixels; - int step = dst_img->format->BytesPerPixel; - int step2 = step * 2; - int stride = src_img->pitch; - for (int y=0; yh; y++) { - for (int x=0; xw; x++) { - switch(step) { - case 1: - *dst_px = *src_px; - break; - case 2: - *(uint16_t*)dst_px = *(uint16_t*)src_px; - break; - case 3: - *(uint24_t*)dst_px = *(uint24_t*)src_px; - break; - case 4: - *(uint32_t*)dst_px = *(uint32_t*)src_px; - break; - } - dst_px += step; - src_px += step2; - } - src_px += stride; - } - - return dst_img; -} +static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img); -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 downsample(void* __restrict src, void* __restrict dst, uint32_t w, uint32_t h, uint32_t pitch, uint32_t dst_pitch); static void State_write(SDL_Surface* calling_s) { // from picoarch char bmp_path[256]; @@ -3075,7 +2987,78 @@ void Core_close(void) { if (core.handle) dlclose(core.handle); } +/////////////////////////////////////// + +#define MENU_ITEM_COUNT 5 +#define MENU_SLOT_COUNT 8 + +enum { + ITEM_CONT, + ITEM_SAVE, + ITEM_LOAD, + ITEM_OPTS, + ITEM_QUIT, +}; + +enum { + STATUS_CONT = 0, + STATUS_SAVE = 1, + STATUS_LOAD = 11, + STATUS_OPTS = 23, + STATUS_DISC = 24, + STATUS_QUIT = 30 +}; + +static struct { + int initialized; + SDL_Surface* overlay; + char* items[MENU_ITEM_COUNT]; + int slot; +} menu = { + .items = { + [ITEM_CONT] = "Continue", + [ITEM_SAVE] = "Save", + [ITEM_LOAD] = "Load", + [ITEM_OPTS] = "Options", + [ITEM_QUIT] = "Quit", + } +}; + +typedef struct __attribute__((__packed__)) uint24_t { + uint8_t a,b,c; +} uint24_t; +static SDL_Surface* Menu_thumbnail(SDL_Surface* src_img) { + SDL_Surface* dst_img = SDL_CreateRGBSurface(0,FIXED_WIDTH/2, FIXED_HEIGHT/2,src_img->format->BitsPerPixel,src_img->format->Rmask,src_img->format->Gmask,src_img->format->Bmask,src_img->format->Amask); + + uint8_t* src_px = src_img->pixels; + uint8_t* dst_px = dst_img->pixels; + int step = dst_img->format->BytesPerPixel; + int step2 = step * 2; + int stride = src_img->pitch; + for (int y=0; yh; y++) { + for (int x=0; xw; x++) { + switch(step) { + case 1: + *dst_px = *src_px; + break; + case 2: + *(uint16_t*)dst_px = *(uint16_t*)src_px; + break; + case 3: + *(uint24_t*)dst_px = *(uint24_t*)src_px; + break; + case 4: + *(uint32_t*)dst_px = *(uint32_t*)src_px; + break; + } + dst_px += step; + src_px += step2; + } + src_px += stride; + } + return dst_img; +} void Menu_init(void) { menu.overlay = SDL_CreateRGBSurface(SDL_SWSURFACE, FIXED_WIDTH, FIXED_HEIGHT, FIXED_DEPTH, 0, 0, 0, 0); @@ -3863,6 +3846,25 @@ 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