Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
DanZaidan committed Sep 29, 2019
1 parent 21f6b6e commit 0b1a983
Show file tree
Hide file tree
Showing 22 changed files with 18,698 additions and 0 deletions.
133 changes: 133 additions & 0 deletions code/asset_loader.c
@@ -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);
}
192 changes: 192 additions & 0 deletions code/audio.c
@@ -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);
}

}
}
47 changes: 47 additions & 0 deletions code/build.bat
@@ -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
9 changes: 9 additions & 0 deletions code/collision.c
@@ -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;
}

0 comments on commit 0b1a983

Please sign in to comment.