Day 43 complete

This commit is contained in:
2023-10-28 17:10:30 -04:00
parent dddf8a1653
commit e1a481f4f6
19 changed files with 745 additions and 210 deletions

View File

@ -24,6 +24,8 @@ using namespace gen;
constexpr StrC fname_vec_header = txt("vectors.hpp");
#pragma push_macro("scast")
#undef scast
constexpr char const* vec2_ops = stringize(
template<>
constexpr <type> tmpl_zero< <type> >() {
@ -38,6 +40,27 @@ constexpr char const* vec2_ops = stringize(
};
return result;
}
inline
<unit_type> magnitude( <type> v ) {
<unit_type> result = sqrt( v.x * v.x + v.y * v.y );
return result;
}
inline
<type> normalize( <type> v ) {
<unit_type> square_size = v.x * v.x + v.y * v.y;
if ( square_size < scast(<unit_type>, 1e-4) ) {
return Zero( <type> );
}
<unit_type> mag = sqrt( square_size );
<type> result {
v.x / mag,
v.y / mag
};
return result;
}
inline
<type> operator - ( <type> v ) {
@ -75,6 +98,15 @@ constexpr char const* vec2_ops = stringize(
return result;
}
inline
<type> operator * ( <unit_type> s, <type> v ) {
<type> result {
v.x * s,
v.y * s
};
return result;
}
inline
<type> operator / ( <type> v, <unit_type> s ) {
<type> result {
@ -111,6 +143,7 @@ constexpr char const* vec2_ops = stringize(
return v;
}
);
#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 )
@ -141,25 +174,51 @@ CodeBody gen__vec2( StrC vec_name, StrC type )
#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 );
String sym_vec = String::fmt_buf( GlobalAllocator, "Vec2_%s", type.Ptr );
String sym_pos = String::fmt_buf( GlobalAllocator, "Pos2_%s", type.Ptr );
String sym_dir = String::fmt_buf( GlobalAllocator, "Dir2_%s", type.Ptr);
String sym_dist = String::fmt_buf( GlobalAllocator, "Dist2_%s", type.Ptr );
String sym_vel = String::fmt_buf( GlobalAllocator, "Vel2_%s", type.Ptr );
String sym_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,
constexpr char const* tmpl_struct = stringize(
struct <type>
{
union {
struct {
<unit_type> x;
<unit_type> y;
};
<unit_type> Basis[2];
};
operator <vec_type>() {
return * rcast(<vec_type>*, this);
}
};
template<>
inline
<type> tmpl_cast< <type>, <vec_type> >( <vec_type> vec )
{
return pcast( <type>, 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,
"vec_type", (StrC)sym_vec,
"vel_type", (StrC)sym_vel,
"accel_type", (StrC)sym_accel,
stringize(
struct <pos_type> {
struct <type>
{
union {
struct {
<unit_type> x;
@ -171,10 +230,35 @@ Code gen__phys2( StrC type )
operator <vec_type>() {
return * rcast(<vec_type>*, this);
}
operator <vel_type>() {
return * rcast(<vel_type>*, this);
}
operator <accel_type>() {
return * rcast(<accel_type>*, this);
}
};
template<>
inline
<type> tmpl_cast< <type>, <vec_type> >( <vec_type> vec )
{
<unit_type> abs_sum = abs( vec.x + vec.y );
if ( is_nearly_zero( abs_sum - 1 ) )
return pcast( <type>, vec );
<vec_type> normalized = normalize(vec);
return pcast( <type>, normalized );
}
)));
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 <dist_type> = <unit_type>;
inline
<dist_type> distance( <pos_type> a, <pos_type> b ) {
<unit_type> x = b.x - a.x;
@ -183,21 +267,23 @@ Code gen__phys2( StrC type )
<dist_type> result = sqrt( x * x + y * y );
return result;
}
struct <vel_type> {
union {
struct {
<unit_type> x;
<unit_type> y;
};
<unit_type> Basis[2];
};
operator <vec_type>() {
return * rcast(<vec_type>*, this);
}
};
)));
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 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 ));
// TODO(Ed): Is there a better name for this?
Code ops = parse_global_body( token_fmt(
"unit_type", (StrC)type,
"vec_type", (StrC)sym_vec,
"pos_type", (StrC)sym_pos,
"dir_type", (StrC)sym_dir,
"vel_type", (StrC)sym_vel,
"accel_type", (StrC)sym_accel,
stringize(
inline
<vel_type> velocity( <pos_type> a, <pos_type> b ) {
<vec_type> result = b - a;
@ -205,39 +291,72 @@ Code gen__phys2( StrC type )
}
inline
<pos_type>& operator +=(<pos_type>& pos, const <vel_type>& vel) {
pos.x += vel.x;
pos.y += vel.y;
<pos_type>& operator +=(<pos_type>& pos, const <vel_type> vel) {
pos.x += vel.x * engine::get_context()->delta_time;
pos.y += vel.y * engine::get_context()->delta_time;
return pos;
}
inline
<vel_type>& operator *= ( <vel_type>& v, <unit_type> s ) {
v.x *= s;
v.y *= s;
return v;
}
struct <accel_type> {
union {
struct {
<unit_type> x;
<unit_type> y;
};
<unit_type> Basis[2];
};
operator <vec_type>() {
return * rcast(<vec_type>*, this);
}
};
inline
<accel_type> acceleration( <vel_type> a, <vel_type> b ) {
<vec_type> result = b - a;
return pcast(<accel_type>, result);
}
inline
<vel_type>& operator +=(<vel_type>& vel, const <accel_type> accel) {
vel.x += accel.x * engine::get_context()->delta_time;
vel.y += accel.y * engine::get_context()->delta_time;
return vel;
}
inline
<dir_type> direction( <pos_type> pos_a, <pos_type> pos_b )
{
<vec_type> diff = pos_b - pos_a;
<unit_type> mag = magnitude( diff );
<dir_type> result {
diff.x / mag,
diff.y / mag
};
return result;
}
inline
<dir_type> direction( <vel_type> vel )
{
<unit_type> mag = magnitude( vel );
<dir_type> result {
vel.x / mag,
vel.y / mag
};
return result;
}
inline
<dir_type> direction( <accel_type> accel )
{
<unit_type> mag = magnitude( accel );
<dir_type> result {
accel.x / mag,
accel.y / mag
};
return result;
}
)));
CodeBody result = def_global_body( args(
pos_struct,
pos_ops,
dist_def,
vel_struct,
vel_ops,
accel_struct,
accel_ops,
dir_struct,
ops
));
return result;
#pragma pop_macro("rcast")
#pragma pop_macro("pcast")
@ -260,6 +379,7 @@ int gen_main()
vec_header.print( def_include( txt("platform.hpp") ));
vec_header.print( preprocess_endif );
vec_header.print( fmt_newline );
// vec_header.print_fmt( "NS_ENGINE_BEGIN\n" );
CodeUsing using_vec2 = parse_using( code( using Vec2 = Vec2_f32; ));
CodeUsing using_vec2i = parse_using( code( using Vec2i = Vec2_s32; ));
@ -272,6 +392,8 @@ int gen_main()
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();
}
@ -282,24 +404,22 @@ int gen_main()
physics_header.print_fmt( "#if INTELLISENSE_DIRECTIVES" );
physics_header.print( fmt_newline );
physics_header.print( def_include( txt("vectors.hpp") ));
physics_header.print( def_include( txt("engine.hpp") ));
physics_header.print( preprocess_endif );
physics_header.print( fmt_newline );
// physics_header.print_fmt( "NS_ENGINE_BEGIN\n" );
physics_header.print( gen_phys2( f32 ) );
physics_header.print( gen_phys2( s32 ) );
physics_header.print( parse_global_body( code(
using Pos2 = Pos2_f32;
using Dir2 = Dir2_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.print_fmt( "NS_ENGINE_END\n" );
physics_header.write();
}

View File

@ -12703,8 +12703,10 @@ char const* AST::debug_str()
case Parameters :
result.append_fmt( "\n\tNumEntries: %d", NumEntries );
result.append_fmt( "\n\tLast : %S", Last->Name );
result.append_fmt( "\n\tNext : %S", Next->Name );
if ( Last )
result.append_fmt( "\n\tLast : %S", Last->Name );
if ( Next )
result.append_fmt( "\n\tNext : %S", Next->Name );
result.append_fmt( "\n\tValueType : %S", ValueType ? ValueType->to_string() : "Null" );
result.append_fmt( "\n\tValue : %S", Value ? Value->to_string() : "Null" );
break;
@ -15189,7 +15191,10 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
break;
case 2 :
if ( ! params_code->ValueType.is_equal( ret_type ) )
break;
// Its not required by c++ to have this constraint so I'm omitting it.
#if 0
if ( ! params_code->ValueType.is_equal( ret_type ) && ! params_code->Next.is_equal( ret_type ) )
{
log_failure(
"gen::def_operator: "
@ -15202,6 +15207,7 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
return OpValidateResult::Fail;
}
break;
#endif
default :
log_failure(

View File

@ -3,56 +3,19 @@
#include "input.hpp"
#include "engine_to_platform_api.hpp"
// TODO(Ed) : This needs to be moved out eventually
#include "handmade.hpp"
#include "tile_map.cpp"
#include "random.cpp"
// TODO(Ed) : This needs to be moved out eventually
#include "handmade.hpp"
#endif
NS_ENGINE_BEGIN
#define pressed( btn ) (btn.ended_down && btn.half_transitions > 0)
// Used to determine if analog input is at move threshold
constexpr f32 analog_move_threshold = 0.5f;
struct EngineActions
{
b32 move_up;
b32 move_down;
b32 move_left;
b32 move_right;
b32 loop_mode_engine;
b32 loop_mode_game;
b32 raise_volume;
b32 lower_volume;
b32 raise_tone_hz;
b32 lower_tone_hz;
b32 toggle_wave_tone;
#if Build_Development
b32 pause_renderer;
b32 load_auto_snapshot;
b32 set_snapshot_slot_1;
b32 set_snapshot_slot_2;
b32 set_snapshot_slot_3;
b32 set_snapshot_slot_4;
b32 force_null_access_violation;
#endif
};
struct EngineState
{
hh::Memory game_memory;
MemoryArena world_arena;
World* world;
f32 auto_snapshot_interval;
f32 auto_snapshot_timer;
@ -66,8 +29,9 @@ struct EngineState
f32 sample_wave_sine_time;
b32 sample_wave_switch;
};
EngineContext context;
};
NS_ENGINE_END
// TODO(Ed) : does this need to be here or can it be moved to handmade_engine.cpp?
@ -81,6 +45,15 @@ NS_ENGINE_END
NS_ENGINE_BEGIN
global EngineContext* Engine_Context = nullptr;
EngineContext* get_context()
{
return Engine_Context;
}
#define pressed( btn ) (btn.ended_down && btn.half_transitions > 0)
internal
void input_poll_engine_actions( InputState* input, EngineActions* actions )
{
@ -391,7 +364,7 @@ Bitmap load_bmp( platform::ModuleAPI* platform_api, Str file_path )
Engine_API
void on_module_reload( Memory* memory, platform::ModuleAPI* platfom_api )
{
Engine_Context = & rcast(EngineState*, memory->persistent)->context;
}
Engine_API
@ -415,6 +388,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
EngineState* state = rcast( EngineState*, memory->persistent );
assert( sizeof(EngineState) <= memory->persistent_size );
Engine_Context = & state->context;
state->auto_snapshot_interval = 60.f;
state->tone_volume = 1000;
@ -432,6 +407,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
state->game_memory.transient_size = memory->transient_size / Memory::game_memory_factor;
state->game_memory.transient = rcast(Byte*, memory->transient) + state->game_memory.transient_size;
World* world;
// World setup
{
ssize world_arena_size = memory->engine_persistent_size() - sizeof(EngineState);
@ -439,8 +416,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
MemoryArena::init( & state->world_arena, world_arena_size, world_arena_storage );
//state->world = MemoryArena_push_struct( & state->world_arena, World);
state->world = state->world_arena.push_struct( World );
World* world = state->world;
state->context.world = state->world_arena.push_struct( World );
world = state->context.world;
TileMap* tile_map = state->world_arena.push_struct( TileMap );
world->tile_map = tile_map;
@ -702,8 +679,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
game_state->hero_direction = HeroBitmaps_Front;
}
game_state->camera_pos.tile_x = state->world->tiles_per_screen_x / 2;
game_state->camera_pos.tile_y = state->world->tiles_per_screen_y / 2;
game_state->camera_pos.tile_x = world->tiles_per_screen_x / 2;
game_state->camera_pos.tile_y = world->tiles_per_screen_y / 2;
hh::PlayerState* player = & game_state->player_state;
player->position.tile_x = 4;
@ -711,6 +688,8 @@ void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI*
player->position.rel_pos.x = 0.f;
player->position.rel_pos.y = 0.f;
player->move_velocity = {};
player->mid_jump = false;
player->jump_time = 0.f;
@ -730,6 +709,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
EngineState* state = rcast( EngineState*, memory->persistent );
assert( sizeof(EngineState) <= memory->persistent_size );
state->context.delta_time = delta_time;
// Engine auto_snapshot
{
state->auto_snapshot_timer += delta_time;
@ -866,7 +847,7 @@ 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;
World* world = state->world;
World* world = state->context.world;
TileMap* tile_map = world->tile_map;
f32 tile_size_in_pixels = scast(f32, world->tile_size_in_pixels);
@ -881,37 +862,35 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
input_poll_player_actions( input, & player_actions );
{
f32 move_speed = 6.f;
f32 move_accel = 36.f;
if ( player_actions.sprint )
{
move_speed = 24.f;
move_accel = 94.f;
}
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 = {};
Vec2 player_move_vec = {};
if ( player_actions.player_x_move_analog || player_actions.player_y_move_analog )
{
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);
player_move_vec.x = scast(f32, player_actions.player_x_move_analog );
player_move_vec.y = scast(f32, player_actions.player_y_move_analog );
}
else
{
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;
player_move_vec.x = scast(f32, player_actions.player_x_move_digital );
player_move_vec.y = scast(f32, player_actions.player_y_move_digital );
}
if ( moved_x && moved_y )
{
player_move_vel *= (f32)0.707106781187f;
}
Dir2 player_direction = cast( Dir2, player_move_vec );
Accel2 player_move_accel = scast( Accel2, player_direction ) * move_accel;
new_player_pos += player_move_vel;
new_player_pos.y -= sinf( player->jump_time * TAU ) * 10.f * delta_time;
// TODO(Ed) : ODE!
Accel2 friction = pcast( Accel2, player->move_velocity) * 9.f;
player_move_accel -= friction;
player->move_velocity += player_move_accel * 0.5f;
new_player_pos += player->move_velocity;
b32 valid_new_pos = true;
{
@ -1033,7 +1012,6 @@ 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
@ -1088,12 +1066,12 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
}
Vec2 tile_pixel_size = { tile_size_in_pixels * 0.5f, tile_size_in_pixels * 0.5f };
Vec2 center {
Pos2 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;
Pos2 min = center - cast( Pos2, tile_pixel_size );
Pos2 max = center + cast( Pos2, tile_pixel_size );
draw_rectangle( back_buffer
, min, max
@ -1130,7 +1108,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
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;
Pos2 player_ground_pos = cast( Pos2, screen_center + player_to_screenspace * world->tile_meters_to_pixels );
hh::HeroBitmaps* hero_bitmaps = & game_state->hero_bitmaps[game_state->hero_direction];

View File

@ -7,9 +7,9 @@
#if INTELLISENSE_DIRECTIVES
#include "platform/platform.hpp"
#include "gen/vectors.hpp"
#include "gen/physics.hpp"
#include "engine_module.hpp"
#include "tile_map.hpp"
#endif
NS_ENGINE_BEGIN
@ -220,4 +220,46 @@ struct Bitmap
u32 bits_per_pixel;
};
// Used to determine if analog input is at move threshold
constexpr f32 analog_move_threshold = 0.5f;
struct EngineActions
{
b32 move_up;
b32 move_down;
b32 move_left;
b32 move_right;
b32 loop_mode_engine;
b32 loop_mode_game;
b32 raise_volume;
b32 lower_volume;
b32 raise_tone_hz;
b32 lower_tone_hz;
b32 toggle_wave_tone;
#if Build_Development
b32 pause_renderer;
b32 load_auto_snapshot;
b32 set_snapshot_slot_1;
b32 set_snapshot_slot_2;
b32 set_snapshot_slot_3;
b32 set_snapshot_slot_4;
b32 force_null_access_violation;
#endif
};
// TODO(Ed) : Do this properly?
struct EngineContext
{
World* world;
float delta_time;
};
EngineContext* get_context();
NS_ENGINE_END

View File

@ -2,6 +2,7 @@
#pragma once
#if INTELLISENSE_DIRECTIVES
#include "vectors.hpp"
#include "engine.hpp"
#endif
struct Pos2_f32
@ -23,6 +24,106 @@ struct Pos2_f32
}
};
template<>
inline Pos2_f32 tmpl_cast< Pos2_f32, Vec2_f32 >( Vec2_f32 vec )
{
return pcast( Pos2_f32, vec );
}
template<>
constexpr Pos2_f32 tmpl_zero< Pos2_f32 >()
{
return { 0, 0 };
}
inline Pos2_f32 abs( Pos2_f32 v )
{
Pos2_f32 result { abs( v.x ), abs( v.y ) };
return result;
}
inline f32 magnitude( Pos2_f32 v )
{
f32 result = sqrt( v.x * v.x + v.y * v.y );
return result;
}
inline Pos2_f32 normalize( Pos2_f32 v )
{
f32 square_size = v.x * v.x + v.y * v.y;
if ( square_size < scast( f32, 1e-4 ) )
{
return Zero( Pos2_f32 );
}
f32 mag = sqrt( square_size );
Pos2_f32 result { v.x / mag, v.y / mag };
return result;
}
inline Pos2_f32 operator-( Pos2_f32 v )
{
Pos2_f32 result { -v.x, -v.y };
return result;
}
inline Pos2_f32 operator+( Pos2_f32 a, Pos2_f32 b )
{
Pos2_f32 result { a.x + b.x, a.y + b.y };
return result;
}
inline Pos2_f32 operator-( Pos2_f32 a, Pos2_f32 b )
{
Pos2_f32 result { a.x - b.x, a.y - b.y };
return result;
}
inline Pos2_f32 operator*( Pos2_f32 v, f32 s )
{
Pos2_f32 result { v.x * s, v.y * s };
return result;
}
inline Pos2_f32 operator*( f32 s, Pos2_f32 v )
{
Pos2_f32 result { v.x * s, v.y * s };
return result;
}
inline Pos2_f32 operator/( Pos2_f32 v, f32 s )
{
Pos2_f32 result { v.x / s, v.y / s };
return result;
}
inline Pos2_f32& operator+=( Pos2_f32& a, Pos2_f32 b )
{
a.x += b.x;
a.y += b.y;
return a;
}
inline Pos2_f32& operator-=( Pos2_f32& a, Pos2_f32 b )
{
a.x -= b.x;
a.y -= b.y;
return a;
}
inline Pos2_f32& operator*=( Pos2_f32& v, f32 s )
{
v.x *= s;
v.y *= s;
return v;
}
inline Pos2_f32& operator/=( Pos2_f32& v, f32 s )
{
v.x /= s;
v.y /= s;
return v;
}
using Dist2_f32 = f32;
inline Dist2_f32 distance( Pos2_f32 a, Pos2_f32 b )
@ -52,17 +153,90 @@ struct Vel2_f32
}
};
inline Vel2_f32 velocity( Pos2_f32 a, Pos2_f32 b )
template<>
inline Vel2_f32 tmpl_cast< Vel2_f32, Vec2_f32 >( Vec2_f32 vec )
{
Vec2_f32 result = b - a;
return pcast( Vel2_f32, result );
return pcast( Vel2_f32, vec );
}
inline Pos2_f32& operator+=( Pos2_f32& pos, Vel2_f32 const& vel )
template<>
constexpr Vel2_f32 tmpl_zero< Vel2_f32 >()
{
pos.x += vel.x;
pos.y += vel.y;
return pos;
return { 0, 0 };
}
inline Vel2_f32 abs( Vel2_f32 v )
{
Vel2_f32 result { abs( v.x ), abs( v.y ) };
return result;
}
inline f32 magnitude( Vel2_f32 v )
{
f32 result = sqrt( v.x * v.x + v.y * v.y );
return result;
}
inline Vel2_f32 normalize( Vel2_f32 v )
{
f32 square_size = v.x * v.x + v.y * v.y;
if ( square_size < scast( f32, 1e-4 ) )
{
return Zero( Vel2_f32 );
}
f32 mag = sqrt( square_size );
Vel2_f32 result { v.x / mag, v.y / mag };
return result;
}
inline Vel2_f32 operator-( Vel2_f32 v )
{
Vel2_f32 result { -v.x, -v.y };
return result;
}
inline Vel2_f32 operator+( Vel2_f32 a, Vel2_f32 b )
{
Vel2_f32 result { a.x + b.x, a.y + b.y };
return result;
}
inline Vel2_f32 operator-( Vel2_f32 a, Vel2_f32 b )
{
Vel2_f32 result { a.x - b.x, a.y - b.y };
return result;
}
inline Vel2_f32 operator*( Vel2_f32 v, f32 s )
{
Vel2_f32 result { v.x * s, v.y * s };
return result;
}
inline Vel2_f32 operator*( f32 s, Vel2_f32 v )
{
Vel2_f32 result { v.x * s, v.y * s };
return result;
}
inline Vel2_f32 operator/( Vel2_f32 v, f32 s )
{
Vel2_f32 result { v.x / s, v.y / s };
return result;
}
inline Vel2_f32& operator+=( Vel2_f32& a, Vel2_f32 b )
{
a.x += b.x;
a.y += b.y;
return a;
}
inline Vel2_f32& operator-=( Vel2_f32& a, Vel2_f32 b )
{
a.x -= b.x;
a.y -= b.y;
return a;
}
inline Vel2_f32& operator*=( Vel2_f32& v, f32 s )
@ -72,6 +246,13 @@ inline Vel2_f32& operator*=( Vel2_f32& v, f32 s )
return v;
}
inline Vel2_f32& operator/=( Vel2_f32& v, f32 s )
{
v.x /= s;
v.y /= s;
return v;
}
struct Accel2_f32
{
union
@ -91,110 +272,195 @@ struct Accel2_f32
}
};
inline Accel2_f32 acceleration( Vel2_f32 a, Vel2_f32 b )
template<>
inline Accel2_f32 tmpl_cast< Accel2_f32, Vec2_f32 >( Vec2_f32 vec )
{
Vec2_f32 result = b - a;
return pcast( Accel2_f32, result );
return pcast( Accel2_f32, vec );
}
struct Pos2_s32
template<>
constexpr Accel2_f32 tmpl_zero< Accel2_f32 >()
{
union
{
struct
{
s32 x;
s32 y;
};
return { 0, 0 };
}
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 )
inline Accel2_f32 abs( Accel2_f32 v )
{
s32 x = b.x - a.x;
s32 y = b.y - a.y;
Dist2_s32 result = sqrt( x * x + y * y );
Accel2_f32 result { abs( v.x ), abs( v.y ) };
return result;
}
struct Vel2_s32
inline f32 magnitude( Accel2_f32 v )
{
union
{
struct
{
s32 x;
s32 y;
};
f32 result = sqrt( v.x * v.x + v.y * v.y );
return result;
}
s32 Basis[ 2 ];
};
operator Vec2_s32()
inline Accel2_f32 normalize( Accel2_f32 v )
{
f32 square_size = v.x * v.x + v.y * v.y;
if ( square_size < scast( f32, 1e-4 ) )
{
return *rcast( Vec2_s32*, this );
return Zero( Accel2_f32 );
}
};
inline Vel2_s32 velocity( Pos2_s32 a, Pos2_s32 b )
{
Vec2_s32 result = b - a;
return pcast( Vel2_s32, result );
f32 mag = sqrt( square_size );
Accel2_f32 result { v.x / mag, v.y / mag };
return result;
}
inline Pos2_s32& operator+=( Pos2_s32& pos, Vel2_s32 const& vel )
inline Accel2_f32 operator-( Accel2_f32 v )
{
pos.x += vel.x;
pos.y += vel.y;
return pos;
Accel2_f32 result { -v.x, -v.y };
return result;
}
inline Vel2_s32& operator*=( Vel2_s32& v, s32 s )
inline Accel2_f32 operator+( Accel2_f32 a, Accel2_f32 b )
{
Accel2_f32 result { a.x + b.x, a.y + b.y };
return result;
}
inline Accel2_f32 operator-( Accel2_f32 a, Accel2_f32 b )
{
Accel2_f32 result { a.x - b.x, a.y - b.y };
return result;
}
inline Accel2_f32 operator*( Accel2_f32 v, f32 s )
{
Accel2_f32 result { v.x * s, v.y * s };
return result;
}
inline Accel2_f32 operator*( f32 s, Accel2_f32 v )
{
Accel2_f32 result { v.x * s, v.y * s };
return result;
}
inline Accel2_f32 operator/( Accel2_f32 v, f32 s )
{
Accel2_f32 result { v.x / s, v.y / s };
return result;
}
inline Accel2_f32& operator+=( Accel2_f32& a, Accel2_f32 b )
{
a.x += b.x;
a.y += b.y;
return a;
}
inline Accel2_f32& operator-=( Accel2_f32& a, Accel2_f32 b )
{
a.x -= b.x;
a.y -= b.y;
return a;
}
inline Accel2_f32& operator*=( Accel2_f32& v, f32 s )
{
v.x *= s;
v.y *= s;
return v;
}
struct Accel2_s32
inline Accel2_f32& operator/=( Accel2_f32& v, f32 s )
{
v.x /= s;
v.y /= s;
return v;
}
struct Dir2_f32
{
union
{
struct
{
s32 x;
s32 y;
f32 x;
f32 y;
};
s32 Basis[ 2 ];
f32 Basis[ 2 ];
};
operator Vec2_s32()
operator Vec2_f32()
{
return *rcast( Vec2_s32*, this );
return *rcast( Vec2_f32*, this );
}
operator Vel2_f32()
{
return *rcast( Vel2_f32*, this );
}
operator Accel2_f32()
{
return *rcast( Accel2_f32*, this );
}
};
inline Accel2_s32 acceleration( Vel2_s32 a, Vel2_s32 b )
template<>
inline Dir2_f32 tmpl_cast< Dir2_f32, Vec2_f32 >( Vec2_f32 vec )
{
Vec2_s32 result = b - a;
return pcast( Accel2_s32, result );
f32 abs_sum = abs( vec.x + vec.y );
if ( is_nearly_zero( abs_sum - 1 ) )
return pcast( Dir2_f32, vec );
Vec2_f32 normalized = normalize( vec );
return pcast( Dir2_f32, normalized );
}
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;
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 * engine::get_context()->delta_time;
pos.y += vel.y * engine::get_context()->delta_time;
return pos;
}
inline Accel2_f32 acceleration( Vel2_f32 a, Vel2_f32 b )
{
Vec2_f32 result = b - a;
return pcast( Accel2_f32, result );
}
inline Vel2_f32& operator+=( Vel2_f32& vel, Accel2_f32 const accel )
{
vel.x += accel.x * engine::get_context()->delta_time;
vel.y += accel.y * engine::get_context()->delta_time;
return vel;
}
inline Dir2_f32 direction( Pos2_f32 pos_a, Pos2_f32 pos_b )
{
Vec2_f32 diff = pos_b - pos_a;
f32 mag = magnitude( diff );
Dir2_f32 result { diff.x / mag, diff.y / mag };
return result;
}
inline Dir2_f32 direction( Vel2_f32 vel )
{
f32 mag = magnitude( vel );
Dir2_f32 result { vel.x / mag, vel.y / mag };
return result;
}
inline Dir2_f32 direction( Accel2_f32 accel )
{
f32 mag = magnitude( accel );
Dir2_f32 result { accel.x / mag, accel.y / mag };
return result;
}
using Pos2 = Pos2_f32;
using Dir2 = Dir2_f32;
using Dist2 = Dist2_f32;
using Vel2 = Vel2_f32;
using Accel2 = Accel2_f32;

View File

@ -31,6 +31,24 @@ inline Vec2_f32 abs( Vec2_f32 v )
return result;
}
inline f32 magnitude( Vec2_f32 v )
{
f32 result = sqrt( v.x * v.x + v.y * v.y );
return result;
}
inline Vec2_f32 normalize( Vec2_f32 v )
{
f32 square_size = v.x * v.x + v.y * v.y;
if ( square_size < scast( f32, 1e-4 ) )
{
return Zero( Vec2_f32 );
}
f32 mag = sqrt( square_size );
Vec2_f32 result { v.x / mag, v.y / mag };
return result;
}
inline Vec2_f32 operator-( Vec2_f32 v )
{
Vec2_f32 result { -v.x, -v.y };
@ -55,6 +73,12 @@ inline Vec2_f32 operator*( Vec2_f32 v, f32 s )
return result;
}
inline Vec2_f32 operator*( f32 s, Vec2_f32 v )
{
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 };
@ -115,6 +139,24 @@ inline Vec2_s32 abs( Vec2_s32 v )
return result;
}
inline s32 magnitude( Vec2_s32 v )
{
s32 result = sqrt( v.x * v.x + v.y * v.y );
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 };
@ -139,6 +181,12 @@ inline Vec2_s32 operator*( Vec2_s32 v, s32 s )
return result;
}
inline Vec2_s32 operator*( s32 s, Vec2_s32 v )
{
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 };

