sms, add ghosting for GG LCD (generic+libretro only)

This commit is contained in:
kub 2021-11-04 20:33:28 +01:00
parent 27005bdb5f
commit f55ce7bf47
7 changed files with 135 additions and 18 deletions

View file

@ -27,6 +27,7 @@ enum renderer_types { RT_16BIT, RT_8BIT_ACC, RT_8BIT_FAST, RT_COUNT };
static int out_x, out_y, out_w, out_h; // renderer output in render buffer
static int screen_x, screen_y, screen_w, screen_h; // final render destination
static int render_bg; // force 16bit mode for bg render
static u16 *ghost_buf; // backbuffer to simulate LCD ghosting
void pemu_prep_defconfig(void)
{
@ -167,6 +168,23 @@ void pemu_finalize_frame(const char *fps, const char *notice)
screen_blit(pd, g_screen_ppitch, ps, 328, Pico.est.HighPal);
}
if (currentConfig.ghosting && out_h == 144) {
// GG LCD ghosting emulation
u16 *pd = screen_buffer(g_screen_ptr) +
out_y * g_screen_ppitch + out_x;
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;
for (y = 0; y < h; y++) {
if (currentConfig.ghosting == 1)
v_blend((u32 *)pd, (u32 *)ps, w/2, p_075_round);
else
v_blend((u32 *)pd, (u32 *)ps, w/2, p_05_round);
pd += g_screen_ppitch;
ps += w;
}
}
if (notice)
emu_osd_text16(4, g_screen_height - 8, notice);
if (currentConfig.EmuOpt & EOPT_SHOW_FPS)
@ -312,27 +330,30 @@ static int cb_vscaling_nop(unsigned int line)
static int cb_vscaling_end(unsigned int line)
{
u16 *dest = Pico.est.DrawLineDest;
u16 *dest = (u16 *)Pico.est.DrawLineDest + out_x;
// helpers for 32 bit operation (2 pixels at once):
u32 *dest32 = (u32 *)dest;
int pp = g_screen_ppitch;
if (out_h == 144)
switch (currentConfig.filter) {
case 0: v_upscale_nn_3_5(dest, g_screen_ppitch, 320, vscale_state);
case 0: v_upscale_nn_3_5(dest32, pp/2, out_w/2, vscale_state);
break;
default: v_upscale_snn_3_5(dest, g_screen_ppitch, 320, vscale_state);
default: v_upscale_snn_3_5(dest32, pp/2, out_w/2, vscale_state);
break;
}
else
switch (currentConfig.filter) {
case 3: v_upscale_bl4_16_17(dest, g_screen_ppitch, 320, vscale_state);
case 3: v_upscale_bl4_16_17(dest32, pp/2, out_w/2, vscale_state);
break;
case 2: v_upscale_bl2_16_17(dest, g_screen_ppitch, 320, vscale_state);
case 2: v_upscale_bl2_16_17(dest32, pp/2, out_w/2, vscale_state);
break;
case 1: v_upscale_snn_16_17(dest, g_screen_ppitch, 320, vscale_state);
case 1: v_upscale_snn_16_17(dest32, pp/2, out_w/2, vscale_state);
break;
default: v_upscale_nn_16_17(dest, g_screen_ppitch, 320, vscale_state);
default: v_upscale_nn_16_17(dest32, pp/2, out_w/2, vscale_state);
break;
}
Pico.est.DrawLineDest = dest;
Pico.est.DrawLineDest = (u16 *)dest32 - out_x;
return 0;
}
@ -382,6 +403,14 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
plat_video_set_size(screen_w, screen_h);
plat_video_set_buffer(g_screen_ptr);
// create a backing buffer for emulating the bad GG lcd display
if (currentConfig.ghosting && out_h == 144) {
int h = currentConfig.vscaling == EOPT_SCALE_SW ? 240:out_h;
int w = currentConfig.scaling == EOPT_SCALE_SW ? 320:out_w;
ghost_buf = realloc(ghost_buf, w * h * 2);
memset(ghost_buf, 0, w * h * 2);
}
// clear whole screen in all buffers
if (!is_16bit_mode())
memset32(Pico.est.Draw2FB, 0xe0e0e0e0, (320+8) * (8+240+8) / 4);
@ -398,6 +427,10 @@ void pemu_loop_end(void)
{
/* do one more frame for menu bg */
pemu_forced_frame(0, 1);
if (ghost_buf) {
free(ghost_buf);
ghost_buf = NULL;
}
}
void plat_wait_till_us(unsigned int us_to)

View file

@ -2,13 +2,16 @@
static const char *men_scaling_opts[] = { "OFF", "software", "hardware", NULL };
static const char *men_filter_opts[] = { "nearest", "smoother", "bilinear 1", "bilinear 2", NULL };
static const char *men_ghosting_opts[] = { "OFF", "weak", "normal", NULL };
static const char h_scale[] = "hardware scaling may not be working on some devices";
static const char h_ghost[] = "when active simulates inertia of the GG LCD display";
#define MENU_OPTIONS_GFX \
mee_enum_h ("Horizontal scaling", MA_OPT_SCALING, currentConfig.scaling, men_scaling_opts, h_scale), \
mee_enum_h ("Vertical scaling", MA_OPT_VSCALING, currentConfig.vscaling, men_scaling_opts, h_scale), \
mee_enum_h ("Scaler type", MA_OPT3_FILTERING, currentConfig.filter, men_filter_opts, NULL), \
mee_enum_h ("Horizontal scaling", MA_OPT_SCALING, currentConfig.scaling, men_scaling_opts, h_scale), \
mee_enum_h ("Vertical scaling", MA_OPT_VSCALING, currentConfig.vscaling, men_scaling_opts, h_scale), \
mee_enum_h ("Scaler type", MA_OPT3_FILTERING, currentConfig.filter, men_filter_opts, NULL), \
mee_enum_h ("Game Gear LCD ghosting", MA_SMSOPT_GHOSTING, currentConfig.ghosting, men_ghosting_opts, h_ghost), \
#define MENU_OPTIONS_ADV