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
*********************************
*/
INTERNAL Animation *getFreeAnimationSlot(AssetManager *assetManager,
MemoryArena *arena, char *key)
INTERNAL Animation *getFreeAnimationSlot(AssetManager *const assetManager,
MemoryArena *const arena,
const char *const key)
{
HashTableEntry *entry = getFreeHashSlot(&assetManager->anims, arena, key);
@ -248,9 +249,11 @@ INTERNAL Animation *getFreeAnimationSlot(AssetManager *assetManager,
}
}
void asset_addAnimation(AssetManager *assetManager, MemoryArena *arena,
char *animName, TexAtlas *atlas, char **subTextureNames,
i32 numSubTextures, f32 frameDuration)
void asset_addAnimation(AssetManager *const assetManager,
MemoryArena *const arena, const char *const animName,
TexAtlas *const atlas,
char **const subTextureNames,
const i32 numSubTextures, const f32 frameDuration)
{
Animation *anim = getFreeAnimationSlot(assetManager, arena, animName);
@ -307,8 +310,10 @@ typedef struct XmlToken
i32 len;
} XmlToken;
INTERNAL XmlToken *tokeniseXmlBuffer(MemoryArena *arena, char *buffer,
i32 bufferSize, int *numTokens)
INTERNAL XmlToken *const tokeniseXmlBuffer(MemoryArena *const arena,
const char *const buffer,
const i32 bufferSize,
int *const numTokens)
{
XmlToken *xmlTokens = PLATFORM_MEM_ALLOC(arena, 8192, XmlToken);
i32 tokenIndex = 0;
@ -412,8 +417,9 @@ INTERNAL XmlToken *tokeniseXmlBuffer(MemoryArena *arena, char *buffer,
return xmlTokens;
}
INTERNAL XmlNode *buildXmlTree(MemoryArena *arena, XmlToken *xmlTokens,
i32 numTokens)
INTERNAL XmlNode *const buildXmlTree(MemoryArena *const arena,
XmlToken *const xmlTokens,
const i32 numTokens)
{
XmlNode *root = PLATFORM_MEM_ALLOC(arena, 1, XmlNode);
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)
{
@ -759,11 +766,12 @@ INTERNAL void recursiveFreeXmlTree(MemoryArena *arena, XmlNode *node)
node->name = NULL;
node->isClosed = FALSE;
PLATFORM_MEM_FREE(arena, node, sizeof(XmlNode));
node = NULL;
}
}
INTERNAL void freeXmlData(MemoryArena *arena, XmlToken *tokens, i32 numTokens,
XmlNode *tree)
INTERNAL void freeXmlData(MemoryArena *const arena, XmlToken *tokens,
const i32 numTokens, XmlNode *tree)
{
if (tree) recursiveFreeXmlTree(arena, tree);
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
*********************************
*/
i32 asset_loadXmlFile(AssetManager *assetManager, MemoryArena *arena,
PlatformFileRead *fileRead)
const i32 asset_loadXmlFile(AssetManager *const assetManager,
MemoryArena *const arena,
const PlatformFileRead *const fileRead)
{
i32 result = 0;
/* Tokenise buffer */
@ -802,49 +811,49 @@ i32 asset_loadXmlFile(AssetManager *assetManager, MemoryArena *arena,
return result;
}
// TODO(doyle): Switch to hash based lookup
// TODO(doyle): Use pointers, so we can forward declare all assets?
AudioVorbis *asset_getVorbis(AssetManager *assetManager,
const enum AudioList type)
AudioVorbis *const asset_getVorbis(AssetManager *const assetManager,
const char *const key)
{
if (type < audiolist_count)
return &assetManager->audio[type];
#ifdef DENGINE_DEBUG
ASSERT(INVALID_CODE_PATH);
#endif
HashTableEntry *entry = getEntryFromHash(&assetManager->audio, key);
return NULL;
AudioVorbis *result = NULL;
if (entry) result = CAST(AudioVorbis *)entry->data;
return result;
}
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
PlatformFileRead fileRead = {0};
platform_readFileToBuffer(arena, path, &fileRead);
entry->data = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis);
i32 error;
AudioVorbis audio = {0};
audio.type = type;
audio.file =
AudioVorbis *audio = CAST(AudioVorbis *) entry->data;
audio->file =
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);
platform_closeFileRead(arena, &fileRead);
stb_vorbis_close(audio.file);
stb_vorbis_close(audio->file);
return 0;
}
audio.info = stb_vorbis_get_info(audio.file);
audio.lengthInSamples = stb_vorbis_stream_length_in_samples(audio.file);
audio.lengthInSeconds = stb_vorbis_stream_length_in_seconds(audio.file);
audio.data = CAST(u8 *) fileRead.buffer;
audio.size = fileRead.size;
assetManager->audio[type] = audio;
audio->name = entry->key;
audio->info = stb_vorbis_get_info(audio->file);
audio->lengthInSamples = stb_vorbis_stream_length_in_samples(audio->file);
audio->lengthInSeconds = stb_vorbis_stream_length_in_seconds(audio->file);
audio->data = CAST(u8 *) fileRead.buffer;
audio->size = fileRead.size;
return 0;
}
@ -902,7 +911,8 @@ INTERNAL i32 shaderLoadProgram(Shader *const shader, const GLuint vertexShader,
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)
return &assetManager->shaders[type];
@ -1202,7 +1212,8 @@ const i32 asset_loadTTFont(AssetManager *assetManager, MemoryArena *arena,
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);
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
// position uniquely
AudioVorbis *copyAudio = PLATFORM_MEM_ALLOC(arena, 1, AudioVorbis);
copyAudio->type = vorbis->type;
copyAudio->info = vorbis->info;
copyAudio->lengthInSamples = vorbis->lengthInSamples;
copyAudio->lengthInSeconds = vorbis->lengthInSeconds;
copyAudio->data = vorbis->data;
copyAudio->size = vorbis->size;
*copyAudio = *vorbis;
i32 error;
copyAudio->file =

