mirror of
				https://github.com/Ed94/HandmadeHero.git
				synced 2025-11-03 15:26:12 -08:00 
			
		
		
		
	Day 34 complete!!!
This commit is contained in:
		
							
								
								
									
										2
									
								
								.vscode/bookmarks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/bookmarks.json
									
									
									
									
										vendored
									
									
								
							@@ -14,7 +14,7 @@
 | 
			
		||||
					"label": "Static Data"
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					"line": 1002,
 | 
			
		||||
					"line": 1001,
 | 
			
		||||
					"column": 0,
 | 
			
		||||
					"label": "Main Loop : End"
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								docs/Day 034.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								docs/Day 034.md
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								docs/imgs/handmade_win32_2023-10-11_23-39-57.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/imgs/handmade_win32_2023-10-11_23-39-57.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 328 KiB  | 
@@ -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"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,6 +131,7 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
 | 
			
		||||
	{
 | 
			
		||||
		DualsensePadState* pad = controller->ds_pad;
 | 
			
		||||
 | 
			
		||||
		actions->sprint |= pressed( pad->circle );
 | 
			
		||||
		actions->jump   |= pressed( pad->cross );
 | 
			
		||||
 | 
			
		||||
		actions->player_x_move_analog += pad->stick.left.X.end;
 | 
			
		||||
@@ -130,6 +141,7 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
 | 
			
		||||
	{
 | 
			
		||||
		XInputPadState* pad = controller->xpad;
 | 
			
		||||
 | 
			
		||||
		actions->sprint |= pressed( pad->B );
 | 
			
		||||
		actions->jump   |= pressed( pad->A );
 | 
			
		||||
 | 
			
		||||
		actions->player_x_move_analog += pad->stick.left.X.end;
 | 
			
		||||
@@ -140,6 +152,7 @@ void input_poll_player_actions( InputState* input, hh::PlayerActions* actions )
 | 
			
		||||
	{
 | 
			
		||||
		KeyboardState* keyboard = controller->keyboard;
 | 
			
		||||
		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 );
 | 
			
		||||
	assert( arena != nullptr );
 | 
			
		||||
	
 | 
			
		||||
	u32 value = tile_chunk->tiles[ (y * world->chunk_dimension) + x ];
 | 
			
		||||
	return value;
 | 
			
		||||
}
 | 
			
		||||
	ssize mem_amount = sizeof( Type ) * num;
 | 
			
		||||
	assert( arena->used + mem_amount <= arena->size );
 | 
			
		||||
	
 | 
			
		||||
// 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 );
 | 
			
		||||
	Type* result = rcast(Type*, arena->storage + arena->used);
 | 
			
		||||
	arena->used += mem_amount;
 | 
			
		||||
	
 | 
			
		||||
	// 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);
 | 
			
		||||
	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,85 +690,18 @@ 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;
 | 
			
		||||
 | 
			
		||||
			draw_rectangle( back_buffer
 | 
			
		||||
			               , min_x, max_y
 | 
			
		||||
			               , max_x, min_y
 | 
			
		||||
			               , color[0], color[1], color[2] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Player
 | 
			
		||||
	f32 player_red   = 0.7f;
 | 
			
		||||
	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_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;
 | 
			
		||||
 | 
			
		||||
//	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_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;
 | 
			
		||||
			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, 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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -809,18 +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 =  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_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 = 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;
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Auto-Snapshot percent bar
 | 
			
		||||
	if (1)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
	This represents the API only accessible to the engine to fullfill for the game module.
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										14
									
								
								project/engine/engine_module.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								project/engine/engine_module.hpp
									
									
									
									
									
										Normal 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
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										0
									
								
								project/engine/input.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										178
									
								
								project/engine/input.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								project/engine/input.hpp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										131
									
								
								project/engine/tile_map.cpp
									
									
									
									
									
										Normal 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
 | 
			
		||||
							
								
								
									
										65
									
								
								project/engine/tile_map.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								project/engine/tile_map.hpp
									
									
									
									
									
										Normal 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
 | 
			
		||||
@@ -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 
 | 
			
		||||
 
 | 
			
		||||
@@ -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,11 +74,7 @@ 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
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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                     \
 | 
			
		||||
 
 | 
			
		||||
@@ -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 );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								project/platform/platform_module.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								project/platform/platform_module.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#define NS_PLATFORM_BEGIN namespace platform {
 | 
			
		||||
#define NS_PLATFORM_END }
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user