}
}
+ kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER34)];
+ for (i = 0; kbinds && me_ctrl_actions[i].name != NULL; i++) {
+ mask = me_ctrl_actions[i].mask;
+ if (mask & kbinds) {
+ strncpy(act, me_ctrl_actions[i].name, 31);
+ fprintf(f, "bind %s = player3 %s\n", name, mystrip(act));
+ kbinds &= ~mask;
+ }
+ mask = me_ctrl_actions[i].mask << 16;
+ if (mask & kbinds) {
+ strncpy(act, me_ctrl_actions[i].name, 31);
+ fprintf(f, "bind %s = player4 %s\n", name, mystrip(act));
+ kbinds &= ~mask;
+ }
+ }
+
kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)];
for (i = 0; kbinds && emuctrl_actions[i].name != NULL; i++) {
mask = emuctrl_actions[i].mask;
int player, shift = 0;
player = atoi(val + 6) - 1;
- if ((unsigned int)player > 1)
+ if ((unsigned int)player > 3)
return -1;
- if (player == 1)
+ if (player & 1)
shift = 16;
- *type = IN_BINDTYPE_PLAYER12;
+ *type = IN_BINDTYPE_PLAYER12 + (player >> 1);
for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0)
return me_ctrl_actions[i].mask << shift;
static EGLSurface esfc;
static EGLContext ectxt;
+static GLuint texture_name;
+
/* for external flips */
void *gl_es_display;
void *gl_es_surface;
+static int tex_w, tex_h;
+static void *tex_mem;
+
static int gl_have_error(const char *name)
{
GLenum e = glGetError();
return 0;
}
-int gl_init(void *display, void *window, int *quirks)
+int gl_init(void *display, void *window, int *quirks, int w, int h)
{
EGLConfig ecfg = NULL;
- GLuint texture_name = 0;
- void *tmp_texture_mem = NULL;
EGLint num_config;
int retval = -1;
int ret;
goto out;
}
- tmp_texture_mem = calloc(1, 1024 * 512 * 2);
- if (tmp_texture_mem == NULL) {
+ for (tex_w = 1; tex_w < w; tex_w *= 2);
+ for (tex_h = 1; tex_h < h; tex_h *= 2);
+ tex_mem = realloc(tex_mem, tex_w * tex_h * 2);
+ if (tex_mem == NULL) {
fprintf(stderr, "OOM\n");
goto out;
}
glEnable(GL_TEXTURE_2D);
+ if (texture_name)
+ glDeleteTextures(1, &texture_name);
+
glGenTextures(1, &texture_name);
glBindTexture(GL_TEXTURE_2D, texture_name);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, tmp_texture_mem);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_w, tex_h, 0, GL_RGB,
+ GL_UNSIGNED_SHORT_5_6_5, tex_mem);
if (gl_have_error("glTexImage2D"))
goto out;
gl_es_surface = (void *)esfc;
retval = 0;
out:
- free(tmp_texture_mem);
return retval;
}
if (fb != NULL) {
if (w != old_w || h != old_h) {
- float f_w = (float)w / 1024.0f;
- float f_h = (float)h / 512.0f;
+ float f_w = (float)w / tex_w;
+ float f_h = (float)h / tex_h;
texture[1*2 + 0] = f_w;
texture[2*2 + 1] = f_h;
texture[3*2 + 0] = f_w;
gl_es_display = (void *)edpy;
gl_es_surface = (void *)esfc;
+ if (tex_mem) free(tex_mem);
+ tex_mem = NULL;
+
gl_platform_finish();
}
#ifdef HAVE_GLES
-int gl_init(void *display, void *window, int *quirks);
+int gl_init(void *display, void *window, int *quirks, int w, int h);
void gl_announce(void);
int gl_flip(const void *fb, int w, int h);
void gl_finish(void);
#else
-static __inline int gl_init(void *display, void *window, int *quirks)
+static __inline int gl_init(void *display, void *window, int *quirks, int w, int h)
{
return -1;
}
SDL_Joystick *joy;
int joy_id;
int axis_keydown[2];
+#ifdef SDL_REDRAW_EVT
+ int rdraw;
+#endif
keybits_t keystate[SDLK_LAST / KEYBITS_WORD_BITS + 1];
// emulator keys should always be processed immediately lest one is lost
keybits_t emu_keys[SDLK_LAST / KEYBITS_WORD_BITS + 1];
*kc_out = event->key.keysym.sym;
if (down_out != NULL)
*down_out = event->type == SDL_KEYDOWN;
- if (emu_out != 0)
+ if (emu_out != NULL)
*emu_out = emu;
return 1;
{
SDL_Event events[4];
Uint32 mask = state->joy ? JOY_EVENTS : (SDL_ALLEVENTS & ~JOY_EVENTS);
- int count, maxcount, is_emukey;
+ int count, maxcount, is_emukey = 0;
int i, ret, retval = 0;
int num_events, num_peeped_events;
SDL_Event *event;
+#ifdef SDL_REDRAW_EVT
+ if (state->rdraw) {
+ if (one_kc != NULL)
+ *one_kc = SDLK_UNKNOWN;
+ if (one_down != NULL)
+ *one_down = 0;
+ state->rdraw = 0;
+ return 1;
+ }
+#endif
maxcount = (one_kc != NULL) ? 1 : sizeof(events) / sizeof(events[0]);
SDL_PumpEvents();
ext_event_handler(event);
break;
}
- continue;
+#ifdef SDL_REDRAW_EVT
+ if (ret != -2 && event->type == SDL_VIDEORESIZE) {
+ if (one_kc != NULL)
+ *one_kc = SDLK_UNKNOWN;
+ if (one_down != NULL)
+ *one_down = 1;
+ state->rdraw = 1;
+ is_emukey = 1, ret = 1;
+ } else
+ continue;
+#endif
}
retval |= ret;
- if ((is_emukey || one_kc != NULL) && ret)
+ if ((is_emukey || one_kc != NULL) && retval)
{
// don't lose events other devices might want to handle
if (++i < count)
}
else
{
+#ifdef SDL_REDRAW_EVT
+ if (keycode == SDLK_UNKNOWN)
+ ret = PBTN_RDRAW;
+ else
+#endif
for (i = 0; i < map_len; i++) {
if (map[i].key == keycode) {
ret = map[i].pbtn;
wait = autorep_delay_ms;
/* wait until either key repeat or a new key has been pressed */
+#ifdef SDL_REDRAW_EVT
+ interesting |= PBTN_RDRAW;
+#endif
do {
ret = in_menu_wait_any(charcode, wait);
if (ret == 0 || ret != menu_key_prev)
#define PBTN_MENU (1 << 10)
#define PBTN_CHAR (1 << 11) /* character (text input) */
+#define PBTN_RDRAW (1 << 12) /* redraw event */
// TODO: move to pico
#if 0
IN_BINDTYPE_NONE = -1,
IN_BINDTYPE_EMU = 0,
IN_BINDTYPE_PLAYER12,
+ IN_BINDTYPE_PLAYER34,
IN_BINDTYPE_COUNT
};
extern char **g_argv;
static struct disassemble_info di;
+static disassembler_ftype print_insn_func;
#if defined __arm__
#define print_insn_func print_insn_little_arm
#elif defined __mips__
#define print_insn_func print_insn_little_mips
#define BFD_ARCH bfd_arch_mips
-#define BFD_MACH bfd_mach_mipsisa32
+#define BFD_MACH bfd_mach_mipsisa64r2
#define DASM_OPTS NULL
#elif defined __riscv
-#define print_insn_func print_insn_riscv
+//#define print_insn_func print_insn_riscv
#define BFD_ARCH bfd_arch_riscv
#define BFD_MACH bfd_mach_riscv64
#define DASM_OPTS NULL
dis_asm_read_memory(bfd_vma memaddr, bfd_byte *myaddr, unsigned int len,
struct disassemble_info *info)
{
- memcpy(myaddr, (void *)(long)memaddr, len);
+ memcpy(myaddr, (void *)memaddr, len);
return 0;
}
return n;
}
+static int print_insn_hex(bfd_vma addr, struct disassemble_info *info)
+{
+ unsigned op;
+
+ dis_asm_read_memory(addr, (bfd_byte *)&op, 4, info);
+ printf("%p %08lx",(void *)addr, (long)op);
+ return 4;
+}
+
static void host_dasm_init(void)
{
bfd_init();
- slurp_symtab(g_argv[0]);
+ if (g_argv && g_argv[0])
+ slurp_symtab(g_argv[0]);
init_disassemble_info(&di, NULL, insn_printf);
di.flavour = bfd_target_unknown_flavour;
di.endian = BFD_ENDIAN_LITTLE;
di.disassembler_options = DASM_OPTS;
disassemble_init_for_target(&di);
+#ifndef print_insn_func
+ print_insn_func = disassembler(BFD_ARCH, 0, BFD_MACH, NULL);
+ if (!print_insn_func) print_insn_func = print_insn_hex;
+#endif
init_done = 1;
}
void host_dasm(void *addr, int len)
{
- bfd_vma vma_end, vma = (bfd_vma)(long)addr;
+ bfd_vma vma_end, vma = (bfd_vma)addr;
const char *name;
if (!init_done)
{
int ret = plat_get_exe_dir(dst, len);
if (ret < 0)
- return ret;
+ ret = 0;
memcpy(dst + ret, "skin/", sizeof "skin/");
return ret + sizeof("skin/") - 1;
{\r
int i;\r
\r
- sel++;\r
for (i = sel + 1; ; i++) {\r
if (i >= len)\r
- i = 1;\r
+ i = 0;\r
if (i == sel)\r
break;\r
\r
break;\r
}\r
\r
- return i - 1;\r
+ return i;\r
}\r
\r
static const char *menu_loop_romsel(char *curr_path, int len,\r
namelist[sel]->d_name);\r
goto rescan;\r
}\r
- if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-1; }\r
- if (inp & PBTN_DOWN) { sel++; if (sel > n-1) sel = 0; }\r
- if (inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; }\r
- if (inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; }\r
- if (inp & PBTN_RIGHT) { sel+=10; if (sel > n-1) sel = n-1; }\r
- if (inp & PBTN_R) { sel+=24; if (sel > n-1) sel = n-1; }\r
-\r
- if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2))\r
+ if (inp & PBTN_UP ) { sel--; if (sel < 0) sel = n-1; }\r
+ else if (inp & PBTN_DOWN) { sel++; if (sel > n-1) sel = 0; }\r
+ else if (inp & PBTN_LEFT) { sel-=10; if (sel < 0) sel = 0; }\r
+ else if (inp & PBTN_RIGHT) { sel+=10; if (sel > n-1) sel = n-1; }\r
+ else if (inp & PBTN_L) { sel-=24; if (sel < 0) sel = 0; }\r
+ else if (inp & PBTN_R) { sel+=24; if (sel > n-1) sel = n-1; }\r
+\r
+ else if ((inp & PBTN_MOK) || (inp & (PBTN_MENU|PBTN_MA2)) == (PBTN_MENU|PBTN_MA2))\r
{\r
if (namelist[sel]->d_type == DT_REG)\r
{\r
type = IN_BINDTYPE_EMU;\r
if (player_idx >= 0) {\r
can_combo = 0;\r
- type = IN_BINDTYPE_PLAYER12;\r
+ type = IN_BINDTYPE_PLAYER12 + (player_idx >> 1);\r
+ if (player_idx & 1)\r
+ action_mask <<= 16;\r
}\r
- if (player_idx == 1)\r
- action_mask <<= 16;\r
\r
if (dev_id >= 0)\r
dev = dev_last = dev_id;\r
\r
dev_id = -1; // show all\r
mask_shift = 0;\r
- if (player_idx == 1)\r
- mask_shift = 16;\r
- bindtype = player_idx >= 0 ? IN_BINDTYPE_PLAYER12 : IN_BINDTYPE_EMU;\r
+ if (player_idx >= 0) {\r
+ if (player_idx & 1)\r
+ mask_shift = 16;\r
+ bindtype = IN_BINDTYPE_PLAYER12 + (player_idx >> 1);\r
+ } else\r
+ bindtype = IN_BINDTYPE_EMU;\r
\r
for (;;)\r
{\r
void (*plat_sdl_quit_cb)(void);
static char vid_drv_name[32];
-static int window_w, window_h;
+static int window_w, window_h, window_b;
static int fs_w, fs_h;
static int old_fullscreen;
+static int screen_flags;
static int vout_mode_overlay = -1, vout_mode_overlay2x = -1, vout_mode_gl = -1;
static void *display, *window;
static int gl_quirks;
{
static int prev_w, prev_h;
+ // skip GL recreation if window doesn't change - avoids flicker
+ if (plat_target.vout_method == vout_mode_gl && plat_sdl_gl_active
+ && plat_target.vout_fullscreen == old_fullscreen
+ && w == prev_w && h == prev_h && !force)
+ {
+ return 0;
+ }
+
if (w == 0)
w = prev_w;
else
plat_target.vout_method = 0;
}
- // skip GL recreation if window doesn't change - avoids flicker
- if (plat_target.vout_method == vout_mode_gl && plat_sdl_gl_active
- && plat_target.vout_fullscreen == old_fullscreen && !force)
- {
- return 0;
- }
-
if (plat_sdl_overlay != NULL) {
SDL_FreeYUVOverlay(plat_sdl_overlay);
plat_sdl_overlay = NULL;
// (seen on r-pi)
SDL_PumpEvents();
- plat_sdl_screen = SDL_SetVideoMode(win_w, win_h, 0, flags);
+ if (!plat_sdl_screen || screen_flags != flags ||
+ plat_sdl_screen->w != win_w || plat_sdl_screen->h != win_h)
+ plat_sdl_screen = SDL_SetVideoMode(win_w, win_h, 0, flags);
+ screen_flags = flags;
if (plat_sdl_screen == NULL) {
fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
plat_target.vout_method = 0;
if (plat_target.vout_method == vout_mode_overlay
|| plat_target.vout_method == vout_mode_overlay2x) {
- int W = plat_target.vout_method == vout_mode_overlay2x && w == 320 ? 2*w : w;
+ int W = plat_target.vout_method == vout_mode_overlay2x && w < 640 ? 2*w : w;
plat_sdl_overlay = SDL_CreateYUVOverlay(W, h, SDL_UYVY_OVERLAY, plat_sdl_screen);
if (plat_sdl_overlay != NULL && SDL_LockYUVOverlay(plat_sdl_overlay) == 0) {
if ((long)plat_sdl_overlay->pixels[0] & 3)
}
}
else if (plat_target.vout_method == vout_mode_gl) {
- plat_sdl_gl_active = (gl_init(display, window, &gl_quirks) == 0);
+ int sw = plat_sdl_screen->w, sh = plat_sdl_screen->h;
+ plat_sdl_gl_active = (gl_init(display, window, &gl_quirks, sw, sh) == 0);
if (!plat_sdl_gl_active) {
fprintf(stderr, "warning: could not init GL.\n");
plat_target.vout_method = 0;
}
if (plat_target.vout_method == 0) {
- SDL_PumpEvents();
+ Uint32 flags;
+ int win_w = w;
+ int win_h = h;
#if defined SDL_SURFACE_SW
- plat_sdl_screen = SDL_SetVideoMode(w, h, 16, SDL_SWSURFACE);
+ flags = SDL_SWSURFACE;
#elif defined(SDL_TRIPLEBUF) && defined(SDL_BUFFER_3X)
- plat_sdl_screen = SDL_SetVideoMode(w, h, 16, SDL_HWSURFACE | SDL_TRIPLEBUF);
+ flags = SDL_HWSURFACE | SDL_TRIPLEBUF;
#else
- plat_sdl_screen = SDL_SetVideoMode(w, h, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
+ flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
#endif
+ if (plat_target.vout_fullscreen && fs_w && fs_h) {
+ flags |= SDL_FULLSCREEN;
+ win_w = fs_w;
+ win_h = fs_h;
+ }
+
+ SDL_PumpEvents();
+
+ if (!plat_sdl_screen || screen_flags != flags ||
+ plat_sdl_screen->w != win_w || plat_sdl_screen->h != win_h)
+ plat_sdl_screen = SDL_SetVideoMode(win_w, win_h, 16, flags);
+ screen_flags = flags;
if (plat_sdl_screen == NULL) {
fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
return -1;
if (plat_target.vout_method != 0
&& !plat_target.vout_fullscreen && !old_fullscreen)
{
- window_w = event->resize.w;
- window_h = event->resize.h;
+ window_w = event->resize.w & ~3;
+ window_h = event->resize.h & ~3;
plat_sdl_change_video_mode(0, 0, 1);
}
break;
}
else if (plat_sdl_gl_active) {
if (gl_quirks & GL_QUIRK_ACTIVATE_RECREATE) {
+ int sw = plat_sdl_screen->w, sh = plat_sdl_screen->h;
gl_finish();
- plat_sdl_gl_active = (gl_init(display, window, &gl_quirks) == 0);
+ plat_sdl_gl_active = (gl_init(display, window, &gl_quirks, sw, sh) == 0);
}
gl_flip(NULL, 0, 0);
}
if (info != NULL) {
fs_w = info->current_w;
fs_h = info->current_h;
+ if (info->wm_available)
+ window_b = WM_DECORATION_H;
printf("plat_sdl: using %dx%d as fullscreen resolution\n", fs_w, fs_h);
}
g_menuscreen_h = 480;
if (fs_h != 0) {
h = fs_h;
- if (info && info->wm_available && h > WM_DECORATION_H)
- h -= WM_DECORATION_H;
+ if (window_b && h > window_b)
+ h -= window_b;
if (g_menuscreen_h > h)
g_menuscreen_h = h;
}
- ret = plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, 1);
- if (ret != 0) {
+ plat_sdl_screen = SDL_SetVideoMode(g_menuscreen_w, g_menuscreen_h, 16, SDL_HWSURFACE);
+ if (plat_sdl_screen == NULL) {
plat_sdl_screen = SDL_SetVideoMode(0, 0, 16, SDL_SWSURFACE);
if (plat_sdl_screen == NULL) {
fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError());
if (env)
try_gl = atoi(env);
if (try_gl)
- ret = gl_init(display, window, &gl_quirks);
+ ret = gl_init(display, window, &gl_quirks, g_menuscreen_w, g_menuscreen_h);
if (ret == 0) {
gl_announce();
gl_works = 1;
int *dst = (int *)plat_sdl_overlay->pixels[0];
int v = 0x10801080;
- for (; pixels > 0; dst += 4, pixels -= 2 * 4)
+ for (; pixels > 7; dst += 4, pixels -= 2 * 4)
dst[0] = dst[1] = dst[2] = dst[3] = v;
- for (; pixels > 0; dst++, pixels -= 2)
+ for (; pixels > 1; dst++, pixels -= 2)
*dst = v;
}
#include <unistd.h>
#include <sys/stat.h>
+#ifndef DT_DIR
/* map PSP names to posix. needs special scandir() function to mask rwx bits */
#define d_type d_stat.st_attr
#define DT_LNK FIO_SO_IFLNK
#define DT_DIR FIO_SO_IFDIR
#define DT_REG FIO_SO_IFREG
#define DT_UNKNOWN 0
+#endif
#else