Skip to content

Commit

Permalink
pandora: allow to move the overlay partially offscreen
Browse files Browse the repository at this point in the history
to allow to cut off black bars, if the user chooses to do so
  • Loading branch information
notaz committed Jan 6, 2024
1 parent d6d6e30 commit d005dfb
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 51 deletions.
69 changes: 46 additions & 23 deletions platform/pandora/menu.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "plat.h"

static int min(int x, int y) { return x < y ? x : y; }
static int max(int x, int y) { return x > y ? x : y; }

static const char *men_scaler[] = { "1x1, 1x1", "2x2, 3x2", "2x2, 2x2", "fullscreen", "custom", NULL };
static const char h_scaler[] = "Scalers for 40 and 32 column modes\n"
"(320 and 256 pixel wide horizontal)";
Expand All @@ -8,28 +11,40 @@ static const char h_cscaler[] = "Displays the scaler layer, you can resize it\

static int menu_loop_cscaler(int id, int keys)
{
int was_layer_clipped = 0;
unsigned int inp;

currentConfig.scaling = SCALE_CUSTOM;

pnd_setup_layer(1, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
pnd_restore_layer_data();

menu_draw_begin(0, 1);
menuscreen_memset_lines(g_menuscreen_ptr, 0, g_menuscreen_h);
menu_draw_end();

for (;;)
{
menu_draw_begin(0, 1);
menuscreen_memset_lines(g_menuscreen_ptr, 0, g_menuscreen_h);
text_out16(2, 480 - 18, "%dx%d | d-pad to resize, R+d-pad to move", g_layer_cw, g_layer_ch);
menu_draw_end();
int top_x = max(0, -g_layer_cx * g_screen_ppitch / 800) + 1;
int top_y = max(0, -g_layer_cy * g_screen_height / 480) + 1;
char text[128];
memcpy(g_screen_ptr, g_menubg_src_ptr,
g_screen_ppitch * g_screen_height * 2);
snprintf(text, sizeof(text), "%d,%d %dx%d",
g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
basic_text_out16_nf(g_screen_ptr, g_screen_ppitch,
saved_start_col + top_x, saved_start_line + top_y, text);
basic_text_out16_nf(g_screen_ptr, g_screen_ppitch, 2,
g_screen_height - 20, "d-pad: resize, R+d-pad: move");
plat_video_flip();

inp = in_menu_wait(PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT
|PBTN_R|PBTN_MOK|PBTN_MBACK, NULL, 40);
if (inp & PBTN_R) {
if (inp & PBTN_UP) g_layer_cy--;
if (inp & PBTN_DOWN) g_layer_cy++;
if (inp & PBTN_LEFT) g_layer_cx--;
if (inp & PBTN_RIGHT) g_layer_cx++;
} else {
if (inp & PBTN_UP) g_layer_cy--;
if (inp & PBTN_DOWN) g_layer_cy++;
if (inp & PBTN_LEFT) g_layer_cx--;
if (inp & PBTN_RIGHT) g_layer_cx++;
if (!(inp & PBTN_R)) {
if (inp & PBTN_UP) g_layer_ch += 2;
if (inp & PBTN_DOWN) g_layer_ch -= 2;
if (inp & PBTN_LEFT) g_layer_cw += 2;
Expand All @@ -39,17 +54,25 @@ static int menu_loop_cscaler(int id, int keys)
break;

if (inp & (PBTN_UP|PBTN_DOWN|PBTN_LEFT|PBTN_RIGHT)) {
if (g_layer_cx < 0) g_layer_cx = 0;
if (g_layer_cx > 640) g_layer_cx = 640;
if (g_layer_cy < 0) g_layer_cy = 0;
if (g_layer_cy > 420) g_layer_cy = 420;
if (g_layer_cw < 160) g_layer_cw = 160;
if (g_layer_ch < 60) g_layer_ch = 60;
if (g_layer_cx + g_layer_cw > 800)
g_layer_cw = 800 - g_layer_cx;
if (g_layer_cy + g_layer_ch > 480)
g_layer_ch = 480 - g_layer_cy;
int layer_clipped = 0;
g_layer_cx = max(-320, min(g_layer_cx, 640));
g_layer_cy = max(-240, min(g_layer_cy, 420));
g_layer_cw = max(160, g_layer_cw);
g_layer_ch = max( 60, g_layer_ch);
if (g_layer_cx < 0 || g_layer_cx + g_layer_cw > 800)
layer_clipped = 1;
if (g_layer_cw > 800+400)
g_layer_cw = 800+400;
if (g_layer_cy < 0 || g_layer_cy + g_layer_ch > 480)
layer_clipped = 1;
if (g_layer_ch > 480+360)
g_layer_ch = 480+360;
// resize the layer
pnd_setup_layer(1, g_layer_cx, g_layer_cy, g_layer_cw, g_layer_ch);
if (layer_clipped || was_layer_clipped)
emu_video_mode_change(saved_start_line, saved_line_count,
saved_start_col, saved_col_count);
was_layer_clipped = layer_clipped;
}
}

Expand All @@ -62,9 +85,9 @@ static int menu_loop_cscaler(int id, int keys)
mee_enum_h ("Scaler", MA_OPT_SCALING, currentConfig.scaling, \
men_scaler, h_scaler), \
mee_onoff ("Vsync", MA_OPT2_VSYNC, currentConfig.EmuOpt, EOPT_VSYNC), \
mee_cust_h ("Setup custom scaler", MA_NONE, menu_loop_cscaler, NULL, h_cscaler), \
mee_range_hide("layer_x", MA_OPT3_LAYER_X, g_layer_cx, 0, 640), \
mee_range_hide("layer_y", MA_OPT3_LAYER_Y, g_layer_cy, 0, 420), \
mee_cust_s_h ("Setup custom scaler", MA_NONE, 0, menu_loop_cscaler, NULL, h_cscaler), \
mee_range_hide("layer_x", MA_OPT3_LAYER_X, g_layer_cx, -320, 640), \
mee_range_hide("layer_y", MA_OPT3_LAYER_Y, g_layer_cy, -240, 420), \
mee_range_hide("layer_w", MA_OPT3_LAYER_W, g_layer_cw, 160, 800), \
mee_range_hide("layer_h", MA_OPT3_LAYER_H, g_layer_ch, 60, 480), \

Expand Down
66 changes: 38 additions & 28 deletions platform/pandora/plat.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
static struct vout_fbdev *main_fb, *layer_fb;
// g_layer_* - in use, g_layer_c* - configured custom
int g_layer_cx = 80, g_layer_cy, g_layer_cw = 640, g_layer_ch = 480;
int saved_start_line = 0, saved_line_count = 240;
int saved_start_col = 0, saved_col_count = 320;
static int g_layer_x, g_layer_y;
static int g_layer_w = 320, g_layer_h = 240;
static int g_osd_start_x, g_osd_fps_x, g_osd_y, doing_bg_frame;
Expand All @@ -47,22 +49,6 @@ static void *temp_frame;
const char *renderer_names[] = { NULL };
const char *renderer_names32x[] = { NULL };

static const char * const pandora_gpio_keys[KEY_MAX + 1] = {
[KEY_UP] = "Up",
[KEY_LEFT] = "Left",
[KEY_RIGHT] = "Right",
[KEY_DOWN] = "Down",
[KEY_HOME] = "A",
[KEY_PAGEDOWN] = "X",
[KEY_END] = "B",
[KEY_PAGEUP] = "Y",
[KEY_RIGHTSHIFT]= "L",
[KEY_RIGHTCTRL] = "R",
[KEY_LEFTALT] = "Start",
[KEY_LEFTCTRL] = "Select",
[KEY_MENU] = "Pandora",
};

static struct in_default_bind in_evdev_defbinds[] =
{
{ KEY_UP, IN_BINDTYPE_PLAYER12, GBTN_UP },
Expand Down Expand Up @@ -314,6 +300,13 @@ static int pnd_setup_layer_(int fd, int enabled, int x, int y, int w, int h)

int pnd_setup_layer(int enabled, int x, int y, int w, int h)
{
// it's not allowed for the layer to be partially offscreen,
// instead it is faked by emu_video_mode_change()
if (x < 0) { w += x; x = 0; }
if (y < 0) { h += y; y = 0; }
if (x + w > 800) w = 800 - x;
if (y + h > 480) h = 480 - y;

return pnd_setup_layer_(vout_fbdev_get_fd(layer_fb), enabled, x, y, w, h);
}

Expand All @@ -332,26 +325,22 @@ void pnd_restore_layer_data(void)

void emu_video_mode_change(int start_line, int line_count, int start_col, int col_count)
{
int fb_w = 320, fb_h = 240, fb_left = 0, fb_right = 0, fb_top = 0, fb_bottom = 0;
int fb_w, fb_h = 240, fb_left = 0, fb_right = 0, fb_top = 0, fb_bottom = 0;

if (doing_bg_frame)
return;

fb_w = col_count;
fb_left = start_col;
fb_right = 320 - (fb_w + fb_left);

switch (currentConfig.scaling) {
case SCALE_1x1:
g_layer_w = fb_w;
g_layer_w = col_count;
g_layer_h = fb_h;
break;
case SCALE_2x2_3x2:
g_layer_w = fb_w * (col_count < 320 ? 3 : 2);
g_layer_w = col_count * (col_count < 320 ? 3 : 2);
g_layer_h = fb_h * 2;
break;
case SCALE_2x2_2x2:
g_layer_w = fb_w * 2;
g_layer_w = col_count * 2;
g_layer_h = fb_h * 2;
break;
case SCALE_FULLSCREEN:
Expand All @@ -376,17 +365,38 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
case SCALE_FULLSCREEN:
case SCALE_CUSTOM:
fb_top = start_line;
fb_h = line_count;
fb_h = start_line + line_count;
break;
}
g_osd_start_x = start_col;
g_osd_fps_x = start_col + col_count - 5*8 - 2;
g_osd_y = fb_top + fb_h - 8;
fb_w = 320;
fb_left = start_col;
fb_right = 320 - (start_col + col_count);
if (currentConfig.scaling == SCALE_CUSTOM) {
int right = g_layer_x + g_layer_w;
int bottom = g_layer_y + g_layer_h;
if (g_layer_x < 0)
fb_left += -g_layer_x * col_count / g_menuscreen_w;
if (g_layer_y < 0)
fb_top += -g_layer_y * line_count / g_menuscreen_h;
if (right > g_menuscreen_w)
fb_right += (right - g_menuscreen_w) * col_count / g_menuscreen_w;
if (bottom > g_menuscreen_h)
fb_bottom += (bottom - g_menuscreen_h) * line_count / g_menuscreen_h;
}
fb_w -= fb_left + fb_right;
fb_h -= fb_top + fb_bottom;

pnd_setup_layer(1, g_layer_x, g_layer_y, g_layer_w, g_layer_h);
vout_fbdev_resize(layer_fb, fb_w, fb_h, 16, fb_left, fb_right, fb_top, fb_bottom, 4, 0);
vout_fbdev_clear(layer_fb);
plat_video_flip();

g_osd_start_x = start_col;
g_osd_fps_x = start_col + col_count - 5*8 - 2;
g_osd_y = fb_top + fb_h - 8;

saved_start_line = start_line, saved_line_count = line_count;
saved_start_col = start_col, saved_col_count = col_count;
}

void plat_video_loop_prepare(void)
Expand Down
2 changes: 2 additions & 0 deletions platform/pandora/plat.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

extern int g_layer_cx, g_layer_cy;
extern int g_layer_cw, g_layer_ch;
extern int saved_start_line, saved_line_count;
extern int saved_start_col, saved_col_count;

void pnd_menu_init(void);
int pnd_setup_layer(int enabled, int x, int y, int w, int h);
Expand Down

0 comments on commit d005dfb

Please sign in to comment.