Day 12 complete

This commit is contained in:
2023-09-16 18:41:07 -04:00
parent 9831c46739
commit ad5288f9e8
7 changed files with 226 additions and 103 deletions

View File

@ -291,7 +291,8 @@ int JslConnectDevices()
cur_dev->product_id == DS4_USB_V2 ||
cur_dev->product_id == DS4_USB_DONGLE ||
cur_dev->product_id == DS4_BT ||
cur_dev->product_id == DS_USB;
cur_dev->product_id == DS_USB ||
cur_dev->product_id == DS_USB_V2;
break;
case BROOK_DS4_VENDOR:
isSupported = cur_dev->product_id == BROOK_DS4_USB;

View File

@ -2,6 +2,49 @@
NS_ENGINE_BEGIN
using GetSoundSampleValueFn = s16( SoundBuffer* sound_buffer );
global s32 SoundWavePeriod = 250;
internal s16
square_wave_sample_value( SoundBuffer* sound_buffer )
{
s16 sample_value = (sound_buffer->RunningSampleIndex / (sound_buffer->WavePeriod /2)) % 2 ?
sound_buffer->ToneVolume : - sound_buffer->ToneVolume;
return sample_value;
}
internal s16
sine_wave_sample_value( SoundBuffer* sound_buffer )
{
local_persist f32 time = 0.f;
f32 sine_value = sinf( time );
s16 sample_value = scast(u16, sine_value * sound_buffer->ToneVolume);
time += TAU * 1.0f / scast(f32, sound_buffer->WavePeriod );
return sample_value;
}
internal void
output_sound( SoundBuffer* sound_buffer, GetSoundSampleValueFn* get_sample_value )
{
s16* sample_out = sound_buffer->Samples;
for ( u32 sample_index = 0; sample_index < sound_buffer->NumSamples; ++ sample_index )
{
s16 sample_value = get_sample_value( sound_buffer );
++ sound_buffer->RunningSampleIndex;
*sample_out = sample_value;
++ sample_out;
*sample_out = sample_value;
++ sample_out;
}
}
internal void
render_weird_graident(OffscreenBuffer* buffer, u32 x_offset, u32 y_offset )
{
@ -50,11 +93,14 @@ render_weird_graident(OffscreenBuffer* buffer, u32 x_offset, u32 y_offset )
}
internal
void update_and_render( OffscreenBuffer* back_buffer
void update_and_render( OffscreenBuffer* back_buffer, SoundBuffer* sound_buffer
// Temp (for feature parity)
, u32 x_offset, u32 y_offset
)
{
// TODO(Ed) : Allow sample offsets here for more robust platform options
output_sound( sound_buffer, square_wave_sample_value );
render_weird_graident( back_buffer, x_offset, y_offset );
}

View File

@ -20,9 +20,20 @@ struct OffscreenBuffer
u32 BytesPerPixel;
};
struct SoundBuffer
{
s16* Samples;
u32 RunningSampleIndex;
s32 SamplesPerSecond;
s32 NumSamples;
s32 ToneVolume;
s32 WaveToneHz;
s32 WavePeriod;
};
// Needs a contextual reference to four things:
// Timing, Input, Bitmap Buffer, Sound Buffer
void update_and_render( OffscreenBuffer* back_buffer
void update_and_render( OffscreenBuffer* back_buffer, SoundBuffer* sound_buffer
// Temp (for feature parity)
, u32 x_offset, u32 y_offset
);

View File

@ -29,11 +29,14 @@
#endif
#include <math.h> // TODO : Implement math ourselves
#include "engine.cpp"
// Platform Layer headers
#include "platform.h"
#include "jsl.h" // Using this to get dualsense controllers
#include "win32.h"
#include <malloc.h>
// Engine layer headers
#include "engine.h"
@ -100,6 +103,8 @@ global s32 DS_SecondaryBuffer_Size;
global s32 DS_SecondaryBuffer_SamplesPerSecond;
global s32 DS_SecondaryBuffer_BytesPerSample;
global s16* SoundBufferSamples;
internal void
init_sound(HWND window_handle, s32 samples_per_second, s32 buffer_size )
{
@ -172,8 +177,7 @@ init_sound(HWND window_handle, s32 samples_per_second, s32 buffer_size )
}
}
struct DS_SoundOutputTest
struct SoundOutput
{
DWORD IsPlaying;
u32 RunningSampleIndex;
@ -183,50 +187,45 @@ struct DS_SoundOutputTest
s32 LatencySampleCount;
};
using DS_FillSoundBuffer_GetSampleValueFn = s16( DS_SoundOutputTest* sound_output );
internal s16
square_wave_sample_value( DS_SoundOutputTest* sound_output )
{
s16 sample_value = (sound_output->RunningSampleIndex / (sound_output->WavePeriod /2)) % 2 ?
sound_output->ToneVolume : - sound_output->ToneVolume;
return sample_value;
}
internal s16
sine_wave_sample_value( DS_SoundOutputTest* sound_output )
{
local_persist f32 time = 0.f;
f32 sine_value = sinf( time );
s16 sample_value = scast(u16, sine_value * sound_output->ToneVolume);
time += TAU * 1.0f / scast(f32, sound_output->WavePeriod );
return sample_value;
}
internal void
ds_fill_soundbuffer_region( LPVOID region, DWORD region_size
, DS_SoundOutputTest* sound_output, DS_FillSoundBuffer_GetSampleValueFn* get_sample_value )
ds_clear_sound_buffer( SoundOutput* sound_output )
{
DWORD region_sample_count = region_size / DS_SecondaryBuffer_BytesPerSample;
s16* sample_out = rcast( s16*, region );
for ( DWORD sample_index = 0; sample_index < region_sample_count; ++ sample_index )
LPVOID region_1;
DWORD region_1_size;
LPVOID region_2;
DWORD region_2_size;
HRESULT ds_lock_result = DS_SecondaryBuffer->Lock( 0, DS_SecondaryBuffer_Size
, & region_1, & region_1_size
, & region_2, & region_2_size
, 0 );
if ( ! SUCCEEDED( ds_lock_result ) )
{
s16 sample_value = get_sample_value( sound_output );
++ sound_output->RunningSampleIndex;
return;
}
*sample_out = sample_value;
u8* sample_out = rcast( u8*, region_1 );
for ( DWORD byte_index = 0; byte_index < region_1_size; ++ byte_index )
{
*sample_out = 0;
++ sample_out;
}
*sample_out = sample_value;
sample_out = rcast( u8*, region_2 );
for ( DWORD byte_index = 0; byte_index < region_2_size; ++ byte_index )
{
*sample_out = 0;
++ sample_out;
}
if ( ! SUCCEEDED( DS_SecondaryBuffer->Unlock( region_1, region_1_size, region_2, region_2_size ) ))
{
return;
}
}
internal void
ds_fill_sound_buffer_test( DS_SoundOutputTest* sound_output, DWORD byte_to_lock, DWORD bytes_to_write, DS_FillSoundBuffer_GetSampleValueFn* get_sample_value )
ds_fill_sound_buffer( SoundOutput* sound_output, DWORD byte_to_lock, DWORD bytes_to_write, engine::SoundBuffer* sound_buffer )
{
LPVOID region_1;
DWORD region_1_size;
@ -244,8 +243,36 @@ ds_fill_sound_buffer_test( DS_SoundOutputTest* sound_output, DWORD byte_to_lock,
// TODO : Assert that region sizes are valid
ds_fill_soundbuffer_region( region_1, region_1_size, sound_output, get_sample_value );
ds_fill_soundbuffer_region( region_2, region_2_size, sound_output, get_sample_value );
DWORD region_1_sample_count = region_1_size / DS_SecondaryBuffer_BytesPerSample;
s16* sample_out = rcast( s16*, region_1 );
s16* sample_in = sound_buffer->Samples;
for ( DWORD sample_index = 0; sample_index < region_1_sample_count; ++ sample_index )
{
*sample_out = *sample_in;
++ sample_out;
++ sample_in;
*sample_out = *sample_in;
++ sample_out;
++ sample_in;
++ sound_output->RunningSampleIndex;
}
DWORD region_2_sample_count = region_2_size / DS_SecondaryBuffer_BytesPerSample;
sample_out = rcast( s16*, region_2 );
for ( DWORD sample_index = 0; sample_index < region_2_sample_count; ++ sample_index )
{
*sample_out = *sample_in;
++ sample_out;
++ sample_in;
*sample_out = *sample_in;
++ sample_out;
++ sample_in;
++ sound_output->RunningSampleIndex;
}
if ( ! SUCCEEDED( DS_SecondaryBuffer->Unlock( region_1, region_1_size, region_2, region_2_size ) ))
{
@ -264,7 +291,6 @@ get_window_dimensions( HWND window_handle )
return result;
}
internal void
resize_dib_section( OffscreenBuffer* buffer, u32 width, u32 height )
{
@ -465,6 +491,7 @@ main_window_callback(
return result;
}
NS_WIN32_END
int CALLBACK
@ -542,7 +569,7 @@ WinMain(
WinDimensions dimensions = get_window_dimensions( window_handle );
resize_dib_section( &BackBuffer, 1280, 720 );
DS_SoundOutputTest sound_output;
SoundOutput sound_output;
sound_output.IsPlaying = 0;
DS_SecondaryBuffer_SamplesPerSecond = 48000;
DS_SecondaryBuffer_BytesPerSample = sizeof(s16) * 2;
@ -550,6 +577,9 @@ WinMain(
DS_SecondaryBuffer_Size = DS_SecondaryBuffer_SamplesPerSecond * DS_SecondaryBuffer_BytesPerSample;
init_sound( window_handle, DS_SecondaryBuffer_SamplesPerSecond, DS_SecondaryBuffer_Size );
SoundBufferSamples = rcast( s16*, VirtualAlloc( 0, 48000 * 2 * sizeof(s16)
, MEM_Commit_Zeroed | MEM_Reserve, Page_Read_Write ));
// Wave Sound Test
bool wave_switch = false;
sound_output.RunningSampleIndex = 0;
@ -557,7 +587,7 @@ WinMain(
sound_output.WavePeriod = DS_SecondaryBuffer_SamplesPerSecond / sound_output.WaveToneHz;
sound_output.ToneVolume = 3000;
sound_output.LatencySampleCount = DS_SecondaryBuffer_SamplesPerSecond / 15;
ds_fill_sound_buffer_test( & sound_output, 0, sound_output.LatencySampleCount * DS_SecondaryBuffer_BytesPerSample, & sine_wave_sample_value );
ds_clear_sound_buffer( & sound_output );
DS_SecondaryBuffer->Play( 0, 0, DSBPLAY_LOOPING );
// Graphics & Input Test
@ -712,7 +742,51 @@ WinMain(
}
}
engine::update_and_render( rcast(engine::OffscreenBuffer*, & BackBuffer.Memory), x_offset, y_offset );
// Pain...
b32 sound_is_valid = false;
DWORD ds_play_cursor;
DWORD ds_write_cursor;
DWORD byte_to_lock;
DWORD bytes_to_write;
if ( SUCCEEDED( DS_SecondaryBuffer->GetCurrentPosition( & ds_play_cursor, & ds_write_cursor ) ))
{
DWORD target_cursor = (ds_play_cursor + sound_output.LatencySampleCount * DS_SecondaryBuffer_BytesPerSample) % DS_SecondaryBuffer_Size;
byte_to_lock = (sound_output.RunningSampleIndex * DS_SecondaryBuffer_BytesPerSample) % DS_SecondaryBuffer_Size;
bytes_to_write;
if ( byte_to_lock == target_cursor )
{
// We are in the middle of playing. Wait for the write cursor to catch up.
bytes_to_write = 0;
}
else if ( byte_to_lock > target_cursor)
{
// Infront of play cursor |--play--byte_to_write-->--|
bytes_to_write = DS_SecondaryBuffer_Size - byte_to_lock;
bytes_to_write += target_cursor;
}
else
{
// Behind play cursor |--byte_to_write-->--play--|
bytes_to_write = target_cursor - byte_to_lock;
}
sound_is_valid = true;
}
// s16 samples[ 48000 * 2 ];
engine::SoundBuffer sound_buffer {};
sound_buffer.NumSamples = DS_SecondaryBuffer_SamplesPerSecond / 30;
sound_buffer.RunningSampleIndex = sound_output.RunningSampleIndex;
sound_buffer.SamplesPerSecond = DS_SecondaryBuffer_SamplesPerSecond;
sound_buffer.ToneVolume = sound_output.ToneVolume;
sound_buffer.Samples = SoundBufferSamples;
sound_buffer.WavePeriod = sound_output.WavePeriod;
sound_buffer.WaveToneHz = sound_output.WaveToneHz;
engine::update_and_render( rcast(engine::OffscreenBuffer*, & BackBuffer.Memory), & sound_buffer, x_offset, y_offset );
// Rendering
{
@ -754,50 +828,14 @@ WinMain(
sound_output.IsPlaying = ds_status & DSBSTATUS_PLAYING;
}
DWORD ds_play_cursor;
DWORD ds_write_cursor;
if ( ! SUCCEEDED( DS_SecondaryBuffer->GetCurrentPosition( & ds_play_cursor, & ds_write_cursor ) ))
{
if ( ! sound_is_valid )
break;
}
DWORD target_cursor = (ds_play_cursor + sound_output.LatencySampleCount * DS_SecondaryBuffer_BytesPerSample) % DS_SecondaryBuffer_Size;
ds_fill_sound_buffer( & sound_output, byte_to_lock, bytes_to_write, & sound_buffer );
DWORD byte_to_lock = (sound_output.RunningSampleIndex * DS_SecondaryBuffer_BytesPerSample) % DS_SecondaryBuffer_Size;
DWORD bytes_to_write;
if ( byte_to_lock == target_cursor )
{
// We are in the middle of playing. Wait for the write cursor to catch up.
bytes_to_write = 0;
}
else if ( byte_to_lock > target_cursor)
{
// Infront of play cursor |--play--byte_to_write-->--|
bytes_to_write = DS_SecondaryBuffer_Size - byte_to_lock;
bytes_to_write += target_cursor;
}
else
{
// Behind play cursor |--byte_to_write-->--play--|
bytes_to_write = target_cursor - byte_to_lock;
}
if ( wave_switch )
{
ds_fill_sound_buffer_test( & sound_output, byte_to_lock, bytes_to_write, square_wave_sample_value );
}
else
{
ds_fill_sound_buffer_test( & sound_output, byte_to_lock, bytes_to_write, sine_wave_sample_value );
}
#if 1
if ( sound_output.IsPlaying )
{
break;
}
#endif
DS_SecondaryBuffer->Play( 0, 0, DSBPLAY_LOOPING );
} while(0);
@ -837,4 +875,4 @@ WinMain(
}
// Engine layer translation unit.
#include "engine.cpp"
// #include "engine.cpp"