-
João Magalhães authoredJoão Magalhães authored
sdl.rs 3.02 KiB
use sdl2::{
render::Canvas, rwops::RWops, surface::Surface, sys::image, ttf::Sdl2TtfContext, video::Window,
AudioSubsystem, EventPump, Sdl, TimerSubsystem, VideoSubsystem,
};
/// Structure that provides the complete set of SDL Graphics
/// and Sound syb-system ready to be used by the overall
/// emulator infrastructure.
pub struct SdlSystem {
pub canvas: Canvas<Window>,
pub video_subsystem: VideoSubsystem,
pub timer_subsystem: TimerSubsystem,
pub audio_subsystem: AudioSubsystem,
pub event_pump: EventPump,
pub ttf_context: Sdl2TtfContext,
}
impl SdlSystem {
/// Start the SDL sub-system and all of its structure and returns
/// a structure with all the needed stuff to handle SDL graphics
/// and sound.
pub fn new(
sdl: &Sdl,
title: &str,
width: u32,
height: u32,
scale: f32,
accelerated: bool,
vsync: bool,
) -> Self {
// initializes the SDL sub-system, making it ready to be
// used for display of graphics and audio
let video_subsystem = sdl.video().unwrap();
let timer_subsystem = sdl.timer().unwrap();
let audio_subsystem = sdl.audio().unwrap();
let event_pump = sdl.event_pump().unwrap();
// initializes the fonts context to be used
// in the loading of fonts (supports TTF fonts)
let ttf_context = sdl2::ttf::init().unwrap();
// creates the system window that is going to be used to
// show the emulator and sets it to the central are o screen
let window = video_subsystem
.window(
title,
(scale * width as f32) as u32,
(scale * height as f32) as u32,
)
.resizable()
.position_centered()
.opengl()
.build()
.unwrap();
// creates a canvas (according to spec) to be used in the drawing
// then clears it so that is can be presented empty initially
let mut canvas_builder = window.into_canvas();
if accelerated {
canvas_builder = canvas_builder.accelerated();
}
if vsync {
canvas_builder = canvas_builder.present_vsync();
}
let mut canvas = canvas_builder.build().unwrap();
canvas.set_logical_size(width, height).unwrap();
canvas.clear();
Self {
canvas,
video_subsystem,
timer_subsystem,
audio_subsystem,
event_pump,
ttf_context,
}
}
pub fn window(&self) -> &Window {
self.canvas.window()
}
pub fn window_mut(&mut self) -> &mut Window {
self.canvas.window_mut()
}
}
/// Creates an SDL2 Surface structure from the provided
/// bytes that represent an image (eg: an PNG image buffer).
pub fn surface_from_bytes(bytes: &[u8]) -> Surface {
unsafe {
let rw_ops = RWops::from_bytes(bytes).unwrap();
let raw_surface = image::IMG_Load_RW(rw_ops.raw(), 0);
Surface::from_ll(raw_surface)
}
}