From bcd4da9b1d59f903cf1ff27befbbcb82c2a26f5c Mon Sep 17 00:00:00 2001 From: kub Date: Fri, 22 Mar 2024 23:37:13 +0100 Subject: [PATCH] platform linux, revisit Pico pad/overlay handling --- platform/common/emu.c | 87 ++++++++++++++++++++++----- platform/common/emu.h | 2 + platform/common/input_pico.h | 12 ++-- platform/common/inputmap_kbd.c | 6 +- platform/common/menu_pico.c | 6 +- platform/linux/emu.c | 106 ++++++++------------------------- platform/pandora/plat.c | 6 +- 7 files changed, 114 insertions(+), 111 deletions(-) diff --git a/platform/common/emu.c b/platform/common/emu.c index d576b4398..167d70ceb 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -19,6 +19,7 @@ #include "../libpicofe/fonts.h" #include "../libpicofe/sndout.h" #include "../libpicofe/lprintf.h" +#include "../libpicofe/readpng.h" #include "../libpicofe/plat.h" #include "emu.h" #include "input_pico.h" @@ -1041,19 +1042,54 @@ void emu_reset_game(void) reset_timing = 1; } -void run_events_pico(unsigned int events) +static int pico_page; +static int pico_w, pico_h; +static u16 *pico_overlay; + +unsigned short *emu_load_pico_overlay(int page, int w, int h) { - if (events & PEV_PICO_SWINP) { - pico_inp_mode++; - if (pico_inp_mode > 2) - pico_inp_mode = 0; - switch (pico_inp_mode) { - case 2: emu_status_msg("Input: Pen on Pad"); break; - case 1: emu_status_msg("Input: Pen on Storyware"); break; - case 0: emu_status_msg("Input: Joystick"); break; + static const char *pic_exts[] = { "png", "PNG" }; + char *ext, *fname = NULL; + int extpos, i; + + if (pico_page == page && pico_w == w && pico_h == h) + return pico_overlay; + pico_page = page; + pico_w = w, pico_h = h; + + ext = strrchr(rom_fname_loaded, '.'); + extpos = ext ? ext-rom_fname_loaded : strlen(rom_fname_loaded); + strcpy(static_buff, rom_fname_loaded); + static_buff[extpos++] = '_'; + if (page < 0) { + 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); + fname = static_buff; + break; } - PicoPicohw.pen_pos[0] = PicoPicohw.pen_pos[1] = 0x8000; } + + pico_overlay = realloc(pico_overlay, w*h*2); + if (!fname || readpng(pico_overlay, fname, READPNG_SCALE, w, h)) { + if (pico_overlay) + free(pico_overlay); + pico_overlay = NULL; + } + + return pico_overlay; +} + +void run_events_pico(unsigned int events) +{ if (events & PEV_PICO_PPREV) { PicoPicohw.page--; if (PicoPicohw.page < 0) @@ -1066,16 +1102,39 @@ void run_events_pico(unsigned int events) PicoPicohw.page = 6; emu_status_msg("Page %i", PicoPicohw.page); } - if (events & PEV_PICO_SHPEN) { - currentConfig.EmuOpt ^= EOPT_PICO_PEN; - emu_status_msg("%s Pen", currentConfig.EmuOpt & EOPT_PICO_PEN ? "Show" : "Hide"); + if (events & PEV_PICO_STORY) { + if (pico_inp_mode == 1) { + pico_inp_mode = 0; + currentConfig.EmuOpt &= ~EOPT_PICO_PEN; + emu_status_msg("Input: Joystick"); + } else { + pico_inp_mode = 1; + currentConfig.EmuOpt |= EOPT_PICO_PEN; + emu_status_msg("Input: Pen on Storyware"); + } + } + if (events & PEV_PICO_PAD) { + if (pico_inp_mode == 2) { + pico_inp_mode = 0; + currentConfig.EmuOpt &= ~EOPT_PICO_PEN; + emu_status_msg("Input: Joystick"); + } else { + pico_inp_mode = 2; + currentConfig.EmuOpt |= EOPT_PICO_PEN; + emu_status_msg("Input: Pen on Pad"); + } } - if (events & PEV_PICO_PPOSV) { + if (events & PEV_PICO_PENON) { PicoPicohw.pen_pos[0] ^= 0x8000; PicoPicohw.pen_pos[1] ^= 0x8000; emu_status_msg("Pen %s", PicoPicohw.pen_pos[0] & 0x8000 ? "Up" : "Down"); } + if ((PicoIn.pad[0]&0x20) && pico_inp_mode && pico_overlay) { + pico_inp_mode = 0; + currentConfig.EmuOpt &= ~EOPT_PICO_PEN; + emu_status_msg("Input: Joystick"); + } if (pico_inp_mode == 0) return; diff --git a/platform/common/emu.h b/platform/common/emu.h index 959ce0b55..2d5b8f8c3 100644 --- a/platform/common/emu.h +++ b/platform/common/emu.h @@ -160,6 +160,8 @@ void emu_get_game_name(char *str150); void emu_set_fastforward(int set_on); void emu_status_msg(const char *format, ...); +unsigned short *emu_load_pico_overlay(int page, int width, int height); + /* default sound code */ void emu_sound_start(void); void emu_sound_stop(void); diff --git a/platform/common/input_pico.h b/platform/common/input_pico.h index 10d651181..a74e95a97 100644 --- a/platform/common/input_pico.h +++ b/platform/common/input_pico.h @@ -27,9 +27,9 @@ #define PEVB_FF 22 #define PEVB_PICO_PNEXT 21 #define PEVB_PICO_PPREV 20 -#define PEVB_PICO_SWINP 19 -#define PEVB_PICO_SHPEN 18 -#define PEVB_PICO_PPOSV 17 +#define PEVB_PICO_STORY 19 +#define PEVB_PICO_PAD 18 +#define PEVB_PICO_PENON 17 #define PEVB_RESET 16 #define PEV_VOL_DOWN (1 << PEVB_VOL_DOWN) @@ -43,9 +43,9 @@ #define PEV_FF (1 << PEVB_FF) #define PEV_PICO_PNEXT (1 << PEVB_PICO_PNEXT) #define PEV_PICO_PPREV (1 << PEVB_PICO_PPREV) -#define PEV_PICO_SWINP (1 << PEVB_PICO_SWINP) -#define PEV_PICO_SHPEN (1 << PEVB_PICO_SHPEN) -#define PEV_PICO_PPOSV (1 << PEVB_PICO_PPOSV) +#define PEV_PICO_STORY (1 << PEVB_PICO_STORY) +#define PEV_PICO_PAD (1 << PEVB_PICO_PAD) +#define PEV_PICO_PENON (1 << PEVB_PICO_PENON) #define PEV_RESET (1 << PEVB_RESET) #define PEV_MASK 0x7fff0000 diff --git a/platform/common/inputmap_kbd.c b/platform/common/inputmap_kbd.c index 821a8ee02..5dcacbdd5 100644 --- a/platform/common/inputmap_kbd.c +++ b/platform/common/inputmap_kbd.c @@ -29,9 +29,9 @@ const struct in_default_bind in_sdl_defbinds[] = { { SDLK_F5, IN_BINDTYPE_EMU, PEVB_SWITCH_RND }, { SDLK_F6, IN_BINDTYPE_EMU, PEVB_PICO_PPREV }, { SDLK_F7, IN_BINDTYPE_EMU, PEVB_PICO_PNEXT }, - { SDLK_F8, IN_BINDTYPE_EMU, PEVB_PICO_SWINP }, - { SDLK_F9, IN_BINDTYPE_EMU, PEVB_PICO_SHPEN }, - { SDLK_F10, IN_BINDTYPE_EMU, PEVB_PICO_PPOSV }, + { SDLK_F8, IN_BINDTYPE_EMU, PEVB_PICO_STORY }, + { SDLK_F9, IN_BINDTYPE_EMU, PEVB_PICO_PAD }, + { SDLK_F10, IN_BINDTYPE_EMU, PEVB_PICO_PENON }, { SDLK_BACKSPACE, IN_BINDTYPE_EMU, PEVB_FF }, { 0, 0, 0 } }; diff --git a/platform/common/menu_pico.c b/platform/common/menu_pico.c index ffd916121..9f305651c 100644 --- a/platform/common/menu_pico.c +++ b/platform/common/menu_pico.c @@ -361,9 +361,9 @@ me_bind_action emuctrl_actions[] = { "Enter Menu ", PEV_MENU }, { "Pico Next page ", PEV_PICO_PNEXT }, { "Pico Prev page ", PEV_PICO_PPREV }, - { "Pico Switch input", PEV_PICO_SWINP }, - { "Pico Pen sensor ", PEV_PICO_PPOSV }, - { "Pico Show pen ", PEV_PICO_SHPEN }, + { "Pico Storyware ", PEV_PICO_STORY }, + { "Pico Pad ", PEV_PICO_PAD }, + { "Pico Pen sensor ", PEV_PICO_PENON }, { NULL, 0 } }; diff --git a/platform/linux/emu.c b/platform/linux/emu.c index dbf24a857..785fe51d9 100644 --- a/platform/linux/emu.c +++ b/platform/linux/emu.c @@ -11,7 +11,6 @@ #include #include "../libpicofe/menu.h" -#include "../libpicofe/readpng.h" #include "../libpicofe/plat.h" #include "../common/emu.h" #include "../common/arm_utils.h" @@ -101,9 +100,10 @@ static void draw_pico_ptr(void) 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] ^= _; - p[-1] ^= o; p[0] ^= o; p[1] ^= o; - p[pitch-1] ^= _; p[pitch] ^= o; p[pitch+1] ^= _; + p[-pitch-1] ^= o; p[-pitch] ^= _; p[-pitch+1] ^= _; p[-pitch+2] ^= o; + p[-1] ^= _; p[0] ^= o; p[1] ^= o; p[2] ^= _; + p[pitch-1] ^= _; p[pitch] ^= o; p[pitch+1] ^= o; p[pitch+2] ^= _; + p[2*pitch-1]^= o; p[2*pitch]^= _; p[2*pitch+1]^= _; p[2*pitch+2]^= o; } /* render/screen buffer handling: @@ -176,38 +176,6 @@ 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()) { @@ -246,50 +214,31 @@ void pemu_finalize_frame(const char *fps, const char *notice) } 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; - } - 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; + u16 *overlay; + + if (pico_inp_mode == 1) { + h = (w/2 < h ? w/2 : h); // storyware has squished h + overlay = emu_load_pico_overlay(PicoPicohw.page, w, h); + } else if (pico_inp_mode == 2) + overlay = emu_load_pico_overlay(-1, w, h); + + // copy overlay onto buffer + if (pico_inp_mode && (currentConfig.EmuOpt & EOPT_PICO_PEN)) { + if (overlay) { + u16 *pd = screen_buffer(g_screen_ptr) + + out_y*g_screen_ppitch + out_x; + + for (y = 0; y < h && y < out_h; y++) + memcpy(pd + y*g_screen_ppitch, overlay + y*w, w*2); + if (y < out_h) + memset(pd + y*g_screen_ppitch, 0, w*2); } - pico_page = -1; - } - // copy image onto buffer - if (currentConfig.EmuOpt & EOPT_PICO_PEN) { - if (pico_inp_mode == 1 && pico_pagebuf) { - for (y = 0; y < w/2; y++) - memcpy(pd + w*y, pico_pagebuf + w*y, w*2); - memset(pd + w*y++, 0, 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) - draw_pico_ptr(); + draw_pico_ptr(); } } + if (notice) emu_osd_text16(4, g_screen_height - 8, notice); if (currentConfig.EmuOpt & EOPT_SHOW_FPS) @@ -526,9 +475,6 @@ 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); @@ -553,10 +499,6 @@ 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) diff --git a/platform/pandora/plat.c b/platform/pandora/plat.c index 32177ace8..d8e21e564 100644 --- a/platform/pandora/plat.c +++ b/platform/pandora/plat.c @@ -75,9 +75,9 @@ static struct in_default_bind in_evdev_defbinds[] = { KEY_4, IN_BINDTYPE_EMU, PEVB_SSLOT_NEXT }, { KEY_5, IN_BINDTYPE_EMU, PEVB_PICO_PPREV }, { KEY_6, IN_BINDTYPE_EMU, PEVB_PICO_PNEXT }, - { KEY_7, IN_BINDTYPE_EMU, PEVB_PICO_SWINP }, - { KEY_8, IN_BINDTYPE_EMU, PEVB_PICO_SHPEN }, - { KEY_9, IN_BINDTYPE_EMU, PEVB_PICO_PPOSV }, + { KEY_7, IN_BINDTYPE_EMU, PEVB_PICO_STORY }, + { KEY_8, IN_BINDTYPE_EMU, PEVB_PICO_PAD }, + { KEY_9, IN_BINDTYPE_EMU, PEVB_PICO_PENON }, { 0, 0, 0 } };