mirror of
https://github.com/gopher64/gopher64.git
synced 2026-07-11 01:25:20 +02:00
Add integer scaling option (#150)
* Add integer scaling option * more * more * more
This commit is contained in:
+31
-21
@@ -51,6 +51,7 @@ enum vi_registers
|
||||
};
|
||||
|
||||
static bool fullscreen;
|
||||
static bool integer_scaling;
|
||||
static SDL_Window *window;
|
||||
static RDP::CommandProcessor *processor;
|
||||
static SDL_WSIPlatform *wsi_platform;
|
||||
@@ -166,13 +167,14 @@ int sdl_event_filter(void *userdata, SDL_Event *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rdp_init(void *_window, GFX_INFO _gfx_info, bool _fullscreen, bool _upscale)
|
||||
void rdp_init(void *_window, GFX_INFO _gfx_info, bool _upscale, bool _integer_scaling, bool _fullscreen)
|
||||
{
|
||||
window = (SDL_Window *)_window;
|
||||
SDL_AddEventWatch(sdl_event_filter, nullptr);
|
||||
|
||||
gfx_info = _gfx_info;
|
||||
fullscreen = _fullscreen;
|
||||
integer_scaling = _integer_scaling;
|
||||
bool window_vsync = 0;
|
||||
wsi = new WSI;
|
||||
wsi_platform = new SDL_WSIPlatform;
|
||||
@@ -234,34 +236,42 @@ void rdp_close()
|
||||
|
||||
static void calculate_viewport(float *x, float *y, float *width, float *height)
|
||||
{
|
||||
bool window_widescreen = false;
|
||||
int32_t display_width = (window_widescreen ? 854 : 640);
|
||||
int32_t display_height = 480;
|
||||
const int32_t display_width = 320;
|
||||
const int32_t display_height = 240;
|
||||
|
||||
int w, h;
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
|
||||
*width = w;
|
||||
*height = h;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
int32_t hw = display_height * *width;
|
||||
int32_t wh = display_width * *height;
|
||||
if (integer_scaling)
|
||||
{
|
||||
// Integer scaling path
|
||||
int scale_x = w / display_width;
|
||||
int scale_y = h / display_height;
|
||||
int scale = (scale_x < scale_y) ? scale_x : scale_y;
|
||||
if (scale < 1)
|
||||
scale = 1;
|
||||
|
||||
// add letterboxes or pillarboxes if the window has a different aspect ratio
|
||||
// than the current display mode
|
||||
if (hw > wh)
|
||||
{
|
||||
int32_t w_max = wh / display_height;
|
||||
*x += (*width - w_max) / 2;
|
||||
*width = w_max;
|
||||
// Calculate scaled dimensions
|
||||
int scaled_width = display_width * scale;
|
||||
int scaled_height = display_height * scale;
|
||||
|
||||
*width = scaled_width;
|
||||
*height = scaled_height;
|
||||
}
|
||||
else if (hw < wh)
|
||||
else
|
||||
{
|
||||
int32_t h_max = hw / display_width;
|
||||
*y += (*height - h_max) / 2;
|
||||
*height = h_max;
|
||||
// Regular scaling path - maintain aspect ratio
|
||||
float scale_x = w / (float)display_width;
|
||||
float scale_y = h / (float)display_height;
|
||||
float scale = (scale_x < scale_y) ? scale_x : scale_y;
|
||||
|
||||
*width = display_width * scale;
|
||||
*height = display_height * scale;
|
||||
}
|
||||
|
||||
// Center the viewport
|
||||
*x = (w - *width) / 2.0f;
|
||||
*y = (h - *height) / 2.0f;
|
||||
}
|
||||
|
||||
static void render_frame(Vulkan::Device &device)
|
||||
|
||||
@@ -23,7 +23,7 @@ extern "C"
|
||||
uint32_t *VI_WIDTH_REG;
|
||||
} GFX_INFO;
|
||||
|
||||
void rdp_init(void *_window, GFX_INFO _gfx_info, bool _fullscreen, bool _upscale);
|
||||
void rdp_init(void *_window, GFX_INFO _gfx_info, bool _upscale, bool _integer_scaling, bool _fullscreen);
|
||||
void rdp_close();
|
||||
void rdp_set_vi_register(uint32_t reg, uint32_t value);
|
||||
bool rdp_update_screen();
|
||||
|
||||
@@ -21,6 +21,7 @@ pub struct Input {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
pub struct Video {
|
||||
pub upscale: bool,
|
||||
pub integer_scaling: bool,
|
||||
pub fullscreen: bool,
|
||||
}
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
@@ -48,6 +49,7 @@ impl Config {
|
||||
},
|
||||
video: Video {
|
||||
upscale: false,
|
||||
integer_scaling: false,
|
||||
fullscreen: false,
|
||||
},
|
||||
}
|
||||
|
||||
+39
-27
@@ -14,6 +14,7 @@ pub struct GopherEguiApp {
|
||||
input_profiles: Vec<String>,
|
||||
controller_enabled: [bool; 4],
|
||||
upscale: bool,
|
||||
integer_scaling: bool,
|
||||
fullscreen: bool,
|
||||
emulate_vru: bool,
|
||||
show_vru_dialog: bool,
|
||||
@@ -22,6 +23,16 @@ pub struct GopherEguiApp {
|
||||
vru_word_list: Vec<String>,
|
||||
}
|
||||
|
||||
struct SaveConfig {
|
||||
selected_controller: [i32; 4],
|
||||
selected_profile: [String; 4],
|
||||
controller_enabled: [bool; 4],
|
||||
upscale: bool,
|
||||
integer_scaling: bool,
|
||||
fullscreen: bool,
|
||||
emulate_vru: bool,
|
||||
}
|
||||
|
||||
fn get_input_profiles(game_ui: &ui::Ui) -> Vec<String> {
|
||||
let mut profiles = vec![];
|
||||
for key in game_ui.config.input.input_profiles.keys() {
|
||||
@@ -85,6 +96,7 @@ impl GopherEguiApp {
|
||||
input_profiles: get_input_profiles(&game_ui),
|
||||
controller_enabled: game_ui.config.input.controller_enabled,
|
||||
upscale: game_ui.config.video.upscale,
|
||||
integer_scaling: game_ui.config.video.integer_scaling,
|
||||
fullscreen: game_ui.config.video.fullscreen,
|
||||
emulate_vru: game_ui.config.input.emulate_vru,
|
||||
show_vru_dialog: false,
|
||||
@@ -95,17 +107,9 @@ impl GopherEguiApp {
|
||||
}
|
||||
}
|
||||
|
||||
fn save_config(
|
||||
game_ui: &mut ui::Ui,
|
||||
selected_controller: [i32; 4],
|
||||
selected_profile: [String; 4],
|
||||
controller_enabled: [bool; 4],
|
||||
upscale: bool,
|
||||
fullscreen: bool,
|
||||
emulate_vru: bool,
|
||||
) {
|
||||
fn save_config(game_ui: &mut ui::Ui, save_config_items: SaveConfig) {
|
||||
let joystick_subsystem = game_ui.joystick_subsystem.as_ref().unwrap();
|
||||
for (pos, item) in selected_controller.iter().enumerate() {
|
||||
for (pos, item) in save_config_items.selected_controller.iter().enumerate() {
|
||||
if *item != -1 {
|
||||
game_ui.config.input.controller_assignment[pos] = Some(
|
||||
joystick_subsystem
|
||||
@@ -118,26 +122,28 @@ fn save_config(
|
||||
}
|
||||
}
|
||||
|
||||
game_ui.config.input.input_profile_binding = selected_profile;
|
||||
game_ui.config.input.controller_enabled = controller_enabled;
|
||||
game_ui.config.input.input_profile_binding = save_config_items.selected_profile;
|
||||
game_ui.config.input.controller_enabled = save_config_items.controller_enabled;
|
||||
|
||||
game_ui.config.video.fullscreen = fullscreen;
|
||||
game_ui.config.video.upscale = upscale;
|
||||
game_ui.config.input.emulate_vru = emulate_vru;
|
||||
game_ui.config.video.upscale = save_config_items.upscale;
|
||||
game_ui.config.video.integer_scaling = save_config_items.integer_scaling;
|
||||
game_ui.config.video.fullscreen = save_config_items.fullscreen;
|
||||
game_ui.config.input.emulate_vru = save_config_items.emulate_vru;
|
||||
}
|
||||
|
||||
impl Drop for GopherEguiApp {
|
||||
fn drop(&mut self) {
|
||||
let mut game_ui = ui::Ui::new(self.config_dir.clone());
|
||||
save_config(
|
||||
&mut game_ui,
|
||||
self.selected_controller,
|
||||
self.selected_profile.clone(),
|
||||
self.controller_enabled,
|
||||
self.upscale,
|
||||
self.fullscreen,
|
||||
self.emulate_vru,
|
||||
);
|
||||
let save_config_items = SaveConfig {
|
||||
selected_controller: self.selected_controller,
|
||||
selected_profile: self.selected_profile.clone(),
|
||||
controller_enabled: self.controller_enabled,
|
||||
upscale: self.upscale,
|
||||
integer_scaling: self.integer_scaling,
|
||||
fullscreen: self.fullscreen,
|
||||
emulate_vru: self.emulate_vru,
|
||||
};
|
||||
save_config(&mut game_ui, save_config_items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +192,7 @@ impl eframe::App for GopherEguiApp {
|
||||
let selected_profile = self.selected_profile.clone();
|
||||
let controller_enabled = self.controller_enabled;
|
||||
let upscale = self.upscale;
|
||||
let integer_scaling = self.integer_scaling;
|
||||
let fullscreen = self.fullscreen;
|
||||
let emulate_vru = self.emulate_vru;
|
||||
let config_dir = self.config_dir.clone();
|
||||
@@ -221,15 +228,18 @@ impl eframe::App for GopherEguiApp {
|
||||
panic!("could not create running file: {}", result.err().unwrap())
|
||||
}
|
||||
let mut device = device::Device::new(config_dir);
|
||||
save_config(
|
||||
&mut device.ui,
|
||||
|
||||
let save_config_items = SaveConfig {
|
||||
selected_controller,
|
||||
selected_profile,
|
||||
controller_enabled,
|
||||
upscale,
|
||||
integer_scaling,
|
||||
fullscreen,
|
||||
emulate_vru,
|
||||
);
|
||||
};
|
||||
save_config(&mut device.ui, save_config_items);
|
||||
|
||||
if emulate_vru {
|
||||
device.vru.window_notifier = Some(vru_window_notifier);
|
||||
device.vru.word_receiver = Some(vru_word_receiver);
|
||||
@@ -306,7 +316,9 @@ impl eframe::App for GopherEguiApp {
|
||||
});
|
||||
ui.add_space(32.0);
|
||||
ui.checkbox(&mut self.upscale, "High-Res Graphics");
|
||||
ui.checkbox(&mut self.integer_scaling, "Integer Scaling");
|
||||
ui.checkbox(&mut self.fullscreen, "Fullscreen (Esc closes game)");
|
||||
ui.add_space(32.0);
|
||||
ui.checkbox(
|
||||
&mut self.emulate_vru,
|
||||
"Emulate VRU (connects VRU to controller port 4)",
|
||||
|
||||
+2
-1
@@ -38,8 +38,9 @@ pub fn init(device: &mut device::Device, fullscreen: bool) {
|
||||
rdp_init(
|
||||
device.ui.window.as_ref().unwrap().raw() as *mut std::ffi::c_void,
|
||||
gfx_info,
|
||||
fullscreen,
|
||||
device.ui.config.video.upscale,
|
||||
device.ui.config.video.integer_scaling,
|
||||
fullscreen,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user