MiniDemoTools/src/config.rs

139 lines
5.6 KiB
Rust
Raw Normal View History

2024-08-10 12:00:47 +03:00
use godot::prelude::*;
use godot::classes::{ConfigFile, Engine, DisplayServer, display_server::{WindowFlags, WindowMode, VSyncMode}, window::WindowInitialPosition};
#[derive(GodotClass)]
#[class(base=Node)]
struct Config {
// DISCUSSION: Should we expose these in-editor so the default values can be modified?
#[export(file = "")]
config_path: GString,
#[var]
window_height: i32,
#[var]
window_width: i32,
#[var]
is_fullscreen: bool,
#[var]
is_borderless: bool,
#[var]
monitor: i32,
#[var]
window_position_x: i32,
#[var]
window_position_y: i32,
#[var]
max_framerate: i32,
#[var]
vertical_sync: bool,
#[var]
resolution_scale: f32,
base: Base<Node>,
}
#[godot_api]
impl INode for Config {
fn init(base: Base<Node>) -> Self {
Self {
config_path: GString::from("res://config.toml"),
window_height: 600,
window_width: 400,
is_fullscreen: false,
is_borderless: true,
monitor: 0,
window_position_x: 0,
window_position_y: 0,
max_framerate: 60,
vertical_sync: true,
resolution_scale: 1.0,
base,
}
}
fn enter_tree(&mut self) {
let editor_hint = Engine::singleton().is_editor_hint();
let mut config = ConfigFile::new_gd();
let res = config.load(GString::from("res://config.toml"));
if res != godot::global::Error::OK {
godot_error!("Failed to load config file");
}
else {
//TODO This could be improved
//// GDext doesn's support defining defaults at this moment, and there's no way in hell I'm implementing checks for each config key.
//// If a config field is missing, it should throw an error, but not halt the whole demo
//
// We can get the keys and sections with get_sections() and get_section_keys() and then iterate over each one and load them if they match with the Config struct
//
self.window_width = config.get_value(GString::from("window"), GString::from("width")).to::<i32>();
self.window_height = config.get_value(GString::from("window"), GString::from("height")).to::<i32>();
self.is_fullscreen = config.get_value(GString::from("window"), GString::from("fullscreen")).to::<bool>();
self.is_borderless = config.get_value(GString::from("window"), GString::from("borderless")).to::<bool>();
self.window_position_x = config.get_value(GString::from("window"), GString::from("position_x")).to::<i32>();
self.window_position_y = config.get_value(GString::from("window"), GString::from("position_y")).to::<i32>();
self.monitor = config.get_value(GString::from("window"), GString::from("monitor")).to::<i32>();
self.max_framerate = config.get_value(GString::from("graphics"), GString::from("max_framerate")).to::<i32>();
self.vertical_sync = config.get_value(GString::from("graphics"), GString::from("vertical_sync")).to::<bool>();
self.resolution_scale = config.get_value(GString::from("graphics"), GString::from("resolution_scale")).to::<f32>();
}
if !editor_hint {
// THIS CHECK IS VERY IMPORTANT!!! I don't want to fuck my godot up again by resizing the editor and moving it out of bounds..
Self::apply_video_settings(self);
}
}
}
#[godot_api]
impl Config {
#[func]
fn apply_video_settings(&mut self) {
let mut disp_server = DisplayServer::singleton();
let mut window = self.base().get_window().unwrap();
let mut engine = Engine::singleton();
let initial_window_size = disp_server.window_get_size();
let window_offset_after_resize: Vector2i = Vector2i::from_array([(self.window_width - initial_window_size.x) / 2, (self.window_height - initial_window_size.y) / 2]);
if self.is_fullscreen {
disp_server.window_set_mode(WindowMode::FULLSCREEN)
}
else {
disp_server.window_set_mode(WindowMode::WINDOWED)
}
if self.vertical_sync {
disp_server.window_set_vsync_mode(VSyncMode::ENABLED);
}
else {
disp_server.window_set_vsync_mode(VSyncMode::DISABLED);
}
disp_server.window_set_flag(WindowFlags::BORDERLESS, self.is_borderless);
disp_server.window_set_current_screen(self.monitor);
disp_server.window_set_size(Vector2i::from_array([self.window_width, self.window_height]));
//FIXME: Doesn't seem to work on Linux, at least not on KDE+Wayland. Most likely an issue with Godot itself
// as trying to set the window position from GDscript doesn't work either...
// EDIT: It worked for a moment, then broke again... weird
window.set_initial_position(WindowInitialPosition::ABSOLUTE);
if cfg!(debug_assertions) {
godot_print!("WINDOW SIZE: {}, {}", initial_window_size.x, initial_window_size.y);
godot_print!("Initial size: {}, {}", initial_window_size.x, initial_window_size.y);
godot_print!("offset: {}, {}", window_offset_after_resize.x, window_offset_after_resize.y);
godot_print!("New pos: {}, {}", self.window_position_x - window_offset_after_resize.x, self.window_position_y - window_offset_after_resize.y);
}
window.set_position(Vector2i::from_array([self.window_position_x - window_offset_after_resize.x, initial_window_size.y - window_offset_after_resize.y]));
engine.set_max_fps(self.max_framerate);
}
}