Add basic sound effects to game

This commit is contained in:
Doyle Thai 2016-11-24 22:54:07 +11:00
parent be1c009dfb
commit ea6ea02404
4 changed files with 150 additions and 38 deletions

View File

@ -6,46 +6,89 @@ void initAssetManager(GameState *state)
AssetManager *assetManager = &state->assetManager;
MemoryArena_ *arena = &state->persistentArena;
i32 audioEntries = 32;
assetManager->audio.size = audioEntries;
assetManager->audio.entries =
memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry));
i32 texAtlasEntries = 8;
assetManager->texAtlas.size = texAtlasEntries;
assetManager->texAtlas.entries =
memory_pushBytes(arena, texAtlasEntries * sizeof(HashTableEntry));
i32 texEntries = 32;
assetManager->textures.size = texEntries;
assetManager->textures.entries =
memory_pushBytes(arena, texEntries * sizeof(HashTableEntry));
i32 animEntries = 1024;
assetManager->anims.size = animEntries;
assetManager->anims.entries =
memory_pushBytes(arena, animEntries * sizeof(HashTableEntry));
/* Create empty 1x1 4bpp black texture */
u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0);
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
{ // Init texture assets
i32 texEntries = 32;
assetManager->textures.size = texEntries;
assetManager->textures.entries =
memory_pushBytes(arena, texEntries * sizeof(HashTableEntry));
/* Load shaders */
asset_loadShaderFiles(
assetManager, arena, "data/shaders/default_tex.vert.glsl",
"data/shaders/default_tex.frag.glsl", shaderlist_default);
/* Create empty 1x1 4bpp black texture */
u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0);
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
asset_loadShaderFiles(
assetManager, arena, "data/shaders/default_no_tex.vert.glsl",
"data/shaders/default_no_tex.frag.glsl", shaderlist_default_no_tex);
i32 result = asset_loadTTFont(assetManager, arena,
"C:/Windows/Fonts/Arialbd.ttf");
}
i32 result =
asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf");
if (result) ASSERT(TRUE);
{ // Init shaders assets
asset_loadShaderFiles(
assetManager, arena, "data/shaders/default_tex.vert.glsl",
"data/shaders/default_tex.frag.glsl", shaderlist_default);
asset_loadShaderFiles(
assetManager, arena, "data/shaders/default_no_tex.vert.glsl",
"data/shaders/default_no_tex.frag.glsl", shaderlist_default_no_tex);
}
{ // Init audio assets
i32 audioEntries = 32;
assetManager->audio.size = audioEntries;
assetManager->audio.entries =
memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry));
i32 result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/bang_large.ogg",
"bang_large");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/bang_medium.ogg",
"bang_medium");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/bang_small.ogg",
"bang_small");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/beat1.ogg", "beat1");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/beat2.ogg", "beat2");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/extra_ship.ogg",
"extra_ship");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/fire.ogg", "fire");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/saucer_big.ogg",
"saucer_big");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/saucer_small.ogg",
"saucer_small");
ASSERT(!result);
result = asset_loadVorbis(assetManager, arena,
"data/audio/Asteroids/thrust.ogg", "thrust");
ASSERT(!result);
}
}
void initRenderer(GameState *state, v2 windowSize) {
void initRenderer(GameState *state, v2 windowSize)
{
AssetManager *assetManager = &state->assetManager;
Renderer *renderer = &state->renderer;
renderer->size = windowSize;
@ -446,6 +489,20 @@ INTERNAL void setCollisionRule(World *world, enum EntityType a,
world->collisionTable[b][a] = rule;
}
INTERNAL AudioRenderer *getFreeAudioRenderer(World *world)
{
for (i32 i = 0; i < world->numAudioRenderers; i++)
{
AudioRenderer *renderer = &world->audioRenderer[i];
if (renderer->state == audiostate_stopped)
{
return renderer;
}
}
return NULL;
}
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
v2 windowSize, f32 dt)
{
@ -460,6 +517,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
srand((u32)time(NULL));
initAssetManager(state);
initRenderer(state, windowSize);
audio_init(&state->audioManager);
world->pixelsPerMeter = 70.0f;
@ -473,10 +531,17 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
Entity *nullEntity = &world->entityList[world->entityIndex++];
nullEntity->id = world->entityIdCounter++;
}
{ // Init asteroid entities
world->numAsteroids = 15;
}
{ // Init audio renderer
world->numAudioRenderers = 6;
world->audioRenderer = MEMORY_PUSH_ARRAY(
&world->entityArena, world->numAudioRenderers, AudioRenderer);
}
{ // Init ship entity
Entity *ship = &world->entityList[world->entityIndex++];
ship->id = world->entityIdCounter++;
@ -595,6 +660,18 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
readkeytype_delayedRepeat, 0.05f, dt))
{
addBullet(world, entity);
AudioRenderer *audioRenderer = getFreeAudioRenderer(world);
if (audioRenderer)
{
AudioVorbis *fire =
asset_getVorbis(&state->assetManager, "fire");
// TODO(doyle): Atm transient arena is not used, this is
// just to fill out the arguments
audio_playVorbis(&state->transientArena,
&state->audioManager, audioRenderer, fire,
1);
}
}
if (ddP.x > 0.0f && ddP.y > 0.0f)
@ -704,7 +781,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
continue;
}
ddPSpeedInMs = 25;
ddPSpeedInMs = 10;
Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f));
ddP = V2(math_cosf(rotation), math_sinf(rotation));
entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs);
@ -749,16 +826,39 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
if (colliderA->type == entitytype_asteroid)
{
ASSERT(colliderB->type == entitytype_bullet);
world->entityList[collisionIndex] =
world->entityList[--world->entityIndex];
world->entityList[i--] =
world->entityList[--world->entityIndex];
world->asteroidCounter--;
ASSERT(world->asteroidCounter >= 0);
AudioRenderer *audioRenderer = getFreeAudioRenderer(world);
if (audioRenderer)
{
char *sound;
i32 choice = rand() % 3;
if (choice == 0)
{
sound = "bang_small";
}
else if (choice == 1)
{
sound = "bang_medium";
}
else
{
sound = "bang_large";
}
AudioVorbis *explode =
asset_getVorbis(&state->assetManager, sound);
audio_playVorbis(&state->transientArena,
&state->audioManager, audioRenderer,
explode, 1);
}
continue;
}
}
@ -769,6 +869,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
collideColor, flags);
}
for (i32 i = 0; i < world->numAudioRenderers; i++)
{
AudioRenderer *audioRenderer = &world->audioRenderer[i];
audio_updateAndPlay(&state->transientArena, &state->audioManager,
audioRenderer);
}
#if 1
debug_drawUi(state, dt);
debug_clearCounter();

