Switch audio to hash table implementation

This commit is contained in:
Doyle Thai 2016-08-31 19:59:56 +10:00
parent f6943e5efb
commit 5cccd3ebe8
5 changed files with 112 additions and 97 deletions

View File

@ -231,8 +231,9 @@ Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena,
* Animation Asset Managing * Animation Asset Managing
********************************* *********************************
*/ */
INTERNAL Animation *getFreeAnimationSlot(AssetManager *assetManager, INTERNAL Animation *getFreeAnimationSlot(AssetManager *const assetManager,
MemoryArena *arena, char *key) MemoryArena *const arena,
const char *const key)
{ {
HashTableEntry *entry = getFreeHashSlot(&assetManager->anims, arena, key); HashTableEntry *entry = getFreeHashSlot(&assetManager->anims, arena, key);
@ -248,9 +249,11 @@ INTERNAL Animation *getFreeAnimationSlot(AssetManager *assetManager,
} }
} }
void asset_addAnimation(AssetManager *assetManager, MemoryArena *arena, void asset_addAnimation(AssetManager *const assetManager,
char *animName, TexAtlas *atlas, char **subTextureNames, MemoryArena *const arena, const char *const animName,
i32 numSubTextures, f32 frameDuration) TexAtlas *const atlas,
char **const subTextureNames,
const i32 numSubTextures, const f32 frameDuration)
{ {
Animation *anim = getFreeAnimationSlot(assetManager, arena, animName); Animation *anim = getFreeAnimationSlot(assetManager, arena, animName);
@ -307,8 +310,10 @@ typedef struct XmlToken
i32 len; i32 len;
} XmlToken; } XmlToken;
INTERNAL XmlToken *tokeniseXmlBuffer(MemoryArena *arena, char *buffer, INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena *const arena,
i32 bufferSize, int *numTokens) const char *const buffer,
const i32 bufferSize,
int *const numTokens)
{ {
XmlToken *xmlTokens = PLATFORM_MEM_ALLOC(arena, 8192, XmlToken); XmlToken *xmlTokens = PLATFORM_MEM_ALLOC(arena, 8192, XmlToken);
i32 tokenIndex = 0; i32 tokenIndex = 0;
@ -412,8 +417,9 @@ INTERNAL XmlToken *tokeniseXmlBuffer(MemoryArena *arena, char *buffer,
return xmlTokens; return xmlTokens;
} }
INTERNAL XmlNode *buildXmlTree(MemoryArena *arena, XmlToken *xmlTokens, INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
i32 numTokens) XmlToken *const xmlTokens,
const i32 numTokens)
{ {
XmlNode *root = PLATFORM_MEM_ALLOC(arena, 1, XmlNode); XmlNode *root = PLATFORM_MEM_ALLOC(arena, 1, XmlNode);
if (!root) return NULL; if (!root) return NULL;
@ -732,7 +738,8 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena,
} }
} }
INTERNAL void recursiveFreeXmlTree(MemoryArena *arena, XmlNode *node) INTERNAL void recursiveFreeXmlTree(MemoryArena *const arena,
XmlNode *node)
{ {
if (!node) if (!node)
{ {
@ -759,11 +766,12 @@ INTERNAL void recursiveFreeXmlTree(MemoryArena *arena, XmlNode *node)
node->name = NULL; node->name = NULL;
node->isClosed = FALSE; node->isClosed = FALSE;
PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode)); PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode));
node = NULL;
} }
} }
INTERNAL void freeXmlData(MemoryArena *arena, XmlToken *tokens, i32 numTokens, INTERNAL void freeXmlData(MemoryArena *const arena, XmlToken *tokens,
XmlNode *tree) const i32 numTokens, XmlNode *tree)
{ {
if (tree) recursiveFreeXmlTree(arena, tree); if (tree) recursiveFreeXmlTree(arena, tree);
if (tokens) PLATFORM_MEM_FREE(arena, tokens, numTokens * sizeof(XmlToken)); if (tokens) PLATFORM_MEM_FREE(arena, tokens, numTokens * sizeof(XmlToken));
@ -774,8 +782,9 @@ INTERNAL void freeXmlData(MemoryArena *arena, XmlToken *tokens, i32 numTokens,
* Everything else * Everything else
********************************* *********************************
*/ */
i32 asset_loadXmlFile(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadXmlFile(AssetManager *const assetManager,
PlatformFileRead *fileRead) MemoryArena *const arena,
const PlatformFileRead *const fileRead)
{ {
i32 result = 0; i32 result = 0;
/* Tokenise buffer */ /* Tokenise buffer */
@ -802,49 +811,49 @@ i32 asset_loadXmlFile(AssetManager *assetManager, MemoryArena *arena,
return result; return result;
} }
// TODO(doyle): Switch to hash based lookup AudioVorbis *const asset_getVorbis(AssetManager *const assetManager,
// TODO(doyle): Use pointers, so we can forward declare all assets? const char *const key)
AudioVorbis *asset_getVorbis(AssetManager *assetManager,
const enum AudioList type)
{ {
if (type < audiolist_count)
return &assetManager->audio[type];
#ifdef DENGINE_DEBUG HashTableEntry *entry = getEntryFromHash(&assetManager->audio, key);
ASSERT(INVALID_CODE_PATH);
#endif
return NULL; AudioVorbis *result = NULL;
if (entry) result = CAST(AudioVorbis *)entry->data;
return result;
} }
const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
const char *const path, const enum AudioList type) const char *const path, const char *const key)
{ {
HashTableEntry *entry = getFreeHashSlot(&assetManager->audio, arena, key);
if (!entry) return -1;
// TODO(doyle): Remember to free vorbis file if we remove from memory // TODO(doyle): Remember to free vorbis file if we remove from memory
PlatformFileRead fileRead = {0}; PlatformFileRead fileRead = {0};
platform_readFileToBuffer(arena, path, &fileRead); platform_readFileToBuffer(arena, path, &fileRead);
entry->data = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis);
i32 error; i32 error;
AudioVorbis audio = {0}; AudioVorbis *audio = CAST(AudioVorbis *) entry->data;
audio.type = type; audio->file =
audio.file =
stb_vorbis_open_memory(fileRead.buffer, fileRead.size, &error, NULL); stb_vorbis_open_memory(fileRead.buffer, fileRead.size, &error, NULL);
if (!audio.file) if (!audio->file)
{ {
printf("stb_vorbis_open_memory() failed: Error code %d\n", error); printf("stb_vorbis_open_memory() failed: Error code %d\n", error);
platform_closeFileRead(arena, &fileRead); platform_closeFileRead(arena, &fileRead);
stb_vorbis_close(audio.file); stb_vorbis_close(audio->file);
return 0; return 0;
} }
audio.info = stb_vorbis_get_info(audio.file); audio->name = entry->key;
audio.lengthInSamples = stb_vorbis_stream_length_in_samples(audio.file); audio->info = stb_vorbis_get_info(audio->file);
audio.lengthInSeconds = stb_vorbis_stream_length_in_seconds(audio.file); audio->lengthInSamples = stb_vorbis_stream_length_in_samples(audio->file);
audio.data = CAST(u8 *) fileRead.buffer; audio->lengthInSeconds = stb_vorbis_stream_length_in_seconds(audio->file);
audio.size = fileRead.size; audio->data = CAST(u8 *) fileRead.buffer;
audio->size = fileRead.size;
assetManager->audio[type] = audio;
return 0; return 0;
} }
@ -902,7 +911,8 @@ INTERNAL i32 shaderLoadProgram(Shader *const shader, const GLuint vertexShader,
return 0; return 0;
} }
Shader *asset_getShader(AssetManager *assetManager, const enum ShaderList type) Shader *const asset_getShader(AssetManager *assetManager,
const enum ShaderList type)
{ {
if (type < shaderlist_count) if (type < shaderlist_count)
return &assetManager->shaders[type]; return &assetManager->shaders[type];
@ -1202,7 +1212,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
return 0; return 0;
} }
v2 asset_stringDimInPixels(const Font *const font, const char *const string) const v2 asset_stringDimInPixels(const Font *const font,
const char *const string)
{ {
v2 stringDim = V2(0, 0); v2 stringDim = V2(0, 0);
for (i32 i = 0; i < common_strlen(string); i++) for (i32 i = 0; i < common_strlen(string); i++)

View File

@ -296,13 +296,7 @@ const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager,
// simultaneously, we need unique file pointers into the data to track song // simultaneously, we need unique file pointers into the data to track song
// position uniquely // position uniquely
AudioVorbis *copyAudio = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis); AudioVorbis *copyAudio = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis);
copyAudio->type = vorbis->type; *copyAudio = *vorbis;
copyAudio->info = vorbis->info;
copyAudio->lengthInSamples = vorbis->lengthInSamples;
copyAudio->lengthInSeconds = vorbis->lengthInSeconds;
copyAudio->data = vorbis->data;
copyAudio->size = vorbis->size;
i32 error; i32 error;
copyAudio->file = copyAudio->file =