View File

@ -0,0 +1,4 @@
#pragma once
#if INTELLISENSE_DIRECTIVES
#endif

View File

@ -75,6 +75,7 @@ struct PlayerState
f32 height;
engine::TileMapPos position;
Vel2 move_velocity;
b32 mid_jump;
f32 jump_time;

View File

@ -14,16 +14,18 @@ Handmade Engine Translation Unit
#include "platform/math_constants.hpp"
#include "platform/types.hpp"
#include "platform/intrinsics.hpp"
#include "platform/float_ops.hpp"
#include "platform/strings.hpp"
#include "platform/context.hpp"
#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"
// Physics Depends on stuff in engine.hpp for now.
#include "gen/physics.hpp"
#include "engine_to_platform_api.hpp"
// Game layer headers

View File

@ -14,6 +14,7 @@ Handmade Win32 Platform Translation Unit
#include "math_constants.hpp"
#include "types.hpp"
#include "intrinsics.hpp"
#include "float_ops.hpp"
#include "strings.hpp"
#include "context.hpp"
#include "platform.hpp"
@ -21,10 +22,10 @@ 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"
#include "engine/gen/physics.hpp"
#include "engine/engine_to_platform_api.hpp"
#include "engine/gen/engine_symbols.gen.hpp"

View File

