diff --git a/build.rs b/build.rs index b2a3f89..affe56d 100644 --- a/build.rs +++ b/build.rs @@ -1,13 +1,14 @@ -use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator}; use std::env; use std::fs::File; use std::path::Path; +use gl_generator::{Api, Fallbacks, GlobalGenerator, Profile, Registry}; + fn main() { - let dest = env::var("OUT_DIR").unwrap(); - let mut file = File::create(&Path::new(&dest).join("gl_bindings.rs")).unwrap(); + let dest = env::var("OUT_DIR").unwrap(); + let mut file = File::create(&Path::new(&dest).join("gl_bindings.rs")).unwrap(); - Registry::new(Api::Gl, (4, 1), Profile::Core, Fallbacks::All, []) - .write_bindings(GlobalGenerator, &mut file) - .unwrap(); + Registry::new(Api::Gl, (4, 1), Profile::Core, Fallbacks::All, []) + .write_bindings(GlobalGenerator, &mut file) + .unwrap(); } diff --git a/src/lib.rs b/src/lib.rs index e3662db..a723ed5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,6 @@ pub use app::App; pub mod game; pub use game::Game; pub mod math; +pub mod renderer; pub mod system; pub mod window; -pub mod renderer; diff --git a/src/renderer.rs b/src/renderer.rs index 51e83d0..29fa7ea 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,26 +1,22 @@ - use std::collections::HashMap; pub mod debug_renderer; - - //use crate::renderer::debug_renderer; -use crate::math::{ +use crate::math::{ Matrix22, Matrix32, -// Matrix33, + // Matrix33, Matrix44, - Vector2 + Vector2, }; use crate::system::System; use crate::window::Window; - //use material::Material; -#[derive(Debug,Copy,Clone)] +#[derive(Debug, Copy, Clone)] pub struct Color { pub r: f32, pub g: f32, @@ -62,16 +58,11 @@ impl Color { a: 1.0, } } - pub fn from_rgba( r: f32, g: f32, b: f32, a: f32 ) -> Self { - Self { - r, - g, - b, - a, - } + pub fn from_rgba(r: f32, g: f32, b: f32, a: f32) -> Self { + Self { r, g, b, a } } - pub fn from_a( a: f32 ) -> Self { + pub fn from_a(a: f32) -> Self { Self { r: a, g: a, @@ -80,55 +71,53 @@ impl Color { } } - pub fn as_rgba8( &self ) -> u32 { - let r = ( self.r * 255.0 ) as u32; - let g = ( self.g * 255.0 ) as u32; - let b = ( self.b * 255.0 ) as u32; - let a = ( self.a * 255.0 ) as u32; - ( r << 24 ) - | ( g << 16 ) - | ( b << 8 ) - | ( a << 0 ) + pub fn as_rgba8(&self) -> u32 { + let r = (self.r * 255.0) as u32; + let g = (self.g * 255.0) as u32; + let b = (self.b * 255.0) as u32; + let a = (self.a * 255.0) as u32; + (r << 24) | (g << 16) | (b << 8) | (a << 0) } - pub fn as_abgr8( &self ) -> u32 { - let r = ( self.r * 255.0 ) as u32; - let g = ( self.g * 255.0 ) as u32; - let b = ( self.b * 255.0 ) as u32; - let a = ( self.a * 255.0 ) as u32; - ( r << 0 ) - | ( g << 8 ) - | ( b << 16 ) - | ( a << 24 ) + pub fn as_abgr8(&self) -> u32 { + let r = (self.r * 255.0) as u32; + let g = (self.g * 255.0) as u32; + let b = (self.b * 255.0) as u32; + let a = (self.a * 255.0) as u32; + (r << 0) | (g << 8) | (b << 16) | (a << 24) } } -#[derive(Debug,Copy,Clone)] +#[derive(Debug, Copy, Clone)] pub struct Vertex { - pos: [f32;3], - tex_coords: [f32;2], - color: [f32;4], + pos: [f32; 3], + tex_coords: [f32; 2], + color: [f32; 4], } impl Vertex { - pub fn from_xyz( x: f32, y: f32, z: f32 ) -> Self { + pub fn from_xyz(x: f32, y: f32, z: f32) -> Self { Self { - pos: [ x, y, z ], - tex_coords: [ 0.0, 0.0 ], - color: [ 1.0, 1.0, 1.0, 1.0 ], + pos: [x, y, z], + tex_coords: [0.0, 0.0], + color: [1.0, 1.0, 1.0, 1.0], } } - pub fn from_pos_with_tex_coords( pos: &Vector2, tex_coords: &Vector2 ) -> Self { + pub fn from_pos_with_tex_coords(pos: &Vector2, tex_coords: &Vector2) -> Self { Self { - pos: [ pos.x, pos.y, 0.0 ], - tex_coords: [ tex_coords.x, tex_coords.y ], - color: [ 1.0, 1.0, 1.0, 1.0 ], + pos: [pos.x, pos.y, 0.0], + tex_coords: [tex_coords.x, tex_coords.y], + color: [1.0, 1.0, 1.0, 1.0], } } - pub fn from_pos_with_tex_coords_and_color( pos: &Vector2, tex_coords: &Vector2, color: &Color ) -> Self { + pub fn from_pos_with_tex_coords_and_color( + pos: &Vector2, + tex_coords: &Vector2, + color: &Color, + ) -> Self { Self { - pos: [ pos.x, pos.y, 0.0 ], - tex_coords: [ tex_coords.x, tex_coords.y ], - color: [ color.r, color.g, color.b, color.a ], + pos: [pos.x, pos.y, 0.0], + tex_coords: [tex_coords.x, tex_coords.y], + color: [color.r, color.g, color.b, color.a], } } } @@ -136,143 +125,141 @@ impl Vertex { const MAX_TEXTURE_CHANNELS: usize = 4; #[derive(Debug)] pub struct Renderer { - frame: u64, - material_manager: Manager, - texture_manager: Manager, - font_manager: FontManager, - vertices: Vec, - effects: HashMap< u16, Effect >, + frame: u64, + material_manager: Manager, + texture_manager: Manager, + font_manager: FontManager, + vertices: Vec, + effects: HashMap, default_effect_id: u16, - active_effect_id: u16, - active_layer_id: u8, + active_effect_id: u16, + active_layer_id: u8, -// fonts: HashMap< u8, Font >, -// default_font_id: u8, - active_font_id: u8, + // fonts: HashMap< u8, Font >, + // default_font_id: u8, + active_font_id: u8, active_font_name: String, - active_textures: [Option< u16 >; MAX_TEXTURE_CHANNELS], + active_textures: [Option; MAX_TEXTURE_CHANNELS], tex_coords: Vector2, - color: Color, + color: Color, mvp_matrix: Matrix44, tex_matrix: Matrix32, - size: Vector2, - viewport_pos: Vector2, + size: Vector2, + viewport_pos: Vector2, viewport_size: Vector2, } impl Renderer { pub fn new() -> Self { Self { - frame: 0, - material_manager: Manager::new(), - texture_manager: Manager::new(), - font_manager: FontManager::new(), - vertices: Vec::new(), // :TODO: pre allocate size? or maybe even a fixed size array - effects: HashMap::new(), -// fonts: HashMap::new(), + frame: 0, + material_manager: Manager::new(), + texture_manager: Manager::new(), + font_manager: FontManager::new(), + vertices: Vec::new(), // :TODO: pre allocate size? or maybe even a fixed size array + effects: HashMap::new(), + // fonts: HashMap::new(), default_effect_id: 0, - active_effect_id: 0, - active_layer_id: 0, -// default_font_id: 0, - active_font_id: 0, - active_font_name: String::new(), - active_textures: [None; MAX_TEXTURE_CHANNELS], + active_effect_id: 0, + active_layer_id: 0, + // default_font_id: 0, + active_font_id: 0, + active_font_name: String::new(), + active_textures: [None; MAX_TEXTURE_CHANNELS], tex_coords: Vector2::zero(), - color: Color::white(), + color: Color::white(), mvp_matrix: Matrix44::identity(), tex_matrix: Matrix32::identity(), - size: Vector2::zero(), - viewport_pos: Vector2::zero(), + size: Vector2::zero(), + viewport_pos: Vector2::zero(), viewport_size: Vector2::zero(), } } - pub fn register_effect( &mut self, effect: Effect ) { - if self.effects.len() == 0 { + pub fn register_effect(&mut self, effect: Effect) { + if self.effects.len() == 0 { self.default_effect_id = effect.id(); } self.effects.insert(effect.id(), effect); } - pub fn register_texture( &mut self, texture: Texture ) -> u16 { - let index = self.texture_manager.add( texture ); + pub fn register_texture(&mut self, texture: Texture) -> u16 { + let index = self.texture_manager.add(texture); if self.texture_manager.len() == 1 { -// self.texture_manager.set_active( index ); - self.active_textures[ 0 ] = Some( index as u16 ); + // self.texture_manager.set_active( index ); + self.active_textures[0] = Some(index as u16); } index as u16 } - pub fn load_font( &mut self, system: &mut System, font_id: u8, name: &str ) { - let texture = Texture::create( system, name ); - let mut font = Font::create( system, name ); - font.recalc_from_matrix( texture.width() ); + pub fn load_font(&mut self, system: &mut System, font_id: u8, name: &str) { + let texture = Texture::create(system, name); + let mut font = Font::create(system, name); + font.recalc_from_matrix(texture.width()); - self.register_texture( texture ); + self.register_texture(texture); - let index = self.font_manager.add( font_id, font ); + let index = self.font_manager.add(font_id, font); } fn get_default_effect(&self) -> &Effect { - match self.effects.get( &self.default_effect_id ) { - Some( e ) => e, - None => panic!("No default render Effect") + match self.effects.get(&self.default_effect_id) { + Some(e) => e, + None => panic!("No default render Effect"), } } fn get_active_effect(&self) -> &Effect { - match self.effects.get( &self.active_effect_id ) { - Some( e ) => e, + match self.effects.get(&self.active_effect_id) { + Some(e) => e, None => { println!("No active render Effect -> using default"); self.get_default_effect() - } + }, } } -/* - fn get_default_font(&self) -> &Font { - match self.fonts.get( &self.default_font_id ) { - Some( e ) => e, - None => panic!("No default render Font") + /* + fn get_default_font(&self) -> &Font { + match self.fonts.get( &self.default_font_id ) { + Some( e ) => e, + None => panic!("No default render Font") + } } - } - fn get_active_font(&self) -> &Font { - match self.fonts.get( &self.active_font_id ) { - Some( e ) => e, - None => { - println!("No active render Font -> using default"); - self.get_default_font() + fn get_active_font(&self) -> &Font { + match self.fonts.get( &self.active_font_id ) { + Some( e ) => e, + None => { + println!("No active render Font -> using default"); + self.get_default_font() + } } } - } -*/ - pub fn setup( &mut self, window: &Window, _system: &mut System ) -> anyhow::Result<()> { + */ + pub fn setup(&mut self, window: &Window, _system: &mut System) -> anyhow::Result<()> { gl::load_with(|s| window.get_proc_address(s) as *const _); // :TODO: maybe use CFBundleGetFunctionPointerForName directly unsafe { - let s = gl::GetString( gl::VERSION ); - let s = String::from_utf8( std::ffi::CStr::from_ptr( s as *const _ ).to_bytes().to_vec() )?; - println!("GL Version: {}", s ); + let s = gl::GetString(gl::VERSION); + let s = String::from_utf8(std::ffi::CStr::from_ptr(s as *const _).to_bytes().to_vec())?; + println!("GL Version: {}", s); } // ensure we have one texture - self.register_texture( Texture::create_canvas( "[]", 2 ) ); + self.register_texture(Texture::create_canvas("[]", 2)); Ok(()) } - pub fn teardown( &mut self ) { + pub fn teardown(&mut self) {} - } - - pub fn begin_frame( &mut self ) { + pub fn begin_frame(&mut self) { self.vertices.clear(); for material in self.material_manager.iter_mut() { material.clear(); @@ -281,28 +268,28 @@ impl Renderer { if self.material_manager.len() == 0 { let mut textures = Vec::new(); for i in 0..MAX_TEXTURE_CHANNELS { - let ti = self.active_textures[ i ].unwrap_or( 0 ); - textures.push( self.texture_manager.get( ti as usize ).unwrap() ); + let ti = self.active_textures[i].unwrap_or(0); + textures.push(self.texture_manager.get(ti as usize).unwrap()); } - let m = Material::new( self.active_layer_id, &self.get_default_effect(), textures ); - let i = self.material_manager.add( m ); - self.material_manager.set_active( i ); + let m = Material::new(self.active_layer_id, &self.get_default_effect(), textures); + let i = self.material_manager.add(m); + self.material_manager.set_active(i); } -// let default_effect_name = self.default_effect_name.clone(); -// self.use_effect( &default_effect_name ); + // let default_effect_name = self.default_effect_name.clone(); + // self.use_effect( &default_effect_name ); unsafe { let p = &self.viewport_pos; let s = &self.viewport_size; - gl::Viewport( p.x as i32, p.y as i32, s.x as i32, s.y as i32 ); -// gl::Scissor( self.pos.x as i32, self.pos.y as i32, self.size.x as i32, self.size.y as i32 ); -// gl::Enable( gl::SCISSOR_TEST ); + gl::Viewport(p.x as i32, p.y as i32, s.x as i32, s.y as i32); + // gl::Scissor( self.pos.x as i32, self.pos.y as i32, self.size.x as i32, self.size.y as i32 ); + // gl::Enable( gl::SCISSOR_TEST ); } self.color = Color::white(); } - pub fn end_frame( &mut self ) { + pub fn end_frame(&mut self) { let mut total_vertices = 0; let mut total_materials = 0; let mut total_materials_with_vertices = 0; @@ -310,48 +297,48 @@ impl Renderer { let debug = self.frame % 500 == 0; // just to avoid ghost unsafe { -// gl::Disable(gl::CULL_FACE); + // gl::Disable(gl::CULL_FACE); gl::Enable(gl::CULL_FACE); gl::Disable(gl::DEPTH_TEST); -// gl::PolygonMode( gl::FRONT_AND_BACK, gl::LINE ); + // gl::PolygonMode( gl::FRONT_AND_BACK, gl::LINE ); } -// println!("---"); + // println!("---"); // :TODO: fix rendering order let mut material_indices = Vec::new(); for i in 0..self.material_manager.len() { - material_indices.push( i ); + material_indices.push(i); } - material_indices.sort_unstable_by(|a, b|{ - let a = self.material_manager.get( *a ).unwrap().key(); - let b = self.material_manager.get( *b ).unwrap().key(); + material_indices.sort_unstable_by(|a, b| { + let a = self.material_manager.get(*a).unwrap().key(); + let b = self.material_manager.get(*b).unwrap().key(); a.partial_cmp(&b).unwrap() }); for i in material_indices { - let material = self.material_manager.get_mut( i ).unwrap(); + let material = self.material_manager.get_mut(i).unwrap(); -// println!("SortKey: 0x{:016X}", material.key() ); + // println!("SortKey: 0x{:016X}", material.key() ); // :TODO: ask material for effect let effect_id = material.effect_id(); - let e = match self.effects.get_mut( &effect_id ) { - Some( e ) => e, - None => match self.effects.get_mut( &self.default_effect_id ) { - Some( e ) => e, - None => panic!("No default render Effect") - } + let e = match self.effects.get_mut(&effect_id) { + Some(e) => e, + None => match self.effects.get_mut(&self.default_effect_id) { + Some(e) => e, + None => panic!("No default render Effect"), + }, }; - material.set_mvp_matrix( &self.mvp_matrix ); - let vc = material.render( e ); + material.set_mvp_matrix(&self.mvp_matrix); + let vc = material.render(e); total_vertices += vc; total_materials += 1; if vc > 0 { total_materials_with_vertices += 1; } if debug { -// println!("Rendered {} vertices for material {:?} with effect {:?}", vc, &material, &e ); + // println!("Rendered {} vertices for material {:?} with effect {:?}", vc, &material, &e ); } } @@ -361,74 +348,81 @@ impl Renderer { } if debug { -// dbg!(&self.material_manager); - println!("Render Stats: {} {} {}", total_vertices, total_materials_with_vertices, total_materials); + // dbg!(&self.material_manager); + println!( + "Render Stats: {} {} {}", + total_vertices, total_materials_with_vertices, total_materials + ); } self.frame += 1; } // rendering functions - pub fn clear( &mut self, color: &Color ) { -// println!("clear with {:?}", &color ); + pub fn clear(&mut self, color: &Color) { + // println!("clear with {:?}", &color ); // glClearColor and glClear unsafe { - gl::ClearColor( color.r, color.g, color.b, color.a ); - gl::Clear( gl::COLOR_BUFFER_BIT ); // :TODO: clear other buffers? + gl::ClearColor(color.r, color.g, color.b, color.a); + gl::Clear(gl::COLOR_BUFFER_BIT); // :TODO: clear other buffers? } } - pub fn aspect_ratio( &self ) -> f32 { + pub fn aspect_ratio(&self) -> f32 { self.size.x / self.size.y } - pub fn size( &self ) -> &Vector2 { + pub fn size(&self) -> &Vector2 { &self.size } - pub fn set_size( &mut self, size: &Vector2 ) { + pub fn set_size(&mut self, size: &Vector2) { self.size = *size; } - pub fn set_viewport( &mut self, pos: &Vector2, size: &Vector2 ) { + pub fn set_viewport(&mut self, pos: &Vector2, size: &Vector2) { self.viewport_pos = *pos; self.viewport_size = *size; } - pub fn set_mvp_matrix( &mut self, mvp_matrix: &Matrix44 ) { + pub fn set_mvp_matrix(&mut self, mvp_matrix: &Matrix44) { self.mvp_matrix = *mvp_matrix; } - pub fn set_tex_matrix( &mut self, tex_matrix: &Matrix32 ) { + pub fn set_tex_matrix(&mut self, tex_matrix: &Matrix32) { self.tex_matrix = *tex_matrix; } - pub fn set_uniform_float( &mut self, name: &str, value: f32 ) { + pub fn set_uniform_float(&mut self, name: &str, value: f32) { // :HACK: let m = self.material_manager.get_mut_active(); - m.set_uniform( name, &Uniform::F32( value ) ); + m.set_uniform(name, &Uniform::F32(value)); } - - fn switch_active_material_if_needed( &mut self ) { -// println!("switch_active_material_if_needed active_effect_name {}", &self.active_effect_name); + + fn switch_active_material_if_needed(&mut self) { + // println!("switch_active_material_if_needed active_effect_name {}", &self.active_effect_name); let lid = self.active_layer_id; let eid = self.get_active_effect().id(); let mut textures = Vec::new(); for i in 0..MAX_TEXTURE_CHANNELS { - let ti = self.active_textures[ i ].unwrap_or( 0 ); - textures.push( self.texture_manager.get( ti as usize ).unwrap() ); - } - let tids = textures.iter().map( |&t| t.hwid() ).collect::>().to_vec(); - let key = Material::calculate_key( lid, eid, &tids ); + let ti = self.active_textures[i].unwrap_or(0); + textures.push(self.texture_manager.get(ti as usize).unwrap()); + } + let tids = textures + .iter() + .map(|&t| t.hwid()) + .collect::>() + .to_vec(); + let key = Material::calculate_key(lid, eid, &tids); let can_render = { let m = self.material_manager.get_active(); - m.can_render( key ) + m.can_render(key) }; if !can_render { - let found_material = self.material_manager.select_active(|m: &Material|{ - m.can_render( key ) - }); + let found_material = self + .material_manager + .select_active(|m: &Material| m.can_render(key)); if !found_material { /* println!( @@ -440,252 +434,247 @@ impl Renderer { */ let mut textures = Vec::new(); for i in 0..MAX_TEXTURE_CHANNELS { - let ti = self.active_textures[ i ].unwrap_or( 0 ); - textures.push( self.texture_manager.get( ti as usize ).unwrap() ); + let ti = self.active_textures[i].unwrap_or(0); + textures.push(self.texture_manager.get(ti as usize).unwrap()); } - let m = Material::new( self.active_layer_id, &self.get_active_effect(), textures ); - let i = self.material_manager.add( m ); - self.material_manager.set_active( i ); + let m = Material::new(self.active_layer_id, &self.get_active_effect(), textures); + let i = self.material_manager.add(m); + self.material_manager.set_active(i); } } - } - pub fn use_effect( &mut self, effect_id: u16 ) { + pub fn use_effect(&mut self, effect_id: u16) { self.active_effect_id = effect_id; self.switch_active_material_if_needed(); } - pub fn use_layer( &mut self, layer_id: u8 ) { + pub fn use_layer(&mut self, layer_id: u8) { self.active_layer_id = layer_id; self.switch_active_material_if_needed(); } - pub fn use_texture( &mut self, name: &str ) { - self.use_texture_in_channel( name, 0 ); + pub fn use_texture(&mut self, name: &str) { + self.use_texture_in_channel(name, 0); /* - let current_active_texture = self.texture_manager.get_active(); - if name != current_active_texture.name() { -// println!("Switching active texture from {} to {}", ¤t_active_texture.name(), &name ); - - let found_texture = self.texture_manager.select_active(|t: &Texture|{ - t.name() == name - }); - - if !found_texture { - println!("Warning: Texture {} not found using default", &name); - self.texture_manager.set_active( 0 ); - } - self.switch_active_material_if_needed(); - } - */ + let current_active_texture = self.texture_manager.get_active(); + if name != current_active_texture.name() { + // println!("Switching active texture from {} to {}", ¤t_active_texture.name(), &name ); + + let found_texture = self.texture_manager.select_active(|t: &Texture|{ + t.name() == name + }); + + if !found_texture { + println!("Warning: Texture {} not found using default", &name); + self.texture_manager.set_active( 0 ); + } + self.switch_active_material_if_needed(); + } + */ } - pub fn use_font( &mut self, font_id: u8 ) { + pub fn use_font(&mut self, font_id: u8) { self.active_font_id = font_id; } - pub fn disable_texture_for_channel( &mut self, channel: u8 ) { - if self.active_textures[ channel as usize ].is_none() { + pub fn disable_texture_for_channel(&mut self, channel: u8) { + if self.active_textures[channel as usize].is_none() { // :TODO: is this ok? return; } - self.active_textures[ channel as usize ] = None; + self.active_textures[channel as usize] = None; self.switch_active_material_if_needed(); } - pub fn use_texture_in_channel( &mut self, name: &str, channel: u8 ) { + pub fn use_texture_in_channel(&mut self, name: &str, channel: u8) { // :TODO: avoid changing texture when it is already active -// dbg!(&self.texture_manager); - match self.texture_manager.find_index(|t: &Texture|{ -// dbg!(&t.name(), &name); + // dbg!(&self.texture_manager); + match self.texture_manager.find_index(|t: &Texture| { + // dbg!(&t.name(), &name); t.name() == name }) { None => todo!("Texture not found {}. User error?", &name), - Some( i ) => { - self.active_textures[ channel as usize ] = Some ( i as u16 ); + Some(i) => { + self.active_textures[channel as usize] = Some(i as u16); self.switch_active_material_if_needed(); }, }; } - - pub fn set_color( &mut self, color: &Color ) { + pub fn set_color(&mut self, color: &Color) { self.color = *color; } - pub fn set_tex_coords( &mut self, tex_coords: &Vector2 ) { + pub fn set_tex_coords(&mut self, tex_coords: &Vector2) { self.tex_coords = *tex_coords; } - pub fn add_vertex( &mut self, pos: &Vector2 ) -> u32 { - let v = Vertex::from_pos_with_tex_coords_and_color( pos, &self.tex_coords, &self.color ); - self.vertices.push( v ); + pub fn add_vertex(&mut self, pos: &Vector2) -> u32 { + let v = Vertex::from_pos_with_tex_coords_and_color(pos, &self.tex_coords, &self.color); + self.vertices.push(v); self.vertices.len() as u32 - 1 } - pub fn add_triangle( &mut self, v0: u32, v1: u32, v2: u32 ) { + pub fn add_triangle(&mut self, v0: u32, v1: u32, v2: u32) { let material = self.material_manager.get_mut_active(); for v in [v0, v1, v2].iter() { - match self.vertices.get( *v as usize ) { - Some( v ) => { - material.add_vertex( v ); + match self.vertices.get(*v as usize) { + Some(v) => { + material.add_vertex(v); }, None => { // :TODO: shout loud }, } - } + } } - pub fn render_quad( &mut self, pos: &Vector2, size: &Vector2 ) { - let mut hs = *size; // hs => half size + pub fn render_quad(&mut self, pos: &Vector2, size: &Vector2) { + let mut hs = *size; // hs => half size hs.x = 0.5 * hs.x; hs.y = 0.5 * hs.y; - let tl = Vector2::new( -hs.x + pos.x, hs.y + pos.y ); - let bl = Vector2::new( -hs.x + pos.x, -hs.y + pos.y ); - let br = Vector2::new( hs.x + pos.x, -hs.y + pos.y ); - let tr = Vector2::new( hs.x + pos.x, hs.y + pos.y ); + let tl = Vector2::new(-hs.x + pos.x, hs.y + pos.y); + let bl = Vector2::new(-hs.x + pos.x, -hs.y + pos.y); + let br = Vector2::new(hs.x + pos.x, -hs.y + pos.y); + let tr = Vector2::new(hs.x + pos.x, hs.y + pos.y); - let v0 = self.add_vertex( &tl ); - let v1 = self.add_vertex( &bl ); - let v2 = self.add_vertex( &br ); - let v3 = self.add_vertex( &tr ); + let v0 = self.add_vertex(&tl); + let v1 = self.add_vertex(&bl); + let v2 = self.add_vertex(&br); + let v3 = self.add_vertex(&tr); - self.add_triangle( v0, v1, v2 ); // TopLeft, BottomLeft, BottomRight - self.add_triangle( v2, v3, v0 ); // BottomRight, TopRight, TopLeft + self.add_triangle(v0, v1, v2); // TopLeft, BottomLeft, BottomRight + self.add_triangle(v2, v3, v0); // BottomRight, TopRight, TopLeft } - pub fn render_textured_fullscreen_quad( &mut self ) { + pub fn render_textured_fullscreen_quad(&mut self) { let size = self.size; -// dbg!(&size); - self.render_textured_quad( &Vector2::zero(), &size ); + // dbg!(&size); + self.render_textured_quad(&Vector2::zero(), &size); } - pub fn render_textured_quad( &mut self, pos: &Vector2, size: &Vector2 ) { - self.render_textured_quad_with_rotation( pos, size, 0.0 ); + pub fn render_textured_quad(&mut self, pos: &Vector2, size: &Vector2) { + self.render_textured_quad_with_rotation(pos, size, 0.0); } - pub fn render_textured_quad_with_rotation( &mut self, pos: &Vector2, size: &Vector2, angle: f32 ) { + pub fn render_textured_quad_with_rotation( + &mut self, + pos: &Vector2, + size: &Vector2, + angle: f32, + ) { let angle = angle * 0.01745329252; - let mtx = Matrix22::z_rotation( angle ); + let mtx = Matrix22::z_rotation(angle); let positions = [ - Vector2::new( -0.5, 0.5 ), - Vector2::new( -0.5, -0.5 ), - Vector2::new( 0.5, -0.5 ), - Vector2::new( 0.5, 0.5 ), + Vector2::new(-0.5, 0.5), + Vector2::new(-0.5, -0.5), + Vector2::new(0.5, -0.5), + Vector2::new(0.5, 0.5), ]; let tex_coords = [ - Vector2::new( 0.0, 0.0 ), - Vector2::new( 0.0, 1.0 ), - Vector2::new( 1.0, 1.0 ), - Vector2::new( 1.0, 0.0 ), + Vector2::new(0.0, 0.0), + Vector2::new(0.0, 1.0), + Vector2::new(1.0, 1.0), + Vector2::new(1.0, 0.0), ]; -// let tex_mtx = Matrix32::identity(); - let ti = self.active_textures[ 0 ].unwrap_or( 0 ); - let at = self.texture_manager.get( ti as usize ).unwrap_or( - self.texture_manager.get( 0 ).unwrap() - ); + // let tex_mtx = Matrix32::identity(); + let ti = self.active_textures[0].unwrap_or(0); + let at = self + .texture_manager + .get(ti as usize) + .unwrap_or(self.texture_manager.get(0).unwrap()); let tex_mtx = *at.mtx(); let user_tex_mtx = self.tex_matrix; - let mut v = [0u32;4]; + let mut v = [0u32; 4]; // :TODO: future optimization once we have full matrix implementation -// let mtx_tr = Matrix32::translation( pos.x, pos.y ); -// let mtx = mtx_r.mul_matrix( &mtx ); + // let mtx_tr = Matrix32::translation( pos.x, pos.y ); + // let mtx = mtx_r.mul_matrix( &mtx ); for i in 0..4 { - let p = positions[ i ]; - let p = p.scale_vector2( &size ); - let p = mtx.mul_vector2( &p ).add( &pos ); + let p = positions[i]; + let p = p.scale_vector2(&size); + let p = mtx.mul_vector2(&p).add(&pos); // :TODO: decide if we might want to move this calculation to set_tex_coords - let t = tex_coords[ i ]; - let t = user_tex_mtx.mul_vector2( &t ); - let t = tex_mtx.mul_vector2( &t ); - - self.set_tex_coords( &t ); - v[ i ] = self.add_vertex( &p ); - } - - self.add_triangle( v[ 0 ], v[ 1 ], v[ 2 ] ); - self.add_triangle( v[ 2 ], v[ 3 ], v[ 0 ] ); - } -/* - pub fn render_textured_quad_with_tex_matrix( &mut self, pos: &Vector2, size: &Vector2, mtx: &Matrix32 ) { -// let mtx = Matrix22::z_rotation( angle ); - - let positions = [ - Vector2::new( -0.5, 0.5 ), - Vector2::new( -0.5, -0.5 ), - Vector2::new( 0.5, -0.5 ), - Vector2::new( 0.5, 0.5 ), - ]; + let t = tex_coords[i]; + let t = user_tex_mtx.mul_vector2(&t); + let t = tex_mtx.mul_vector2(&t); + + self.set_tex_coords(&t); + v[i] = self.add_vertex(&p); + } + + self.add_triangle(v[0], v[1], v[2]); + self.add_triangle(v[2], v[3], v[0]); + } + /* + pub fn render_textured_quad_with_tex_matrix( &mut self, pos: &Vector2, size: &Vector2, mtx: &Matrix32 ) { + // let mtx = Matrix22::z_rotation( angle ); + + let positions = [ + Vector2::new( -0.5, 0.5 ), + Vector2::new( -0.5, -0.5 ), + Vector2::new( 0.5, -0.5 ), + Vector2::new( 0.5, 0.5 ), + ]; + + let tex_coords = [ + Vector2::new( 0.0, 0.0 ), + Vector2::new( 0.0, 1.0 ), + Vector2::new( 1.0, 1.0 ), + Vector2::new( 1.0, 0.0 ), + ]; + + // let tex_mtx = Matrix32::identity(); + let ti = self.active_textures[ 0 ].unwrap_or( 0 ); + let at = self.texture_manager.get( ti as usize ).unwrap_or( + self.texture_manager.get( 0 ).unwrap() + ); - let tex_coords = [ - Vector2::new( 0.0, 0.0 ), - Vector2::new( 0.0, 1.0 ), - Vector2::new( 1.0, 1.0 ), - Vector2::new( 1.0, 0.0 ), - ]; + // let tex_mtx = *at.mtx(); + let tex_mtx = mtx; // :TODO: combine with active texture matrix - if we want fonts in atlases + let user_tex_mtx = self.tex_matrix; -// let tex_mtx = Matrix32::identity(); - let ti = self.active_textures[ 0 ].unwrap_or( 0 ); - let at = self.texture_manager.get( ti as usize ).unwrap_or( - self.texture_manager.get( 0 ).unwrap() - ); + let mut v = [0u32;4]; -// let tex_mtx = *at.mtx(); - let tex_mtx = mtx; // :TODO: combine with active texture matrix - if we want fonts in atlases - let user_tex_mtx = self.tex_matrix; + // :TODO: future optimization once we have full matrix implementation + // let mtx_tr = Matrix32::translation( pos.x, pos.y ); + // let mtx = mtx_r.mul_matrix( &mtx ); + for i in 0..4 { + let p = positions[ i ]; + let p = p.scale_vector2( &size ); + // let p = mtx.mul_vector2( &p ).add( &pos ); - let mut v = [0u32;4]; + // :TODO: decide if we might want to move this calculation to set_tex_coords + let t = tex_coords[ i ]; + let t = user_tex_mtx.mul_vector2( &t ); + let t = tex_mtx.mul_vector2( &t ); - // :TODO: future optimization once we have full matrix implementation -// let mtx_tr = Matrix32::translation( pos.x, pos.y ); -// let mtx = mtx_r.mul_matrix( &mtx ); - for i in 0..4 { - let p = positions[ i ]; - let p = p.scale_vector2( &size ); -// let p = mtx.mul_vector2( &p ).add( &pos ); + self.set_tex_coords( &t ); + v[ i ] = self.add_vertex( &p ); + } - // :TODO: decide if we might want to move this calculation to set_tex_coords - let t = tex_coords[ i ]; - let t = user_tex_mtx.mul_vector2( &t ); - let t = tex_mtx.mul_vector2( &t ); - - self.set_tex_coords( &t ); - v[ i ] = self.add_vertex( &p ); + self.add_triangle( v[ 0 ], v[ 1 ], v[ 2 ] ); + self.add_triangle( v[ 2 ], v[ 3 ], v[ 0 ] ); } - - self.add_triangle( v[ 0 ], v[ 1 ], v[ 2 ] ); - self.add_triangle( v[ 2 ], v[ 3 ], v[ 0 ] ); - } -*/ - pub fn find_texture_mut( &mut self, name: &str ) -> Option< &mut Texture > { - self.texture_manager.find_mut( |t|{ - t.name() == name - }) + */ + pub fn find_texture_mut(&mut self, name: &str) -> Option<&mut Texture> { + self.texture_manager.find_mut(|t| t.name() == name) } - - pub fn print( - &mut self, - pos: &Vector2, - size: &Vector2, - alignment: &Vector2, - text: &str - ) { - let old_texture_id = self.active_textures[ 0 ]; + pub fn print(&mut self, pos: &Vector2, size: &Vector2, alignment: &Vector2, text: &str) { + let old_texture_id = self.active_textures[0]; { - let font = self.font_manager.get( self.active_font_id ); + let font = self.font_manager.get(self.active_font_id); self.active_font_name = font.name().to_owned(); } // :HACK: @@ -696,88 +685,88 @@ impl Renderer { }; */ let font_name = self.active_font_name.clone(); - self.use_texture( &font_name ); - - + self.use_texture(&font_name); let mut layout = TextLayout::new(); { - let font = self.font_manager.get( self.active_font_id ); - layout.layout( font, &Vector2::zero(), text ); + let font = self.font_manager.get(self.active_font_id); + layout.layout(font, &Vector2::zero(), text); } -// let layout_pos = pos; // :TODO: apply alignment - let layout_size_half = layout.size().scaled( 0.5 ); -// let layout_pos = pos.sub( &layout_size_half ); -// let cpos = ws.sub( &cs ).scaled( 0.5 ).scaled_vector2( &g ); - let layout_pos = size.sub( layout.size() ).scaled( 0.5 ).scaled_vector2( alignment ); - let layout_pos = pos.add( &layout_pos ); - let layout_pos_2 = layout_pos.sub( &layout_size_half ); + // let layout_pos = pos; // :TODO: apply alignment + let layout_size_half = layout.size().scaled(0.5); + // let layout_pos = pos.sub( &layout_size_half ); + // let cpos = ws.sub( &cs ).scaled( 0.5 ).scaled_vector2( &g ); + let layout_pos = size + .sub(layout.size()) + .scaled(0.5) + .scaled_vector2(alignment); + let layout_pos = pos.add(&layout_pos); + let layout_pos_2 = layout_pos.sub(&layout_size_half); for q in layout.quads() { - self.set_tex_matrix( &q.tex_mtx ); + self.set_tex_matrix(&q.tex_mtx); // :TODO: fix position for alignment - self.render_textured_quad( &q.pos.add( &layout_pos_2 ), &q.size ); -// self.render_textured_quad_with_tex_matrix( &q.pos, &q.size, &q.tex_mtx ); + self.render_textured_quad(&q.pos.add(&layout_pos_2), &q.size); + // self.render_textured_quad_with_tex_matrix( &q.pos, &q.size, &q.tex_mtx ); debug_renderer::debug_renderer_add_frame( - &q.pos.add( &layout_pos_2 ), + &q.pos.add(&layout_pos_2), &q.size, 3.0, &Color::red(), ); } -// dbg!(&layout); -// todo!("die"); + // dbg!(&layout); + // todo!("die"); - self.set_tex_matrix( &Matrix32::identity() ); - self.active_textures[ 0 ] = old_texture_id; + self.set_tex_matrix(&Matrix32::identity()); + self.active_textures[0] = old_texture_id; self.switch_active_material_if_needed(); debug_renderer::debug_renderer_add_frame( &pos, &size, 5.0, - &Color::from_rgba( 0.9, 0.75, 0.3, 0.6 ), + &Color::from_rgba(0.9, 0.75, 0.3, 0.6), ); debug_renderer::debug_renderer_add_frame( &layout_pos, &layout.size(), 3.0, - &Color::from_rgba( 0.4, 0.75, 0.3, 0.6 ), + &Color::from_rgba(0.4, 0.75, 0.3, 0.6), ); - } - } #[derive(Debug)] struct Manager { - materials: Vec, + materials: Vec, active_index: usize, } #[allow(dead_code)] -impl Manager { +impl Manager { pub fn new() -> Self { println!("Creating manager for {}", std::any::type_name::()); Self { - materials: Vec::new(), + materials: Vec::new(), active_index: 0, } } - pub fn set_active( &mut self, index: usize ) { + pub fn set_active(&mut self, index: usize) { self.active_index = index; } - pub fn select_active( &mut self, f: F) -> bool - where F: Fn( &T ) -> bool + pub fn select_active(&mut self, f: F) -> bool + where + F: Fn(&T) -> bool, { - for (i,m) in self.materials.iter().enumerate() { - if f( m ) { + for (i, m) in self.materials.iter().enumerate() { + if f(m) { self.active_index = i; return true; } @@ -785,70 +774,70 @@ impl Manager { false } - pub fn len( &self ) -> usize { + pub fn len(&self) -> usize { self.materials.len() } - pub fn add( &mut self, material: T ) -> usize { + pub fn add(&mut self, material: T) -> usize { let i = self.materials.len(); self.materials.push(material); i } - pub fn get( &self, index: usize ) -> Option< &T > { - self.materials.get( index ) + pub fn get(&self, index: usize) -> Option<&T> { + self.materials.get(index) } - pub fn get_mut( &mut self, index: usize ) -> Option< &mut T > { - self.materials.get_mut( index ) + pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { + self.materials.get_mut(index) } - pub fn find_index( &mut self, f: F) -> Option< usize > - where F: Fn( &T ) -> bool + pub fn find_index(&mut self, f: F) -> Option + where + F: Fn(&T) -> bool, { - for (i,m) in self.materials.iter().enumerate() { - if f( m ) { - return Some( i ); + for (i, m) in self.materials.iter().enumerate() { + if f(m) { + return Some(i); } } None } - pub fn find_mut( &mut self, f: F ) -> Option< &mut T > - where F: Fn( &T ) -> bool + pub fn find_mut(&mut self, f: F) -> Option<&mut T> + where + F: Fn(&T) -> bool, { for m in self.materials.iter_mut() { - if f( &m ) { - return Some( m ); + if f(&m) { + return Some(m); } } None } - pub fn iter( &mut self ) -> std::slice::Iter<'_, T> { - self.materials.iter() + pub fn iter(&mut self) -> std::slice::Iter<'_, T> { + self.materials.iter() } - pub fn iter_mut( &mut self ) -> std::slice::IterMut<'_, T> { + pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> { self.materials.iter_mut() } - pub fn get_mut_active( &mut self ) -> &mut T { - match self.materials.get_mut( self.active_index ) { - Some( m ) => m, + pub fn get_mut_active(&mut self) -> &mut T { + match self.materials.get_mut(self.active_index) { + Some(m) => m, None => panic!("No active {}", std::any::type_name::()), } } - pub fn get_active( &self ) -> &T { - match self.materials.get( self.active_index ) { - Some( m ) => m, + pub fn get_active(&self) -> &T { + match self.materials.get(self.active_index) { + Some(m) => m, None => panic!("No active {}", std::any::type_name::()), } } - } - #[derive(Debug)] struct FontManager { - fonts: HashMap< u8, Font >, + fonts: HashMap, } impl FontManager { @@ -858,41 +847,40 @@ impl FontManager { } } - pub fn add( &mut self, id: u8, font: Font ) { - self.fonts.insert( id, font ); + pub fn add(&mut self, id: u8, font: Font) { + self.fonts.insert(id, font); } - pub fn get( &self, id: u8 ) -> &Font { - self.fonts.get( &id ).unwrap() + pub fn get(&self, id: u8) -> &Font { + self.fonts.get(&id).unwrap() } } mod animated_texture; - pub use animated_texture::AnimatedTexture as AnimatedTexture; +pub use animated_texture::AnimatedTexture; mod debug; - pub use debug::Debug as Debug; +pub use debug::Debug; mod gl { - include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs")); + include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs")); } mod effect; - pub use effect::Effect as Effect; +pub use effect::Effect; mod font; - pub use font::Font; +pub use font::Font; mod material; - pub use material::Material as Material; +pub use material::Material; //mod material_builder; // pub use material_builder::MaterialBuilder as MaterialBuilder; mod program; - pub use program::Program as Program; - pub use program::ShaderType as ShaderType; +pub use program::Program; +pub use program::ShaderType; mod text_layout; - pub use text_layout::TextLayout; +pub use text_layout::TextLayout; mod texture; - pub use texture::Texture as Texture; +pub use texture::Texture; mod texture_atlas; - pub use texture_atlas::TextureAtlas as TextureAtlas; +pub use texture_atlas::TextureAtlas; mod uniform; - pub use uniform::Uniform as Uniform; - +pub use uniform::Uniform; diff --git a/src/renderer/animated_texture.rs b/src/renderer/animated_texture.rs index 01fc143..dae9959 100644 --- a/src/renderer/animated_texture.rs +++ b/src/renderer/animated_texture.rs @@ -1,22 +1,23 @@ - - -use crate::renderer::{ - Renderer, - Texture, -}; +use crate::renderer::{Renderer, Texture}; use crate::system::System; #[derive(Debug)] pub struct AnimatedTextureConfiguration { - pub prefix: String, + pub prefix: String, pub number_of_digits: i8, - pub first_frame: u16, - pub last_frame: u16, - pub fps: f32, + pub first_frame: u16, + pub last_frame: u16, + pub fps: f32, } impl AnimatedTextureConfiguration { - pub fn new( prefix: &str, number_of_digits: i8, first_frame: u16, last_frame: u16, fps: f32 ) -> Self { + pub fn new( + prefix: &str, + number_of_digits: i8, + first_frame: u16, + last_frame: u16, + fps: f32, + ) -> Self { Self { prefix: prefix.to_owned(), number_of_digits, @@ -27,69 +28,75 @@ impl AnimatedTextureConfiguration { } } -impl From< ( &str, i8, u16, u16, f32 ) > for AnimatedTextureConfiguration { - fn from( t: ( &str, i8, u16, u16, f32 ) ) -> Self { +impl From<(&str, i8, u16, u16, f32)> for AnimatedTextureConfiguration { + fn from(t: (&str, i8, u16, u16, f32)) -> Self { Self { - prefix: t.0.to_owned(), + prefix: t.0.to_owned(), number_of_digits: t.1, - first_frame: t.2, - last_frame: t.3, - fps: t.4, + first_frame: t.2, + last_frame: t.3, + fps: t.4, } } } #[derive(Debug)] pub struct AnimatedTexture { - prefix: String, - number_of_digits: i8, - first_frame: u16, - number_of_frames: u16, - fps: f32, - current_frame: u16, - time_per_frame: f32, + prefix: String, + number_of_digits: i8, + first_frame: u16, + number_of_frames: u16, + fps: f32, + current_frame: u16, + time_per_frame: f32, time_in_current_frame: f32, } impl AnimatedTexture { - pub fn new() -> Self { Self { - prefix: String::new(), - number_of_digits: 0, - first_frame: 0, - number_of_frames: 0, - fps: 0.0, - current_frame: 0, - time_per_frame: f32::MAX, + prefix: String::new(), + number_of_digits: 0, + first_frame: 0, + number_of_frames: 0, + fps: 0.0, + current_frame: 0, + time_per_frame: f32::MAX, time_in_current_frame: 0.0, } } - pub fn setup( &mut self, prefix: &str, number_of_digits: i8, first_frame: u16, number_of_frames: u16, fps: f32 ) { + pub fn setup( + &mut self, + prefix: &str, + number_of_digits: i8, + first_frame: u16, + number_of_frames: u16, + fps: f32, + ) { self.prefix = prefix.to_owned(); self.number_of_digits = number_of_digits; self.first_frame = first_frame; self.number_of_frames = number_of_frames; self.fps = fps; - self.time_per_frame = 1.0/fps; + self.time_per_frame = 1.0 / fps; self.current_frame = first_frame; } - pub fn setup_from_config( &mut self, config: &AnimatedTextureConfiguration ) { + pub fn setup_from_config(&mut self, config: &AnimatedTextureConfiguration) { self.prefix = config.prefix.clone(); self.number_of_digits = config.number_of_digits; self.first_frame = config.first_frame; self.number_of_frames = config.last_frame - config.first_frame; self.fps = config.fps; - self.time_per_frame = 1.0/self.fps; + self.time_per_frame = 1.0 / self.fps; self.current_frame = self.first_frame; } - pub fn set_current_frame(&mut self, f: u16 ){ + pub fn set_current_frame(&mut self, f: u16) { let mut f = f; while f < self.first_frame { -// todo!("Clip into range"); + // todo!("Clip into range"); f += self.number_of_frames; } while f >= self.first_frame + self.number_of_frames { @@ -99,14 +106,14 @@ impl AnimatedTexture { if f < self.first_frame || f >= self.first_frame + self.number_of_frames { todo!("how di we get here?"); } - + self.current_frame = f; } - pub fn update( &mut self, time_step: f64 ) { + pub fn update(&mut self, time_step: f64) { self.time_in_current_frame += time_step as f32; while self.time_in_current_frame > self.time_per_frame { -// self.current_frame = ( self.current_frame+1 ) % self.number_of_frames; + // self.current_frame = ( self.current_frame+1 ) % self.number_of_frames; self.current_frame += 1; if self.current_frame >= self.first_frame + self.number_of_frames { self.current_frame -= self.number_of_frames; @@ -115,13 +122,17 @@ impl AnimatedTexture { } } - pub fn r#use( &self, renderer: &mut Renderer ) { -// dbg!(&self); - let name = AnimatedTexture::append_number_with_digits( &self.prefix, self.current_frame, self.number_of_digits ); - renderer.use_texture( &name ) + pub fn r#use(&self, renderer: &mut Renderer) { + // dbg!(&self); + let name = AnimatedTexture::append_number_with_digits( + &self.prefix, + self.current_frame, + self.number_of_digits, + ); + renderer.use_texture(&name) } - fn append_number_with_digits( prefix: &str, number: u16, number_of_digits: i8 ) -> String { + fn append_number_with_digits(prefix: &str, number: u16, number_of_digits: i8) -> String { match number_of_digits { 0 => { format!("{}", &prefix) @@ -129,7 +140,7 @@ impl AnimatedTexture { 2 => { format!("{}{:02}", &prefix, number) }, - n if n<0 => { + n if n < 0 => { format!("{}{}", &prefix, number) }, 4 => { @@ -140,36 +151,40 @@ impl AnimatedTexture { } // :HACK: Scanning the filesystem is a bad idea, the info should come from the config - pub fn register_all( system: &mut System, renderer: &mut Renderer, prefix: &str, number_of_digits: i8 ) -> usize { - + pub fn register_all( + system: &mut System, + renderer: &mut Renderer, + prefix: &str, + number_of_digits: i8, + ) -> usize { let fs = system.default_filesystem_mut(); let mut to_load = Vec::new(); let mut i = 0; loop { -// let name = format!( &template, i ); // :( - let name = AnimatedTexture::append_number_with_digits( prefix, i, number_of_digits ); + // let name = format!( &template, i ); // :( + let name = AnimatedTexture::append_number_with_digits(prefix, i, number_of_digits); // :HACK: to workaround missing "exists with .*" let name_ext = format!("{}.png", &name); - if fs.exists( &name_ext ) { - to_load.push( name.to_owned() ); + if fs.exists(&name_ext) { + to_load.push(name.to_owned()); } else { println!("{} does not exist", &name_ext); break; } i += 1; - }; + } dbg!(&to_load); for name in to_load.iter() { - renderer.register_texture( Texture::create( system, &name ) ); + renderer.register_texture(Texture::create(system, &name)); } -// todo!("die"); + // todo!("die"); to_load.len() - } -} \ No newline at end of file + } +} diff --git a/src/renderer/debug.rs b/src/renderer/debug.rs index 83734f0..744996a 100644 --- a/src/renderer/debug.rs +++ b/src/renderer/debug.rs @@ -1,28 +1,25 @@ - use crate::renderer::gl; -pub struct Debug { - - -} +pub struct Debug {} impl Debug { - - pub fn check_gl_error( file: &str, line: u32 ) { + pub fn check_gl_error(file: &str, line: u32) { unsafe { match gl::GetError() { gl::NO_ERROR => {}, e => { - println!("GL Error in {}:{} => {}", file, line, + println!( + "GL Error in {}:{} => {}", + file, + line, match e { gl::INVALID_VALUE => "INVALID_VALUE".to_string(), gl::INVALID_OPERATION => "INVALID_OPERATION".to_string(), - e => format!("{}",e ), + e => format!("{}", e), } ); }, } } } - } diff --git a/src/renderer/debug_renderer.rs b/src/renderer/debug_renderer.rs index e19bbc2..a0c1a4a 100644 --- a/src/renderer/debug_renderer.rs +++ b/src/renderer/debug_renderer.rs @@ -5,26 +5,21 @@ use lazy_static::lazy_static; use crate::math::Matrix22; use crate::math::Vector2; - -use crate::renderer::{ - Color, - Renderer -}; - +use crate::renderer::{Color, Renderer}; #[derive(Debug)] struct Line { start: Vector2, - end: Vector2, + end: Vector2, width: f32, color: Color, } #[derive(Debug)] pub struct DebugRenderer { - layer: u8, + layer: u8, effect: u16, - lines: Vec< Line >, + lines: Vec, } //pub static mut DEFAULT_DEBUGRENDERER: Option< Arc< Mutex< DebugRenderer > > > = None; @@ -36,57 +31,56 @@ lazy_static! { } // :TODO: make these macros that compiles to NOP -pub fn debug_renderer_toggle( layer_id: u8, effect_id: u16 ) { +pub fn debug_renderer_toggle(layer_id: u8, effect_id: u16) { let mut lock = DEFAULT_DEBUGRENDERER.try_lock(); if let Ok(ref mut dr) = lock { if dr.is_none() { - **dr = Some( DebugRenderer::new( layer_id, effect_id ) ); + **dr = Some(DebugRenderer::new(layer_id, effect_id)); } else { **dr = None; - } - } + } + } } -pub fn debug_renderer_add_line( start: &Vector2, end: &Vector2, width: f32, color: &Color ) { +pub fn debug_renderer_add_line(start: &Vector2, end: &Vector2, width: f32, color: &Color) { let mut lock = DEFAULT_DEBUGRENDERER.try_lock(); if let Ok(ref mut dr) = lock { - if let Some( dr ) = &mut **dr { - dr.add_line( start, end, width, color ); - } + if let Some(dr) = &mut **dr { + dr.add_line(start, end, width, color); + } } } -pub fn debug_renderer_add_frame( pos: &Vector2, size: &Vector2, width: f32, color: &Color ) { +pub fn debug_renderer_add_frame(pos: &Vector2, size: &Vector2, width: f32, color: &Color) { let mut lock = DEFAULT_DEBUGRENDERER.try_lock(); if let Ok(ref mut dr) = lock { - if let Some( dr ) = &mut **dr { - dr.add_frame( pos, size, width, color ); - } + if let Some(dr) = &mut **dr { + dr.add_frame(pos, size, width, color); + } } } -pub fn debug_renderer_begin_frame( ) { +pub fn debug_renderer_begin_frame() { let mut lock = DEFAULT_DEBUGRENDERER.try_lock(); if let Ok(ref mut dr) = lock { - if let Some( dr ) = &mut **dr { - dr.begin_frame( ); - } + if let Some(dr) = &mut **dr { + dr.begin_frame(); + } } } -pub fn debug_renderer_render( renderer: &mut Renderer ) { +pub fn debug_renderer_render(renderer: &mut Renderer) { let mut lock = DEFAULT_DEBUGRENDERER.try_lock(); if let Ok(ref mut dr) = lock { - if let Some( dr ) = &mut **dr { - dr.render( renderer ); + if let Some(dr) = &mut **dr { + dr.render(renderer); } } } - // end of macros impl DebugRenderer { - pub fn new( layer: u8, effect: u16 ) -> Self { + pub fn new(layer: u8, effect: u16) -> Self { Self { layer, effect, @@ -94,91 +88,117 @@ impl DebugRenderer { } } - - pub fn begin_frame( &mut self ) { + pub fn begin_frame(&mut self) { self.lines.clear(); } - pub fn end_frame( &mut self ) { - - } + pub fn end_frame(&mut self) {} - pub fn render( &self, renderer: &mut Renderer ) { -// println!("Debug Render rendering"); -// println!("{} lines", self.lines.len()); + pub fn render(&self, renderer: &mut Renderer) { + // println!("Debug Render rendering"); + // println!("{} lines", self.lines.len()); - renderer.use_layer( self.layer ); - renderer.use_effect( self.effect ); + renderer.use_layer(self.layer); + renderer.use_effect(self.effect); for l in &self.lines { let v0 = l.start; let v1 = l.end; - let v01 = v1.sub( &v0 ).normalized(); - let vp = Vector2::new( -v01.y, v01.x ); -// let vp = Vector2::new( 0.0, 1.0 ); - let vl = vp.scaled( 0.5*l.width ); - let vr = vp.scaled( -0.5*l.width ); - - let v0 = l.start.add( &vr ); - let v1 = l.end.add( &vr ); + let v01 = v1.sub(&v0).normalized(); + let vp = Vector2::new(-v01.y, v01.x); + // let vp = Vector2::new( 0.0, 1.0 ); + let vl = vp.scaled(0.5 * l.width); + let vr = vp.scaled(-0.5 * l.width); - let v2 = l.start.add( &vl ); - let v3 = l.end.add( &vl ); + let v0 = l.start.add(&vr); + let v1 = l.end.add(&vr); -// println!("{:?} {:?} \n{:?} {:?} {:?} {:?} \n{:?} {:?} {:?} ",&l.start, &l.end, &v0,&v1,&v2, &v3, &v01, &vl, &vr); -// println!("{} + {} = {}", l.start.y, vl.y, v2.y ); + let v2 = l.start.add(&vl); + let v3 = l.end.add(&vl); - renderer.set_color( &l.color ); + // println!("{:?} {:?} \n{:?} {:?} {:?} {:?} \n{:?} {:?} {:?} ",&l.start, &l.end, &v0,&v1,&v2, &v3, &v01, &vl, &vr); + // println!("{} + {} = {}", l.start.y, vl.y, v2.y ); - let v0 = renderer.add_vertex( &v0 ); - let v1 = renderer.add_vertex( &v1 ); - let v2 = renderer.add_vertex( &v2 ); - let v3 = renderer.add_vertex( &v3 ); + renderer.set_color(&l.color); - renderer.add_triangle( v0, v1, v2 ); - renderer.add_triangle( v2, v1, v3 ); + let v0 = renderer.add_vertex(&v0); + let v1 = renderer.add_vertex(&v1); + let v2 = renderer.add_vertex(&v2); + let v3 = renderer.add_vertex(&v3); + renderer.add_triangle(v0, v1, v2); + renderer.add_triangle(v2, v1, v3); } } - pub fn add_line( &mut self, start: &Vector2, end: &Vector2, width: f32, color: &Color ) { - let line = { Line { start: *start, end: *end, width, color: *color } }; - self.lines.push( line ); + pub fn add_line(&mut self, start: &Vector2, end: &Vector2, width: f32, color: &Color) { + let line = { + Line { + start: *start, + end: *end, + width, + color: *color, + } + }; + self.lines.push(line); } - pub fn add_frame( &mut self, pos: &Vector2, size: &Vector2, width: f32, color: &Color ) { - let half_size = size.scaled_vector2( &Vector2::new( -0.5, 0.5 ) ); - let top_left = pos.add( &half_size ); - let bottom_right = pos.sub( &half_size ); - - self.add_line( &top_left, &bottom_right, width, color ); - self.add_line( &Vector2::new( bottom_right.x, top_left.y ), &Vector2::new( top_left.x, bottom_right.y ), width, color ); - self.add_line( &Vector2::new( top_left.x, top_left.y ), &Vector2::new( top_left.x, bottom_right.y ), width, color ); - self.add_line( &Vector2::new( bottom_right.x, top_left.y ), &Vector2::new( bottom_right.x, bottom_right.y ), width, color ); - self.add_line( &Vector2::new( top_left.x, top_left.y ), &Vector2::new( bottom_right.x, top_left.y ), width, color ); - self.add_line( &Vector2::new( top_left.x, bottom_right.y ), &Vector2::new( bottom_right.x, bottom_right.y ), width, color ); + pub fn add_frame(&mut self, pos: &Vector2, size: &Vector2, width: f32, color: &Color) { + let half_size = size.scaled_vector2(&Vector2::new(-0.5, 0.5)); + let top_left = pos.add(&half_size); + let bottom_right = pos.sub(&half_size); + + self.add_line(&top_left, &bottom_right, width, color); + self.add_line( + &Vector2::new(bottom_right.x, top_left.y), + &Vector2::new(top_left.x, bottom_right.y), + width, + color, + ); + self.add_line( + &Vector2::new(top_left.x, top_left.y), + &Vector2::new(top_left.x, bottom_right.y), + width, + color, + ); + self.add_line( + &Vector2::new(bottom_right.x, top_left.y), + &Vector2::new(bottom_right.x, bottom_right.y), + width, + color, + ); + self.add_line( + &Vector2::new(top_left.x, top_left.y), + &Vector2::new(bottom_right.x, top_left.y), + width, + color, + ); + self.add_line( + &Vector2::new(top_left.x, bottom_right.y), + &Vector2::new(bottom_right.x, bottom_right.y), + width, + color, + ); } - pub fn add_circle( &mut self, pos: &Vector2, radius: f32, width: f32, color: &Color ) { - let mut vr = Vector2::new( radius, 0.0 ); + pub fn add_circle(&mut self, pos: &Vector2, radius: f32, width: f32, color: &Color) { + let mut vr = Vector2::new(radius, 0.0); // we could add some code to decide on the number of segments here let n = 24; let r_step = 360.0 / n as f32; // rotate - let mtx = Matrix22::z_rotation( r_step * 0.01745329252); // DEG to RAD - + let mtx = Matrix22::z_rotation(r_step * 0.01745329252); // DEG to RAD let mut vertices = Vec::new(); for _ in 0..n { - let v = pos.add( &vr ); - vertices.push( v ); + let v = pos.add(&vr); + vertices.push(v); - vr = mtx.mul_vector2( &vr ); + vr = mtx.mul_vector2(&vr); } for i in 0..vertices.len() { - let v0 = vertices[ i ]; - let v1 = vertices[ ( i + 1 ) % vertices.len() ]; - self.add_line( &v0, &v1, width, color ); - } - + let v0 = vertices[i]; + let v1 = vertices[(i + 1) % vertices.len()]; + self.add_line(&v0, &v1, width, color); + } } } diff --git a/src/renderer/effect.rs b/src/renderer/effect.rs index 23580ed..7c9f549 100644 --- a/src/renderer/effect.rs +++ b/src/renderer/effect.rs @@ -1,18 +1,15 @@ - - use crate::renderer::{ -// Debug, -// gl, + // Debug, + // gl, Program, ShaderType, }; use crate::system::System; - #[derive(Debug)] pub struct Effect { - id: u16, - name: String, + id: u16, + name: String, program: Program, } @@ -24,31 +21,25 @@ impl Effect { vertex_shader_name: &str, fragment_shader_name: &str, ) -> Self { - Effect::new( - system, - id, - name, - vertex_shader_name, - fragment_shader_name, - ) + Effect::new(system, id, name, vertex_shader_name, fragment_shader_name) } fn new( system: &mut System, id: u16, name: &str, vertex_shader_name: &str, - fragment_shader_name: &str, + fragment_shader_name: &str, ) -> Self { let mut program = Program::new(); - let mut vsf = system.default_filesystem_mut().open( &vertex_shader_name ); + let mut vsf = system.default_filesystem_mut().open(&vertex_shader_name); let vs = vsf.read_as_string(); - let mut fsf = system.default_filesystem_mut().open( &fragment_shader_name ); + let mut fsf = system.default_filesystem_mut().open(&fragment_shader_name); let fs = fsf.read_as_string(); - program.add_shader( ShaderType::Vertex, &vs ); - program.add_shader( ShaderType::Fragment, &fs ); + program.add_shader(ShaderType::Vertex, &vs); + program.add_shader(ShaderType::Fragment, &fs); program.link(); Self { @@ -58,19 +49,19 @@ impl Effect { } } - pub fn id( &self ) -> u16 { + pub fn id(&self) -> u16 { self.id } - pub fn r#use( &mut self ) { + pub fn r#use(&mut self) { self.program.r#use(); } - pub fn name( &self ) -> &str { + pub fn name(&self) -> &str { &self.name } - pub fn program(&self) -> &Program { + pub fn program(&self) -> &Program { &self.program } } diff --git a/src/renderer/font.rs b/src/renderer/font.rs index d316fc6..7021239 100644 --- a/src/renderer/font.rs +++ b/src/renderer/font.rs @@ -1,96 +1,93 @@ - - use crate::system::System; -#[derive(Debug,Copy,Clone)] +#[derive(Debug, Copy, Clone)] pub struct Glyph { - pub codepoint: u8, - pub width: u32, - pub height: u32, - pub x: u32, - pub y: u32, - pub advance: u16, - pub y_offset: f32, - pub matrix: [f32;6], + pub codepoint: u8, + pub width: u32, + pub height: u32, + pub x: u32, + pub y: u32, + pub advance: u16, + pub y_offset: f32, + pub matrix: [f32; 6], } impl Glyph { - pub fn new( codepoint: u8, width: u32, height: u32 ) -> Glyph { + pub fn new(codepoint: u8, width: u32, height: u32) -> Glyph { Glyph { codepoint: codepoint, - width: width, - height: height, - x: 0, - y: 0, - advance: 0, - y_offset: 0.0, - matrix: [0.0;6], + width: width, + height: height, + x: 0, + y: 0, + advance: 0, + y_offset: 0.0, + matrix: [0.0; 6], } } - fn recalc_from_matrix( &mut self, texsize: u32 ) { - self.width = ( self.matrix[ 0*3 + 0 ] * texsize as f32 ).trunc() as u32; - self.height = ( self.matrix[ 1*3 + 1 ] * texsize as f32 ).trunc() as u32; - self.x = ( self.matrix[ 0*3 + 2 ] * texsize as f32 ).trunc() as u32; - self.y = ( self.matrix[ 1*3 + 2 ] * texsize as f32 ).trunc() as u32; + fn recalc_from_matrix(&mut self, texsize: u32) { + self.width = (self.matrix[0 * 3 + 0] * texsize as f32).trunc() as u32; + self.height = (self.matrix[1 * 3 + 1] * texsize as f32).trunc() as u32; + self.x = (self.matrix[0 * 3 + 2] * texsize as f32).trunc() as u32; + self.y = (self.matrix[1 * 3 + 2] * texsize as f32).trunc() as u32; // :HACK: since omt-font might be broken - if self.codepoint != 32 { // leave SPACE alone + if self.codepoint != 32 { + // leave SPACE alone self.advance = self.width as u16; } self.y_offset = self.y_offset * texsize as f32; } - } - #[derive(Debug)] pub struct Font { glyphs: Vec, - size: u16, - name: String, + size: u16, + name: String, } impl Font { - pub fn create( system: &mut System, name: &str ) -> Self { - let mut f = Font::new( name ); - f.load( system, name ); + pub fn create(system: &mut System, name: &str) -> Self { + let mut f = Font::new(name); + f.load(system, name); f } - pub fn recalc_from_matrix( &mut self, texsize: u32 ) { + pub fn recalc_from_matrix(&mut self, texsize: u32) { let mut hi_code = 0; let mut hi_h = 0; for g in &mut self.glyphs { - g.recalc_from_matrix( texsize ); - let y = ( g.height as f32 - g.y_offset ) as u32; + g.recalc_from_matrix(texsize); + let y = (g.height as f32 - g.y_offset) as u32; if y > hi_h { hi_h = y; hi_code = g.codepoint; -// dbg!(&g); + // dbg!(&g); } } -// dbg!(&hi_code, &hi_h, self.size); + // dbg!(&hi_code, &hi_h, self.size); // :HACK: cheat, since the font converter doesn't give us what we need self.size = hi_h as u16; -// todo!("die"); + // todo!("die"); } - fn new( name: &str ) -> Self { + fn new(name: &str) -> Self { Self { glyphs: Vec::new(), - size: 0, - name: name.to_owned(), + size: 0, + name: name.to_owned(), } } - fn load( &mut self, system: &mut System, name: &str ) -> bool { - let filename = format!("{}{}", name, ".omfont" ); - let mut f = system.default_filesystem_mut().open( &filename ); + fn load(&mut self, system: &mut System, name: &str) -> bool { + let filename = format!("{}{}", name, ".omfont"); + let mut f = system.default_filesystem_mut().open(&filename); if f.is_valid() { - println!("Loading font from {}", &filename ); + println!("Loading font from {}", &filename); } - let chunk_magic = [ 0x4fu8, 0x4d, 0x46, 0x4f, 0x4e, 0x54, ]; + let chunk_magic = [0x4fu8, 0x4d, 0x46, 0x4f, 0x4e, 0x54]; for m in &chunk_magic { let b = f.read_u8(); if b != *m { @@ -109,42 +106,42 @@ impl Font { for _ in 0..count { let codepoint = f.read_u32(); - codepoints.push( codepoint ); + codepoints.push(codepoint); } for c in 0..count { - let codepoint = codepoints[ c as usize ]; - let mut glyph = Glyph::new( codepoint as u8, 0, 0 ); + let codepoint = codepoints[c as usize]; + let mut glyph = Glyph::new(codepoint as u8, 0, 0); for m in &mut glyph.matrix { *m = f.read_f32(); } glyph.advance = f.read_f32() as u16; - if codepoint == 32 { //SPACE // :HACK: since space is written with an advance of 0 + if codepoint == 32 { + //SPACE // :HACK: since space is written with an advance of 0 glyph.advance = self.size / 4; dbg!(&glyph); } glyph.y_offset = f.read_f32(); - self.glyphs.push( glyph ); + self.glyphs.push(glyph); } - true } - pub fn find_glyph( &self, codepoint: u8 ) -> Option< &Glyph > { + pub fn find_glyph(&self, codepoint: u8) -> Option<&Glyph> { for g in self.glyphs.iter() { if g.codepoint == codepoint { - return Some( g ); + return Some(g); } } None } - pub fn name( &self ) -> &str { + pub fn name(&self) -> &str { &self.name } - pub fn size( &self ) -> f32 { + pub fn size(&self) -> f32 { self.size as f32 } } diff --git a/src/renderer/material.rs b/src/renderer/material.rs index f5784e5..af381c8 100644 --- a/src/renderer/material.rs +++ b/src/renderer/material.rs @@ -1,59 +1,61 @@ - use std::collections::HashMap; +use derivative::Derivative; + use crate::math::Matrix44; use crate::renderer::{ -// Debug, - Effect, gl, -// Program, -// ShaderType, + // Debug, + Effect, + // Program, + // ShaderType, Texture, Uniform, Vertex, }; -use derivative::Derivative; - //#[derive(Debug)] #[derive(Derivative)] #[derivative(Debug)] pub struct Material { - #[derivative(Debug="ignore")] + #[derivative(Debug = "ignore")] vertices: Vec, - buffer: gl::types::GLuint, - vao: gl::types::GLuint, + buffer: gl::types::GLuint, + vao: gl::types::GLuint, - layer_id: u8, - effect_id: u16, + layer_id: u8, + effect_id: u16, texture_hwids: Vec, - effect_name: String, + effect_name: String, texture_name: String, key: u128, - uniforms: HashMap< String, Uniform >, + uniforms: HashMap, mvp_matrix: Matrix44, } impl Material { - - pub fn new( layer_id: u8, effect: &Effect, textures: Vec< &Texture > ) -> Self { - let texture_hwids = textures.iter().map( |&t| t.hwid() ).collect(); - let key = Material::calculate_key( layer_id, effect.id(), &texture_hwids ); - let texture_name = textures.iter().map( |&t| t.name().to_owned() ).collect::>().join(" "); + pub fn new(layer_id: u8, effect: &Effect, textures: Vec<&Texture>) -> Self { + let texture_hwids = textures.iter().map(|&t| t.hwid()).collect(); + let key = Material::calculate_key(layer_id, effect.id(), &texture_hwids); + let texture_name = textures + .iter() + .map(|&t| t.name().to_owned()) + .collect::>() + .join(" "); let mut s = Self { vertices: Vec::new(), - buffer: 0xffffffff, - vao: 0xffffffff, + buffer: 0xffffffff, + vao: 0xffffffff, - layer_id: layer_id, - effect_id: effect.id(), + layer_id: layer_id, + effect_id: effect.id(), texture_hwids: texture_hwids, - effect_name: effect.name().to_string(), + effect_name: effect.name().to_string(), texture_name: texture_name, key: key, @@ -64,15 +66,15 @@ impl Material { }; unsafe { - gl::GenVertexArrays( 1, &mut s.vao ); - gl::GenBuffers( 1, &mut s.buffer ); + gl::GenVertexArrays(1, &mut s.vao); + gl::GenBuffers(1, &mut s.buffer); } s } - pub fn calculate_key( layer_id: u8, effect_id: u16, texture_hwids: &Vec< u16 > ) -> u128 { - // old fiiish: + pub fn calculate_key(layer_id: u8, effect_id: u16, texture_hwids: &Vec) -> u128 { + // old fiiish: // 00##llll pppppppp rrrrtttt tttttttt // .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. @@ -81,170 +83,187 @@ impl Material { // .. .. .. .. .. .. .l rr t3 t3 t2 t2 t1 t1 tt tt if texture_hwids.len() > 4 { - panic!("Too many texture channels. {}", texture_hwids.len() ); + panic!("Too many texture channels. {}", texture_hwids.len()); } if effect_id > 0xff { - panic!("Too many effects. Got id {}", &effect_id ); + panic!("Too many effects. Got id {}", &effect_id); } let mut r = 0u128; let mut shift = 0; for i in 0..4 { - if let Some( texture_hwid ) = texture_hwids.get( i ) { + if let Some(texture_hwid) = texture_hwids.get(i) { /* :TODO: reenable if we change type, or extend maximum number of textures if *texture_hwid > 0xffff { panic!("Too many textures. Got id {}", &texture_hwid ); } */ - r |= ( *texture_hwid as u128 & 0xffff ) << shift; + r |= (*texture_hwid as u128 & 0xffff) << shift; } shift += 16; } - r - | ( ( effect_id as u128 & 0xff ) << ( shift ) ) - | ( ( layer_id as u128 & 0x000f ) << ( 8+shift ) ) + r | ((effect_id as u128 & 0xff) << (shift)) | ((layer_id as u128 & 0x000f) << (8 + shift)) } - pub fn can_render( &self, key: u128 ) -> bool { -// self.effect_id == effect_id + pub fn can_render(&self, key: u128) -> bool { + // self.effect_id == effect_id self.key == key } - pub fn key( &self ) -> u128 { + pub fn key(&self) -> u128 { self.key } - pub fn layer_id( &self ) -> u8 { + pub fn layer_id(&self) -> u8 { self.layer_id } - pub fn effect_id( &self ) -> u16 { + pub fn effect_id(&self) -> u16 { self.effect_id } -/* - pub fn texture_hwid( &self ) -> u16 { - self.texture_hwid - } -*/ - pub fn effect_name( &self ) -> &str { + /* + pub fn texture_hwid( &self ) -> u16 { + self.texture_hwid + } + */ + pub fn effect_name(&self) -> &str { &self.effect_name } - pub fn texture_name( &self ) -> &str { + pub fn texture_name(&self) -> &str { &self.texture_name } - pub fn clear( &mut self ) { + pub fn clear(&mut self) { self.vertices.clear(); } - pub fn add_vertex( &mut self, vertex: &Vertex ) { - self.vertices.push( *vertex ); + pub fn add_vertex(&mut self, vertex: &Vertex) { + self.vertices.push(*vertex); } - pub fn set_uniform( &mut self, name: &str, value: &Uniform ) { - self.uniforms.insert( name.to_owned(), *value ); + pub fn set_uniform(&mut self, name: &str, value: &Uniform) { + self.uniforms.insert(name.to_owned(), *value); } - pub fn set_mvp_matrix( &mut self, mvp_matrix: &Matrix44 ) { + pub fn set_mvp_matrix(&mut self, mvp_matrix: &Matrix44) { self.mvp_matrix = *mvp_matrix; } - pub fn render( &mut self, effect: &mut Effect ) -> u32 { + pub fn render(&mut self, effect: &mut Effect) -> u32 { let vertex_count = self.vertices.len(); if vertex_count == 0 { return 0; } unsafe { - gl::Enable( gl::BLEND ); - gl::BlendFunc( gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA ); + gl::Enable(gl::BLEND); + gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); -// gl::Disable( gl::BLEND ); -// gl::BlendFunc( gl::ONE, gl::ONE ); + // gl::Disable( gl::BLEND ); + // gl::BlendFunc( gl::ONE, gl::ONE ); - gl::BindVertexArray( self.vao ); - gl::BindBuffer( gl::ARRAY_BUFFER, self.buffer ); + gl::BindVertexArray(self.vao); + gl::BindBuffer(gl::ARRAY_BUFFER, self.buffer); -// let vertex_size = ( core::mem::size_of() * 3 ) as i32; - let vertex_size = ( core::mem::size_of::( ) * ( 3 + 2 + 4 ) ) as isize; // :HACK: - // :TODO: we might want to reuse this + // let vertex_size = ( core::mem::size_of() * 3 ) as i32; + let vertex_size = (core::mem::size_of::() * (3 + 2 + 4)) as isize; // :HACK: + // :TODO: we might want to reuse this gl::BufferData( gl::ARRAY_BUFFER, vertex_size * vertex_count as isize, self.vertices.as_ptr() as *const core::ffi::c_void, - gl::STATIC_DRAW //maybe STREAM? + gl::STATIC_DRAW, //maybe STREAM? ); let attrib_pos_index = 0; let attrib_tex_coords_index = 1; let attrib_color_index = 2; - gl::EnableVertexAttribArray( attrib_pos_index ); - gl::VertexAttribPointer( attrib_pos_index, 3, gl::FLOAT, gl::FALSE, vertex_size as i32, 0 as *const _ ); + gl::EnableVertexAttribArray(attrib_pos_index); + gl::VertexAttribPointer( + attrib_pos_index, + 3, + gl::FLOAT, + gl::FALSE, + vertex_size as i32, + 0 as *const _, + ); // :TODO: only enable when needed - gl::EnableVertexAttribArray( attrib_tex_coords_index ); - gl::VertexAttribPointer( attrib_tex_coords_index, 2, gl::FLOAT, gl::FALSE, vertex_size as i32, ( 3 * 4 ) as *const _ ); + gl::EnableVertexAttribArray(attrib_tex_coords_index); + gl::VertexAttribPointer( + attrib_tex_coords_index, + 2, + gl::FLOAT, + gl::FALSE, + vertex_size as i32, + (3 * 4) as *const _, + ); // :TODO: only enable when needed - gl::EnableVertexAttribArray( attrib_color_index ); - gl::VertexAttribPointer( attrib_color_index, 4, gl::FLOAT, gl::FALSE, vertex_size as i32, ( ( 3+2 ) * 4 ) as *const _ ); + gl::EnableVertexAttribArray(attrib_color_index); + gl::VertexAttribPointer( + attrib_color_index, + 4, + gl::FLOAT, + gl::FALSE, + vertex_size as i32, + ((3 + 2) * 4) as *const _, + ); effect.r#use(); // :HACK: - for ( n, v ) in self.uniforms.iter() { - match effect.program().lookup_uniform( &n ) { - Some( l ) => { -// println!("Location for {} is {}", &n, l ); + for (n, v) in self.uniforms.iter() { + match effect.program().lookup_uniform(&n) { + Some(l) => { + // println!("Location for {} is {}", &n, l ); match v { - Uniform::F32( v ) => { - gl::Uniform1f( l, *v ); + Uniform::F32(v) => { + gl::Uniform1f(l, *v); }, -// _ => todo!("Uniform type not supported. {:?}", v ), - + // _ => todo!("Uniform type not supported. {:?}", v ), } }, None => { - println!("Warning: Location of {} not found {:?}", &n, &effect ); + println!("Warning: Location of {} not found {:?}", &n, &effect); }, } } - for ( n, l ) in effect.program().uniforms_iter() { -// println!("{} -> {}", &n, &l ); + for (n, l) in effect.program().uniforms_iter() { + // println!("{} -> {}", &n, &l ); match n.as_str() { "texture0\0" => { - gl::Uniform1i( *l, 0 ); // always use channel 0 for texture0 + gl::Uniform1i(*l, 0); // always use channel 0 for texture0 }, "texture1\0" => { - gl::Uniform1i( *l, 1 ); // always use channel 1 for texture1 + gl::Uniform1i(*l, 1); // always use channel 1 for texture1 }, "modelViewProjectionMatrix\0" => { - gl::UniformMatrix4fv( *l, 1, 0, self.mvp_matrix.as_ptr() as *const _ ); - - } + gl::UniformMatrix4fv(*l, 1, 0, self.mvp_matrix.as_ptr() as *const _); + }, _ => { todo!("handle uniform {:?}", &n); }, } } -// gl::Uniform1i( 0, 0 ); + // gl::Uniform1i( 0, 0 ); - for ( i, hwid ) in self.texture_hwids.iter().enumerate() { - gl::ActiveTexture( gl::TEXTURE0+i as u32 ); - gl::BindTexture( gl::TEXTURE_2D, *hwid as u32 ); + for (i, hwid) in self.texture_hwids.iter().enumerate() { + gl::ActiveTexture(gl::TEXTURE0 + i as u32); + gl::BindTexture(gl::TEXTURE_2D, *hwid as u32); } // :TODO: decide if we really cleanup in case somebody else expects defaults - gl::ActiveTexture( gl::TEXTURE0 ); + gl::ActiveTexture(gl::TEXTURE0); -// dbg!(&self.vertices); -// gl::PolygonMode( gl::FRONT_AND_BACK, gl::LINE ); - gl::DrawArrays( gl::TRIANGLES, 0, vertex_count as i32 ); -// println!("Rendering {} vertices", vertex_count); + // dbg!(&self.vertices); + // gl::PolygonMode( gl::FRONT_AND_BACK, gl::LINE ); + gl::DrawArrays(gl::TRIANGLES, 0, vertex_count as i32); + // println!("Rendering {} vertices", vertex_count); vertex_count as u32 } -// dbg!(&self); + // dbg!(&self); } } /* diff --git a/src/renderer/program.rs b/src/renderer/program.rs index fce20df..cbf7d9f 100644 --- a/src/renderer/program.rs +++ b/src/renderer/program.rs @@ -1,16 +1,15 @@ - use std::collections::HashMap; +use derivative::Derivative; + //use crate::renderer::Program; use crate::renderer::{ - Debug, gl, -// Uniform, + // Uniform, + Debug, }; -use derivative::Derivative; - -#[derive(Debug,Copy,Clone,PartialEq,Eq,Hash)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum ShaderType { Vertex, Fragment, @@ -19,84 +18,86 @@ pub enum ShaderType { #[derive(Derivative)] #[derivative(Debug)] pub struct Program { - -// shader_ids: HashMap, - shader_ids: Vec< (ShaderType, gl::types::GLuint) >, + // shader_ids: HashMap, + shader_ids: Vec<(ShaderType, gl::types::GLuint)>, program_id: gl::types::GLuint, - uniforms: HashMap< String, i32 >, + uniforms: HashMap, - #[derivative(Debug="ignore")] + #[derivative(Debug = "ignore")] // :TODO: make debug only - shader_sources: Vec< (ShaderType, String) >, + shader_sources: Vec<(ShaderType, String)>, } impl Program { pub fn new() -> Self { Self { -// shader_ids: HashMap::new(), + // shader_ids: HashMap::new(), shader_ids: Vec::new(), program_id: 0xffffffff, - uniforms: HashMap::new(), + uniforms: HashMap::new(), shader_sources: Vec::new(), } } - pub fn add_shader( &mut self, shader_type: ShaderType, source: &str ) { + pub fn add_shader(&mut self, shader_type: ShaderType, source: &str) { let gl_shader_type = match shader_type { ShaderType::Vertex => gl::VERTEX_SHADER, ShaderType::Fragment => gl::FRAGMENT_SHADER, -// _ => todo!("{:?}", &shader_type), + // _ => todo!("{:?}", &shader_type), }; unsafe { - let id = gl::CreateShader( gl_shader_type ); + let id = gl::CreateShader(gl_shader_type); gl::ShaderSource( id, 1, - [ source.as_ptr() as *const _].as_ptr() as *const _, + [source.as_ptr() as *const _].as_ptr() as *const _, //std::ptr::null(), - [ source.len() ].as_ptr() as *const _, + [source.len()].as_ptr() as *const _, ); - gl::CompileShader( id ); + gl::CompileShader(id); let mut log_length = 0; - gl::GetShaderiv( id, gl::INFO_LOG_LENGTH, &mut log_length ); + gl::GetShaderiv(id, gl::INFO_LOG_LENGTH, &mut log_length); if log_length > 0 { // :TODO: get actual log - println!("Warning: LogLength {} for shader {:?}\n{}", &log_length, &shader_type, &source ); - - let mut buf: Vec = Vec::with_capacity( log_length as usize ); - gl::GetShaderInfoLog( id, log_length, &mut log_length, buf.as_mut_ptr() as *mut _ ); - buf.set_len( log_length as usize ); - let s = String::from_utf8( buf ).unwrap(); - println!("Error Log: {}", &s ); -/* - - GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(*shader, logLength, &logLength, log); -*/ + println!( + "Warning: LogLength {} for shader {:?}\n{}", + &log_length, &shader_type, &source + ); + + let mut buf: Vec = Vec::with_capacity(log_length as usize); + gl::GetShaderInfoLog(id, log_length, &mut log_length, buf.as_mut_ptr() as *mut _); + buf.set_len(log_length as usize); + let s = String::from_utf8(buf).unwrap(); + println!("Error Log: {}", &s); + /* + + GLchar *log = (GLchar *)malloc(logLength); + glGetShaderInfoLog(*shader, logLength, &logLength, log); + */ } -// self.shader_ids.insert( shader_type, id ); - self.shader_ids.push( ( shader_type, id ) ); - self.shader_sources.push( ( shader_type, source.to_string() ) ); + // self.shader_ids.insert( shader_type, id ); + self.shader_ids.push((shader_type, id)); + self.shader_sources.push((shader_type, source.to_string())); } - Debug::check_gl_error( std::file!(), std::line!() ); + Debug::check_gl_error(std::file!(), std::line!()); } - pub fn link( &mut self ) { + pub fn link(&mut self) { unsafe { let id = gl::CreateProgram(); -// for s_id in self.shader_ids.values() { - for ( _, s_id ) in self.shader_ids.iter() { - gl::AttachShader( id, *s_id ); + // for s_id in self.shader_ids.values() { + for (_, s_id) in self.shader_ids.iter() { + gl::AttachShader(id, *s_id); } - gl::LinkProgram( id ); + gl::LinkProgram(id); let mut status = 0; - gl::GetProgramiv( id, gl::LINK_STATUS, &mut status ); + gl::GetProgramiv(id, gl::LINK_STATUS, &mut status); if status != 1 { println!("Warning: Failed linking shaders into program"); for (_k, s) in self.shader_sources.iter() { @@ -105,46 +106,43 @@ impl Program { } dbg!(&status); - self.program_id = id; } - Debug::check_gl_error( std::file!(), std::line!() ); + Debug::check_gl_error(std::file!(), std::line!()); // lookup common uniforms unsafe { - let uniform_names = [ "texture0\0", "texture1\0", "modelViewProjectionMatrix\0" ]; + let uniform_names = ["texture0\0", "texture1\0", "modelViewProjectionMatrix\0"]; for un in uniform_names.iter() { - let l = gl::GetUniformLocation( self.program_id, un.as_ptr() as *const _ ); + let l = gl::GetUniformLocation(self.program_id, un.as_ptr() as *const _); if l != -1 { - println!("Got uniform {} at location {}", &un, l ); - self.uniforms.insert( un.to_string(), l ); + println!("Got uniform {} at location {}", &un, l); + self.uniforms.insert(un.to_string(), l); } } - } } - pub fn lookup_uniform( &self, name: &str ) -> Option< i32 > { + pub fn lookup_uniform(&self, name: &str) -> Option { unsafe { // :TODO: use cache - let l = gl::GetUniformLocation( self.program_id, name.as_ptr() as *const _ ); + let l = gl::GetUniformLocation(self.program_id, name.as_ptr() as *const _); if l != -1 { - Some( l ) + Some(l) } else { None } } } - - pub fn uniforms_iter( &self ) -> std::collections::hash_map::Iter<'_, String, i32> { + pub fn uniforms_iter(&self) -> std::collections::hash_map::Iter<'_, String, i32> { self.uniforms.iter() } // :TODO: find better name, `use` is rust keyword :( - pub fn r#use( &mut self ) { + pub fn r#use(&mut self) { unsafe { - gl::UseProgram( self.program_id ); + gl::UseProgram(self.program_id); } } } diff --git a/src/renderer/text_layout.rs b/src/renderer/text_layout.rs index fa6faeb..de67ed0 100644 --- a/src/renderer/text_layout.rs +++ b/src/renderer/text_layout.rs @@ -1,33 +1,31 @@ - - -use crate::math::Vector2; use crate::math::Matrix32; -use crate::renderer::{ Color, Font }; +use crate::math::Vector2; use crate::renderer::debug_renderer; +use crate::renderer::{Color, Font}; #[derive(Debug)] pub struct TextLayoutQuad { - pub pos: Vector2, - pub size: Vector2, + pub pos: Vector2, + pub size: Vector2, pub tex_mtx: Matrix32, -// pub vertices: [Vector2;4], -// tex_coords: [Vector2;4], + // pub vertices: [Vector2;4], + // tex_coords: [Vector2;4], } #[derive(Debug)] pub struct TextLayout { - quads: Vec< TextLayoutQuad >, - size: Vector2, + quads: Vec, + size: Vector2, } impl TextLayout { pub fn new() -> Self { Self { quads: Vec::new(), - size: Vector2::zero(), + size: Vector2::zero(), } } - pub fn layout( &mut self, font: &Font, pos: &Vector2, text: &str ) { + pub fn layout(&mut self, font: &Font, pos: &Vector2, text: &str) { let initial_pos = pos; let mut pos = *pos; /* @@ -53,16 +51,16 @@ impl TextLayout { line_count += 1; continue; } - if let Some( g ) = font.find_glyph( c as u8 ) { -// println!("{} -> {:?}", c, g); - let s = Vector2::new( g.width as f32, g.height as f32 ); - let y_offset = g.y_offset as f32;// * 260.0*5.0; + if let Some(g) = font.find_glyph(c as u8) { + // println!("{} -> {:?}", c, g); + let s = Vector2::new(g.width as f32, g.height as f32); + let y_offset = g.y_offset as f32; // * 260.0*5.0; let q = TextLayoutQuad { - pos: Vector2::new( pos.x + 0.5*s.x, pos.y + 0.5*s.y - y_offset ), - size: s, + pos: Vector2::new(pos.x + 0.5 * s.x, pos.y + 0.5 * s.y - y_offset), + size: s, tex_mtx: g.matrix.into(), }; - self.quads.push( q ); + self.quads.push(q); pos.x += g.advance as f32; if self.size.x < pos.x { @@ -72,19 +70,18 @@ impl TextLayout { } if line_count > 1 { - let y_fix = ( line_count - 1 ) as f32 * font.size(); + let y_fix = (line_count - 1) as f32 * font.size(); for q in self.quads.iter_mut() { q.pos.y += y_fix; } } } - pub fn quads( &self ) -> &Vec< TextLayoutQuad > { + pub fn quads(&self) -> &Vec { &self.quads } - pub fn size( &self ) -> &Vector2 { + pub fn size(&self) -> &Vector2 { &self.size } - } diff --git a/src/renderer/texture.rs b/src/renderer/texture.rs index d3e86ee..f367871 100644 --- a/src/renderer/texture.rs +++ b/src/renderer/texture.rs @@ -1,111 +1,106 @@ +use derivative::Derivative; -use crate::math::Vector2; use crate::math::Matrix32; - -use crate::renderer::{ - Debug, - gl, -}; +use crate::math::Vector2; +use crate::renderer::{gl, Debug}; use crate::system::System; -use derivative::Derivative; - #[derive(Derivative)] #[derivative(Debug)] pub struct Texture { - name: String, - hwid: gl::types::GLuint, - width: u32, + name: String, + hwid: gl::types::GLuint, + width: u32, height: u32, - canvas: Option< Vec >, - mtx: Matrix32, + canvas: Option>, + mtx: Matrix32, } impl Texture { - pub fn create( system: &mut System, name: &str ) -> Self { - let mut t = Texture::new( name ); - if !t.load( system, name ) { - println!( "Warning: Failed loading texture {}", &name ); + pub fn create(system: &mut System, name: &str) -> Self { + let mut t = Texture::new(name); + if !t.load(system, name) { + println!("Warning: Failed loading texture {}", &name); } t } - pub fn create_canvas( name: &str, size: u32 ) -> Self { - let mut t = Texture::new( name ); - t.make_canvas( size ); + pub fn create_canvas(name: &str, size: u32) -> Self { + let mut t = Texture::new(name); + t.make_canvas(size); t.update_canvas(); t } - pub fn create_from_atlas( name: &str, mtx: &Matrix32, atlas: &Texture ) -> Self { + pub fn create_from_atlas(name: &str, mtx: &Matrix32, atlas: &Texture) -> Self { Self { - name: name.to_string(), - hwid: atlas.hwid() as u32, - width: 0, // :TODO: - height: 0, // :TODO: + name: name.to_string(), + hwid: atlas.hwid() as u32, + width: 0, // :TODO: + height: 0, // :TODO: canvas: None, - mtx: *mtx, + mtx: *mtx, } } - pub fn new( name: &str ) -> Self { + pub fn new(name: &str) -> Self { let mut hwid = 0xffff; unsafe { - gl::GenTextures( 1, &mut hwid ); - gl::BindTexture( gl::TEXTURE_2D, hwid ); + gl::GenTextures(1, &mut hwid); + gl::BindTexture(gl::TEXTURE_2D, hwid); gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST as i32); gl::TexParameteri(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST as i32); } Self { - name: name.to_string(), - hwid: hwid, - width: 0, + name: name.to_string(), + hwid: hwid, + width: 0, height: 0, canvas: None, - mtx: Matrix32::identity(), + mtx: Matrix32::identity(), } } - pub fn name( &self ) -> &str { + pub fn name(&self) -> &str { &self.name } - pub fn hwid( &self ) -> u16 { + pub fn hwid(&self) -> u16 { self.hwid as u16 } - pub fn mtx( &self ) -> &Matrix32 { + pub fn mtx(&self) -> &Matrix32 { &self.mtx } - pub fn bind( &self ) { + pub fn bind(&self) { // :TODO: support texture channels unsafe { - gl::ActiveTexture( gl::TEXTURE0 ); - gl::BindTexture( gl::TEXTURE_2D, self.hwid ); + gl::ActiveTexture(gl::TEXTURE0); + gl::BindTexture(gl::TEXTURE_2D, self.hwid); } } - pub fn clear( &mut self ) { - if let Some( c ) = &mut self.canvas { - c.fill( 0 ); - } + pub fn clear(&mut self) { + if let Some(c) = &mut self.canvas { + c.fill(0); + } } - pub fn set_texel( &mut self, pos: &Vector2, color: u32 ) { - if let Some( c ) = &mut self.canvas { - let p = ( self.width * pos.y as u32 + pos.x as u32 ) as usize; + pub fn set_texel(&mut self, pos: &Vector2, color: u32) { + if let Some(c) = &mut self.canvas { + let p = (self.width * pos.y as u32 + pos.x as u32) as usize; if p < c.len() { - c[ p ] = color; + c[p] = color; } - } + } } - pub fn update_canvas( &mut self ) { - if let Some( c ) = &self.canvas { + pub fn update_canvas(&mut self) { + if let Some(c) = &self.canvas { unsafe { - gl::BindTexture( gl::TEXTURE_2D, self.hwid ); + gl::BindTexture(gl::TEXTURE_2D, self.hwid); gl::TexImage2D( gl::TEXTURE_2D, 0, // mimap @@ -121,45 +116,45 @@ impl Texture { c.as_ptr() as *const _, ); - Debug::check_gl_error( std::file!(), std::line!() ); + Debug::check_gl_error(std::file!(), std::line!()); -// gl::GenerateMipmap( gl::TEXTURE_2D ); + // gl::GenerateMipmap( gl::TEXTURE_2D ); } } } - fn make_canvas( &mut self, size: u32 ) { + fn make_canvas(&mut self, size: u32) { self.width = size; self.height = size; - let buf_size = ( size*size ) as usize; - let mut c = Vec::with_capacity( buf_size ); + let buf_size = (size * size) as usize; + let mut c = Vec::with_capacity(buf_size); unsafe { - c.set_len( buf_size ); + c.set_len(buf_size); } - c.fill( 0x00000000 ); -// c[ 0 ] = 0xff0000ff; - self.canvas = Some( c ); + c.fill(0x00000000); + // c[ 0 ] = 0xff0000ff; + self.canvas = Some(c); } - fn load( &mut self, system: &mut System, name: &str ) -> bool { -// let extensions = [ ".jpg", ".png" ]; - let extensions = [ /*".jpg", */ ".png" ]; + fn load(&mut self, system: &mut System, name: &str) -> bool { + // let extensions = [ ".jpg", ".png" ]; + let extensions = [/*".jpg", */ ".png"]; for e in extensions.iter() { let filename = format!("{}{}", name, e); - let mut f = system.default_filesystem_mut().open( &filename ); + let mut f = system.default_filesystem_mut().open(&filename); if f.is_valid() { println!("Loading {} from {} ({}).", &name, &filename, &f.name()); let mut buf = Vec::new(); while !f.eof() { let c = f.read_u8(); - buf.push( c ); + buf.push(c); } let buf: &[u8] = buf.as_slice(); -// let dummy_buf = [ 0xffffffffu32, 0x0, 0xffffffff, 0x0 ]; + // let dummy_buf = [ 0xffffffffu32, 0x0, 0xffffffff, 0x0 ]; - match image::load_from_memory( buf ) { - Ok( i ) => { + match image::load_from_memory(buf) { + Ok(i) => { let i = i.to_rgba8(); let w = i.width(); let h = i.height(); @@ -168,7 +163,7 @@ impl Texture { self.height = h; unsafe { - gl::BindTexture( gl::TEXTURE_2D, self.hwid ); + gl::BindTexture(gl::TEXTURE_2D, self.hwid); gl::TexImage2D( gl::TEXTURE_2D, 0, // mimap @@ -183,31 +178,28 @@ impl Texture { i.into_raw().as_ptr() as *const _, ); - Debug::check_gl_error( std::file!(), std::line!() ); + Debug::check_gl_error(std::file!(), std::line!()); -// gl::GenerateMipmap( gl::TEXTURE_2D ); + // gl::GenerateMipmap( gl::TEXTURE_2D ); } return true; - }, - Err( e ) => { - println!("Error: '{}' loading image from {}", &e, &filename ); + Err(e) => { + println!("Error: '{}' loading image from {}", &e, &filename); }, } - } } false } - pub fn width( &self ) -> u32 { + pub fn width(&self) -> u32 { self.width } - pub fn height( &self ) -> u32 { + pub fn height(&self) -> u32 { self.height } - } diff --git a/src/renderer/texture_atlas.rs b/src/renderer/texture_atlas.rs index 731bba4..6a192a6 100644 --- a/src/renderer/texture_atlas.rs +++ b/src/renderer/texture_atlas.rs @@ -1,46 +1,41 @@ - use regex::Regex; use crate::math::Matrix32; - -use crate::renderer::{ - Renderer, - Texture, -}; -use crate::system::System; +use crate::renderer::{Renderer, Texture}; use crate::system::filesystem_stream::FilesystemStream; +use crate::system::System; #[derive(Debug)] pub struct Entry { name: String, - mtx: Matrix32, + mtx: Matrix32, } #[derive(Debug)] pub struct TextureAtlas { - entries: Vec< Entry >, + entries: Vec, } impl Entry { pub fn new() -> Self { Self { name: String::new(), - mtx: Matrix32::identity(), + mtx: Matrix32::identity(), } } - pub fn load( &mut self, f: &mut Box< dyn FilesystemStream > ) -> bool { - let mut name_buffer = Vec::with_capacity( 128 ); + pub fn load(&mut self, f: &mut Box) -> bool { + let mut name_buffer = Vec::with_capacity(128); for _ in 0..128 { let b = f.read_u8(); - name_buffer.push( b ); + name_buffer.push(b); } - let mut name = String::from_utf8( name_buffer ).unwrap(); - let first_zero = name.find( "\u{0}" ).unwrap_or( name.len() ); - name.truncate( first_zero ); + let mut name = String::from_utf8(name_buffer).unwrap(); + let first_zero = name.find("\u{0}").unwrap_or(name.len()); + name.truncate(first_zero); - let mut matrix_buffer = [0f32;6]; + let mut matrix_buffer = [0f32; 6]; for m in &mut matrix_buffer { *m = f.read_f32(); } @@ -51,73 +46,69 @@ impl Entry { } } // :TODO: move somewhere more sane -fn simple_format_u32( f: &str, n: u32 ) -> String { +fn simple_format_u32(f: &str, n: u32) -> String { let s = f.clone(); let re = Regex::new(r"(%d)").unwrap(); -// println!("simple_format_u32 {:?} with {:?}", s, re ); - let s = re.replace_all( - &s, - |c: ®ex::Captures| { - let placeholder = c.get(1).map_or( "", |m| m.as_str() ); -// println!("Found {:?}", placeholder ); - match placeholder { - "" => "".to_string(), - "%d" => n.to_string(), - x => { - println!("simple_format_u32 got {:?}", x); - x.to_string() - }, - } + // println!("simple_format_u32 {:?} with {:?}", s, re ); + let s = re.replace_all(&s, |c: ®ex::Captures| { + let placeholder = c.get(1).map_or("", |m| m.as_str()); + // println!("Found {:?}", placeholder ); + match placeholder { + "" => "".to_string(), + "%d" => n.to_string(), + x => { + println!("simple_format_u32 got {:?}", x); + x.to_string() + }, } - ); + }); s.to_string() } impl TextureAtlas { - pub fn load_all( system: &mut System, renderer: &mut Renderer, template: &str ) -> usize { + pub fn load_all(system: &mut System, renderer: &mut Renderer, template: &str) -> usize { let fs = system.default_filesystem_mut(); let mut to_load = Vec::new(); let mut i = 0; loop { - let name = simple_format_u32( template, i ); + let name = simple_format_u32(template, i); let name_atlas = format!("{}.atlas", &name); let name_png = format!("{}.png", &name); - if fs.exists( &name_atlas ) && fs.exists( &name_png ){ - to_load.push( name.to_owned() ); + if fs.exists(&name_atlas) && fs.exists(&name_png) { + to_load.push(name.to_owned()); } else { break; } i += 1; } -// dbg!(&to_load); - + // dbg!(&to_load); let mut total_textures_registered = 0; for name in to_load.iter() { let name_atlas = format!("{}.atlas", &name); - let t = Texture::create( system, &name ); + let t = Texture::create(system, &name); let mut ta = TextureAtlas::new(); - ta.load( system, &name_atlas ); + ta.load(system, &name_atlas); for e in ta.entries.iter() { let mut name_wo_ext = e.name.clone(); // :TODO: last dot might be better ;) - let first_dot = name_wo_ext.find( "." ).unwrap_or( name_wo_ext.len() ); - name_wo_ext.truncate( first_dot ); + let first_dot = name_wo_ext.find(".").unwrap_or(name_wo_ext.len()); + name_wo_ext.truncate(first_dot); - let te = Texture::create_from_atlas( &name_wo_ext, &e.mtx, &t ); -// println!("Registering atlas (sub) texture '{}' with renderer {:?}", &name_wo_ext, &te); - renderer.register_texture( te ); + let te = Texture::create_from_atlas(&name_wo_ext, &e.mtx, &t); + // println!("Registering atlas (sub) texture '{}' with renderer {:?}", &name_wo_ext, &te); + renderer.register_texture(te); total_textures_registered += 1; } - renderer.register_texture( t ); + renderer.register_texture(t); } total_textures_registered } @@ -127,25 +118,25 @@ impl TextureAtlas { entries: Vec::new(), } } - pub fn load( &mut self, system: &mut System, name: &str ) -> bool { - let mut f = system.default_filesystem_mut().open( &name ); + pub fn load(&mut self, system: &mut System, name: &str) -> bool { + let mut f = system.default_filesystem_mut().open(&name); if !f.is_valid() { return false; } - println!("Loading atlas from {}", &name ); + println!("Loading atlas from {}", &name); let magic = f.read_u16(); if magic != 0x4f53 { println!("Got broken magic expected 0x4f53 got {:X}", magic); - return false + return false; } let v = f.read_u16(); if v != 1 { println!("Version {} not supported", v); return false; } - let chunk_magic = [ 0x4fu8, 0x4d, 0x41, 0x54, 0x4c, 0x41, 0x53, ]; + let chunk_magic = [0x4fu8, 0x4d, 0x41, 0x54, 0x4c, 0x41, 0x53]; for m in &chunk_magic { let b = f.read_u8(); if b != *m { @@ -160,33 +151,31 @@ impl TextureAtlas { return false; } - let chunk_version = [ 0x01u8, 0x00, 0x00, 0x00 ]; + let chunk_version = [0x01u8, 0x00, 0x00, 0x00]; for m in &chunk_version { let b = f.read_u8(); if b != *m { println!("Broken chunk version"); return false; } - } + } let entry_count = f.read_u16(); - println!("Got {:?} entries", entry_count ); + println!("Got {:?} entries", entry_count); for i in 0..entry_count { let mut e = Entry::new(); - if !e.load( &mut f ) { + if !e.load(&mut f) { println!("Load of entry {}/{} failed.", i, entry_count); return false; } - self.entries.push( e ); + self.entries.push(e); } -// dbg!(&self); + // dbg!(&self); true - } - } diff --git a/src/renderer/uniform.rs b/src/renderer/uniform.rs index 62dcdb3..a325403 100644 --- a/src/renderer/uniform.rs +++ b/src/renderer/uniform.rs @@ -1,6 +1,4 @@ - - -#[derive(Debug,Copy,Clone)] +#[derive(Debug, Copy, Clone)] pub enum Uniform { - F32( f32 ), + F32(f32), } diff --git a/src/system.rs b/src/system.rs index 37a4b17..3b11f13 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,4 +1,3 @@ - use std::fs; use std::path::Path; @@ -8,70 +7,69 @@ use crate::system::filesystem_empty::FilesystemEmpty; #[derive(Debug)] pub struct System { - default_filesystem: Box, - savegame_filesystem: Box< dyn Filesystem>, + default_filesystem: Box, + savegame_filesystem: Box, } impl System { pub fn new() -> Self { Self { - default_filesystem: Box::new( FilesystemEmpty::new() ), - savegame_filesystem: Box::new( FilesystemEmpty::new() ), + default_filesystem: Box::new(FilesystemEmpty::new()), + savegame_filesystem: Box::new(FilesystemEmpty::new()), } } - pub fn set_default_filesystem(&mut self, fs: Box< dyn Filesystem > ) { + pub fn set_default_filesystem(&mut self, fs: Box) { self.default_filesystem = fs; } - pub fn default_filesystem_mut( &mut self ) -> &mut Box< dyn Filesystem > { + pub fn default_filesystem_mut(&mut self) -> &mut Box { &mut self.default_filesystem } - pub fn default_filesystem( &self ) -> & Box< dyn Filesystem > { + pub fn default_filesystem(&self) -> &Box { &self.default_filesystem } - pub fn set_savegame_filesystem(&mut self, fs: Box< dyn Filesystem > ) { + pub fn set_savegame_filesystem(&mut self, fs: Box) { self.savegame_filesystem = fs; } - pub fn savegame_filesystem_mut( &mut self ) -> &mut Box< dyn Filesystem > { + pub fn savegame_filesystem_mut(&mut self) -> &mut Box { &mut self.savegame_filesystem } - pub fn get_document_dir( name: &str ) -> String { + pub fn get_document_dir(name: &str) -> String { let doc_dir = dirs_next::document_dir().unwrap(); let doc_dir = doc_dir.to_string_lossy(); - let dir = format!("{}/{}", doc_dir, name ); + let dir = format!("{}/{}", doc_dir, name); - fs::create_dir_all( &dir ).unwrap(); + fs::create_dir_all(&dir).unwrap(); dir } - pub fn get_resource_path( name: &str ) -> Option { + pub fn get_resource_path(name: &str) -> Option { let exe_dir = std::env::current_exe().unwrap(); - let exe_path = Path::new( &exe_dir ).parent().unwrap(); - + let exe_path = Path::new(&exe_dir).parent().unwrap(); -// dbg!(&exe_path); + // dbg!(&exe_path); - let p = exe_path.join( "../Resources" ).join( &name ); -// dbg!(&p); + let p = exe_path.join("../Resources").join(&name); + // dbg!(&p); if p.exists() { - return Some( p.to_string_lossy().to_string() ); + return Some(p.to_string_lossy().to_string()); } - let p = exe_path.join( &name ); -// dbg!(&p); + let p = exe_path.join(&name); + // dbg!(&p); if p.exists() { - return Some( p.to_string_lossy().to_string() ); + return Some(p.to_string_lossy().to_string()); } - let p = exe_path.join( "../.." ).join( &name ); -// dbg!(&p); + let p = exe_path.join("../..").join(&name); + // dbg!(&p); if p.exists() { - return Some( p.to_string_lossy().to_string() ); + return Some(p.to_string_lossy().to_string()); } None } @@ -95,4 +93,4 @@ pub mod filesystem_stream_memory; pub mod filesystem_layered; mod serializer; - pub use serializer::Serializer; +pub use serializer::Serializer; diff --git a/src/system/filesystem.rs b/src/system/filesystem.rs index bafc84c..40dcaaf 100644 --- a/src/system/filesystem.rs +++ b/src/system/filesystem.rs @@ -1,34 +1,36 @@ - use crate::system::filesystem_stream::FilesystemStream; - use crate::system::filesystem_stream_empty::FilesystemStreamEmpty; pub trait Filesystem { + fn open(&mut self, name: &str) -> Box; + fn create(&mut self, name: &str, overwrite: bool) -> Box { + let stream = FilesystemStreamEmpty::open(name); - fn open( &mut self, name: &str ) -> Box< dyn FilesystemStream >; - fn create( &mut self, name: &str, overwrite: bool ) -> Box< dyn FilesystemStream > { - let stream = FilesystemStreamEmpty::open( name ); - - Box::new( stream ) + Box::new(stream) } - fn exists( &self, _name: &str ) -> bool { + fn exists(&self, _name: &str) -> bool { false } - fn writable( &self ) -> bool { + fn writable(&self) -> bool { false } - fn name( &self ) -> &str; - fn filesystem_type( &self ) -> &str; + fn name(&self) -> &str; + fn filesystem_type(&self) -> &str; - fn format( &self, f: &mut std::fmt::Formatter ) -> std::fmt::Result { - writeln!( f,"[Trait] Filesystem: {} [{}]", self.name(), self.filesystem_type() ) + fn format(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + writeln!( + f, + "[Trait] Filesystem: {} [{}]", + self.name(), + self.filesystem_type() + ) } } impl std::fmt::Debug for dyn Filesystem { - fn fmt( &self, f: &mut std::fmt::Formatter ) -> std::fmt::Result { - self.format( f ) + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.format(f) } } diff --git a/src/system/filesystem_archive.rs b/src/system/filesystem_archive.rs index 4500a25..88970c2 100644 --- a/src/system/filesystem_archive.rs +++ b/src/system/filesystem_archive.rs @@ -1,31 +1,30 @@ - //use std::fs::File; -use std::rc::Rc; //use std::io::prelude::*; use std::collections::HashMap; +use std::rc::Rc; use crate::system::filesystem::Filesystem; use crate::system::filesystem_stream::FilesystemStream; use crate::system::filesystem_stream_archive::FilesystemStreamArchive; pub struct Entry { - pub crc: u32, - pub pos: u32, + pub crc: u32, + pub pos: u32, pub size: u32, - pub data: Vec< u8 >, + pub data: Vec, } impl Entry { pub fn new() -> Self { Self { - crc: 0, - pos: 0, + crc: 0, + pos: 0, size: 0, data: Vec::new(), } } - pub fn initialize_from_file( &mut self, file: &mut Box< dyn FilesystemStream > ) -> bool { + pub fn initialize_from_file(&mut self, file: &mut Box) -> bool { self.crc = file.read_u32(); self.pos = file.read_u32(); self.size = file.read_u32(); @@ -33,164 +32,179 @@ impl Entry { true } - pub fn load_from_file( &mut self, file: &mut Box< dyn FilesystemStream > ) -> bool { + pub fn load_from_file(&mut self, file: &mut Box) -> bool { for _n in 0..self.size { let b = file.read_u8(); - self.data.push( b ); + self.data.push(b); } true } - } pub struct FilesystemArchive { - name: String, + name: String, entries: HashMap, - data: Rc< Vec< u8 > >, + data: Rc>, } impl FilesystemArchive { // :TODO: optimize out extra copying of data - pub fn new_from_file( name: &str, file: &mut Box< dyn FilesystemStream > ) -> Self { + pub fn new_from_file(name: &str, file: &mut Box) -> Self { let mut s = Self { - name: name.to_owned(), + name: name.to_owned(), entries: HashMap::new(), - data: Rc::new( Vec::new() ), + data: Rc::new(Vec::new()), }; - s.initialize_from_file( file ); + s.initialize_from_file(file); s } - fn initialize_from_file( &mut self, file: &mut Box< dyn FilesystemStream > ) -> bool { - let magic = [ 0x4fu8, 0x4d, 0x41, 0x52 ]; + fn initialize_from_file(&mut self, file: &mut Box) -> bool { + let magic = [0x4fu8, 0x4d, 0x41, 0x52]; for m in &magic { let b = file.read_u8(); if b != *m { - println!("Warning: Broken magic for .omar. Got {:X} expected {:X}.", b, m); + println!( + "Warning: Broken magic for .omar. Got {:X} expected {:X}.", + b, m + ); return false; } } let v = file.read_u8(); if v != 2 { - println!("Warning:Wrong version" ); + println!("Warning:Wrong version"); return false; } let flags = file.read_u8(); if flags != 0 { - println!("Warning: :TODO: Flags not implemented" ); + println!("Warning: :TODO: Flags not implemented"); return false; } for _reserved in 0..2 { let r = file.read_u8(); if r != 0 { - println!("Warning: :TODO: Reserved field not zero" ); + println!("Warning: :TODO: Reserved field not zero"); return false; } } let number_of_files = file.read_u32(); - println!("Reading {:?} files from archive {}", number_of_files, &self.name ); + println!( + "Reading {:?} files from archive {}", + number_of_files, &self.name + ); for _e in 0..number_of_files { let mut entry = Entry::new(); - if !entry.initialize_from_file( file ) { + if !entry.initialize_from_file(file) { println!("Warning: Failed to read entry from file"); return false; } - self.entries.insert( entry.crc, entry ); + self.entries.insert(entry.crc, entry); } -// let l = self.entries.len(); + // let l = self.entries.len(); let data_start = file.pos(); - for ( _i, entry ) in self.entries.values_mut().enumerate() { -// println!("{}/{}", i, l); + for (_i, entry) in self.entries.values_mut().enumerate() { + // println!("{}/{}", i, l); // adjust file position let entry_start = data_start + entry.pos as usize; - file.set_pos( entry_start ); - (*entry).load_from_file( file ); + file.set_pos(entry_start); + (*entry).load_from_file(file); } true } - fn calc_crc_for_name( name: &str ) -> u32 { + fn calc_crc_for_name(name: &str) -> u32 { // :DANGER: this if for ruby converter compatibility // :TODO: calculate actual CRC name let downcase_name = name.to_lowercase(); // Ruby: .gsub( /\W\./, ' ' ) // should be 'a-zA-Z0-9_', but actual code behaves differently - let clean_name: String = downcase_name.chars().map(|c| match c { - '0'..='9' => c, - 'a'..='z' => c, - // 'A'..='Z' => c, // already downcase - '!'..='@' => c, - '['..='`' => c, - '{'..='~' => c, - // 0x7f => c, // ignore DEL - _ => ' ' - }).collect(); + let clean_name: String = downcase_name + .chars() + .map(|c| match c { + '0'..='9' => c, + 'a'..='z' => c, + // 'A'..='Z' => c, // already downcase + '!'..='@' => c, + '['..='`' => c, + '{'..='~' => c, + // 0x7f => c, // ignore DEL + _ => ' ', + }) + .collect(); const CRC32: crc::Crc = crc::Crc::::new(&crc::CRC_32_ISO_HDLC); - let crc = CRC32.checksum( clean_name.as_bytes() ); + let crc = CRC32.checksum(clean_name.as_bytes()); -// println!("CRC: {:?} -> {:?} crc: {:?} {:#10X}\n", name, clean_name, crc, crc ); -// panic!("CRC"); + // println!("CRC: {:?} -> {:?} crc: {:?} {:#10X}\n", name, clean_name, crc, crc ); + // panic!("CRC"); crc } } impl Filesystem for FilesystemArchive { - fn open( &mut self, name: &str ) -> Box< dyn FilesystemStream > { - let crc = FilesystemArchive::calc_crc_for_name( name ); - match self.entries.get( &crc ) { + fn open(&mut self, name: &str) -> Box { + let crc = FilesystemArchive::calc_crc_for_name(name); + match self.entries.get(&crc) { None => { - let mut stream = FilesystemStreamArchive::open( crc, &Vec::new() ); + let mut stream = FilesystemStreamArchive::open(crc, &Vec::new()); stream.mark_invalid(); - Box::new( stream ) + Box::new(stream) }, - Some( entry ) => { - let stream = FilesystemStreamArchive::open( entry.crc, &entry.data ); - Box::new( stream ) + Some(entry) => { + let stream = FilesystemStreamArchive::open(entry.crc, &entry.data); + Box::new(stream) }, } } - fn exists( &self, name: &str ) -> bool { - let crc = FilesystemArchive::calc_crc_for_name( name ); - if self.entries.contains_key( &crc ) { + fn exists(&self, name: &str) -> bool { + let crc = FilesystemArchive::calc_crc_for_name(name); + if self.entries.contains_key(&crc) { true } else { -// dbg!(crc, &self.entries.contains_key( &crc )); -// dbg!(&self.entries); + // dbg!(crc, &self.entries.contains_key( &crc )); + // dbg!(&self.entries); false } } - fn name( &self ) -> &str { + fn name(&self) -> &str { &self.name } - - fn filesystem_type( &self ) -> &str { + + fn filesystem_type(&self) -> &str { "Archive" } } impl std::fmt::Debug for Entry { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { - write!( f, "0x{:08X} {} {} {}", self.crc, self.pos, self.size, self.data.len() ) + write!( + f, + "0x{:08X} {} {} {}", + self.crc, + self.pos, + self.size, + self.data.len() + ) } } impl std::fmt::Debug for FilesystemArchive { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { - writeln!( f, "FilesystemArchive:\n\tsize: {}", self.data.len() ).unwrap(); + writeln!(f, "FilesystemArchive:\n\tsize: {}", self.data.len()).unwrap(); - for ( k, e ) in self.entries.iter() { - writeln!( f, "\t0x{:08X}\t{:?}", k, &e ).unwrap(); + for (k, e) in self.entries.iter() { + writeln!(f, "\t0x{:08X}\t{:?}", k, &e).unwrap(); } writeln!(f, "") diff --git a/src/system/filesystem_disk.rs b/src/system/filesystem_disk.rs index c0861b5..52ccc7a 100644 --- a/src/system/filesystem_disk.rs +++ b/src/system/filesystem_disk.rs @@ -1,66 +1,70 @@ - use crate::system::filesystem::Filesystem; use crate::system::filesystem_stream::FilesystemStream; use crate::system::filesystem_stream_disk::FilesystemStreamDisk; pub struct FilesystemDisk { - basedir: String, + basedir: String, writable: bool, } impl FilesystemDisk { - pub fn new( basedir: &str ) -> Self { + pub fn new(basedir: &str) -> Self { Self { - basedir: basedir.to_string(), + basedir: basedir.to_string(), writable: false, } } - pub fn enable_write( &mut self ) { + pub fn enable_write(&mut self) { self.writable = true; } } impl Filesystem for FilesystemDisk { - fn open( &mut self, name: &str ) -> Box< dyn FilesystemStream > { + fn open(&mut self, name: &str) -> Box { let fullname = format!("{}/{}", &self.basedir, &name); -// println!("fullname: {}", &fullname); - let stream = FilesystemStreamDisk::open( &fullname ); + // println!("fullname: {}", &fullname); + let stream = FilesystemStreamDisk::open(&fullname); - Box::new( stream ) + Box::new(stream) } - fn create( &mut self, name: &str, overwrite: bool ) -> Box< dyn FilesystemStream > { + fn create(&mut self, name: &str, overwrite: bool) -> Box { let fullname = format!("{}/{}", &self.basedir, &name); - let stream = FilesystemStreamDisk::create( &fullname, overwrite ); + let stream = FilesystemStreamDisk::create(&fullname, overwrite); - Box::new( stream ) + Box::new(stream) } - fn exists( &self, name: &str ) -> bool { + fn exists(&self, name: &str) -> bool { let fullname = format!("{}/{}", &self.basedir, &name); std::path::Path::new(&fullname).exists() } - fn writable( &self ) -> bool { + fn writable(&self) -> bool { self.writable } - fn name( &self ) -> &str { + fn name(&self) -> &str { "" } - - fn filesystem_type( &self ) -> &str { + + fn filesystem_type(&self) -> &str { "Disk" } - fn format( &self, f: &mut std::fmt::Formatter ) -> std::fmt::Result { - writeln!( f,"Filesystem: {} [{}] -> {}", self.name(), self.filesystem_type(), &self.basedir ) - } + fn format(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + writeln!( + f, + "Filesystem: {} [{}] -> {}", + self.name(), + self.filesystem_type(), + &self.basedir + ) + } } impl std::fmt::Debug for FilesystemDisk { - fn fmt( &self, f: &mut std::fmt::Formatter ) -> std::fmt::Result { - self.format( f ) + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + self.format(f) } } - diff --git a/src/system/filesystem_empty.rs b/src/system/filesystem_empty.rs index b76ad64..a0c37fc 100644 --- a/src/system/filesystem_empty.rs +++ b/src/system/filesystem_empty.rs @@ -1,32 +1,27 @@ - use crate::system::filesystem::Filesystem; use crate::system::filesystem_stream::FilesystemStream; use crate::system::filesystem_stream_empty::FilesystemStreamEmpty; -pub struct FilesystemEmpty { - -} +pub struct FilesystemEmpty {} impl FilesystemEmpty { pub fn new() -> Self { - Self { - - } + Self {} } } impl Filesystem for FilesystemEmpty { - fn open( &mut self, name: &str ) -> Box< dyn FilesystemStream > { - let stream = FilesystemStreamEmpty::open( name ); + fn open(&mut self, name: &str) -> Box { + let stream = FilesystemStreamEmpty::open(name); - Box::new( stream ) + Box::new(stream) } - fn name( &self ) -> &str { + fn name(&self) -> &str { "" } - - fn filesystem_type( &self ) -> &str { + + fn filesystem_type(&self) -> &str { "Empty" } } diff --git a/src/system/filesystem_layered.rs b/src/system/filesystem_layered.rs index 0e63a32..cb83289 100644 --- a/src/system/filesystem_layered.rs +++ b/src/system/filesystem_layered.rs @@ -1,75 +1,73 @@ - use crate::system::filesystem::Filesystem; - use crate::system::filesystem_stream::FilesystemStream; #[derive(Debug)] pub struct FilesystemLayered { - filesystems: Vec< Box< dyn Filesystem > >, + filesystems: Vec>, } impl FilesystemLayered { - pub fn new( ) -> Self { + pub fn new() -> Self { Self { filesystems: Vec::new(), } } - pub fn add_filesystem( &mut self, filesystem: Box< dyn Filesystem > ) { - self.filesystems.push( filesystem ); + pub fn add_filesystem(&mut self, filesystem: Box) { + self.filesystems.push(filesystem); } } impl Filesystem for FilesystemLayered { - fn open( &mut self, name: &str ) -> Box< dyn FilesystemStream > { + fn open(&mut self, name: &str) -> Box { for fs in self.filesystems.iter_mut().rev() { - if fs.exists( name ) { -// println!("{} exists in {:?}", &name, &fs); - return fs.open( name ); + if fs.exists(name) { + // println!("{} exists in {:?}", &name, &fs); + return fs.open(name); } } - if let Some( fs ) = self.filesystems.get_mut( 0 ) { -// todo!("File not found: {}", name ); - fs.open( name ) + if let Some(fs) = self.filesystems.get_mut(0) { + // todo!("File not found: {}", name ); + fs.open(name) } else { - panic!( "Error: FilesystemLayered tried to open a file without any filesystem" ); + panic!("Error: FilesystemLayered tried to open a file without any filesystem"); } } - fn create( &mut self, name: &str, overwrite: bool ) -> Box< dyn FilesystemStream > { + fn create(&mut self, name: &str, overwrite: bool) -> Box { for fs in self.filesystems.iter_mut().rev() { - if fs.writable( ) { - let mut fss = fs.create( name, overwrite ); + if fs.writable() { + let mut fss = fs.create(name, overwrite); if fss.is_valid() { return fss; } } } - if let Some( fs ) = self.filesystems.get_mut( 0 ) { -// todo!("File not found: {}", name ); - fs.create( name, overwrite ) + if let Some(fs) = self.filesystems.get_mut(0) { + // todo!("File not found: {}", name ); + fs.create(name, overwrite) } else { - panic!( "Error: FilesystemLayered tried to create a file without any filesystem" ); + panic!("Error: FilesystemLayered tried to create a file without any filesystem"); } } - fn exists( &self, name: &str ) -> bool { + fn exists(&self, name: &str) -> bool { for fs in self.filesystems.iter().rev() { - if fs.exists( name ) { + if fs.exists(name) { return true; } } -// dbg!(&self, &name); + // dbg!(&self, &name); false } - fn name( &self ) -> &str { + fn name(&self) -> &str { "" } - - fn filesystem_type( &self ) -> &str { + + fn filesystem_type(&self) -> &str { "Layered" } } diff --git a/src/system/filesystem_memory.rs b/src/system/filesystem_memory.rs index e79fcd9..ec4021f 100644 --- a/src/system/filesystem_memory.rs +++ b/src/system/filesystem_memory.rs @@ -1,37 +1,32 @@ - use crate::system::filesystem::Filesystem; use crate::system::filesystem_stream::FilesystemStream; use crate::system::filesystem_stream_memory::FilesystemStreamMemory; -pub struct FilesystemMemory { - -} +pub struct FilesystemMemory {} impl FilesystemMemory { pub fn new() -> Self { - Self { - - } + Self {} } - pub fn open_from_data( &mut self, name: &str, data: &Vec< u8 > ) -> Box< dyn FilesystemStream > { - let stream = FilesystemStreamMemory::open( name, data ); + pub fn open_from_data(&mut self, name: &str, data: &Vec) -> Box { + let stream = FilesystemStreamMemory::open(name, data); - Box::new( stream ) + Box::new(stream) } } impl Filesystem for FilesystemMemory { - fn open( &mut self, name: &str ) -> Box< dyn FilesystemStream > { - let stream = FilesystemStreamMemory::open( name, &Vec::new() ); + fn open(&mut self, name: &str) -> Box { + let stream = FilesystemStreamMemory::open(name, &Vec::new()); - Box::new( stream ) + Box::new(stream) } - fn name( &self ) -> &str { + fn name(&self) -> &str { "" } - - fn filesystem_type( &self ) -> &str { + + fn filesystem_type(&self) -> &str { "Memory" } } diff --git a/src/system/filesystem_stream.rs b/src/system/filesystem_stream.rs index b21e345..5242527 100644 --- a/src/system/filesystem_stream.rs +++ b/src/system/filesystem_stream.rs @@ -1,30 +1,29 @@ - -#[derive(Debug,Copy,Clone,Eq,PartialEq)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum FilesystemStreamMode { Read, - Write + Write, } pub trait FilesystemStream { - fn size( &self, ) -> usize; - fn pos( &self, ) -> usize; - fn set_pos( &mut self, pos: usize ); - fn read_u8( &mut self ) -> u8; - fn write_u8( &mut self, data: u8 ){} - fn is_valid( &self ) -> bool; - fn eof( &self ) -> bool; - fn name( &self ) -> &str; - fn filesystem_stream_type( &self ) -> &str; + fn size(&self) -> usize; + fn pos(&self) -> usize; + fn set_pos(&mut self, pos: usize); + fn read_u8(&mut self) -> u8; + fn write_u8(&mut self, data: u8) {} + fn is_valid(&self) -> bool; + fn eof(&self) -> bool; + fn name(&self) -> &str; + fn filesystem_stream_type(&self) -> &str; - fn mode( &self ) -> FilesystemStreamMode { + fn mode(&self) -> FilesystemStreamMode { FilesystemStreamMode::Read } - fn read_as_string( &mut self ) -> String { + fn read_as_string(&mut self) -> String { let mut s = String::new(); while !self.eof() { let c = self.read_u8() as char; - s.push( c ); + s.push(c); } s } @@ -33,44 +32,39 @@ pub trait FilesystemStream { let mut s = String::new(); for _n in 0..size { let c = self.read_u8() as char; - s.push( c ); + s.push(c); } s } - fn read_u16( &mut self ) -> u16 { + fn read_u16(&mut self) -> u16 { let a = self.read_u8() as u16; let b = self.read_u8() as u16; - ( b << 8 ) - | ( a << 0 ) + (b << 8) | (a << 0) } - fn read_u32( &mut self ) -> u32 { + fn read_u32(&mut self) -> u32 { let a = self.read_u8() as u32; let b = self.read_u8() as u32; let c = self.read_u8() as u32; let d = self.read_u8() as u32; - ( d << 24 ) - | ( c << 16 ) - | ( b << 8 ) - | ( a << 0 ) + (d << 24) | (c << 16) | (b << 8) | (a << 0) } - fn read_f32( &mut self ) -> f32 { + fn read_f32(&mut self) -> f32 { let f = self.read_u32(); - unsafe { std::mem::transmute( f ) } + unsafe { std::mem::transmute(f) } } - } - impl std::fmt::Debug for dyn FilesystemStream { - fn fmt( &self, f: &mut std::fmt::Formatter ) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { writeln!( - f, "[Trait] FilesystemStream: {} [{}] {}", + f, + "[Trait] FilesystemStream: {} [{}] {}", self.name(), self.filesystem_stream_type(), if self.is_valid() { diff --git a/src/system/filesystem_stream_archive.rs b/src/system/filesystem_stream_archive.rs index e9532d4..586eefa 100644 --- a/src/system/filesystem_stream_archive.rs +++ b/src/system/filesystem_stream_archive.rs @@ -1,65 +1,62 @@ - - use crate::system::filesystem_stream::FilesystemStream; #[derive(Debug)] pub struct FilesystemStreamArchive { - crc: u32, - name: String, - data: Vec< u8 >, - pos: usize, + crc: u32, + name: String, + data: Vec, + pos: usize, valid: bool, } impl FilesystemStreamArchive { - pub fn open( crc: u32, data: &Vec< u8 > ) -> Self { + pub fn open(crc: u32, data: &Vec) -> Self { Self { - crc: crc, - name: format!( "0x{:08X}", crc ), - data: data.clone(), // :TODO: optimize out copy - pos: 0, + crc: crc, + name: format!("0x{:08X}", crc), + data: data.clone(), // :TODO: optimize out copy + pos: 0, valid: true, } } - pub fn mark_invalid( &mut self ) { + pub fn mark_invalid(&mut self) { self.valid = false; } } impl FilesystemStream for FilesystemStreamArchive { - fn size( &self ) -> usize { + fn size(&self) -> usize { self.data.len() } - fn pos( &self ) -> usize { + fn pos(&self) -> usize { self.pos } - fn set_pos( &mut self, pos: usize ) { + fn set_pos(&mut self, pos: usize) { self.pos = pos; } - fn read_u8( &mut self ) -> u8 { - match self.data.get( self.pos ) { + fn read_u8(&mut self) -> u8 { + match self.data.get(self.pos) { None => { - println!( "Warning: Failed to get u8 for {}", &self.name ); + println!("Warning: Failed to get u8 for {}", &self.name); 0 }, - Some( b ) => { + Some(b) => { self.pos += 1; *b }, } } - fn is_valid( &self ) -> bool { + fn is_valid(&self) -> bool { self.valid } - fn eof( &self ) -> bool { + fn eof(&self) -> bool { self.pos >= self.data.len() } - fn name( &self ) -> &str { + fn name(&self) -> &str { &self.name } - fn filesystem_stream_type( &self ) -> &str { + fn filesystem_stream_type(&self) -> &str { "Archive" } - } diff --git a/src/system/filesystem_stream_disk.rs b/src/system/filesystem_stream_disk.rs index 350117c..6062ed2 100644 --- a/src/system/filesystem_stream_disk.rs +++ b/src/system/filesystem_stream_disk.rs @@ -1,74 +1,72 @@ - -use std::fs::{ File, OpenOptions }; -use std::io::{BufReader,SeekFrom}; +use std::fs::{File, OpenOptions}; use std::io::prelude::*; +use std::io::{BufReader, SeekFrom}; -use crate::system::filesystem_stream::{ FilesystemStream, FilesystemStreamMode }; +use crate::system::filesystem_stream::{FilesystemStream, FilesystemStreamMode}; pub struct FilesystemStreamDisk { - filename: String, // only needed for better debugging - file: Option< BufReader< File > >, - file_write: Option< File >, -// file: Option< File >, - size: usize, - pos: usize, - mode: FilesystemStreamMode, + filename: String, // only needed for better debugging + file: Option>, + file_write: Option, + // file: Option< File >, + size: usize, + pos: usize, + mode: FilesystemStreamMode, } impl FilesystemStreamDisk { - pub fn open( filename: &str ) -> Self { + pub fn open(filename: &str) -> Self { let mut s = Self { - filename: filename.to_string(), - file: None, + filename: filename.to_string(), + file: None, file_write: None, - size: 0, - pos: 0, - mode: FilesystemStreamMode::Read, + size: 0, + pos: 0, + mode: FilesystemStreamMode::Read, }; - if let Ok( mut f ) = File::open( &s.filename ) { - if let Ok( p ) = f.seek(SeekFrom::End(0)) { - f.seek( SeekFrom::Start( 0 ) ).unwrap(); + if let Ok(mut f) = File::open(&s.filename) { + if let Ok(p) = f.seek(SeekFrom::End(0)) { + f.seek(SeekFrom::Start(0)).unwrap(); s.size = p as usize } else { } let f = BufReader::new(f); - s.file = Some( f ); + s.file = Some(f); }; - s } - pub fn create( filename: &str, overwrite: bool ) -> Self { + pub fn create(filename: &str, overwrite: bool) -> Self { let mut s = Self { - filename: filename.to_string(), - file: None, + filename: filename.to_string(), + file: None, file_write: None, - size: 0, - pos: 0, - mode: FilesystemStreamMode::Write, + size: 0, + pos: 0, + mode: FilesystemStreamMode::Write, }; let file = OpenOptions::new() - .write( true ) - .truncate( true ) - .create( overwrite ) - .create_new( !overwrite ) - .open( &s.filename ); -// dbg!(&file); + .write(true) + .truncate(true) + .create(overwrite) + .create_new(!overwrite) + .open(&s.filename); + // dbg!(&file); match file { - Ok( mut f ) => { + Ok(mut f) => { s.size = 0; /* let f = BufReader::new(f); */ - s.file_write = Some( f ); + s.file_write = Some(f); + }, + Err(e) => { + println!("Error creating >{}< -> {:?}", &filename, &e); }, - Err( e ) => { - println!("Error creating >{}< -> {:?}", &filename, &e ); - } } s @@ -76,94 +74,81 @@ impl FilesystemStreamDisk { } impl Drop for FilesystemStreamDisk { - fn drop(&mut self) { - if let Some( f ) = &mut self.file_write { - f.sync_all().unwrap(); - self.file_write = None; - } - } + fn drop(&mut self) { + if let Some(f) = &mut self.file_write { + f.sync_all().unwrap(); + self.file_write = None; + } + } } impl FilesystemStream for FilesystemStreamDisk { - fn size( &self ) -> usize { + fn size(&self) -> usize { self.size } - fn pos( &self ) -> usize { + fn pos(&self) -> usize { self.pos } - fn set_pos( &mut self, pos: usize ) { + fn set_pos(&mut self, pos: usize) { match &mut self.file { - Some( f ) => { - f.seek( SeekFrom::Start( pos as u64 ) ).unwrap(); - if let Ok( p ) = f.stream_position() { + Some(f) => { + f.seek(SeekFrom::Start(pos as u64)).unwrap(); + if let Ok(p) = f.stream_position() { self.pos = p as usize; } else { - } }, None => {}, } } - fn mode( &self ) -> FilesystemStreamMode { + fn mode(&self) -> FilesystemStreamMode { self.mode } - fn read_u8( &mut self ) -> u8 { - + fn read_u8(&mut self) -> u8 { match &mut self.file { - Some( f ) => { + Some(f) => { let mut buf = [0]; - match f.read( &mut buf ) { - Ok( _ ) => { + match f.read(&mut buf) { + Ok(_) => { self.pos += 1; - buf[ 0 ] + buf[0] }, - Err( _ ) => 0, + Err(_) => 0, } - - }, - None => { - 0 }, + None => 0, } - } - fn write_u8( &mut self, data: u8 ) { + fn write_u8(&mut self, data: u8) { match &mut self.file_write { - Some( f ) => { - let mut buf = [ data ]; - match f.write( &mut buf ) { - Ok( _ ) => { + Some(f) => { + let mut buf = [data]; + match f.write(&mut buf) { + Ok(_) => { self.pos += 1; }, - Err( _ ) => {}, + Err(_) => {}, } - - }, - None => { }, + None => {}, } } - fn is_valid( &self ) -> bool { + fn is_valid(&self) -> bool { match self.mode { - FilesystemStreamMode::Read => { - self.file.is_some() - }, - FilesystemStreamMode::Write => { - self.file_write.is_some() - }, + FilesystemStreamMode::Read => self.file.is_some(), + FilesystemStreamMode::Write => self.file_write.is_some(), } } - fn eof( &self ) -> bool { + fn eof(&self) -> bool { self.pos >= self.size } - fn name( &self ) -> &str { + fn name(&self) -> &str { &self.filename } - fn filesystem_stream_type( &self ) -> &str { + fn filesystem_stream_type(&self) -> &str { "Disk" } - } diff --git a/src/system/filesystem_stream_empty.rs b/src/system/filesystem_stream_empty.rs index eaf6481..f87c36d 100644 --- a/src/system/filesystem_stream_empty.rs +++ b/src/system/filesystem_stream_empty.rs @@ -1,5 +1,3 @@ - - use crate::system::filesystem_stream::FilesystemStream; pub struct FilesystemStreamEmpty { @@ -7,7 +5,7 @@ pub struct FilesystemStreamEmpty { } impl FilesystemStreamEmpty { - pub fn open( name: &str ) -> Self { + pub fn open(name: &str) -> Self { Self { name: name.to_owned(), } @@ -15,29 +13,26 @@ impl FilesystemStreamEmpty { } impl FilesystemStream for FilesystemStreamEmpty { - fn size( &self ) -> usize { + fn size(&self) -> usize { 0 } - fn pos( &self ) -> usize { + fn pos(&self) -> usize { 0 } - fn set_pos( &mut self, _pos: usize ) { - - } - fn read_u8( &mut self ) -> u8 { + fn set_pos(&mut self, _pos: usize) {} + fn read_u8(&mut self) -> u8 { 0 } - fn is_valid( &self ) -> bool { + fn is_valid(&self) -> bool { true } - fn eof( &self ) -> bool { + fn eof(&self) -> bool { true } - fn name( &self ) -> &str { + fn name(&self) -> &str { &self.name } - fn filesystem_stream_type( &self ) -> &str { + fn filesystem_stream_type(&self) -> &str { "Empty" } - } diff --git a/src/system/filesystem_stream_memory.rs b/src/system/filesystem_stream_memory.rs index ad52fda..72c9a26 100644 --- a/src/system/filesystem_stream_memory.rs +++ b/src/system/filesystem_stream_memory.rs @@ -1,56 +1,53 @@ - - use crate::system::filesystem_stream::FilesystemStream; pub struct FilesystemStreamMemory { name: String, - data: Vec< u8 >, - pos: usize, + data: Vec, + pos: usize, } impl FilesystemStreamMemory { - pub fn open( name: &str, data: &Vec< u8 > ) -> Self { + pub fn open(name: &str, data: &Vec) -> Self { Self { name: name.to_owned(), data: data.clone(), // :TODO: optimize out copy - pos: 0, + pos: 0, } } } impl FilesystemStream for FilesystemStreamMemory { - fn size( &self ) -> usize { + fn size(&self) -> usize { self.data.len() } - fn pos( &self ) -> usize { + fn pos(&self) -> usize { self.pos } - fn set_pos( &mut self, pos: usize ) { + fn set_pos(&mut self, pos: usize) { self.pos = pos; } - fn read_u8( &mut self ) -> u8 { - match self.data.get( self.pos ) { + fn read_u8(&mut self) -> u8 { + match self.data.get(self.pos) { None => { - println!( "Warning: Failed to get u8 for MemoryStream" ); + println!("Warning: Failed to get u8 for MemoryStream"); 0 }, - Some( b ) => { + Some(b) => { self.pos += 1; *b }, } } - fn is_valid( &self ) -> bool { + fn is_valid(&self) -> bool { true } - fn eof( &self ) -> bool { + fn eof(&self) -> bool { self.pos >= self.data.len() } - fn name( &self ) -> &str { + fn name(&self) -> &str { &self.name } - fn filesystem_stream_type( &self ) -> &str { + fn filesystem_stream_type(&self) -> &str { "Memory" } - } diff --git a/src/system/serializer.rs b/src/system/serializer.rs index ed6467a..3e6f538 100644 --- a/src/system/serializer.rs +++ b/src/system/serializer.rs @@ -1,6 +1,4 @@ - -use crate::system::filesystem_stream::{ FilesystemStream, FilesystemStreamMode }; - +use crate::system::filesystem_stream::{FilesystemStream, FilesystemStreamMode}; #[derive(Debug)] enum SerializerMode { @@ -10,14 +8,14 @@ enum SerializerMode { #[derive(Debug)] pub struct Serializer { - file: Box< dyn FilesystemStream >, - mode: SerializerMode, - any_error: bool, + file: Box, + mode: SerializerMode, + any_error: bool, byte_count: usize, } impl Serializer { - pub fn new( file: Box< dyn FilesystemStream > ) -> Self { + pub fn new(file: Box) -> Self { let mode = match file.mode() { FilesystemStreamMode::Read => SerializerMode::Read, FilesystemStreamMode::Write => SerializerMode::Write, @@ -30,61 +28,47 @@ impl Serializer { } } - pub fn serialize_u8( &mut self, data: &mut u8 ) { + pub fn serialize_u8(&mut self, data: &mut u8) { self.byte_count += 1; match self.mode { SerializerMode::Read => { - *data = self.file.read_u8( ); - + *data = self.file.read_u8(); }, SerializerMode::Write => { - self.file.write_u8( *data ); + self.file.write_u8(*data); }, } } - pub fn serialize_u16( &mut self, data: &mut u16 ) { - let mut h = ( ( *data >> 8 ) & 0xff ) as u8; - let mut l = ( ( *data >> 0 ) & 0xff ) as u8; + pub fn serialize_u16(&mut self, data: &mut u16) { + let mut h = ((*data >> 8) & 0xff) as u8; + let mut l = ((*data >> 0) & 0xff) as u8; - self.serialize_u8( &mut h ); - self.serialize_u8( &mut l ); + self.serialize_u8(&mut h); + self.serialize_u8(&mut l); - *data = ( ( h as u16 ) <<8 ) | ( l as u16 ); + *data = ((h as u16) << 8) | (l as u16); } - pub fn serialize_u32( &mut self, data: &mut u32 ) { - let mut a = ( ( *data >> 24 ) & 0xff ) as u8; - let mut b = ( ( *data >> 16 ) & 0xff ) as u8; - let mut c = ( ( *data >> 8 ) & 0xff ) as u8; - let mut d = ( ( *data >> 0 ) & 0xff ) as u8; + pub fn serialize_u32(&mut self, data: &mut u32) { + let mut a = ((*data >> 24) & 0xff) as u8; + let mut b = ((*data >> 16) & 0xff) as u8; + let mut c = ((*data >> 8) & 0xff) as u8; + let mut d = ((*data >> 0) & 0xff) as u8; - self.serialize_u8( &mut a ); - self.serialize_u8( &mut b ); - self.serialize_u8( &mut c ); - self.serialize_u8( &mut d ); + self.serialize_u8(&mut a); + self.serialize_u8(&mut b); + self.serialize_u8(&mut c); + self.serialize_u8(&mut d); - *data = - ( ( a as u32 ) << 24 ) - | ( ( b as u32 ) << 16 ) - | ( ( c as u32 ) << 8 ) - | ( d as u32 ); + *data = ((a as u32) << 24) | ((b as u32) << 16) | ((c as u32) << 8) | (d as u32); } - pub fn serialize_bool( &mut self, value: &mut bool ) { - let mut v: u8 = if *value { - 1 - } else { - 0 - }; + pub fn serialize_bool(&mut self, value: &mut bool) { + let mut v: u8 = if *value { 1 } else { 0 }; - self.serialize_u8( &mut v ); + self.serialize_u8(&mut v); - *value = if v > 0 { - true - } else { - false - } + *value = if v > 0 { true } else { false } } - }