mirror of
https://github.com/Ed94/HandmadeHero.git
synced 2025-06-16 03:31:49 -07:00
Day 17 complete
This commit is contained in:
@ -141,10 +141,11 @@ void update_and_render( InputState* input, OffscreenBuffer* back_buffer, SoundBu
|
||||
#endif
|
||||
|
||||
EngineState* state = rcast( EngineState*, memory->Persistent );
|
||||
|
||||
do_once_start
|
||||
assert( sizeof(EngineState) <= memory->PersistentSize );
|
||||
|
||||
state->ToneVolume = 3000;
|
||||
state->ToneVolume = 1000;
|
||||
state->WaveToneHz = 262;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
|
||||
@ -167,128 +168,108 @@ void update_and_render( InputState* input, OffscreenBuffer* back_buffer, SoundBu
|
||||
do_once_end
|
||||
|
||||
ControllerState* controller = & input->Controllers[0];
|
||||
|
||||
// Abstracting the actionables as booleans and processing within this scope
|
||||
// for now until proper callbacks for input bindings are setup.
|
||||
b32 move_up = false;
|
||||
b32 move_down = false;
|
||||
b32 move_left = false;
|
||||
b32 move_right = false;
|
||||
|
||||
b32 action_up = false;
|
||||
b32 action_down = false;
|
||||
b32 action_left = false;
|
||||
b32 action_right = false;
|
||||
|
||||
f32 analog_threshold = 0.5f;
|
||||
|
||||
b32 raise_volume = false;
|
||||
b32 lower_volume = false;
|
||||
b32 raise_tone_hz = false;
|
||||
b32 lower_tone_hz = false;
|
||||
|
||||
b32 toggle_wave_tone = false;
|
||||
|
||||
if ( controller->DSPad )
|
||||
{
|
||||
DualsensePadState* pad = controller->DSPad;
|
||||
|
||||
x_offset += pad->DPad.Right.State;
|
||||
x_offset -= pad->DPad.Left.State;
|
||||
y_offset += pad->DPad.Down.State;
|
||||
y_offset -= pad->DPad.Up.State;
|
||||
|
||||
x_offset += scast(u32, pad->Stick.Left.X.End);
|
||||
y_offset += scast(u32, pad->Stick.Left.Y.End);
|
||||
|
||||
if ( pad->Triangle.State )
|
||||
{
|
||||
state->ToneVolume += 10;
|
||||
}
|
||||
if ( pad->Circle.State )
|
||||
{
|
||||
state->ToneVolume -= 10;
|
||||
}
|
||||
|
||||
if ( pad->Square.State )
|
||||
{
|
||||
state->WaveToneHz += 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
if ( pad->X.State )
|
||||
{
|
||||
state->WaveToneHz -= 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
|
||||
if ( pad->Options.State )
|
||||
{
|
||||
wave_switch ^= true;
|
||||
}
|
||||
|
||||
if ( pad->Share.State )
|
||||
{
|
||||
// TODO(Ed) : Add rumble test
|
||||
}
|
||||
|
||||
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->Triangle.EndedDown;
|
||||
lower_volume |= pad->Circle.EndedDown;
|
||||
|
||||
raise_tone_hz |= pad->Square.EndedDown;
|
||||
lower_tone_hz |= pad->X.EndedDown;
|
||||
|
||||
toggle_wave_tone |= pad->Options.EndedDown;
|
||||
}
|
||||
if ( controller->XPad )
|
||||
{
|
||||
XInputPadState* pad = controller->XPad;
|
||||
|
||||
x_offset += pad->DPad.Right.State;
|
||||
x_offset -= pad->DPad.Left.State;
|
||||
y_offset -= pad->DPad.Down.State;
|
||||
y_offset += pad->DPad.Up.State;
|
||||
|
||||
x_offset += scast(u32, pad->Stick.Left.X.End);
|
||||
y_offset += scast(u32, pad->Stick.Left.Y.End);
|
||||
|
||||
if ( pad->Y.State )
|
||||
{
|
||||
state->ToneVolume += 10;
|
||||
}
|
||||
if ( pad->B.State )
|
||||
{
|
||||
state->ToneVolume -= 10;
|
||||
}
|
||||
|
||||
if ( pad->X.State )
|
||||
{
|
||||
state->WaveToneHz += 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
if ( pad->A.State )
|
||||
{
|
||||
state->WaveToneHz -= 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
|
||||
if ( pad->Start.State )
|
||||
{
|
||||
wave_switch ^= true;
|
||||
}
|
||||
|
||||
if ( pad->Back.State )
|
||||
{
|
||||
// TODO(Ed) : Add rumble test
|
||||
}
|
||||
|
||||
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 |= pad->Start.EndedDown;
|
||||
}
|
||||
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;
|
||||
|
||||
toggle_wave_tone |= keyboard->Space.EndedDown;
|
||||
}
|
||||
|
||||
x_offset += move_right;
|
||||
x_offset -= move_left;
|
||||
y_offset += move_down;
|
||||
y_offset -= move_up;
|
||||
|
||||
x_offset += keyboard->D.State;
|
||||
x_offset -= keyboard->A.State;
|
||||
y_offset += keyboard->W.State;
|
||||
y_offset -= keyboard->S.State;
|
||||
if ( raise_volume )
|
||||
{
|
||||
state->ToneVolume += 10;
|
||||
}
|
||||
if ( lower_volume )
|
||||
{
|
||||
state->ToneVolume -= 10;
|
||||
}
|
||||
|
||||
if ( keyboard->Esc.State )
|
||||
{
|
||||
// TODO : Add exit game
|
||||
}
|
||||
if ( raise_tone_hz )
|
||||
{
|
||||
state->WaveToneHz += 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
if ( lower_tone_hz )
|
||||
{
|
||||
state->WaveToneHz -= 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
|
||||
if ( keyboard->Space.State )
|
||||
{
|
||||
wave_switch ^= true;
|
||||
}
|
||||
|
||||
if ( keyboard->Up.State )
|
||||
{
|
||||
state->ToneVolume += 10;
|
||||
}
|
||||
if ( keyboard->Down.State )
|
||||
{
|
||||
state->ToneVolume -= 10;
|
||||
}
|
||||
if ( keyboard->Left.State )
|
||||
{
|
||||
state->WaveToneHz -= 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
if ( keyboard->Right.State )
|
||||
{
|
||||
state->WaveToneHz += 1;
|
||||
state->WavePeriod = sound_buffer->SamplesPerSecond / state->WaveToneHz;
|
||||
}
|
||||
if ( toggle_wave_tone )
|
||||
{
|
||||
wave_switch ^= true;
|
||||
}
|
||||
|
||||
// TODO(Ed) : Allow sample offsets here for more robust platform options
|
||||
|
113
project/engine.h
113
project/engine.h
@ -56,7 +56,7 @@ struct SoundBuffer
|
||||
struct DigitalBtn
|
||||
{
|
||||
s32 HalfTransitions;
|
||||
b32 State;
|
||||
b32 EndedDown;
|
||||
};
|
||||
#define DigitalBtn_Up 0
|
||||
#define DigitalBtn_Down 1
|
||||
@ -67,6 +67,9 @@ struct AnalogAxis
|
||||
f32 End;
|
||||
f32 Min;
|
||||
f32 Max;
|
||||
|
||||
// Platform doesn't provide this, we process in the engine layer.
|
||||
f32 Average;
|
||||
};
|
||||
|
||||
struct AnalogStick
|
||||
@ -75,20 +78,24 @@ struct AnalogStick
|
||||
AnalogAxis Y;
|
||||
};
|
||||
|
||||
struct KeyboardState
|
||||
union KeyboardState
|
||||
{
|
||||
DigitalBtn Q;
|
||||
DigitalBtn E;
|
||||
DigitalBtn W;
|
||||
DigitalBtn A;
|
||||
DigitalBtn S;
|
||||
DigitalBtn D;
|
||||
DigitalBtn Esc;
|
||||
DigitalBtn Up;
|
||||
DigitalBtn Down;
|
||||
DigitalBtn Left;
|
||||
DigitalBtn Right;
|
||||
DigitalBtn Space;
|
||||
DigitalBtn Keys[12];
|
||||
struct {
|
||||
DigitalBtn Q;
|
||||
DigitalBtn E;
|
||||
DigitalBtn W;
|
||||
DigitalBtn A;
|
||||
DigitalBtn S;
|
||||
DigitalBtn D;
|
||||
DigitalBtn Escape;
|
||||
DigitalBtn Backspace;
|
||||
DigitalBtn Up;
|
||||
DigitalBtn Down;
|
||||
DigitalBtn Left;
|
||||
DigitalBtn Right;
|
||||
DigitalBtn Space;
|
||||
};
|
||||
};
|
||||
|
||||
struct MousesState
|
||||
@ -128,11 +135,6 @@ struct XInputPadState
|
||||
DigitalBtn RightShoulder;
|
||||
};
|
||||
};
|
||||
|
||||
b32 using_analog()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
struct DualsensePadState
|
||||
@ -165,11 +167,6 @@ struct DualsensePadState
|
||||
DigitalBtn R1;
|
||||
};
|
||||
};
|
||||
|
||||
b32 using_analog()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
struct ControllerState
|
||||
@ -185,10 +182,76 @@ struct InputState
|
||||
ControllerState Controllers[4];
|
||||
};
|
||||
|
||||
b32 input_using_analog();
|
||||
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 NumBinds;
|
||||
char _PAD_[4];
|
||||
};
|
||||
|
||||
void input_mode_pop( InputMode* mode );
|
||||
void input_mode_pop( InputMode* mode );
|
||||
|
||||
// Needs a contextual reference to four things:
|
||||
// Timing, Input, Bitmap Buffer, Sound Buffer
|
||||
void update_and_render( InputState* input, OffscreenBuffer* back_buffer, SoundBuffer* sound_buffer, Memory* memory );
|
||||
|
||||
NS_ENGINE_END
|
||||
|
||||
// TODO(Ed) : Move this to handmade game layer later.
|
||||
|
||||
#define NS_HANDMADE_BEGIN namespace handmade {
|
||||
#define NS_HANDMADE_END }
|
||||
|
||||
NS_HANDMADE_BEGIN
|
||||
|
||||
// We want a 'binding' to have multiple binds to active it (most likely)
|
||||
struct Actionable
|
||||
{
|
||||
char const* Name;
|
||||
engine::InputBindCallback* Binds;
|
||||
s32 NumBinds;
|
||||
char _PAD_[4];
|
||||
};
|
||||
|
||||
struct ActionableMode
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
Platform Layer:
|
||||
|
||||
Controller : Keyboard & Mouse, XPad, DSPad
|
||||
|
||||
---VV---
|
||||
|
||||
Engine Layer:
|
||||
|
||||
InputBinding callbacks (per-game-logic frame basis)
|
||||
Push/Pop input modes (binding sets)
|
||||
|
||||
---VV---
|
||||
|
||||
Game Layer:
|
||||
|
||||
Actionables : Binding Sets where a raw input, or input interpretation leads to an player action.
|
||||
ActionSet : Actionables.Push/Pop -> Input.Push/Pop ?
|
||||
Player : Controller, Actionables, ActionSets
|
||||
*/
|
||||
|
||||
struct Player
|
||||
{
|
||||
// So far just has an assigned controller.
|
||||
engine::ControllerState* Controller;
|
||||
|
||||
// Possilby some other stuff in the future.
|
||||
};
|
||||
|
||||
NS_HANDMADE_END
|
||||
|
||||
|
@ -16,3 +16,4 @@ int gen_main()
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#include <math.h> // TODO : Implement math ourselves
|
||||
#include <stdio.h>
|
||||
#include "engine.cpp"
|
||||
|
||||
|
||||
@ -188,6 +189,60 @@ b32 debug_file_write_content( char* file_path, u32 content_size, void* content_m
|
||||
}
|
||||
#endif
|
||||
|
||||
internal void
|
||||
input_process_digital_btn( engine::DigitalBtn* old_state, engine::DigitalBtn* new_state, u32 raw_btns, u32 btn_flag )
|
||||
{
|
||||
#define had_transition() ( old_state->EndedDown == new_state->EndedDown )
|
||||
new_state->EndedDown = (raw_btns & btn_flag) > 0;
|
||||
new_state->HalfTransitions = had_transition() ? 1 : 0;
|
||||
#undef had_transition
|
||||
}
|
||||
|
||||
internal f32
|
||||
xinput_process_axis_value( s16 value, s16 deadzone_threshold )
|
||||
{
|
||||
f32 result = 0;
|
||||
if ( value < -deadzone_threshold )
|
||||
{
|
||||
result = scast(f32, value + deadzone_threshold) / (32768.0f - scast(f32, deadzone_threshold));
|
||||
}
|
||||
else if ( value > deadzone_threshold )
|
||||
{
|
||||
result = scast(f32, value + deadzone_threshold) / (32767.0f - scast(f32, deadzone_threshold));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal f32
|
||||
input_process_axis_value( f32 value, f32 deadzone_threshold )
|
||||
{
|
||||
f32 result = 0;
|
||||
if ( value < -deadzone_threshold )
|
||||
{
|
||||
result = (value + deadzone_threshold ) / (1.0f - deadzone_threshold );
|
||||
|
||||
if (result < -1.0f)
|
||||
result = -1.0f; // Clamp to ensure it doesn't go below -1
|
||||
}
|
||||
else if ( value > deadzone_threshold )
|
||||
{
|
||||
result = (value - deadzone_threshold ) / (1.0f - deadzone_threshold );
|
||||
|
||||
if (result > 1.0f)
|
||||
result = 1.0f; // Clamp to ensure it doesn't exceed 1
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void
|
||||
input_process_keyboard_key( engine::DigitalBtn* key, b32 is_down )
|
||||
{
|
||||
// This assert fails all the time, have no idea why. I'm just going to use GetAsyncKeyState instead, using the messaging events is horrible.
|
||||
// assert( key->EndedDown != is_down )
|
||||
key->EndedDown = is_down;
|
||||
key->HalfTransitions += is_down;
|
||||
}
|
||||
|
||||
internal void
|
||||
init_sound(HWND window_handle, s32 samples_per_second, s32 buffer_size )
|
||||
{
|
||||
@ -487,19 +542,115 @@ main_window_callback(
|
||||
}
|
||||
|
||||
internal void
|
||||
input_process_digital_btn( engine::DigitalBtn* old_state, engine::DigitalBtn* new_state, u32 raw_btns, u32 btn_flag )
|
||||
process_pending_window_messages( engine::KeyboardState* keyboard )
|
||||
{
|
||||
#define had_transition() ( old_state->State == new_state->State )
|
||||
new_state->State = (raw_btns & btn_flag);
|
||||
new_state->HalfTransitions = had_transition() ? 1 : 0;
|
||||
#undef had_transition
|
||||
}
|
||||
MSG window_msg_info;
|
||||
while ( PeekMessageA( & window_msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) )
|
||||
{
|
||||
if ( window_msg_info.message == WM_QUIT )
|
||||
{
|
||||
OutputDebugStringA("WM_QUIT\n");
|
||||
Running = false;
|
||||
}
|
||||
|
||||
internal void
|
||||
input_process_keyboard_key( engine::DigitalBtn* key, b32 is_down )
|
||||
{
|
||||
key->State = is_down;
|
||||
key->HalfTransitions += is_down;
|
||||
// Keyboard input handling
|
||||
switch (window_msg_info.message)
|
||||
{
|
||||
// I rather do this with GetAsyncKeyState...
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
#if 0
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
#endif
|
||||
{
|
||||
WPARAM vk_code = window_msg_info.wParam;
|
||||
b32 is_down = scast(b32, (window_msg_info.lParam >> 31) == 0 );
|
||||
b32 was_down = scast(b32, (window_msg_info.lParam >> 30) );
|
||||
b32 alt_down = scast(b32, (window_msg_info.lParam & (1 << 29)) );
|
||||
|
||||
switch ( vk_code )
|
||||
{
|
||||
#if 0
|
||||
case 'Q':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Q, is_down );
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->E, is_down );
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->W, is_down );
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->A, is_down );
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->S, is_down );
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->D, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_ESCAPE:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Escape, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_BACK:
|
||||
input_process_keyboard_key( & keyboard->Backspace, is_down );
|
||||
break;
|
||||
case VK_UP:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Up, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_DOWN:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Down, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_LEFT:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Left, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_RIGHT:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Right, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_SPACE:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard->Space, is_down );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case VK_F4:
|
||||
{
|
||||
if ( alt_down )
|
||||
Running = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TranslateMessage( & window_msg_info );
|
||||
DispatchMessageW( & window_msg_info );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_PLATFORM_END
|
||||
@ -561,7 +712,6 @@ WinMain(
|
||||
|
||||
WNDCLASSW window_class {};
|
||||
HWND window_handle = nullptr;
|
||||
MSG window_msg_info;
|
||||
{
|
||||
window_class.style = CS_Horizontal_Redraw | CS_Vertical_Redraw;
|
||||
window_class.lpfnWndProc = main_window_callback;
|
||||
@ -635,17 +785,18 @@ WinMain(
|
||||
|
||||
engine::InputState input {};
|
||||
|
||||
engine::KeyboardState keyboard;
|
||||
input.Controllers[0].Keyboard = & keyboard;
|
||||
engine::KeyboardState keyboard_states[2] {};
|
||||
engine::KeyboardState* old_keyboard = & keyboard_states[0];
|
||||
engine::KeyboardState* new_keyboard = & keyboard_states[1];
|
||||
// Important: Assuming keyboard always connected for now, and assigning to first controller.
|
||||
|
||||
using EngineXInputPadStates = engine::XInputPadState[ Max_Controllers ];
|
||||
EngineXInputPadStates xpad_states[2];
|
||||
EngineXInputPadStates xpad_states[2] {};
|
||||
EngineXInputPadStates* old_xpads = & xpad_states[0];
|
||||
EngineXInputPadStates* new_xpads = & xpad_states[1];
|
||||
|
||||
using EngineDSPadStates = engine::DualsensePadState[Max_Controllers];
|
||||
EngineDSPadStates ds_pad_states[2];
|
||||
EngineDSPadStates ds_pad_states[2] {};
|
||||
EngineDSPadStates* old_ds_pads = & ds_pad_states[0];
|
||||
EngineDSPadStates* new_ds_pads = & ds_pad_states[1];
|
||||
|
||||
@ -684,116 +835,50 @@ WinMain(
|
||||
Running = true;
|
||||
while( Running )
|
||||
{
|
||||
keyboard = {};
|
||||
|
||||
// Window Management
|
||||
// Handeled properly in the input section.
|
||||
#if 0
|
||||
swap( old_keyboard, new_keyboard );
|
||||
*new_keyboard = {};
|
||||
for ( u32 key_index = 0; key_index < array_count( new_keyboard->Keys ); ++ key_index )
|
||||
{
|
||||
while ( PeekMessageW( & window_msg_info, 0, 0, 0, PM_Remove_Messages_From_Queue ) )
|
||||
{
|
||||
if ( window_msg_info.message == WM_QUIT )
|
||||
{
|
||||
OutputDebugStringA("WM_QUIT\n");
|
||||
Running = false;
|
||||
}
|
||||
engine::DigitalBtn* old_key = & old_keyboard->Keys[ key_index ];
|
||||
engine::DigitalBtn* new_key = & new_keyboard->Keys[ key_index ];
|
||||
|
||||
|
||||
// Keyboard input handling
|
||||
switch (window_msg_info.message)
|
||||
{
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
WPARAM vk_code = window_msg_info.wParam;
|
||||
b32 is_down = scast(b32, (window_msg_info.lParam >> 31) == 0 );
|
||||
b32 was_down = scast(b32, (window_msg_info.lParam >> 30) );
|
||||
b32 alt_down = scast(b32, (window_msg_info.lParam & (1 << 29)) );
|
||||
|
||||
switch ( vk_code )
|
||||
{
|
||||
case 'Q':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Q, is_down );
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.E, is_down );
|
||||
}
|
||||
break;
|
||||
case 'W':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.W, is_down );
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.A, is_down );
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.S, is_down );
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.D, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_ESCAPE:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Esc, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_UP:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Up, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_DOWN:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Down, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_LEFT:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Left, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_RIGHT:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Right, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_SPACE:
|
||||
{
|
||||
input_process_keyboard_key( & keyboard.Space, is_down );
|
||||
}
|
||||
break;
|
||||
case VK_F4:
|
||||
{
|
||||
if ( alt_down )
|
||||
Running = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
TranslateMessage( & window_msg_info );
|
||||
DispatchMessageW( & window_msg_info );
|
||||
}
|
||||
}
|
||||
new_key->EndedDown = old_key->EndedDown;
|
||||
}
|
||||
#endif
|
||||
process_pending_window_messages( new_keyboard );
|
||||
|
||||
|
||||
input.Controllers[0].Keyboard = new_keyboard;
|
||||
// printf("Q- Old: %d, New: %d\n", old_keyboard->Q.EndedDown, new_keyboard->Q.EndedDown);
|
||||
printf("Q- HTOld: %d, HTNew: %d\n", old_keyboard->Q.HalfTransitions, new_keyboard->Q.HalfTransitions);
|
||||
|
||||
// Input
|
||||
// TODO(Ed) : Setup user definable deadzones for triggers and sticks.
|
||||
{
|
||||
// Swapping at the beginning of the input frame instead of the end.
|
||||
swap( old_xpads, new_xpads );
|
||||
swap( old_ds_pads, new_ds_pads );
|
||||
swap( old_keyboard, new_keyboard );
|
||||
swap( old_xpads, new_xpads );
|
||||
swap( old_ds_pads, new_ds_pads );
|
||||
|
||||
// Keyboard Polling
|
||||
{
|
||||
constexpr u32 is_down = 0x8000;
|
||||
input_process_digital_btn( & old_keyboard->Q, & new_keyboard->Q, GetAsyncKeyState( 'Q' ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->E, & new_keyboard->E, GetAsyncKeyState( 'E' ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->W, & new_keyboard->W, GetAsyncKeyState( 'W' ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->A, & new_keyboard->A, GetAsyncKeyState( 'A' ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->S, & new_keyboard->S, GetAsyncKeyState( 'S' ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->D, & new_keyboard->D, GetAsyncKeyState( 'D' ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Escape, & new_keyboard->Escape, GetAsyncKeyState( VK_ESCAPE ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Backspace, & new_keyboard->Backspace, GetAsyncKeyState( VK_BACK ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Up, & new_keyboard->Up, GetAsyncKeyState( VK_UP ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Down, & new_keyboard->Down, GetAsyncKeyState( VK_DOWN ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Left, & new_keyboard->Left, GetAsyncKeyState( VK_LEFT ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Right, & new_keyboard->Right, GetAsyncKeyState( VK_RIGHT ), is_down );
|
||||
input_process_digital_btn( & old_keyboard->Space, & new_keyboard->Space, GetAsyncKeyState( VK_SPACE ), is_down );
|
||||
}
|
||||
|
||||
// XInput Polling
|
||||
// TODO(Ed) : Should we poll this more frequently?
|
||||
@ -826,46 +911,16 @@ WinMain(
|
||||
new_xpad->Stick.Left.X.Start = old_xpad->Stick.Left.X.End;
|
||||
new_xpad->Stick.Left.Y.Start = old_xpad->Stick.Left.Y.End;
|
||||
|
||||
// TODO(Ed) : Compress this into a proc
|
||||
f32 X;
|
||||
if ( xpad->sThumbLX < 0 )
|
||||
{
|
||||
X = scast(f32, xpad->sThumbLX) / scast(f32, -S16_MIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
X = scast(f32, xpad->sThumbLX) / scast(f32, S16_MAX);
|
||||
}
|
||||
f32 left_x = xinput_process_axis_value( xpad->sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE );
|
||||
f32 left_y = xinput_process_axis_value( xpad->sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE );
|
||||
|
||||
// TODO(Ed) : Min/Max macros!!!
|
||||
new_xpad->Stick.Left.X.Min = new_xpad->Stick.Left.X.Max = new_xpad->Stick.Left.X.End = X;
|
||||
|
||||
f32 Y;
|
||||
if ( xpad->sThumbLY < 0 )
|
||||
{
|
||||
Y = scast(f32, xpad->sThumbLY) / scast(f32, -S16_MIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
Y = scast(f32, xpad->sThumbLY) / scast(f32, S16_MAX);
|
||||
}
|
||||
|
||||
// TODO(Ed) : Min/Max macros!!!
|
||||
new_xpad->Stick.Left.Y.Min = new_xpad->Stick.Left.Y.Max = new_xpad->Stick.Left.Y.End = Y;
|
||||
|
||||
|
||||
|
||||
// epad->Stick.Left.X.End = xpad->sThumbLX;
|
||||
// epad->Stick.Left.Y.End = xpad->sThumbLY;
|
||||
// epad->Stick.Right.X.End = xpad->sThumbRX;
|
||||
// epad->Stick.Right.X.End = xpad->sThumbRY;
|
||||
|
||||
// TODO(Ed) : Dead zone processing!!!!!!!!!!!!!!!
|
||||
// XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE
|
||||
// XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE
|
||||
|
||||
// S16_MAX
|
||||
// S16_MIN
|
||||
new_xpad->Stick.Left.X.Min = new_xpad->Stick.Left.X.Max = new_xpad->Stick.Left.X.End = left_x;
|
||||
new_xpad->Stick.Left.Y.Min = new_xpad->Stick.Left.Y.Max = new_xpad->Stick.Left.Y.End = left_y;
|
||||
|
||||
// TODO(Ed): Make this actually an average for later
|
||||
new_xpad->Stick.Left.X.Average = left_x;
|
||||
new_xpad->Stick.Left.Y.Average = left_y;
|
||||
|
||||
input.Controllers[ controller_index ].XPad = new_xpad;
|
||||
}
|
||||
@ -888,7 +943,7 @@ WinMain(
|
||||
if ( jsl_device_index > 4 )
|
||||
break;
|
||||
|
||||
JOY_SHOCK_STATE state = JslGetSimpleState( jsl_device_handles[ jsl_device_index ] );
|
||||
JOY_SHOCK_STATE state = JslGetSimpleState( jsl_device_handles[ jsl_device_index ] );
|
||||
engine::DualsensePadState* old_ds_pad = old_ds_pads[ jsl_device_index ];
|
||||
engine::DualsensePadState* new_ds_pad = new_ds_pads[ jsl_device_index ];
|
||||
|
||||
@ -908,10 +963,20 @@ WinMain(
|
||||
input_process_digital_btn( & old_ds_pad->L1, & new_ds_pad->L1, state.buttons, JSMASK_L );
|
||||
input_process_digital_btn( & old_ds_pad->R1, & new_ds_pad->R1, state.buttons, JSMASK_R );
|
||||
|
||||
// epad->Stick.Left.X.End = state.stickLX;
|
||||
// epad->Stick.Left.Y.End = state.stickLY;
|
||||
// epad->Stick.Right.X.End = state.stickRX;
|
||||
// epad->Stick.Right.X.End = state.stickRY;
|
||||
new_ds_pad->Stick.Left.X.Start = old_ds_pad->Stick.Left.X.End;
|
||||
new_ds_pad->Stick.Left.Y.Start = old_ds_pad->Stick.Left.Y.End;
|
||||
|
||||
// Joyshock abstracts the sticks to a float value already for us of -1.f to 1.f.
|
||||
// We'll assume a deadzone of 10% for now.
|
||||
f32 left_x = input_process_axis_value( state.stickLX, 0.1f );
|
||||
f32 left_y = input_process_axis_value( state.stickLY, 0.1f );
|
||||
|
||||
new_ds_pad->Stick.Left.X.Min = new_ds_pad->Stick.Left.X.Max = new_ds_pad->Stick.Left.X.End = left_x;
|
||||
new_ds_pad->Stick.Left.Y.Min = new_ds_pad->Stick.Left.Y.Max = new_ds_pad->Stick.Left.Y.End = left_y;
|
||||
|
||||
// TODO(Ed): Make this actually an average for later
|
||||
new_ds_pad->Stick.Left.X.Average = left_x;
|
||||
new_ds_pad->Stick.Left.Y.Average = left_y;
|
||||
|
||||
input.Controllers[ jsl_device_index ].DSPad = new_ds_pad;
|
||||
}
|
||||
|
@ -52,9 +52,9 @@
|
||||
|
||||
#if Build_Development
|
||||
# define assert( expression ) \
|
||||
if ( !( expression ) ) \
|
||||
{ \
|
||||
*( int* )0 = 0; \
|
||||
if ( !( expression ) ) \
|
||||
{ \
|
||||
__debugbreak(); \
|
||||
}
|
||||
// platform::assertion_failure( __FILE__, __LINE__, #expression );
|
||||
#else
|
||||
@ -67,3 +67,41 @@
|
||||
#define ensure( condition, expression )
|
||||
#define fatal( message )
|
||||
#endif
|
||||
|
||||
// Just experimenting with a way to check for global variables being accessed from the wrong place.
|
||||
// (Could also be done with gencpp technically)
|
||||
#if 0
|
||||
enum class EGlobalVarsAllowFuncs
|
||||
{
|
||||
ProcessPendingWindowMessages,
|
||||
Num,
|
||||
Invalid,
|
||||
};
|
||||
EGlobalVarsAllowFuncs to_type( char const* proc_name )
|
||||
{
|
||||
char const* global_vars_allowed_funcs[] {
|
||||
"process_pending_window_messages"
|
||||
};
|
||||
|
||||
if ( proc_name )
|
||||
{
|
||||
for ( u32 idx = 0; idx < array_count( global_vars_allowed_funcs ); ++idx )
|
||||
{
|
||||
if ( strcmp( proc_name, global_vars_allowed_funcs[idx] ) == 0 )
|
||||
{
|
||||
return scast( EGlobalVarsAllowFuncs, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return EGlobalVarsAllowFuncs::Invalid;
|
||||
}
|
||||
|
||||
#if Build_Development
|
||||
# define checked_global_getter( global_var, procedure ) \
|
||||
( ensure( to_type(procedure) != EGlobalVarsAllowFuncs::Invalid), global_var )
|
||||
#else
|
||||
# define checked_global_getter( global_var, procedure ) global_var
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@
|
||||
#pragma warning( disable: 4189 ) // Support for unused variables
|
||||
#pragma warning( disable: 4514 ) // Support for unused inline functions
|
||||
#pragma warning( disable: 4505 ) // Support for unused static functions
|
||||
#pragma warning( disable: 5045 ) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
|
||||
#pragma warning( disable: 5045 ) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
|
||||
|
||||
#include "grime.h"
|
||||
#include "macros.h"
|
||||
|
Reference in New Issue
Block a user