@ -0,0 +1,17 @@
#pragma once
#if INTELLISENSE_DIRECTIVES
#include "types.hpp"
#include "intrinsics.hpp"
#endif
#define mili_accuracy 0.001
#define micro_accuracy 0.00001
#define nano_accuracy 0.000000001
b32 is_nearly_zero( f32 value, f32 accuracy = mili_accuracy ) {
return abs(value) < accuracy;
}
f32 square( f32 value ) {
return value * value;
}

View File

@ -12,3 +12,10 @@ void swap( Type& a, Type& b )
#define Zero( type ) tmpl_zero<type>()
template< class Type >
constexpr Type tmpl_zero();
// Custom casting trait for when you cannot define an implicit cast ergonomically.
#define cast( type, obj ) tmpl_cast<type, decltype(obj)>( obj )
template< class Type, class OtherType >
constexpr Type tmpl_cast( OtherType obj ) {
static_assert( false, "No overload templated cast defined for type combination. Define this using an overload of tmpl_cast specialization." );
}

View File

@ -38,6 +38,9 @@
#define F64_MIN 2.2250738585072014e-308
#define F64_MAX 1.7976931348623157e+308
#define F32_EPSILON 1.1920929e-7f
#define F64_EPSILON 2.220446049250313e-16
#if defined( COMPILER_MSVC )
# if _MSC_VER < 1300
typedef unsigned char u8;

View File

@ -936,6 +936,7 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
engine_api_load_time = engine_api_current_time;
unload_engine_module_api( & engine_api );
engine_api = load_engine_module_api();
engine_api.on_module_reload( & engine_memory, & platform_api );
} while (0);