Fix debug info for structs
This commit is contained in:
		
							parent
							
								
									4f0ee72c83
								
							
						
					
					
						commit
						4fada0036c
					
				
							
								
								
									
										10
									
								
								examples/a.reid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								examples/a.reid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | struct Foo { | ||||||
|  |     a: i32, | ||||||
|  |     b: i32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn main() -> i32 { | ||||||
|  |     // ISSUE: The debugger says b is 1 | ||||||
|  |     let foos = [Foo { a: 1, b: 2}]; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
| @ -540,7 +540,7 @@ impl DebugTypeHolder { | |||||||
|                                 field.pos.map(|p| p.line).unwrap_or(1), |                                 field.pos.map(|p| p.line).unwrap_or(1), | ||||||
|                                 field.size_bits, |                                 field.size_bits, | ||||||
|                                 0, |                                 0, | ||||||
|                                 1, |                                 field.offset, | ||||||
|                                 field.flags.as_llvm(), |                                 field.flags.as_llvm(), | ||||||
|                                 *debug.types.get(&field.ty).unwrap(), |                                 *debug.types.get(&field.ty).unwrap(), | ||||||
|                             ) |                             ) | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| use reid_lib::{CmpPredicate, ConstValueKind, Instr, Type, builder::InstructionValue}; | use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     codegen::{ErrorKind, StackValueKind}, |     codegen::{ErrorKind, StackValueKind}, | ||||||
| @ -377,7 +377,9 @@ impl IntrinsicFunction for IntrinsicSizeOf { | |||||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { |     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||||
|         let instr = scope |         let instr = scope | ||||||
|             .block |             .block | ||||||
|             .build(Instr::Constant(reid_lib::ConstValueKind::U64(self.0.size_of() / 8))) |             .build(Instr::Constant(reid_lib::ConstValueKind::U64( | ||||||
|  |                 self.0.size_of(&scope.type_map) / 8, | ||||||
|  |             ))) | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         Ok(StackValue(StackValueKind::Literal(instr), self.0.clone())) |         Ok(StackValue(StackValueKind::Literal(instr), self.0.clone())) | ||||||
|     } |     } | ||||||
| @ -395,7 +397,9 @@ impl IntrinsicFunction for IntrinsicMalloc { | |||||||
| 
 | 
 | ||||||
|         let sizeof = scope |         let sizeof = scope | ||||||
|             .block |             .block | ||||||
|             .build(Instr::Constant(ConstValueKind::U64(self.0.size_of() / 8))) |             .build(Instr::Constant(ConstValueKind::U64( | ||||||
|  |                 self.0.size_of(&scope.type_map) / 8, | ||||||
|  |             ))) | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
|         let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap(); |         let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap(); | ||||||
|         let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap(); |         let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap(); | ||||||
|  | |||||||
| @ -144,6 +144,7 @@ impl mir::Module { | |||||||
|         let mut types = HashMap::new(); |         let mut types = HashMap::new(); | ||||||
|         let mut type_values = HashMap::new(); |         let mut type_values = HashMap::new(); | ||||||
|         let mut debug_types = HashMap::new(); |         let mut debug_types = HashMap::new(); | ||||||
|  |         let mut type_map = HashMap::new(); | ||||||
| 
 | 
 | ||||||
|         macro_rules! insert_debug { |         macro_rules! insert_debug { | ||||||
|             ($kind:expr) => { |             ($kind:expr) => { | ||||||
| @ -153,8 +154,7 @@ impl mir::Module { | |||||||
|                         &compile_unit, |                         &compile_unit, | ||||||
|                         &debug, |                         &debug, | ||||||
|                         &debug_types, |                         &debug_types, | ||||||
|                         &type_values, |                         &type_map, | ||||||
|                         &types, |  | ||||||
|                         self.module_id, |                         self.module_id, | ||||||
|                         &self.tokens, |                         &self.tokens, | ||||||
|                         &modules, |                         &modules, | ||||||
| @ -182,6 +182,8 @@ impl mir::Module { | |||||||
| 
 | 
 | ||||||
|         for typedef in typedefs { |         for typedef in typedefs { | ||||||
|             let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module); |             let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module); | ||||||
|  |             type_map.insert(type_key.clone(), typedef.clone()); | ||||||
|  | 
 | ||||||
|             let type_value = match &typedef.kind { |             let type_value = match &typedef.kind { | ||||||
|                 TypeDefinitionKind::Struct(StructType(fields)) => { |                 TypeDefinitionKind::Struct(StructType(fields)) => { | ||||||
|                     module.custom_type(CustomTypeKind::NamedStruct(NamedStruct( |                     module.custom_type(CustomTypeKind::NamedStruct(NamedStruct( | ||||||
| @ -198,6 +200,7 @@ impl mir::Module { | |||||||
|             }; |             }; | ||||||
|             types.insert(type_value, typedef.clone()); |             types.insert(type_value, typedef.clone()); | ||||||
|             type_values.insert(type_key.clone(), type_value); |             type_values.insert(type_key.clone(), type_value); | ||||||
|  | 
 | ||||||
|             insert_debug!(&TypeKind::CustomType(type_key.clone())); |             insert_debug!(&TypeKind::CustomType(type_key.clone())); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -380,6 +383,7 @@ impl mir::Module { | |||||||
|                                 functions: &functions, |                                 functions: &functions, | ||||||
|                                 types: &types, |                                 types: &types, | ||||||
|                                 type_values: &type_values, |                                 type_values: &type_values, | ||||||
|  |                                 type_map: &type_map, | ||||||
|                                 globals: &globals, |                                 globals: &globals, | ||||||
|                                 stack_values: HashMap::new(), |                                 stack_values: HashMap::new(), | ||||||
|                                 debug: Some(Debug { |                                 debug: Some(Debug { | ||||||
| @ -457,6 +461,7 @@ impl mir::Module { | |||||||
|                     functions: &functions, |                     functions: &functions, | ||||||
|                     types: &types, |                     types: &types, | ||||||
|                     type_values: &type_values, |                     type_values: &type_values, | ||||||
|  |                     type_map: &type_map, | ||||||
|                     stack_values: HashMap::new(), |                     stack_values: HashMap::new(), | ||||||
|                     debug: Some(Debug { |                     debug: Some(Debug { | ||||||
|                         info: &debug, |                         info: &debug, | ||||||
| @ -518,6 +523,7 @@ impl mir::Module { | |||||||
|                     functions: &functions, |                     functions: &functions, | ||||||
|                     types: &types, |                     types: &types, | ||||||
|                     type_values: &type_values, |                     type_values: &type_values, | ||||||
|  |                     type_map: &type_map, | ||||||
|                     stack_values: HashMap::new(), |                     stack_values: HashMap::new(), | ||||||
|                     debug: Some(Debug { |                     debug: Some(Debug { | ||||||
|                         info: &debug, |                         info: &debug, | ||||||
| @ -1388,7 +1394,11 @@ impl mir::Expression { | |||||||
|                         .build(Instr::Alloca(ty.get_type(scope.type_values))) |                         .build(Instr::Alloca(ty.get_type(scope.type_values))) | ||||||
|                         .unwrap(); |                         .unwrap(); | ||||||
| 
 | 
 | ||||||
|                     scope.block.build(Instr::Store(allocated, value)).unwrap(); |                     scope | ||||||
|  |                         .block | ||||||
|  |                         .build(Instr::Store(allocated, value)) | ||||||
|  |                         .unwrap() | ||||||
|  |                         .maybe_location(&mut scope.block, location.clone()); | ||||||
| 
 | 
 | ||||||
|                     let a = Some(StackValue( |                     let a = Some(StackValue( | ||||||
|                         StackValueKind::Literal(allocated), |                         StackValueKind::Literal(allocated), | ||||||
|  | |||||||
| @ -26,6 +26,7 @@ pub struct Scope<'ctx, 'scope> { | |||||||
|     pub(super) block: Block<'ctx>, |     pub(super) block: Block<'ctx>, | ||||||
|     pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>, |     pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>, | ||||||
|     pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>, |     pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>, | ||||||
|  |     pub(super) type_map: &'scope HashMap<CustomTypeKey, TypeDefinition>, | ||||||
|     pub(super) assoc_functions: &'scope HashMap<AssociatedFunctionKey, ScopeFunctionKind<'ctx>>, |     pub(super) assoc_functions: &'scope HashMap<AssociatedFunctionKey, ScopeFunctionKind<'ctx>>, | ||||||
|     pub(super) functions: &'scope HashMap<String, ScopeFunctionKind<'ctx>>, |     pub(super) functions: &'scope HashMap<String, ScopeFunctionKind<'ctx>>, | ||||||
|     pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>, |     pub(super) binops: &'scope HashMap<BinopKey, StackBinopDefinition<'ctx>>, | ||||||
| @ -49,6 +50,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { | |||||||
|             functions: self.functions, |             functions: self.functions, | ||||||
|             types: self.types, |             types: self.types, | ||||||
|             type_values: self.type_values, |             type_values: self.type_values, | ||||||
|  |             type_map: self.type_map, | ||||||
|             stack_values: self.stack_values.clone(), |             stack_values: self.stack_values.clone(), | ||||||
|             debug: self.debug.clone(), |             debug: self.debug.clone(), | ||||||
|             allocator: self.allocator.clone(), |             allocator: self.allocator.clone(), | ||||||
|  | |||||||
| @ -109,8 +109,7 @@ impl TypeKind { | |||||||
|             &debug.scope, |             &debug.scope, | ||||||
|             debug.info, |             debug.info, | ||||||
|             debug.types, |             debug.types, | ||||||
|             scope.type_values, |             scope.type_map, | ||||||
|             scope.types, |  | ||||||
|             scope.module_id, |             scope.module_id, | ||||||
|             scope.tokens, |             scope.tokens, | ||||||
|             scope.modules, |             scope.modules, | ||||||
| @ -122,8 +121,7 @@ impl TypeKind { | |||||||
|         scope: &DebugScopeValue, |         scope: &DebugScopeValue, | ||||||
|         debug_info: &DebugInformation, |         debug_info: &DebugInformation, | ||||||
|         debug_types: &HashMap<TypeKind, DebugTypeValue>, |         debug_types: &HashMap<TypeKind, DebugTypeValue>, | ||||||
|         type_values: &HashMap<CustomTypeKey, TypeValue>, |         type_map: &HashMap<CustomTypeKey, TypeDefinition>, | ||||||
|         types: &HashMap<TypeValue, TypeDefinition>, |  | ||||||
|         local_mod: SourceModuleId, |         local_mod: SourceModuleId, | ||||||
|         tokens: &Vec<FullToken>, |         tokens: &Vec<FullToken>, | ||||||
|         modules: &HashMap<SourceModuleId, ModuleCodegen>, |         modules: &HashMap<SourceModuleId, ModuleCodegen>, | ||||||
| @ -142,13 +140,12 @@ impl TypeKind { | |||||||
|                         scope, |                         scope, | ||||||
|                         debug_info, |                         debug_info, | ||||||
|                         debug_types, |                         debug_types, | ||||||
|                         type_values, |                         type_map, | ||||||
|                         types, |  | ||||||
|                         local_mod, |                         local_mod, | ||||||
|                         tokens, |                         tokens, | ||||||
|                         modules, |                         modules, | ||||||
|                     ), |                     ), | ||||||
|                     size_bits: self.size_of(), |                     size_bits: self.size_of(type_map), | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|             TypeKind::Array(elem_ty, len) => { |             TypeKind::Array(elem_ty, len) => { | ||||||
| @ -156,21 +153,20 @@ impl TypeKind { | |||||||
|                     scope, |                     scope, | ||||||
|                     debug_info, |                     debug_info, | ||||||
|                     debug_types, |                     debug_types, | ||||||
|                     type_values, |                     type_map, | ||||||
|                     types, |  | ||||||
|                     local_mod, |                     local_mod, | ||||||
|                     tokens, |                     tokens, | ||||||
|                     modules, |                     modules, | ||||||
|                 ); |                 ); | ||||||
|                 DebugTypeData::Array(DebugArrayType { |                 DebugTypeData::Array(DebugArrayType { | ||||||
|                     size_bits: self.size_of(), |                     size_bits: self.size_of(type_map), | ||||||
|                     align_bits: self.alignment(), |                     align_bits: self.alignment(), | ||||||
|                     element_type: elem_ty, |                     element_type: elem_ty, | ||||||
|                     length: *len, |                     length: *len, | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|             TypeKind::CustomType(key) => { |             TypeKind::CustomType(key) => { | ||||||
|                 let typedef = types.get(type_values.get(key).unwrap()).unwrap(); |                 let typedef = type_map.get(key).unwrap(); | ||||||
|                 match &typedef.kind { |                 match &typedef.kind { | ||||||
|                     TypeDefinitionKind::Struct(struct_type) => { |                     TypeDefinitionKind::Struct(struct_type) => { | ||||||
|                         let mut fields = Vec::new(); |                         let mut fields = Vec::new(); | ||||||
| @ -186,21 +182,20 @@ impl TypeKind { | |||||||
|                                 name: field.0.clone(), |                                 name: field.0.clone(), | ||||||
|                                 scope: scope.clone(), |                                 scope: scope.clone(), | ||||||
|                                 pos: location.map(|l| l.pos), |                                 pos: location.map(|l| l.pos), | ||||||
|                                 size_bits: field.1.size_of(), |                                 size_bits: field.1.size_of(type_map), | ||||||
|                                 offset: size_bits, |                                 offset: size_bits, | ||||||
|                                 flags: DwarfFlags, |                                 flags: DwarfFlags, | ||||||
|                                 ty: field.1.get_debug_type_hard( |                                 ty: field.1.get_debug_type_hard( | ||||||
|                                     scope, |                                     scope, | ||||||
|                                     debug_info, |                                     debug_info, | ||||||
|                                     debug_types, |                                     debug_types, | ||||||
|                                     type_values, |                                     type_map, | ||||||
|                                     types, |  | ||||||
|                                     local_mod, |                                     local_mod, | ||||||
|                                     tokens, |                                     tokens, | ||||||
|                                     modules, |                                     modules, | ||||||
|                                 ), |                                 ), | ||||||
|                             }); |                             }); | ||||||
|                             size_bits += field.1.size_of(); |                             size_bits += field.1.size_of(type_map); | ||||||
|                         } |                         } | ||||||
|                         { |                         { | ||||||
|                             let location = if typedef.source_module != local_mod { |                             let location = if typedef.source_module != local_mod { | ||||||
| @ -222,7 +217,7 @@ impl TypeKind { | |||||||
|             } |             } | ||||||
|             _ => DebugTypeData::Basic(DebugBasicType { |             _ => DebugTypeData::Basic(DebugBasicType { | ||||||
|                 name, |                 name, | ||||||
|                 size_bits: self.size_of(), |                 size_bits: self.size_of(type_map), | ||||||
|                 encoding: match self { |                 encoding: match self { | ||||||
|                     TypeKind::Bool => DwarfEncoding::Boolean, |                     TypeKind::Bool => DwarfEncoding::Boolean, | ||||||
|                     TypeKind::I8 => DwarfEncoding::SignedChar, |                     TypeKind::I8 => DwarfEncoding::SignedChar, | ||||||
|  | |||||||
| @ -1,3 +1,5 @@ | |||||||
|  | use reid_lib::builder::TypeValue; | ||||||
|  | 
 | ||||||
| use crate::util::maybe; | use crate::util::maybe; | ||||||
| 
 | 
 | ||||||
| use super::{typecheck::typerefs::TypeRefs, *}; | use super::{typecheck::typerefs::TypeRefs, *}; | ||||||
| @ -57,7 +59,7 @@ impl TypeKind { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn size_of(&self) -> u64 { |     pub fn size_of(&self, map: &HashMap<CustomTypeKey, TypeDefinition>) -> u64 { | ||||||
|         match self { |         match self { | ||||||
|             TypeKind::Bool => 1, |             TypeKind::Bool => 1, | ||||||
|             TypeKind::I8 => 8, |             TypeKind::I8 => 8, | ||||||
| @ -72,8 +74,16 @@ impl TypeKind { | |||||||
|             TypeKind::U128 => 128, |             TypeKind::U128 => 128, | ||||||
|             TypeKind::Void => 0, |             TypeKind::Void => 0, | ||||||
|             TypeKind::Char => 8, |             TypeKind::Char => 8, | ||||||
|             TypeKind::Array(type_kind, len) => type_kind.size_of() * (*len as u64), |             TypeKind::Array(type_kind, len) => type_kind.size_of(map) * (*len as u64), | ||||||
|             TypeKind::CustomType(..) => 32, |             TypeKind::CustomType(key) => match &map.get(key).unwrap().kind { | ||||||
|  |                 TypeDefinitionKind::Struct(struct_type) => { | ||||||
|  |                     let mut size = 0; | ||||||
|  |                     for field in &struct_type.0 { | ||||||
|  |                         size += field.1.size_of(map) | ||||||
|  |                     } | ||||||
|  |                     size | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|             TypeKind::CodegenPtr(_) => 64, |             TypeKind::CodegenPtr(_) => 64, | ||||||
|             TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"), |             TypeKind::Vague(_) => panic!("Tried to sizeof a vague type!"), | ||||||
|             TypeKind::Borrow(..) => 64, |             TypeKind::Borrow(..) => 64, | ||||||
|  | |||||||
							
								
								
									
										215
									
								
								test.reid
									
									
									
									
									
								
							
							
						
						
									
										215
									
								
								test.reid
									
									
									
									
									
								
							| @ -1,215 +0,0 @@ | |||||||
| //////////// |  | ||||||
| /// math /// |  | ||||||
| //////////// |  | ||||||
| 
 |  | ||||||
| struct Vec2 { x: f32, y: f32 } |  | ||||||
| 
 |  | ||||||
| impl Vec2 { |  | ||||||
|     pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } } |  | ||||||
|     pub fn at(x: f32, y: f32) -> Vec2 { Vec2 { x: x, y: y } } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //impl binop () |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /////////////////// |  | ||||||
| /// SDL externs /// |  | ||||||
| /////////////////// |  | ||||||
| 
 |  | ||||||
| struct SDL_FPoint { x: f32, y: f32 } |  | ||||||
| struct SDL_FColor { r: f32, g: f32, b: f32, a: f32 } |  | ||||||
| struct SDL_Vertex { position: SDL_FPoint, color: SDL_FColor, tex_coord: SDL_FPoint } |  | ||||||
| impl SDL_Vertex { |  | ||||||
|     pub fn new() -> SDL_Vertex { |  | ||||||
|         SDL_Vertex { |  | ||||||
|             position: SDL_FPoint { x: 0.0, y: 0.0 }, |  | ||||||
|             color: SDL_FColor { r: 1.0, g: 0.0, b: 1.0, a: 1.0 }, |  | ||||||
|             tex_coord: SDL_FPoint { x: 0.0, y: 0.0 }, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn pos(self, pos: Vec2) -> SDL_Vertex { |  | ||||||
|         return SDL_Vertex { |  | ||||||
|             position: SDL_FPoint { x: pos.x, y: pos.y }, |  | ||||||
|             color: self.color, |  | ||||||
|             tex_coord: self.tex_coord, |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn col(self, color: [f32; 3]) -> SDL_Vertex { |  | ||||||
|         return SDL_Vertex { |  | ||||||
|             position: self.position, |  | ||||||
|             color: [color[0], color[1], color[2], self.color.a], |  | ||||||
|             tex_coord: self.tex_coord, |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct SDL_Window {} |  | ||||||
| struct SDL_Renderer {} |  | ||||||
| struct SDL_Texture {} |  | ||||||
| struct SDL_Event { type: u32, reserved: [u8; 124] } |  | ||||||
| struct SDL_FRect { x: f32, y: f32, w: f32, h: f32 } |  | ||||||
| struct SDL_Rect { x: i32, y: i32, w: i32, h: i32 } |  | ||||||
| extern fn SDL_malloc(size: u64) -> *u8; |  | ||||||
| extern fn SDL_Init(flags: u32) -> bool; |  | ||||||
| extern fn SDL_Quit(); |  | ||||||
| extern fn SDL_CreateWindowAndRenderer(title: *char, width: i32, height: i32, flags: i32, |  | ||||||
|     window_out: &mut *SDL_Window, renderer_out: &mut *SDL_Renderer) -> bool; |  | ||||||
| extern fn SDL_Delay(ms: u32); |  | ||||||
| extern fn SDL_SetRenderDrawColor(renderer: *SDL_Renderer, r: u8, g: u8, b: u8, a: u8); |  | ||||||
| extern fn SDL_RenderClear(renderer: *SDL_Renderer); |  | ||||||
| extern fn SDL_RenderPresent(renderer: *SDL_Renderer); |  | ||||||
| extern fn SDL_HasEvent(event_type: u32) -> bool; |  | ||||||
| extern fn SDL_PollEvent(event: &mut SDL_Event) -> bool; |  | ||||||
| extern fn SDL_PumpEvents(); |  | ||||||
| extern fn SDL_FlushEvents(min_type: u32, max_type: u32); |  | ||||||
| extern fn SDL_GetTicks() -> u64; |  | ||||||
| extern fn SDL_SetWindowTitle(window: *SDL_Window, title: *char) -> bool; |  | ||||||
| extern fn SDL_CreateTexture(renderer: *SDL_Renderer, |  | ||||||
|     pixel_format: u32, texture_access: u32, width: u32, height: u32) -> *SDL_Texture; |  | ||||||
| extern fn SDL_RenderTexture(renderer: *SDL_Renderer, |  | ||||||
|     texture: *SDL_Texture, srcfrect: &SDL_FRect, dstfrect: &SDL_FRect) -> bool; |  | ||||||
| extern fn SDL_UpdateTexture(texture: *SDL_Texture, rect: &SDL_Rect, pixels: *u8, pitch: u32) -> bool; |  | ||||||
| extern fn SDL_GetError() -> *char; |  | ||||||
| extern fn SDL_GetWindowSize(window: *SDL_Window, w: &mut i32, h: &mut i32) -> bool; |  | ||||||
| extern fn SDL_rand(max_exclusive: u32) -> u32; |  | ||||||
| extern fn SDL_SetTextureScaleMode(texture: *SDL_Texture, scale_mode: i32) -> bool; |  | ||||||
| extern fn SDL_sqrtf(value: f32) -> f32; |  | ||||||
| extern fn SDL_randf() -> f32; |  | ||||||
| extern fn SDL_powf(value: f32, power: f32) -> f32; |  | ||||||
| extern fn exit(exit_code: i32); |  | ||||||
| extern fn SDL_RenderGeometry(renderer: *SDL_Renderer, texture: *SDL_Texture, |  | ||||||
|     vertices: *SDL_Vertex, num_vertices: i32, indices: *i32, num_indices: i32) -> bool; |  | ||||||
| 
 |  | ||||||
| // SDL error reporting helper |  | ||||||
| import std::print; |  | ||||||
| import std::String; |  | ||||||
| fn print_sdl_error(context: *char) { |  | ||||||
|     let mut message = String::new(); |  | ||||||
|     message = message + context + ": " + SDL_GetError(); |  | ||||||
|     print(message); |  | ||||||
|     message.free(); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //////////////// |  | ||||||
| /// the game /// |  | ||||||
| //////////////// |  | ||||||
| 
 |  | ||||||
| struct Ship { |  | ||||||
|     position: Vec2, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| struct Game { |  | ||||||
|     ship: Ship, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Game { |  | ||||||
|     pub fn new() -> Game { |  | ||||||
|         Game { |  | ||||||
|             ship: Ship { |  | ||||||
|                 position: Vec2::zero(), |  | ||||||
|             }, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn run_frame(&mut self, dt: f32, renderer: *SDL_Renderer, aspect_ratio: f32) { |  | ||||||
|         let ship = *self.ship; |  | ||||||
|         let vertices = [ |  | ||||||
|             SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]), |  | ||||||
|             SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]), |  | ||||||
|             SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]) |  | ||||||
|         ]; |  | ||||||
|         let borrow: &[SDL_Vertex; 3] = &vertices; |  | ||||||
|         SDL_RenderGeometry(renderer, SDL_Texture::null(), |  | ||||||
|             borrow as *SDL_Vertex, 3, i32::null(), 0); |  | ||||||
|         // TODO: add a ship |  | ||||||
|         // TODO: wind sim |  | ||||||
|         // TODO: wave sim |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //////////////// |  | ||||||
| /// the game /// |  | ||||||
| //////////////// |  | ||||||
| 
 |  | ||||||
| struct Platform { |  | ||||||
|     window: *SDL_Window, |  | ||||||
|     renderer: *SDL_Renderer, |  | ||||||
|     game: Game, |  | ||||||
|     last_frame_ticks: u64, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Platform { |  | ||||||
|     pub fn new() -> Platform { |  | ||||||
|         let SDL_INIT_VIDEO = 32; |  | ||||||
|         let SDL_WINDOW_RESIZABLE = 32; |  | ||||||
| 
 |  | ||||||
|         let init_success = SDL_Init(SDL_INIT_VIDEO); |  | ||||||
|         if init_success == false { |  | ||||||
|             print_sdl_error("SDL init failed"); |  | ||||||
|             return exit(1); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let mut window = SDL_Window::null(); |  | ||||||
|         let mut renderer = SDL_Renderer::null(); |  | ||||||
|         let mut window_title = "Yacht Reid"; |  | ||||||
|         let gfx_init_success = SDL_CreateWindowAndRenderer( |  | ||||||
|             window_title, 640, 480, SDL_WINDOW_RESIZABLE, |  | ||||||
|             &mut window, &mut renderer |  | ||||||
|         ); |  | ||||||
|         if gfx_init_success == false { |  | ||||||
|             print_sdl_error("SDL renderer and window creation failed"); |  | ||||||
|             return exit(1); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return Platform {  |  | ||||||
|             window: window,  |  | ||||||
|             renderer: renderer, |  | ||||||
|             game: Game::new(), |  | ||||||
|             last_frame_ticks: SDL_GetTicks(), |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn run_frame(&mut self) -> bool { |  | ||||||
|         let mut event = SDL_Event { type: 0, reserved: [0; 124] }; |  | ||||||
|         while (SDL_PollEvent(&mut event)) { |  | ||||||
|             if event.type == 256 { // SDL_EVENT_QUIT |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let now = SDL_GetTicks(); |  | ||||||
|         let dt = (now - *self.last_frame_ticks) as f32 / 1000.0; |  | ||||||
|         *self.last_frame_ticks = now; |  | ||||||
| 
 |  | ||||||
|         let mut screen_width = 0; |  | ||||||
|         let mut screen_height = 0; |  | ||||||
|         SDL_GetWindowSize(*self.window, &mut screen_width, &mut screen_height); |  | ||||||
|         let aspect_ratio = screen_width as f32 / screen_height as f32; |  | ||||||
| 
 |  | ||||||
|         SDL_SetRenderDrawColor(*self.renderer, 0, 50, 90, 255); |  | ||||||
|         SDL_RenderClear(*self.renderer); |  | ||||||
| 
 |  | ||||||
|         *self.game.run_frame(dt, *self.renderer, aspect_ratio); |  | ||||||
| 
 |  | ||||||
|         SDL_RenderPresent(*self.renderer); |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn cleanup(&mut self) { |  | ||||||
|         SDL_Quit(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| //////////// |  | ||||||
| /// main /// |  | ||||||
| //////////// |  | ||||||
| 
 |  | ||||||
| fn main() -> i32 { |  | ||||||
|     let mut platform = Platform::new(); |  | ||||||
|     while platform.run_frame() {} |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user