mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-12-21 22:14:43 -08:00
Day 30 complete
This commit is contained in:
parent
a103054023
commit
dcc14d154f
3
.gitignore
vendored
3
.gitignore
vendored
@ -19,7 +19,8 @@ build
|
||||
**/*.dll
|
||||
**/*.exe
|
||||
**/*.pdb
|
||||
**/*.exe
|
||||
**/*.exp
|
||||
**/*.lib
|
||||
|
||||
**/*.hmi
|
||||
**/*.symbols
|
||||
|
47
README.md
47
README.md
@ -1,16 +1,19 @@
|
||||
# HandmadeHero
|
||||
|
||||
Any code I do for this [series](https://handmadehero.org) will be here.
|
||||
Any code I do for this [series](https://handmadehero.org) will be here.
|
||||
|
||||
***(Only original hand-written code will be here, no code from the series itself)***
|
||||
|
||||
## Scripts
|
||||
|
||||
* `build.ps1` - Builds the project use `.\scripts\build msvc debug` or `.\scripts\build clang debug`.
|
||||
* `build.ps1` - Builds the project use `.\scripts\build msvc <args> <module>` or `.\scripts\build clang <args> <module>`
|
||||
* `debug` adds debug symbols, etc
|
||||
* `dev` for development builds. (automatically adds debug)
|
||||
* `optimize` for optimized builds.
|
||||
* `dev` for development builds. ( Dev memory layout and code paths compiled ).
|
||||
* `verbose` gives more info on arguments passed to tools, etc.
|
||||
* `module` is the module to build, can be any of `platform` or `engine` for this point in the codebase. (Eventually game will also be a separate module)
|
||||
* `clean.ps1` - Cleans the project
|
||||
* `update_deps.ps1` - Updates the project dependencies to their latest from their respective repos. (Not done automatically on build)
|
||||
* `update_deps.ps1` - Updates the project dependencies to their latest from their respective repos.
|
||||
|
||||
*Make sure to run `update_deps.ps1` before building for the first time.*
|
||||
|
||||
@ -20,17 +23,45 @@ Building requires msvc or llvm's clang + lld, and powershell 7
|
||||
|
||||
The build is done in two stages:
|
||||
|
||||
1. ~~Build and run metaprogram to scan and generate dependent code.~~ (Not needed yet)
|
||||
2. Build the handmade hero runtime.
|
||||
1. Build and run metaprogram to scan and generate dependent code for the module being built.
|
||||
2. Build the the runtime for the module.
|
||||
|
||||
Module build order:
|
||||
|
||||
1. Engine
|
||||
2. Platform
|
||||
|
||||
## Milestone
|
||||
|
||||
Day 028: Drawing a Tile Map
|
||||
Day 30 : Moving Between Tile Maps
|
||||
|
||||
Features Done so far:
|
||||
|
||||
* Tailor made build system via powershell scripts
|
||||
* Supports building the repo with msvc or clang
|
||||
* Can stage codegen metaprograms to run before building the module
|
||||
* Will automatically not run if app process is found (for engine module).
|
||||
* Can emit exported mangled symbols for the engine module for hot-reload with the platform module without needing to use C linkage symbols or a complex hot-reload library (Live++, etc).
|
||||
* Platform Layer:
|
||||
* Direct Sound audio
|
||||
* Keyboard & Mouse Input via GetAsyncKeyState & Win32 window messagng
|
||||
* XInput controller support
|
||||
* Dualsense controller support via joyshock library
|
||||
* Software rendering via Win32 GDI
|
||||
* Instantaneous hot reload of engine module
|
||||
* Block Memory allocation via VirtualAlloc for engine module
|
||||
* Memory mapped files for engine & game snapshots.
|
||||
* Engine Layer:
|
||||
* Take & load snapshots of either the engine's or game's memory state.
|
||||
* 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
|
||||
|
||||
## Gallery
|
||||
|
||||
![img](docs/imgs/handmade_win32_2023-10-01_20-22-20.gif)
|
||||
![img](docs/imgs/Code_2023-10-01_19-20-56.gif)
|
||||
![img](docs/imgs/Code_2023-09-28_15-14-53.gif)
|
||||
![img](https://files.catbox.moe/ruv97s.gif)
|
||||
![img](https://files.catbox.moe/9zau4s.png)
|
||||
![img](https://files.catbox.moe/b7ifa8.png)
|
||||
|
7
docs/Day 030.md
Normal file
7
docs/Day 030.md
Normal file
@ -0,0 +1,7 @@
|
||||
# Day 30
|
||||
|
||||
Tile map stuff is looking alright. Doing my best to not clean-up the code as Casey pleads in the vods.
|
||||
|
||||
I would have perferred if he didn't just do one tilemap at a time and instead I would have had the current tile map and surrounding loaded at the same time (He might do this in the future). Since were aren't constrained memory wise like the old machines, we could have those loaded as well and it would make the management of the tilemaps easier (possibly...).
|
||||
|
||||
Looking foward to when he introduces a proper vector space for the positioning.
|
BIN
docs/imgs/Code_2023-10-01_19-20-56.gif
Normal file
BIN
docs/imgs/Code_2023-10-01_19-20-56.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 MiB |
@ -382,6 +382,13 @@ output_sound( EngineState* state, AudioBuffer* sound_buffer, GetSoundSampleValue
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
s32 floor_f32_to_s32( f32 value )
|
||||
{
|
||||
// TODO : Casey wants to use an intrinsic
|
||||
return scast(s32, floorf( value ));
|
||||
}
|
||||
|
||||
inline
|
||||
s32 round_f32_to_s32( f32 value )
|
||||
{
|
||||
@ -472,7 +479,7 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api )
|
||||
EngineState* state = rcast( EngineState*, memory->persistent );
|
||||
assert( sizeof(EngineState) <= memory->persistent_size );
|
||||
|
||||
state->auto_snapshot_interval = 10.f;
|
||||
state->auto_snapshot_interval = 60.f;
|
||||
|
||||
state->tone_volume = 1000;
|
||||
|
||||
@ -489,15 +496,17 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api )
|
||||
state->game_memory.transient_size = memory->transient_size / 2;
|
||||
state->game_memory.transient = rcast(Byte*, memory->transient) + state->game_memory.transient_size;
|
||||
|
||||
hh::PlayerState* player = rcast( hh::PlayerState*, state->game_memory.persistent );
|
||||
assert( sizeof(hh::PlayerState) <= state->game_memory.persistent_size );
|
||||
hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent );
|
||||
assert( sizeof(hh::GameState) <= state->game_memory.persistent_size );
|
||||
|
||||
player->width = 50.f;
|
||||
player->height = 100.f;
|
||||
player->pos_x = 920;
|
||||
player->pos_y = 466;
|
||||
player->mid_jump = false;
|
||||
player->jump_time = 0.f;
|
||||
game_state->tile_map_x = 0;
|
||||
game_state->tile_map_y = 0;
|
||||
|
||||
hh::PlayerState* player = & game_state->player_state;
|
||||
player->pos_x = 920;
|
||||
player->pos_y = 466;
|
||||
player->mid_jump = false;
|
||||
player->jump_time = 0.f;
|
||||
}
|
||||
|
||||
Engine_API
|
||||
@ -506,45 +515,110 @@ void shutdown( Memory* memory, platform::ModuleAPI* platform_api )
|
||||
}
|
||||
|
||||
inline
|
||||
u32 tilemap_tile_value( TileMap* tile_map, s32 x, s32 y )
|
||||
CanonPosition get_cannonical_position( World* world, RawPosition raw_pos )
|
||||
{
|
||||
assert( x >= 0 && x < scast(s32, tile_map->num_x) );
|
||||
assert( y >= 0 && y < scast(s32, tile_map->num_y) );
|
||||
return tile_map->tiles[ (y * tile_map->num_x) + x ];
|
||||
s32 tile_map_x = raw_pos.tile_map_x;
|
||||
s32 tile_map_y = raw_pos.tile_map_y;
|
||||
|
||||
f32 pos_x = ( raw_pos.x - world->tile_upper_left_x );
|
||||
f32 pos_y = ( raw_pos.y - world->tile_upper_left_y );
|
||||
|
||||
s32 tile_x = floor_f32_to_s32( pos_x / world->tile_width );
|
||||
s32 tile_y = floor_f32_to_s32( pos_y / world->tile_height );
|
||||
|
||||
f32 tile_rel_x = pos_x - scast(f32, tile_x) * world->tile_width;
|
||||
f32 tile_rel_y = pos_y - scast(f32, tile_y) * world->tile_height;
|
||||
|
||||
assert( tile_rel_x >= 0.f );
|
||||
assert( tile_rel_y >= 0.f );
|
||||
assert( tile_rel_x < world->tile_width );
|
||||
assert( tile_rel_y < world->tile_height );
|
||||
|
||||
/*
|
||||
The puprpose of this is to be able to detect if the point is outside of the tilemap,
|
||||
and if so, roll the point over to an adjacent tilemap.
|
||||
|
||||
For example : If the point is at x = -1, then it is outside of the tilemap, and
|
||||
should be rolled over to the tilemap to the left of the current tilemap.
|
||||
*/
|
||||
if ( tile_x < 0 )
|
||||
{
|
||||
tile_x += world->num_tiles_x;
|
||||
-- tile_map_x;
|
||||
}
|
||||
if ( tile_y < 0 )
|
||||
{
|
||||
tile_y += world->num_tiles_y;
|
||||
-- tile_map_y;
|
||||
}
|
||||
if ( tile_x >= world->num_tiles_x )
|
||||
{
|
||||
tile_x -= world->num_tiles_x;
|
||||
++ tile_map_x;
|
||||
}
|
||||
if ( tile_y >= world->num_tiles_y )
|
||||
{
|
||||
tile_y -= world->num_tiles_y;
|
||||
++ tile_map_y;
|
||||
}
|
||||
|
||||
return { tile_rel_x, tile_rel_y, tile_map_x, tile_map_y, tile_x, tile_y };
|
||||
}
|
||||
|
||||
inline
|
||||
b32 tilemap_is_pos_empty( TileMap* tile_map, f32 x, f32 y )
|
||||
u32 tilemap_tile_value( TileMap* tile_map, World* world, s32 x, s32 y )
|
||||
{
|
||||
s32 tile_x = truncate_f32_to_s32(( x - scast(f32, tile_map->upper_left_X)) / scast(f32, tile_map->width) );
|
||||
s32 tile_y = truncate_f32_to_s32(( y - scast(f32, tile_map->upper_left_Y)) / scast(f32, tile_map->height) );
|
||||
assert( tile_map != nullptr );
|
||||
assert( world != nullptr );
|
||||
assert( x >= 0 && x < scast(s32, world->num_tiles_x) );
|
||||
assert( y >= 0 && y < scast(s32, world->num_tiles_y) );
|
||||
return tile_map->tiles[ (y * world->num_tiles_x) + x ];
|
||||
}
|
||||
|
||||
inline
|
||||
b32 tilemap_is_point_empty( TileMap* tile_map, World* world, s32 tile_x, s32 tile_y )
|
||||
{
|
||||
assert( tile_map != nullptr );
|
||||
assert( world != nullptr );
|
||||
|
||||
// Assume space is occupied if there is bad data
|
||||
if ( tile_map == nullptr )
|
||||
return false;
|
||||
|
||||
b32 is_empty = false;
|
||||
if ( tile_x >= 0 && tile_x < scast(s32, tile_map->num_x)
|
||||
&& tile_y >= 0 && tile_y < scast(s32, tile_map->num_y) )
|
||||
if ( tile_x >= 0 && tile_x < world->num_tiles_x
|
||||
&& tile_y >= 0 && tile_y < world->num_tiles_y )
|
||||
{
|
||||
u32 tile_value = tilemap_tile_value( tile_map, tile_x, tile_y );
|
||||
u32 tile_value = tilemap_tile_value( tile_map, world, tile_x, tile_y );
|
||||
is_empty = tile_value == 0;
|
||||
}
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
inline
|
||||
TileMap* world_tilemap( World* world, s32 x, s32 y )
|
||||
TileMap* world_get_tilemap( World* world, s32 tile_map_x, s32 tile_map_y )
|
||||
{
|
||||
assert( x >= 0 && x < world->tilemaps_num_x );
|
||||
assert( y >= 0 && y < world->tilemaps_num_y );
|
||||
return & world->tile_maps[ (y * world->tilemaps_num_x) + x ];
|
||||
assert( tile_map_x >= 0 && tile_map_x < world->tilemaps_num_x );
|
||||
assert( tile_map_y >= 0 && tile_map_y < world->tilemaps_num_y );
|
||||
return & world->tile_maps[ (tile_map_y * world->tilemaps_num_x) + tile_map_x ];
|
||||
}
|
||||
|
||||
internal
|
||||
b32 world_is_pos_empty( World* world, s32 tm_x, s32 tm_y, f32 x, f32 y )
|
||||
b32 world_is_point_empty( World* world, RawPosition raw_pos )
|
||||
{
|
||||
return false;
|
||||
assert( world != nullptr );
|
||||
|
||||
b32 is_empty = false;
|
||||
|
||||
CanonPosition position = get_cannonical_position( world, raw_pos );
|
||||
|
||||
TileMap* tile_map = world_get_tilemap( world, position.tile_map_x, position.tile_map_y );
|
||||
is_empty = tilemap_is_point_empty( tile_map, world, position.tile_x, position.tile_y );
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
Engine_API
|
||||
// TODO : I rather expose the back_buffer and sound_buffer using getters for access in any function.
|
||||
void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back_buffer
|
||||
, Memory* memory, platform::ModuleAPI* platform_api, ThreadContext* thread )
|
||||
{
|
||||
@ -684,11 +758,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
}
|
||||
#endif
|
||||
|
||||
hh::PlayerState* player = rcast( hh::PlayerState*, state->game_memory.persistent );
|
||||
assert( sizeof(hh::PlayerState) <= state->game_memory.persistent_size );
|
||||
|
||||
f32 half_width = player->width / 2.f;
|
||||
f32 quater_height = player->height / 4.f;
|
||||
hh::GameState* game_state = rcast( hh::GameState*, state->game_memory.persistent );
|
||||
hh::PlayerState* player = & game_state->player_state;
|
||||
|
||||
f32 x_offset_f = scast(f32, state->x_offset);
|
||||
f32 y_offset_f = scast(f32, state->y_offset);
|
||||
@ -696,70 +767,83 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
constexpr s32 tile_map_num_x = 16;
|
||||
constexpr s32 tile_map_num_y = 9;
|
||||
|
||||
// tiles_XY
|
||||
u32 tiles_00 [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, 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 },
|
||||
{ 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 },
|
||||
};
|
||||
u32 tiles_10 [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, 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 },
|
||||
{ 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, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||
};
|
||||
u32 tiles_01 [tile_map_num_y][tile_map_num_x] = {
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 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, 0 },
|
||||
{ 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 },
|
||||
};
|
||||
u32 tiles_10 [tile_map_num_y][tile_map_num_x] = {
|
||||
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||
u32 tiles_11 [tile_map_num_y][tile_map_num_x] = {
|
||||
{ 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 },
|
||||
{ 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 },
|
||||
};
|
||||
u32 tiles_11 [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, 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 },
|
||||
{ 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||
};
|
||||
|
||||
TileMap tile_maps[2][2] {};
|
||||
tile_maps[0][0].upper_left_X = 0;
|
||||
tile_maps[0][0].upper_left_Y = 0;
|
||||
tile_maps[0][0].width = 80;
|
||||
tile_maps[0][0].height = 80;
|
||||
tile_maps[0][0].num_x = tile_map_num_x;
|
||||
tile_maps[0][0].num_y = tile_map_num_y;
|
||||
tile_maps[0][0].tiles = rcast(u32*, tiles_00);
|
||||
|
||||
tile_maps[0][1] = tile_maps[0][0];
|
||||
tile_maps[0][1].tiles = rcast(u32*, tiles_01);
|
||||
|
||||
tile_maps[1][0] = tile_maps[0][0];
|
||||
tile_maps[1][0].tiles = rcast(u32*, tiles_10);
|
||||
|
||||
tile_maps[1][1] = tile_maps[0][0];
|
||||
tile_maps[0][0].tiles = rcast(u32*, tiles_00);
|
||||
tile_maps[0][1].tiles = rcast(u32*, tiles_10);
|
||||
tile_maps[1][0].tiles = rcast(u32*, tiles_01);
|
||||
tile_maps[1][1].tiles = rcast(u32*, tiles_11);
|
||||
|
||||
s32 current_tile_map_id[2] = { 0, 0 };
|
||||
TileMap* current_tile_map = & tile_maps[current_tile_map_id[0] ][current_tile_map_id[1] ];
|
||||
World world;
|
||||
world.num_tiles_x = tile_map_num_x;
|
||||
world.num_tiles_y = tile_map_num_y;
|
||||
|
||||
f32 scale = 85;
|
||||
|
||||
world.tile_width = scale;
|
||||
world.tile_height = scale * 1.05f;
|
||||
|
||||
world.tile_upper_left_x = -(world.tile_width * 0.5f);
|
||||
world.tile_upper_left_y = -(world.tile_height * 0.5f);
|
||||
|
||||
world.tilemaps_num_x = 2;
|
||||
world.tilemaps_num_y = 2;
|
||||
|
||||
world.tile_maps = rcast(TileMap*, tile_maps);
|
||||
|
||||
TileMap* current_tile_map = world_get_tilemap( & world, game_state->tile_map_x, game_state->tile_map_y );
|
||||
assert( current_tile_map != nullptr );
|
||||
|
||||
player->width = world.tile_width * 0.75f;
|
||||
player->height = world.tile_height;
|
||||
|
||||
f32 player_half_width = player->width / 2.f;
|
||||
f32 player_quarter_height = player->height / 4.f;
|
||||
|
||||
input_poll_player_actions( input, & player_actions );
|
||||
{
|
||||
@ -779,16 +863,35 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
}
|
||||
new_player_pos_y += sinf( player->jump_time * TAU ) * 200.f * delta_time;
|
||||
|
||||
b32 valid_new_pos =
|
||||
tilemap_is_pos_empty( current_tile_map, new_player_pos_x - half_width, new_player_pos_y - quater_height )
|
||||
&& tilemap_is_pos_empty( current_tile_map, new_player_pos_x + half_width, new_player_pos_y - quater_height )
|
||||
&& tilemap_is_pos_empty( current_tile_map, new_player_pos_x - half_width, new_player_pos_y )
|
||||
&& tilemap_is_pos_empty( current_tile_map, new_player_pos_x + half_width, new_player_pos_y );
|
||||
b32 valid_new_pos = true;
|
||||
{
|
||||
RawPosition test_pos = { new_player_pos_x - player_half_width, new_player_pos_y - player_quarter_height, game_state->tile_map_x, game_state->tile_map_y };
|
||||
|
||||
valid_new_pos &= world_is_point_empty( & world, test_pos );
|
||||
|
||||
test_pos.x = new_player_pos_x + player_half_width;
|
||||
valid_new_pos &= world_is_point_empty( & world, test_pos );
|
||||
|
||||
test_pos.x = new_player_pos_x - player_half_width;
|
||||
test_pos.y = new_player_pos_y;
|
||||
valid_new_pos &= world_is_point_empty( & world, test_pos );
|
||||
|
||||
test_pos.x = new_player_pos_x + player_half_width;
|
||||
valid_new_pos &= world_is_point_empty( & world, test_pos );
|
||||
}
|
||||
|
||||
if ( valid_new_pos )
|
||||
{
|
||||
player->pos_x = new_player_pos_x;
|
||||
player->pos_y = new_player_pos_y;
|
||||
RawPosition raw_pos = { new_player_pos_x, new_player_pos_y, game_state->tile_map_x, game_state->tile_map_y };
|
||||
CanonPosition canon_pos = get_cannonical_position( & world, raw_pos);
|
||||
|
||||
game_state->tile_map_x = canon_pos.tile_map_x;
|
||||
game_state->tile_map_y = canon_pos.tile_map_y;
|
||||
|
||||
// current_tile_map = world_get_tilemap( & world, game_state->tile_map_x, game_state->tile_map_y );
|
||||
|
||||
player->pos_x = world.tile_upper_left_x + world.tile_width * scast(f32, canon_pos.tile_x) + canon_pos.x;
|
||||
player->pos_y = world.tile_upper_left_y + world.tile_height * scast(f32, canon_pos.tile_y) + canon_pos.y;
|
||||
}
|
||||
|
||||
// player_tile_x
|
||||
@ -821,7 +924,7 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
{
|
||||
for ( s32 col = 0; col < 16; ++ col )
|
||||
{
|
||||
u32 tileID = tilemap_tile_value( & tile_maps[0][0], col, row );
|
||||
u32 tileID = tilemap_tile_value( current_tile_map, & world, col, row );
|
||||
f32 grey[3] = { 0.15f, 0.15f, 0.15f };
|
||||
|
||||
if ( tileID == 1 )
|
||||
@ -831,10 +934,10 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
grey[2] = 0.22f;
|
||||
}
|
||||
|
||||
f32 min_x = current_tile_map->upper_left_X + scast(f32, col) * current_tile_map->width;
|
||||
f32 min_y = current_tile_map->upper_left_Y + scast(f32, row) * current_tile_map->height;
|
||||
f32 max_x = min_x + current_tile_map->width;
|
||||
f32 max_y = min_y + current_tile_map->height;
|
||||
f32 min_x = world.tile_upper_left_x + scast(f32, col) * world.tile_width;
|
||||
f32 min_y = world.tile_upper_left_y + scast(f32, row) * world.tile_height;
|
||||
f32 max_x = min_x + world.tile_width;
|
||||
f32 max_y = min_y + world.tile_height;
|
||||
|
||||
draw_rectangle( back_buffer
|
||||
, min_x, min_y
|
||||
@ -849,8 +952,8 @@ void update_and_render( f32 delta_time, InputState* input, OffscreenBuffer* back
|
||||
f32 player_blue = 0.3f;
|
||||
|
||||
draw_rectangle( back_buffer
|
||||
, player->pos_x - half_width, player->pos_y - player->height
|
||||
, player->pos_x + half_width, player->pos_y
|
||||
, player->pos_x - player_half_width, player->pos_y - player->height
|
||||
, player->pos_x + player_half_width, player->pos_y
|
||||
, player_red, player_green, player_blue );
|
||||
|
||||
// Auto-Snapshot percent bar
|
||||
|
@ -277,20 +277,20 @@ struct RecordedInput
|
||||
|
||||
struct TileMap
|
||||
{
|
||||
f32 upper_left_X;
|
||||
f32 upper_left_Y;
|
||||
|
||||
f32 width;
|
||||
f32 height;
|
||||
|
||||
s32 num_x;
|
||||
s32 num_y;
|
||||
|
||||
u32* tiles;
|
||||
};
|
||||
|
||||
struct World
|
||||
{
|
||||
f32 tile_upper_left_x;
|
||||
f32 tile_upper_left_y;
|
||||
|
||||
f32 tile_width;
|
||||
f32 tile_height;
|
||||
|
||||
s32 num_tiles_x; // Number of tiles on the x-axis for a tilemap.
|
||||
s32 num_tiles_y; // Number of tiles on the y-axis for a tilemap.
|
||||
|
||||
// TODO(Ed) : Beginner's sparseness
|
||||
s32 tilemaps_num_x;
|
||||
s32 tilemaps_num_y;
|
||||
@ -298,4 +298,29 @@ struct World
|
||||
TileMap* tile_maps;
|
||||
};
|
||||
|
||||
struct CanonPosition
|
||||
{
|
||||
// Note: Tile-Relative position
|
||||
// TODO(Ed) : These are still in pixels
|
||||
f32 x;
|
||||
f32 y;
|
||||
|
||||
s32 tile_map_x;
|
||||
s32 tile_map_y;
|
||||
|
||||
s32 tile_x;
|
||||
s32 tile_y;
|
||||
};
|
||||
|
||||
// TODO(Ed) : Is this necessary?
|
||||
struct RawPosition
|
||||
{
|
||||
// Note: TileMap-Relative position
|
||||
f32 x;
|
||||
f32 y;
|
||||
|
||||
s32 tile_map_x;
|
||||
s32 tile_map_y;
|
||||
};
|
||||
|
||||
NS_ENGINE_END
|
||||
|
@ -73,6 +73,7 @@ struct PlayerState
|
||||
f32 width;
|
||||
f32 height;
|
||||
|
||||
// TODO(Ed) : Should this be canonical position now?
|
||||
f32 pos_x;
|
||||
f32 pos_y;
|
||||
|
||||
@ -90,4 +91,12 @@ struct PlayerActions
|
||||
b32 jump = false;
|
||||
};
|
||||
|
||||
struct GameState
|
||||
{
|
||||
s32 tile_map_x;
|
||||
s32 tile_map_y;
|
||||
|
||||
PlayerState player_state;
|
||||
};
|
||||
|
||||
NS_HANDMADE_END
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma warning( disable: 5105 )
|
||||
#pragma warning( disable: 4820 )
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#include <xinput.h>
|
||||
#include <mmeapi.h>
|
||||
|
@ -642,8 +642,8 @@ WinMain( HINSTANCE instance, HINSTANCE prev_instance, LPSTR commandline, int sho
|
||||
}
|
||||
|
||||
window_handle = CreateWindowExW(
|
||||
WS_EX_LAYERED | WS_EX_TOPMOST,
|
||||
// WS_EX_LAYERED,
|
||||
// WS_EX_LAYERED | WS_EX_TOPMOST,
|
||||
WS_EX_LAYERED,
|
||||
window_class.lpszClassName,
|
||||
L"Handmade Hero",
|
||||
WS_Overlapped_Window | WS_Initially_Visible,
|
||||
|
@ -1,6 +1,4 @@
|
||||
if ( $CursorPosition ) {
|
||||
Clear-Host
|
||||
}
|
||||
Clear-Host
|
||||
|
||||
$target_arch = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
|
||||
$devshell = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
|
||||
@ -8,13 +6,11 @@ $format_cpp = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
|
||||
$config_toolchain = Join-Path $PSScriptRoot 'helpers/configure_toolchain.ps1'
|
||||
|
||||
$path_root = git rev-parse --show-toplevel
|
||||
$path_build = Join-Path $path_root 'build'
|
||||
$path_build = Join-Path $path_root 'build'
|
||||
|
||||
Import-Module $target_arch
|
||||
Import-Module $format_cpp
|
||||
|
||||
Push-Location $path_root
|
||||
|
||||
#region Arguments
|
||||
$vendor = $null
|
||||
$optimize = $null
|
||||
@ -49,6 +45,8 @@ if ( $args ) { $args | ForEach-Object {
|
||||
. $config_toolchain
|
||||
|
||||
#region Building
|
||||
write-host "Building HandmadeHero with $vendor"
|
||||
|
||||
$path_project = Join-Path $path_root 'project'
|
||||
$path_data = Join-Path $path_root 'data'
|
||||
$path_binaries = Join-Path $path_data 'binaries'
|
||||
@ -140,7 +138,7 @@ function build-engine
|
||||
$unit = Join-Path $path_project 'handmade_engine.cpp'
|
||||
$dynamic_library = Join-Path $path_binaries 'handmade_engine.dll'
|
||||
|
||||
build-simple $includes $compiler_args $linker_args $unit $dynamic_library
|
||||
build-simple $path_build $includes $compiler_args $linker_args $unit $dynamic_library
|
||||
|
||||
Remove-Item $path_pdb_lock -Force
|
||||
|
||||
@ -233,7 +231,7 @@ function build-engine
|
||||
$unit = Join-Path $path_codegen 'engine_postbuild_gen.cpp'
|
||||
$executable = Join-Path $path_build 'engine_postbuild_gen.exe'
|
||||
|
||||
build-simple $includes $compiler_args $linker_args $unit $executable
|
||||
build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||
|
||||
Push-Location $path_build
|
||||
$time_taken = Measure-Command {
|
||||
@ -279,7 +277,7 @@ function build-platform
|
||||
$unit = Join-Path $path_codegen 'platform_gen.cpp'
|
||||
$executable = Join-Path $path_build 'platform_gen.exe'
|
||||
|
||||
build-simple $includes $compiler_args $linker_args $unit $executable
|
||||
build-simple $path_build $includes $compiler_args $linker_args $unit $executable $path_build
|
||||
|
||||
Push-Location $path_platform
|
||||
$time_taken = Measure-Command {
|
||||
@ -308,14 +306,14 @@ function build-platform
|
||||
|
||||
$lib_jsl,
|
||||
|
||||
$flag_link_win_subsystem_windows
|
||||
$flag_link_win_subsystem_windows,
|
||||
$flag_link_optimize_references
|
||||
)
|
||||
|
||||
$unit = Join-Path $path_project 'handmade_win32.cpp'
|
||||
$executable = Join-Path $path_binaries 'handmade_win32.exe'
|
||||
|
||||
build-simple $includes $compiler_args $linker_args $unit $executable
|
||||
build-simple $path_build $includes $compiler_args $linker_args $unit $executable
|
||||
|
||||
# if ( Test-Path $executable )
|
||||
# {
|
||||
|
Binary file not shown.
@ -7,11 +7,9 @@ if ($IsWindows) {
|
||||
|
||||
if ( $vendor -eq $null ) {
|
||||
write-host "No vendor specified, assuming clang available"
|
||||
$compiler = "clang"
|
||||
$vendor = "clang"
|
||||
}
|
||||
|
||||
write-host "Building HandmadeHero with $vendor"
|
||||
|
||||
if ( $dev ) {
|
||||
if ( $debug -eq $null ) {
|
||||
$debug = $true
|
||||
@ -133,6 +131,8 @@ if ( $vendor -match "clang" )
|
||||
$flag_set_stack_size = '-stack='
|
||||
$flag_syntax_only = '-fsyntax-only'
|
||||
$flag_target_arch = '-target'
|
||||
$flag_time_trace = '-ftime-trace'
|
||||
$flag_verbose = '-v'
|
||||
$flag_wall = '-Wall'
|
||||
$flag_warning = '-W'
|
||||
$flag_warnings_as_errors = '-Werror'
|
||||
@ -155,16 +155,15 @@ if ( $vendor -match "clang" )
|
||||
# 'libucrt',
|
||||
'libcmt' # For the C Runtime (Static Linkage)
|
||||
)
|
||||
|
||||
function build-simple
|
||||
{
|
||||
param( [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary )
|
||||
param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary )
|
||||
#Write-Host "build-simple: clang"
|
||||
|
||||
$object = $unit -replace '\.cpp', '.obj'
|
||||
$map = $unit -replace '\.cpp', '.map'
|
||||
$object = join-path $path_build (split-path $object -Leaf)
|
||||
$map = join-path $path_build (split-path $map -Leaf)
|
||||
$object = join-path $path_output (split-path $object -Leaf)
|
||||
$map = join-path $path_output (split-path $map -Leaf)
|
||||
|
||||
# The PDB file has to also be time-stamped so that we can reload the DLL at runtime
|
||||
$pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
|
||||
@ -174,11 +173,15 @@ if ( $vendor -match "clang" )
|
||||
$flag_exceptions_disabled,
|
||||
$flag_target_arch, $target_arch,
|
||||
$flag_wall,
|
||||
$flag_preprocess_on_intergrated,
|
||||
$flag_preprocess_non_intergrated,
|
||||
# $flag_section_data,
|
||||
# $flag_section_functions,
|
||||
( $flag_path_output + $object )
|
||||
)
|
||||
if ( $verbose ) {
|
||||
# $compiler_args += $flag_verbose
|
||||
# $compiler_args += $flag_time_trace
|
||||
}
|
||||
if ( $optimize ) {
|
||||
$compiler_args += $flag_optimize_fast
|
||||
}
|
||||
@ -278,13 +281,13 @@ if ( $vendor -match "msvc" )
|
||||
# This works because this project uses a single unit to build
|
||||
function build-simple
|
||||
{
|
||||
param( [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary )
|
||||
param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary )
|
||||
#Write-Host "build-simple: msvc"
|
||||
|
||||
$object = $unit -replace '\.(cpp)$', '.obj'
|
||||
$map = $unit -replace '\.(cpp)$', '.map'
|
||||
$object = join-path $path_build (split-path $object -Leaf)
|
||||
$map = join-path $path_build (split-path $map -Leaf)
|
||||
$object = join-path $path_output (split-path $object -Leaf)
|
||||
$map = join-path $path_output (split-path $map -Leaf)
|
||||
|
||||
# The PDB file has to also be time-stamped so that we can reload the DLL at runtime
|
||||
$pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb"
|
||||
@ -297,10 +300,13 @@ if ( $vendor -match "msvc" )
|
||||
$flag_RTTI_disabled,
|
||||
$flag_preprocess_conform,
|
||||
$flag_full_src_path,
|
||||
( $flag_path_interm + $path_build + '\' ),
|
||||
( $flag_path_output + $path_build + '\' )
|
||||
( $flag_path_interm + $path_output + '\' ),
|
||||
( $flag_path_output + $path_output + '\' )
|
||||
)
|
||||
|
||||
if ( $verbose ) {
|
||||
}
|
||||
|
||||
if ( $optimize ) {
|
||||
$compiler_args += $flag_optimize_fast
|
||||
}
|
||||
@ -312,7 +318,7 @@ if ( $vendor -match "msvc" )
|
||||
{
|
||||
$compiler_args += $flag_debug
|
||||
$compiler_args += ( $flag_define + 'Build_Debug=1' )
|
||||
$compiler_args += ( $flag_path_debug + $path_build + '\' )
|
||||
$compiler_args += ( $flag_path_debug + $path_output + '\' )
|
||||
$compiler_args += $flag_link_win_rt_static_debug
|
||||
|
||||
if ( $optimize ) {
|
||||
|
@ -8,7 +8,7 @@ function format-cpp
|
||||
Write-Host "Beginning format"
|
||||
$formatParams = @(
|
||||
'-i' # In-place
|
||||
'-style=file:./scripts/.clang-format'
|
||||
'-style=file:.clang-format'
|
||||
'-verbose'
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user