Day 34 complete!!!

This commit is contained in:
Edward R. Gonzalez 2023-10-11 17:52:13 -04:00
parent 7958fabd00
commit a4f07c67d2
25 changed files with 670 additions and 564 deletions

View File

@ -14,7 +14,7 @@
"label": "Static Data"
},
{
"line": 1002,
"line": 1001,
"column": 0,
"label": "Main Loop : End"
}

View File

@ -57,10 +57,11 @@ Features Done so far:
* Allows for engine or game state to be restored even if a crash occurs to exact memory state it was before.
* Basic input abstraction into hard-coded actions (``EngineActions` & `PlayerActions`)
* Record & replay input.
* (WIP) : 2D Tile Map setup
* (WIP) : 2D Tile Map (Virtualized into chunks)
## Gallery
![img](docs/imgs/handmade_win32_2023-10-11_23-39-57.gif)
![img](docs/imgs/handmade_win32_2023-10-11_00-47-19.gif)
![img](docs/imgs/handmade_win32_2023-10-10_13-13-14.gif)
![img](docs/imgs/handmade_win32_2023-10-06_12-43-47.gif)

6
docs/Day 034.md Normal file
View File

@ -0,0 +1,6 @@
# Day 34
Casey decided to start offloading tile map definitions to separate files so I took the time to also cleanup some of the organization of the code.
I'm still keeping some cpp files directly included within engine.cpp and win32_platform.cpp for now (instead of their translation unit files). I'll problably wait till much later to offload them.
Making that first baby step for procedural gen, and proper tile_chunk memory felt pretty good after many vods of stumbling.

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

View File

@ -15,12 +15,16 @@
#undef do_once_end
using namespace gen;
#include "platform/platform_module.hpp"
#include "platform/grime.hpp"
#include "platform/macros.hpp"
#include "platform/types.hpp"
#include "platform/strings.hpp"
#include "platform/platform.hpp"
#include "engine/engine_module.hpp"
#include "engine/input.hpp"
#include "engine/tile_map.hpp"
#include "engine/engine.hpp"
#include "engine/engine_to_platform_api.hpp"

View File

@ -1,7 +1,12 @@
#if INTELLISENSE_DIRECTIVES
#include "engine.hpp"
#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"
#endif
NS_ENGINE_BEGIN
@ -43,6 +48,11 @@ struct EngineActions
struct EngineState
{
hh::Memory game_memory;
MemoryArena world_arena;
World* world;
f32 auto_snapshot_interval;
f32 auto_snapshot_timer;
@ -55,15 +65,15 @@ struct EngineState
f32 sample_wave_sine_time;
b32 sample_wave_switch;
hh::Memory game_memory;
};
NS_ENGINE_END
// TODO(Ed) : does this need to be here or can it be moved to handmade_engine.cpp?
#include "test_samples.cpp"
#if Build_Development
// TODO(Ed) : Do a proper header/src pair for this
#include "state_and_replay.cpp"
// Build_Development
#endif
@ -121,7 +131,8 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
{
DualsensePadState* pad = controller->ds_pad;
actions->jump |= pressed( pad->cross );
actions->sprint |= pressed( pad->circle );
actions->jump |= pressed( pad->cross );
actions->player_x_move_analog += pad->stick.left.X.end;
actions->player_y_move_analog += pad->stick.left.Y.end;
@ -130,7 +141,8 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
{
XInputPadState* pad = controller->xpad;
actions->jump |= pressed( pad->A );
actions->sprint |= pressed( pad->B );
actions->jump |= pressed( pad->A );
actions->player_x_move_analog += pad->stick.left.X.end;
actions->player_y_move_analog += pad->stick.left.Y.end;
@ -139,7 +151,8 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
if ( controller->keyboard )
{
KeyboardState* keyboard = controller->keyboard;
actions->jump |= pressed( keyboard->space );
actions->jump |= pressed( keyboard->space );
actions->sprint |= keyboard->left_shift.ended_down;
actions->player_x_move_digital += keyboard->D.ended_down - keyboard->A.ended_down;
actions->player_y_move_digital += keyboard->W.ended_down - keyboard->S.ended_down;
@ -151,8 +164,8 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
}
}
internal void
output_sound( EngineState* state, AudioBuffer* sound_buffer, GetSoundSampleValueFn* get_sample_value )
internal
void output_sound( EngineState* state, AudioBuffer* sound_buffer, GetSoundSampleValueFn* get_sample_value )
{
s16* sample_out = sound_buffer->samples;
for ( s32 sample_index = 0; sample_index < sound_buffer->num_samples; ++ sample_index )
@ -223,122 +236,55 @@ void draw_rectangle( OffscreenBuffer* buffer
}
inline
void cannonicalize_coord( World* world, u32* tile_coord, f32* pos_coord )
void draw_debug_point(OffscreenBuffer* back_buffer, World* world, TileMapPosition pos, f32 red, f32 green, f32 blue)
{
f32 tile_size = scast(f32, world->tile_size_in_meters);
TileMap* tile_map = world->tile_map;
// Note(Ed) : World is assumed to be a "torodial topology"
s32 offset = floor( (* pos_coord) / tile_size );
u32 new_tile_coord = (* tile_coord) + offset;
f32 new_pos_coord = (* pos_coord) - scast(f32, offset) * tile_size;
assert( new_pos_coord >= 0 );
assert( new_pos_coord <= tile_size );
(* tile_coord) = new_tile_coord;
(* pos_coord) = new_pos_coord;
draw_rectangle(back_buffer,
pos.x * tile_map->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * tile_map->tile_size_in_pixels),
pos.y * tile_map->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * tile_map->tile_size_in_pixels),
(pos.x + 0.1f) * tile_map->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * tile_map->tile_size_in_pixels),
(pos.y + 0.1f) * tile_map->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * tile_map->tile_size_in_pixels),
red, green, blue);
}
inline
WorldPosition recannonicalize_position( World* world, WorldPosition pos )
internal
void MemoryArena_init( MemoryArena* arena, ssize size, Byte* storage )
{
WorldPosition result = pos;
cannonicalize_coord( world, & result.tile_x, & result.x );
cannonicalize_coord( world, & result.tile_y, & result.y );
arena->storage = storage;
arena->size = size;
arena->used = 0;
}
#define MemoryArena_push_struct( arena, type ) MemoryArena__push_struct<type>( arena )
template< typename Type > inline
Type* MemoryArena__push_struct( MemoryArena* arena )
{
assert( arena != nullptr );
ssize type_size = sizeof( Type );
assert( arena->used + type_size <= arena->size );
Type* result = rcast(Type*, arena->storage + arena->used);
arena->used += type_size;
return result;
}
inline
u32 TileChunk_tile_value( TileChunk* tile_chunk, World* world, u32 x, u32 y )
#define MemoryArena_push_array( arena, type, num ) MemoryArena__push_array<type>( arena, num )
template< typename Type> inline
Type* MemoryArena__push_array( MemoryArena* arena, ssize num )
{
assert( world != nullptr );
assert( tile_chunk != nullptr );
assert( x < world->chunk_dimension );
assert( y < world->chunk_dimension );
u32 value = tile_chunk->tiles[ (y * world->chunk_dimension) + x ];
return value;
}
// TODO(Ed) : Review if this is needed anymore?
#if 0
inline
b32 TileChunk_is_tile_empty( TileChunk* tile_chunk, World* world, u32 tile_x, u32 tile_y )
{
//assert( tile_chunk != nullptr );
assert( world != nullptr );
// Assume space is occupied if there is bad data
if ( tile_chunk == nullptr )
return false;
b32 is_empty = false;
u32 tile_value = TileChunk_tile_value( tile_chunk, world, tile_x, tile_y );
is_empty = tile_value == 0;
return is_empty;
}
#endif
inline
TileChunk* World_get_tile_chunk( World* world, s32 tile_chunk_x, s32 tile_chunk_y )
{
TileChunk* chunk = nullptr;
if ( tile_chunk_x >= 0 && tile_chunk_x < scast(s32, world->tile_chunks_num_x)
&& tile_chunk_y >= 0 && tile_chunk_y < scast(s32, world->tile_chunks_num_y) )
{
chunk = & world->tile_chunks[ tile_chunk_y * world->tile_chunks_num_x + tile_chunk_x ];
}
return chunk;
}
inline
TileChunkPosition get_tile_chunk_position_for( World* world, u32 abs_tile_x, u32 abs_tile_y )
{
TileChunkPosition chunk_pos {};
chunk_pos.tile_chunk_x = abs_tile_x >> world->chunk_shift;
chunk_pos.tile_chunk_y = abs_tile_y >> world->chunk_shift;
chunk_pos.tile_x = abs_tile_x & world->chunk_mask;
chunk_pos.tile_y = abs_tile_y & world->chunk_mask;
return chunk_pos;
}
internal // TODO(Ed) : Review if he keeps this crap.
u32 piggy_get_tile_value( World* world, u32 tile_x, u32 tile_y )
{
assert( world != nullptr );
u32 value = 0;
TileChunkPosition chunk_pos = get_tile_chunk_position_for( world, tile_x, tile_y );
TileChunk* chunk = World_get_tile_chunk( world, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y );
if ( chunk )
value = TileChunk_tile_value( chunk, world, chunk_pos.tile_x, chunk_pos.tile_y );
return value;
}
internal
b32 world_is_point_empty( World* world, WorldPosition position )
{
assert( world != nullptr );
u32 chunk_value = piggy_get_tile_value( world, position.tile_x, position.tile_y );
b32 is_empty = chunk_value == 0;
return is_empty;
}
inline
void draw_debug_point(OffscreenBuffer* back_buffer, World* world, WorldPosition pos, f32 red, f32 green, f32 blue)
{
draw_rectangle(back_buffer,
pos.x * world->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels),
pos.y * world->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels),
(pos.x + 0.1f) * world->tile_meters_to_pixels + world->tile_lower_left_x + scast(f32, pos.tile_x * world->tile_size_in_pixels),
(pos.y + 0.1f) * world->tile_meters_to_pixels + world->tile_lower_left_y + scast(f32, pos.tile_y * world->tile_size_in_pixels),
red, green, blue);
assert( arena != nullptr );
ssize mem_amount = sizeof( Type ) * num;
assert( arena->used + mem_amount <= arena->size );
Type* result = rcast(Type*, arena->storage + arena->used);
arena->used += mem_amount;
return result;
}
Engine_API
@ -348,7 +294,7 @@ void on_module_reload( Memory* memory, platform::ModuleAPI* platfom_api )
}
Engine_API
void startup( Memory* memory, platform::ModuleAPI* platform_api )
void startup( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* platform_api )
{
#if Build_Development
memory->active_snapshot_slot = 1;
@ -380,22 +326,88 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api )
state->sample_wave_sine_time = 0.f;
state->renderer_paused = false;
state->game_memory.persistent_size = memory->persistent_size / 2;
state->game_memory.persistent_size = memory->persistent_size / Memory::game_memory_factor;
state->game_memory.persistent = rcast(Byte*, memory->persistent) + state->game_memory.persistent_size;
state->game_memory.transient_size = memory->transient_size / 2;
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 setup
{
ssize world_arena_size = memory->engine_persistent_size() - sizeof(EngineState);
Byte* world_arena_storage = memory->persistent + sizeof(EngineState);
MemoryArena_init( & state->world_arena, world_arena_size, world_arena_storage );
state->world = MemoryArena_push_struct( & state->world_arena, World);
World* world = state->world;
TileMap* tile_map = MemoryArena_push_struct( & state->world_arena, TileMap);
world->tile_map = tile_map;
tile_map->chunk_shift = 4;
tile_map->chunk_mask = (1 << tile_map->chunk_shift) - 1;
tile_map->chunk_dimension = (1 << tile_map->chunk_shift);
tile_map->tile_chunks_num_x = 128;
tile_map->tile_chunks_num_y = 128;
tile_map->chunks = MemoryArena_push_array( & state->world_arena, TileChunk, tile_map->tile_chunks_num_x * tile_map->tile_chunks_num_y );
for ( s32 y = 0; y < tile_map->tile_chunks_num_y; ++ y )
{
for ( s32 x = 0; x < tile_map->tile_chunks_num_x; ++ x )
{
ssize num_tiles = tile_map->chunk_dimension * tile_map->chunk_dimension;
tile_map->chunks[ (y * tile_map->tile_chunks_num_x) + x ].tiles = MemoryArena_push_array( & state->world_arena, u32, num_tiles );
}
}
//TileChunk temp_chunk;
//temp_chunk.tiles = rcast( u32*, & temp_tiles );
//tile_map->chunks = & temp_chunk;
tile_map->tile_size_in_meters = 1.4f;
tile_map->tile_size_in_pixels = 85;
tile_map->tile_meters_to_pixels = scast(f32, tile_map->tile_size_in_pixels) / tile_map->tile_size_in_meters;
f32 tile_size_in_pixels = scast(f32, tile_map->tile_size_in_pixels);
world->tile_lower_left_x = -( tile_size_in_pixels * 0.5f);
world->tile_lower_left_y = +( tile_size_in_pixels * 0.25f) + scast(f32, back_buffer->height);
u32 tiles_per_screen_x = 17;
u32 tiles_per_screen_y = 9;
for ( u32 screen_y = 0; screen_y < 32; ++ screen_y )
{
for ( u32 screen_x = 0; screen_x < 32; ++ screen_x )
{
for (u32 tile_y = 0; tile_y < tiles_per_screen_y; ++ tile_y )
{
for ( u32 tile_x = 0; tile_x < tiles_per_screen_x; ++ tile_x )
{
u32 abs_tile_x = screen_x * tiles_per_screen_x + tile_x;
u32 abs_tile_y = screen_y * tiles_per_screen_y + tile_y;
u32 tile_value = tile_x == tile_y && tile_y % 2 ? 1 : 0;
TileMap_set_tile_value( & state->world_arena, world->tile_map, abs_tile_x, abs_tile_y, tile_value );
}
}
}
}
}
hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent );
assert( sizeof(hh::GameState) <= state->game_memory.persistent_size );
hh::PlayerState* player = & game_state->player_state;
player->position.tile_x = 3;
player->position.tile_y = 3;
player->position.tile_x = 4;
player->position.tile_y = 4;
player->position.x = 0.f;
player->position.y = 0.f;
player->mid_jump = false;
player->jump_time = 0.f;
player->height = 1.4f;
player->width = player->height * 0.7f;
}
Engine_API
@ -549,63 +561,21 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
f32 x_offset_f = scast(f32, state->x_offset);
f32 y_offset_f = scast(f32, state->y_offset);
constexpr s32 tile_map_num_x = 256;
constexpr s32 tile_map_num_y = 256;
// tiles_XY
u32 temp_tiles [tile_map_num_y][tile_map_num_x] = {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};
World world;
world.chunk_shift = 8;
world.chunk_mask = (1 << world.chunk_shift) - 1;
world.chunk_dimension = 256;
world.tile_chunks_num_x = 1;
world.tile_chunks_num_y = 1;
TileChunk temp_chunk;
temp_chunk.tiles = rcast( u32*, & temp_tiles );
world.tile_chunks = & temp_chunk;
world.tile_size_in_meters = 1.4f;
world.tile_size_in_pixels = 85;
world.tile_meters_to_pixels = scast(f32, world.tile_size_in_pixels) / world.tile_size_in_meters;
f32 tile_size_in_pixels = scast(f32, world.tile_size_in_pixels);
f32 scale = 85;
world.tile_lower_left_x = -( tile_size_in_pixels * 0.5f);
world.tile_lower_left_y = +( tile_size_in_pixels * 0.25f) + scast(f32, back_buffer->height);
player->height = 1.4f;
player->width = player->height * 0.7f;
World* world = state->world;
TileMap* tile_map = world->tile_map;
f32 tile_size_in_pixels = scast(f32, tile_map->tile_size_in_pixels);
f32 player_half_width = player->width / 2.f;
f32 player_quarter_height = player->height / 4.f;
input_poll_player_actions( input, & player_actions );
{
f32 move_speed = 4.f;
f32 move_speed = 2.f;
if ( player_actions.sprint )
{
move_speed = 6.f;
}
f32 new_player_pos_x = player->position.x;
f32 new_player_pos_y = player->position.y;
@ -623,53 +593,52 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
b32 valid_new_pos = true;
{
WorldPosition test_pos = {
TileMapPosition test_pos = {
new_player_pos_x, new_player_pos_y,
player->position.tile_x, player->position.tile_y
};
test_pos = recannonicalize_position( & world, test_pos );
test_pos = recannonicalize_position( tile_map, test_pos );
// TODO(Ed) : Need a delta-function that auto-reconnonicalizes.
WorldPosition test_pos_nw {
new_player_pos_x - player_half_width, new_player_pos_y - player_quarter_height,
TileMapPosition test_pos_nw {
new_player_pos_x - player_half_width, new_player_pos_y + player_quarter_height,
player->position.tile_x, player->position.tile_y
};
test_pos_nw = recannonicalize_position( & world, test_pos_nw );
valid_new_pos &= world_is_point_empty( & world, test_pos_nw );
test_pos_nw = recannonicalize_position( tile_map, test_pos_nw );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_nw );
WorldPosition test_pos_ne {
new_player_pos_x + player_half_width, new_player_pos_y - player_quarter_height,
TileMapPosition 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
};
test_pos_ne = recannonicalize_position( & world, test_pos_ne );
valid_new_pos &= world_is_point_empty( & world, test_pos_ne );
test_pos_ne = recannonicalize_position( tile_map, test_pos_ne );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_ne );
WorldPosition test_pos_sw {
TileMapPosition test_pos_sw {
new_player_pos_x - player_half_width, new_player_pos_y,
player->position.tile_x, player->position.tile_y
};
test_pos_sw = recannonicalize_position( & world, test_pos_sw );
valid_new_pos &= world_is_point_empty( & world, test_pos_sw );
test_pos_sw = recannonicalize_position( tile_map, test_pos_sw );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_sw );
WorldPosition test_pos_se {
TileMapPosition test_pos_se {
new_player_pos_x + player_half_width, new_player_pos_y,
player->position.tile_x, player->position.tile_y
};
test_pos_se = recannonicalize_position( & world, test_pos_se );
valid_new_pos &= world_is_point_empty( & world, test_pos_se );
test_pos_se = recannonicalize_position( tile_map, test_pos_se );
valid_new_pos &= TileMap_is_point_empty( tile_map, test_pos_se );
}
if ( valid_new_pos )
{
WorldPosition new_pos = {
TileMapPosition new_pos = {
new_player_pos_x, new_player_pos_y,
player->position.tile_x, player->position.tile_y
};
player->position = recannonicalize_position( & world, new_pos );
player->position = recannonicalize_position( tile_map, new_pos );
}
if ( player->jump_time > 0.f )
{
player->jump_time -= delta_time;
@ -693,10 +662,9 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
, 1.f, 0.24f, 0.24f );
// Scrolling shitshow
#if 1
f32 center_x = 0.5f * scast(f32, back_buffer->width);
f32 center_y = 0.5f * scast(f32, back_buffer->height);
// Scrolling
f32 screen_center_x = 0.5f * scast(f32, back_buffer->width);
f32 screen_center_y = 0.5f * scast(f32, back_buffer->height);
for ( s32 relative_row = -10; relative_row < +10; ++ relative_row )
{
@ -705,7 +673,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
u32 col = player->position.tile_x + relative_col;
u32 row = player->position.tile_y + relative_row;
u32 tileID = piggy_get_tile_value( & world, col, row );
u32 tileID = TileMap_get_tile_value( tile_map, col, row );
f32 color[3] = { 0.15f, 0.15f, 0.15f };
if ( tileID == 1 )
@ -722,14 +690,17 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
color[2] = 0.3f;
}
f32 min_x = center_x + scast(f32, relative_col) * tile_size_in_pixels;
f32 min_y = center_y - scast(f32, relative_row) * tile_size_in_pixels;
f32 max_x = min_x + tile_size_in_pixels;
f32 max_y = min_y - tile_size_in_pixels;
f32 center_x = screen_center_x + scast(f32, relative_col) * tile_size_in_pixels - player->position.x * tile_map->tile_meters_to_pixels;
f32 center_y = screen_center_y - scast(f32, relative_row) * tile_size_in_pixels + player->position.y * tile_map->tile_meters_to_pixels;
f32 min_x = center_x - tile_size_in_pixels * 0.5f;
f32 min_y = center_y - tile_size_in_pixels * 0.5f;
f32 max_x = center_x + tile_size_in_pixels * 0.5f;
f32 max_y = center_y + tile_size_in_pixels * 0.5f;
draw_rectangle( back_buffer
, min_x, max_y
, max_x, min_y
, min_x, min_y
, max_x, max_y
, color[0], color[1], color[2] );
}
}
@ -739,88 +710,18 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
f32 player_green = 0.7f;
f32 player_blue = 0.3f;
f32 player_tile_x_offset = center_x + scast(f32, player->position.tile_x) * world.tile_meters_to_pixels;
f32 player_tile_y_offset = center_y - scast(f32, player->position.tile_y) * world.tile_meters_to_pixels;
f32 player_tile_x_offset = screen_center_x + scast(f32, player->position.tile_x) * tile_map->tile_meters_to_pixels + player->position.x * tile_map->tile_meters_to_pixels;
f32 player_tile_y_offset = screen_center_y - scast(f32, player->position.tile_y) * tile_map->tile_meters_to_pixels + player->position.y * tile_map->tile_meters_to_pixels;
f32 player_screen_pos_x = center_x + player->position.x * world.tile_meters_to_pixels;
f32 player_screen_pos_y = center_y - player->position.y * world.tile_meters_to_pixels;
f32 player_screen_pos_x = screen_center_x;
f32 player_screen_pos_y = screen_center_y;
// player_min_x = player_tile_x_offset - player_half_width * world;
draw_rectangle( back_buffer
, player_screen_pos_x - player_half_width * world.tile_meters_to_pixels, player_screen_pos_y - player->height * world.tile_meters_to_pixels
, player_screen_pos_x + player_half_width * world.tile_meters_to_pixels, player_screen_pos_y
, player_screen_pos_x - player_half_width * tile_map->tile_meters_to_pixels, player_screen_pos_y - player->height * tile_map->tile_meters_to_pixels
, player_screen_pos_x + player_half_width * tile_map->tile_meters_to_pixels, player_screen_pos_y
, player_red, player_green, player_blue );
#endif
// Non-scrolling screen
#if 0
// Draw TileChunk
for ( u32 row = 0; row < 9; ++ row )
{
for ( u32 col = 0; col < 16; ++ col )
{
u32 tileID = piggy_get_tile_value( & world, col, row );
f32 color[3] = { 0.15f, 0.15f, 0.15f };
if ( tileID == 1 )
{
color[0] = 0.22f;
color[1] = 0.22f;
color[2] = 0.22f;
}
if ( row == player->position.tile_y && col == player->position.tile_x )
{
color[0] = 0.44f;
color[1] = 0.3f;
color[2] = 0.3f;
}
#if 0
// Was able to flip Y properly but not get the center alignemnt with the world.tile_lower_left that I wanted..
f32 min_x = world.tile_lower_left_x + scast(f32, col) * tile_size_in_pixels;
f32 min_y = scast(f32, row) * tile_size_in_pixels;
f32 max_x = min_x + tile_size_in_pixels;
f32 max_y = min_y + tile_size_in_pixels;
draw_rectangle( back_buffer
, min_x, min_y
, max_x, max_y
//, min_x, max_y
//, max_x, min_y
, color[0], color[1], color[2] );
#else
f32 min_x = world.tile_lower_left_x + scast(f32, col) * tile_size_in_pixels;
f32 min_y = world.tile_lower_left_y - scast(f32, row) * tile_size_in_pixels;
f32 max_x = min_x + tile_size_in_pixels;
f32 max_y = min_y - tile_size_in_pixels;
draw_rectangle( back_buffer
, min_x, max_y
, max_x, min_y
, color[0], color[1], color[2] );
#endif
}
}
// Player
f32 player_red = 0.7f;
f32 player_green = 0.7f;
f32 player_blue = 0.3f;
f32 player_tile_x_offset = scast(f32, player->position.tile_x * world.tile_size_in_pixels);
f32 player_tile_y_offset = -scast(f32, player->position.tile_y * world.tile_size_in_pixels);
f32 player_screen_pos_x = world.tile_lower_left_x + player_tile_x_offset + player->position.x * world.tile_meters_to_pixels;
f32 player_screen_pos_y = world.tile_lower_left_y + player_tile_y_offset - player->position.y * world.tile_meters_to_pixels;
draw_rectangle( back_buffer
, player_screen_pos_x - player_half_width * world.tile_meters_to_pixels, player_screen_pos_y - player->height * world.tile_meters_to_pixels
, player_screen_pos_x + player_half_width * world.tile_meters_to_pixels, player_screen_pos_y
, player_red, player_green, player_blue );
#endif
// Auto-Snapshot percent bar
if (1)

View File

@ -6,25 +6,12 @@
#if INTELLISENSE_DIRECTIVES
#include "platform/platform.hpp"
#endif
#define NS_ENGINE_BEGIN namespace engine {
#define NS_ENGINE_END }
#ifndef Engine_API
// The build system is reponsible for defining this API macro for exporting symbols.
# define Engine_API
#include "engine_module.hpp"
#include "tile_map.hpp"
#endif
NS_ENGINE_BEGIN
enum ReplayMode : s32
{
ReplayMode_Off,
ReplayMode_Record,
ReplayMode_Playback
};
struct Clocks
{
// TODO(Ed) : Clock values...
@ -45,23 +32,49 @@ struct MemorySnapshot
u64 age;
};
enum ReplayMode : s32
{
ReplayMode_Off,
ReplayMode_Record,
ReplayMode_Playback
};
struct ReplayData
{
static constexpr
s32 Num_Snapshot_Slots = 3;
// Abuse RAM to store snapshots of the Engine or Game state.
MemorySnapshot snapshots[ Num_Snapshot_Slots ];
s32 active_snapshot_slot;
// Recording and playback info is the same for either engine or game.
ReplayMode replay_mode;
platform::File active_input_replay_file;
// Engine-wide recording & playback loop.
s32 engine_loop_active;
s32 game_loop_active;
};
struct Memory
{
// All memory for the engine is required to be zero initialized.
// Wiped on shutdown
void* persistent;
u64 persistent_size;
Byte* persistent;
ssize persistent_size;
// Wiped on a per-frame basis
// void* Frame;
// u64 FrameSize;
// Wiped whenever the engine wants to?
void* transient;
u64 transient_size;
Byte* transient;
ssize transient_size;
// TODO(Ed) : Move this crap to state & replay archive definitions?
// TODO(Ed) : Move this to state & replay archive definitions?
#if Build_Development
static constexpr
s32 Num_Snapshot_Slots = 3;
@ -77,14 +90,32 @@ struct Memory
// Engine-wide recording & playback loop.
s32 engine_loop_active;
s32 game_loop_active;
//ReplayData replay;
#endif
u64 total_size()
// The game will have 1/4 of persistent's memory available ot it.
static constexpr
ssize game_memory_factor = 4;
ssize engine_persistent_size()
{
return persistent_size - persistent_size / game_memory_factor;
}
ssize total_size()
{
return persistent_size + transient_size;
}
};
struct MemoryArena
{
Byte* storage;
ssize size;
ssize used;
};
struct OffscreenBuffer
{
void* memory; // Lets use directly mess with the "pixel's memory buffer"
@ -103,238 +134,13 @@ struct AudioBuffer
s32 num_samples;
};
struct DigitalBtn
{
s32 half_transitions;
b32 ended_down;
};
struct AnalogAxis
{
f32 start;
f32 end;
f32 min;
f32 max;
// Platform doesn't provide this, we process in the engine layer.
f32 average;
};
struct AnalogStick
{
AnalogAxis X;
AnalogAxis Y;
};
union KeyboardState
{
DigitalBtn keys[12];
struct {
DigitalBtn _1;
DigitalBtn _2;
DigitalBtn _3;
DigitalBtn _4;
DigitalBtn Q;
DigitalBtn E;
DigitalBtn W;
DigitalBtn A;
DigitalBtn S;
DigitalBtn D;
DigitalBtn K;
DigitalBtn L;
DigitalBtn escape;
DigitalBtn backspace;
DigitalBtn up;
DigitalBtn down;
DigitalBtn left;
DigitalBtn right;
DigitalBtn space;
DigitalBtn pause;
DigitalBtn left_alt;
DigitalBtn right_alt;
DigitalBtn right_shift;
DigitalBtn left_shift;
};
};
struct MousesState
{
DigitalBtn left;
DigitalBtn middle;
DigitalBtn right;
AnalogAxis X;
AnalogAxis Y;
AnalogAxis vertical_wheel;
AnalogAxis horizontal_wheel;
};
struct XInputPadState
{
struct
{
AnalogStick left;
AnalogStick right;
} stick;
AnalogAxis left_trigger;
AnalogAxis right_trigger;
union {
DigitalBtn btns[14];
struct {
struct {
DigitalBtn up;
DigitalBtn down;
DigitalBtn left;
DigitalBtn right;
} dpad;
DigitalBtn A;
DigitalBtn B;
DigitalBtn X;
DigitalBtn Y;
DigitalBtn back;
DigitalBtn start;
DigitalBtn left_shoulder;
DigitalBtn right_shoulder;
};
};
};
struct DualsensePadState
{
struct
{
AnalogStick left;
AnalogStick right;
} stick;
AnalogAxis L2;
AnalogAxis R2;
union {
DigitalBtn btns[14];
struct {
struct {
DigitalBtn up;
DigitalBtn down;
DigitalBtn left;
DigitalBtn right;
} dpad;
DigitalBtn cross;
DigitalBtn circle;
DigitalBtn square;
DigitalBtn triangle;
DigitalBtn share;
DigitalBtn options;
DigitalBtn L1;
DigitalBtn R1;
};
};
};
struct ControllerState
{
KeyboardState* keyboard;
MousesState* mouse;
XInputPadState* xpad;
DualsensePadState* ds_pad;
};
struct ControllerStateSnapshot
{
KeyboardState keyboard;
MousesState mouse;
XInputPadState xpad;
DualsensePadState ds_pad;
};
struct InputState
{
ControllerState controllers[4];
};
struct InputStateSnapshot
{
ControllerStateSnapshot controllers[4];
};
using InputBindCallback = void( void* );
using InputBindCallback_DigitalBtn = void( engine::DigitalBtn* button );
using InputBindCallback_AnalogAxis = void( engine::AnalogAxis* axis );
using InputBindCallback_AnalogStick = void( engine::AnalogStick* stick );
struct InputMode
{
InputBindCallback* binds;
s32 num_binds;
};
void input_mode_pop( InputMode* mode );
void input_mode_pop( InputMode* mode );
#if 0
struct RecordedInput
{
s32 num;
InputState* stream;
};
#endif
struct TileChunk
{
u32* tiles;
};
struct World
{
// TODO(Ed) : Remove
f32 tile_lower_left_x;
f32 tile_lower_left_y;
u32 chunk_shift;
u32 chunk_mask;
f32 tile_size_in_meters;
s32 tile_size_in_pixels;
f32 tile_meters_to_pixels;
u32 chunk_dimension;
// TODO(Ed) : Beginner's sparseness
s32 tile_chunks_num_x;
s32 tile_chunks_num_y;
TileChunk* tile_chunks;
};
/*
This is a "backend" transient datatype for handling lookup of tile data from "chunks" of tiles.
*/
struct TileChunkPosition
{
u32 tile_chunk_x;
u32 tile_chunk_y;
// "Chunk-relative (x, y)
u32 tile_x;
u32 tile_y;
};
struct WorldPosition
{
// TODO(Ed) : Should this be from the center of the tile?
f32 x;
f32 y;
// "World-relative (x, y), AKA: Absolute Position, etc
u32 tile_x;
u32 tile_y;
TileMap* tile_map;
};
NS_ENGINE_END

View File

@ -1,3 +0,0 @@
/*
This represents the API only accessible to the engine to fullfill for the game module.
*/

View File

@ -0,0 +1,14 @@
/*
This header exists for base shared definitions across engine files.
For now what every file needs is at least the namespace macros.
*/
#pragma once
#define NS_ENGINE_BEGIN namespace engine {
#define NS_ENGINE_END }
#ifndef Engine_API
// The build system is reponsible for defining this API macro for exporting symbols.
# define Engine_API
#endif

View File

@ -2,11 +2,14 @@
This represents the API only accessible to the platform layer to fullfill for the engine layer.
*/
#pragma once
#if INTELLISENSE_DIRECTIVES
#include "engine_module.hpp"
#endif
NS_ENGINE_BEGIN
using OnModuleRelaodFn = void( Memory* memory, platform::ModuleAPI* platform_api );
using StartupFn = void( Memory* memory, platform::ModuleAPI* platform_api );
using StartupFn = void( OffscreenBuffer* back_buffer, Memory* memory, platform::ModuleAPI* platform_api );
using ShutdownFn = void( Memory* memory, platform::ModuleAPI* platform_api );
// Needs a contextual reference to four things:

0
project/engine/input.cpp Normal file
View File

178
project/engine/input.hpp Normal file
View File

@ -0,0 +1,178 @@
#pragma once
#if INTELLISENSE_DIRECTIVES
#include "platform/platform.hpp"
#include "engine_module.hpp"
#endif
NS_ENGINE_BEGIN
struct DigitalBtn
{
s32 half_transitions;
b32 ended_down;
};
struct AnalogAxis
{
f32 start;
f32 end;
f32 min;
f32 max;
// Platform doesn't provide this, we process in the engine layer.
f32 average;
};
struct AnalogStick
{
AnalogAxis X;
AnalogAxis Y;
};
union KeyboardState
{
DigitalBtn keys[12];
struct {
DigitalBtn _1;
DigitalBtn _2;
DigitalBtn _3;
DigitalBtn _4;
DigitalBtn Q;
DigitalBtn E;
DigitalBtn W;
DigitalBtn A;
DigitalBtn S;
DigitalBtn D;
DigitalBtn K;
DigitalBtn L;
DigitalBtn escape;
DigitalBtn backspace;
DigitalBtn up;
DigitalBtn down;
DigitalBtn left;
DigitalBtn right;
DigitalBtn space;
DigitalBtn pause;
DigitalBtn left_alt;
DigitalBtn right_alt;
DigitalBtn right_shift;
DigitalBtn left_shift;
};
};
struct MousesState
{
DigitalBtn left;
DigitalBtn middle;
DigitalBtn right;
AnalogAxis X;
AnalogAxis Y;
AnalogAxis vertical_wheel;
AnalogAxis horizontal_wheel;
};
struct XInputPadState
{
struct
{
AnalogStick left;
AnalogStick right;
} stick;
AnalogAxis left_trigger;
AnalogAxis right_trigger;
union {
DigitalBtn btns[14];
struct {
struct {
DigitalBtn up;
DigitalBtn down;
DigitalBtn left;
DigitalBtn right;
} dpad;
DigitalBtn A;
DigitalBtn B;
DigitalBtn X;
DigitalBtn Y;
DigitalBtn back;
DigitalBtn start;
DigitalBtn left_shoulder;
DigitalBtn right_shoulder;
};
};
};
struct DualsensePadState
{
struct
{
AnalogStick left;
AnalogStick right;
} stick;
AnalogAxis L2;
AnalogAxis R2;
union {
DigitalBtn btns[14];
struct {
struct {
DigitalBtn up;
DigitalBtn down;
DigitalBtn left;
DigitalBtn right;
} dpad;
DigitalBtn cross;
DigitalBtn circle;
DigitalBtn square;
DigitalBtn triangle;
DigitalBtn share;
DigitalBtn options;
DigitalBtn L1;
DigitalBtn R1;
};
};
};
struct ControllerState
{
KeyboardState* keyboard;
MousesState* mouse;
XInputPadState* xpad;
DualsensePadState* ds_pad;
};
struct ControllerStateSnapshot
{
KeyboardState keyboard;
MousesState mouse;
XInputPadState xpad;
DualsensePadState ds_pad;
};
struct InputState
{
ControllerState controllers[4];
};
struct InputStateSnapshot
{
ControllerStateSnapshot controllers[4];
};
using InputBindCallback = void( void* );
using InputBindCallback_DigitalBtn = void( engine::DigitalBtn* button );
using InputBindCallback_AnalogAxis = void( engine::AnalogAxis* axis );
using InputBindCallback_AnalogStick = void( engine::AnalogStick* stick );
struct InputMode
{
InputBindCallback* binds;
s32 num_binds;
};
NS_ENGINE_END

131
project/engine/tile_map.cpp Normal file
View File

@ -0,0 +1,131 @@
#if INTELLISENSE_DIRECTIVES
#include "tile_map.hpp"
#endif
NS_ENGINE_BEGIN
inline
void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord )
{
assert( tile_map != nullptr );
assert( tile_coord != nullptr );
f32 tile_size = scast(f32, tile_map->tile_size_in_meters);
// Note(Ed) : World is assumed to be a "torodial topology"
s32 offset = round( (* pos_coord) / tile_size );
u32 new_tile_coord = (* tile_coord) + offset;
f32 new_pos_coord = (* pos_coord) - scast(f32, offset) * tile_size;
assert( new_pos_coord >= -tile_size * 0.5f );
assert( new_pos_coord <= tile_size * 0.5f );
(* tile_coord) = new_tile_coord;
(* pos_coord) = new_pos_coord;
}
inline
TileMapPosition recannonicalize_position( TileMap* tile_map, TileMapPosition pos )
{
assert( tile_map != nullptr );
TileMapPosition result = pos;
cannonicalize_coord( tile_map, & result.tile_x, & result.x );
cannonicalize_coord( tile_map, & result.tile_y, & result.y );
return result;
}
inline
u32 TileChunk_get_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u32 y )
{
assert( tile_map != nullptr );
assert( tile_chunk != nullptr );
assert( x < tile_map->chunk_dimension );
assert( y < tile_map->chunk_dimension );
u32 value = tile_chunk->tiles[ (y * tile_map->chunk_dimension) + x ];
return value;
}
inline
void TileChunk_set_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u32 y , u32 value)
{
assert( tile_map != nullptr );
assert( tile_chunk != nullptr );
assert( x < tile_map->chunk_dimension );
assert( y < tile_map->chunk_dimension );
tile_chunk->tiles[ (y * tile_map->chunk_dimension) + x ] = value;
}
inline
TileChunk* TileMap_get_chunk( TileMap* tile_map, s32 tile_chunk_x, s32 tile_chunk_y )
{
TileChunk* chunk = nullptr;
if ( tile_chunk_x >= 0 && tile_chunk_x < scast(s32, tile_map->tile_chunks_num_x)
&& tile_chunk_y >= 0 && tile_chunk_y < scast(s32, tile_map->tile_chunks_num_y) )
{
chunk = & tile_map->chunks[ tile_chunk_y * tile_map->tile_chunks_num_x + tile_chunk_x ];
}
return chunk;
}
inline
TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y )
{
assert( tile_map != nullptr );
TileChunkPosition chunk_pos {};
chunk_pos.tile_chunk_x = abs_tile_x >> tile_map->chunk_shift;
chunk_pos.tile_chunk_y = abs_tile_y >> tile_map->chunk_shift;
chunk_pos.tile_x = abs_tile_x & tile_map->chunk_mask;
chunk_pos.tile_y = abs_tile_y & tile_map->chunk_mask;
return chunk_pos;
}
u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y )
{
assert( tile_map != nullptr );
u32 value = 0;
TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, tile_x, tile_y );
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y );
if ( chunk )
value = TileChunk_get_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y );
return value;
}
internal
b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPosition position )
{
assert( tile_map != nullptr );
u32 chunk_value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y );
b32 is_empty = chunk_value == 0;
return is_empty;
}
internal
void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y, u32 value )
{
TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, abs_tile_x, abs_tile_y );
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y );
#if 0
if ( chunk == nullptr )
{
}
#else
assert( chunk != nullptr );
#endif
TileChunk_set_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y, value );
}
NS_ENGINE_END

View File

@ -0,0 +1,65 @@
/*
*/
#pragma once
#if INTELLISENSE_DIRECTIVES
#include "platform/platform.hpp"
#include "engine_module.hpp"
#endif
NS_ENGINE_BEGIN
struct TileChunk
{
u32* tiles;
};
/*
This is a "backend" transient datatype for handling lookup of tile data from "chunks" of tiles.
*/
struct TileChunkPosition
{
u32 tile_chunk_x;
u32 tile_chunk_y;
// "Chunk-relative (x, y)
u32 tile_x;
u32 tile_y;
};
struct TileMap
{
// TODO(Ed) : Beginner's sparseness
s32 tile_chunks_num_x;
s32 tile_chunks_num_y;
s32 tile_size_in_pixels;
f32 tile_size_in_meters;
f32 tile_meters_to_pixels;
u32 chunk_shift;
u32 chunk_mask;
u32 chunk_dimension;
TileChunk* chunks;
};
struct TileMapPosition
{
// TODO(Ed) : Should this be from the center of the tile?
f32 x;
f32 y;
// "World-relative (x, y), AKA: Absolute Position
// Fixed point tile locations.
// High bits are the tile-chunk index, and the low bits are the tile index in the chunk.
u32 tile_x;
u32 tile_y;
};
NS_ENGINE_END

View File

@ -6,7 +6,7 @@ NS_ENGINE_BEGIN
constexpr
Str const symbol_on_module_load = str_ascii("?on_module_reload@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z");
constexpr
Str const symbol_startup = str_ascii("?startup@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z");
Str const symbol_startup = str_ascii("?startup@engine@@YAXPEAUOffscreenBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z");
constexpr
Str const symbol_shutdown = str_ascii("?shutdown@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z");
constexpr

View File

@ -13,15 +13,15 @@ struct Memory
// Subscection of engine memory for the game to use.
void* persistent;
u64 persistent_size;
ssize persistent_size;
// void* Frame;
// u64 FrameSize;
void* transient;
u64 transient_size;
ssize transient_size;
u64 total_size()
ssize total_size()
{
return persistent_size + transient_size;
}
@ -74,12 +74,8 @@ struct PlayerState
f32 width;
f32 height;
// TODO(Ed) : Should this be canonical position now?
//f32 pos_x;
//f32 pos_y;
engine::WorldPosition position;
engine::TileMapPosition position;
b32 mid_jump;
f32 jump_time;
};
@ -91,7 +87,8 @@ struct PlayerActions
f32 player_x_move_analog;
f32 player_y_move_analog;
b32 jump = false;
b32 sprint;
b32 jump;
};
struct GameState

View File

@ -7,6 +7,7 @@ Handmade Engine Translation Unit
#include <math.h> // TEMP
#include <stdio.h> // TEMP
#include "platform/platform_module.hpp"
#include "platform/grime.hpp"
#include "platform/macros.hpp"
#include "platform/generics.hpp"
@ -17,10 +18,14 @@ Handmade Engine Translation Unit
#include "platform/context.hpp"
#include "platform/platform.hpp"
#include "engine_module.hpp"
#include "input.hpp"
#include "tile_map.hpp"
#include "engine.hpp"
#include "engine_to_platform_api.hpp"
// Game layer headers
#include "handmade.hpp"
#include "tile_map.cpp"
#include "engine.cpp"

View File

@ -7,6 +7,7 @@ Handmade Win32 Platform Translation Unit
#include <math.h> // TEMP
#include <stdio.h> // TEMP
#include "platform_module.hpp"
#include "grime.hpp"
#include "macros.hpp"
#include "generics.hpp"
@ -18,6 +19,9 @@ Handmade Win32 Platform Translation Unit
#include "platform.hpp"
// Engine layer headers
#include "engine/engine_module.hpp"
#include "engine/input.hpp"
#include "engine/tile_map.hpp"
#include "engine/engine.hpp"
#include "engine/engine_to_platform_api.hpp"
#include "gen/engine_symbol_table.hpp"

View File

@ -22,7 +22,7 @@ s32 floor( f32 value )
inline
s32 round( f32 value )
{
s32 result = scast(s32, value + 0.5f);
s32 result = scast(s32, roundf( value ));
return result;
}

View File

@ -15,16 +15,7 @@
#define rcast( type, value ) reinterpret_cast< type >( value )
#define scast( type, value ) static_cast< type >( value )
#define do_once() \
do \
{ \
local_persist \
bool done = false; \
if ( done ) \
return; \
done = true; \
} \
while(0)
#define do_once() for ( local_persist b32 once = true; once; once = false )
#define do_once_start \
do \

View File

@ -10,9 +10,9 @@
#if INTELLISENSE_DIRECTIVES
// TODO(Ed) : REMOVE THESE WHEN CASEY GETS TO THEM
#include <math.h> // TODO : Implement math ourselves
#include <stdio.h> // TODO : Implement output logging ourselves
#include "platform_module.hpp"
#include "grime.hpp"
#include "macros.hpp"
#include "generics.hpp"
@ -23,9 +23,6 @@
#include "context.hpp"
#endif
#define NS_PLATFORM_BEGIN namespace platform {
#define NS_PLATFORM_END }
NS_PLATFORM_BEGIN
// On-Demand platform interface.
@ -121,6 +118,8 @@ struct ModuleAPI
};
#if Build_Development
// TODO(Ed): This can't be done this way, we need a separate interface for other modules to use this.
// (At least, we need to hookup the symbols statically or at runtime somehow, and right now the only thing that does is the module api passthrough via the Engine API)
void impl_congrats( char const* message );
bool impl_ensure( bool condition, char const* message );
void impl_fatal( char const* message );

View File

@ -0,0 +1,4 @@
#pragma once
#define NS_PLATFORM_BEGIN namespace platform {
#define NS_PLATFORM_END }

View File

@ -79,10 +79,10 @@ static_assert( sizeof( u16 ) == 2, "sizeof(u16) != 2" );
static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" );
static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" );
typedef size_t uw;
typedef ptrdiff_t sw;
typedef size_t usize;
typedef ptrdiff_t ssize;
static_assert( sizeof( uw ) == sizeof( sw ), "sizeof(uw) != sizeof(sw)" );
static_assert( sizeof( usize ) == sizeof( ssize ), "sizeof(usize) != sizeof(ssize)" );
#if defined( _WIN64 )
typedef signed __int64 sptr;

View File

@ -135,7 +135,6 @@ timing_get_wall_clock()
return clock;
}
#pragma endregion Timing
NS_PLATFORM_END
#include "win32_audio.cpp"
@ -540,8 +539,8 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
void* base_address = 0;
#endif
engine_memory.persistent = VirtualAlloc( base_address, total_size , MEM_Commit_Zeroed | MEM_Reserve, Page_Read_Write );
engine_memory.transient = rcast( u8*, engine_memory.persistent ) + engine_memory.persistent_size;
engine_memory.persistent = rcast( Byte*, VirtualAlloc( base_address, total_size , MEM_Commit_Zeroed | MEM_Reserve, Page_Read_Write ));
engine_memory.transient = rcast( Byte*, engine_memory.persistent ) + engine_memory.persistent_size;
#if Build_Development
// First slot is for restore
@ -794,7 +793,7 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
}
}
engine_api.startup( & engine_memory, & platform_api );
engine_api.startup( rcast(engine::OffscreenBuffer*, & Surface_Back_Buffer.memory), & engine_memory, & platform_api );
u64 last_frame_clock = timing_get_wall_clock();
u64 last_frame_cycle = __rdtsc();

View File

@ -152,6 +152,7 @@ else {
$should_format_gen = $false
# TODO(Ed) : Support detecting codegen changes separate from the module's runtime builds (so that it can be rebuild only when necessary as well)
function build-engine
{
$should_build = check-ModuleForChanges $path_engine