diff --git a/desmume/src/frontend/posix/gtk/main.cpp b/desmume/src/frontend/posix/gtk/main.cpp
index f3e4c96d6..06861431e 100644
--- a/desmume/src/frontend/posix/gtk/main.cpp
+++ b/desmume/src/frontend/posix/gtk/main.cpp
@@ -313,6 +313,8 @@ enum orientation_enum {
ORIENT_VERTICAL = 0,
ORIENT_HORIZONTAL = 1,
ORIENT_SINGLE = 2,
+ ORIENT_HYBRID_EQUAL = 3,
+ ORIENT_HYBRID_VERTICAL = 4,
ORIENT_N
};
@@ -322,9 +324,11 @@ struct screen_size_t {
};
const struct screen_size_t screen_size[ORIENT_N] = {
- {256, 384},
- {512, 192},
- {256, 192}
+ {GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2},
+ {GPU_FRAMEBUFFER_NATIVE_WIDTH*2, GPU_FRAMEBUFFER_NATIVE_HEIGHT},
+ {GPU_FRAMEBUFFER_NATIVE_WIDTH, GPU_FRAMEBUFFER_NATIVE_HEIGHT},
+ {GPU_FRAMEBUFFER_NATIVE_WIDTH*3, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2},
+ {GPU_FRAMEBUFFER_NATIVE_WIDTH*3, GPU_FRAMEBUFFER_NATIVE_HEIGHT*2}
};
enum spumode_enum {
@@ -539,7 +543,9 @@ struct nds_screen_t {
gint rotation_angle;
orientation_enum orientation;
cairo_matrix_t touch_matrix;
+ cairo_matrix_t touch_matrix_hybrid;
cairo_matrix_t topscreen_matrix;
+ cairo_matrix_t topscreen_matrix_hybrid;
gboolean swap;
};
@@ -1213,6 +1219,33 @@ static void Reset(GSimpleAction *action, GVariant *parameter, gpointer user_data
/////////////////////////////// DRAWING SCREEN //////////////////////////////////
+
+struct DrawParams {
+ bool valid;
+
+ //Drawing area size
+ gint daW;
+ gint daH;
+
+ //Image size
+ gint imgW;
+ gint imgH;
+
+ //Buffer size
+ gint dstW;
+ gint dstH;
+ gint dstScale;
+
+ gint gap;
+ gint gapOffset;
+
+ gfloat ratio;
+
+ gdouble hybridBigScreenScale;
+};
+
+static DrawParams draw_params = {false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, 0.0};
+
static void UpdateDrawingAreaAspect()
{
gint H, W;
@@ -1226,11 +1259,16 @@ static void UpdateDrawingAreaAspect()
}
if (nds_screen.orientation != ORIENT_SINGLE) {
- if (nds_screen.orientation == ORIENT_VERTICAL) {
+ if ((nds_screen.orientation == ORIENT_VERTICAL) || (nds_screen.orientation == ORIENT_HYBRID_EQUAL) ||
+ (nds_screen.orientation == ORIENT_HYBRID_VERTICAL)) {
if ((nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180)) {
- H += nds_screen.gap_size;
+ if((nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL))
+ W = (W * 2.0/3.0) * (double)(H + nds_screen.gap_size) / (double)H + W / 3.0;
+ H += nds_screen.gap_size;
} else {
- W += nds_screen.gap_size;
+ if((nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL))
+ H = (H * 2.0/3.0) * (double)(W + nds_screen.gap_size) / (double)W + H / 3.0;
+ W += nds_screen.gap_size;
}
}
}
@@ -1243,6 +1281,8 @@ static void UpdateDrawingAreaAspect()
gtk_window_set_resizable(GTK_WINDOW(pWindow), FALSE);
gtk_widget_set_size_request(GTK_WIDGET(pDrawingArea), W * winsize_current / 2, H * winsize_current / 2);
}
+
+ draw_params.valid = false;
}
static void ToggleGap(GSimpleAction *action, GVariant *parameter, gpointer user_data)
@@ -1306,9 +1346,15 @@ static void SetOrientation(GSimpleAction *action, GVariant *parameter, gpointer
orient = ORIENT_HORIZONTAL;
else if(strcmp(string, "single") == 0)
orient = ORIENT_SINGLE;
+ else if(strcmp(string, "hybrid_equal") == 0)
+ orient = ORIENT_HYBRID_EQUAL;
+ else if(strcmp(string, "hybrid_vertical") == 0)
+ orient = ORIENT_HYBRID_VERTICAL;
nds_screen.orientation = orient;
#ifdef HAVE_LIBAGG
osd->singleScreen = nds_screen.orientation == ORIENT_SINGLE;
+ bool hybrid = (nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL);
+ osd->swapScreens = nds_screen.swap && !hybrid;
#endif
config.view_orient = nds_screen.orientation;
UpdateDrawingAreaAspect();
@@ -1320,7 +1366,8 @@ static void ToggleSwapScreens(GSimpleAction *action, GVariant *parameter, gpoint
gboolean value = !g_variant_get_boolean(variant);
nds_screen.swap = value;
#ifdef HAVE_LIBAGG
- osd->swapScreens = nds_screen.swap;
+ bool hybrid = (nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL);
+ osd->swapScreens = nds_screen.swap && !hybrid;
#endif
config.view_swap = nds_screen.swap;
RedrawScreen();
@@ -1364,6 +1411,17 @@ static inline void drawTopScreen(cairo_t* cr, u32* buf, gint w, gint h, gint gap
cairo_translate(cr, w, 0);
}
break;
+ case ORIENT_HYBRID_EQUAL:
+ case ORIENT_HYBRID_VERTICAL:
+ if (!swap && (draw_params.hybridBigScreenScale > 0.0)) {
+ cairo_save(cr);
+ cairo_scale(cr, draw_params.hybridBigScreenScale, draw_params.hybridBigScreenScale);
+ cairo_get_matrix(cr, &nds_screen.topscreen_matrix_hybrid);
+ drawScreen(cr, buf, w, h);
+ cairo_restore(cr);
+ }
+ cairo_translate(cr, w * draw_params.hybridBigScreenScale, 0);
+ break;
}
// Used for HUD editor mode
cairo_get_matrix(cr, &nds_screen.topscreen_matrix);
@@ -1387,6 +1445,19 @@ static inline void drawBottomScreen(cairo_t* cr, u32* buf, gint w, gint h, gint
cairo_translate(cr, w, 0);
}
break;
+ case ORIENT_HYBRID_EQUAL:
+ case ORIENT_HYBRID_VERTICAL:
+ if (swap && (draw_params.hybridBigScreenScale > 0.0)) {
+ cairo_save(cr);
+ if(orientation == ORIENT_HYBRID_VERTICAL)
+ cairo_translate(cr, 0, h * (2.0 - draw_params.hybridBigScreenScale) + gap);
+ cairo_scale(cr, draw_params.hybridBigScreenScale, draw_params.hybridBigScreenScale);
+ cairo_get_matrix(cr, &nds_screen.touch_matrix_hybrid);
+ drawScreen(cr, buf, w, h);
+ cairo_restore(cr);
+ }
+ cairo_translate(cr, w * draw_params.hybridBigScreenScale, h + gap);
+ break;
}
// Store the matrix for converting touchscreen coordinates
cairo_get_matrix(cr, &nds_screen.touch_matrix);
@@ -1394,6 +1465,21 @@ static inline void drawBottomScreen(cairo_t* cr, u32* buf, gint w, gint h, gint
cairo_restore(cr);
}
+static void calc_hybrid_vertical_params(gint daW, gint daH, gint gap, gint dstScale, gint & imgW, gint & imgH)
+{
+ gdouble hyb_hratio1, hyb_hratio2, hyb_vratio1, hyb_vratio2, hyb_ratio1, hyb_ratio2;
+ hyb_hratio1 = (gdouble)daW / (gdouble)(GPU_FRAMEBUFFER_NATIVE_WIDTH * dstScale / 2);
+ hyb_vratio1 = (gdouble)daH / (gdouble)(GPU_FRAMEBUFFER_NATIVE_HEIGHT * dstScale + gap);
+ hyb_ratio1 = MIN(hyb_hratio1, hyb_vratio1);
+ gint w_rem = daW - GPU_FRAMEBUFFER_NATIVE_WIDTH * dstScale / 2.0 * hyb_ratio1;
+ hyb_hratio2 = (gdouble)w_rem / (gdouble)(GPU_FRAMEBUFFER_NATIVE_WIDTH * dstScale / 2);
+ hyb_vratio2 = (gdouble)daH / (gdouble)(GPU_FRAMEBUFFER_NATIVE_HEIGHT * dstScale / 2);
+ hyb_ratio2 = MIN(hyb_hratio2, hyb_vratio2);
+ imgW = GPU_FRAMEBUFFER_NATIVE_WIDTH * dstScale / 2 * (1.0 + hyb_ratio2 / hyb_ratio1);
+ imgH = GPU_FRAMEBUFFER_NATIVE_HEIGHT * dstScale + gap;
+ draw_params.hybridBigScreenScale = hyb_ratio2 / hyb_ratio1;
+}
+
/* Drawing callback */
static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
@@ -1408,51 +1494,96 @@ static gboolean ExposeDrawingArea (GtkWidget *widget, GdkEventExpose *event, gpo
u32* fbuf = video->GetDstBufferPtr();
gint dstW = video->GetDstWidth();
gint dstH = video->GetDstHeight();
-
- gint dstScale = dstW * 2 / GPU_FRAMEBUFFER_NATIVE_WIDTH; // Actual scale * 2 to handle 1.5x filters
- gint gap = nds_screen.orientation == ORIENT_VERTICAL ? nds_screen.gap_size * dstScale / 2 : 0;
- gint imgW, imgH;
- if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
- imgW = screen_size[nds_screen.orientation].width * dstScale / 2;
- imgH = screen_size[nds_screen.orientation].height * dstScale / 2 + gap;
- } else {
- imgH = screen_size[nds_screen.orientation].width * dstScale / 2;
- imgW = screen_size[nds_screen.orientation].height * dstScale / 2 + gap;
+ if(draw_params.valid)
+ if(draw_params.daW != daW || draw_params.daH != daH || draw_params.dstW != dstW || draw_params.dstH != dstH)
+ draw_params.valid = false;
+
+ if(!draw_params.valid) {
+ draw_params.daW = daW;
+ draw_params.daH = daH;
+ draw_params.dstW = dstW;
+ draw_params.dstH = dstH;
+
+ draw_params.dstScale = dstW * 2 / GPU_FRAMEBUFFER_NATIVE_WIDTH; // Actual scale * 2 to handle 1.5x filters
+
+ draw_params.gap = ((nds_screen.orientation == ORIENT_VERTICAL) || (nds_screen.orientation == ORIENT_HYBRID_EQUAL)
+ || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL)) ? nds_screen.gap_size * draw_params.dstScale / 2 : 0;
+ if(nds_screen.orientation == ORIENT_HYBRID_VERTICAL) {
+ if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180)
+ calc_hybrid_vertical_params(daW, daH, draw_params.gap, draw_params.dstScale, draw_params.imgW, draw_params.imgH);
+ else
+ calc_hybrid_vertical_params(daH, daW, draw_params.gap, draw_params.dstScale, draw_params.imgH, draw_params.imgW);
+ }
+ else {
+ if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
+ draw_params.imgW = screen_size[nds_screen.orientation].width * draw_params.dstScale / 2;
+ draw_params.imgH = screen_size[nds_screen.orientation].height * draw_params.dstScale / 2 + draw_params.gap;
+ if(nds_screen.orientation == ORIENT_HYBRID_EQUAL)
+ draw_params.imgW = (draw_params.imgW * 2.0/3.0) * (double)draw_params.imgH /
+ (double)(draw_params.imgH - draw_params.gap) + draw_params.imgW / 3.0;
+ } else {
+ draw_params.imgH = screen_size[nds_screen.orientation].width * draw_params.dstScale / 2;
+ draw_params.imgW = screen_size[nds_screen.orientation].height * draw_params.dstScale / 2 + draw_params.gap;
+ if(nds_screen.orientation == ORIENT_HYBRID_EQUAL)
+ draw_params.imgH = (draw_params.imgH * 2.0/3.0) * (double)draw_params.imgW /
+ (double)(draw_params.imgW - draw_params.gap) + draw_params.imgH / 3.0;
+ }
+ if(nds_screen.orientation == ORIENT_HYBRID_EQUAL)
+ draw_params.hybridBigScreenScale = (double)(dstH + draw_params.gap) / (double)(dstH / 2);
+ }
+
+ // Calculate scale to fit display area to window
+ gfloat hratio = (gfloat)daW / (gfloat)draw_params.imgW;
+ gfloat vratio = (gfloat)daH / (gfloat)draw_params.imgH;
+ draw_params.ratio = MIN(hratio, vratio);
+
+ draw_params.gapOffset = 0;
+ switch(nds_screen.orientation) {
+ case ORIENT_HYBRID_EQUAL:
+ draw_params.gapOffset = dstW * ((gdouble)(dstH + draw_params.gap) / (dstH / 2.0));
+ break;
+ case ORIENT_HYBRID_VERTICAL:
+ draw_params.gapOffset = dstW * draw_params.hybridBigScreenScale;
+ break;
+ }
+
+ draw_params.valid = true;
}
- // Calculate scale to fit display area to window
- gfloat hratio = (gfloat)daW / (gfloat)imgW;
- gfloat vratio = (gfloat)daH / (gfloat)imgH;
- hratio = MIN(hratio, vratio);
- vratio = hratio;
-
GdkDrawingContext *context = gdk_window_begin_draw_frame(window, gdk_window_get_clip_region(window));
cairo_t* cr = gdk_drawing_context_get_cairo_context(context);
// Scale to window size at center of area
cairo_translate(cr, daW / 2, daH / 2);
- cairo_scale(cr, hratio, vratio);
+ cairo_scale(cr, draw_params.ratio, draw_params.ratio);
// Rotate area
cairo_rotate(cr, M_PI / 180 * nds_screen.rotation_angle);
// Translate area to top-left corner
if (nds_screen.rotation_angle == 0 || nds_screen.rotation_angle == 180) {
- cairo_translate(cr, -imgW / 2, -imgH / 2);
+ cairo_translate(cr, -draw_params.imgW / 2, -draw_params.imgH / 2);
} else {
- cairo_translate(cr, -imgH / 2, -imgW / 2);
+ cairo_translate(cr, -draw_params.imgH / 2, -draw_params.imgW / 2);
}
// Draw both screens
- drawTopScreen(cr, fbuf, dstW, dstH / 2, gap, nds_screen.rotation_angle, nds_screen.swap, nds_screen.orientation);
- drawBottomScreen(cr, fbuf + dstW * dstH / 2, dstW, dstH / 2, gap, nds_screen.rotation_angle, nds_screen.swap, nds_screen.orientation);
+ drawTopScreen(cr, fbuf, dstW, dstH / 2, draw_params.gap, nds_screen.rotation_angle, nds_screen.swap, nds_screen.orientation);
+ drawBottomScreen(cr, fbuf + dstW * dstH / 2, dstW, dstH / 2, draw_params.gap, nds_screen.rotation_angle, nds_screen.swap, nds_screen.orientation);
// Draw gap
+
cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
- cairo_rectangle(cr, 0, dstH / 2, dstW, gap);
+ cairo_rectangle(cr, draw_params.gapOffset, dstH / 2, dstW, draw_params.gap);
cairo_fill(cr);
// Complete the touch transformation matrix
- cairo_matrix_scale(&nds_screen.topscreen_matrix, (double)dstScale / 2, (double)dstScale / 2);
+ cairo_matrix_scale(&nds_screen.topscreen_matrix, (double)draw_params.dstScale / 2, (double)draw_params.dstScale / 2);
cairo_matrix_invert(&nds_screen.topscreen_matrix);
- cairo_matrix_scale(&nds_screen.touch_matrix, (double)dstScale / 2, (double)dstScale / 2);
+ cairo_matrix_scale(&nds_screen.touch_matrix, (double)draw_params.dstScale / 2, (double)draw_params.dstScale / 2);
cairo_matrix_invert(&nds_screen.touch_matrix);
+ if((nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL)) {
+ cairo_matrix_scale(&nds_screen.topscreen_matrix_hybrid, (double)draw_params.dstScale / 2, (double)draw_params.dstScale / 2);
+ cairo_matrix_invert(&nds_screen.topscreen_matrix_hybrid);
+ cairo_matrix_scale(&nds_screen.touch_matrix_hybrid, (double)draw_params.dstScale / 2, (double)draw_params.dstScale / 2);
+ cairo_matrix_invert(&nds_screen.touch_matrix_hybrid);
+ }
gdk_window_end_draw_frame(window, context);
draw_count++;
@@ -1476,12 +1607,17 @@ static void RedrawScreen() {
/////////////////////////////// KEYS AND STYLUS UPDATE ///////////////////////////////////////
+static bool move_started_in_big_screen = false;
+static bool hud_move_started_in_big_screen = false;
+
#ifdef HAVE_LIBAGG
static gboolean rotoscaled_hudedit(gint x, gint y, gboolean start)
{
double devX, devY;
- gint X, Y, topX = -1, topY = -1, botX = -1, botY = -1;
+ gint X, Y, topX = -1, topY = -1, botX = -1, botY = -1, hybTopX = -1, hybTopY = -1, hybBotX = -1, hybBotY = -1;
static gint startScreen = 0;
+ bool hybrid = ((nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL)) &&
+ (draw_params.hybridBigScreenScale > 0.0);
if (nds_screen.orientation != ORIENT_SINGLE || !nds_screen.swap) {
devX = x;
@@ -1489,6 +1625,14 @@ static gboolean rotoscaled_hudedit(gint x, gint y, gboolean start)
cairo_matrix_transform_point(&nds_screen.topscreen_matrix, &devX, &devY);
topX = devX * gpu_scale_factor;
topY = devY * gpu_scale_factor;
+
+ if(hybrid && !nds_screen.swap) {
+ devX = x;
+ devY = y;
+ cairo_matrix_transform_point(&nds_screen.topscreen_matrix_hybrid, &devX, &devY);
+ hybTopX = devX * gpu_scale_factor;
+ hybTopY = devY * gpu_scale_factor;
+ }
}
if (nds_screen.orientation != ORIENT_SINGLE || nds_screen.swap) {
@@ -1497,23 +1641,57 @@ static gboolean rotoscaled_hudedit(gint x, gint y, gboolean start)
cairo_matrix_transform_point(&nds_screen.touch_matrix, &devX, &devY);
botX = devX * gpu_scale_factor;
botY = devY * gpu_scale_factor;
+
+ if(hybrid && nds_screen.swap) {
+ devX = x;
+ devY = y;
+ cairo_matrix_transform_point(&nds_screen.touch_matrix_hybrid, &devX, &devY);
+ hybBotX = devX * gpu_scale_factor;
+ hybBotY = devY * gpu_scale_factor;
+ }
}
if (topX >= 0 && topY >= 0 && topX < real_framebuffer_width && topY < real_framebuffer_height) {
X = topX;
- Y = topY + (nds_screen.swap ? real_framebuffer_height : 0);
+ Y = topY + (osd->swapScreens ? real_framebuffer_height : 0);
+ startScreen = 0;
+ if(start)
+ hud_move_started_in_big_screen = false;
+ } else if (hybTopX >= 0 && hybTopY >= 0 && hybTopX < real_framebuffer_width && hybTopY < real_framebuffer_height) {
+ X = hybTopX;
+ Y = hybTopY;
startScreen = 0;
+ if(start)
+ hud_move_started_in_big_screen = true;
} else if (botX >= 0 && botY >= 0 && botX < real_framebuffer_width && botY < real_framebuffer_height) {
X = botX;
- Y = botY + (nds_screen.swap ? 0 : real_framebuffer_height);
+ Y = botY + (osd->swapScreens ? 0 : real_framebuffer_height);
startScreen = 1;
+ if(start)
+ hud_move_started_in_big_screen = false;
+ } else if (hybBotX >= 0 && hybBotY >= 0 && hybBotX < real_framebuffer_width && hybBotY < real_framebuffer_height) {
+ X = hybBotX;
+ Y = hybBotY + real_framebuffer_height;
+ startScreen = 1;
+ if(start)
+ hud_move_started_in_big_screen = true;
} else if (!start) {
if (startScreen == 0) {
- X = CLAMP(topX, 0, real_framebuffer_width-1);
- Y = CLAMP(topY, 0, real_framebuffer_height-1) + (nds_screen.swap ? real_framebuffer_height : 0);
+ if(!hud_move_started_in_big_screen || !hybrid) {
+ X = CLAMP(topX, 0, real_framebuffer_width-1);
+ Y = CLAMP(topY, 0, real_framebuffer_height-1) + (osd->swapScreens ? real_framebuffer_height : 0);
+ } else {
+ X = CLAMP(hybTopX, 0, real_framebuffer_width-1);
+ Y = CLAMP(hybTopY, 0, real_framebuffer_height-1);
+ }
} else {
- X = CLAMP(botX, 0, real_framebuffer_width-1);
- Y = CLAMP(botY, 0, real_framebuffer_height-1) + (nds_screen.swap ? 0 : real_framebuffer_height);
+ if(!hud_move_started_in_big_screen || !hybrid) {
+ X = CLAMP(botX, 0, real_framebuffer_width-1);
+ Y = CLAMP(botY, 0, real_framebuffer_height-1) + (osd->swapScreens ? 0 : real_framebuffer_height);
+ } else {
+ X = CLAMP(hybBotX, 0, real_framebuffer_width-1);
+ Y = CLAMP(hybBotY, 0, real_framebuffer_height-1) + real_framebuffer_height;
+ }
}
} else {
LOG("TopX=%d, TopY=%d, BotX=%d, BotY=%d\n", topX, topY, botX, botY);
@@ -1545,13 +1723,33 @@ static gboolean rotoscaled_touchpos(gint x, gint y, gboolean start)
LOG("X=%d, Y=%d\n", X, Y);
- if (!start || (X >= 0 && Y >= 0 && X < 256 && Y < 192)) {
+ if ((!start && !move_started_in_big_screen) || (X >= 0 && Y >= 0 && X < 256 && Y < 192)) {
+ if(start)
+ move_started_in_big_screen = false;
EmuX = CLAMP(X, 0, 255);
EmuY = CLAMP(Y, 0, 191);
NDS_setTouchPos(EmuX, EmuY);
return TRUE;
}
-
+
+ if((((nds_screen.orientation == ORIENT_HYBRID_EQUAL) ||
+ (nds_screen.orientation == ORIENT_HYBRID_VERTICAL)) && (draw_params.hybridBigScreenScale > 0.0)) && (nds_screen.swap)) {
+ devX = x;
+ devY = y;
+ cairo_matrix_transform_point(&nds_screen.touch_matrix_hybrid, &devX, &devY);
+ X = devX;
+ Y = devY;
+
+ if ((!start && move_started_in_big_screen) || (X >= 0 && Y >= 0 && X < 256 && Y < 192)) {
+ if(start)
+ move_started_in_big_screen = true;
+ EmuX = CLAMP(X, 0, 255);
+ EmuY = CLAMP(Y, 0, 191);
+ NDS_setTouchPos(EmuX, EmuY);
+ return TRUE;
+ }
+ }
+
return FALSE;
}
@@ -3450,7 +3648,7 @@ common_gtk_main(GApplication *app, gpointer user_data)
}
g_simple_action_set_state(G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "winsize")), g_variant_new_string(string.c_str()));
- if (config.view_orient < ORIENT_VERTICAL || config.view_orient > ORIENT_SINGLE) {
+ if (config.view_orient < ORIENT_VERTICAL || config.view_orient > ORIENT_HYBRID_VERTICAL) {
config.view_orient = ORIENT_VERTICAL;
}
nds_screen.orientation = (orientation_enum)config.view_orient.get();
@@ -3464,6 +3662,12 @@ common_gtk_main(GApplication *app, gpointer user_data)
case ORIENT_SINGLE:
string = "single";
break;
+ case ORIENT_HYBRID_EQUAL:
+ string = "hybrid_equal";
+ break;
+ case ORIENT_HYBRID_VERTICAL:
+ string = "hybrid_vertical";
+ break;
}
g_simple_action_set_state(G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "orient")), g_variant_new_string(string.c_str()));
@@ -3484,6 +3688,10 @@ common_gtk_main(GApplication *app, gpointer user_data)
nds_screen.gap_size = config.view_gap ? GAP_SIZE : 0;
nds_screen.swap = config.view_swap;
+ #ifdef HAVE_LIBAGG
+ bool hybrid = (nds_screen.orientation == ORIENT_HYBRID_EQUAL) || (nds_screen.orientation == ORIENT_HYBRID_VERTICAL);
+ osd->swapScreens = nds_screen.swap && !hybrid;
+ #endif
g_simple_action_set_state(G_SIMPLE_ACTION(g_action_map_lookup_action(G_ACTION_MAP(app), "swapscreens")), g_variant_new_boolean(config.view_swap));
builder = gtk_builder_new_from_resource("/org/desmume/DeSmuME/menu.ui");
diff --git a/desmume/src/frontend/posix/gtk/menu.ui b/desmume/src/frontend/posix/gtk/menu.ui
index 807efa898..c9369d697 100644
--- a/desmume/src/frontend/posix/gtk/menu.ui
+++ b/desmume/src/frontend/posix/gtk/menu.ui
@@ -254,6 +254,18 @@
app.orient
single
<Control>0
+
+ -
+ Hybrid (_equal height)
+ app.orient
+ hybrid_equal
+ <Control>3
+
+ -
+ Hybrid (e_mphasize vertical)
+ app.orient
+ hybrid_vertical
+ <Control>4