Add small hybrid screen core option

This commit is contained in:
Mats 2021-09-22 23:27:23 +02:00
parent 90ac1276ab
commit f173be0f39
4 changed files with 99 additions and 20 deletions

View File

@ -159,13 +159,14 @@ void retro_set_environment(retro_environment_t cb)
{
{ "melonds_boot_directly", "Boot game directly; enabled|disabled" },
{ "melonds_screen_layout", "Screen Layout; Top/Bottom|Bottom/Top|Left/Right|Right/Left|Top Only|Bottom Only|Hybrid Top|Hybrid Bottom" },
{ "melonds_hybrid_ratio", "Hybrid ratio; 2|3" },
{ "melonds_hybrid_small_screen", "Hybrid small screen mode; Bottom|Top|Duplicate" },
{ "melonds_swapscreen_mode", "Swap Screen mode; Toggle|Hold" },
#ifdef HAVE_THREADS
{ "melonds_threaded_renderer", "Threaded software renderer; disabled|enabled" },
#endif
{ "melonds_touch_mode", "Touch mode; disabled|Mouse|Touch|Joystick" },
#ifdef HAVE_OPENGL
{ "melonds_hybrid_ratio", "Hybrid ratio (OpenGL only); 2|3" },
{ "melonds_opengl_renderer", "OpenGL Renderer (Restart); disabled|enabled" },
{ "melonds_opengl_resolution", opengl_resolution.c_str() },
{ "melonds_opengl_better_polygons", "OpenGL Improved polygon splitting; disabled|enabled" },
@ -246,6 +247,10 @@ static void check_variables(bool init)
{
struct retro_variable var = {0};
#ifdef HAVE_OPENGL
bool gl_update = false;
#endif
var.key = "melonds_boot_directly";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
@ -277,11 +282,33 @@ static void check_variables(bool init)
layout = ScreenLayout::HybridBottom;
}
#ifdef HAVE_OPENGL
var.key = "melonds_hybrid_ratio";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value != NULL)
{
screen_layout_data.hybrid_ratio = std::stoi(var.value);
}
#else
screen_layout_data.hybrid_ratio = 2;
#endif
var.key = "melonds_hybrid_small_screen";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value != NULL)
{
SmallScreenLayout old_hybrid_screen_value = screen_layout_data.hybrid_small_screen; // Copy the hybrid screen value
if (!strcmp(var.value, "Top"))
screen_layout_data.hybrid_small_screen = SmallScreenLayout::SmallScreenTop;
else if (!strcmp(var.value, "Bottom"))
screen_layout_data.hybrid_small_screen = SmallScreenLayout::SmallScreenBottom;
else
screen_layout_data.hybrid_small_screen = SmallScreenLayout::SmallScreenDuplicate;
#ifdef HAVE_OPENGL
if(old_hybrid_screen_value != screen_layout_data.hybrid_small_screen) {
gl_update = true;
}
#endif
}
var.key = "melonds_swapscreen_mode";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value != NULL)
@ -314,8 +341,6 @@ static void check_variables(bool init)
}
#ifdef HAVE_OPENGL
bool gl_update = false;
if(input_state.current_touch_mode != new_touch_mode) // Hide the cursor
gl_update = true;
@ -485,9 +510,20 @@ static void render_frame(void)
unsigned primary = screen_layout_data.displayed_layout == ScreenLayout::HybridTop ? 0 : 1;
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][primary], ScreenId::Primary);
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][0], ScreenId::Top);
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][1], ScreenId::Bottom);
switch(screen_layout_data.hybrid_small_screen) {
case SmallScreenLayout::SmallScreenTop:
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][0], ScreenId::Bottom);
break;
case SmallScreenLayout::SmallScreenBottom:
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][1], ScreenId::Bottom);
break;
case SmallScreenLayout::SmallScreenDuplicate:
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][0], ScreenId::Top);
copy_hybrid_screen(&screen_layout_data, GPU::Framebuffer[frontbuf][1], ScreenId::Bottom);
break;
}
if(cursor_enabled(&input_state))
draw_cursor(&screen_layout_data, input_state.touch_x, input_state.touch_y);
@ -560,6 +596,7 @@ void retro_run(void)
struct retro_system_av_info updated_av_info;
retro_get_system_av_info(&updated_av_info);
environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &updated_av_info);
clean_screenlayout_buffer(&screen_layout_data);
}
}

View File

