X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=frontend%2Fplugin_lib.c;h=ab4d4152eb6309a98057b9de590ea1f94c2f40e8;hp=159da702c8caa90c9eb6cc6300d747250042c632;hb=HEAD;hpb=2f70bda7011efe14e8e689cab687cf00b9fdfe7c diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c index 159da702..324fede5 100644 --- a/frontend/plugin_lib.c +++ b/frontend/plugin_lib.c @@ -34,6 +34,9 @@ #include "../libpcsxcore/new_dynarec/new_dynarec.h" #include "../libpcsxcore/psxmem_map.h" #include "../libpcsxcore/gpu.h" +#include "../libpcsxcore/r3000a.h" +#include "../libpcsxcore/psxcounters.h" +#include "arm_features.h" #define HUD_HEIGHT 10 @@ -42,17 +45,22 @@ int multitap1; int multitap2; int in_analog_left[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }}; int in_analog_right[8][2] = {{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 },{ 127, 127 }}; -int in_adev[2] = { -1, -1 }, in_adev_axis[2][2] = {{ 0, 1 }, { 0, 1 }}; +int in_adev[2] = { -1, -1 }; +int in_adev_axis[2][2] = +#ifdef PANDORA + {{ 0, 1 }, { 0, 1 }}; +#else + {{ 0, 1 }, { 2, 3 }}; +#endif int in_adev_is_nublike[2]; unsigned short in_keystate[8]; int in_mouse[8][2]; -int in_state_gun; int in_enable_vibration; void *tsdev; void *pl_vout_buf; int g_layer_x, g_layer_y, g_layer_w, g_layer_h; static int pl_vout_w, pl_vout_h, pl_vout_bpp; /* output display/layer */ -static int pl_vout_scale_w, pl_vout_scale_h, pl_vout_yoffset; +static int pl_vout_scale_w, pl_vout_scale_h; static int psx_w, psx_h, psx_bpp; static int vsync_cnt; static int is_pal, frame_interval, frame_interval1024; @@ -176,7 +184,7 @@ static void print_hud(int x, int w, int h) } /* update scaler target size according to user settings */ -static void update_layer_size(int w, int h) +void pl_update_layer_size(int w, int h, int fw, int fh) { float mult; int imult; @@ -188,51 +196,57 @@ static void update_layer_size(int w, int h) case SCALE_2_2: g_layer_w = w; g_layer_h = h; - if (w * 2 <= g_menuscreen_w) + if (w * 2 <= fw) g_layer_w = w * 2; - if (h * 2 <= g_menuscreen_h) + if (h * 2 <= fh) g_layer_h = h * 2; break; case SCALE_4_3v2: - if (h > g_menuscreen_h || (240 < h && h <= 360)) - goto fractional_4_3; +#ifdef PANDORA + if (h <= fh && !(240 < h && h <= 360)) + { +#endif // 4:3 that prefers integer scaling - imult = g_menuscreen_h / h; + imult = fh / h; + if (imult < 1) + imult = 1; g_layer_w = w * imult; g_layer_h = h * imult; mult = (float)g_layer_w / (float)g_layer_h; if (mult < 1.25f || mult > 1.666f) g_layer_w = 4.0f/3.0f * (float)g_layer_h; - printf(" -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult); + //printf(" -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult); break; +#ifdef PANDORA + } +#endif - fractional_4_3: case SCALE_4_3: mult = 240.0f / (float)h * 4.0f / 3.0f; if (h > 256) mult *= 2.0f; - g_layer_w = mult * (float)g_menuscreen_h; - g_layer_h = g_menuscreen_h; - printf(" -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult); + g_layer_w = mult * (float)fh; + g_layer_h = fh; + //printf(" -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult); break; case SCALE_FULLSCREEN: - g_layer_w = g_menuscreen_w; - g_layer_h = g_menuscreen_h; + g_layer_w = fw; + g_layer_h = fh; break; default: break; } - g_layer_x = g_menuscreen_w / 2 - g_layer_w / 2; - g_layer_y = g_menuscreen_h / 2 - g_layer_h / 2; - if (g_layer_x < 0) g_layer_x = 0; - if (g_layer_y < 0) g_layer_y = 0; - if (g_layer_w > g_menuscreen_w) g_layer_w = g_menuscreen_w; - if (g_layer_h > g_menuscreen_h) g_layer_h = g_menuscreen_h; + if (g_scaler != SCALE_CUSTOM) { + g_layer_x = fw / 2 - g_layer_w / 2; + g_layer_y = fh / 2 - g_layer_h / 2; + } + if (g_layer_w > fw * 2) g_layer_w = fw * 2; + if (g_layer_h > fh * 2) g_layer_h = fh * 2; } // XXX: this is platform specific really @@ -244,7 +258,6 @@ static inline int resolution_ok(int w, int h) static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) { int vout_w, vout_h, vout_bpp; - int buf_yoffset = 0; // special h handling, Wipeout likes to change it by 1-6 static int vsync_cnt_ms_prev; @@ -264,7 +277,7 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) assert(vout_h >= 192); pl_vout_scale_w = pl_vout_scale_h = 1; -#ifdef __ARM_NEON__ +#ifdef HAVE_NEON32 if (soft_filter) { if (resolution_ok(w * 2, h * 2) && bpp == 16) { pl_vout_scale_w = 2; @@ -283,7 +296,7 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) vout_w *= pl_vout_scale_w; vout_h *= pl_vout_scale_h; - update_layer_size(vout_w, vout_h); + pl_update_layer_size(vout_w, vout_h, g_menuscreen_w, g_menuscreen_h); pl_vout_buf = plat_gvideo_set_mode(&vout_w, &vout_h, &vout_bpp); if (pl_vout_buf == NULL && pl_plat_blit == NULL) @@ -293,11 +306,7 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp) pl_vout_w = vout_w; pl_vout_h = vout_h; pl_vout_bpp = vout_bpp; - pl_vout_yoffset = buf_yoffset; } - if (pl_vout_buf != NULL) - pl_vout_buf = (char *)pl_vout_buf - + pl_vout_yoffset * pl_vout_w * pl_vout_bpp / 8; menu_notify_mode_change(pl_vout_w, pl_vout_h, pl_vout_bpp); } @@ -309,14 +318,16 @@ void pl_force_clear(void) flip_clear_counter = 2; } -static void pl_vout_flip(const void *vram, int stride, int bgr24, +static void pl_vout_flip(const void *vram_, int vram_ofs, int bgr24, int x, int y, int w, int h, int dims_changed) { unsigned char *dest = pl_vout_buf; - const unsigned short *src = vram; + const unsigned char *vram = vram_; int dstride = pl_vout_w, h1 = h; - int h_full = pl_vout_h - pl_vout_yoffset; + int h_full = pl_vout_h; + int enhres = w > psx_w; int xoffs = 0, doffs; + int hwrapped; pcnt_start(PCNT_BLIT); @@ -335,10 +346,10 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, // offset xoffs = x * pl_vout_scale_w; - doffs = xoffs + y * dstride; + doffs = xoffs + y * pl_vout_scale_h * dstride; if (dims_changed) - flip_clear_counter = 2; + flip_clear_counter = 3; if (flip_clear_counter > 0) { if (pl_plat_clear) @@ -351,7 +362,7 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, if (pl_plat_blit) { - pl_plat_blit(doffs, src, w, h, stride, bgr24); + pl_plat_blit(doffs, vram + vram_ofs, w, h, 1024, bgr24); goto out_hud; } @@ -362,58 +373,94 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, if (bgr24) { + hwrapped = (vram_ofs & 2047) + w * 3 - 2048; if (pl_rearmed_cbs.only_16bpp) { - for (; h1-- > 0; dest += dstride * 2, src += stride) - { - bgr888_to_rgb565(dest, src, w * 3); + for (; h1-- > 0; dest += dstride * 2) { + bgr888_to_rgb565(dest, vram + vram_ofs, w * 3); + vram_ofs = (vram_ofs + 2048) & 0xfffff; + } + + if (hwrapped > 0) { + // this is super-rare so just fix-up + vram_ofs = (vram_ofs - h * 2048) & 0xff800; + dest -= dstride * 2 * h; + dest += (w - hwrapped / 3) * 2; + for (h1 = h; h1-- > 0; dest += dstride * 2) { + bgr888_to_rgb565(dest, vram + vram_ofs, hwrapped); + vram_ofs = (vram_ofs + 2048) & 0xfffff; + } } } else { dest -= doffs * 2; dest += (doffs / 8) * 24; - for (; h1-- > 0; dest += dstride * 3, src += stride) - { - bgr888_to_rgb888(dest, src, w * 3); + for (; h1-- > 0; dest += dstride * 3) { + bgr888_to_rgb888(dest, vram + vram_ofs, w * 3); + vram_ofs = (vram_ofs + 2048) & 0xfffff; + } + + if (hwrapped > 0) { + vram_ofs = (vram_ofs - h * 2048) & 0xff800; + dest -= dstride * 3 * h; + dest += w * 3 - hwrapped; + for (h1 = h; h1-- > 0; dest += dstride * 3) { + bgr888_to_rgb888(dest, vram + vram_ofs, hwrapped); + vram_ofs = (vram_ofs + 2048) & 0xfffff; + } } } } -#ifdef __ARM_NEON__ +#ifdef HAVE_NEON32 else if (soft_filter == SOFT_FILTER_SCALE2X && pl_vout_scale_w == 2) { - neon_scale2x_16_16(src, (void *)dest, w, - stride * 2, dstride * 2, h); + neon_scale2x_16_16((const void *)(vram + vram_ofs), (void *)dest, w, + 2048, dstride * 2, h); } else if (soft_filter == SOFT_FILTER_EAGLE2X && pl_vout_scale_w == 2) { - neon_eagle2x_16_16(src, (void *)dest, w, - stride * 2, dstride * 2, h); + neon_eagle2x_16_16((const void *)(vram + vram_ofs), (void *)dest, w, + 2048, dstride * 2, h); } else if (scanlines != 0 && scanline_level != 100) { int h2, l = scanline_level * 2048 / 100; - int stride_0 = pl_vout_scale_h >= 2 ? 0 : stride; + int stride_0 = pl_vout_scale_h >= 2 ? 0 : 2048; h1 *= pl_vout_scale_h; while (h1 > 0) { for (h2 = scanlines; h2 > 0 && h1 > 0; h2--, h1--) { - bgr555_to_rgb565(dest, src, w * 2); - dest += dstride * 2, src += stride_0; + bgr555_to_rgb565(dest, vram + vram_ofs, w * 2); + vram_ofs = (vram_ofs + stride_0) & 0xfffff; + dest += dstride * 2; } for (h2 = scanlines; h2 > 0 && h1 > 0; h2--, h1--) { - bgr555_to_rgb565_b(dest, src, w * 2, l); - dest += dstride * 2, src += stride; + bgr555_to_rgb565_b(dest, vram + vram_ofs, w * 2, l); + vram_ofs = (vram_ofs + 2048) & 0xfffff; + dest += dstride * 2; } } } #endif else { - for (; h1-- > 0; dest += dstride * 2, src += stride) - { - bgr555_to_rgb565(dest, src, w * 2); + unsigned int vram_mask = enhres ? ~0 : 0xfffff; + for (; h1-- > 0; dest += dstride * 2) { + bgr555_to_rgb565(dest, vram + vram_ofs, w * 2); + vram_ofs = (vram_ofs + 2048) & vram_mask; + } + + hwrapped = (vram_ofs & 2047) + w * 2 - 2048; + if (!enhres && hwrapped > 0) { + vram_ofs = (vram_ofs - h * 2048) & 0xff800; + dest -= dstride * 2 * h; + dest += w * 2 - hwrapped; + for (h1 = h; h1-- > 0; dest += dstride * 2) { + bgr555_to_rgb565(dest, vram + vram_ofs, hwrapped); + vram_ofs = (vram_ofs + 2048) & 0xfffff; + } } } @@ -425,9 +472,6 @@ out: // let's flip now pl_vout_buf = plat_gvideo_flip(); - if (pl_vout_buf != NULL) - pl_vout_buf = (char *)pl_vout_buf - + pl_vout_yoffset * pl_vout_w * pl_vout_bpp / 8; pl_rearmed_cbs.flip_cnt++; } @@ -481,7 +525,6 @@ static int dispmode_default(void) return 1; } -#ifdef BUILTIN_GPU_NEON static int dispmode_doubleres(void) { if (!(pl_rearmed_cbs.gpu_caps & GPU_CAP_SUPPORTS_2X) @@ -493,9 +536,8 @@ static int dispmode_doubleres(void) snprintf(hud_msg, sizeof(hud_msg), "double resolution"); return 1; } -#endif -#ifdef __ARM_NEON__ +#ifdef HAVE_NEON32 static int dispmode_scale2x(void) { if (!resolution_ok(psx_w * 2, psx_h * 2) || psx_bpp != 16) @@ -521,10 +563,8 @@ static int dispmode_eagle2x(void) static int (*dispmode_switchers[])(void) = { dispmode_default, -#ifdef BUILTIN_GPU_NEON dispmode_doubleres, -#endif -#ifdef __ARM_NEON__ +#ifdef HAVE_NEON32 dispmode_scale2x, dispmode_eagle2x, #endif @@ -609,16 +649,29 @@ static void update_analogs(void) } } +static void emu_set_action(enum sched_action action_) +{ + extern enum sched_action emu_action, emu_action_old; + + if (action_ == SACTION_NONE) + emu_action_old = 0; + else if (action_ != emu_action_old) + psxRegs.stop++; + emu_action = action_; +} + static void update_input(void) { int actions[IN_BINDTYPE_COUNT] = { 0, }; unsigned int emu_act; + int in_state_gun; + int i; in_update(actions); if (in_type[0] == PSE_PAD_TYPE_ANALOGJOY || in_type[0] == PSE_PAD_TYPE_ANALOGPAD) update_analogs(); emu_act = actions[IN_BINDTYPE_EMU]; - in_state_gun = (emu_act & SACTION_GUN_MASK) >> SACTION_GUN_TRIGGER; + in_state_gun = emu_act & SACTION_GUN_MASK; emu_act &= ~SACTION_GUN_MASK; if (emu_act) { @@ -629,12 +682,35 @@ static void update_input(void) } emu_set_action(emu_act); - in_keystate[0] = actions[IN_BINDTYPE_PLAYER12]; + in_keystate[0] = actions[IN_BINDTYPE_PLAYER12] & 0xffff; + in_keystate[1] = (actions[IN_BINDTYPE_PLAYER12] >> 16) & 0xffff; - // fixme - //if (in_type[0] == PSE_PAD_TYPE_GUNCON && tsdev) - // pl_gun_ts_update(tsdev, xn, yn, in); - // in_analog_left[0][0] = xn + if (tsdev) for (i = 0; i < 2; i++) { + int in = 0, x = 0, y = 0, trigger;; + if (in_type[i] != PSE_PAD_TYPE_GUN + && in_type[i] != PSE_PAD_TYPE_GUNCON) + continue; + trigger = in_type[i] == PSE_PAD_TYPE_GUN + ? (1 << DKEY_SQUARE) : (1 << DKEY_CIRCLE); + + pl_gun_ts_update(tsdev, &x, &y, &in); + in_analog_left[i][0] = 65536; + in_analog_left[i][1] = 65536; + if (in && !(in_state_gun & (1 << SACTION_GUN_TRIGGER2))) { + in_analog_left[i][0] = x; + in_analog_left[i][1] = y; + if (!(g_opts & OPT_TSGUN_NOTRIGGER)) + in_state_gun |= (1 << SACTION_GUN_TRIGGER); + } + in_keystate[i] = 0; + if (in_state_gun & ((1 << SACTION_GUN_TRIGGER) + | (1 << SACTION_GUN_TRIGGER2))) + in_keystate[i] |= trigger; + if (in_state_gun & (1 << SACTION_GUN_A)) + in_keystate[i] |= (1 << DKEY_START); + if (in_state_gun & (1 << SACTION_GUN_B)) + in_keystate[i] |= (1 << DKEY_CROSS); + } } #else /* MAEMO */ extern void update_input(void); @@ -642,6 +718,13 @@ extern void update_input(void); void pl_gun_byte2(int port, unsigned char byte) { + if (!tsdev || in_type[port] != PSE_PAD_TYPE_GUN || !(byte & 0x10)) + return; + if (in_analog_left[port][0] == 65536) + return; + + psxScheduleIrq10(4, in_analog_left[port][0] * 1629 / 1024, + in_analog_left[port][1] * psx_h / 1024); } #define MAX_LAG_FRAMES 3 @@ -731,14 +814,14 @@ void pl_frame_limit(void) // recompilation is not that fast and may cause frame skip on // loading screens and such, resulting in flicker or glitches - if (new_dynarec_did_compile) { + if (ndrc_g.did_compile) { if (drc_active_vsyncs < 32) pl_rearmed_cbs.fskip_advice = 0; drc_active_vsyncs++; } else drc_active_vsyncs = 0; - new_dynarec_did_compile = 0; + ndrc_g.did_compile = 0; } pcnt_start(PCNT_ALL); @@ -746,18 +829,20 @@ void pl_frame_limit(void) void pl_timing_prepare(int is_pal_) { + double fps; pl_rearmed_cbs.fskip_advice = 0; pl_rearmed_cbs.flips_per_sec = 0; pl_rearmed_cbs.cpu_usage = 0; is_pal = is_pal_; - frame_interval = is_pal ? 20000 : 16667; - frame_interval1024 = is_pal ? 20000*1024 : 17066667; + fps = psxGetFps(); + frame_interval = (int)(1000000.0 / fps); + frame_interval1024 = (int)(1000000.0 * 1024.0 / fps); // used by P.E.Op.S. frameskip code - pl_rearmed_cbs.gpu_peops.fFrameRateHz = is_pal ? 50.0f : 59.94f; + pl_rearmed_cbs.gpu_peops.fFrameRateHz = (float)fps; pl_rearmed_cbs.gpu_peops.dwFrameRateTicks = - (100000*100 / (unsigned long)(pl_rearmed_cbs.gpu_peops.fFrameRateHz*100)); + (100000*100 / (int)(pl_rearmed_cbs.gpu_peops.fFrameRateHz*100)); } static void pl_get_layer_pos(int *x, int *y, int *w, int *h) @@ -791,15 +876,11 @@ static void *watchdog_thread(void *unused) int seen_dead = 0; int sleep_time = 5; -#if !defined(NDEBUG) || defined(DRC_DBG) - // don't interfere with debug - return NULL; -#endif while (1) { sleep(sleep_time); - if (stop) { + if (psxRegs.stop) { seen_dead = 0; sleep_time = 5; continue; @@ -817,6 +898,7 @@ static void *watchdog_thread(void *unused) fprintf(stderr, "watchdog: seen_dead %d\n", seen_dead); if (seen_dead > 4) { fprintf(stderr, "watchdog: lockup detected, aborting\n"); + fflush(stderr); // we can't do any cleanup here really, the main thread is // likely touching resources and would crash anyway abort(); @@ -826,9 +908,25 @@ static void *watchdog_thread(void *unused) void pl_start_watchdog(void) { +#if defined(NDEBUG) && !defined(DRC_DBG) pthread_attr_t attr; pthread_t tid; int ret; +#ifdef __linux__ + int tpid = 0; + char buf[256]; + FILE *f = fopen("/proc/self/status", "r"); + if (f) { + while (fgets(buf, sizeof(buf), f)) + if (buf[0] == 'T' && sscanf(buf, "TracerPid: %d", &tpid) == 1) + break; + fclose(f); + } + if (tpid) { + printf("no watchdog to tracer %d\n", tpid); + return; + } +#endif pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); @@ -836,12 +934,15 @@ void pl_start_watchdog(void) ret = pthread_create(&tid, &attr, watchdog_thread, NULL); if (ret != 0) fprintf(stderr, "could not start watchdog: %d\n", ret); +#endif + (void)watchdog_thread; } -static void *pl_emu_mmap(unsigned long addr, size_t size, int is_fixed, - enum psxMapTag tag) +static void *pl_emu_mmap(unsigned long addr, size_t size, + enum psxMapTag tag, int *can_retry_addr) { - return plat_mmap(addr, size, 0, is_fixed); + *can_retry_addr = 1; + return plat_mmap(addr, size, 0, 0); } static void pl_emu_munmap(void *ptr, size_t size, enum psxMapTag tag) @@ -851,7 +952,8 @@ static void pl_emu_munmap(void *ptr, size_t size, enum psxMapTag tag) static void *pl_mmap(unsigned int size) { - return psxMapHook(0, size, 0, MAP_TAG_VRAM); + int can_retry_addr; + return psxMapHook(0, size, MAP_TAG_VRAM, &can_retry_addr); } static void pl_munmap(void *ptr, unsigned int size)