View File

@ -299,6 +299,9 @@ const i32 audio_streamPlayVorbis(MemoryArena_ *arena, AudioManager *audioManager
AudioVorbis *vorbis, i32 numPlays)
{
// TODO(doyle): Streaming leaks memory, we don't free the "copy audio"
ASSERT(INVALID_CODE_PATH);
i32 result = initRendererForPlayback(arena, audioManager, audioRenderer,
vorbis, numPlays);
// NOTE(doyle): We make a copy of the audio vorbis file using all the same

View File

@ -2,6 +2,7 @@
#define ASTEROID_H
#include "Dengine/AssetManager.h"
#include "Dengine/Audio.h"
#include "Dengine/Common.h"
#include "Dengine/Entity.h"
#include "Dengine/MemoryArena.h"
@ -23,6 +24,10 @@ typedef struct World
v2 *asteroidVertexCache[10];
v2 *bulletVertexCache;
// TODO(doyle): Audio mixing instead of multiple renderers
AudioRenderer *audioRenderer;
i32 numAudioRenderers;
f32 pixelsPerMeter;
v2 worldSize;
Rect camera;
@ -34,14 +39,15 @@ typedef struct World
typedef struct GameState {
b32 init;
World world;
AssetManager assetManager;
KeyInput input;
MemoryArena_ transientArena;
MemoryArena_ persistentArena;
AudioManager audioManager;
AssetManager assetManager;
KeyInput input;
Renderer renderer;
World world;
} GameState;
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,

View File

@ -77,10 +77,6 @@ typedef struct Entity
EntityAnim animList[16];
i32 animListIndex;
// TODO(doyle): Audio mixing instead of multiple renderers
AudioRenderer *audioRenderer;
i32 numAudioRenderers;
} Entity;
SubTexture entity_getActiveSubTexture(Entity *const entity);