Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
18,698 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
char* pak_file; | ||
|
||
inline char* | ||
load_pak_file() { | ||
pak_file = os_get_pak_data().data; | ||
|
||
assert(*pak_file == 'G'); | ||
assert(*(pak_file+1) == 'A'); | ||
assert(*(s16*)(pak_file+2) == 1); // Version Number | ||
assert(*(u32*)(pak_file+4) == ASSET_COUNT); | ||
|
||
return pak_file; | ||
} | ||
|
||
|
||
internal String | ||
load_asset(int asset, u8 *asset_format) { | ||
String result; | ||
|
||
u32 file_location = *(u32*)(pak_file + HEADER_SIZE + asset*sizeof(u32)); | ||
u32 file_end_location = *(u32*)(pak_file + HEADER_SIZE + (asset+1)*sizeof(u32)); | ||
|
||
if (asset_format) *asset_format = *((u8*)pak_file + file_location); | ||
file_location++; | ||
|
||
result.data = pak_file + file_location; | ||
result.size = file_end_location - file_location; | ||
|
||
return result; | ||
} | ||
|
||
|
||
////////// | ||
// Sounds | ||
|
||
|
||
OS_JOB_CALLBACK(async_load_ogg_callback) { | ||
*(Loaded_Sound*)data3 = load_ogg_from_memory((String){data1, (s64)data2}); | ||
} | ||
|
||
inline void | ||
async_load_ogg_from_memory(String s, Loaded_Sound *loaded_sound) { | ||
os_add_job_to_queue(general_queue, async_load_ogg_callback, s.data, (void*)s.size, loaded_sound); | ||
} | ||
|
||
|
||
Loaded_Sound sounds[LAST_SOUND-FIRST_SOUND+1]; | ||
|
||
|
||
internal void | ||
load_sound_from_pak(int asset, Loaded_Sound *result) { | ||
|
||
u8 asset_format; | ||
String sound = load_asset(asset, &asset_format); | ||
|
||
if (asset_format == ASSET_FORMAT_WAV) { | ||
*result = load_wav_from_memory(sound); | ||
} else if (asset_format == ASSET_FORMAT_OGG) { | ||
async_load_ogg_from_memory(sound, result); | ||
} else { | ||
invalid_code_path; | ||
} | ||
} | ||
|
||
|
||
///////// | ||
// Bitmap | ||
|
||
struct { | ||
u32 *pixels; | ||
int width, height; | ||
} typedef Bitmap; | ||
|
||
Bitmap bitmaps[LAST_BITMAP+1]; | ||
|
||
internal Bitmap | ||
load_png(char *path) { | ||
Bitmap result; | ||
|
||
String image = os_read_entire_file(path); | ||
int n; | ||
stbi_set_flip_vertically_on_load(1); | ||
result.pixels = (u32*)stbi_load_from_memory((void*)image.data, (int)image.size, &result.width, &result.height, &n, 4); | ||
u32 *pixel = result.pixels; | ||
for (int y = 0; y < result.height; y++) { | ||
for (int x = 0; x < result.width; x++) { | ||
u8 r = (u8)(*pixel & 0x0000ff); | ||
u8 g = (u8)((*pixel & 0x00ff00) >> 8); | ||
u8 b = (u8)((*pixel & 0xff0000) >> 16); | ||
u8 a = (u8)((*pixel & 0xff000000) >> 24); | ||
*pixel++ = b | (g << 8) | (r << 16) | (a << 24); | ||
} | ||
} | ||
|
||
os_free_file(image); | ||
return result; | ||
} | ||
|
||
|
||
internal Bitmap | ||
load_png_from_pak(int asset) { | ||
Bitmap result; | ||
|
||
u8 format; | ||
String image = load_asset(asset, &format); | ||
assert(format == ASSET_FORMAT_PNG); | ||
|
||
int n; | ||
stbi_set_flip_vertically_on_load(1); | ||
result.pixels = (u32*)stbi_load_from_memory((void*)image.data, (int)image.size, &result.width, &result.height, &n, 4); | ||
u32 *pixel = result.pixels; | ||
for (int y = 0; y < result.height; y++) { | ||
for (int x = 0; x < result.width; x++) { | ||
u8 r = (u8)(*pixel & 0x0000ff); | ||
u8 g = (u8)((*pixel & 0x00ff00) >> 8); | ||
u8 b = (u8)((*pixel & 0xff0000) >> 16); | ||
u8 a = (u8)((*pixel & 0xff000000) >> 24); | ||
*pixel++ = b | (g << 8) | (r << 16) | (a << 24); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
inline Bitmap* | ||
get_bitmap(int asset) { | ||
return bitmaps + asset; | ||
} | ||
|
||
inline Loaded_Sound* | ||
get_sound(int asset) { | ||
return sounds + (asset - FIRST_SOUND); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
|
||
// @Hack | ||
f32 *player_visual_p_x_ptr; | ||
|
||
enum { | ||
SOUND_NORMAL, | ||
SOUND_ZEROING, | ||
SOUND_READING, | ||
} typedef Sound_Reading_Access; | ||
|
||
struct Playing_Sound { | ||
// Every member but acces must be manually zeroed in play_sound | ||
b32 active; | ||
volatile Sound_Reading_Access access; | ||
|
||
Loaded_Sound *sound; | ||
f32 position; //Sample position | ||
|
||
b32 looping; | ||
f32 volume; | ||
f32 target_volume; | ||
f32 fading_speed; | ||
f32 pan; | ||
f32 speed_multiplier; | ||
|
||
f32 *source_x; | ||
|
||
struct Playing_Sound *synced_sound; | ||
struct Playing_Sound *next_free; | ||
} typedef Playing_Sound; | ||
|
||
Playing_Sound playing_sounds[48]; | ||
int next_playing_sound; | ||
Playing_Sound *first_free_sound; | ||
int immutable_sound_count; | ||
|
||
internal void | ||
set_volume(Playing_Sound *sound, f32 volume) { | ||
volume = max(0.f, volume); | ||
sound->target_volume = volume; | ||
sound->volume = volume; | ||
} | ||
|
||
|
||
internal Playing_Sound* | ||
play_sound(Loaded_Sound *sound, b32 looping) { | ||
Playing_Sound *result = first_free_sound; | ||
|
||
if (result) { | ||
first_free_sound = result->next_free; | ||
} else { | ||
assert(next_playing_sound >= 0 && next_playing_sound < array_count(playing_sounds)); | ||
result = playing_sounds + next_playing_sound++; | ||
|
||
if (next_playing_sound >= array_count(playing_sounds)) { | ||
next_playing_sound = immutable_sound_count; | ||
} | ||
assert(next_playing_sound >= 0 && next_playing_sound < array_count(playing_sounds)); | ||
} | ||
|
||
for (;;) { | ||
volatile Sound_Reading_Access interlocked = interlocked_compare_exchange(&result->access, SOUND_ZEROING, SOUND_NORMAL); | ||
if (interlocked == SOUND_NORMAL) break; | ||
} | ||
assert(result->access == SOUND_ZEROING); | ||
|
||
result->active = true; | ||
result->sound = sound; | ||
result->position = 0; | ||
result->looping = looping; | ||
result->volume = 1; | ||
result->target_volume = 1; | ||
result->fading_speed = 3.f; | ||
result->pan = 0; | ||
result->speed_multiplier = 1.f; | ||
result->source_x = 0; | ||
result->synced_sound = 0; | ||
result->next_free = 0; | ||
|
||
{ | ||
assert(result->access == SOUND_ZEROING); | ||
volatile Sound_Reading_Access interlocked = interlocked_compare_exchange(&result->access, SOUND_NORMAL, SOUND_ZEROING); | ||
} | ||
|
||
|
||
return result; | ||
} | ||
|
||
internal Playing_Sound* | ||
play_sound_with_variation(Loaded_Sound *sound, f32 variation, f32 *source) { | ||
Playing_Sound *result = play_sound(sound, false); | ||
set_volume(result, random_f32_in_range(1.f-variation, 1.f+variation)); | ||
result->speed_multiplier = random_f32_in_range(1.f-variation, 1.f+variation); | ||
result->source_x = source; | ||
return result; | ||
} | ||
|
||
internal void | ||
stop_sound(Playing_Sound *sound) { | ||
sound->active = false; | ||
sound->next_free = first_free_sound; | ||
first_free_sound = sound; | ||
} | ||
|
||
internal void | ||
update_game_audio(Game_Sound_Buffer *sound_buffer, f32 dt) { | ||
f32 min = (f32)MIN_S16; | ||
f32 max = (f32)MAX_S16; | ||
|
||
for (Playing_Sound *sound = playing_sounds; sound != playing_sounds + array_count(playing_sounds); sound++) { | ||
|
||
for (;;) { | ||
volatile Sound_Reading_Access interlocked = interlocked_compare_exchange(&sound->access, SOUND_READING, SOUND_NORMAL); | ||
if (interlocked == SOUND_NORMAL) break; | ||
} | ||
assert(sound->access == SOUND_READING); | ||
|
||
if (sound->active && sound->sound && sound->sound->samples) { | ||
|
||
assert(sound->sound); | ||
if (sound->synced_sound) { | ||
sound->position = sound->synced_sound->position; | ||
sound->speed_multiplier = sound->synced_sound->speed_multiplier; | ||
assert((s64)sound < (s64)sound->synced_sound); | ||
} | ||
|
||
s16 *at = sound_buffer->samples; | ||
for (int i = 0; i < sound_buffer->samples_to_write; i++) { | ||
assert(sound->sound); | ||
sound->volume = move_towards(sound->volume, sound->target_volume, sound->fading_speed/sound_buffer->samples_per_second); | ||
|
||
if (sound->volume) { | ||
assert(sound->sound); | ||
if (sound->source_x) sound->pan = move_towards(sound->pan, (*sound->source_x - *player_visual_p_x_ptr) * .005f, 10.f/sound_buffer->samples_per_second); | ||
|
||
// I clamp that to "sound->sound->sample_count - sound->sound->channel_count-1" because get more samples based on the sample count | ||
int sample = clamp(0, (int)sound->position, sound->sound->sample_count - sound->sound->channel_count-1); | ||
|
||
assert(sound->sound); | ||
f32 frac = sound->position - (f32)sample; | ||
sample *= sound->sound->channel_count; | ||
assert(sound->sound); | ||
int next_sample = sample + sound->sound->channel_count-1 + 1; | ||
if (next_sample >= sound->sound->sample_count*sound->sound->channel_count) { | ||
if (sound->looping) next_sample -= sound->sound->sample_count*sound->sound->channel_count; | ||
else next_sample = sample; | ||
} | ||
assert(sound->sound); | ||
|
||
f32 left_sound_sample_1 = (f32)sound->sound->samples[sample]; | ||
f32 left_sound_sample_2 = (f32)sound->sound->samples[next_sample]; | ||
|
||
f32 right_sound_sample_1 = (f32)sound->sound->samples[sample + sound->sound->channel_count-1]; | ||
f32 right_sound_sample_2 = (f32)sound->sound->samples[next_sample + sound->sound->channel_count-1]; | ||
|
||
f32 left_sound_sample = lerp(left_sound_sample_1, frac, left_sound_sample_2)*sound->volume; | ||
f32 right_sound_sample = lerp(right_sound_sample_1, frac, right_sound_sample_2)*sound->volume; | ||
|
||
f32 left_sample = (left_sound_sample*clampf(0, (1.f-sound->pan), 1.f) + | ||
right_sound_sample*clampf(0, (-sound->pan), 1.f)); | ||
f32 right_sample = (right_sound_sample*clampf(0, (1.f+sound->pan), 1.f) + | ||
left_sound_sample*clampf(0, (sound->pan), 1.f)); | ||
|
||
assert(at); | ||
*at = (s16)clampf(min, left_sample*.5f + *at, max); | ||
assert(at); | ||
at++; | ||
assert(at); | ||
*at = (s16)clampf(min, right_sample*.5f + *at, max); | ||
assert(at); | ||
at++; | ||
assert(at); | ||
|
||
} | ||
|
||
sound->position += sound->speed_multiplier; | ||
if (sound->position >= sound->sound->sample_count) { | ||
if (sound->looping) sound->position -= sound->sound->sample_count; | ||
else stop_sound(sound); | ||
} | ||
|
||
} | ||
} | ||
|
||
|
||
{ | ||
assert(sound->access == SOUND_READING); | ||
volatile Sound_Reading_Access interlocked = interlocked_compare_exchange(&sound->access, SOUND_NORMAL, SOUND_READING); | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
@echo off | ||
if not exist ..\build mkdir ..\build | ||
pushd ..\build | ||
del *.pdb > NUL 2> NUL | ||
echo WAITING FOR PDB > lock.tmp | ||
|
||
set warnings_to_ignore=-wd4201 -wd4204 -wd4255 -wd4668 -wd4820 -wd4100 -wd4189 -wd4711 -wd4710 -wd4101 -wd4296 -wd4311 -wd4115 -wd4702 -wd4456 -wd4555 | ||
|
||
REM Asset Cooker Build | ||
REM cl -nologo -O2 -Zi -FC -WX -Wall %warnings_to_ignore% ..\code\cooker.c /link user32.lib gdi32.lib -incremental:no -opt:ref | ||
|
||
REM Game Build | ||
cl -nologo -O2 -FC -WX -Wall -DDEVELOPMENT=0 -DPROFILER=0 %warnings_to_ignore% ..\code\win32_platform.c /link user32.lib gdi32.lib winmm.lib -incremental:no -opt:ref | ||
|
||
|
||
del lock.tmp | ||
del *.obj | ||
|
||
popd | ||
|
||
|
||
REM Compiler Flags: | ||
|
||
REM Zi : debug info (Z7 older debug format for complex builds) | ||
REM Zo : More debug info for optimized builds | ||
REM FC : Full path on errors | ||
REM Oi : Always do intrinsics with you can | ||
REM Od : No optimizations | ||
REM O2 : Full optimizations | ||
REM MT : Use the c static lib instead of searching for dll at run-time | ||
REM MTd : Sabe as MT but using the debug version of CRT | ||
REM GR- : Turn off C++ run-time type info | ||
REM Gm- : Turn off incremental build | ||
REM EHa-: Turn off exception handling | ||
REM WX : Treat warning as errors | ||
REM W4 : Set Warning level to 4 (Wall to all levels) | ||
REM wd : Ignore warning | ||
REM fp:fast : Ignores the rules in some cases to optimize fp operations | ||
REM Fmfile.map : Outputs a map file (mapping of the functions on the exr) | ||
|
||
REM Linker Options: | ||
|
||
REM subsystem:windows,5.1 : Make exe compatible with Windows XP (only works on x86) | ||
REM opt:ref : Don't put unused things in the exe | ||
REM incremental:no : Don't need to do incremental builds | ||
REM LD : Build a dll | ||
REM PDB:file.pdb : Change the .pdb's path |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
// Overlapping | ||
inline b32 | ||
aabb_vs_aabb(v2 p1, v2 half_size1, v2 p2, v2 half_size2) { | ||
return p1.y + half_size1.y > p2.y - half_size2.y && | ||
p1.y - half_size1.y < p2.y + half_size2.y && | ||
p1.x + half_size1.x > p2.x - half_size2.x && | ||
p1.x - half_size1.x < p2.x + half_size2.x; | ||
} |
Oops, something went wrong.