diff --git a/project/codegen/engine_gen.cpp b/project/codegen/engine_gen.cpp index d08f001..94b94bb 100644 --- a/project/codegen/engine_gen.cpp +++ b/project/codegen/engine_gen.cpp @@ -26,7 +26,7 @@ constexpr StrC fname_vec_header = txt("vectors.hpp"); #pragma push_macro("scast") #undef scast -constexpr char const* vec2_ops = stringize( +constexpr char const* vec2f_ops = stringize( template<> constexpr tmpl_zero< >() { return { 0, 0 }; @@ -40,20 +40,20 @@ constexpr char const* vec2_ops = stringize( }; return result; } - + inline magnitude( v ) { result = sqrt( v.x * v.x + v.y * v.y ); return result; } - + inline normalize( v ) { square_size = v.x * v.x + v.y * v.y; if ( square_size < scast(, 1e-4) ) { return Zero( ); } - + mag = sqrt( square_size ); result { v.x / mag, @@ -62,6 +62,13 @@ constexpr char const* vec2_ops = stringize( return result; } + inline + scalar_product( a, b ) + { + result = a.x * b.x + a.y * b.y; + return result; + } + inline operator - ( v ) { result { @@ -88,7 +95,7 @@ constexpr char const* vec2_ops = stringize( }; return result; } - + inline operator * ( v, s ) { result { @@ -97,7 +104,7 @@ constexpr char const* vec2_ops = stringize( }; return result; } - + inline operator * ( s, v ) { result { @@ -106,7 +113,110 @@ constexpr char const* vec2_ops = stringize( }; 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; + } +); + +constexpr char const* vec2i_ops = stringize( + template<> + constexpr tmpl_zero< >() { + return { 0, 0 }; + } + + inline + abs( v ) { + result { + abs( v.x ), + abs( v.y ) + }; + return result; + } + + inline + magnitude( v ) { + result = sqrt( v.x * v.x + v.y * 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 * ( s, v ) { + result { + v.x * s, + v.y * s + }; + return result; + } + inline operator / ( v, s ) { result { @@ -145,8 +255,8 @@ constexpr char const* vec2_ops = stringize( ); #pragma pop_macro("scast") -#define gen_vec2( vec_name, type ) gen__vec2( txt( stringize(vec_name) ), txt( stringize(type) ) ) -CodeBody gen__vec2( StrC vec_name, StrC type ) +#define gen_vec2f( vec_name, type ) gen__vec2f( txt( stringize(vec_name) ), txt( stringize(type) ) ) +CodeBody gen__vec2f( StrC vec_name, StrC type ) { CodeStruct vec_struct = parse_struct( token_fmt( "type", vec_name, "unit_type", type, stringize( struct @@ -161,7 +271,33 @@ CodeBody gen__vec2( StrC vec_name, StrC type ) }; ))); - CodeBody vec_ops = parse_global_body( token_fmt( "type", vec_name, "unit_type", type, vec2_ops) ); + CodeBody vec_ops = parse_global_body( token_fmt( "type", vec_name, "unit_type", type, vec2f_ops) ); + CodeBody vec_def = def_global_body( args( + vec_struct, + fmt_newline, + vec_ops + )); + + return vec_def; +} + +#define gen_vec2i( vec_name, type ) gen__vec2i( txt( stringize(vec_name) ), txt( stringize(type) ) ) +CodeBody gen__vec2i( 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, vec2i_ops) ); CodeBody vec_def = def_global_body( args( vec_struct, fmt_newline, @@ -199,20 +335,20 @@ Code gen__phys2( StrC type ) return * rcast(*, this); } }; - + template<> inline tmpl_cast< , >( vec ) { return pcast( , vec ); - } + } ); CodeBody pos_struct = parse_global_body( token_fmt( "type", (StrC)sym_pos, "unit_type", type, "vec_type", (StrC)sym_vec, tmpl_struct )); - CodeBody pos_ops = parse_global_body( token_fmt( "type", (StrC)sym_pos, "unit_type", type, vec2_ops )); - - CodeBody dir_struct = parse_global_body( token_fmt( - "type", (StrC)sym_dir, - "unit_type", type, + CodeBody pos_ops = parse_global_body( token_fmt( "type", (StrC)sym_pos, "unit_type", type, vec2f_ops )); + + CodeBody dir_struct = parse_global_body( token_fmt( + "type", (StrC)sym_dir, + "unit_type", type, "vec_type", (StrC)sym_vec, "vel_type", (StrC)sym_vel, "accel_type", (StrC)sym_accel, @@ -226,7 +362,7 @@ Code gen__phys2( StrC type ) }; Basis[2]; }; - + operator () { return * rcast(*, this); } @@ -237,7 +373,7 @@ Code gen__phys2( StrC type ) return * rcast(*, this); } }; - + template<> inline tmpl_cast< , >( vec ) @@ -248,17 +384,17 @@ Code gen__phys2( StrC type ) normalized = normalize(vec); return pcast( , normalized ); - } + } ))); - CodeBody dist_def = parse_global_body( token_fmt( - "type", (StrC)sym_dist, - "unit_type", type, + CodeBody dist_def = parse_global_body( token_fmt( + "type", (StrC)sym_dist, + "unit_type", type, "dist_type", (StrC)sym_dist, "pos_type", (StrC)sym_pos, stringize( using = ; - + inline distance( a, b ) { x = b.x - a.x; @@ -268,13 +404,13 @@ Code gen__phys2( StrC type ) return result; } ))); - + CodeBody vel_struct = parse_global_body( token_fmt( "type", (StrC)sym_vel, "unit_type", type, "vec_type", (StrC)sym_vec, tmpl_struct )); - CodeBody vel_ops = parse_global_body( token_fmt( "type", (StrC)sym_vel, "unit_type", type, vec2_ops )); - + CodeBody vel_ops = parse_global_body( token_fmt( "type", (StrC)sym_vel, "unit_type", type, vec2f_ops )); + CodeBody accel_struct = parse_global_body( token_fmt( "type", (StrC)sym_accel, "unit_type", type, "vec_type", (StrC)sym_vec, tmpl_struct )); - CodeBody accel_ops = parse_global_body( token_fmt( "type", (StrC)sym_accel, "unit_type", type, vec2_ops )); - + CodeBody accel_ops = parse_global_body( token_fmt( "type", (StrC)sym_accel, "unit_type", type, vec2f_ops )); + // TODO(Ed): Is there a better name for this? Code ops = parse_global_body( token_fmt( "unit_type", (StrC)type, @@ -302,27 +438,27 @@ Code gen__phys2( StrC type ) result = b - a; return pcast(, result); } - + inline & operator +=(& vel, const accel) { vel.x += accel.x * engine::get_context()->delta_time; vel.y += accel.y * engine::get_context()->delta_time; return vel; } - + inline direction( pos_a, pos_b ) { diff = pos_b - pos_a; mag = magnitude( diff ); - + result { diff.x / mag, diff.y / mag }; return result; } - + inline direction( vel ) { @@ -333,7 +469,7 @@ Code gen__phys2( StrC type ) }; return result; } - + inline direction( accel ) { @@ -383,16 +519,11 @@ int gen_main() 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( gen_vec2f( Vec2_f32, f32) ); + vec_header.print( gen_vec2i( 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.print_fmt( "NS_ENGINE_END\n" ); vec_header.write(); } diff --git a/project/codegen/engine_postbuild_gen.cpp b/project/codegen/engine_postbuild_gen.cpp index e859627..a87ecf0 100644 --- a/project/codegen/engine_postbuild_gen.cpp +++ b/project/codegen/engine_postbuild_gen.cpp @@ -23,16 +23,17 @@ using namespace gen; #include "platform/generics.hpp" #include "platform/types.hpp" #include "platform/intrinsics.hpp" +#include "platform/float_ops.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" #include "engine/engine_to_platform_api.hpp" +#include "engine/gen/physics.hpp" constexpr StrC fname_handmade_engine_symbols = txt("handmade_engine.symbols"); diff --git a/project/engine/engine.cpp b/project/engine/engine.cpp index 7a9d247..87ef506 100644 --- a/project/engine/engine.cpp +++ b/project/engine/engine.cpp @@ -892,13 +892,18 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back player->move_velocity += player_move_accel * 0.5f; new_player_pos += player->move_velocity; - b32 valid_new_pos = true; + b32 collision_nw = false; + b32 collision_ne = false; + b32 collision_sw = false; + b32 collision_se = false; + do { - 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 ); + // Base position + //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. @@ -906,72 +911,105 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back 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 ); + test_pos_nw = recannonicalize_position( tile_map, test_pos_nw ); + collision_nw = ! TileMap_is_point_empty( tile_map, test_pos_nw ); 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 ); + test_pos_ne = recannonicalize_position( tile_map, test_pos_ne ); + collision_ne = ! TileMap_is_point_empty( tile_map, test_pos_ne ); 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 ); + test_pos_sw = recannonicalize_position( tile_map, test_pos_sw ); + collision_sw = ! TileMap_is_point_empty( tile_map, test_pos_sw ); 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 ); - valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_se ); + test_pos_se = recannonicalize_position( tile_map, test_pos_se ); + collision_se = ! TileMap_is_point_empty( tile_map, test_pos_se ); + } + while(0); + + if ( collision_se || collision_sw || collision_ne || collision_nw ) + { + // Should be colliding with a wall + + Vec2 wall_vector = { 0, 0 }; + if ( collision_nw && collision_sw ) + { + wall_vector = { 1.f, 0.f }; + } + if ( collision_ne && collision_se ) + { + wall_vector = { -1.f, 0.f }; + } + if ( collision_nw && collision_ne ) + { + wall_vector = { 0.f, 1.f }; + } + if ( collision_se && collision_sw ) + { + wall_vector = { 0.f, -1.f }; + } + + //if ( collision_nw && !collision_ne && !collision_sw && !collision_se ) + //{ + // wall_vector = { 1.f, 1.f }; + //} + + // The 2x multiplier allows for the the "bounce off" velocity to occur instead of the player just looking like they impacted the wall and stopped + player->move_velocity -= cast( Vel2, 1.f * scalar_product( Vec2( player->move_velocity ), wall_vector ) * wall_vector ); + + + new_player_pos = { player->position.rel_pos.x, player->position.rel_pos.y }; + new_player_pos += player->move_velocity; + } + + 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 ); + + bool on_new_tile = TileMap_are_on_same_tile( & new_pos, & player->position ); + if ( ! on_new_tile ) + { + u32 new_tile_value = TileMap_get_tile_value( tile_map, new_pos ); + + if ( new_tile_value == 3 ) + { + ++ new_pos.tile_z; + } + else if ( new_tile_value == 4 ) + { + -- new_pos.tile_z; + } } - if ( valid_new_pos ) + player->position = new_pos; + + if ( player_actions.player_y_move_digital > 0 || player_actions.player_y_move_analog > 0 ) { - 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 ); - - bool on_new_tile = TileMap_are_on_same_tile( & new_pos, & player->position ); - if ( ! on_new_tile ) - { - u32 new_tile_value = TileMap_get_tile_value( tile_map, new_pos ); - - if ( new_tile_value == 3 ) - { - ++ new_pos.tile_z; - } - else if ( new_tile_value == 4 ) - { - -- new_pos.tile_z; - } - } - - player->position = new_pos; - - if ( player_actions.player_y_move_digital > 0 || player_actions.player_y_move_analog > 0 ) - { - game_state->hero_direction = HeroBitmaps_Back; - } - if ( player_actions.player_y_move_digital < 0 || player_actions.player_y_move_analog < 0 ) - { - game_state->hero_direction = HeroBitmaps_Front; - } - if ( player_actions.player_x_move_digital > 0 || player_actions.player_x_move_analog > 0 ) - { - game_state->hero_direction = HeroBitmaps_Right; - } - if ( player_actions.player_x_move_digital < 0 || player_actions.player_x_move_analog < 0 ) - { - game_state->hero_direction = HeroBitmaps_Left; - } + game_state->hero_direction = HeroBitmaps_Back; + } + if ( player_actions.player_y_move_digital < 0 || player_actions.player_y_move_analog < 0 ) + { + game_state->hero_direction = HeroBitmaps_Front; + } + if ( player_actions.player_x_move_digital > 0 || player_actions.player_x_move_analog > 0 ) + { + game_state->hero_direction = HeroBitmaps_Right; + } + if ( player_actions.player_x_move_digital < 0 || player_actions.player_x_move_analog < 0 ) + { + game_state->hero_direction = HeroBitmaps_Left; } if ( player->jump_time > 0.f ) diff --git a/project/engine/gen/physics.hpp b/project/engine/gen/physics.hpp index e07515b..4ae6a7f 100644 --- a/project/engine/gen/physics.hpp +++ b/project/engine/gen/physics.hpp @@ -60,6 +60,12 @@ inline Pos2_f32 normalize( Pos2_f32 v ) return result; } +inline f32 scalar_product( Pos2_f32 a, Pos2_f32 b ) +{ + f32 result = a.x * b.x + a.y * b.y; + return result; +} + inline Pos2_f32 operator-( Pos2_f32 v ) { Pos2_f32 result { -v.x, -v.y }; @@ -189,6 +195,12 @@ inline Vel2_f32 normalize( Vel2_f32 v ) return result; } +inline f32 scalar_product( Vel2_f32 a, Vel2_f32 b ) +{ + f32 result = a.x * b.x + a.y * b.y; + return result; +} + inline Vel2_f32 operator-( Vel2_f32 v ) { Vel2_f32 result { -v.x, -v.y }; @@ -308,6 +320,12 @@ inline Accel2_f32 normalize( Accel2_f32 v ) return result; } +inline f32 scalar_product( Accel2_f32 a, Accel2_f32 b ) +{ + f32 result = a.x * b.x + a.y * b.y; + return result; +} + inline Accel2_f32 operator-( Accel2_f32 v ) { Accel2_f32 result { -v.x, -v.y }; diff --git a/project/engine/gen/vectors.hpp b/project/engine/gen/vectors.hpp index 0732a4c..98cd0f1 100644 --- a/project/engine/gen/vectors.hpp +++ b/project/engine/gen/vectors.hpp @@ -49,6 +49,12 @@ inline Vec2_f32 normalize( Vec2_f32 v ) return result; } +inline f32 scalar_product( Vec2_f32 a, Vec2_f32 b ) +{ + f32 result = a.x * b.x + a.y * b.y; + return result; +} + inline Vec2_f32 operator-( Vec2_f32 v ) { Vec2_f32 result { -v.x, -v.y }; @@ -145,18 +151,6 @@ inline s32 magnitude( Vec2_s32 v ) return result; } -inline Vec2_s32 normalize( Vec2_s32 v ) -{ - s32 square_size = v.x * v.x + v.y * v.y; - if ( square_size < scast( s32, 1e-4 ) ) - { - return Zero( Vec2_s32 ); - } - s32 mag = sqrt( square_size ); - Vec2_s32 result { v.x / mag, v.y / mag }; - return result; -} - inline Vec2_s32 operator-( Vec2_s32 v ) { Vec2_s32 result { -v.x, -v.y }; diff --git a/project/platform/compiler_ignores.hpp b/project/platform/compiler_ignores.hpp index 3f60aae..9433425 100644 --- a/project/platform/compiler_ignores.hpp +++ b/project/platform/compiler_ignores.hpp @@ -15,6 +15,7 @@ #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. +#pragma warning( disable: 4701 ) // Support for potentially uninitalized variables #endif #ifdef __clang__