From e9f7e47dc72b91d9a00c6e3c98783bae90efd8dd Mon Sep 17 00:00:00 2001 From: kub Date: Wed, 20 Mar 2024 23:43:10 +0100 Subject: [PATCH] platform linux, display pad overlay and storyware pages for Pico --- pico/pico/pico.c | 3 +- platform/libpicofe | 2 +- platform/linux/emu.c | 90 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 6 deletions(-) diff --git a/pico/pico/pico.c b/pico/pico/pico.c index 99f21f4a2..94c80f203 100644 --- a/pico/pico/pico.c +++ b/pico/pico/pico.c @@ -60,6 +60,5 @@ PICO_INTERNAL void PicoInitPico(void) PicoIn.AHW = PAHW_PICO; memset(&PicoPicohw, 0, sizeof(PicoPicohw)); - PicoPicohw.pen_pos[0] = 0x03c + 320/2; - PicoPicohw.pen_pos[1] = 0x200 + 240/2; + PicoPicohw.pen_pos[0] = PicoPicohw.pen_pos[1] = 0x8000; } diff --git a/platform/libpicofe b/platform/libpicofe index 82b485477..4563c1316 160000 --- a/platform/libpicofe +++ b/platform/libpicofe @@ -1 +1 @@ -Subproject commit 82b4854771302e23201de274eee2969fc28be8be +Subproject commit 4563c13167deb97851397789bf2fb95bb44cf1ed diff --git a/platform/linux/emu.c b/platform/linux/emu.c index ba384ba40..356ccd8d1 100644 --- a/platform/linux/emu.c +++ b/platform/linux/emu.c @@ -11,6 +11,7 @@ #include #include "../libpicofe/menu.h" +#include "../libpicofe/readpng.h" #include "../libpicofe/plat.h" #include "../common/emu.h" #include "../common/arm_utils.h" @@ -92,9 +93,12 @@ static void draw_pico_ptr(void) int pitch = g_screen_ppitch; u16 *p = g_screen_ptr; int x = pico_pen_x, y = pico_pen_y; + // storyware pages are actually squished, 2:1 + u64 h = (pico_inp_mode == 1 ? 160 : out_h); + if (h < 224) y++; x = (x * out_w * ((1ULL<<32) / 320 + 1)) >> 32; - y = (y * out_h * ((1ULL<<32) / 224 + 1)) >> 32; + y = (y * h * ((1ULL<<32) / 224 + 1)) >> 32; p += (screen_y+y)*pitch + (screen_x+x); p[-pitch-1] ^= _; p[-pitch] ^= o; p[-pitch+1] ^= _; @@ -172,6 +176,38 @@ void screen_blit(u16 *pd, int pp, u8* ps, int ss, u16 *pal) upscale[currentConfig.filter & 0x3](pd, pp, ps, ss, out_w, out_h, pal); } +static int pico_page; +static u16 *pico_pagebuf; + +static const char *pic_exts[] = { "png", "PNG" }; +static char static_buff[512]; + +char *find_pico_file() +{ + char *ext = strrchr(rom_fname_loaded, '.'); + int extpos = ext ? ext-rom_fname_loaded : strlen(rom_fname_loaded); + int i; + + strcpy(static_buff, rom_fname_loaded); + static_buff[extpos++] = '_'; + if (pico_inp_mode == 2) { + static_buff[extpos++] = 'p'; + static_buff[extpos++] = 'a'; + static_buff[extpos++] = 'd'; + } else + static_buff[extpos++] = '0'+PicoPicohw.page; + static_buff[extpos++] = '.'; + + for (i = 0; i < ARRAY_SIZE(pic_exts); i++) { + strcpy(static_buff+extpos, pic_exts[i]); + if (access(static_buff, R_OK) == 0) { + printf("found Pico file: %s\n", static_buff); + return static_buff; + } + } + return NULL; +} + void pemu_finalize_frame(const char *fps, const char *notice) { if (!is_16bit_mode()) { @@ -194,6 +230,7 @@ void pemu_finalize_frame(const char *fps, const char *notice) u16 *ps = ghost_buf; int y, h = currentConfig.vscaling == EOPT_SCALE_SW ? 240:out_h; int w = currentConfig.scaling == EOPT_SCALE_SW ? 320:out_w; + if (currentConfig.ghosting == 1) for (y = 0; y < h; y++) { v_blend((u32 *)pd, (u32 *)ps, w/2, p_075_round); @@ -208,8 +245,48 @@ void pemu_finalize_frame(const char *fps, const char *notice) } } - if ((PicoIn.AHW & PAHW_PICO) && (currentConfig.EmuOpt & EOPT_PICO_PEN)) - if (pico_inp_mode) draw_pico_ptr(); + if (PicoIn.AHW & PAHW_PICO) { + u16 *pd = screen_buffer(g_screen_ptr) + + out_y * g_screen_ppitch + out_x; + int y, h = currentConfig.vscaling == EOPT_SCALE_SW ? 240:out_h; + int w = currentConfig.scaling == EOPT_SCALE_SW ? 320:out_w; + + if (pico_inp_mode == 1 && pico_page != PicoPicohw.page) { + char *fname = find_pico_file(); + pico_pagebuf = realloc(pico_pagebuf, 320*160*2); + memset(pico_pagebuf, 0, 320*160*2); + if (!fname || + readpng(pico_pagebuf, fname, READPNG_SCALE, w, w/2)) { + if (pico_pagebuf) + free(pico_pagebuf); + pico_pagebuf = NULL; + } else { + pico_page = PicoPicohw.page; + } + } + if (pico_inp_mode == 2 && pico_page != -1) { + char *fname = find_pico_file(); + pico_pagebuf = realloc(pico_pagebuf, 320*240*2); + memset(pico_pagebuf, 0, 320*240*2); + if (!fname || + readpng(pico_pagebuf, fname, READPNG_SCALE, w, h)) { + if (pico_pagebuf) + free(pico_pagebuf); + pico_pagebuf = NULL; + } else + pico_page = -1; + } + // copy image onto buffer + if (pico_inp_mode == 1 && pico_pagebuf) + for (y = 0; y < w/2; y++) + memcpy(pd + w*y, pico_pagebuf + w*y, w*2); + if (pico_inp_mode == 2 && pico_pagebuf) + for (y = 0; y < h; y++) + memcpy(pd + w*y, pico_pagebuf + w*y, w*2); + + if (pico_inp_mode && (currentConfig.EmuOpt & EOPT_PICO_PEN)) + draw_pico_ptr(); + } if (notice) emu_osd_text16(4, g_screen_height - 8, notice); if (currentConfig.EmuOpt & EOPT_SHOW_FPS) @@ -446,6 +523,9 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co memset(ghost_buf, 0, w * h * 2); } + free(pico_pagebuf); + pico_pagebuf = NULL; + // clear whole screen in all buffers if (!is_16bit_mode()) memset32(Pico.est.Draw2FB, 0xe0e0e0e0, (320+8) * (8+240+8) / 4); @@ -470,6 +550,10 @@ void pemu_loop_end(void) free(ghost_buf); ghost_buf = NULL; } + if (pico_pagebuf) { + free(pico_pagebuf); + pico_pagebuf = NULL; + } } void plat_wait_till_us(unsigned int us_to)