Created
March 19, 2021 12:43
-
-
Save rexim/b58b42351e7215b5db584aae5c482771 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ffi::{c_void, CStr, CString}; | |
use std::os::raw::c_char; | |
const SDL_INIT_VIDEO: u32 = 0x00000020; | |
const SDL_WINDOW_RESIZABLE: u32 = 0x00000020; | |
const SDL_RENDERER_ACCELERATED: u32 = 0x00000002; | |
const SDL_QUIT: u32 = 0x100; | |
type RawSdlWindow = c_void; | |
type RawSdlRenderer = c_void; | |
#[repr(C, packed)] | |
struct SdlEvent { | |
tipe: u32, | |
#[allow(dead_code)] | |
padding: [u8; 52], | |
} | |
#[link(name = "SDL2")] | |
extern "C" { | |
fn SDL_Init(flags: u32) -> i32; | |
fn SDL_GetError() -> *const c_char; | |
fn SDL_Quit(); | |
fn SDL_CreateWindow( | |
title: *const c_char, | |
x: i32, | |
y: i32, | |
w: i32, | |
h: i32, | |
flags: u32, | |
) -> *mut RawSdlWindow; | |
fn SDL_CreateRenderer(window: *mut RawSdlWindow, index: i32, flags: u32) | |
-> *mut RawSdlRenderer; | |
fn SDL_SetRenderDrawColor(renderer: *mut RawSdlRenderer, r: u8, g: u8, b: u8, a: u8) -> i32; | |
fn SDL_RenderPresent(renderer: *mut RawSdlRenderer); | |
fn SDL_RenderClear(renderer: *mut RawSdlRenderer) -> i32; | |
fn SDL_PollEvent(event: *mut SdlEvent) -> i32; | |
fn SDL_Delay(ms: u32); | |
fn SDL_DestroyWindow(window: *mut RawSdlWindow); | |
fn SDL_DestroyRenderer(renderer: *mut RawSdlRenderer); | |
} | |
struct SdlWindow { | |
raw: *mut RawSdlWindow, | |
} | |
fn sdl_error_result<T>() -> Result<T, &'static str> { | |
unsafe { | |
Err(CStr::from_ptr(SDL_GetError()).to_str().expect( | |
"Expected SDL to do their job properly and return UTF-8 compatible error messages", | |
)) | |
} | |
} | |
impl SdlWindow { | |
fn create_renderer(&mut self, index: i32, flags: u32) -> Result<SdlRenderer, &'static str> { | |
unsafe { | |
let raw_renderer = SDL_CreateRenderer(self.raw, index, flags); | |
if raw_renderer.is_null() { | |
sdl_error_result() | |
} else { | |
Ok(SdlRenderer { raw: raw_renderer }) | |
} | |
} | |
} | |
} | |
impl Drop for SdlWindow { | |
fn drop(&mut self) { | |
unsafe { | |
SDL_DestroyWindow(self.raw); | |
} | |
} | |
} | |
struct SdlRenderer { | |
raw: *mut RawSdlRenderer, | |
} | |
impl SdlRenderer { | |
fn set_draw_color(&mut self, r: u8, g: u8, b: u8, a: u8) -> Result<(), &'static str> { | |
unsafe { | |
if SDL_SetRenderDrawColor(self.raw, r, g, b, a) < 0 { | |
sdl_error_result() | |
} else { | |
Ok(()) | |
} | |
} | |
} | |
fn present(&mut self) { | |
unsafe { SDL_RenderPresent(self.raw) } | |
} | |
fn clear(&mut self) -> Result<(), &'static str> { | |
unsafe { | |
if SDL_RenderClear(self.raw) < 0 { | |
sdl_error_result() | |
} else { | |
Ok(()) | |
} | |
} | |
} | |
} | |
impl Drop for SdlRenderer { | |
fn drop(&mut self) { | |
unsafe { | |
SDL_DestroyRenderer(self.raw); | |
} | |
} | |
} | |
struct Sdl {} | |
impl Sdl { | |
fn init(flags: u32) -> Result<Self, &'static str> { | |
unsafe { | |
if SDL_Init(flags) < 0 { | |
sdl_error_result() | |
} else { | |
Ok(Self {}) | |
} | |
} | |
} | |
fn create_window( | |
&mut self, | |
title: &str, | |
x: i32, | |
y: i32, | |
w: i32, | |
h: i32, | |
flags: u32, | |
) -> Result<SdlWindow, &'static str> { | |
unsafe { | |
let raw_title = CString::new(title).expect("Expect the unexpectable ZULUL"); | |
let raw_window = SDL_CreateWindow(raw_title.as_ptr(), x, y, w, h, flags); | |
if raw_window.is_null() { | |
sdl_error_result() | |
} else { | |
Ok(SdlWindow { raw: raw_window }) | |
} | |
} | |
} | |
fn poll_event(&mut self, event: &mut SdlEvent) -> bool { | |
unsafe { SDL_PollEvent(event as *mut SdlEvent) > 0 } | |
} | |
fn delay(&mut self, ms: u32) { | |
unsafe { | |
SDL_Delay(ms); | |
} | |
} | |
} | |
impl Drop for Sdl { | |
fn drop(&mut self) { | |
unsafe { SDL_Quit() } | |
} | |
} | |
fn main() { | |
let mut sdl = Sdl::init(SDL_INIT_VIDEO).expect("Could not initialize SDL"); | |
let mut window = sdl | |
.create_window("Hello from Rust", 0, 0, 800, 600, SDL_WINDOW_RESIZABLE) | |
.expect("Could not create SDL window"); | |
let mut renderer = window | |
.create_renderer(-1, SDL_RENDERER_ACCELERATED) | |
.expect("Could not initialize SDL renderer"); | |
let mut quit = false; | |
while !quit { | |
let mut event: SdlEvent = SdlEvent { | |
tipe: 0, | |
padding: [0; 52], | |
}; | |
while sdl.poll_event(&mut event) { | |
if event.tipe == SDL_QUIT { | |
quit = true; | |
} | |
} | |
renderer.set_draw_color(0x3D, 0x3D, 0x3D, 255).unwrap(); | |
renderer.clear().unwrap(); | |
renderer.present(); | |
sdl.delay(100); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment