mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2024-12-22 06:14:45 -08:00
Day 23 complete
This commit is contained in:
parent
06252e91f5
commit
b2b9592880
4
.gitignore
vendored
4
.gitignore
vendored
@ -21,6 +21,10 @@ vc140.pdb
|
|||||||
build
|
build
|
||||||
|
|
||||||
**/*.dll
|
**/*.dll
|
||||||
|
**/*.exe
|
||||||
|
**/*.pdb
|
||||||
|
|
||||||
|
**/*.hmi
|
||||||
data/test.out
|
data/test.out
|
||||||
data/handmade_engine.symbols
|
data/handmade_engine.symbols
|
||||||
data/handmade_win32.exe
|
data/handmade_win32.exe
|
||||||
|
39
.vscode/bookmarks.json
vendored
Normal file
39
.vscode/bookmarks.json
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "project/platform/win32_platform.cpp",
|
||||||
|
"bookmarks": [
|
||||||
|
{
|
||||||
|
"line": 57,
|
||||||
|
"column": 0,
|
||||||
|
"label": "Struct Defs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"line": 96,
|
||||||
|
"column": 0,
|
||||||
|
"label": "Static Data"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"line": 629,
|
||||||
|
"column": 0,
|
||||||
|
"label": "Timing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"line": 1479,
|
||||||
|
"column": 4,
|
||||||
|
"label": "Main Loop : Audio Processing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"line": 1598,
|
||||||
|
"column": 2,
|
||||||
|
"label": "Main Loop : Timing Update"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"line": 1682,
|
||||||
|
"column": 0,
|
||||||
|
"label": "Main Loop : End"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
22
README.md
22
README.md
@ -23,7 +23,29 @@ The build is done in two stages:
|
|||||||
1. ~~Build and run metaprogram to scan and generate dependent code.~~ (Not needed yet)
|
1. ~~Build and run metaprogram to scan and generate dependent code.~~ (Not needed yet)
|
||||||
2. Build the handmade hero runtime.
|
2. Build the handmade hero runtime.
|
||||||
|
|
||||||
|
## Milestones
|
||||||
|
|
||||||
|
## Win32 Platform Layer
|
||||||
|
|
||||||
|
- [x] Day 001
|
||||||
|
- [x] Day 002
|
||||||
|
- [x] Day 003
|
||||||
|
- [x] Day 004
|
||||||
|
- [x] Day 005
|
||||||
|
- [x] Day 006
|
||||||
|
- [x] Day 007
|
||||||
|
- [x] Day 008
|
||||||
|
- [x] Day 009
|
||||||
|
- [x] Day 010
|
||||||
|
- [x] Day 011
|
||||||
|
- [x] Day 012
|
||||||
|
- [x] Day 013
|
||||||
|
- [x] Day 014
|
||||||
|
- [x] Day 015
|
||||||
|
|
||||||
|
|
||||||
## Gallery
|
## Gallery
|
||||||
|
|
||||||
|
![img](https://files.catbox.moe/ruv97s.gif)
|
||||||
![img](https://files.catbox.moe/9zau4s.png)
|
![img](https://files.catbox.moe/9zau4s.png)
|
||||||
![img](https://files.catbox.moe/b7ifa8.png)
|
![img](https://files.catbox.moe/b7ifa8.png)
|
||||||
|
5
data/binaries/handmade_engine.symbols
Normal file
5
data/binaries/handmade_engine.symbols
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
?on_module_reload@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z
|
||||||
|
?startup@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z
|
||||||
|
?shutdown@engine@@YAXPEAUMemory@1@PEAUModuleAPI@platform@@@Z
|
||||||
|
?update_and_render@engine@@YAXPEAUInputState@1@PEAUOffscreenBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z
|
||||||
|
?update_audio@engine@@YAXPEAUAudioBuffer@1@PEAUMemory@1@PEAUModuleAPI@platform@@@Z
|
BIN
data/test_input.hmi
Normal file
BIN
data/test_input.hmi
Normal file
Binary file not shown.
@ -1,2 +1,4 @@
|
|||||||
# Day 22
|
# Day 22
|
||||||
|
|
||||||
|
There is an issue with the hot-reload on vscode, does not show up in vs2022 debugger nor remedybg so I won't bother with it.
|
||||||
|
(Debugging hot-reloaded module doesn't work with vscode's debugger)
|
||||||
|
11
docs/Day 023.md
Normal file
11
docs/Day 023.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Day 23
|
||||||
|
|
||||||
|
Getting state saving was nice.
|
||||||
|
|
||||||
|
I decided to expose the file inteface through the platform API permanently, so that I can use it for other things later on.
|
||||||
|
|
||||||
|
I'm changing my varaible naming convention in structus from UpperCamel to lower_snake_case.
|
||||||
|
I realized that semantic highlighting covers any contextual issues along with editor intellisense.
|
||||||
|
Even at worst case with public/protected/private specifers intellisense covers it.
|
||||||
|
|
||||||
|
So I'm going with the option that keeps my naming convention consistent and more flexible to use with Casey's exploratory programming style.
|
@ -5,6 +5,40 @@
|
|||||||
|
|
||||||
NS_ENGINE_BEGIN
|
NS_ENGINE_BEGIN
|
||||||
|
|
||||||
|
#define pressed( btn ) (btn.EndedDown && btn.HalfTransitions == 1)
|
||||||
|
|
||||||
|
// Used to determine if analog input is at move threshold
|
||||||
|
constexpr f32 analog__move_threshold = 0.5f;
|
||||||
|
|
||||||
|
struct EngineActions
|
||||||
|
{
|
||||||
|
b32 move_up = false;
|
||||||
|
b32 move_down = false;
|
||||||
|
b32 move_left = false;
|
||||||
|
b32 move_right = false;
|
||||||
|
|
||||||
|
b32 loop_mode = false;
|
||||||
|
|
||||||
|
b32 raise_volume = false;
|
||||||
|
b32 lower_volume = false;
|
||||||
|
b32 raise_tone_hz = false;
|
||||||
|
b32 lower_tone_hz = false;
|
||||||
|
|
||||||
|
b32 toggle_wave_tone = false;
|
||||||
|
|
||||||
|
b32 pause_renderer = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerActions
|
||||||
|
{
|
||||||
|
s32 player_x_move_digital = 0;
|
||||||
|
s32 player_y_move_digital = 0;
|
||||||
|
f32 player_x_move_analog = 0;
|
||||||
|
f32 player_y_move_analog = 0;
|
||||||
|
|
||||||
|
b32 jump = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct EngineState
|
struct EngineState
|
||||||
{
|
{
|
||||||
s32 WaveToneHz;
|
s32 WaveToneHz;
|
||||||
@ -16,8 +50,17 @@ struct EngineState
|
|||||||
|
|
||||||
f32 SampleWaveSineTime;
|
f32 SampleWaveSineTime;
|
||||||
b32 SampleWaveSwitch;
|
b32 SampleWaveSwitch;
|
||||||
|
|
||||||
|
s32 InputRecordingIndex;
|
||||||
|
s32 InputPlayingIndex;
|
||||||
|
|
||||||
|
platform::File ActiveInputRecordingFile;
|
||||||
|
platform::File ActivePlaybackFile;
|
||||||
|
|
||||||
|
hh::Memory game_memory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using GetSoundSampleValueFn = s16( EngineState* state, AudioBuffer* sound_buffer );
|
using GetSoundSampleValueFn = s16( EngineState* state, AudioBuffer* sound_buffer );
|
||||||
|
|
||||||
internal s16
|
internal s16
|
||||||
@ -117,6 +160,209 @@ render_weird_graident(OffscreenBuffer* buffer, u32 x_offset, u32 y_offset )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
render_player( OffscreenBuffer* buffer, s32 pos_x, s32 pos_y )
|
||||||
|
{
|
||||||
|
u8* end_of_buffer = rcast(u8*, buffer->Memory)
|
||||||
|
- buffer->BytesPerPixel * buffer->Width
|
||||||
|
+ buffer->Pitch * buffer->Height;
|
||||||
|
|
||||||
|
s32 top = pos_y;
|
||||||
|
s32 bottom = pos_y + 10;
|
||||||
|
|
||||||
|
u32 color = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
for ( s32 coord_x = pos_x; coord_x < (pos_x+ 10); ++ coord_x )
|
||||||
|
{
|
||||||
|
u8*
|
||||||
|
pixel_byte = rcast(u8*, buffer->Memory);
|
||||||
|
pixel_byte += coord_x * buffer->BytesPerPixel;
|
||||||
|
pixel_byte += top * buffer->Pitch;
|
||||||
|
|
||||||
|
for ( s32 coord_y = top; coord_y < bottom; ++ coord_y )
|
||||||
|
{
|
||||||
|
if ( pixel_byte < buffer->Memory || pixel_byte >= end_of_buffer )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s32* pixel = rcast(s32*, pixel_byte);
|
||||||
|
*pixel = color;
|
||||||
|
|
||||||
|
pixel_byte += buffer->Pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void begin_recording_input( EngineState* state, InputState* input, platform::ModuleAPI* platform_api )
|
||||||
|
{
|
||||||
|
state->ActiveInputRecordingFile.Path = str_ascii("test_input.hmi");
|
||||||
|
state->InputRecordingIndex = 1;
|
||||||
|
|
||||||
|
// TODO(Ed) : If game persist memory is larger than 4 gb, this will need to be done in chunks...
|
||||||
|
platform_api->file_write_content( & state->ActiveInputRecordingFile, scast(u32, state->game_memory.PersistentSize), state->game_memory.Persistent );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void end_recording_input( EngineState* state, InputState* input, platform::ModuleAPI* platform_api )
|
||||||
|
{
|
||||||
|
platform_api->file_close( & state->ActiveInputRecordingFile );
|
||||||
|
state->InputRecordingIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void begin_playback_input( EngineState* state, InputState* input, platform::ModuleAPI* platform_api )
|
||||||
|
{
|
||||||
|
Str file_name = str_ascii("test_input.hmi");
|
||||||
|
if ( platform_api->file_check_exists( file_name ) )
|
||||||
|
{
|
||||||
|
state->ActivePlaybackFile.Path = str_ascii("test_input.hmi");
|
||||||
|
state->InputPlayingIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( state->ActiveInputRecordingFile.OpaqueHandle == nullptr )
|
||||||
|
{
|
||||||
|
platform_api->file_read_stream( & state->ActivePlaybackFile, scast(u32, state->game_memory.PersistentSize), state->game_memory.Persistent );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void end_playback_input( EngineState* state, InputState* input, platform::ModuleAPI* platform_api )
|
||||||
|
{
|
||||||
|
platform_api->file_rewind( & state->ActivePlaybackFile );
|
||||||
|
platform_api->file_read_stream( & state->ActivePlaybackFile, scast(u32, state->game_memory.PersistentSize), state->game_memory.Persistent );
|
||||||
|
platform_api->file_close( & state->ActivePlaybackFile );
|
||||||
|
|
||||||
|
state->InputPlayingIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStateSnapshot input_state_snapshot( InputState* input )
|
||||||
|
{
|
||||||
|
InputStateSnapshot snapshot = {};
|
||||||
|
for ( s32 idx = 0; idx < array_count( snapshot.Controllers ); ++ idx )
|
||||||
|
{
|
||||||
|
ControllerState* controller = & input->Controllers[idx];
|
||||||
|
if ( controller == nullptr )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( controller->DSPad )
|
||||||
|
snapshot.Controllers[idx].DSPad = *controller->DSPad;
|
||||||
|
|
||||||
|
if ( controller->XPad )
|
||||||
|
snapshot.Controllers[idx].XPad = *controller->XPad;
|
||||||
|
|
||||||
|
if ( controller->Keyboard )
|
||||||
|
{
|
||||||
|
snapshot.Controllers[idx].Keyboard = *controller->Keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( controller->Mouse )
|
||||||
|
snapshot.Controllers[idx].Mouse = *controller->Mouse;
|
||||||
|
}
|
||||||
|
return snapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void record_input( EngineState* state, InputState* input, platform::ModuleAPI* platform_api )
|
||||||
|
{
|
||||||
|
InputStateSnapshot snapshot = input_state_snapshot( input );
|
||||||
|
if ( platform_api->file_write_stream( & state->ActiveInputRecordingFile, sizeof(snapshot), &snapshot ) == 0 )
|
||||||
|
{
|
||||||
|
// TODO(Ed) : Logging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void play_input( EngineState* state, InputState* input, platform::ModuleAPI* platform_api )
|
||||||
|
{
|
||||||
|
InputStateSnapshot new_input;
|
||||||
|
if ( platform_api->file_read_stream( & state->ActivePlaybackFile, sizeof(InputStateSnapshot), & new_input ) == 0 )
|
||||||
|
{
|
||||||
|
end_playback_input( state, input, platform_api );
|
||||||
|
begin_playback_input( state, input, platform_api );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( s32 idx = 0; idx < array_count( new_input.Controllers ); ++ idx )
|
||||||
|
{
|
||||||
|
ControllerState* controller = & input->Controllers[idx];
|
||||||
|
if ( controller == nullptr )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( controller->DSPad )
|
||||||
|
*controller->DSPad = new_input.Controllers[idx].DSPad;
|
||||||
|
|
||||||
|
if ( controller->XPad )
|
||||||
|
*controller->XPad = new_input.Controllers[idx].XPad;
|
||||||
|
|
||||||
|
if ( controller->Keyboard )
|
||||||
|
{
|
||||||
|
*controller->Keyboard = new_input.Controllers[idx].Keyboard;
|
||||||
|
printf("keyboard D key: %d\n", controller->Keyboard->D.EndedDown );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( controller->Mouse )
|
||||||
|
*controller->Mouse = new_input.Controllers[idx].Mouse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void input_poll_engine_actions( InputState* input, EngineActions* actions )
|
||||||
|
{
|
||||||
|
ControllerState* controller = & input->Controllers[0];
|
||||||
|
KeyboardState* keyboard = controller->Keyboard;
|
||||||
|
|
||||||
|
actions->move_right |= keyboard->D.EndedDown;
|
||||||
|
actions->move_left |= keyboard->A.EndedDown;
|
||||||
|
actions->move_up |= keyboard->W.EndedDown;
|
||||||
|
actions->move_down |= keyboard->S.EndedDown;
|
||||||
|
|
||||||
|
actions->raise_volume |= keyboard->Up.EndedDown;
|
||||||
|
actions->lower_volume |= keyboard->Down.EndedDown;
|
||||||
|
|
||||||
|
actions->raise_tone_hz |= keyboard->Right.EndedDown;
|
||||||
|
actions->lower_tone_hz |= keyboard->Left.EndedDown;
|
||||||
|
|
||||||
|
actions->pause_renderer |= pressed( keyboard->Pause );
|
||||||
|
|
||||||
|
actions->toggle_wave_tone |= pressed( keyboard->Q );
|
||||||
|
|
||||||
|
actions->loop_mode |= pressed( keyboard->L );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
void input_poll_player_actions( InputState* input, PlayerActions* actions )
|
||||||
|
{
|
||||||
|
ControllerState* controller = & input->Controllers[0];
|
||||||
|
|
||||||
|
if ( controller->DSPad )
|
||||||
|
{
|
||||||
|
DualsensePadState* pad = controller->DSPad;
|
||||||
|
|
||||||
|
actions->jump |= pressed( pad->X );
|
||||||
|
|
||||||
|
actions->player_x_move_analog += pad->Stick.Left.X.End;
|
||||||
|
actions->player_y_move_analog += pad->Stick.Left.Y.End;
|
||||||
|
}
|
||||||
|
if ( controller->XPad )
|
||||||
|
{
|
||||||
|
XInputPadState* pad = controller->XPad;
|
||||||
|
|
||||||
|
actions->jump |= pressed( pad->A );
|
||||||
|
|
||||||
|
actions->player_x_move_analog += pad->Stick.Left.X.End;
|
||||||
|
actions->player_y_move_analog += pad->Stick.Left.Y.End;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( controller->Keyboard )
|
||||||
|
{
|
||||||
|
KeyboardState* keyboard = controller->Keyboard;
|
||||||
|
actions->jump |= pressed( keyboard->Space );
|
||||||
|
|
||||||
|
actions->player_x_move_digital += keyboard->D.EndedDown - keyboard->A.EndedDown;
|
||||||
|
actions->player_y_move_digital += keyboard->W.EndedDown - keyboard->S.EndedDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Engine_API
|
Engine_API
|
||||||
void on_module_reload( Memory* memory, platform::ModuleAPI* platfom_api )
|
void on_module_reload( Memory* memory, platform::ModuleAPI* platfom_api )
|
||||||
{
|
{
|
||||||
@ -135,24 +381,28 @@ void startup( Memory* memory, platform::ModuleAPI* platform_api )
|
|||||||
state->YOffset = 0;
|
state->YOffset = 0;
|
||||||
|
|
||||||
state->SampleWaveSwitch = false;
|
state->SampleWaveSwitch = false;
|
||||||
state->WaveToneHz = 120;
|
state->WaveToneHz = 60;
|
||||||
state->SampleWaveSineTime = 0.f;
|
state->SampleWaveSineTime = 0.f;
|
||||||
|
|
||||||
state->RendererPaused = false;
|
state->RendererPaused = false;
|
||||||
|
|
||||||
#if Build_Debug && 0
|
state->InputRecordingIndex = 0;
|
||||||
{
|
state->InputPlayingIndex = 0;
|
||||||
using namespace platform;
|
|
||||||
|
|
||||||
char const* file_path = __FILE__;
|
state->ActiveInputRecordingFile = {};
|
||||||
Debug_FileContent file_content = platform_api->debug_file_read_content( file_path );
|
state->ActivePlaybackFile = {};
|
||||||
if ( file_content.Size )
|
|
||||||
{
|
state->game_memory.PersistentSize = memory->PersistentSize / 2;
|
||||||
platform_api->debug_file_write_content( "test.out", file_content.Size, file_content.Data );
|
state->game_memory.Persistent = rcast(Byte*, memory->Persistent) + state->game_memory.PersistentSize;
|
||||||
platform_api->debug_file_free_content( & file_content );
|
state->game_memory.TransientSize = memory->TransientSize / 2;
|
||||||
}
|
state->game_memory.Transient = rcast(Byte*, memory->Transient) + state->game_memory.TransientSize;
|
||||||
}
|
|
||||||
#endif
|
hh::PlayerState* player = rcast( hh::PlayerState*, state->game_memory.Persistent );
|
||||||
|
assert( sizeof(hh::PlayerState) <= state->game_memory.PersistentSize );
|
||||||
|
|
||||||
|
player->Pos_X = 100;
|
||||||
|
player->Pos_Y = 100;
|
||||||
|
player->MidJump = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine_API
|
Engine_API
|
||||||
@ -169,119 +419,61 @@ void update_and_render( InputState* input, OffscreenBuffer* back_buffer, Memory*
|
|||||||
|
|
||||||
ControllerState* controller = & input->Controllers[0];
|
ControllerState* controller = & input->Controllers[0];
|
||||||
|
|
||||||
// Abstracting the actionables as booleans and processing within this scope
|
EngineActions engine_actions {};
|
||||||
// for now until proper callbacks for input bindings are setup.
|
PlayerActions player_actions {};
|
||||||
b32 move_up = false;
|
|
||||||
b32 move_down = false;
|
|
||||||
b32 move_left = false;
|
|
||||||
b32 move_right = false;
|
|
||||||
|
|
||||||
b32 action_up = false;
|
input_poll_engine_actions( input, & engine_actions );
|
||||||
b32 action_down = false;
|
|
||||||
b32 action_left = false;
|
|
||||||
b32 action_right = false;
|
|
||||||
|
|
||||||
b32 raise_volume = false;
|
|
||||||
b32 lower_volume = false;
|
|
||||||
b32 raise_tone_hz = false;
|
|
||||||
b32 lower_tone_hz = false;
|
|
||||||
|
|
||||||
b32 toggle_wave_tone = false;
|
|
||||||
|
|
||||||
b32 pause_renderer = false;
|
|
||||||
|
|
||||||
f32 analog_threshold = 0.5f;
|
|
||||||
|
|
||||||
#define pressed( btn ) (btn.EndedDown && btn.HalfTransitions < 1)
|
|
||||||
|
|
||||||
if ( controller->DSPad )
|
|
||||||
{
|
{
|
||||||
DualsensePadState* pad = controller->DSPad;
|
state->XOffset += 3 * engine_actions.move_right;
|
||||||
|
state->XOffset -= 3 * engine_actions.move_left;
|
||||||
|
state->YOffset += 3 * engine_actions.move_down;
|
||||||
|
state->YOffset -= 3 * engine_actions.move_up;
|
||||||
|
|
||||||
move_right |= pad->DPad.Right.EndedDown || pad->Stick.Left.X.End > analog_threshold;
|
if ( engine_actions.raise_volume )
|
||||||
move_left |= pad->DPad.Left.EndedDown || pad->Stick.Left.X.End < -analog_threshold;
|
|
||||||
move_up |= pad->DPad.Up.EndedDown || pad->Stick.Left.Y.End > analog_threshold;
|
|
||||||
move_down |= pad->DPad.Down.EndedDown || pad->Stick.Left.Y.End < -analog_threshold;
|
|
||||||
|
|
||||||
raise_volume |= pad->Triangle.EndedDown;
|
|
||||||
lower_volume |= pad->Circle.EndedDown;
|
|
||||||
|
|
||||||
raise_tone_hz |= pad->Square.EndedDown;
|
|
||||||
lower_tone_hz |= pad->X.EndedDown;
|
|
||||||
|
|
||||||
toggle_wave_tone |= pressed( pad->Options );
|
|
||||||
}
|
|
||||||
if ( controller->XPad )
|
|
||||||
{
|
|
||||||
XInputPadState* pad = controller->XPad;
|
|
||||||
|
|
||||||
move_right |= pad->DPad.Right.EndedDown || pad->Stick.Left.X.End > analog_threshold;
|
|
||||||
move_left |= pad->DPad.Left.EndedDown || pad->Stick.Left.X.End < -analog_threshold;
|
|
||||||
move_up |= pad->DPad.Up.EndedDown || pad->Stick.Left.Y.End > analog_threshold;
|
|
||||||
move_down |= pad->DPad.Down.EndedDown || pad->Stick.Left.Y.End < -analog_threshold;
|
|
||||||
|
|
||||||
raise_volume |= pad->Y.EndedDown;
|
|
||||||
lower_volume |= pad->B.EndedDown;
|
|
||||||
|
|
||||||
raise_tone_hz |= pad->X.EndedDown;
|
|
||||||
lower_tone_hz |= pad->A.EndedDown;
|
|
||||||
|
|
||||||
toggle_wave_tone |= pressed( pad->Start );
|
|
||||||
}
|
|
||||||
if ( controller->Keyboard )
|
|
||||||
{
|
|
||||||
KeyboardState* keyboard = controller->Keyboard;
|
|
||||||
|
|
||||||
move_right |= keyboard->D.EndedDown;
|
|
||||||
move_left |= keyboard->A.EndedDown;
|
|
||||||
move_up |= keyboard->W.EndedDown;
|
|
||||||
move_down |= keyboard->S.EndedDown;
|
|
||||||
|
|
||||||
raise_volume |= keyboard->Up.EndedDown;
|
|
||||||
lower_volume |= keyboard->Down.EndedDown;
|
|
||||||
|
|
||||||
raise_tone_hz |= keyboard->Right.EndedDown;
|
|
||||||
lower_tone_hz |= keyboard->Left.EndedDown;
|
|
||||||
|
|
||||||
pause_renderer |= pressed( keyboard->Pause );
|
|
||||||
|
|
||||||
toggle_wave_tone |= pressed( keyboard->Space );
|
|
||||||
}
|
|
||||||
|
|
||||||
state->XOffset += 3 * move_right;
|
|
||||||
state->XOffset -= 3 * move_left;
|
|
||||||
state->YOffset += 3 * move_down;
|
|
||||||
state->YOffset -= 3 * move_up;
|
|
||||||
|
|
||||||
if ( raise_volume )
|
|
||||||
{
|
{
|
||||||
state->ToneVolume += 10;
|
state->ToneVolume += 10;
|
||||||
}
|
}
|
||||||
if ( lower_volume )
|
if ( engine_actions.lower_volume )
|
||||||
{
|
{
|
||||||
state->ToneVolume -= 10;
|
state->ToneVolume -= 10;
|
||||||
if ( state->ToneVolume <= 0 )
|
if ( state->ToneVolume <= 0 )
|
||||||
state->ToneVolume = 0;
|
state->ToneVolume = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( raise_tone_hz )
|
if ( engine_actions.raise_tone_hz )
|
||||||
{
|
{
|
||||||
state->WaveToneHz += 1;
|
state->WaveToneHz += 1;
|
||||||
}
|
}
|
||||||
if ( lower_tone_hz )
|
if ( engine_actions.lower_tone_hz )
|
||||||
{
|
{
|
||||||
state->WaveToneHz -= 1;
|
state->WaveToneHz -= 1;
|
||||||
if ( state->WaveToneHz <= 0 )
|
if ( state->WaveToneHz <= 0 )
|
||||||
state->WaveToneHz = 1;
|
state->WaveToneHz = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( toggle_wave_tone )
|
if ( engine_actions.toggle_wave_tone )
|
||||||
{
|
{
|
||||||
state->SampleWaveSwitch ^= true;
|
state->SampleWaveSwitch ^= true;
|
||||||
}
|
}
|
||||||
render_weird_graident( back_buffer, state->XOffset, state->YOffset );
|
|
||||||
|
|
||||||
if ( pause_renderer )
|
if ( engine_actions.loop_mode )
|
||||||
|
{
|
||||||
|
if ( state->InputRecordingIndex == 0 && state->InputPlayingIndex == 0 )
|
||||||
|
{
|
||||||
|
begin_recording_input( state, input, platform_api );
|
||||||
|
}
|
||||||
|
else if ( state->InputPlayingIndex )
|
||||||
|
{
|
||||||
|
end_playback_input( state, input, platform_api );
|
||||||
|
}
|
||||||
|
else if ( state->InputRecordingIndex )
|
||||||
|
{
|
||||||
|
end_recording_input( state, input, platform_api );
|
||||||
|
begin_playback_input( state, input, platform_api );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( engine_actions.pause_renderer )
|
||||||
{
|
{
|
||||||
if ( state->RendererPaused )
|
if ( state->RendererPaused )
|
||||||
{
|
{
|
||||||
@ -294,6 +486,49 @@ void update_and_render( InputState* input, OffscreenBuffer* back_buffer, Memory*
|
|||||||
state->RendererPaused = true;
|
state->RendererPaused = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( state->InputRecordingIndex )
|
||||||
|
{
|
||||||
|
record_input( state, input, platform_api );
|
||||||
|
}
|
||||||
|
if ( state->InputPlayingIndex )
|
||||||
|
{
|
||||||
|
play_input( state, input, platform_api );
|
||||||
|
}
|
||||||
|
|
||||||
|
hh::PlayerState* player = rcast( hh::PlayerState*, state->game_memory.Persistent );
|
||||||
|
assert( sizeof(hh::PlayerState) <= state->game_memory.PersistentSize );
|
||||||
|
|
||||||
|
input_poll_player_actions( input, & player_actions );
|
||||||
|
{
|
||||||
|
player->Pos_X += player_actions.player_x_move_digital * 5;
|
||||||
|
player->Pos_Y -= player_actions.player_y_move_digital * 5;
|
||||||
|
player->Pos_X += scast(u32, player_actions.player_x_move_analog * 5);
|
||||||
|
player->Pos_Y -= scast(u32, player_actions.player_y_move_analog * 5) - scast(u32, sinf( player->JumpTime * TAU ) * 10);
|
||||||
|
|
||||||
|
if ( player->JumpTime > 0.f )
|
||||||
|
{
|
||||||
|
player->JumpTime -= 0.025f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player->JumpTime = 0.f;
|
||||||
|
player->MidJump = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! player->MidJump && player_actions.jump )
|
||||||
|
{
|
||||||
|
player->JumpTime = 1.f;
|
||||||
|
player->MidJump = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render_weird_graident( back_buffer, 0, 0 );
|
||||||
|
render_player( back_buffer, player->Pos_X, player->Pos_Y );
|
||||||
|
|
||||||
|
if ( state->InputRecordingIndex )
|
||||||
|
render_player( back_buffer, player->Pos_X + 20, player->Pos_Y - 20 );
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine_API
|
Engine_API
|
||||||
@ -312,3 +547,5 @@ void update_audio( AudioBuffer* audio_buffer, Memory* memory, platform::ModuleAP
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_ENGINE_END
|
NS_ENGINE_END
|
||||||
|
|
||||||
|
#undef pressed
|
||||||
|
@ -79,12 +79,14 @@ union KeyboardState
|
|||||||
{
|
{
|
||||||
DigitalBtn Keys[12];
|
DigitalBtn Keys[12];
|
||||||
struct {
|
struct {
|
||||||
|
DigitalBtn Row_1;
|
||||||
DigitalBtn Q;
|
DigitalBtn Q;
|
||||||
DigitalBtn E;
|
DigitalBtn E;
|
||||||
DigitalBtn W;
|
DigitalBtn W;
|
||||||
DigitalBtn A;
|
DigitalBtn A;
|
||||||
DigitalBtn S;
|
DigitalBtn S;
|
||||||
DigitalBtn D;
|
DigitalBtn D;
|
||||||
|
DigitalBtn L;
|
||||||
DigitalBtn Escape;
|
DigitalBtn Escape;
|
||||||
DigitalBtn Backspace;
|
DigitalBtn Backspace;
|
||||||
DigitalBtn Up;
|
DigitalBtn Up;
|
||||||
@ -175,11 +177,24 @@ struct ControllerState
|
|||||||
DualsensePadState* DSPad;
|
DualsensePadState* DSPad;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ControllerStateSnapshot
|
||||||
|
{
|
||||||
|
KeyboardState Keyboard;
|
||||||
|
MousesState Mouse;
|
||||||
|
XInputPadState XPad;
|
||||||
|
DualsensePadState DSPad;
|
||||||
|
};
|
||||||
|
|
||||||
struct InputState
|
struct InputState
|
||||||
{
|
{
|
||||||
ControllerState Controllers[4];
|
ControllerState Controllers[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InputStateSnapshot
|
||||||
|
{
|
||||||
|
ControllerStateSnapshot Controllers[4];
|
||||||
|
};
|
||||||
|
|
||||||
using InputBindCallback = void( void* );
|
using InputBindCallback = void( void* );
|
||||||
using InputBindCallback_DigitalBtn = void( engine::DigitalBtn* Button );
|
using InputBindCallback_DigitalBtn = void( engine::DigitalBtn* Button );
|
||||||
using InputBindCallback_AnalogAxis = void( engine::AnalogAxis* Axis );
|
using InputBindCallback_AnalogAxis = void( engine::AnalogAxis* Axis );
|
||||||
@ -194,4 +209,12 @@ struct InputMode
|
|||||||
void input_mode_pop( InputMode* mode );
|
void input_mode_pop( InputMode* mode );
|
||||||
void input_mode_pop( InputMode* mode );
|
void input_mode_pop( InputMode* mode );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
struct RecordedInput
|
||||||
|
{
|
||||||
|
s32 Num;
|
||||||
|
InputState* Stream;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_ENGINE_END
|
NS_ENGINE_END
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "engine/engine.hpp"
|
#include "engine/engine.hpp"
|
||||||
|
|
||||||
#define NS_HANDMADE_BEGIN namespace handmade {
|
#define NS_HANDMADE_BEGIN namespace hh {
|
||||||
#define NS_HANDMADE_END }
|
#define NS_HANDMADE_END }
|
||||||
|
|
||||||
NS_HANDMADE_BEGIN
|
NS_HANDMADE_BEGIN
|
||||||
@ -63,4 +63,13 @@ struct Player
|
|||||||
// Possilby some other stuff in the future.
|
// Possilby some other stuff in the future.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PlayerState
|
||||||
|
{
|
||||||
|
s32 Pos_X;
|
||||||
|
s32 Pos_Y;
|
||||||
|
|
||||||
|
b32 MidJump;
|
||||||
|
f32 JumpTime;
|
||||||
|
};
|
||||||
|
|
||||||
NS_HANDMADE_END
|
NS_HANDMADE_END
|
||||||
|
@ -44,33 +44,24 @@ NS_PLATFORM_BEGIN
|
|||||||
IMPORTANT : These are not for shipping code - they are blocking and the write isn't protected.
|
IMPORTANT : These are not for shipping code - they are blocking and the write isn't protected.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct Debug_FileContent
|
using DebugSetPauseRenderingFn = void (b32 value);
|
||||||
{
|
|
||||||
void* Data;
|
|
||||||
u32 Size;
|
|
||||||
Byte _PAD_[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BinaryModule
|
struct File
|
||||||
{
|
{
|
||||||
void* OpaqueHandle;
|
void* OpaqueHandle;
|
||||||
|
Str Path;
|
||||||
|
void* Data;
|
||||||
|
u32 Size;
|
||||||
};
|
};
|
||||||
|
|
||||||
using DebugFileFreeContentFn = void ( Debug_FileContent* file_content );
|
|
||||||
using DebugFileReadContentFn = Debug_FileContent ( char const* file_path );
|
|
||||||
using DebugFileWriteContentFn = b32 ( char const* file_path, u32 content_size, void* content_memory );
|
|
||||||
|
|
||||||
using DebugSetPauseRenderingFn = void (b32 value);
|
|
||||||
|
|
||||||
// TODO(Ed): This also assumes the symbol name is always within size of the provided buffer, needs to fail if not.
|
// TODO(Ed): This also assumes the symbol name is always within size of the provided buffer, needs to fail if not.
|
||||||
// Note: This is a temporary solution until there is more infrastructure for the engine to use.
|
// Note: This is a temporary solution until there is more infrastructure for the engine to use.
|
||||||
void get_symbol_from_module_table( Debug_FileContent symbol_table, u32 symbol_ID, char* symbol_name )
|
void get_symbol_from_module_table( File symbol_table, u32 symbol_ID, char* symbol_name )
|
||||||
{
|
{
|
||||||
struct Token
|
struct Token
|
||||||
{
|
{
|
||||||
char const* Ptr;
|
char const* Ptr;
|
||||||
u32 Len;
|
u32 Len;
|
||||||
char _PAD_[4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Token tokens[256] = {};
|
Token tokens[256] = {};
|
||||||
@ -124,17 +115,34 @@ using SetEngineFrameTargetFn = void ( u32 rate_in_hz );
|
|||||||
// This module api will be used to manage the editor and game modules from the engine side,
|
// This module api will be used to manage the editor and game modules from the engine side,
|
||||||
// without the platform layer needing to know about it.
|
// without the platform layer needing to know about it.
|
||||||
|
|
||||||
|
struct BinaryModule
|
||||||
|
{
|
||||||
|
void* OpaqueHandle;
|
||||||
|
};
|
||||||
|
|
||||||
using LoadBinaryModuleFn = BinaryModule ( char const* module_path );
|
using LoadBinaryModuleFn = BinaryModule ( char const* module_path );
|
||||||
using UnloadBinaryModuleFn = void ( BinaryModule* module );
|
using UnloadBinaryModuleFn = void ( BinaryModule* module );
|
||||||
using GetModuleProcedureFn = void* ( BinaryModule module, char const* symbol );
|
using GetModuleProcedureFn = void* ( BinaryModule module, char const* symbol );
|
||||||
|
|
||||||
|
// The file interface is really just made for the engine to use.
|
||||||
|
// It will allow for only reading or writting to a file at a time.
|
||||||
|
// Note: If anything more robust is needed, I'll grab it from the zpl-c library.
|
||||||
|
|
||||||
|
using FileCheckExistsFn = b32 ( Str const file_path );
|
||||||
|
using FileCloseFn = void ( File* file );
|
||||||
|
using FileDelete = b32 ( Str const file_path );
|
||||||
|
using FileReadContentFn = b32 ( File* file );
|
||||||
|
using FileReadStreamFn = b32 ( File* file, u32 content_size, void* content_memory );
|
||||||
|
using FileWriteContentFn = u32 ( File* file, u32 content_size, void* content_memory );
|
||||||
|
using FileWriteStreamFn = u32 ( File* file, u32 content_size, void* content_memory );
|
||||||
|
using FileRewindFn = void ( File* file );
|
||||||
|
|
||||||
struct ModuleAPI
|
struct ModuleAPI
|
||||||
{
|
{
|
||||||
#if Build_Development
|
Str PathRoot;
|
||||||
DebugFileFreeContentFn* debug_file_free_content;
|
Str PathBinaries;
|
||||||
DebugFileReadContentFn* debug_file_read_content;
|
|
||||||
DebugFileWriteContentFn* debug_file_write_content;
|
|
||||||
|
|
||||||
|
#if Build_Development
|
||||||
DebugSetPauseRenderingFn* debug_set_pause_rendering;
|
DebugSetPauseRenderingFn* debug_set_pause_rendering;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -147,6 +155,15 @@ struct ModuleAPI
|
|||||||
LoadBinaryModuleFn* load_binary_module;
|
LoadBinaryModuleFn* load_binary_module;
|
||||||
UnloadBinaryModuleFn* unload_binary_module;
|
UnloadBinaryModuleFn* unload_binary_module;
|
||||||
GetModuleProcedureFn* get_module_procedure;
|
GetModuleProcedureFn* get_module_procedure;
|
||||||
|
|
||||||
|
FileCheckExistsFn* file_check_exists; // Checks if a file exists
|
||||||
|
FileCloseFn* file_close; // Files successfuly provided to the user are not automatically closed, use this to close them.
|
||||||
|
FileDelete* file_delete; // Deletes a file from the file system
|
||||||
|
FileReadContentFn* file_read_content; // Read all content within file
|
||||||
|
FileReadStreamFn* file_read_stream; // Read next chunk of content within file
|
||||||
|
FileRewindFn* file_rewind; // Rewinds the file stream to the beginning
|
||||||
|
FileWriteContentFn* file_write_content; // Writes content to file (overwrites)
|
||||||
|
FileWriteStreamFn* file_write_stream; // Appends content to file
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma endregion Settings Exposure
|
#pragma endregion Settings Exposure
|
||||||
|
@ -44,6 +44,12 @@
|
|||||||
|
|
||||||
NS_WIN32_BEGIN
|
NS_WIN32_BEGIN
|
||||||
|
|
||||||
|
enum LWA : DWORD
|
||||||
|
{
|
||||||
|
LWA_Alpha = 0x00000002,
|
||||||
|
LWA_ColorKey = 0x00000001,
|
||||||
|
};
|
||||||
|
|
||||||
enum BI : DWORD
|
enum BI : DWORD
|
||||||
{
|
{
|
||||||
BI_RGB_Uncompressed = 0L,
|
BI_RGB_Uncompressed = 0L,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -479,8 +479,11 @@ else {
|
|||||||
|
|
||||||
if ( $engine )
|
if ( $engine )
|
||||||
{
|
{
|
||||||
|
$path_pdb_lock = Join-Path $path_binaries 'handmade_engine.pdb.lock'
|
||||||
|
New-Item $path_pdb_lock -ItemType File -Force -Verbose
|
||||||
|
|
||||||
# Delete old PDBs
|
# Delete old PDBs
|
||||||
$pdb_files = Get-ChildItem -Path $path_binaries -Filter "handmade_engine_*.pdb"
|
[Array]$pdb_files = Get-ChildItem -Path $path_binaries -Filter "handmade_engine_*.pdb"
|
||||||
foreach ($file in $pdb_files) {
|
foreach ($file in $pdb_files) {
|
||||||
Remove-Item -Path $file.FullName -Force
|
Remove-Item -Path $file.FullName -Force
|
||||||
Write-Host "Deleted $file" -ForegroundColor Green
|
Write-Host "Deleted $file" -ForegroundColor Green
|
||||||
@ -564,6 +567,8 @@ if ( $engine )
|
|||||||
$path_engine_symbols = Join-Path $path_binaries 'handmade_engine.symbols'
|
$path_engine_symbols = Join-Path $path_binaries 'handmade_engine.symbols'
|
||||||
$engine_symbol_list | Out-File -Path $path_engine_symbols
|
$engine_symbol_list | Out-File -Path $path_engine_symbols
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Remove-Item $path_pdb_lock -Force -Verbose
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $platform )
|
if ( $platform )
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user