diff --git a/.vscode/launch.json b/.vscode/launch.json index 85c72b9..e4b8563 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,16 @@ { "type":"cppvsdbg", "request": "launch", - "name" : "Debug handmade engine (post_build) gen msvc", + "name" : "Debug handmade engine gen msvc", + "program": "${workspaceFolder}/build/engine_gen.exe", + "args": [], + "cwd": "${workspaceFolder}/project/engine/gen", + "visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis" + }, + { + "type":"cppvsdbg", + "request": "launch", + "name" : "Debug handmade engine (post-build) gen msvc", "program": "${workspaceFolder}/build/engine_postbuild_gen.exe", "args": [], "cwd": "${workspaceFolder}/build", diff --git a/docs/Day 025.md b/docs/Day 025.md deleted file mode 100644 index 2b36fff..0000000 --- a/docs/Day 025.md +++ /dev/null @@ -1,13 +0,0 @@ -# Day 25 - -Him doing replay save states at the platform layer is causing issues for me... -I'm going to most likely end up doing two categories of save states, one for engine level and one for platform level. - -The engine level can just store it in the memory struct, and the game memory can just stay where it is. -I want to use the same "save state" slots for both engine and game since there is no need different memory buckets for that. They will at worst case be ofcourse the size of engine's memory block. - -So if there is 4, we are looking at 5x the actual memory size. This is fine for now since the engine block is 2 gigs. -Snapshots of of memory are are handled using take and load snapshot functions. They can be used separate from the replay looping functionality. -Replay looping however is dependent on snapshots so if a replay is save/loaded it will use the same snapshot slot of memory to do that state management. - -Feels great to be past the platform layer bulk!!! diff --git a/docs/Day 026-40.md b/docs/Day 026-40.md new file mode 100644 index 0000000..450d902 --- /dev/null +++ b/docs/Day 026-40.md @@ -0,0 +1,77 @@ +# Day 27 + +Definitely feels refreshing to not touch win32. + +# Day 30 + +Tile map stuff is looking alright. Doing my best to not clean-up the code as Casey pleads in the vods. + +I would have perferred if he didn't just do one tilemap at a time and instead I would have had the current tile map and surrounding loaded at the same time (He might do this in the future). Since were aren't constrained memory wise like the old machines, we could have those loaded as well and it would make the management of the tilemaps easier (possibly...). + +Looking foward to when he introduces a proper vector space for the positioning. + +# Day 31 + +This was really a prepatory day for day 32 so I did some extra stuff... +I setup codebase so now that the build translation unit files have every single file included for that unit explicitly. +I do not (or should not) have nested includes other than from `grime.hpp` + +## Side Tracking + +I did some refactoring and added `INTELLISENSE_DIRECTIVES` preprocessor conditional blocks throughout the codebase. + +I wanted to see if I could get all IDE/Editors I've ever used to support the project without bad errors from parsing failures. +Unfortunately getting Visual Studio and Rider's intellisense to behave was not possible. +This is mostly from how the code is structured across files currently. +I'll have to re-sturcture it down the line to make it more IDE friendly. + +10xEditor Needs help with the intellisense directives macros, but otherwise was able to parse everything quite accurately. + +VSCode has some failures in few files, they are nearly the same failures as VS2022, however like 10xEditor I saw that it has include awareness beyond a single file's scope! +In fact, if I open all the files, the parser corrects itself (you can close them afterwards). It essentially cached the include graph for the project by doing so for the lifetime of the process. + +VS2022 has issues due to it strictly parsing each file, without awareness of whats going on in other files. +(It doesn't build a proper include graph). + +Rider just straight up broken, it seems to not work every well with NMake projects. +At least, you can't depend on it to use the external include directories field properly. +It will show errors for all external include symbols. + +# Day 32 + +Vod was more of a pain to follow along than usual... + +I updated the scripts to only build each module if it detects changes (just using md5 hash on the files). + +# Day 33 + +I thought the last few vods were not great to follow... That was just training for today. + +# Day 34 + +Casey decided to start offloading tile map definitions to separate files so I took the time to also cleanup some of the organization of the code. +I'm still keeping some cpp files directly included within engine.cpp and win32_platform.cpp for now (instead of their translation unit files). I'll problably wait till much later to offload them. + +Making that first baby step for procedural gen, and proper tile_chunk memory felt pretty good after many vods of stumbling. + +# Day 36 + +Just dealing with Casey's "methods" for going about the code exploration... + +Loading an image was nice, I got it to render somewhat properly with draw_bitmap but until he does it I kept the bad way hes doing it. + +# Day 37 + +I went ahead and did some extra stuff. +My "hero" is a mojito bmp for now. I'll eventually do something else for it. +I also added incremental build support for the codegen metaprograms. + +I originally wanted to make the assets on the fly (just as a break from the code), +but decided to just use his assets as this series is already going to take forever. + +I have the assets mapped to an "offical" directory within content, however they'll be naturally ignored on the repo. + +# Day 40 + +Its finally done with this phase of the project. +Looking forward to seeing some vectors after all these days. diff --git a/docs/Day 027.md b/docs/Day 027.md deleted file mode 100644 index 88bc651..0000000 --- a/docs/Day 027.md +++ /dev/null @@ -1,3 +0,0 @@ -# Day 27 - -Definitely feels refreshing to not touch win32. diff --git a/docs/Day 030.md b/docs/Day 030.md deleted file mode 100644 index 02c5132..0000000 --- a/docs/Day 030.md +++ /dev/null @@ -1,7 +0,0 @@ -# Day 30 - -Tile map stuff is looking alright. Doing my best to not clean-up the code as Casey pleads in the vods. - -I would have perferred if he didn't just do one tilemap at a time and instead I would have had the current tile map and surrounding loaded at the same time (He might do this in the future). Since were aren't constrained memory wise like the old machines, we could have those loaded as well and it would make the management of the tilemaps easier (possibly...). - -Looking foward to when he introduces a proper vector space for the positioning. diff --git a/docs/Day 031.md b/docs/Day 031.md deleted file mode 100644 index e1d1e6c..0000000 --- a/docs/Day 031.md +++ /dev/null @@ -1,26 +0,0 @@ -# Day 31 - -This was really a prepatory day for day 32 so I did some extra stuff... -I setup codebase so now that the build translation unit files have every single file included for that unit explicitly. -I do not (or should not) have nested includes other than from `grime.hpp` - -## Side Tracking - -I did some refactoring and added `INTELLISENSE_DIRECTIVES` preprocessor conditional blocks throughout the codebase. - -I wanted to see if I could get all IDE/Editors I've ever used to support the project without bad errors from parsing failures. -Unfortunately getting Visual Studio and Rider's intellisense to behave was not possible. -This is mostly from how the code is structured across files currently. -I'll have to re-sturcture it down the line to make it more IDE friendly. - -10xEditor Needs help with the intellisense directives macros, but otherwise was able to parse everything quite accurately. - -VSCode has some failures in few files, they are nearly the same failures as VS2022, however like 10xEditor I saw that it has include awareness beyond a single file's scope! -In fact, if I open all the files, the parser corrects itself (you can close them afterwards). It essentially cached the include graph for the project by doing so for the lifetime of the process. - -VS2022 has issues due to it strictly parsing each file, without awareness of whats going on in other files. -(It doesn't build a proper include graph). - -Rider just straight up broken, it seems to not work every well with NMake projects. -At least, you can't depend on it to use the external include directories field properly. -It will show errors for all external include symbols. diff --git a/docs/Day 032.md b/docs/Day 032.md deleted file mode 100644 index 681c559..0000000 --- a/docs/Day 032.md +++ /dev/null @@ -1,5 +0,0 @@ -# Day 32 - -Vod was more of a pain to follow along than usual... - -I updated the scripts to only build each module if it detects changes (just using md5 hash on the files). diff --git a/docs/Day 033.md b/docs/Day 033.md deleted file mode 100644 index 8b19baa..0000000 --- a/docs/Day 033.md +++ /dev/null @@ -1,3 +0,0 @@ -# Day 033 - -I thought the last few vods were not great to follow... That was just training for today. diff --git a/docs/Day 034.md b/docs/Day 034.md deleted file mode 100644 index 11315a8..0000000 --- a/docs/Day 034.md +++ /dev/null @@ -1,6 +0,0 @@ -# Day 34 - -Casey decided to start offloading tile map definitions to separate files so I took the time to also cleanup some of the organization of the code. -I'm still keeping some cpp files directly included within engine.cpp and win32_platform.cpp for now (instead of their translation unit files). I'll problably wait till much later to offload them. - -Making that first baby step for procedural gen, and proper tile_chunk memory felt pretty good after many vods of stumbling. diff --git a/docs/Day 036.md b/docs/Day 036.md deleted file mode 100644 index 5f66c9c..0000000 --- a/docs/Day 036.md +++ /dev/null @@ -1,5 +0,0 @@ -# Day 36 - -Just dealing with Casey's "methods" for going about the code exploration... - -Loading an image was nice, I got it to render somewhat properly with draw_bitmap but until he does it I kept the bad way hes doing it. diff --git a/docs/Day 037.md b/docs/Day 037.md deleted file mode 100644 index 0a52ec8..0000000 --- a/docs/Day 037.md +++ /dev/null @@ -1,10 +0,0 @@ -# Day 37 - -I went ahead and did some extra stuff. -My "hero" is a mojito bmp for now. I'll eventually do something else for it. -I also added incremental build support for the codegen metaprograms. - -I originally wanted to make the assets on the fly (just as a break from the code), -but decided to just use his assets as this series is already going to take forever. - -I have the assets mapped to an "offical" directory within content, however they'll be naturally ignored on the repo. diff --git a/docs/Day 039.md b/docs/Day 039.md deleted file mode 100644 index 502ad38..0000000 --- a/docs/Day 039.md +++ /dev/null @@ -1,18 +0,0 @@ -# Day 39 - -My `draw_bitmap` proc has been already setup to have the position specified -from the assumped position of the center of the image. -Its how I'm used to anchoring images by default so thats why I decided to go with it. - -Casey however is using the corner however... -and then is doing some offset alignment based on what he sees for the coordinates on GIMP.. - -I decided to hand calibrate the alignment by eye. Since I already have it centered on X, the `align_x` could -stay zeroed for now and all I needed to do was align_y. - -I also did not do the difference using a `tile_map_diff` like he did, -I just returned a tile_map_position and switch the map coodinates to be signed -(which tbh is fine I'll just adjust the math later when I need to). - -I'm assuming it won't matter because the tile map setup we currently have is before he revamps the project with proper -vector math data structures, and he might switch to signed coordinates for them in the stream. diff --git a/docs/Day 042.md b/docs/Day 042.md new file mode 100644 index 0000000..b859b12 --- /dev/null +++ b/docs/Day 042.md @@ -0,0 +1,8 @@ +# Day 42 + +I decided to generate the vectors since I wanted f32 and s32 vectors. However, I didn't want to use templates. +I ended up messing aroudn with templates a bit for the `Zero(type)` macro which is just an alt for `type {}`. +Pattern is useful for other constant inits though (if I want to do it that way...) + +Found bugs in gencpp which was nice! +Compressing the code with vector abstraction was nice, hopefuly these pixel will soon as well... diff --git a/project/codegen/engine_gen.cpp b/project/codegen/engine_gen.cpp new file mode 100644 index 0000000..13a2725 --- /dev/null +++ b/project/codegen/engine_gen.cpp @@ -0,0 +1,310 @@ +#include "platform/compiler_ignores.hpp" + +#if GEN_TIME +#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS +#define GEN_IMPLEMENTATION +#define GEN_BENCHMARK +#define GEN_ENFORCE_STRONG_CODE_TYPES +#include "dependencies/gen.hpp" +#undef ccast +#undef pcast +#undef rcast +#undef scast +#undef do_once +#undef do_once_start +#undef do_once_end +using namespace gen; + +#include "platform/platform_module.hpp" +#include "platform/grime.hpp" +#include "platform/macros.hpp" +#include "platform/types.hpp" +#include "platform/strings.hpp" +#include "platform/platform.hpp" + +constexpr StrC fname_vec_header = txt("vectors.hpp"); + +constexpr char const* vec2_ops = stringize( + template<> + constexpr tmpl_zero< >() { + return { 0, 0 }; + } + + inline + abs( v ) { + result { + abs( v.x ), + abs( v.y ) + }; + return result; + } + + inline + operator - ( v ) { + result { + - v.x, + - v.y + }; + return result; + } + + inline + operator + ( a, b ) { + result { + a.x + b.x, + a.y + b.y + }; + return result; + } + + inline + operator - ( a, b ) { + result { + a.x - b.x, + a.y - b.y + }; + return result; + } + + inline + operator * ( v, s ) { + result { + v.x * s, + v.y * s + }; + return result; + } + + inline + operator / ( v, s ) { + result { + v.x / s, + v.y / s + }; + return result; + } + + inline + & operator += ( & a, b ) { + a.x += b.x; + a.y += b.y; + return a; + } + inline + & operator -= ( & a, b ) { + a.x -= b.x; + a.y -= b.y; + return a; + } + + inline + & operator *= ( & v, s ) { + v.x *= s; + v.y *= s; + return v; + } + + inline + & operator /= ( & v, s ) { + v.x /= s; + v.y /= s; + return v; + } +); + +#define gen_vec2( vec_name, type ) gen__vec2( txt( stringize(vec_name) ), txt( stringize(type) ) ) +CodeBody gen__vec2( StrC vec_name, StrC type ) +{ + CodeStruct vec_struct = parse_struct( token_fmt( "type", vec_name, "unit_type", type, stringize( + struct + { + union { + struct { + x; + y; + }; + Basis[2]; + }; + }; + ))); + + CodeBody vec_ops = parse_global_body( token_fmt( "type", vec_name, "unit_type", type, vec2_ops) ); + CodeBody vec_def = def_global_body( args( + vec_struct, + fmt_newline, + vec_ops + )); + + return vec_def; +} + +#define gen_phys2( type ) gen__phys2( txt( stringize(type) ) ) +Code gen__phys2( StrC type ) +{ + String t_vec = String::fmt_buf( GlobalAllocator, "Vec2_%s", type.Ptr ); + String t_pos = String::fmt_buf( GlobalAllocator, "Pos2_%s", type.Ptr ); + String t_dist = String::fmt_buf( GlobalAllocator, "Dist2_%s", type.Ptr ); + String t_vel = String::fmt_buf( GlobalAllocator, "Vel2_%s", type.Ptr ); + String t_accel = String::fmt_buf( GlobalAllocator, "Accel2_%s", type.Ptr ); + +#pragma push_macro("pcast") +#pragma push_macro("rcast") +#undef pcast +#undef rcast + Code result = parse_global_body( token_fmt( + "unit_type", (StrC)type, + "vec_type", (StrC)t_vec, + "pos_type", (StrC)t_pos, + "dist_type", (StrC)t_dist, + "vel_type", (StrC)t_vel, + "accel_type", (StrC)t_accel, + stringize( + struct { + union { + struct { + x; + y; + }; + Basis[2]; + }; + + operator () { + return * rcast(*, this); + } + }; + + using = ; + + inline + distance( a, b ) { + x = b.x - a.x; + y = b.y - a.y; + + result = sqrt( x * x + y * y ); + return result; + } + + struct { + union { + struct { + x; + y; + }; + Basis[2]; + }; + + operator () { + return * rcast(*, this); + } + }; + + inline + velocity( a, b ) { + result = b - a; + return pcast(, result); + } + + inline + & operator +=(& pos, const & vel) { + pos.x += vel.x; + pos.y += vel.y; + return pos; + } + + inline + & operator *= ( & v, s ) { + v.x *= s; + v.y *= s; + return v; + } + + struct { + union { + struct { + x; + y; + }; + Basis[2]; + }; + + operator () { + return * rcast(*, this); + } + }; + + inline + acceleration( a, b ) { + result = b - a; + return pcast(, result); + } + ))); + return result; +#pragma pop_macro("rcast") +#pragma pop_macro("pcast") +} + +int gen_main() +{ + gen::init(); + log_fmt("Generating code for Handmade Hero: Engine Module\n"); + + CodeComment cmt_gen_notice = def_comment( txt("This was generated by project/codegen/engine_gen.cpp") ); + + Builder vec_header = Builder::open(fname_vec_header); + { + vec_header.print( cmt_gen_notice ); + vec_header.print( pragma_once ); + vec_header.print_fmt( "#if INTELLISENSE_DIRECTIVES" ); + vec_header.print( fmt_newline ); + vec_header.print( def_include( txt("engine_module.hpp") )); + vec_header.print( def_include( txt("platform.hpp") )); + vec_header.print( preprocess_endif ); + vec_header.print( fmt_newline ); + + CodeUsing using_vec2 = parse_using( code( using Vec2 = Vec2_f32; )); + CodeUsing using_vec2i = parse_using( code( using Vec2i = Vec2_s32; )); + vec_header.print( gen_vec2( Vec2_f32, f32) ); + vec_header.print( gen_vec2( Vec2_s32, s32) ); + vec_header.print( using_vec2 ); + vec_header.print( using_vec2i ); + + CodeUsing using_vec3 = parse_using( code( using Vec2 = Vec3_f32; )); + CodeUsing using_vec3i = parse_using( code( using Vec2i = Vec3_f32; )); + + // vec_header.print( using_vec3 ); + vec_header.write(); + } + + Builder physics_header = Builder::open( txt("physics.hpp") ); + { + physics_header.print( cmt_gen_notice ); + physics_header.print( pragma_once ); + physics_header.print_fmt( "#if INTELLISENSE_DIRECTIVES" ); + physics_header.print( fmt_newline ); + physics_header.print( def_include( txt("vectors.hpp") )); + physics_header.print( preprocess_endif ); + physics_header.print( fmt_newline ); + + physics_header.print( gen_phys2( f32 ) ); + physics_header.print( gen_phys2( s32 ) ); + + physics_header.print( parse_global_body( code( + using Pos2 = Pos2_f32; + using Dist2 = Dist2_f32; + using Vel2 = Vel2_f32; + using Accel2 = Accel2_f32; + + using Pos2i = Pos2_s32; + using Dist2i = Dist2_s32; + using Vel2i = Vel2_s32; + using Accel2i = Accel2_s32; + ))); + + physics_header.write(); + } + + log_fmt("Generaton finished for Handmade Hero: Engine Module\n\n"); + // gen::deinit(); + return 0; +} +#endif diff --git a/project/codegen/engine_postbuild_gen.cpp b/project/codegen/engine_postbuild_gen.cpp index f917e06..e859627 100644 --- a/project/codegen/engine_postbuild_gen.cpp +++ b/project/codegen/engine_postbuild_gen.cpp @@ -15,14 +15,20 @@ #undef do_once_end using namespace gen; +#include + #include "platform/platform_module.hpp" #include "platform/grime.hpp" #include "platform/macros.hpp" +#include "platform/generics.hpp" #include "platform/types.hpp" +#include "platform/intrinsics.hpp" #include "platform/strings.hpp" #include "platform/platform.hpp" #include "engine/engine_module.hpp" +#include "engine/gen/vectors.hpp" +#include "engine/gen/physics.hpp" #include "engine/input.hpp" #include "engine/tile_map.hpp" #include "engine/engine.hpp" @@ -65,7 +71,7 @@ void get_symbols_from_module_table( FileContents symbol_table, Array sym int gen_main() { gen::init(); - log_fmt("Generating code for Handmade Hero: Engine Module\n"); + log_fmt("Generating code for Handmade Hero: Engine Module (Post-Build)\n"); FileContents symbol_table = file_read_contents( GlobalAllocator, true, fname_handmade_engine_symbols ); @@ -103,7 +109,7 @@ int gen_main() builder.write(); #pragma pop_macro("str_ascii") - log_fmt("Generaton finished for Handmade Hero: Engine Module\n\n"); + log_fmt("Generaton finished for Handmade Hero: Engine Module (Post-Build)\n\n"); // gen::deinit(); return 0; } diff --git a/project/dependencies/gen.hpp b/project/dependencies/gen.hpp index 0171dc4..021cc7e 100644 --- a/project/dependencies/gen.hpp +++ b/project/dependencies/gen.hpp @@ -56,7 +56,7 @@ /* Platform architecture */ #if defined( _WIN64 ) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( __64BIT__ ) || defined( __powerpc64__ ) || defined( __ppc64__ ) \ -|| defined( __aarch64__ ) + || defined( __aarch64__ ) #ifndef GEN_ARCH_64_BIT #define GEN_ARCH_64_BIT 1 #endif @@ -226,218 +226,218 @@ GEN_NS_BEGIN // #if defined(__GNUC__) || defined(__clang__) // Supports 0-50 arguments #define num_args_impl( \ -_0, \ -_1, \ -_2, \ -_3, \ -_4, \ -_5, \ -_6, \ -_7, \ -_8, \ -_9, \ -_10, \ -_11, \ -_12, \ -_13, \ -_14, \ -_15, \ -_16, \ -_17, \ -_18, \ -_19, \ -_20, \ -_21, \ -_22, \ -_23, \ -_24, \ -_25, \ -_26, \ -_27, \ -_28, \ -_29, \ -_30, \ -_31, \ -_32, \ -_33, \ -_34, \ -_35, \ -_36, \ -_37, \ -_38, \ -_39, \ -_40, \ -_41, \ -_42, \ -_43, \ -_44, \ -_45, \ -_46, \ -_47, \ -_48, \ -_49, \ -_50, \ -_51, \ -_52, \ -_53, \ -_54, \ -_55, \ -_56, \ -_57, \ -_58, \ -_59, \ -_60, \ -_61, \ -_62, \ -_63, \ -_64, \ -_65, \ -_66, \ -_67, \ -_68, \ -_69, \ -_70, \ -_71, \ -_72, \ -_73, \ -_74, \ -_75, \ -_76, \ -_77, \ -_78, \ -_79, \ -_80, \ -_81, \ -_82, \ -_83, \ -_84, \ -_85, \ -_86, \ -_87, \ -_88, \ -_89, \ -_90, \ -_91, \ -_92, \ -_93, \ -_94, \ -_95, \ -_96, \ -_97, \ -_98, \ -_99, \ -_100, \ -N, \ -... \ + _0, \ + _1, \ + _2, \ + _3, \ + _4, \ + _5, \ + _6, \ + _7, \ + _8, \ + _9, \ + _10, \ + _11, \ + _12, \ + _13, \ + _14, \ + _15, \ + _16, \ + _17, \ + _18, \ + _19, \ + _20, \ + _21, \ + _22, \ + _23, \ + _24, \ + _25, \ + _26, \ + _27, \ + _28, \ + _29, \ + _30, \ + _31, \ + _32, \ + _33, \ + _34, \ + _35, \ + _36, \ + _37, \ + _38, \ + _39, \ + _40, \ + _41, \ + _42, \ + _43, \ + _44, \ + _45, \ + _46, \ + _47, \ + _48, \ + _49, \ + _50, \ + _51, \ + _52, \ + _53, \ + _54, \ + _55, \ + _56, \ + _57, \ + _58, \ + _59, \ + _60, \ + _61, \ + _62, \ + _63, \ + _64, \ + _65, \ + _66, \ + _67, \ + _68, \ + _69, \ + _70, \ + _71, \ + _72, \ + _73, \ + _74, \ + _75, \ + _76, \ + _77, \ + _78, \ + _79, \ + _80, \ + _81, \ + _82, \ + _83, \ + _84, \ + _85, \ + _86, \ + _87, \ + _88, \ + _89, \ + _90, \ + _91, \ + _92, \ + _93, \ + _94, \ + _95, \ + _96, \ + _97, \ + _98, \ + _99, \ + _100, \ + N, \ + ... \ ) \ N // ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang) #define num_args( ... ) \ num_args_impl( \ - _, \ - ##__VA_ARGS__, \ - 100, \ - 99, \ - 98, \ - 97, \ - 96, \ - 95, \ - 94, \ - 93, \ - 92, \ - 91, \ - 90, \ - 89, \ - 88, \ - 87, \ - 86, \ - 85, \ - 84, \ - 83, \ - 82, \ - 81, \ - 80, \ - 79, \ - 78, \ - 77, \ - 76, \ - 75, \ - 74, \ - 73, \ - 72, \ - 71, \ - 70, \ - 69, \ - 68, \ - 67, \ - 66, \ - 65, \ - 64, \ - 63, \ - 62, \ - 61, \ - 60, \ - 59, \ - 58, \ - 57, \ - 56, \ - 55, \ - 54, \ - 53, \ - 52, \ - 51, \ - 50, \ - 49, \ - 48, \ - 47, \ - 46, \ - 45, \ - 44, \ - 43, \ - 42, \ - 41, \ - 40, \ - 39, \ - 38, \ - 37, \ - 36, \ - 35, \ - 34, \ - 33, \ - 32, \ - 31, \ - 30, \ - 29, \ - 28, \ - 27, \ - 26, \ - 25, \ - 24, \ - 23, \ - 22, \ - 21, \ - 20, \ - 19, \ - 18, \ - 17, \ - 16, \ - 15, \ - 14, \ - 13, \ - 12, \ - 11, \ - 10, \ - 9, \ - 8, \ - 7, \ - 6, \ - 5, \ - 4, \ - 3, \ - 2, \ - 1, \ - 0 \ + _, \ + ##__VA_ARGS__, \ + 100, \ + 99, \ + 98, \ + 97, \ + 96, \ + 95, \ + 94, \ + 93, \ + 92, \ + 91, \ + 90, \ + 89, \ + 88, \ + 87, \ + 86, \ + 85, \ + 84, \ + 83, \ + 82, \ + 81, \ + 80, \ + 79, \ + 78, \ + 77, \ + 76, \ + 75, \ + 74, \ + 73, \ + 72, \ + 71, \ + 70, \ + 69, \ + 68, \ + 67, \ + 66, \ + 65, \ + 64, \ + 63, \ + 62, \ + 61, \ + 60, \ + 59, \ + 58, \ + 57, \ + 56, \ + 55, \ + 54, \ + 53, \ + 52, \ + 51, \ + 50, \ + 49, \ + 48, \ + 47, \ + 46, \ + 45, \ + 44, \ + 43, \ + 42, \ + 41, \ + 40, \ + 39, \ + 38, \ + 37, \ + 36, \ + 35, \ + 34, \ + 33, \ + 32, \ + 31, \ + 30, \ + 29, \ + 28, \ + 27, \ + 26, \ + 25, \ + 24, \ + 23, \ + 22, \ + 21, \ + 20, \ + 19, \ + 18, \ + 17, \ + 16, \ + 15, \ + 14, \ + 13, \ + 12, \ + 11, \ + 10, \ + 9, \ + 8, \ + 7, \ + 6, \ + 5, \ + 4, \ + 3, \ + 2, \ + 1, \ + 0 \ ) // #else @@ -716,7 +716,7 @@ void process_exit( u32 code ); #define GEN__ONES ( zpl_cast( uw ) - 1 / GEN_U8_MAX ) #define GEN__HIGHS ( GEN__ONES * ( GEN_U8_MAX / 2 + 1 ) ) -#define GEN__HAS_ZERO( x ) ( ( ( x )-GEN__ONES ) & ~( x )&GEN__HIGHS ) +#define GEN__HAS_ZERO( x ) ( ( ( x )-GEN__ONES ) & ~( x ) & GEN__HIGHS ) //! Checks if value is power of 2. GEN_DEF_INLINE b32 is_power_of_two( sw x ); @@ -3931,10 +3931,10 @@ struct AST operator CodeVar(); #pragma endregion Member Functions - constexpr static int ArrSpecs_Cap = - ( AST_POD_Size - sizeof( AST* ) * 3 - sizeof( Parser::Token* ) - sizeof( AST* ) - sizeof( StringCached ) - sizeof( CodeT ) - sizeof( ModuleFlag ) - sizeof( int ) ) - / sizeof( int ) - - 1; // -1 for 4 extra bytes + constexpr static int ArrSpecs_Cap = ( AST_POD_Size - sizeof( AST* ) * 3 - sizeof( Parser::Token* ) - sizeof( AST* ) - sizeof( StringCached ) + - sizeof( CodeT ) - sizeof( ModuleFlag ) - sizeof( int ) ) + / sizeof( int ) + - 1; // -1 for 4 extra bytes union { @@ -5141,14 +5141,14 @@ CodeAttributes def_attributes( StrC content ); CodeComment def_comment( StrC content ); CodeClass def_class( -StrC name, -Code body = NoCode, -CodeType parent = NoCode, -AccessSpec access = AccessSpec::Default, -CodeAttributes attributes = NoCode, -ModuleFlag mflags = ModuleFlag::None, -CodeType* interfaces = nullptr, -s32 num_interfaces = 0 + StrC name, + Code body = NoCode, + CodeType parent = NoCode, + AccessSpec access = AccessSpec::Default, + CodeAttributes attributes = NoCode, + ModuleFlag mflags = ModuleFlag::None, + CodeType* interfaces = nullptr, + s32 num_interfaces = 0 ); CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode ); @@ -5158,12 +5158,12 @@ CodeDefine def_define( StrC name, StrC content ); CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = NoCode ); CodeEnum def_enum( -StrC name, -Code body = NoCode, -CodeType type = NoCode, -EnumT specifier = EnumRegular, -CodeAttributes attributes = NoCode, -ModuleFlag mflags = ModuleFlag::None + StrC name, + Code body = NoCode, + CodeType type = NoCode, + EnumT specifier = EnumRegular, + CodeAttributes attributes = NoCode, + ModuleFlag mflags = ModuleFlag::None ); CodeExec def_execution( StrC content ); @@ -5171,13 +5171,13 @@ CodeExtern def_extern_link( StrC name, Code body ); CodeFriend def_friend( Code symbol ); CodeFn def_function( -StrC name, -CodeParam params = NoCode, -CodeType ret_type = NoCode, -Code body = NoCode, -CodeSpecifiers specifiers = NoCode, -CodeAttributes attributes = NoCode, -ModuleFlag mflags = ModuleFlag::None + StrC name, + CodeParam params = NoCode, + CodeType ret_type = NoCode, + Code body = NoCode, + CodeSpecifiers specifiers = NoCode, + CodeAttributes attributes = NoCode, + ModuleFlag mflags = ModuleFlag::None ); CodeInclude def_include( StrC content, bool foreign = false ); @@ -5185,14 +5185,14 @@ CodeModule def_module( StrC name, ModuleFlag mflags = ModuleFlag::None ); CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); CodeOperator def_operator( -OperatorT op, -StrC nspace, -CodeParam params = NoCode, -CodeType ret_type = NoCode, -Code body = NoCode, -CodeSpecifiers specifiers = NoCode, -CodeAttributes attributes = NoCode, -ModuleFlag mflags = ModuleFlag::None + OperatorT op, + StrC nspace, + CodeParam params = NoCode, + CodeType ret_type = NoCode, + Code body = NoCode, + CodeSpecifiers specifiers = NoCode, + CodeAttributes attributes = NoCode, + ModuleFlag mflags = ModuleFlag::None ); CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode ); @@ -5205,14 +5205,14 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC content ); CodeSpecifiers def_specifier( SpecifierT specifier ); CodeStruct def_struct( -StrC name, -Code body = NoCode, -CodeType parent = NoCode, -AccessSpec access = AccessSpec::Default, -CodeAttributes attributes = NoCode, -ModuleFlag mflags = ModuleFlag::None, -CodeType* interfaces = nullptr, -s32 num_interfaces = 0 + StrC name, + Code body = NoCode, + CodeType parent = NoCode, + AccessSpec access = AccessSpec::Default, + CodeAttributes attributes = NoCode, + ModuleFlag mflags = ModuleFlag::None, + CodeType* interfaces = nullptr, + s32 num_interfaces = 0 ); CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None ); @@ -5227,12 +5227,12 @@ CodeUsing def_using( StrC name, CodeType type = NoCode, CodeAttributes attribute CodeUsing def_using_namespace( StrC name ); CodeVar def_variable( -CodeType type, -StrC name, -Code value = NoCode, -CodeSpecifiers specifiers = NoCode, -CodeAttributes attributes = NoCode, -ModuleFlag mflags = ModuleFlag::None + CodeType type, + StrC name, + Code value = NoCode, + CodeSpecifiers specifiers = NoCode, + CodeAttributes attributes = NoCode, + ModuleFlag mflags = ModuleFlag::None ); // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. @@ -8882,10 +8882,10 @@ internal sw _scan_zpl_i64( const char* text, s32 base, s64* value ) // TODO : Are these good enough for characters? global const char _num_to_char_table[] = -"0123456789" -"ABCDEFGHIJKLMNOPQRSTUVWXYZ" -"abcdefghijklmnopqrstuvwxyz" -"@$"; + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "@$"; s64 str_to_i64( const char* str, char** end_ptr, s32 base ) { @@ -9752,7 +9752,7 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali switch ( type ) { #if defined( GEN_COMPILER_MSVC ) || ( defined( GEN_COMPILER_GCC ) && defined( GEN_SYSTEM_WINDOWS ) ) \ -|| ( defined( GEN_COMPILER_TINYC ) && defined( GEN_SYSTEM_WINDOWS ) ) + || ( defined( GEN_COMPILER_TINYC ) && defined( GEN_SYSTEM_WINDOWS ) ) case EAllocation_ALLOC : ptr = _aligned_malloc( size, alignment ); if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO ) @@ -11022,13 +11022,13 @@ u64 read_cpu_time_stamp_counter( void ) u64 result = 0; u32 upper, lower, tmp; __asm__ volatile( - "0: \n" - "\tmftbu %0 \n" - "\tmftb %1 \n" - "\tmftbu %2 \n" - "\tcmpw %2,%0 \n" - "\tbne 0b \n" - : "=r"( upper ), "=r"( lower ), "=r"( tmp ) + "0: \n" + "\tmftbu %0 \n" + "\tmftb %1 \n" + "\tmftbu %2 \n" + "\tcmpw %2,%0 \n" + "\tbne 0b \n" + : "=r"( upper ), "=r"( lower ), "=r"( tmp ) ); result = upper; result = result << 32; @@ -13569,7 +13569,10 @@ String AST::to_string() if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export ) ) result.append( "export " ); - result.append_fmt( "template< %S >\n%S", Params->to_string(), Declaration->to_string() ); + if ( Params ) + result.append_fmt( "template< %S >\n%S", Params->to_string(), Declaration->to_string() ); + else + result.append_fmt( "template<>\n%S", Declaration->to_string() ); } break; @@ -13879,94 +13882,94 @@ bool AST::is_equal( AST* other ) { using namespace ECode; -#define check_member_val( val ) \ - if ( val != other->val ) \ - { \ - log_fmt( \ - "\nAST::is_equal: Member - " #val \ - " failed\n" \ - "AST : %S\n" \ - "Other: %S\n", \ - debug_str(), \ - other->debug_str() \ - ); \ - \ - return false; \ +#define check_member_val( val ) \ + if ( val != other->val ) \ + { \ + log_fmt( \ + "\nAST::is_equal: Member - " #val \ + " failed\n" \ + "AST : %S\n" \ + "Other: %S\n", \ + debug_str(), \ + other->debug_str() \ + ); \ + \ + return false; \ } -#define check_member_str( str ) \ - if ( str != other->str ) \ - { \ - log_fmt( \ - "\nAST::is_equal: Member string - " #str \ - " failed\n" \ - "AST : %S\n" \ - "Other: %S\n", \ - debug_str(), \ - other->debug_str() \ - ); \ - \ - return false; \ +#define check_member_str( str ) \ + if ( str != other->str ) \ + { \ + log_fmt( \ + "\nAST::is_equal: Member string - " #str \ + " failed\n" \ + "AST : %S\n" \ + "Other: %S\n", \ + debug_str(), \ + other->debug_str() \ + ); \ + \ + return false; \ } -#define check_member_content( content ) \ - if ( content != other->content ) \ - { \ - log_fmt( \ - "\nAST::is_equal: Member content - " #content \ - " failed\n" \ - "AST : %S\n" \ - "Other: %S\n", \ - debug_str(), \ - other->debug_str() \ - ); \ - \ - log_fmt( \ - "Content cannot be trusted to be unique with this check " \ - "so it must be verified by eye for now\n" \ - "AST Content:\n%S\n" \ - "Other Content:\n%S\n", \ - content.visualize_whitespace(), \ - other->content.visualize_whitespace() \ - ); \ +#define check_member_content( content ) \ + if ( content != other->content ) \ + { \ + log_fmt( \ + "\nAST::is_equal: Member content - " #content \ + " failed\n" \ + "AST : %S\n" \ + "Other: %S\n", \ + debug_str(), \ + other->debug_str() \ + ); \ + \ + log_fmt( \ + "Content cannot be trusted to be unique with this check " \ + "so it must be verified by eye for now\n" \ + "AST Content:\n%S\n" \ + "Other Content:\n%S\n", \ + content.visualize_whitespace(), \ + other->content.visualize_whitespace() \ + ); \ } -#define check_member_ast( ast ) \ - if ( ast ) \ - { \ - if ( other->ast == nullptr ) \ - { \ - log_fmt( \ - "\nAST::is_equal: Failed for member " #ast \ - " other equivalent param is null\n" \ - "AST : %s\n" \ - "Other: %s\n" \ - "For ast member: %s\n", \ - debug_str(), \ - other->debug_str(), \ - ast->debug_str() \ - ); \ - \ - return false; \ - } \ - \ - if ( ! ast->is_equal( other->ast ) ) \ - { \ - log_fmt( \ - "\nAST::is_equal: Failed for " #ast \ - "\n" \ - "AST : %S\n" \ - "Other: %S\n" \ - "For ast member: %S\n" \ - "other's ast member: %S\n", \ - debug_str(), \ - other->debug_str(), \ - ast->debug_str(), \ - other->ast->debug_str() \ - ); \ - \ - return false; \ - } \ +#define check_member_ast( ast ) \ + if ( ast ) \ + { \ + if ( other->ast == nullptr ) \ + { \ + log_fmt( \ + "\nAST::is_equal: Failed for member " #ast \ + " other equivalent param is null\n" \ + "AST : %s\n" \ + "Other: %s\n" \ + "For ast member: %s\n", \ + debug_str(), \ + other->debug_str(), \ + ast->debug_str() \ + ); \ + \ + return false; \ + } \ + \ + if ( ! ast->is_equal( other->ast ) ) \ + { \ + log_fmt( \ + "\nAST::is_equal: Failed for " #ast \ + "\n" \ + "AST : %S\n" \ + "Other: %S\n" \ + "For ast member: %S\n" \ + "other's ast member: %S\n", \ + debug_str(), \ + other->debug_str(), \ + ast->debug_str(), \ + other->ast->debug_str() \ + ); \ + \ + return false; \ + } \ } case NewLine : @@ -14187,11 +14190,11 @@ bool AST::is_equal( AST* other ) if ( curr_other == nullptr ) { log_fmt( - "\nAST::is_equal: Failed for parameter, other equivalent param is null\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n", - curr->debug_str() + "\nAST::is_equal: Failed for parameter, other equivalent param is null\n" + "AST : %S\n" + "Other: %S\n" + "For ast member: %S\n", + curr->debug_str() ); return false; @@ -14200,15 +14203,15 @@ bool AST::is_equal( AST* other ) if ( curr->Name != curr_other->Name ) { log_fmt( - "\nAST::is_equal: Failed for parameter name check\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n", - debug_str(), - other->debug_str(), - curr->debug_str(), - curr_other->debug_str() + "\nAST::is_equal: Failed for parameter name check\n" + "AST : %S\n" + "Other: %S\n" + "For ast member: %S\n" + "other's ast member: %S\n", + debug_str(), + other->debug_str(), + curr->debug_str(), + curr_other->debug_str() ); return false; } @@ -14216,15 +14219,15 @@ bool AST::is_equal( AST* other ) if ( curr->ValueType && ! curr->ValueType->is_equal( curr_other->ValueType ) ) { log_fmt( - "\nAST::is_equal: Failed for parameter value type check\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n", - debug_str(), - other->debug_str(), - curr->debug_str(), - curr_other->debug_str() + "\nAST::is_equal: Failed for parameter value type check\n" + "AST : %S\n" + "Other: %S\n" + "For ast member: %S\n" + "other's ast member: %S\n", + debug_str(), + other->debug_str(), + curr->debug_str(), + curr_other->debug_str() ); return false; } @@ -14232,15 +14235,15 @@ bool AST::is_equal( AST* other ) if ( curr->Value && ! curr->Value->is_equal( curr_other->Value ) ) { log_fmt( - "\nAST::is_equal: Failed for parameter value check\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n", - debug_str(), - other->debug_str(), - curr->debug_str(), - curr_other->debug_str() + "\nAST::is_equal: Failed for parameter value check\n" + "AST : %S\n" + "Other: %S\n" + "For ast member: %S\n" + "other's ast member: %S\n", + debug_str(), + other->debug_str(), + curr->debug_str(), + curr_other->debug_str() ); return false; } @@ -14383,11 +14386,11 @@ bool AST::is_equal( AST* other ) if ( curr_other == nullptr ) { log_fmt( - "\nAST::is_equal: Failed for body, other equivalent param is null\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n", - curr->debug_str() + "\nAST::is_equal: Failed for body, other equivalent param is null\n" + "AST : %S\n" + "Other: %S\n" + "For ast member: %S\n", + curr->debug_str() ); return false; @@ -14396,15 +14399,15 @@ bool AST::is_equal( AST* other ) if ( ! curr->is_equal( curr_other ) ) { log_fmt( - "\nAST::is_equal: Failed for body\n" - "AST : %S\n" - "Other: %S\n" - "For ast member: %S\n" - "other's ast member: %S\n", - debug_str(), - other->debug_str(), - curr->debug_str(), - curr_other->debug_str() + "\nAST::is_equal: Failed for body\n" + "AST : %S\n" + "Other: %S\n" + "For ast member: %S\n" + "other's ast member: %S\n", + debug_str(), + other->debug_str(), + curr->debug_str(), + curr_other->debug_str() ); return false; @@ -14696,6 +14699,11 @@ internal void define_constants() #endif #undef def_constant_code_type + +#define def_constant_spec( Type_, ... ) \ + spec_##Type_ = def_specifiers( num_args( __VA_ARGS__ ), __VA_ARGS__ ); \ + spec_##Type_.set_global(); + #pragma push_macro( "forceinline" ) #pragma push_macro( "global" ) #pragma push_macro( "internal" ) @@ -14706,11 +14714,6 @@ internal void define_constants() #undef internal #undef local_persist #undef neverinline - -#define def_constant_spec( Type_, ... ) \ - spec_##Type_ = def_specifiers( num_args( __VA_ARGS__ ), __VA_ARGS__ ); \ - spec_##Type_.set_global(); - def_constant_spec( const, ESpecifier::Const ); def_constant_spec( consteval, ESpecifier::Consteval ); def_constant_spec( constexpr, ESpecifier::Constexpr ); @@ -14735,7 +14738,7 @@ internal void define_constants() def_constant_spec( virtual, ESpecifier::Virtual ); def_constant_spec( volatile, ESpecifier::Volatile ) - spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); + spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); spec_local_persist.set_global(); #pragma pop_macro( "forceinline" ) @@ -15004,18 +15007,18 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy return OpValidateResult::Fail; \ } -#define check_param_eq_ret() \ - if ( ! is_member_symbol && params_code->ValueType != ret_type ) \ - { \ - log_failure( \ - "gen_def_operator: operator%s requires first parameter to equal return type\n" \ - "param types: %s\n" \ - "return type: %s", \ - to_str( op ), \ - params_code.debug_str(), \ - ret_type.debug_str() \ - ); \ - return OpValidateResult::Fail; \ +#define check_param_eq_ret() \ + if ( ! is_member_symbol && ! params_code->ValueType.is_equal( ret_type ) ) \ + { \ + log_failure( \ + "gen::def_operator: operator%s requires first parameter to equal return type\n" \ + "param types: %s\n" \ + "return type: %s", \ + to_str( op ).Ptr, \ + params_code.debug_str(), \ + ret_type.debug_str() \ + ); \ + return OpValidateResult::Fail; \ } #pragma endregion Helper Macros @@ -15041,10 +15044,10 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( params_code->NumEntries > 1 ) { log_failure( - "gen::def_operator: " - "operator%s does not support non-member definition (more than one parameter provided) - %s", - to_str( op ), - params_code.debug_str() + "gen::def_operator: " + "operator%s does not support non-member definition (more than one parameter provided) - %s", + to_str( op ), + params_code.debug_str() ); return OpValidateResult::Fail; } @@ -15073,10 +15076,10 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( params_code->NumEntries > 2 ) { log_failure( - "gen::def_operator: operator%s may not be defined with more than two parametes - param count; %d\n%s", - to_str( op ), - params_code->NumEntries, - params_code.debug_str() + "gen::def_operator: operator%s may not be defined with more than two parametes - param count; %d\n%s", + to_str( op ), + params_code->NumEntries, + params_code.debug_str() ); return OpValidateResult::Fail; } @@ -15109,9 +15112,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( ! params_code.get( 1 ).is_equal( t_int ) ) { log_failure( - "gen::def_operator: " - "operator%s requires second parameter of non-member definition to be int for post-decrement", - to_str( op ) + "gen::def_operator: " + "operator%s requires second parameter of non-member definition to be int for post-decrement", + to_str( op ) ); return OpValidateResult::Fail; } @@ -15119,9 +15122,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy default : log_failure( - "gen::def_operator: operator%s recieved unexpected number of parameters recived %d instead of 0-2", - to_str( op ), - params_code->NumEntries + "gen::def_operator: operator%s recieved unexpected number of parameters recived %d instead of 0-2", + to_str( op ), + params_code->NumEntries ); return OpValidateResult::Fail; } @@ -15145,12 +15148,12 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( params_code->ValueType.is_equal( ret_type ) ) { log_failure( - "gen::def_operator: " - "operator%s is non-member symbol yet first paramter does not equal return type\n" - "param type: %s\n" - "return type: %s\n", - params_code.debug_str(), - ret_type.debug_str() + "gen::def_operator: " + "operator%s is non-member symbol yet first paramter does not equal return type\n" + "param type: %s\n" + "return type: %s\n", + params_code.debug_str(), + ret_type.debug_str() ); return OpValidateResult::Fail; } @@ -15158,9 +15161,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( params_code->NumEntries > 1 ) { log_failure( - "gen::def_operator: operator%s may not have more than one parameter - param count: %d", - to_str( op ), - params_code->NumEntries + "gen::def_operator: operator%s may not have more than one parameter - param count: %d", + to_str( op ), + params_code->NumEntries ); return OpValidateResult::Fail; } @@ -15189,12 +15192,12 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( ! params_code->ValueType.is_equal( ret_type ) ) { log_failure( - "gen::def_operator: " - "operator%s is non-member symbol yet first paramter does not equal return type\n" - "param type: %s\n" - "return type: %s\n", - params_code.debug_str(), - ret_type.debug_str() + "gen::def_operator: " + "operator%s is non-member symbol yet first paramter does not equal return type\n" + "param type: %s\n" + "return type: %s\n", + params_code.debug_str(), + ret_type.debug_str() ); return OpValidateResult::Fail; } @@ -15202,9 +15205,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy default : log_failure( - "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-2", - to_str( op ), - params_code->NumEntries + "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-2", + to_str( op ), + params_code->NumEntries ); return OpValidateResult::Fail; } @@ -15225,9 +15228,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( params_code->NumEntries != 1 ) { log_failure( - "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-1", - to_str( op ), - params_code->NumEntries + "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-1", + to_str( op ), + params_code->NumEntries ); return OpValidateResult::Fail; } @@ -15261,9 +15264,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy default : log_failure( - "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 1-2", - to_str( op ), - params_code->NumEntries + "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 1-2", + to_str( op ), + params_code->NumEntries ); return OpValidateResult::Fail; } @@ -15275,9 +15278,9 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy if ( params_code && params_code->NumEntries > 1 ) { log_failure( - "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-1", - to_str( op ), - params_code->NumEntries + "gen::def_operator: operator%s recieved unexpected number of paramters recived %d instead of 0-1", + to_str( op ), + params_code->NumEntries ); return OpValidateResult::Fail; } @@ -15473,14 +15476,14 @@ CodeConstructor def_constructor( CodeParam params, Code initializer_list, Code b } CodeClass def_class( -StrC name, -Code body, -CodeType parent, -AccessSpec parent_access, -CodeAttributes attributes, -ModuleFlag mflags, -CodeType* interfaces, -s32 num_interfaces + StrC name, + Code body, + CodeType parent, + AccessSpec parent_access, + CodeAttributes attributes, + ModuleFlag mflags, + CodeType* interfaces, + s32 num_interfaces ) { using namespace ECode; @@ -15864,14 +15867,14 @@ CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags ) } CodeOperator def_operator( -OperatorT op, -StrC nspace, -CodeParam params_code, -CodeType ret_type, -Code body, -CodeSpecifiers specifiers, -CodeAttributes attributes, -ModuleFlag mflags + OperatorT op, + StrC nspace, + CodeParam params_code, + CodeType ret_type, + Code body, + CodeSpecifiers specifiers, + CodeAttributes attributes, + ModuleFlag mflags ) { using namespace ECode; @@ -15905,6 +15908,7 @@ ModuleFlag mflags CodeOperator result = ( CodeOperator )make_code(); result->Name = get_cached_string( { str_len( name ), name } ); result->ModuleFlags = mflags; + result->Op = op; if ( body ) { @@ -16076,14 +16080,14 @@ CodeSpecifiers def_specifier( SpecifierT spec ) } CodeStruct def_struct( -StrC name, -Code body, -CodeType parent, -AccessSpec parent_access, -CodeAttributes attributes, -ModuleFlag mflags, -CodeType* interfaces, -s32 num_interfaces + StrC name, + Code body, + CodeType parent, + AccessSpec parent_access, + CodeAttributes attributes, + ModuleFlag mflags, + CodeType* interfaces, + s32 num_interfaces ) { using namespace ECode; @@ -16445,9 +16449,9 @@ CodeBody def_class_body( s32 num, ... ) if ( ! entry ) { log_failure( - "gen::" - "def_class_body" - ": Provided an null entry" + "gen::" + "def_class_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16456,10 +16460,10 @@ CodeBody def_class_body( s32 num, ... ) { GEN_AST_BODY_CLASS_UNALLOWED_TYPES log_failure( - "gen::" - "def_class_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_class_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16489,9 +16493,9 @@ CodeBody def_class_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_class_body" - ": Provided an null entry" + "gen::" + "def_class_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16500,10 +16504,10 @@ CodeBody def_class_body( s32 num, Code* codes ) { GEN_AST_BODY_CLASS_UNALLOWED_TYPES log_failure( - "gen::" - "def_class_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_class_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16596,9 +16600,9 @@ CodeBody def_export_body( s32 num, ... ) if ( ! entry ) { log_failure( - "gen::" - "def_export_body" - ": Provided an null entry" + "gen::" + "def_export_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16607,10 +16611,10 @@ CodeBody def_export_body( s32 num, ... ) { GEN_AST_BODY_EXPORT_UNALLOWED_TYPES log_failure( - "gen::" - "def_export_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_export_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16640,9 +16644,9 @@ CodeBody def_export_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_export_body" - ": Provided an null entry" + "gen::" + "def_export_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16651,10 +16655,10 @@ CodeBody def_export_body( s32 num, Code* codes ) { GEN_AST_BODY_EXPORT_UNALLOWED_TYPES log_failure( - "gen::" - "def_export_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_export_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16685,9 +16689,9 @@ CodeBody def_extern_link_body( s32 num, ... ) if ( ! entry ) { log_failure( - "gen::" - "def_extern_linkage_body" - ": Provided an null entry" + "gen::" + "def_extern_linkage_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16696,10 +16700,10 @@ CodeBody def_extern_link_body( s32 num, ... ) { GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES log_failure( - "gen::" - "def_extern_linkage_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_extern_linkage_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16729,9 +16733,9 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_extern_linkage_body" - ": Provided an null entry" + "gen::" + "def_extern_linkage_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16740,10 +16744,10 @@ CodeBody def_extern_link_body( s32 num, Code* codes ) { GEN_AST_BODY_EXTERN_LINKAGE_UNALLOWED_TYPES log_failure( - "gen::" - "def_extern_linkage_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_extern_linkage_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16811,9 +16815,9 @@ CodeBody def_function_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_function_body" - ": Provided an null entry" + "gen::" + "def_function_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16822,10 +16826,10 @@ CodeBody def_function_body( s32 num, Code* codes ) { GEN_AST_BODY_FUNCTION_UNALLOWED_TYPES log_failure( - "gen::" - "def_function_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_function_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16855,9 +16859,9 @@ CodeBody def_global_body( s32 num, ... ) if ( ! entry ) { log_failure( - "gen::" - "def_global_body" - ": Provided an null entry" + "gen::" + "def_global_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16870,10 +16874,10 @@ CodeBody def_global_body( s32 num, ... ) GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES log_failure( - "gen::" - "def_global_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_global_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return ( *Code::Invalid.ast ); @@ -16903,9 +16907,9 @@ CodeBody def_global_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_global_body" - ": Provided an null entry" + "gen::" + "def_global_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16918,10 +16922,10 @@ CodeBody def_global_body( s32 num, Code* codes ) GEN_AST_BODY_GLOBAL_UNALLOWED_TYPES log_failure( - "gen::" - "def_global_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_global_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16952,9 +16956,9 @@ CodeBody def_namespace_body( s32 num, ... ) if ( ! entry ) { log_failure( - "gen::" - "def_namespace_body" - ": Provided an null entry" + "gen::" + "def_namespace_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -16963,10 +16967,10 @@ CodeBody def_namespace_body( s32 num, ... ) { GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES log_failure( - "gen::" - "def_namespace_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_namespace_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -16996,9 +17000,9 @@ CodeBody def_namespace_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_namespace_body" - ": Provided an null entry" + "gen::" + "def_namespace_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -17007,10 +17011,10 @@ CodeBody def_namespace_body( s32 num, Code* codes ) { GEN_AST_BODY_NAMESPACE_UNALLOWED_TYPES log_failure( - "gen::" - "def_namespace_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_namespace_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -17171,9 +17175,9 @@ CodeBody def_struct_body( s32 num, ... ) if ( ! entry ) { log_failure( - "gen::" - "def_struct_body" - ": Provided an null entry" + "gen::" + "def_struct_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -17182,10 +17186,10 @@ CodeBody def_struct_body( s32 num, ... ) { GEN_AST_BODY_STRUCT_UNALLOWED_TYPES log_failure( - "gen::" - "def_struct_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_struct_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -17215,9 +17219,9 @@ CodeBody def_struct_body( s32 num, Code* codes ) if ( ! entry ) { log_failure( - "gen::" - "def_struct_body" - ": Provided an null entry" + "gen::" + "def_struct_body" + ": Provided an null entry" ); return CodeInvalid; } @@ -17226,10 +17230,10 @@ CodeBody def_struct_body( s32 num, Code* codes ) { GEN_AST_BODY_STRUCT_UNALLOWED_TYPES log_failure( - "gen::" - "def_struct_body" - ": Entry type is not allowed: %s", - entry.debug_str() + "gen::" + "def_struct_body" + ": Entry type is not allowed: %s", + entry.debug_str() ); return CodeInvalid; @@ -17779,13 +17783,13 @@ namespace Parser if ( Arr[ Idx ].Type != type ) { log_failure( - "Parse Error, TokArray::eat, Expected: ' %s ' not ' %.*s ' (%d, %d)`\n%s", - ETokType::to_str( type ).Ptr, - Arr[ Idx ].Length, - Arr[ Idx ].Text, - current().Line, - current().Column, - Context.to_string() + "Parse Error, TokArray::eat, Expected: ' %s ' not ' %.*s ' (%d, %d)`\n%s", + ETokType::to_str( type ).Ptr, + Arr[ Idx ].Length, + Arr[ Idx ].Text, + current().Line, + current().Column, + Context.to_string() ); return false; @@ -17958,14 +17962,14 @@ namespace Parser else { log_failure( - "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)" - " in preprocessor directive (%d, %d)\n%.100s", - current, - line, - column, - token.Line, - token.Column, - token.Text + "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)" + " in preprocessor directive (%d, %d)\n%.100s", + current, + line, + column, + token.Line, + token.Column, + token.Text ); break; } @@ -18042,11 +18046,11 @@ namespace Parser String directive_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 80, left + content.Length ), token.Text ); log_failure( - "gen::Parser::lex: Expected '\"' or '<' after #include, not '%c' (%d, %d)\n%s", - current, - content.Line, - content.Column, - directive_str.Data + "gen::Parser::lex: Expected '\"' or '<' after #include, not '%c' (%d, %d)\n%s", + current, + content.Line, + content.Column, + directive_str.Data ); return { { nullptr }, 0 }; } @@ -18101,15 +18105,15 @@ namespace Parser String content_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 400, left + content.Length ), content.Text ); log_failure( - "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)" - " in preprocessor directive '%s' (%d, %d)\n%s", - current, - line, - column, - directive_str, - content.Line, - content.Column, - content_str + "gen::Parser::lex: Invalid escape sequence '\\%c' (%d, %d)" + " in preprocessor directive '%s' (%d, %d)\n%s", + current, + line, + column, + directive_str, + content.Line, + content.Column, + content_str ); break; } @@ -18323,6 +18327,18 @@ namespace Parser if ( left ) move_forward(); + + if ( current == '=' ) + { + token.Length++; + token.IsAssign = true; + // token.Flags |= TokFlags::Assignment; + // token.Type = TokType::Assign_Multiply; + + if ( left ) + move_forward(); + } + goto FoundToken; } case ';' : @@ -18518,7 +18534,14 @@ namespace Parser if ( left ) { - if ( current == '/' ) + if ( current == '=' ) + { + // token.Type = TokeType::Assign_Divide; + move_forward(); + token.Length++; + token.IsAssign = true; + } + else if ( current == '/' ) { token.Type = TokType::Comment; token.Length = 2; @@ -19794,9 +19817,9 @@ internal inline Code parse_foward_or_definition( Parser::TokType which, bool is_ default : log_failure( - "Error, wrong token type given to parse_complicated_definition " - "(only supports class, enum, struct, union) \n%s", - Context.to_string() + "Error, wrong token type given to parse_complicated_definition " + "(only supports class, enum, struct, union) \n%s", + Context.to_string() ); Context.pop(); @@ -19808,7 +19831,7 @@ internal inline Code parse_foward_or_definition( Parser::TokType which, bool is_ // Function parsing is handled in multiple places because its initial signature is shared with variable parsing internal inline CodeFn -parse_function_after_name( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType ret_type, Parser::Token name ) + parse_function_after_name( ModuleFlag mflags, CodeAttributes attributes, CodeSpecifiers specifiers, CodeType ret_type, Parser::Token name ) { using namespace Parser; push_scope(); @@ -20302,7 +20325,8 @@ internal CodeOperator parse_operator_after_ret_type( ModuleFlag mflags, CodeAttr eat( TokType::Decl_Operator ); - if ( ! left && currtok.Type != TokType::Operator && currtok.Type != TokType::Star && currtok.Type != TokType::Ampersand && currtok.Type != TokType::Ampersand_DBL ) + if ( ! left && currtok.Type != TokType::Operator && currtok.Type != TokType::Star && currtok.Type != TokType::Ampersand + && currtok.Type != TokType::Ampersand_DBL ) { log_failure( "Expected operator after 'operator' keyword\n%s", Context.to_string() ); Context.pop(); @@ -20319,7 +20343,7 @@ internal CodeOperator parse_operator_after_ret_type( ModuleFlag mflags, CodeAttr if ( currtok.Text[ 1 ] == '=' ) op = Assign_Add; - if ( currtok.Text[ 1 ] == '+' ) + else if ( currtok.Text[ 1 ] == '+' ) op = Increment; else @@ -20339,7 +20363,7 @@ internal CodeOperator parse_operator_after_ret_type( ModuleFlag mflags, CodeAttr break; } - if ( currtok.Text[ 1 ] == '=' ) + else if ( currtok.Text[ 1 ] == '=' ) op = Assign_Subtract; else @@ -20691,6 +20715,12 @@ internal inline CodeParam parse_params( bool use_template_capture ) Context.pop(); return { nullptr }; } + else if ( check( TokType::Operator ) && currtok.Text[ 0 ] == '>' ) + { + eat( TokType::Operator ); + Context.pop(); + return { nullptr }; + } CodeType type = { nullptr }; Code value = { nullptr }; @@ -21860,11 +21890,11 @@ internal CodeOperator parse_operator() default : log_failure( - "Invalid specifier " - "%s" - " for operator\n%s", - ESpecifier::to_str( spec ), - Context.to_string() + "Invalid specifier " + "%s" + " for operator\n%s", + ESpecifier::to_str( spec ), + Context.to_string() ); Context.pop(); return CodeInvalid; @@ -22227,7 +22257,8 @@ internal CodeType parse_type( bool* typedef_is_function ) } // All kinds of nonsense can makeup a type signature, first we check for a in-place definition of a class, enum, or struct - if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct || currtok.Type == TokType::Decl_Union ) + if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct + || currtok.Type == TokType::Decl_Union ) { name = currtok; eat( currtok.Type ); @@ -22479,10 +22510,10 @@ internal CodeType parse_type( bool* typedef_is_function ) { SpecifierT spec = ESpecifier::to_type( currtok ); - if ( spec != ESpecifier::Const - // TODO : Add support for NoExcept - // && spec != ESpecifier::NoExcept - && spec != ESpecifier::RValue ) + if ( spec != ESpecifier::Const + // TODO : Add support for NoExcept + // && spec != ESpecifier::NoExcept + && spec != ESpecifier::RValue ) { log_failure( "Error, invalid specifier used in type definition: %s\n%s", currtok.Text, Context.to_string() ); Context.pop(); @@ -22619,7 +22650,7 @@ internal CodeTypedef parse_typedef() else { bool is_complicated = currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Struct - || currtok.Type == TokType::Decl_Union; + || currtok.Type == TokType::Decl_Union; if ( is_complicated ) { diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index 2d5d03b..efe1852 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -188,26 +188,23 @@ void output_sound( EngineState* state, AudioBuffer* sound_buffer, GetSoundSample internal void draw_rectangle( OffscreenBuffer* buffer - , f32 min_x, f32 min_y - , f32 max_x, f32 max_y + , Vec2 min, Vec2 max , f32 red, f32 green, f32 blue ) { - s32 min_x_32 = round( min_x ); - s32 min_y_32 = round( min_y ); - s32 max_x_32 = round( max_x ); - s32 max_y_32 = round( max_y ); + Vec2i min_rounded { round(min.x), round(min.y) }; + Vec2i max_rounded { round(max.x), round(max.y) }; - s32 buffer_width = buffer->width; - s32 buffer_height = buffer->height; + s32 width = buffer->width; + s32 height = buffer->height; - if ( min_x_32 < 0 ) - min_x_32 = 0; - if ( min_y_32 < 0 ) - min_y_32 = 0; - if ( max_x_32 > buffer_width ) - max_x_32 = buffer_width; - if ( max_y_32 > buffer_height ) - max_y_32 = buffer_height; + if ( min_rounded.x < 0 ) + min_rounded.x = 0; + if ( min_rounded.y < 0 ) + min_rounded.y = 0; + if ( max_rounded.x > width ) + max_rounded.x = width; + if ( max_rounded.y > height ) + max_rounded.y = height; s32 red_32 = round( 255.f * red ); s32 green_32 = round( 255.f * green ); @@ -220,14 +217,14 @@ void draw_rectangle( OffscreenBuffer* buffer // Start with the pixel on the top left corner of the rectangle u8* row = rcast(u8*, buffer->memory ) - + min_x_32 * buffer->bytes_per_pixel - + min_y_32 * buffer->pitch; + + min_rounded.x * buffer->bytes_per_pixel + + min_rounded.y * buffer->pitch; - for ( s32 y = min_y_32; y < max_y_32; ++ y ) + for ( s32 y = min_rounded.y; y < max_rounded.y; ++ y ) { s32* pixel_32 = rcast(s32*, row); - for ( s32 x = min_x_32; x < max_x_32; ++ x ) + for ( s32 x = min_rounded.x; x < max_rounded.x; ++ x ) { *pixel_32 = color; pixel_32++; @@ -237,45 +234,46 @@ void draw_rectangle( OffscreenBuffer* buffer } internal -void draw_bitmap( OffscreenBuffer* buffer - , f32 pos_x, f32 pos_y - , Bitmap* bitmap ) +void draw_bitmap( OffscreenBuffer* buffer, Vec2 pos, Bitmap* bitmap ) { s32 half_width = bitmap->width / 2; s32 half_height = bitmap->height / 2; + + Vec2i pos_rounded { round(pos.x), round(pos.y) }; + Vec2i bmp_half_size { bitmap->width / 2, bitmap->height / 2 }; + Vec2i min = pos_rounded - bmp_half_size; + Vec2i max = pos_rounded + bmp_half_size; + + s32 max_x = round( pos.x ) + half_width; + s32 max_y = round( pos.y ) + half_height; - s32 min_x = round( pos_x ) - half_width; - s32 min_y = round( pos_y ) - half_height; - s32 max_x = round( pos_x ) + half_width; - s32 max_y = round( pos_y ) + half_height; + s32 bmp_offset_x = min.x < 0 ? min.x * -1 : 0; + u32 bmp_offset_y = min.y < 0 ? bitmap->height + min.y - 1 : bitmap->height - 1; - s32 bmp_offset_x = min_x < 0 ? min_x * -1 : 0; - u32 bmp_offset_y = min_y < 0 ? bitmap->height + min_y - 1 : bitmap->height - 1; + s32 width = buffer->width; + s32 height = buffer->height; - s32 buffer_width = buffer->width; - s32 buffer_height = buffer->height; - - if ( min_x < 0 ) - min_x = 0; - if ( min_y < 0 ) - min_y = 0; - if ( max_x > buffer_width ) - max_x = buffer_width; - if ( max_y > buffer_height ) - max_y = buffer_height; + if ( min.x < 0 ) + min.x = 0; + if ( min.y < 0 ) + min.y = 0; + if ( max.x > width ) + max.x = width; + if ( max.y > height ) + max.y = height; // Start with the pixel on the top left corner of the rectangle u8* dst_row = rcast(u8*, buffer->memory ) - + min_x * buffer->bytes_per_pixel - + min_y * buffer->pitch; + + min.x * buffer->bytes_per_pixel + + min.y * buffer->pitch; u32* src_row = bitmap->pixels + bitmap->width * bmp_offset_y; - for ( s32 y = min_y; y < max_y; ++ y ) + for ( s32 y = min.y; y < max.y; ++ y ) { u32* dst = rcast(u32*, dst_row); u32* src = src_row + bmp_offset_x; - for ( s32 x = min_x; x < max_x; ++ x ) + for ( s32 x = min.x; x < max.x; ++ x ) { #define extract( pixel, shift ) (( *pixel >> shift ) & 0xFF) f32 alpha = scast(f32, extract(src, 24)) / 255.f; @@ -305,16 +303,22 @@ void draw_bitmap( OffscreenBuffer* buffer } inline -void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPosition pos, f32 red, f32 green, f32 blue) +void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPos pos, f32 red, f32 green, f32 blue) { TileMap* tile_map = world->tile_map; + + Vec2 min { + pos.rel_pos.x * world->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels), + pos.rel_pos.y * world->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels) + }; + Vec2 max { + (pos.rel_pos.x + 0.1f) * world->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels), + (pos.rel_pos.y + 0.1f) * world->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels) + }; - draw_rectangle(back_buffer, - pos.x * world->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels), - pos.y * world->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels), - (pos.x + 0.1f) * world->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels), - (pos.y + 0.1f) * world->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels), - red, green, blue); + draw_rectangle(back_buffer + , min, max + , red, green, blue); } internal @@ -702,10 +706,10 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* game_state->camera_pos.tile_y = state->world->tiles_per_screen_y / 2; hh::PlayerState* player = & game_state->player_state; - player->position.tile_x = 4; - player->position.tile_y = 4; - player->position.x = 0.f; - player->position.y = 0.f; + player->position.tile_x = 4; + player->position.tile_y = 4; + player->position.rel_pos.x = 0.f; + player->position.rel_pos.y = 0.f; player->mid_jump = false; player->jump_time = 0.f; @@ -862,9 +866,6 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent ); hh::PlayerState* player = & game_state->player_state; - f32 x_offset_f = scast(f32, state->x_offset); - f32 y_offset_f = scast(f32, state->y_offset); - World* world = state->world; TileMap* tile_map = world->tile_map; @@ -887,53 +888,64 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back move_speed = 24.f; } - f32 new_player_pos_x = player->position.x; - f32 new_player_pos_y = player->position.y; + Pos2_f32 new_player_pos = { player->position.rel_pos.x, player->position.rel_pos.y }; + + b32 moved_x = player_actions.player_x_move_analog != 0 || player_actions.player_x_move_digital != 0; + b32 moved_y = player_actions.player_y_move_analog != 0 || player_actions.player_y_move_digital != 0; + + Vel2_f32 player_move_vel = {}; if ( player_actions.player_x_move_analog || player_actions.player_y_move_analog ) { - new_player_pos_x += scast(f32, player_actions.player_x_move_analog * delta_time * move_speed); - new_player_pos_y += scast(f32, player_actions.player_y_move_analog * delta_time * move_speed); + player_move_vel.x = scast(f32, player_actions.player_x_move_analog * delta_time * move_speed); + player_move_vel.y = scast(f32, player_actions.player_y_move_analog * delta_time * move_speed); } else { - new_player_pos_x += scast(f32, player_actions.player_x_move_digital) * delta_time * move_speed; - new_player_pos_y += scast(f32, player_actions.player_y_move_digital) * delta_time * move_speed; + player_move_vel.x = scast(f32, player_actions.player_x_move_digital) * delta_time * move_speed; + player_move_vel.y = scast(f32, player_actions.player_y_move_digital) * delta_time * move_speed; } - new_player_pos_y += sinf( player->jump_time * TAU ) * 10.f * delta_time; + + if ( moved_x && moved_y ) + { + player_move_vel *= (f32)0.707106781187f; + } + + new_player_pos += player_move_vel; + new_player_pos.y -= sinf( player->jump_time * TAU ) * 10.f * delta_time; b32 valid_new_pos = true; { - TileMapPosition test_pos = { - new_player_pos_x, new_player_pos_y, - player->position.tile_x, player->position.tile_y, player->position.tile_z + TileMapPos test_pos = { + new_player_pos.x, new_player_pos.y, + player->position.tile_x, player->position.tile_y, player->position.tile_z }; test_pos = recannonicalize_position( tile_map, test_pos ); // TODO(Ed) : Need a delta-function that auto-reconnonicalizes. - TileMapPosition test_pos_nw { - new_player_pos_x - player_half_width, new_player_pos_y + player_quarter_height, + TileMapPos test_pos_nw { + new_player_pos.x - player_half_width, new_player_pos.y + player_quarter_height, player->position.tile_x, player->position.tile_y, player->position.tile_z }; test_pos_nw = recannonicalize_position( tile_map, test_pos_nw ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_nw ); - TileMapPosition test_pos_ne { - new_player_pos_x + player_half_width, new_player_pos_y + player_quarter_height, + TileMapPos test_pos_ne { + new_player_pos.x + player_half_width, new_player_pos.y + player_quarter_height, player->position.tile_x, player->position.tile_y, player->position.tile_z }; test_pos_ne = recannonicalize_position( tile_map, test_pos_ne ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_ne ); - TileMapPosition test_pos_sw { - new_player_pos_x - player_half_width, new_player_pos_y, + TileMapPos test_pos_sw { + new_player_pos.x - player_half_width, new_player_pos.y, player->position.tile_x, player->position.tile_y, player->position.tile_z }; test_pos_sw = recannonicalize_position( tile_map, test_pos_sw ); valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_sw ); - TileMapPosition test_pos_se { - new_player_pos_x + player_half_width, new_player_pos_y, + TileMapPos test_pos_se { + new_player_pos.x + player_half_width, new_player_pos.y, player->position.tile_x, player->position.tile_y, player->position.tile_z }; test_pos_se = recannonicalize_position( tile_map, test_pos_se ); @@ -942,9 +954,9 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back if ( valid_new_pos ) { - TileMapPosition new_pos = { - new_player_pos_x, new_player_pos_y, - player->position.tile_x, player->position.tile_y, player->position.tile_z + TileMapPos new_pos = { + new_player_pos.x, new_player_pos.y, + player->position.tile_x, player->position.tile_y, player->position.tile_z }; new_pos = recannonicalize_position( tile_map, new_pos ); @@ -999,7 +1011,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back player->mid_jump = true; } - TileMapPosition player_to_camera = subtract( player->position, game_state->camera_pos ); + TileMapPos player_to_camera = subtract( player->position, game_state->camera_pos ); game_state->camera_pos.tile_z = player->position.tile_z; @@ -1022,25 +1034,20 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back } + Vec2 screen_center { + scast(f32, back_buffer->width) * 0.5f, + scast(f32, back_buffer->height) * 0.5f + }; + draw_rectangle( back_buffer - , 0.f, 0.f - , scast(f32, back_buffer->width), scast(f32, back_buffer->height) + , Zero(Vec2) + , { scast(f32, back_buffer->width), scast(f32, back_buffer->height) } , 1.f, 0.24f, 0.24f ); - draw_bitmap( back_buffer - , scast(f32, back_buffer->width) / 2.f, scast(f32, back_buffer->height) / 2.f - , & game_state->test_bg - ); - - draw_bitmap( back_buffer - , scast(f32, back_buffer->width) / 2.f, scast(f32, back_buffer->height) / 2.f - , & game_state->test_bg_hh - ); + draw_bitmap( back_buffer, screen_center, & game_state->test_bg ); + draw_bitmap( back_buffer, screen_center, & game_state->test_bg_hh ); // Screen Camera - f32 screen_center_x = 0.5f * scast(f32, back_buffer->width); - f32 screen_center_y = 0.5f * scast(f32, back_buffer->height); - for ( s32 relative_row = -10; relative_row < +10; ++ relative_row ) { for ( s32 relative_col = -20; relative_col < +20; ++ relative_col ) @@ -1080,17 +1087,16 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back color[2] = 0.3f; } - f32 center_x = screen_center_x + scast(f32, relative_col) * tile_size_in_pixels - game_state->camera_pos.x * world->tile_meters_to_pixels; - f32 center_y = screen_center_y - scast(f32, relative_row) * tile_size_in_pixels + game_state->camera_pos.y * world->tile_meters_to_pixels; - - f32 min_x = center_x - tile_size_in_pixels * 0.5f; - f32 min_y = center_y - tile_size_in_pixels * 0.5f; - f32 max_x = center_x + tile_size_in_pixels * 0.5f; - f32 max_y = center_y + tile_size_in_pixels * 0.5f; + Vec2 tile_pixel_size = { tile_size_in_pixels * 0.5f, tile_size_in_pixels * 0.5f }; + Vec2 center { + screen_center.x + scast(f32, relative_col) * tile_size_in_pixels - game_state->camera_pos.rel_pos.x * world->tile_meters_to_pixels, + screen_center.y - scast(f32, relative_row) * tile_size_in_pixels + game_state->camera_pos.rel_pos.y * world->tile_meters_to_pixels + }; + Vec2 min = center - tile_pixel_size; + Vec2 max = center + tile_pixel_size; draw_rectangle( back_buffer - , min_x, min_y - , max_x, max_y + , min, max , color[0], color[1], color[2] ); } } @@ -1118,38 +1124,44 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back f32 player_green = 0.7f; f32 player_blue = 0.3f; - TileMapPosition player_to_camera = subtract( player->position, game_state->camera_pos ); - - f32 offcenter_amount_x = player_to_camera.x + scast(f32, player_to_camera.tile_x) * world->tile_map->tile_size_in_meters; - f32 offcenter_amount_y = player_to_camera.y + scast(f32, player_to_camera.tile_y) * world->tile_map->tile_size_in_meters; - offcenter_amount_x *= world->tile_meters_to_pixels; - offcenter_amount_y *= world->tile_meters_to_pixels * -1; - - f32 player_ground_pos_x = screen_center_x + offcenter_amount_x; - f32 player_ground_pos_y = screen_center_y + offcenter_amount_y; + TileMapPos player_to_camera = subtract( player->position, game_state->camera_pos ); + + Vec2 player_to_screenspace { + player_to_camera.rel_pos.x + scast(f32, player_to_camera.tile_x) * world->tile_map->tile_size_in_meters, + -1 * (player_to_camera.rel_pos.y + scast(f32, player_to_camera.tile_y) * world->tile_map->tile_size_in_meters) + }; + Vec2 player_ground_pos = screen_center + player_to_screenspace * world->tile_meters_to_pixels; hh::HeroBitmaps* hero_bitmaps = & game_state->hero_bitmaps[game_state->hero_direction]; #if 1 + Vec2 player_collision_min { + player_ground_pos.x - player_half_width * world->tile_meters_to_pixels, + player_ground_pos.y - player->height * world->tile_meters_to_pixels, + }; + Vec2 player_collision_max { + player_ground_pos.x + player_half_width * world->tile_meters_to_pixels, + player_ground_pos.y + }; + draw_rectangle( back_buffer - , player_ground_pos_x - player_half_width * world->tile_meters_to_pixels, player_ground_pos_y - player->height * world->tile_meters_to_pixels - , player_ground_pos_x + player_half_width * world->tile_meters_to_pixels, player_ground_pos_y + , player_collision_min, player_collision_max , player_red, player_green, player_blue ); #endif draw_bitmap( back_buffer - , player_ground_pos_x, player_ground_pos_y - scast(f32, hero_bitmaps->align_y) + , { player_ground_pos.x, player_ground_pos.y - scast(f32, hero_bitmaps->align_y) } , & hero_bitmaps->torso ); draw_bitmap( back_buffer - , player_ground_pos_x, player_ground_pos_y - scast(f32, hero_bitmaps->align_y) + , { player_ground_pos.x, player_ground_pos.y - scast(f32, hero_bitmaps->align_y) } , & hero_bitmaps->cape ); -#if 0 +#if 1 draw_bitmap( back_buffer - , player_ground_pos_x, player_ground_pos_y - 45.f + , { player_ground_pos.x, player_ground_pos.y - 125.f } , & game_state->mojito_head ); #else draw_bitmap( back_buffer - , player_ground_pos_x, player_ground_pos_y - scast(f32, hero_bitmaps->align_y) + , { player_ground_pos.x, player_ground_pos.y - scast(f32, hero_bitmaps->align_y) } , & hero_bitmaps->head ); #endif @@ -1158,17 +1170,18 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back { f32 snapshot_percent_x = ((state->auto_snapshot_timer / state->auto_snapshot_interval)) * (f32)back_buffer->width / 4.f; draw_rectangle( back_buffer - , 0.f, 0.f - , snapshot_percent_x, 10.f + , Zero(Vec2) + , { snapshot_percent_x, 10.f } , 0.f, 0.15f, 0.35f ); } #if Build_Development if ( memory->replay_mode == ReplayMode_Record ) { + // TODO(Ed) : We're prob going to need a better indicator for recording... draw_rectangle( back_buffer - , player->position.x + 50.f, player->position.y - 50.f - , player->position.x + 10.f, player->position.y + 40.f + , { player->position.rel_pos.x + 50.f, player->position.rel_pos.y - 50.f } + , { player->position.rel_pos.x + 10.f, player->position.rel_pos.y + 40.f } , 1.f, 1.f, 1.f ); } #endif @@ -1177,8 +1190,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back if ( 0 ) { draw_rectangle( back_buffer - , (f32)input->controllers[0].mouse->X.end, (f32)input->controllers[0].mouse->Y.end - , (f32)input->controllers[0].mouse->X.end + 10.f, (f32)input->controllers[0].mouse->Y.end + 10.f + , { (f32)input->controllers[0].mouse->X.end, (f32)input->controllers[0].mouse->Y.end } + , { (f32)input->controllers[0].mouse->X.end + 10.f, (f32)input->controllers[0].mouse->Y.end + 10.f } , 1.f, 1.f, 0.f ); } diff --git a/project/engine/engine.hpp b/project/engine/engine.hpp index 009e9e6..be87ebc 100644 --- a/project/engine/engine.hpp +++ b/project/engine/engine.hpp @@ -6,6 +6,8 @@ #if INTELLISENSE_DIRECTIVES #include "platform/platform.hpp" +#include "gen/vectors.hpp" +#include "gen/physics.hpp" #include "engine_module.hpp" #include "tile_map.hpp" #endif @@ -177,7 +179,7 @@ struct World f32 tile_meters_to_pixels; s32 tile_size_in_pixels; - + s32 tiles_per_screen_x; s32 tiles_per_screen_y; @@ -203,7 +205,7 @@ struct BitmapHeaderPacked s32 vertical_resolution; u32 colors_used; u32 colors_important; - + u32 red_mask; u32 green_mask; u32 blue_mask; diff --git a/project/engine/gen/physics.hpp b/project/engine/gen/physics.hpp new file mode 100644 index 0000000..6de8de1 --- /dev/null +++ b/project/engine/gen/physics.hpp @@ -0,0 +1,200 @@ +// This was generated by project/codegen/engine_gen.cpp +#pragma once +#if INTELLISENSE_DIRECTIVES +#include "vectors.hpp" +#endif + +struct Pos2_f32 +{ + union + { + struct + { + f32 x; + f32 y; + }; + + f32 Basis[ 2 ]; + }; + + operator Vec2_f32() + { + return *rcast( Vec2_f32*, this ); + } +}; + +using Dist2_f32 = f32; + +inline Dist2_f32 distance( Pos2_f32 a, Pos2_f32 b ) +{ + f32 x = b.x - a.x; + f32 y = b.y - a.y; + Dist2_f32 result = sqrt( x * x + y * y ); + return result; +} + +struct Vel2_f32 +{ + union + { + struct + { + f32 x; + f32 y; + }; + + f32 Basis[ 2 ]; + }; + + operator Vec2_f32() + { + return *rcast( Vec2_f32*, this ); + } +}; + +inline Vel2_f32 velocity( Pos2_f32 a, Pos2_f32 b ) +{ + Vec2_f32 result = b - a; + return pcast( Vel2_f32, result ); +} + +inline Pos2_f32& operator+=( Pos2_f32& pos, Vel2_f32 const& vel ) +{ + pos.x += vel.x; + pos.y += vel.y; + return pos; +} + +inline Vel2_f32& operator*=( Vel2_f32& v, f32 s ) +{ + v.x *= s; + v.y *= s; + return v; +} + +struct Accel2_f32 +{ + union + { + struct + { + f32 x; + f32 y; + }; + + f32 Basis[ 2 ]; + }; + + operator Vec2_f32() + { + return *rcast( Vec2_f32*, this ); + } +}; + +inline Accel2_f32 acceleration( Vel2_f32 a, Vel2_f32 b ) +{ + Vec2_f32 result = b - a; + return pcast( Accel2_f32, result ); +} + +struct Pos2_s32 +{ + union + { + struct + { + s32 x; + s32 y; + }; + + s32 Basis[ 2 ]; + }; + + operator Vec2_s32() + { + return *rcast( Vec2_s32*, this ); + } +}; + +using Dist2_s32 = s32; + +inline Dist2_s32 distance( Pos2_s32 a, Pos2_s32 b ) +{ + s32 x = b.x - a.x; + s32 y = b.y - a.y; + Dist2_s32 result = sqrt( x * x + y * y ); + return result; +} + +struct Vel2_s32 +{ + union + { + struct + { + s32 x; + s32 y; + }; + + s32 Basis[ 2 ]; + }; + + operator Vec2_s32() + { + return *rcast( Vec2_s32*, this ); + } +}; + +inline Vel2_s32 velocity( Pos2_s32 a, Pos2_s32 b ) +{ + Vec2_s32 result = b - a; + return pcast( Vel2_s32, result ); +} + +inline Pos2_s32& operator+=( Pos2_s32& pos, Vel2_s32 const& vel ) +{ + pos.x += vel.x; + pos.y += vel.y; + return pos; +} + +inline Vel2_s32& operator*=( Vel2_s32& v, s32 s ) +{ + v.x *= s; + v.y *= s; + return v; +} + +struct Accel2_s32 +{ + union + { + struct + { + s32 x; + s32 y; + }; + + s32 Basis[ 2 ]; + }; + + operator Vec2_s32() + { + return *rcast( Vec2_s32*, this ); + } +}; + +inline Accel2_s32 acceleration( Vel2_s32 a, Vel2_s32 b ) +{ + Vec2_s32 result = b - a; + return pcast( Accel2_s32, result ); +} + +using Pos2 = Pos2_f32; +using Dist2 = Dist2_f32; +using Vel2 = Vel2_f32; +using Accel2 = Accel2_f32; +using Pos2i = Pos2_s32; +using Dist2i = Dist2_s32; +using Vel2i = Vel2_s32; +using Accel2i = Accel2_s32; diff --git a/project/engine/gen/vectors.hpp b/project/engine/gen/vectors.hpp new file mode 100644 index 0000000..850e536 --- /dev/null +++ b/project/engine/gen/vectors.hpp @@ -0,0 +1,177 @@ +// This was generated by project/codegen/engine_gen.cpp +#pragma once +#if INTELLISENSE_DIRECTIVES +#include "engine_module.hpp" +#include "platform.hpp" +#endif + +struct Vec2_f32 +{ + union + { + struct + { + f32 x; + f32 y; + }; + + f32 Basis[ 2 ]; + }; +}; + +template<> +constexpr Vec2_f32 tmpl_zero< Vec2_f32 >() +{ + return { 0, 0 }; +} + +inline Vec2_f32 abs( Vec2_f32 v ) +{ + Vec2_f32 result { abs( v.x ), abs( v.y ) }; + return result; +} + +inline Vec2_f32 operator-( Vec2_f32 v ) +{ + Vec2_f32 result { -v.x, -v.y }; + return result; +} + +inline Vec2_f32 operator+( Vec2_f32 a, Vec2_f32 b ) +{ + Vec2_f32 result { a.x + b.x, a.y + b.y }; + return result; +} + +inline Vec2_f32 operator-( Vec2_f32 a, Vec2_f32 b ) +{ + Vec2_f32 result { a.x - b.x, a.y - b.y }; + return result; +} + +inline Vec2_f32 operator*( Vec2_f32 v, f32 s ) +{ + Vec2_f32 result { v.x * s, v.y * s }; + return result; +} + +inline Vec2_f32 operator/( Vec2_f32 v, f32 s ) +{ + Vec2_f32 result { v.x / s, v.y / s }; + return result; +} + +inline Vec2_f32& operator+=( Vec2_f32& a, Vec2_f32 b ) +{ + a.x += b.x; + a.y += b.y; + return a; +} + +inline Vec2_f32& operator-=( Vec2_f32& a, Vec2_f32 b ) +{ + a.x -= b.x; + a.y -= b.y; + return a; +} + +inline Vec2_f32& operator*=( Vec2_f32& v, f32 s ) +{ + v.x *= s; + v.y *= s; + return v; +} + +inline Vec2_f32& operator/=( Vec2_f32& v, f32 s ) +{ + v.x /= s; + v.y /= s; + return v; +} + +struct Vec2_s32 +{ + union + { + struct + { + s32 x; + s32 y; + }; + + s32 Basis[ 2 ]; + }; +}; + +template<> +constexpr Vec2_s32 tmpl_zero< Vec2_s32 >() +{ + return { 0, 0 }; +} + +inline Vec2_s32 abs( Vec2_s32 v ) +{ + Vec2_s32 result { abs( v.x ), abs( v.y ) }; + return result; +} + +inline Vec2_s32 operator-( Vec2_s32 v ) +{ + Vec2_s32 result { -v.x, -v.y }; + return result; +} + +inline Vec2_s32 operator+( Vec2_s32 a, Vec2_s32 b ) +{ + Vec2_s32 result { a.x + b.x, a.y + b.y }; + return result; +} + +inline Vec2_s32 operator-( Vec2_s32 a, Vec2_s32 b ) +{ + Vec2_s32 result { a.x - b.x, a.y - b.y }; + return result; +} + +inline Vec2_s32 operator*( Vec2_s32 v, s32 s ) +{ + Vec2_s32 result { v.x * s, v.y * s }; + return result; +} + +inline Vec2_s32 operator/( Vec2_s32 v, s32 s ) +{ + Vec2_s32 result { v.x / s, v.y / s }; + return result; +} + +inline Vec2_s32& operator+=( Vec2_s32& a, Vec2_s32 b ) +{ + a.x += b.x; + a.y += b.y; + return a; +} + +inline Vec2_s32& operator-=( Vec2_s32& a, Vec2_s32 b ) +{ + a.x -= b.x; + a.y -= b.y; + return a; +} + +inline Vec2_s32& operator*=( Vec2_s32& v, s32 s ) +{ + v.x *= s; + v.y *= s; + return v; +} + +inline Vec2_s32& operator/=( Vec2_s32& v, s32 s ) +{ + v.x /= s; + v.y /= s; + return v; +} + +using Vec2 = Vec2_f32; +using Vec2i = Vec2_s32; diff --git a/project/engine/tile_map.cpp b/project/engine/tile_map.cpp index 061b42a..020fbda 100644 --- a/project/engine/tile_map.cpp +++ b/project/engine/tile_map.cpp @@ -5,14 +5,14 @@ NS_ENGINE_BEGIN inline -TileMapPosition subtract( TileMapPosition pos_a, TileMapPosition pos_b ) +TileMapPos subtract( TileMapPos pos_a, TileMapPos pos_b ) { - TileMapPosition result { - pos_a.x - pos_b.x, - pos_a.y - pos_b.y, + TileMapPos result { + pos_a.rel_pos - pos_b.rel_pos, + pos_a.tile_x - pos_b.tile_x, pos_a.tile_y - pos_b.tile_y, - + // TODO(Ed) : Think about how to handle z... pos_a.tile_z - pos_b.tile_z }; @@ -23,7 +23,7 @@ TileMapPosition subtract( TileMapPosition pos_a, TileMapPosition pos_b ) inline void cannonicalize_coord( TileMap* tile_map, s32* tile_coord, f32* pos_coord ) { - assert( tile_map != nullptr ); + assert( tile_map != nullptr ); assert( tile_coord != nullptr ); f32 tile_size = scast(f32, tile_map->tile_size_in_meters); @@ -42,13 +42,13 @@ void cannonicalize_coord( TileMap* tile_map, s32* tile_coord, f32* pos_coord ) // TODO(Ed) : Consider moving (Casey wants to) inline -TileMapPosition recannonicalize_position( TileMap* tile_map, TileMapPosition pos ) +TileMapPos recannonicalize_position( TileMap* tile_map, TileMapPos pos ) { assert( tile_map != nullptr ); - TileMapPosition result = pos; - cannonicalize_coord( tile_map, & result.tile_x, & result.x ); - cannonicalize_coord( tile_map, & result.tile_y, & result.y ); + TileMapPos result = pos; + cannonicalize_coord( tile_map, & result.tile_x, & result.rel_pos.x ); + cannonicalize_coord( tile_map, & result.tile_y, & result.rel_pos.y ); return result; } @@ -109,11 +109,11 @@ TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, u32 abs_tile_x } inline -u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y, u32 tile_z ) +u32 TileMap_get_tile_value( TileMap* tile_map, s32 tile_x, s32 tile_y, s32 tile_z ) { assert( tile_map != nullptr ); - u32 value = 0; + s32 value = 0; TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, tile_x, tile_y, tile_z ); TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y, chunk_pos.tile_chunk_z ); @@ -124,14 +124,14 @@ u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y, u32 tile_ } inline -u32 TileMap_get_tile_value( TileMap* tile_map, TileMapPosition position ) +u32 TileMap_get_tile_value( TileMap* tile_map, TileMapPos position ) { u32 value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y, position.tile_z ); return value; } internal -b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPosition position ) +b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPos position ) { assert( tile_map != nullptr ); @@ -168,7 +168,7 @@ void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, s32 abs_tile internal -b32 TileMap_are_on_same_tile( TileMapPosition* pos_a, TileMapPosition* pos_b ) +b32 TileMap_are_on_same_tile( TileMapPos* pos_a, TileMapPos* pos_b ) { b32 result = pos_a->tile_x == pos_b->tile_x diff --git a/project/engine/tile_map.hpp b/project/engine/tile_map.hpp index c82999c..ed41882 100644 --- a/project/engine/tile_map.hpp +++ b/project/engine/tile_map.hpp @@ -50,11 +50,10 @@ struct TileMap TileChunk* chunks; }; -struct TileMapPosition +struct TileMapPos { // Note(Ed) : Relative position from tile center. - f32 x; - f32 y; + Vec2 rel_pos; // "World-relative (x, y), AKA: Absolute Position // Fixed point tile locations. diff --git a/project/handmade.hpp b/project/handmade.hpp index 8b3ea38..2fa025d 100644 --- a/project/handmade.hpp +++ b/project/handmade.hpp @@ -74,7 +74,7 @@ struct PlayerState f32 width; f32 height; - engine::TileMapPosition position; + engine::TileMapPos position; b32 mid_jump; f32 jump_time; @@ -124,7 +124,7 @@ struct GameState Bitmap test_bg_hh; - engine::TileMapPosition camera_pos; + engine::TileMapPos camera_pos; EHeroBitmapsDirection hero_direction; HeroBitmaps hero_bitmaps[4]; diff --git a/project/handmade_engine.cpp b/project/handmade_engine.cpp index 52fb4a2..933ceab 100644 --- a/project/handmade_engine.cpp +++ b/project/handmade_engine.cpp @@ -19,6 +19,8 @@ Handmade Engine Translation Unit #include "platform/platform.hpp" #include "engine_module.hpp" +#include "gen/vectors.hpp" +#include "gen/physics.hpp" #include "input.hpp" #include "tile_map.hpp" #include "engine.hpp" diff --git a/project/handmade_win32.cpp b/project/handmade_win32.cpp index 1230356..e3b1502 100644 --- a/project/handmade_win32.cpp +++ b/project/handmade_win32.cpp @@ -20,6 +20,8 @@ Handmade Win32 Platform Translation Unit // Engine layer headers #include "engine/engine_module.hpp" +#include "engine/gen/vectors.hpp" +#include "engine/gen/physics.hpp" #include "engine/input.hpp" #include "engine/tile_map.hpp" #include "engine/engine.hpp" diff --git a/project/platform/compiler_ignores.hpp b/project/platform/compiler_ignores.hpp index f76eb73..6e9570e 100644 --- a/project/platform/compiler_ignores.hpp +++ b/project/platform/compiler_ignores.hpp @@ -14,6 +14,7 @@ #pragma warning( disable: 4711 ) // Support automatic inline expansion #pragma warning( disable: 4710 ) // Support automatic inline expansion #pragma warning( disable: 4805 ) // Support comparisons of s32 to bool. +#pragma warning( disable: 5246 ) // Support for initialization of subobject without braces. #endif #ifdef __clang__ diff --git a/project/platform/generics.hpp b/project/platform/generics.hpp index fa3995a..19b0dde 100644 --- a/project/platform/generics.hpp +++ b/project/platform/generics.hpp @@ -8,3 +8,7 @@ void swap( Type& a, Type& b ) a = b; b = temp; } + +#define Zero( type ) tmpl_zero() +template< class Type > +constexpr Type tmpl_zero(); diff --git a/project/platform/intrinsics.hpp b/project/platform/intrinsics.hpp index 5fe8b28..9bf23e9 100644 --- a/project/platform/intrinsics.hpp +++ b/project/platform/intrinsics.hpp @@ -7,11 +7,43 @@ // TODO(Ed) : Convert all of these to platform-efficient versions -//inline -//s32 abs( s32 value ) -//{ -// return ; -//} +inline +f32 abs( f32 value ) +{ + return fabsf(value); +} + +inline +f32 sqrt( f32 value ) +{ + return sqrtf(value); +} + +inline +s32 sqrt(s32 value) { + if (value < 0) { + return -1; + } + + if (value == 0 || value == 1) { + return value; + } + + // Initial guess for the square root + s32 current_estimate = value; + s32 reciprocal_estimate = 1; + // Second estimate based on the reciprocal of our current guess + + // Tolerance level for convergence + const s32 tolerance = 1; + + while (current_estimate - reciprocal_estimate > tolerance) { + current_estimate = (current_estimate + reciprocal_estimate) / 2; + reciprocal_estimate = value / current_estimate; + } + + return current_estimate; +} inline s32 floor( f32 value ) diff --git a/project/platform/win32/win32_platform.cpp b/project/platform/win32/win32_platform.cpp index 052beb1..e9ab63a 100644 --- a/project/platform/win32/win32_platform.cpp +++ b/project/platform/win32/win32_platform.cpp @@ -155,7 +155,7 @@ void toggle_fullscreen( HWND window_handle ) { MONITORINFO info = { sizeof(MONITORINFO) }; HMONITOR monitor_handle = MonitorFromWindow( window_handle, MONITOR_DEFAULTTOPRIMARY ); - + if ( GetWindowPlacement( window_handle, & Window_Position ) && GetMonitorInfoA( monitor_handle, & info ) ) { @@ -193,7 +193,7 @@ display_buffer_in_window( HDC device_context, s32 window_width, s32 window_heigh , s32 x, s32 y , s32 width, s32 height ) { - if ( (window_width % buffer->width ) == 0 + if ( (window_width % buffer->width ) == 0 && (window_height % buffer->height) == 0 ) { // TODO(Ed) : Aspect ratio correction @@ -202,10 +202,10 @@ display_buffer_in_window( HDC device_context, s32 window_width, s32 window_heigh , 0, 0, buffer->width, buffer->height , buffer->memory, & buffer->info , DIB_ColorTable_RGB, RO_Source_To_Dest ); - + return; } - + s32 offset_x = 0; s32 offset_y = 0; @@ -348,14 +348,14 @@ main_window_callback( HWND handle while (ShowCursor(FALSE) >= 0); } break; - + case WM_NCMOUSEMOVE: { // Show the cursor when it's outside the window's client area (i.e., on the frame or elsewhere) while (ShowCursor(TRUE) < 0); } break; - + case WM_SETCURSOR: { if ( Show_Windows_Cursor ) @@ -581,9 +581,9 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho Path_Scratch.concat( Path_Root, str_ascii("scratch") ); Path_Scratch.ptr[ Path_Scratch.len ] = '\\'; ++ Path_Scratch.len; - + CreateDirectoryA( Path_Scratch, 0 ); - + Path_Content.concat( Path_Root, str_ascii("content") ); Path_Content.ptr[ Path_Content.len ] = '\\'; ++ Path_Content.len; @@ -593,7 +593,7 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho engine::Memory engine_memory {}; { engine_memory.persistent_size = megabytes( 128 ); - // engine_memory.FrameSize = megabytes( 64 ); + // engine_memory.FrameSize = megabytes( 64 ); engine_memory.transient_size = gigabytes( 2 ); u64 total_size = engine_memory.persistent_size @@ -688,7 +688,7 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho // window_class.hbrBackground = ; window_class.lpszMenuName = L"Handmade Hero!"; window_class.lpszClassName = L"HandmadeHeroWindowClass"; - + Show_Windows_Cursor = true; Windows_Cursor = LoadCursorW( 0, IDC_CROSS ); Window_Position = {sizeof(WINDOWPLACEMENT)}; diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 1ac548c..3d48965 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -188,6 +188,44 @@ else { function build-engine { + $unit = Join-Path $path_codegen 'engine_gen.cpp' + $should_build = (check-FileForChanges $unit) -eq $true + if ( $should_build ) + { + $executable = Join-Path $path_build 'engine_gen.exe' + + $compiler_args = @() + $compiler_args += ( $flag_define + 'GEN_TIME' ) + + $linker_args = @( + $flag_link_win_subsystem_console + ) + + $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable + if ( $build_result -eq $false ) { + return $false + } + + Push-Location $path_engine_gen + $time_taken = Measure-Command { + & $executable 2>&1 | ForEach-Object { + write-host `t $_ -ForegroundColor Green + } + } + Pop-Location + + push-location $path_scripts + $include = @( + '*.cpp' + '*.hpp' + ) + format-cpp $path_engine_gen $include + pop-location + } + else { + write-host "No changes detected in engine gen, skipping build" -ForegroundColor Yellow + } + $should_build = check-ModuleForChanges $path_engine if ( $should_build -eq $false ) { write-host "No changes detected in engine module, skipping build" -ForegroundColor Yellow @@ -318,13 +356,6 @@ function build-engine $should_build = (check-FileForChanges $unit) -eq $true if ( $should_build ) { - # Delete old PDBs - $pdb_files = Get-ChildItem -Path $path_build -Filter "engine_postbuild_gen_*.pdb" - foreach ($file in $pdb_files) { - Remove-Item -Path $file.FullName -Force - if ($verbose) { Write-Host "Deleted $file" -ForegroundColor Green } - } - $compiler_args = @() $compiler_args += ( $flag_define + 'GEN_TIME' )