//////////// /// math /// //////////// struct Vec2 { x: f32, y: f32 } impl Vec2 { pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } } pub fn at(x: f32, y: f32) -> Vec2 { Vec2 { x: x, y: y } } } //impl binop () /////////////////// /// SDL externs /// /////////////////// struct SDL_FPoint { x: f32, y: f32 } struct SDL_FColor { r: f32, g: f32, b: f32, a: f32 } struct SDL_Vertex { position: SDL_FPoint, color: SDL_FColor, tex_coord: SDL_FPoint } impl SDL_Vertex { pub fn new() -> SDL_Vertex { SDL_Vertex { position: SDL_FPoint { x: 0.0, y: 0.0 }, color: SDL_FColor { r: 1.0, g: 0.0, b: 1.0, a: 1.0 }, tex_coord: SDL_FPoint { x: 0.0, y: 0.0 }, } } pub fn pos(self, pos: Vec2) -> SDL_Vertex { return SDL_Vertex { position: SDL_FPoint { x: pos.x, y: pos.y }, color: self.color, tex_coord: self.tex_coord, }; } pub fn col(self, color: [f32; 3]) -> SDL_Vertex { return SDL_Vertex { position: self.position, color: [color[0], color[1], color[2], self.color.a], tex_coord: self.tex_coord, }; } } struct SDL_Window {} struct SDL_Renderer {} struct SDL_Texture {} struct SDL_Event { type: u32, reserved: [u8; 124] } struct SDL_FRect { x: f32, y: f32, w: f32, h: f32 } struct SDL_Rect { x: i32, y: i32, w: i32, h: i32 } extern fn SDL_malloc(size: u64) -> *u8; extern fn SDL_Init(flags: u32) -> bool; extern fn SDL_Quit(); extern fn SDL_CreateWindowAndRenderer(title: *char, width: i32, height: i32, flags: i32, window_out: &mut *SDL_Window, renderer_out: &mut *SDL_Renderer) -> bool; extern fn SDL_Delay(ms: u32); extern fn SDL_SetRenderDrawColor(renderer: *SDL_Renderer, r: u8, g: u8, b: u8, a: u8); extern fn SDL_RenderClear(renderer: *SDL_Renderer); extern fn SDL_RenderPresent(renderer: *SDL_Renderer); extern fn SDL_HasEvent(event_type: u32) -> bool; extern fn SDL_PollEvent(event: &mut SDL_Event) -> bool; extern fn SDL_PumpEvents(); extern fn SDL_FlushEvents(min_type: u32, max_type: u32); extern fn SDL_GetTicks() -> u64; extern fn SDL_SetWindowTitle(window: *SDL_Window, title: *char) -> bool; extern fn SDL_CreateTexture(renderer: *SDL_Renderer, pixel_format: u32, texture_access: u32, width: u32, height: u32) -> *SDL_Texture; extern fn SDL_RenderTexture(renderer: *SDL_Renderer, texture: *SDL_Texture, srcfrect: &SDL_FRect, dstfrect: &SDL_FRect) -> bool; extern fn SDL_UpdateTexture(texture: *SDL_Texture, rect: &SDL_Rect, pixels: *u8, pitch: u32) -> bool; extern fn SDL_GetError() -> *char; extern fn SDL_GetWindowSize(window: *SDL_Window, w: &mut i32, h: &mut i32) -> bool; extern fn SDL_rand(max_exclusive: u32) -> u32; extern fn SDL_SetTextureScaleMode(texture: *SDL_Texture, scale_mode: i32) -> bool; extern fn SDL_sqrtf(value: f32) -> f32; extern fn SDL_randf() -> f32; extern fn SDL_powf(value: f32, power: f32) -> f32; extern fn exit(exit_code: i32); extern fn SDL_RenderGeometry(renderer: *SDL_Renderer, texture: *SDL_Texture, vertices: *SDL_Vertex, num_vertices: i32, indices: *i32, num_indices: i32) -> bool; // SDL error reporting helper import std::print; import std::String; fn print_sdl_error(context: *char) { let mut message = String::new(); message = message + context + ": " + SDL_GetError(); print(message); message.free(); } //////////////// /// the game /// //////////////// struct Ship { position: Vec2, } struct Game { ship: Ship, } impl Game { pub fn new() -> Game { Game { ship: Ship { position: Vec2::zero(), }, } } pub fn run_frame(&mut self, dt: f32, renderer: *SDL_Renderer, aspect_ratio: f32) { let ship = *self.ship; let vertices = [ SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]), SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]), SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]) ]; let borrow: &[SDL_Vertex; 3] = &vertices; SDL_RenderGeometry(renderer, SDL_Texture::null(), borrow as *SDL_Vertex, 3, i32::null(), 0); // TODO: add a ship // TODO: wind sim // TODO: wave sim } } //////////////// /// the game /// //////////////// struct Platform { window: *SDL_Window, renderer: *SDL_Renderer, game: Game, last_frame_ticks: u64, } impl Platform { pub fn new() -> Platform { let SDL_INIT_VIDEO = 32; let SDL_WINDOW_RESIZABLE = 32; let init_success = SDL_Init(SDL_INIT_VIDEO); if init_success == false { print_sdl_error("SDL init failed"); return exit(1); } let mut window = SDL_Window::null(); let mut renderer = SDL_Renderer::null(); let mut window_title = "Yacht Reid"; let gfx_init_success = SDL_CreateWindowAndRenderer( window_title, 640, 480, SDL_WINDOW_RESIZABLE, &mut window, &mut renderer ); if gfx_init_success == false { print_sdl_error("SDL renderer and window creation failed"); return exit(1); } return Platform { window: window, renderer: renderer, game: Game::new(), last_frame_ticks: SDL_GetTicks(), }; } pub fn run_frame(&mut self) -> bool { let mut event = SDL_Event { type: 0, reserved: [0; 124] }; while (SDL_PollEvent(&mut event)) { if event.type == 256 { // SDL_EVENT_QUIT return false; } } let now = SDL_GetTicks(); let dt = (now - *self.last_frame_ticks) as f32 / 1000.0; *self.last_frame_ticks = now; let mut screen_width = 0; let mut screen_height = 0; SDL_GetWindowSize(*self.window, &mut screen_width, &mut screen_height); let aspect_ratio = screen_width as f32 / screen_height as f32; SDL_SetRenderDrawColor(*self.renderer, 0, 50, 90, 255); SDL_RenderClear(*self.renderer); *self.game.run_frame(dt, *self.renderer, aspect_ratio); SDL_RenderPresent(*self.renderer); return true; } pub fn cleanup(&mut self) { SDL_Quit(); } } //////////// /// main /// //////////// fn main() -> i32 { let mut platform = Platform::new(); while platform.run_frame() {} return 0; }