mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 03:29:43 +00:00
ui: Make aspect ratio config independent, add autodetect
This commit is contained in:
parent
129c48dd6e
commit
0ee7502c23
@ -138,8 +138,12 @@ display:
|
||||
default: true
|
||||
fit:
|
||||
type: enum
|
||||
values: [center, scale, scale_16_9, scale_4_3, stretch]
|
||||
values: [center, scale, stretch]
|
||||
default: scale
|
||||
aspect_ratio:
|
||||
type: enum
|
||||
values: [native, auto, 4x3, 16x9]
|
||||
default: auto
|
||||
scale:
|
||||
type: integer
|
||||
default: 1
|
||||
|
2
dtc
2
dtc
@ -1 +1 @@
|
||||
Subproject commit 85e5d839847af54efab170f2b1331b2a6421e647
|
||||
Subproject commit b6910bec11614980a21e46fbccc35934b671bd81
|
@ -30,6 +30,7 @@
|
||||
#include "hw/xbox/xbox_pci.h"
|
||||
#include "hw/xbox/acpi_xbox.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "ui/xemu-widescreen.h"
|
||||
|
||||
// #define DEBUG
|
||||
#ifdef DEBUG
|
||||
@ -44,6 +45,8 @@
|
||||
#define XBOX_PM_GPIO_BASE 0xC0
|
||||
#define XBOX_PM_GPIO_LEN 26
|
||||
|
||||
#define XBOX_PM_GPIO_ASPECT_RATIO 0x16
|
||||
|
||||
static int field_pin;
|
||||
|
||||
static uint64_t xbox_pm_gpio_read(void *opaque, hwaddr addr, unsigned width)
|
||||
@ -66,6 +69,12 @@ static void xbox_pm_gpio_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned width)
|
||||
{
|
||||
XBOX_DPRINTF("pm gpio write [0x%llx] = 0x%llx\n", addr, val);
|
||||
|
||||
if (addr == XBOX_PM_GPIO_ASPECT_RATIO) {
|
||||
xemu_set_widescreen(val == 5);
|
||||
}
|
||||
|
||||
// FIXME: Add GPIO to VM state
|
||||
}
|
||||
|
||||
static const MemoryRegionOps xbox_pm_gpio_ops = {
|
||||
|
2
meson
2
meson
@ -1 +1 @@
|
||||
Subproject commit 776acd2a805c9b42b4f0375150977df42130317f
|
||||
Subproject commit 3a9b285a55b91b53b2acda987192274352ecb5be
|
@ -28,6 +28,7 @@ xemu_ss.add(files(
|
||||
'xemu-data.c',
|
||||
'xemu-snapshots.c',
|
||||
'xemu-thumbnail.cc',
|
||||
'xemu-widescreen.c',
|
||||
))
|
||||
|
||||
subdir('xui')
|
||||
|
37
ui/xemu-widescreen.c
Normal file
37
ui/xemu-widescreen.c
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* xemu wide screen handler
|
||||
*
|
||||
* Copyright (c) 2023 Matt Borgerson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "xemu-widescreen.h"
|
||||
|
||||
static bool g_widescreen = false;
|
||||
|
||||
void xemu_set_widescreen(bool widescreen)
|
||||
{
|
||||
g_widescreen = widescreen;
|
||||
}
|
||||
|
||||
bool xemu_get_widescreen(void)
|
||||
{
|
||||
return g_widescreen;
|
||||
}
|
40
ui/xemu-widescreen.h
Normal file
40
ui/xemu-widescreen.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* xemu wide screen handler
|
||||
*
|
||||
* Copyright (c) 2023 Matt Borgerson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef XEMU_WIDESCREEN
|
||||
#define XEMU_WIDESCREEN
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void xemu_set_widescreen(bool widescreen);
|
||||
bool xemu_get_widescreen(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -28,6 +28,7 @@
|
||||
#include "ui/shader/xemu-logo-frag.h"
|
||||
#include "data/xemu_64x64.png.h"
|
||||
#include "notifications.hh"
|
||||
#include "ui/xemu-widescreen.h"
|
||||
|
||||
Fbo *controller_fbo,
|
||||
*logo_fbo;
|
||||
@ -706,6 +707,21 @@ void RenderFramebuffer(GLint tex, int width, int height, bool flip, float scale[
|
||||
}
|
||||
}
|
||||
|
||||
float GetDisplayAspectRatio(int width, int height)
|
||||
{
|
||||
switch (g_config.display.ui.aspect_ratio) {
|
||||
case CONFIG_DISPLAY_UI_ASPECT_RATIO_NATIVE:
|
||||
return (float)width/(float)height;
|
||||
case CONFIG_DISPLAY_UI_ASPECT_RATIO_16X9:
|
||||
return 16.0f/9.0f;
|
||||
case CONFIG_DISPLAY_UI_ASPECT_RATIO_4X3:
|
||||
return 4.0f/3.0f;
|
||||
case CONFIG_DISPLAY_UI_ASPECT_RATIO_AUTO:
|
||||
default:
|
||||
return xemu_get_widescreen() ? 16.0f/9.0f : 4.0f/3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderFramebuffer(GLint tex, int width, int height, bool flip)
|
||||
{
|
||||
int tw, th;
|
||||
@ -723,20 +739,11 @@ void RenderFramebuffer(GLint tex, int width, int height, bool flip)
|
||||
scale[1] = 1.0;
|
||||
} else if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_CENTER) {
|
||||
// Centered
|
||||
scale[0] = (float)tw/(float)width;
|
||||
float t_ratio = GetDisplayAspectRatio(tw, th);
|
||||
scale[0] = t_ratio*(float)th/(float)width;
|
||||
scale[1] = (float)th/(float)height;
|
||||
} else {
|
||||
float t_ratio;
|
||||
if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_SCALE_16_9) {
|
||||
// Scale to fit window using a fixed 16:9 aspect ratio
|
||||
t_ratio = 16.0f/9.0f;
|
||||
} else if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_SCALE_4_3) {
|
||||
t_ratio = 4.0f/3.0f;
|
||||
} else {
|
||||
// Scale to fit, preserving framebuffer aspect ratio
|
||||
t_ratio = (float)tw/(float)th;
|
||||
}
|
||||
|
||||
float t_ratio = GetDisplayAspectRatio(tw, th);
|
||||
float w_ratio = (float)width/(float)height;
|
||||
if (w_ratio >= t_ratio) {
|
||||
scale[0] = t_ratio/w_ratio;
|
||||
@ -759,11 +766,7 @@ bool RenderFramebufferToPng(GLuint tex, bool flip, std::vector<uint8_t> &png, in
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
|
||||
|
||||
if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_SCALE_16_9) {
|
||||
width = height * (16.0f / 9.0f);
|
||||
} else if (g_config.display.ui.fit == CONFIG_DISPLAY_UI_FIT_SCALE_4_3) {
|
||||
width = height * (4.0f / 3.0f);
|
||||
}
|
||||
width = height * GetDisplayAspectRatio(width, height);
|
||||
|
||||
if (!max_width) max_width = width;
|
||||
if (!max_height) max_height = height;
|
||||
|
@ -340,10 +340,14 @@ void MainMenuDisplayView::Draw()
|
||||
ChevronCombo("Display mode", &g_config.display.ui.fit,
|
||||
"Center\0"
|
||||
"Scale\0"
|
||||
"Scale (Widescreen 16:9)\0"
|
||||
"Scale (4:3)\0"
|
||||
"Stretch\0",
|
||||
"Select how the framebuffer should fit or scale into the window");
|
||||
ChevronCombo("Aspect ratio", &g_config.display.ui.aspect_ratio,
|
||||
"Native\0"
|
||||
"Auto (Default)\0"
|
||||
"4:3\0"
|
||||
"16:9\0",
|
||||
"Select the displayed aspect ratio");
|
||||
}
|
||||
|
||||
void MainMenuAudioView::Draw()
|
||||
|
@ -191,11 +191,12 @@ void ShowMainMenu()
|
||||
}
|
||||
|
||||
ImGui::Combo("Display Mode", &g_config.display.ui.fit,
|
||||
"Center\0Scale\0Scale (Widescreen 16:9)\0Scale "
|
||||
"(4:3)\0Stretch\0");
|
||||
"Center\0Scale\0Stretch\0");
|
||||
ImGui::SameLine();
|
||||
HelpMarker("Controls how the rendered content should be scaled "
|
||||
"into the window");
|
||||
ImGui::Combo("Aspect Ratio", &g_config.display.ui.aspect_ratio,
|
||||
"Native\0Auto\0""4:3\0""16:9\0");
|
||||
if (ImGui::MenuItem("Fullscreen", SHORTCUT_MENU_TEXT(Alt + F),
|
||||
xemu_is_fullscreen(), true)) {
|
||||
xemu_toggle_fullscreen();
|
||||
|
@ -258,7 +258,7 @@ public:
|
||||
bool DrawItems(PopupMenuItemDelegate &nav) override
|
||||
{
|
||||
const char *values[] = {
|
||||
"Center", "Scale", "Scale (Widescreen 16:9)", "Scale (4:3)", "Stretch"
|
||||
"Center", "Scale", "Stretch"
|
||||
};
|
||||
|
||||
for (int i = 0; i < CONFIG_DISPLAY_UI_FIT__COUNT; i++) {
|
||||
@ -272,11 +272,34 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class AspectRatioPopupMenu : public virtual PopupMenu {
|
||||
public:
|
||||
bool DrawItems(PopupMenuItemDelegate &nav) override
|
||||
{
|
||||
const char *values[] = {
|
||||
"Native",
|
||||
"Auto (Default)",
|
||||
"4:3",
|
||||
"16:9"
|
||||
};
|
||||
|
||||
for (int i = 0; i < CONFIG_DISPLAY_UI_ASPECT_RATIO__COUNT; i++) {
|
||||
bool selected = g_config.display.ui.aspect_ratio == i;
|
||||
if (m_focus && selected) ImGui::SetKeyboardFocusHere();
|
||||
if (PopupMenuCheck(values[i], "", selected))
|
||||
g_config.display.ui.aspect_ratio = i;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
extern MainMenuScene g_main_menu;
|
||||
|
||||
class SettingsPopupMenu : public virtual PopupMenu {
|
||||
protected:
|
||||
DisplayModePopupMenu display_mode;
|
||||
AspectRatioPopupMenu aspect_ratio;
|
||||
|
||||
public:
|
||||
bool DrawItems(PopupMenuItemDelegate &nav) override
|
||||
@ -295,6 +318,10 @@ public:
|
||||
nav.PushFocus();
|
||||
nav.PushMenu(display_mode);
|
||||
}
|
||||
if (PopupMenuSubmenuButton("Aspect Ratio", ICON_FA_EXPAND)) {
|
||||
nav.PushFocus();
|
||||
nav.PushMenu(aspect_ratio);
|
||||
}
|
||||
if (PopupMenuButton("Snapshots...", ICON_FA_CLOCK_ROTATE_LEFT)) {
|
||||
nav.ClearMenuStack();
|
||||
g_scene_mgr.PushScene(g_main_menu);
|
||||
|
Loading…
Reference in New Issue
Block a user