View File

@ -114,7 +114,12 @@ INTERNAL void rendererInit(GameState *state, v2 windowSize)
INTERNAL void assetInit(GameState *state)
{
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;
assetManager->texAtlas.size = texAtlasEntries;
@ -280,11 +285,11 @@ INTERNAL void assetInit(GameState *state)
char *audioPath =
"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";
asset_loadVorbis(assetManager, arena, audioPath, audiolist_overworld);
asset_loadVorbis(assetManager, arena, audioPath, "audio_overworld");
audioPath = "data/audio/nuindependent_hit22.ogg";
asset_loadVorbis(assetManager, arena, audioPath, audiolist_tackle);
asset_loadVorbis(assetManager, arena, audioPath, "audio_tackle");
#ifdef DENGINE_DEBUG
DEBUG_LOG("Sound assets initialised");
@ -1160,10 +1165,11 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
if (world->numEntitiesInBattle > 0)
{
AudioVorbis *battleTheme =
asset_getVorbis(assetManager, audiolist_battle);
asset_getVorbis(assetManager, "audio_battle");
if (audioRenderer->audio)
{
if (audioRenderer->audio->type != audiolist_battle)
if (common_strcmp(audioRenderer->audio->key,
"audio_battle") != 0)
{
audio_streamPlayVorbis(arena, &state->audioManager,
audioRenderer, battleTheme,
@ -1180,10 +1186,11 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
else
{
AudioVorbis *overworldTheme =
asset_getVorbis(assetManager, audiolist_overworld);
asset_getVorbis(assetManager, "audio_overworld");
if (audioRenderer->audio)
{
if (audioRenderer->audio->type != audiolist_overworld)
if (common_strcmp(audioRenderer->audio->key,
"audio_overworld") != 0)
{
audio_streamPlayVorbis(
arena, &state->audioManager, audioRenderer,
@ -1484,7 +1491,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
Entity *defender = attackSpec->defender;
audio_playVorbis(arena, audioManager, attacker->audioRenderer,
asset_getVorbis(assetManager, audiolist_tackle),
asset_getVorbis(assetManager, "audio_tackle"),
1);
/* Get first free string position and store the damage str data */

View File

@ -15,10 +15,10 @@ typedef struct AssetManager
HashTable texAtlas;
HashTable textures;
HashTable anims;
HashTable audio;
/* Primitive Array */
Shader shaders[32];
AudioVorbis audio[32];
Shader shaders[2];
Font font;
} AssetManager;
@ -45,26 +45,33 @@ Texture *asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena,
* Animation Asset Managing
*********************************
*/
void asset_addAnimation(AssetManager *assetManager, MemoryArena *arena,
char *animName, TexAtlas *atlas, char **subTextureNames,
i32 numSubTextures, f32 frameDuration);
void asset_addAnimation(AssetManager *const assetManager,
MemoryArena *const arena, const char *const animName,
TexAtlas *const atlas, char **const subTextureNames,
const i32 numSubTextures, const f32 frameDuration);
Animation *asset_getAnim(AssetManager *const assetManager,
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
*********************************
*/
i32 asset_loadXmlFile(AssetManager *assetManager, MemoryArena *arena,
PlatformFileRead *fileRead);
const i32 asset_loadXmlFile(AssetManager *const assetManager,
MemoryArena *const arena,
const PlatformFileRead *const fileRead);
AudioVorbis *asset_getVorbis(AssetManager *assetManager,
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);
Shader *const asset_getShader(AssetManager *assetManager, const enum ShaderList type);
const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena,
const char *const vertexPath,
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 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);

View File

@ -48,33 +48,6 @@ enum ShaderList
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
@ -94,6 +67,28 @@ typedef struct HashTable
i32 size;
} 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