View File

@ -116,6 +116,11 @@ INTERNAL void assetInit(GameState *state)
AssetManager *assetManager = &state->assetManager; AssetManager *assetManager = &state->assetManager;
MemoryArena *arena = &state->arena; MemoryArena *arena = &state->arena;
i32 audioEntries = 32;
assetManager->audio.size = audioEntries;
assetManager->audio.entries =
PLATFORM_MEM_ALLOC(arena, audioEntries, HashTableEntry);
i32 texAtlasEntries = 8; i32 texAtlasEntries = 8;
assetManager->texAtlas.size = texAtlasEntries; assetManager->texAtlas.size = texAtlasEntries;
assetManager->texAtlas.entries = assetManager->texAtlas.entries =
@ -280,11 +285,11 @@ INTERNAL void assetInit(GameState *state)
char *audioPath = char *audioPath =
"data/audio/Motoi Sakuraba - Stab the sword of justice.ogg"; "data/audio/Motoi Sakuraba - Stab the sword of justice.ogg";
asset_loadVorbis(assetManager, arena, audioPath, audiolist_battle); asset_loadVorbis(assetManager, arena, audioPath, "audio_battle");
audioPath = "data/audio/Motoi Sakuraba - Field of Exper.ogg"; audioPath = "data/audio/Motoi Sakuraba - Field of Exper.ogg";
asset_loadVorbis(assetManager, arena, audioPath, audiolist_overworld); asset_loadVorbis(assetManager, arena, audioPath, "audio_overworld");
audioPath = "data/audio/nuindependent_hit22.ogg"; audioPath = "data/audio/nuindependent_hit22.ogg";
asset_loadVorbis(assetManager, arena, audioPath, audiolist_tackle); asset_loadVorbis(assetManager, arena, audioPath, "audio_tackle");
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
DEBUG_LOG("Sound assets initialised"); DEBUG_LOG("Sound assets initialised");
@ -1160,10 +1165,11 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
if (world->numEntitiesInBattle > 0) if (world->numEntitiesInBattle > 0)
{ {
AudioVorbis *battleTheme = AudioVorbis *battleTheme =
asset_getVorbis(assetManager, audiolist_battle); asset_getVorbis(assetManager, "audio_battle");
if (audioRenderer->audio) if (audioRenderer->audio)
{ {
if (audioRenderer->audio->type != audiolist_battle) if (common_strcmp(audioRenderer->audio->key,
"audio_battle") != 0)
{ {
audio_streamPlayVorbis(arena, &state->audioManager, audio_streamPlayVorbis(arena, &state->audioManager,
audioRenderer, battleTheme, audioRenderer, battleTheme,
@ -1180,10 +1186,11 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
else else
{ {
AudioVorbis *overworldTheme = AudioVorbis *overworldTheme =
asset_getVorbis(assetManager, audiolist_overworld); asset_getVorbis(assetManager, "audio_overworld");
if (audioRenderer->audio) if (audioRenderer->audio)
{ {
if (audioRenderer->audio->type != audiolist_overworld) if (common_strcmp(audioRenderer->audio->key,
"audio_overworld") != 0)
{ {
audio_streamPlayVorbis( audio_streamPlayVorbis(
arena, &state->audioManager, audioRenderer, arena, &state->audioManager, audioRenderer,
@ -1484,7 +1491,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
Entity *defender = attackSpec->defender; Entity *defender = attackSpec->defender;
audio_playVorbis(arena, audioManager, attacker->audioRenderer, audio_playVorbis(arena, audioManager, attacker->audioRenderer,
asset_getVorbis(assetManager, audiolist_tackle), asset_getVorbis(assetManager, "audio_tackle"),
1); 1);
/* Get first free string position and store the damage str data */ /* Get first free string position and store the damage str data */

View File

@ -15,10 +15,10 @@ typedef struct AssetManager
HashTable texAtlas; HashTable texAtlas;
HashTable textures; HashTable textures;
HashTable anims; HashTable anims;
HashTable audio;
/* Primitive Array */ /* Primitive Array */
Shader shaders[32]; Shader shaders[2];
AudioVorbis audio[32];
Font font; Font font;
} AssetManager; } AssetManager;
@ -45,26 +45,33 @@ Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena,
* Animation Asset Managing * Animation Asset Managing
********************************* *********************************
*/ */
void asset_addAnimation(AssetManager *assetManager, MemoryArena *arena, void asset_addAnimation(AssetManager *const assetManager,
char *animName, TexAtlas *atlas, char **subTextureNames, MemoryArena *const arena, const char *const animName,
i32 numSubTextures, f32 frameDuration); TexAtlas *const atlas, char **const subTextureNames,
const i32 numSubTextures, const f32 frameDuration);
Animation *asset_getAnim(AssetManager *const assetManager, Animation *asset_getAnim(AssetManager *const assetManager,
const char *const key); const char *const key);
/*
*********************************
* Audio
*********************************
*/
AudioVorbis *const asset_getVorbis(AssetManager *const assetManager,
const char *const key);
const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
const char *const path, const char *const key);
/* /*
********************************* *********************************
* Everything else * Everything else
********************************* *********************************
*/ */
i32 asset_loadXmlFile(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadXmlFile(AssetManager *const assetManager,
PlatformFileRead *fileRead); MemoryArena *const arena,
const PlatformFileRead *const fileRead);
AudioVorbis *asset_getVorbis(AssetManager *assetManager, Shader *const asset_getShader(AssetManager *assetManager, const enum ShaderList type);
const enum AudioList type);
const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena,
const char *const path, const enum AudioList type);
Shader *asset_getShader(AssetManager *assetManager, const enum ShaderList type);
const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena,
const char *const vertexPath, const char *const vertexPath,
const char *const fragmentPath, const char *const fragmentPath,
@ -72,7 +79,8 @@ const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena,
const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena, const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
const char *filePath); const char *filePath);
v2 asset_stringDimInPixels(const Font *const font, const char *const string); const v2 asset_stringDimInPixels(const Font *const font,
const char *const string);
void asset_unitTest(MemoryArena *arena); void asset_unitTest(MemoryArena *arena);

View File

@ -48,33 +48,6 @@ enum ShaderList
shaderlist_count, shaderlist_count,
}; };
/*
*********************************
* Audio
*********************************
*/
enum AudioList
{
audiolist_battle,
audiolist_overworld,
audiolist_tackle,
audiolist_count,
audiolist_invalid,
};
typedef struct AudioVorbis
{
enum AudioList type;
stb_vorbis *file;
stb_vorbis_info info;
u32 lengthInSamples;
f32 lengthInSeconds;
u8 *data;
i32 size;
} AudioVorbis;
/* /*
********************************* *********************************
* Hash Table * Hash Table
@ -94,6 +67,28 @@ typedef struct HashTable
i32 size; i32 size;
} HashTable; } HashTable;
/*
*********************************
* Audio
*********************************
*/
typedef struct AudioVorbis
{
union {
char *key;
char *name;
};
stb_vorbis *file;
stb_vorbis_info info;
u32 lengthInSamples;
f32 lengthInSeconds;
u8 *data;
i32 size;
} AudioVorbis;
/* /*
********************************* *********************************
* Texture Assets * Texture Assets