move vsync and target_framerate options back into System
since i realized there is an SDL hint that can be used to toggle this the reason why the rust-sdl "Canvas" struct (which abstracts an "SDL_Renderer") is not being created in System directly (which would allow vsync to be toggled on/off via System directly without the use of a hint) is because not all future SystemResource implementations will need it (e.g. a future OpenGL implementation definitely won't).
This commit is contained in:
parent
29628bf680
commit
9e06a13c6d
|
@ -53,8 +53,11 @@ impl AudioGenerator for SineWaveGenerator {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = DosLikeConfig::new().vsync(true);
|
||||
let mut system = SystemBuilder::new().window_title("Audio Playback").build(config)?;
|
||||
let config = DosLikeConfig::new();
|
||||
let mut system = SystemBuilder::new()
|
||||
.window_title("Audio Playback")
|
||||
.vsync(true)
|
||||
.build(config)?;
|
||||
|
||||
let mut using_queue_commands = false;
|
||||
let mut volume = 1.0;
|
||||
|
|
|
@ -22,9 +22,10 @@ struct Ball {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = DosLikeConfig::new().vsync(true);
|
||||
let config = DosLikeConfig::new();
|
||||
let mut system = SystemBuilder::new()
|
||||
.window_title("Flying Balls!")
|
||||
.vsync(true)
|
||||
.build(config)?;
|
||||
|
||||
let font = BitmaskFont::new_vga_font()?;
|
||||
|
|
|
@ -12,8 +12,11 @@ mod entities;
|
|||
mod states;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = DosLikeConfig::new().vsync(true);
|
||||
let system = SystemBuilder::new().window_title("Flying Balls").build(config)?;
|
||||
let config = DosLikeConfig::new();
|
||||
let system = SystemBuilder::new()
|
||||
.window_title("Flying Balls")
|
||||
.vsync(true)
|
||||
.build(config)?;
|
||||
let mut game = Game::new(system)?;
|
||||
let mut states = States::new();
|
||||
states.push(SimulationState)?;
|
||||
|
|
|
@ -196,8 +196,11 @@ impl Game {
|
|||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = DosLikeConfig::new().vsync(true);
|
||||
let system = SystemBuilder::new().window_title("Slime Stabbing Simulator").build(config)?;
|
||||
let config = DosLikeConfig::new();
|
||||
let system = SystemBuilder::new()
|
||||
.window_title("Slime Stabbing Simulator")
|
||||
.vsync(true)
|
||||
.build(config)?;
|
||||
let game = Game::new(system)?;
|
||||
main_loop(game, MainMenuState::new()).context("Main loop error")
|
||||
}
|
||||
|
|
|
@ -225,8 +225,11 @@ impl App {
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = DosLikeConfig::new().vsync(true);
|
||||
let system = SystemBuilder::new().window_title("Complicated Template").build(config)?;
|
||||
let config = DosLikeConfig::new();
|
||||
let system = SystemBuilder::new()
|
||||
.window_title("Complicated Template")
|
||||
.vsync(true)
|
||||
.build(config)?;
|
||||
let app = App::new(system)?;
|
||||
main_loop(app, DemoState).context("Main loop error")
|
||||
}
|
||||
|
|
|
@ -6,8 +6,11 @@ use ggdt::system::*;
|
|||
use ggdt::utils::rnd_value;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = DosLikeConfig::new().vsync(true);
|
||||
let mut system = SystemBuilder::new().window_title("Minimal Template").build(config)?;
|
||||
let config = DosLikeConfig::new();
|
||||
let mut system = SystemBuilder::new()
|
||||
.window_title("Minimal Template")
|
||||
.vsync(true)
|
||||
.build(config)?;
|
||||
|
||||
system.res.video.clear(0);
|
||||
system.res.video.print_string("Hello, world!", 20, 20, FontRenderOpts::Color(15), &system.res.font);
|
||||
|
|
|
@ -70,6 +70,8 @@ pub enum SystemError {
|
|||
#[derive(Debug)]
|
||||
pub struct SystemBuilder {
|
||||
window_title: String,
|
||||
vsync: bool,
|
||||
target_framerate: Option<u32>,
|
||||
resizable: bool,
|
||||
show_mouse: bool,
|
||||
relative_mouse_scaling: bool,
|
||||
|
@ -81,6 +83,8 @@ impl SystemBuilder {
|
|||
pub fn new() -> SystemBuilder {
|
||||
SystemBuilder {
|
||||
window_title: String::new(),
|
||||
vsync: false,
|
||||
target_framerate: None,
|
||||
resizable: true,
|
||||
show_mouse: false,
|
||||
relative_mouse_scaling: true,
|
||||
|
@ -89,13 +93,30 @@ impl SystemBuilder {
|
|||
}
|
||||
|
||||
/// Set the window title for the [`System`] to be built.
|
||||
pub fn window_title(&mut self, window_title: &str) -> &mut SystemBuilder {
|
||||
pub fn window_title(mut self, window_title: &str) -> Self {
|
||||
self.window_title = window_title.to_string();
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables or disables V-Sync for the [`System`] to be built. Enabling V-sync automatically
|
||||
/// disables `target_framerate`.
|
||||
pub fn vsync(mut self, enable: bool) -> Self {
|
||||
self.vsync = enable;
|
||||
self.target_framerate = None;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a target framerate for the [`System`] being built to run at. This is intended to be
|
||||
/// used when V-sync is not desired, so setting a target framerate automatically disables
|
||||
/// `vsync`.
|
||||
pub fn target_framerate(mut self, target_framerate: u32) -> Self {
|
||||
self.target_framerate = Some(target_framerate);
|
||||
self.vsync = false;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether the window will be resizable by the user for the [`System`] being built.
|
||||
pub fn resizable(&mut self, enable: bool) -> &mut SystemBuilder {
|
||||
pub fn resizable(mut self, enable: bool) -> Self {
|
||||
self.resizable = enable;
|
||||
self
|
||||
}
|
||||
|
@ -103,14 +124,14 @@ impl SystemBuilder {
|
|||
/// Enables or disables mouse cursor display by the operating system when the cursor is over
|
||||
/// the window for the [`System`] being built. Disable this if you intend to render your own
|
||||
/// custom mouse cursor.
|
||||
pub fn show_mouse(&mut self, enable: bool) -> &mut SystemBuilder {
|
||||
pub fn show_mouse(mut self, enable: bool) -> Self {
|
||||
self.show_mouse = enable;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enables or disables automatic DPI scaling of mouse relative movement values (delta values)
|
||||
/// available via the [`Mouse`] input device.
|
||||
pub fn relative_mouse_scaling(&mut self, enable: bool) -> &mut SystemBuilder {
|
||||
pub fn relative_mouse_scaling(mut self, enable: bool) -> Self {
|
||||
self.relative_mouse_scaling = enable;
|
||||
self
|
||||
}
|
||||
|
@ -120,7 +141,7 @@ impl SystemBuilder {
|
|||
/// default setting that [`SystemBuilder`] configures is to follow the SDL default, except where
|
||||
/// the setting affects the system globally (in certain desktop environments, e.g. KDE/Kwin)
|
||||
/// which may be undesired by end-users, at the cost of some additional input latency.
|
||||
pub fn skip_x11_compositor(&mut self, enable: bool) -> &mut SystemBuilder {
|
||||
pub fn skip_x11_compositor(mut self, enable: bool) -> Self {
|
||||
self.skip_x11_compositor = enable;
|
||||
self
|
||||
}
|
||||
|
@ -130,23 +151,10 @@ impl SystemBuilder {
|
|||
&self,
|
||||
config: ConfigType,
|
||||
) -> Result<System<ConfigType::SystemResourcesType>, SystemError> {
|
||||
sdl2::hint::set(
|
||||
"SDL_MOUSE_RELATIVE_SCALING",
|
||||
if self.relative_mouse_scaling {
|
||||
"1"
|
||||
} else {
|
||||
"0"
|
||||
},
|
||||
);
|
||||
|
||||
sdl2::hint::set(
|
||||
"SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR",
|
||||
if self.skip_x11_compositor {
|
||||
"1"
|
||||
} else {
|
||||
"0"
|
||||
},
|
||||
);
|
||||
sdl2::hint::set("SDL_RENDER_VSYNC", if self.vsync { "1" } else { "0" });
|
||||
sdl2::hint::set("SDL_MOUSE_RELATIVE_SCALING", if self.relative_mouse_scaling { "1" } else { "0" });
|
||||
sdl2::hint::set("SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR", if self.skip_x11_compositor { "1" } else { "0" });
|
||||
|
||||
// build all the individual SDL subsystems
|
||||
|
||||
|
@ -211,6 +219,8 @@ impl SystemBuilder {
|
|||
sdl_timer_subsystem,
|
||||
res: system_resources,
|
||||
event_pump,
|
||||
vsync: self.vsync,
|
||||
target_framerate: self.target_framerate,
|
||||
target_framerate_delta: None,
|
||||
next_tick: 0,
|
||||
})
|
||||
|
@ -228,6 +238,8 @@ where SystemResType: SystemResources {
|
|||
sdl_video_subsystem: VideoSubsystem,
|
||||
sdl_timer_subsystem: TimerSubsystem,
|
||||
|
||||
vsync: bool,
|
||||
target_framerate: Option<u32>,
|
||||
target_framerate_delta: Option<i64>,
|
||||
next_tick: i64,
|
||||
|
||||
|
@ -241,6 +253,8 @@ where SystemResType: SystemResources {
|
|||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("System")
|
||||
.field("res", &self.res)
|
||||
.field("vsync", &self.vsync)
|
||||
.field("target_framerate", &self.target_framerate)
|
||||
.field("target_framerate_delta", &self.target_framerate_delta)
|
||||
.field("next_tick", &self.next_tick)
|
||||
.finish_non_exhaustive()
|
||||
|
@ -259,7 +273,7 @@ where SystemResType: SystemResources {
|
|||
// if a specific target framerate is desired, apply some loop timing/delay to achieve it
|
||||
// TODO: do this better. delaying when running faster like this is a poor way to do this..
|
||||
|
||||
if let Some(target_framerate) = self.res.target_framerate() {
|
||||
if let Some(target_framerate) = self.target_framerate {
|
||||
if self.target_framerate_delta.is_some() {
|
||||
// normal path for every other loop iteration except the first
|
||||
let delay = self.next_tick - self.ticks() as i64;
|
||||
|
@ -346,6 +360,16 @@ where SystemResType: SystemResources {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn vsync(&self) -> bool {
|
||||
self.vsync
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn target_framerate(&self) -> Option<u32> {
|
||||
self.target_framerate
|
||||
}
|
||||
|
||||
pub fn ticks(&self) -> u64 {
|
||||
self.sdl_timer_subsystem.performance_counter()
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ use crate::system::*;
|
|||
pub struct DosLikeConfig {
|
||||
screen_width: u32,
|
||||
screen_height: u32,
|
||||
vsync: bool,
|
||||
target_framerate: Option<u32>,
|
||||
initial_scale_factor: u32,
|
||||
integer_scaling: bool,
|
||||
}
|
||||
|
@ -16,30 +14,11 @@ impl DosLikeConfig {
|
|||
DosLikeConfig {
|
||||
screen_width: SCREEN_WIDTH,
|
||||
screen_height: SCREEN_HEIGHT,
|
||||
vsync: false,
|
||||
target_framerate: None,
|
||||
initial_scale_factor: DEFAULT_SCALE_FACTOR,
|
||||
integer_scaling: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enables or disables V-Sync for the [`System`] to be built. Enabling V-sync automatically
|
||||
/// disables `target_framerate`.
|
||||
pub fn vsync(mut self, enable: bool) -> Self {
|
||||
self.vsync = enable;
|
||||
self.target_framerate = None;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a target framerate for the [`System`] being built to run at. This is intended to be
|
||||
/// used when V-sync is not desired, so setting a target framerate automatically disables
|
||||
/// `vsync`.
|
||||
pub fn target_framerate(mut self, target_framerate: u32) -> Self {
|
||||
self.target_framerate = Some(target_framerate);
|
||||
self.vsync = false;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets an integer scaling factor for the [`System`] being built to up-scale the virtual
|
||||
/// framebuffer to when displaying it on screen.
|
||||
pub fn scale_factor(mut self, scale_factor: u32) -> Self {
|
||||
|
@ -75,9 +54,6 @@ impl SystemResourcesConfig for DosLikeConfig {
|
|||
// turn the window into a canvas (under the hood, an SDL Renderer that owns the window)
|
||||
|
||||
let mut canvas_builder = window.into_canvas();
|
||||
if self.vsync {
|
||||
canvas_builder = canvas_builder.present_vsync();
|
||||
}
|
||||
let mut sdl_canvas = match canvas_builder.build() {
|
||||
Ok(canvas) => canvas,
|
||||
Err(error) => return Err(SystemResourcesError::SDLError(error.to_string())),
|
||||
|
@ -162,8 +138,6 @@ impl SystemResourcesConfig for DosLikeConfig {
|
|||
sdl_texture,
|
||||
sdl_texture_pitch,
|
||||
texture_pixels,
|
||||
vsync: self.vsync,
|
||||
target_framerate: self.target_framerate,
|
||||
audio,
|
||||
audio_queue,
|
||||
palette,
|
||||
|
@ -180,8 +154,6 @@ pub struct DosLike {
|
|||
sdl_texture: Texture,
|
||||
sdl_texture_pitch: usize,
|
||||
texture_pixels: Box<[u32]>,
|
||||
vsync: bool,
|
||||
target_framerate: Option<u32>,
|
||||
|
||||
/// An [`Audio`] instance that allows interacting with the system's audio output device.
|
||||
pub audio: Audio,
|
||||
|
@ -223,8 +195,6 @@ impl std::fmt::Debug for DosLike {
|
|||
.field("font", &self.font)
|
||||
.field("keyboard", &self.keyboard)
|
||||
.field("mouse", &self.mouse)
|
||||
.field("vsync", &self.vsync)
|
||||
.field("target_framerate", &self.target_framerate)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
@ -285,14 +255,4 @@ impl SystemResources for DosLike {
|
|||
fn height(&self) -> u32 {
|
||||
self.video.height()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn vsync(&self) -> bool {
|
||||
self.vsync
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn target_framerate(&self) -> Option<u32> {
|
||||
self.target_framerate
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,4 @@ pub trait SystemResources : std::fmt::Debug {
|
|||
|
||||
fn width(&self) -> u32;
|
||||
fn height(&self) -> u32;
|
||||
fn vsync(&self) -> bool;
|
||||
fn target_framerate(&self) -> Option<u32>;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue