extern crate ggpo; mod constants; mod game_state; mod non_game_state; // mod resource_manager; mod sdl_renderer; mod vectorwar; use sdl2::{ event::Event, keyboard::Keycode, pixels::Color, rect::Rect, render::{Canvas, RendererContext, Texture, TextureCreator, TextureQuery}, video::Window, }; use std::path::Path; use std::time::Duration; static SCREEN_WIDTH: u32 = 640; static SCREEN_HEIGHT: u32 = 480; // handle the annoying Rect i32 macro_rules! rect( ($x:expr, $y:expr, $w:expr, $h:expr) => ( Rect::new($x as i32, $y as i32, $w as u32, $h as u32) ) ); // Scale fonts to a reasonable size when they're too big (though they might look less smooth) fn get_centered_rect(rect_width: u32, rect_height: u32, cons_width: u32, cons_height: u32) -> Rect { let wr = rect_width as f32 / cons_width as f32; let hr = rect_height as f32 / cons_height as f32; let (w, h) = if wr > 1f32 || hr > 1f32 { if wr > hr { println!("Scaling down! The text will look worse!"); let h = (rect_height as f32 / wr) as i32; (cons_width as i32, h) } else { println!("Scaling down! The text will look worse!"); let w = (rect_width as f32 / hr) as i32; (w, cons_height as i32) } } else { (rect_width as i32, rect_height as i32) }; let cx = (SCREEN_WIDTH as i32 - w) / 2; let cy = (SCREEN_HEIGHT as i32 - h) / 2; rect!(cx, cy, w, h) } fn run(font_path: &Path) -> Result<(), String> { let sdl_context = sdl2::init()?; let video_subsys = sdl_context.video()?; let ttf_context = sdl2::ttf::init().map_err(|e| e.to_string())?; let window = video_subsys .window( &format!("(pid: {}) ggpo sdk sample: vector war", std::process::id()), 640, 480, ) .position_centered() .build() .map_err(|e| e.to_string())?; let mut canvas = window .into_canvas() .target_texture() .present_vsync() .accelerated() .build() .map_err(|e| e.to_string())?; let texture_creator = canvas.texture_creator(); let mut font = ttf_context.load_font(font_path, 16)?; font.set_style(sdl2::ttf::FontStyle::BOLD); // render a surface, and convert it to a texture bound to the canvas let surface = font .render("Hello Rust!") .blended(Color::RGBA(255, 0, 0, 255)) .map_err(|e| e.to_string())?; let texture = texture_creator .create_texture_from_surface(&surface) .map_err(|e| e.to_string())?; canvas.set_draw_color(Color::RGBA(195, 217, 255, 255)); canvas.clear(); let TextureQuery { width, height, .. } = texture.query(); // If the example text is too big for the screen, downscale it (and center irregardless) let padding = 64; let target = get_centered_rect( width, height, SCREEN_WIDTH - padding, SCREEN_HEIGHT - padding, ); canvas.copy(&texture, None, Some(target))?; canvas.present(); let mut renderer = sdl_renderer::SDLRenderer::new(&canvas); 'mainloop: loop { for event in sdl_context.event_pump()?.poll_iter() { match event { Event::KeyDown { keycode: Some(Keycode::Escape), .. } | Event::Quit { .. } => break 'mainloop, _ => {} } } canvas.present(); } Ok(()) } pub fn main() -> Result<(), String> { let args: Vec<_> = std::env::args().collect(); println!("linked sdl2_ttf: {}", sdl2::ttf::get_linked_version()); if args.len() < 2 { println!("Usage: ./demo font.[ttf|ttc|fon]"); let path: &Path = Path::new("F:\\Code\\ggpo-rs\\examples\\vectorwar\\OpenSans-Regular.ttf"); run(path)?; } else { let path: &Path = Path::new(&args[1]); run(path)?; } Ok(()) }