@ -279,20 +279,45 @@ void setup_opengl_frame_state(void)
SETVERTEX(5, primary_x, primary_y, primary_tex_v5_x, primary_tex_v5_y); // bottom right
//Top screen
SETVERTEX(6, primary_x, 0.0f, 0.0f, 0.0f); // top left
SETVERTEX(7, primary_x, 0.0f + screen_height, 0.0f, 0.5f - pixel_pad); // bottom left
SETVERTEX(8, primary_x + screen_width, 0.0f + screen_height, 1.0f, 0.5f - pixel_pad); // bottom right
SETVERTEX(9, primary_x, 0.0f, 0.0f, 0.0f); // top left
SETVERTEX(10, primary_x + screen_width, 0.0f, 1.0f, 0.0f); // top right
SETVERTEX(11, primary_x + screen_width, 0.0f + screen_height, 1.0f, 0.5f - pixel_pad); // bottom right
if(screen_layout_data.hybrid_small_screen == SmallScreenLayout::SmallScreenTop)
{
SETVERTEX(6, primary_x, 0.0f, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(7, primary_x, 0.0f + screen_height, 0.0f, 1.0f); // bottom left
SETVERTEX(8, primary_x + screen_width, 0.0f + screen_height, 1.0f, 1.0f); // bottom right
SETVERTEX(9, primary_x, 0.0f, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(10, primary_x + screen_width, 0.0f, 1.0f, 0.5f + pixel_pad); // top right
SETVERTEX(11, primary_x + screen_width, 0.0f + screen_height, 1.0f, 1.0f); // bottom right
}
else if (screen_layout_data.hybrid_small_screen == SmallScreenLayout::SmallScreenDuplicate)
{
SETVERTEX(6, primary_x, 0.0f, 0.0f, 0.0f); // top left
SETVERTEX(7, primary_x, 0.0f + screen_height, 0.0f, 0.5f - pixel_pad); // bottom left
SETVERTEX(8, primary_x + screen_width, 0.0f + screen_height, 1.0f, 0.5f - pixel_pad); // bottom right
SETVERTEX(9, primary_x, 0.0f, 0.0f, 0.0f); // top left
SETVERTEX(10, primary_x + screen_width, 0.0f, 1.0f, 0.0f); // top right
SETVERTEX(11, primary_x + screen_width, 0.0f + screen_height, 1.0f, 0.5f - pixel_pad); // bottom right
}
//Bottom Screen
SETVERTEX(12, primary_x, primary_y - screen_height, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(13, primary_x, primary_y, 0.0f, 1.0f); // bottom left
SETVERTEX(14, primary_x + screen_width, primary_y, 1.0f, 1.0f); // bottom right
SETVERTEX(15, primary_x, primary_y - screen_height, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(16, primary_x + screen_width, primary_y - screen_height, 1.0f, 0.5f + pixel_pad); // top right
SETVERTEX(17, primary_x + screen_width, primary_y, 1.0f, 1.0f); // bottom right
if(screen_layout_data.hybrid_small_screen == SmallScreenLayout::SmallScreenBottom)
{
SETVERTEX(6, primary_x, primary_y - screen_height, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(7, primary_x, primary_y, 0.0f, 1.0f); // bottom left
SETVERTEX(8, primary_x + screen_width, primary_y, 1.0f, 1.0f); // bottom right
SETVERTEX(9, primary_x, primary_y - screen_height, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(10, primary_x + screen_width, primary_y - screen_height, 1.0f, 0.5f + pixel_pad); // top right
SETVERTEX(11, primary_x + screen_width, primary_y, 1.0f, 1.0f); // bottom right
}
else if (screen_layout_data.hybrid_small_screen == SmallScreenLayout::SmallScreenDuplicate)
{
SETVERTEX(12, primary_x, primary_y - screen_height, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(13, primary_x, primary_y, 0.0f, 1.0f); // bottom left
SETVERTEX(14, primary_x + screen_width, primary_y, 1.0f, 1.0f); // bottom right
SETVERTEX(15, primary_x, primary_y - screen_height, 0.0f, 0.5f + pixel_pad); // top left
SETVERTEX(16, primary_x + screen_width, primary_y - screen_height, 1.0f, 0.5f + pixel_pad); // top right
SETVERTEX(17, primary_x + screen_width, primary_y, 1.0f, 1.0f); // bottom right
}
}
else
{
@ -331,8 +356,9 @@ void render_opengl_frame(bool sw)
if(refresh_opengl)
{
glClearColor(0,0,0,0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
setup_opengl_frame_state();
glClearColor(0, 0, 0, 1);
}
if(virtual_cursor)
@ -381,7 +407,7 @@ void render_opengl_frame(bool sw)
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 18);
glDrawArrays(GL_TRIANGLES, 0, screen_layout_data.hybrid_small_screen == SmallScreenLayout::SmallScreenDuplicate ? 18 : 12);
glFlush();

View File

@ -211,3 +211,11 @@ void update_screenlayout(ScreenLayout layout, ScreenLayoutData *data, bool openg
}
}
}
void clean_screenlayout_buffer(ScreenLayoutData *data)
{
if(data->buffer_ptr == NULL) return;
unsigned size = data->buffer_stride * data->buffer_height;
memset(data->buffer_ptr, 0, size);
}

View File

@ -23,6 +23,12 @@ enum ScreenLayout
HybridBottom = 7,
};
enum SmallScreenLayout
{
SmallScreenTop = 0,
SmallScreenBottom = 1,
SmallScreenDuplicate = 2
};
enum ScreenId
{
@ -49,6 +55,7 @@ struct ScreenLayoutData
unsigned touch_offset_y;
bool hybrid;
SmallScreenLayout hybrid_small_screen;
unsigned hybrid_ratio;
unsigned buffer_width;
@ -65,4 +72,5 @@ extern GPU::RenderSettings video_settings;
void initialize_screnlayout_data(ScreenLayoutData *data);
void update_screenlayout(ScreenLayout layout, ScreenLayoutData *data, bool opengl, bool swap_screens);
void clean_screenlayout_buffer(ScreenLayoutData *data);
#endif