mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-12-21 22:14:43 -08:00
Day 43 complete
This commit is contained in:
parent
dddf8a1653
commit
e1a481f4f6
@ -33,7 +33,7 @@ Module build order:
|
||||
|
||||
## Milestone
|
||||
|
||||
Day 40 : Cursor Hiding and Fullscreen Support
|
||||
Day 43 : The Equations of Motion
|
||||
|
||||
Features Done so far:
|
||||
|
||||
@ -68,9 +68,11 @@ Features Done so far:
|
||||
* Basic rendering
|
||||
* Linear alpha blending
|
||||
* Anchored to center position
|
||||
* Experimental type sytem for physics vectors.
|
||||
|
||||
## Gallery
|
||||
|
||||
![img](docs/imgs/10x_2023-10-28_16-58-16.gif)
|
||||
![img](docs/imgs/10x_2023-10-22_01-44-21.gif)
|
||||
![img](docs/imgs/handmade_win32_2023-10-21_22-18-47.gif)
|
||||
![img](docs/imgs/handmade_win32_2023-10-21_02-16-43.png)
|
||||
|
37
docs/Day 043.md
Normal file
37
docs/Day 043.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Day 43
|
||||
|
||||
My little experiment with making a types of vectors for the physical interpreations
|
||||
used when doing basic 2D physics actually produced some interesting results.
|
||||
|
||||
I made types for position, distance, direction, velocity, and acceleration so far.
|
||||
Right now at the level of complexity our "physics" code is operating at they feel more
|
||||
"in the way" than actually something helping us with intuition or productivity.
|
||||
|
||||
However, when Casey explained that delta-time is essentially applied to intergrate to "lower" frame of time;
|
||||
I realized that you could technically compress the application of delta time when you apply acceleration to velocity, velocity to position, etc.
|
||||
|
||||
```cpp
|
||||
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 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;
|
||||
}
|
||||
```
|
||||
|
||||
The of this encapsulation is that the operators need to have awareness of the delta time from some context.
|
||||
So in a sense your enforcing that there is an implicit delta universally.
|
||||
For now I'm making that context just the engine's known delta from the platform's frametime.
|
||||
|
||||
This most likely would get more complex if there are multiple physics threads or substepping is involved.
|
||||
I'm also not sure how much performance is also sacrificed with this approach since an indirection was introduced with having to grab the context.
|
||||
|
||||
If there is a issue with performance the user can always at worst case downcast to regular vectors and just do the math directly...
|
||||
For now I'll continue to use this approach and see how it goes.
|
BIN
docs/imgs/10x_2023-10-28_16-58-16.gif
Normal file
BIN
docs/imgs/10x_2023-10-28_16-58-16.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 MiB |
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
4
project/engine/state_and_replay.hpp
Normal file
4
project/engine/state_and_replay.hpp
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#if INTELLISENSE_DIRECTIVES
|
||||
|
||||
#endif
|
@ -75,6 +75,7 @@ struct PlayerState
|
||||
f32 height;
|
||||
|
||||
engine::TileMapPos position;
|
||||
Vel2 move_velocity;
|
||||
|
||||
b32 mid_jump;
|
||||
f32 jump_time;
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
17
project/platform/float_ops.hpp
Normal file
17
project/platform/float_ops.hpp
Normal 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;
|
||||
}
|
@ -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." );
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -121,7 +121,7 @@ function build-engine
|
||||
$should_build = (check-FileForChanges $unit) -eq $true
|
||||
if ( $should_build )
|
||||
{
|
||||
$executable = Join-Path $path_build 'engine_gen.exe'
|
||||
$executable = Join-Path $path_build 'engine_gen.exe'
|
||||
|
||||
$compiler_args = @()
|
||||
$compiler_args += ( $flag_define + 'GEN_TIME' )
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user