Add entity attack audio cue
This commit is contained in:
		
							parent
							
								
									9ec87fc8be
								
							
						
					
					
						commit
						190822c1f6
					
				| @ -131,7 +131,6 @@ | |||||||
|     <ClCompile Include="src\Shader.c" /> |     <ClCompile Include="src\Shader.c" /> | ||||||
|     <ClCompile Include="src\WorldTraveller.c" /> |     <ClCompile Include="src\WorldTraveller.c" /> | ||||||
|     <ClCompile Include="src\Texture.c" /> |     <ClCompile Include="src\Texture.c" /> | ||||||
|     <ClCompile Include="src\Tutorial.cpp" /> |  | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="data\shaders\default.frag.glsl" /> |     <None Include="data\shaders\default.frag.glsl" /> | ||||||
|  | |||||||
| @ -15,9 +15,6 @@ | |||||||
|     </Filter> |     </Filter> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="src\Tutorial.cpp"> |  | ||||||
|       <Filter>Source Files</Filter> |  | ||||||
|     </ClCompile> |  | ||||||
|     <ClCompile Include="src\WorldTraveller.c"> |     <ClCompile Include="src\WorldTraveller.c"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  | |||||||
| @ -80,6 +80,7 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, | |||||||
| 
 | 
 | ||||||
| 	i32 error; | 	i32 error; | ||||||
| 	AudioVorbis audio = {0}; | 	AudioVorbis audio = {0}; | ||||||
|  | 	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); | ||||||
| 	 | 	 | ||||||
| @ -94,6 +95,8 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, | |||||||
| 	audio.info            = stb_vorbis_get_info(audio.file); | 	audio.info            = stb_vorbis_get_info(audio.file); | ||||||
| 	audio.lengthInSamples = stb_vorbis_stream_length_in_samples(audio.file); | 	audio.lengthInSamples = stb_vorbis_stream_length_in_samples(audio.file); | ||||||
| 	audio.lengthInSeconds = stb_vorbis_stream_length_in_seconds(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; | 	assetManager->audio[type] = audio; | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										125
									
								
								src/Audio.c
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								src/Audio.c
									
									
									
									
									
								
							| @ -6,6 +6,8 @@ | |||||||
| #include "Dengine/Assets.h" | #include "Dengine/Assets.h" | ||||||
| #include "Dengine/Audio.h" | #include "Dengine/Audio.h" | ||||||
| #include "Dengine/Debug.h" | #include "Dengine/Debug.h" | ||||||
|  | #include "Dengine/MemoryArena.h" | ||||||
|  | #include "dengine/Platform.h" | ||||||
| 
 | 
 | ||||||
| #define AL_CHECK_ERROR() alCheckError_(__FILE__, __LINE__); | #define AL_CHECK_ERROR() alCheckError_(__FILE__, __LINE__); | ||||||
| void alCheckError_(const char *file, int line) | void alCheckError_(const char *file, int line) | ||||||
| @ -101,13 +103,8 @@ const i32 audio_init(AudioManager *audioManager) | |||||||
| 		alGenSources(1, &audioManager->sourceList[i].id); | 		alGenSources(1, &audioManager->sourceList[i].id); | ||||||
| 		AL_CHECK_ERROR(); | 		AL_CHECK_ERROR(); | ||||||
| 
 | 
 | ||||||
| 		// NOTE(doyle): If last entry, loop the free source to front of list
 | 		audioManager->sourceList[i].isFree = TRUE; | ||||||
| 		if (i + 1 >= ARRAY_COUNT(audioManager->sourceList)) |  | ||||||
| 			audioManager->sourceList[i].nextFreeIndex = 0; |  | ||||||
| 		else |  | ||||||
| 			audioManager->sourceList[i].nextFreeIndex = i+1; |  | ||||||
| 	} | 	} | ||||||
| 	audioManager->freeSourceIndex = 0; |  | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @ -119,44 +116,41 @@ INTERNAL inline u32 getSourceId(AudioManager *audioManager, | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL i32 rendererAcquire(AudioManager *audioManager, | INTERNAL i32 rendererAcquire(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                              AudioRenderer *audioRenderer) |                              AudioRenderer *audioRenderer) | ||||||
| { | { | ||||||
| 
 |  | ||||||
| 	i32 vacantSource = audioManager->freeSourceIndex; |  | ||||||
| 
 |  | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 	ASSERT(audioManager && audioRenderer); | 	ASSERT(arena && audioManager && audioRenderer); | ||||||
| 	ASSERT(vacantSource >= 0); |  | ||||||
| #endif | #endif | ||||||
| 
 |  | ||||||
| 	if (audioManager->sourceList[vacantSource].nextFreeIndex == |  | ||||||
| 	    AUDIO_NO_FREE_SOURCE) |  | ||||||
| 	{ |  | ||||||
| 		// TODO(doyle): Error messaging return paths
 |  | ||||||
| 		DEBUG_LOG("rendererAcquire(): Failed to acquire free source, all busy"); |  | ||||||
| 		return -1; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	u32 checkSource = getSourceId(audioManager, audioRenderer); | 	u32 checkSource = getSourceId(audioManager, audioRenderer); | ||||||
| 	if (alIsSource(checkSource) == AL_TRUE) | 	if (alIsSource(checkSource) == AL_TRUE) | ||||||
| 	{ | 	{ | ||||||
| 		DEBUG_LOG( | 		DEBUG_LOG( | ||||||
| 		    "rendererAcquire(): Renderer has not been released before " | 		    "rendererAcquire(): Renderer has not been released before " | ||||||
| 		    "acquiring, force release by stopping stream"); | 		    "acquiring, force release by stopping stream"); | ||||||
| 		audio_streamStopVorbis(audioManager, audioRenderer); | 		audio_streamStopVorbis(arena, audioManager, audioRenderer); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// TODO(doyle): Super bad linear O(n) search for every audio-enabled entity
 | ||||||
|  | 	i32 vacantSource = AUDIO_SOURCE_UNASSIGNED; | ||||||
|  | 	for (i32 i = 0; i < ARRAY_COUNT(audioManager->sourceList); i++) | ||||||
|  | 	{ | ||||||
|  | 		if (audioManager->sourceList[i].isFree) | ||||||
|  | 		{ | ||||||
|  | 			vacantSource = i; | ||||||
|  | 			audioManager->sourceList[i].isFree = FALSE; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (vacantSource == AUDIO_SOURCE_UNASSIGNED) | ||||||
|  | 	{ | ||||||
|  | 		DEBUG_LOG("rendererAcquire(): Failed to acquire free source, all busy"); | ||||||
|  | 		return -1; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Assign a vacant source slot to renderer */ |  | ||||||
| 	audioRenderer->sourceIndex = vacantSource; | 	audioRenderer->sourceIndex = vacantSource; | ||||||
| 
 | 
 | ||||||
| 	/* Update the immediate free source index */ |  | ||||||
| 	audioManager->freeSourceIndex = |  | ||||||
| 	    audioManager->sourceList[vacantSource].nextFreeIndex; |  | ||||||
| 
 |  | ||||||
| 	/* Mark current source as in use */ |  | ||||||
| 	audioManager->sourceList[vacantSource].nextFreeIndex = AUDIO_NO_FREE_SOURCE; |  | ||||||
| 
 |  | ||||||
| 	/* Generate audio data buffers */ | 	/* Generate audio data buffers */ | ||||||
| 	alGenBuffers(ARRAY_COUNT(audioRenderer->bufferId), audioRenderer->bufferId); | 	alGenBuffers(ARRAY_COUNT(audioRenderer->bufferId), audioRenderer->bufferId); | ||||||
| 	AL_CHECK_ERROR(); | 	AL_CHECK_ERROR(); | ||||||
| @ -166,7 +160,7 @@ INTERNAL i32 rendererAcquire(AudioManager *audioManager, | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL const i32 rendererRelease(AudioManager *audioManager, | INTERNAL const i32 rendererRelease(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                                    AudioRenderer *audioRenderer) |                                    AudioRenderer *audioRenderer) | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| @ -181,8 +175,29 @@ INTERNAL const i32 rendererRelease(AudioManager *audioManager, | |||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	alSourceUnqueueBuffers(alSourceId, ARRAY_COUNT(audioRenderer->bufferId), | 	/*
 | ||||||
|  | 	  NOTE(doyle): Doing an alSourceRewind will result in the source going to | ||||||
|  | 	  the AL_INITIAL state, but the properties of the source (position, | ||||||
|  | 	  velocity, etc.) will not change. | ||||||
|  | 	*/ | ||||||
|  | 	alSourceRewind(alSourceId); | ||||||
|  | 	AL_CHECK_ERROR(); | ||||||
|  | 
 | ||||||
|  | 	// TODO(doyle): We can possible remove this by just attaching the null buffer ..
 | ||||||
|  | 	ALint numProcessedBuffers; | ||||||
|  | 	alGetSourcei(alSourceId, AL_BUFFERS_PROCESSED, &numProcessedBuffers); | ||||||
|  | 	if (numProcessedBuffers > 0) | ||||||
|  | 	{ | ||||||
|  | 		alSourceUnqueueBuffers(alSourceId, numProcessedBuffers, | ||||||
| 		                       audioRenderer->bufferId); | 		                       audioRenderer->bufferId); | ||||||
|  | 	} | ||||||
|  | 	AL_CHECK_ERROR(); | ||||||
|  | 
 | ||||||
|  | 	// NOTE(doyle): Any buffer queued up that has not been played cannot be
 | ||||||
|  | 	// deleted without being played once. We can set the source buffers to NULL
 | ||||||
|  | 	// (0) to free up the buffer, since we still hold the reference ids for the
 | ||||||
|  | 	// buffer in our audio structure we can delete it afterwards ..
 | ||||||
|  | 	alSourcei(alSourceId, AL_BUFFER, 0); | ||||||
| 	alDeleteBuffers(ARRAY_COUNT(audioRenderer->bufferId), | 	alDeleteBuffers(ARRAY_COUNT(audioRenderer->bufferId), | ||||||
| 	                audioRenderer->bufferId); | 	                audioRenderer->bufferId); | ||||||
| 	AL_CHECK_ERROR(); | 	AL_CHECK_ERROR(); | ||||||
| @ -192,21 +207,22 @@ INTERNAL const i32 rendererRelease(AudioManager *audioManager, | |||||||
| 		audioRenderer->bufferId[i] = 0; | 		audioRenderer->bufferId[i] = 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	stb_vorbis_close(audioRenderer->audio->file); | ||||||
|  | 	PLATFORM_MEM_FREE(arena, audioRenderer->audio, sizeof(AudioVorbis)); | ||||||
|  | 
 | ||||||
| 	audioRenderer->audio    = NULL; | 	audioRenderer->audio    = NULL; | ||||||
| 	audioRenderer->numPlays = 0; | 	audioRenderer->numPlays = 0; | ||||||
| 
 | 
 | ||||||
| 	u32 sourceIndexToFree      = audioRenderer->sourceIndex; | 	u32 sourceIndexToFree      = audioRenderer->sourceIndex; | ||||||
| 	audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED; | 	audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED; | ||||||
| 
 | 
 | ||||||
| 	audioManager->sourceList[sourceIndexToFree].nextFreeIndex = | 	audioManager->sourceList[sourceIndexToFree].isFree = TRUE; | ||||||
| 	    audioManager->freeSourceIndex; |  | ||||||
| 	audioManager->freeSourceIndex = sourceIndexToFree; |  | ||||||
| 
 | 
 | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #define AUDIO_CHUNK_SIZE_ 65536 | #define AUDIO_CHUNK_SIZE_ 65536 | ||||||
| const i32 audio_streamPlayVorbis(AudioManager *audioManager, | const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                                  AudioRenderer *audioRenderer, |                                  AudioRenderer *audioRenderer, | ||||||
|                                  AudioVorbis *vorbis, i32 numPlays) |                                  AudioVorbis *vorbis, i32 numPlays) | ||||||
| { | { | ||||||
| @ -218,7 +234,7 @@ const i32 audio_streamPlayVorbis(AudioManager *audioManager, | |||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	i32 result = rendererAcquire(audioManager, audioRenderer); | 	i32 result = rendererAcquire(arena, audioManager, audioRenderer); | ||||||
| 	if (result) | 	if (result) | ||||||
| 	{ | 	{ | ||||||
| 		DEBUG_LOG("audio_streamPlayVorbis() failed: Could not acquire renderer"); | 		DEBUG_LOG("audio_streamPlayVorbis() failed: Could not acquire renderer"); | ||||||
| @ -237,13 +253,30 @@ const i32 audio_streamPlayVorbis(AudioManager *audioManager, | |||||||
| #endif | #endif | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	audioRenderer->audio    = vorbis; | 	// NOTE(doyle): We make a copy of the audio vorbis file using all the same
 | ||||||
|  | 	// data except the file pointer. If the same sound is playing twice
 | ||||||
|  | 	// 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; | ||||||
|  | 
 | ||||||
|  | 	i32 error; | ||||||
|  | 	copyAudio->file = | ||||||
|  | 	    stb_vorbis_open_memory(copyAudio->data, copyAudio->size, &error, NULL); | ||||||
|  | 
 | ||||||
|  | 	audioRenderer->audio    = copyAudio; | ||||||
| 	audioRenderer->numPlays = numPlays; | 	audioRenderer->numPlays = numPlays; | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const i32 audio_streamStopVorbis(AudioManager *audioManager, | const i32 audio_streamStopVorbis(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                                  AudioRenderer *audioRenderer) |                                  AudioRenderer *audioRenderer) | ||||||
| { | { | ||||||
| 	i32 result     = 0; | 	i32 result     = 0; | ||||||
| @ -252,7 +285,7 @@ const i32 audio_streamStopVorbis(AudioManager *audioManager, | |||||||
| 	{ | 	{ | ||||||
| 		alSourceStop(alSourceId); | 		alSourceStop(alSourceId); | ||||||
| 		AL_CHECK_ERROR(); | 		AL_CHECK_ERROR(); | ||||||
| 		result = rendererRelease(audioManager, audioRenderer); | 		result = rendererRelease(arena, audioManager, audioRenderer); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -300,18 +333,20 @@ const i32 audio_streamResumeVorbis(AudioManager *audioManager, | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const i32 audio_updateAndPlay(AudioManager *audioManager, | const i32 audio_updateAndPlay(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                               AudioRenderer *audioRenderer) |                               AudioRenderer *audioRenderer) | ||||||
| { | { | ||||||
| 	AudioVorbis *audio = audioRenderer->audio; | 	AudioVorbis *audio = audioRenderer->audio; | ||||||
| 	if (!audio) return 0; | 	if (!audio) return 0; | ||||||
| 
 | 
 | ||||||
|  | #if 0 | ||||||
| 	if (audioRenderer->numPlays != AUDIO_REPEAT_INFINITE && | 	if (audioRenderer->numPlays != AUDIO_REPEAT_INFINITE && | ||||||
| 	    audioRenderer->numPlays <= 0) | 	    audioRenderer->numPlays <= 0) | ||||||
| 	{ | 	{ | ||||||
| 		i32 result = rendererRelease(audioManager, audioRenderer); | 		i32 result = rendererRelease(arena, audioManager, audioRenderer); | ||||||
| 		return result; | 		return result; | ||||||
| 	} | 	} | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	u32 alSourceId = getSourceId(audioManager, audioRenderer); | 	u32 alSourceId = getSourceId(audioManager, audioRenderer); | ||||||
| 	if (alIsSource(alSourceId) == AL_FALSE) | 	if (alIsSource(alSourceId) == AL_FALSE) | ||||||
| @ -345,13 +380,12 @@ const i32 audio_updateAndPlay(AudioManager *audioManager, | |||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				i32 result = rendererRelease(audioManager, audioRenderer); | 				i32 result = | ||||||
|  | 				    rendererRelease(arena, audioManager, audioRenderer); | ||||||
| 				return result; | 				return result; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// TODO(doyle): Possible bug! Multiple sources playing same file seeking
 |  | ||||||
| 		// file ptr to start may interrupt other stream
 |  | ||||||
| 		stb_vorbis_seek_start(audio->file); | 		stb_vorbis_seek_start(audio->file); | ||||||
| 		for (i32 i = 0; i < ARRAY_COUNT(audioRenderer->bufferId); i++) | 		for (i32 i = 0; i < ARRAY_COUNT(audioRenderer->bufferId); i++) | ||||||
| 		{ | 		{ | ||||||
| @ -380,6 +414,7 @@ const i32 audio_updateAndPlay(AudioManager *audioManager, | |||||||
| 		AL_CHECK_ERROR(); | 		AL_CHECK_ERROR(); | ||||||
| 		if (numProcessedBuffers > 0) | 		if (numProcessedBuffers > 0) | ||||||
| 		{ | 		{ | ||||||
|  | 			// TODO(doyle): Possibly wrong, we should pass in all processed buffers?
 | ||||||
| 			ALint numBuffersToUnqueue = 1; | 			ALint numBuffersToUnqueue = 1; | ||||||
| 			ALuint emptyBufferId; | 			ALuint emptyBufferId; | ||||||
| 			alSourceUnqueueBuffers(alSourceId, numBuffersToUnqueue, | 			alSourceUnqueueBuffers(alSourceId, numBuffersToUnqueue, | ||||||
|  | |||||||
							
								
								
									
										29
									
								
								src/Debug.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/Debug.c
									
									
									
									
									
								
							| @ -189,6 +189,13 @@ void debug_pushString(char *formatString, void *data, char *dataType) | |||||||
| 			         ARRAY_COUNT(GLOBAL_debug.debugStrings[0]), | 			         ARRAY_COUNT(GLOBAL_debug.debugStrings[0]), | ||||||
| 			         formatString, val.x, val.y); | 			         formatString, val.x, val.y); | ||||||
| 		} | 		} | ||||||
|  | 		else if (common_strcmp(dataType, "v3") == 0) | ||||||
|  | 		{ | ||||||
|  | 			v3 val = *(CAST(v3 *) data); | ||||||
|  | 			snprintf(GLOBAL_debug.debugStrings[numDebugStrings], | ||||||
|  | 			         ARRAY_COUNT(GLOBAL_debug.debugStrings[0]), | ||||||
|  | 			         formatString, val.x, val.y, val.z); | ||||||
|  | 		} | ||||||
| 		else if (common_strcmp(dataType, "i32") == 0) | 		else if (common_strcmp(dataType, "i32") == 0) | ||||||
| 		{ | 		{ | ||||||
| 			i32 val = *(CAST(i32 *) data); | 			i32 val = *(CAST(i32 *) data); | ||||||
| @ -394,6 +401,19 @@ void debug_drawUi(GameState *state, f32 dt) | |||||||
| 			char *entityStateStr = debug_entitystate_string(entity->state); | 			char *entityStateStr = debug_entitystate_string(entity->state); | ||||||
| 			renderer_string(&state->renderer, &state->arena, cameraBounds, font, | 			renderer_string(&state->renderer, &state->arena, cameraBounds, font, | ||||||
| 			                entityStateStr, strPos, V2(0, 0), 0, color); | 			                entityStateStr, strPos, V2(0, 0), 0, color); | ||||||
|  | 
 | ||||||
|  | 			if (entity->audioRenderer) | ||||||
|  | 			{ | ||||||
|  | 				strPos.y -= GLOBAL_debug.stringLineGap; | ||||||
|  | 				char entityAudioSourceIndex[32]; | ||||||
|  | 				snprintf(entityAudioSourceIndex, | ||||||
|  | 				         ARRAY_COUNT(entityAudioSourceIndex), | ||||||
|  | 				         "AudioSource Index: %d", | ||||||
|  | 				         entity->audioRenderer->sourceIndex); | ||||||
|  | 				renderer_string(&state->renderer, &state->arena, cameraBounds, | ||||||
|  | 				                font, entityAudioSourceIndex, strPos, V2(0, 0), | ||||||
|  | 				                0, color); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -418,6 +438,15 @@ void debug_drawUi(GameState *state, f32 dt) | |||||||
| 	i32 debug_kbAllocated = state->arena.bytesAllocated / 1024; | 	i32 debug_kbAllocated = state->arena.bytesAllocated / 1024; | ||||||
| 	DEBUG_PUSH_VAR("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32"); | 	DEBUG_PUSH_VAR("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32"); | ||||||
| 
 | 
 | ||||||
|  | 	AudioManager *audioManager = &state->audioManager; | ||||||
|  | 	DEBUG_PUSH_STRING("== Audio System =="); | ||||||
|  | 	for (i32 i = 0; i < ARRAY_COUNT(audioManager->sourceList); i++) | ||||||
|  | 	{ | ||||||
|  | 		v3 tmp = V3i(i, audioManager->sourceList[i].id, | ||||||
|  | 		             audioManager->sourceList[i].isFree); | ||||||
|  | 		DEBUG_PUSH_VAR("Source ID[%02.0f].id[%02.0f].isFree: %1.0f", tmp, "v3"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	DEBUG_PUSH_STRING("== EntityIDs in Battle List == "); | 	DEBUG_PUSH_STRING("== EntityIDs in Battle List == "); | ||||||
| 	DEBUG_PUSH_VAR("NumEntitiesInBattle: %d", world->numEntitiesInBattle, | 	DEBUG_PUSH_VAR("NumEntitiesInBattle: %d", world->numEntitiesInBattle, | ||||||
| 	               "i32"); | 	               "i32"); | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								src/Entity.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/Entity.c
									
									
									
									
									
								
							| @ -77,6 +77,9 @@ void entity_addGenericMob(MemoryArena *arena, AssetManager *assetManager, | |||||||
| 	b32 collides         = TRUE; | 	b32 collides         = TRUE; | ||||||
| 	Entity *mob = entity_add(arena, world, pos, size, type, dir, tex, collides); | 	Entity *mob = entity_add(arena, world, pos, size, type, dir, tex, collides); | ||||||
| 
 | 
 | ||||||
|  | 	mob->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer); | ||||||
|  | 	mob->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED; | ||||||
|  | 
 | ||||||
| 	/* Populate mob animation references */ | 	/* Populate mob animation references */ | ||||||
| 	entity_addAnim(assetManager, mob, animlist_hero_idle); | 	entity_addAnim(assetManager, mob, animlist_hero_idle); | ||||||
| 	entity_addAnim(assetManager, mob, animlist_hero_walk); | 	entity_addAnim(assetManager, mob, animlist_hero_walk); | ||||||
| @ -125,7 +128,7 @@ Entity *entity_add(MemoryArena *arena, World *world, v2 pos, v2 size, | |||||||
| 		entity.stats               = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); | 		entity.stats               = PLATFORM_MEM_ALLOC(arena, 1, EntityStats); | ||||||
| 		entity.stats->maxHealth    = 100; | 		entity.stats->maxHealth    = 100; | ||||||
| 		entity.stats->health       = entity.stats->maxHealth; | 		entity.stats->health       = entity.stats->maxHealth; | ||||||
| 		entity.stats->actionRate   = 100; | 		entity.stats->actionRate   = 80; | ||||||
| 		entity.stats->actionTimer  = entity.stats->actionRate; | 		entity.stats->actionTimer  = entity.stats->actionRate; | ||||||
| 		entity.stats->actionSpdMul = 100; | 		entity.stats->actionSpdMul = 100; | ||||||
| 		entity.stats->entityIdToAttack = -1; | 		entity.stats->entityIdToAttack = -1; | ||||||
| @ -147,8 +150,13 @@ Entity *entity_add(MemoryArena *arena, World *world, v2 pos, v2 size, | |||||||
| void entity_delete(MemoryArena *arena, World *world, i32 entityIndex) | void entity_delete(MemoryArena *arena, World *world, i32 entityIndex) | ||||||
| { | { | ||||||
| 	Entity *entity = &world->entities[entityIndex]; | 	Entity *entity = &world->entities[entityIndex]; | ||||||
|  | 
 | ||||||
|  | 	if (entity->stats) | ||||||
| 		PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats)); | 		PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats)); | ||||||
| 
 | 
 | ||||||
|  | 	if (entity->audioRenderer) | ||||||
|  | 		PLATFORM_MEM_FREE(arena, entity->audioRenderer, sizeof(AudioRenderer)); | ||||||
|  | 
 | ||||||
| 	// TODO(doyle): Inefficient shuffle down all elements
 | 	// TODO(doyle): Inefficient shuffle down all elements
 | ||||||
| 	for (i32 i             = entityIndex; i < world->freeEntityIndex - 1; i++) | 	for (i32 i             = entityIndex; i < world->freeEntityIndex - 1; i++) | ||||||
| 		world->entities[i] = world->entities[i + 1]; | 		world->entities[i] = world->entities[i + 1]; | ||||||
|  | |||||||
| @ -187,6 +187,8 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | |||||||
| 	asset_loadVorbis(assetManager, arena, audioPath, audiolist_battle); | 	asset_loadVorbis(assetManager, arena, audioPath, audiolist_battle); | ||||||
| 	audioPath = "data/audio/Yuki Kajiura - Swordland.ogg"; | 	audioPath = "data/audio/Yuki Kajiura - Swordland.ogg"; | ||||||
| 	asset_loadVorbis(assetManager, arena, audioPath, audiolist_overworld); | 	asset_loadVorbis(assetManager, arena, audioPath, audiolist_overworld); | ||||||
|  | 	audioPath = "data/audio/nuindependent_hit22.ogg"; | ||||||
|  | 	asset_loadVorbis(assetManager, arena, audioPath, audiolist_tackle); | ||||||
| 
 | 
 | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 	DEBUG_LOG("Sound assets initialised"); | 	DEBUG_LOG("Sound assets initialised"); | ||||||
| @ -278,6 +280,8 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize) | |||||||
| 	tex             = asset_getTexture(assetManager, texlist_hero); | 	tex             = asset_getTexture(assetManager, texlist_hero); | ||||||
| 	collides        = TRUE; | 	collides        = TRUE; | ||||||
| 	Entity *hero = entity_add(arena, world, pos, size, type, dir, tex, collides); | 	Entity *hero = entity_add(arena, world, pos, size, type, dir, tex, collides); | ||||||
|  | 	hero->audioRenderer = PLATFORM_MEM_ALLOC(arena, 1, AudioRenderer); | ||||||
|  | 	hero->audioRenderer->sourceIndex = AUDIO_SOURCE_UNASSIGNED; | ||||||
| 
 | 
 | ||||||
| 	/* Populate hero animation references */ | 	/* Populate hero animation references */ | ||||||
| 	entity_addAnim(assetManager, hero, animlist_hero_idle); | 	entity_addAnim(assetManager, hero, animlist_hero_idle); | ||||||
| @ -579,7 +583,6 @@ INTERNAL inline void resetEntityState(World *world, Entity *entity) | |||||||
| 
 | 
 | ||||||
| INTERNAL void beginAttack(World *world, Entity *attacker) | INTERNAL void beginAttack(World *world, Entity *attacker) | ||||||
| { | { | ||||||
| 
 |  | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 	ASSERT(attacker->stats->entityIdToAttack != ENTITY_NULL_ID); | 	ASSERT(attacker->stats->entityIdToAttack != ENTITY_NULL_ID); | ||||||
| 	ASSERT(attacker->state == entitystate_battle); | 	ASSERT(attacker->state == entitystate_battle); | ||||||
| @ -596,17 +599,18 @@ INTERNAL void beginAttack(World *world, Entity *attacker) | |||||||
| 			attacker->dPos.x += (1.0f * METERS_TO_PIXEL); | 			attacker->dPos.x += (1.0f * METERS_TO_PIXEL); | ||||||
| 		else | 		else | ||||||
| 			attacker->dPos.x -= (1.0f * METERS_TO_PIXEL); | 			attacker->dPos.x -= (1.0f * METERS_TO_PIXEL); | ||||||
| 
 |  | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 		ASSERT(INVALID_CODE_PATH); | 		ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | INTERNAL void endAttack(MemoryArena *arena, AssetManager *assetManager, | ||||||
| 
 |                         AudioManager *audioManager, World *world, | ||||||
| INTERNAL void endAttack(World *world, Entity *attacker) |                         Entity *attacker) | ||||||
| { | { | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 	ASSERT(attacker->stats->entityIdToAttack != ENTITY_NULL_ID); | 	ASSERT(attacker->stats->entityIdToAttack != ENTITY_NULL_ID); | ||||||
| @ -621,11 +625,18 @@ INTERNAL void endAttack(World *world, Entity *attacker) | |||||||
| 		else | 		else | ||||||
| 			attacker->dPos.x += (1.0f * METERS_TO_PIXEL); | 			attacker->dPos.x += (1.0f * METERS_TO_PIXEL); | ||||||
| 
 | 
 | ||||||
|  | #if 1 | ||||||
|  | 		audio_streamPlayVorbis(arena, audioManager, attacker->audioRenderer, | ||||||
|  | 		                       asset_getVorbis(assetManager, audiolist_tackle), | ||||||
|  | 		                       1); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 		ASSERT(INVALID_CODE_PATH); | 		ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Compute attack damage */ | 	/* Compute attack damage */ | ||||||
| @ -681,8 +692,9 @@ INTERNAL void endAttack(World *world, Entity *attacker) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| INTERNAL void entityStateSwitch(World *world, Entity *entity, | INTERNAL void entityStateSwitch(MemoryArena *arena, AssetManager *assetManager, | ||||||
|                                 enum EntityState newState) |                                 AudioManager *audioManager, World *world, | ||||||
|  |                                 Entity *entity, enum EntityState newState) | ||||||
| { | { | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 	ASSERT(world && entity) | 	ASSERT(world && entity) | ||||||
| @ -718,6 +730,7 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity, | |||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 			ASSERT(INVALID_CODE_PATH); | 			ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case entitystate_battle: | 	case entitystate_battle: | ||||||
| @ -736,13 +749,14 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity, | |||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 			ASSERT(INVALID_CODE_PATH); | 			ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case entitystate_attack: | 	case entitystate_attack: | ||||||
| 		switch (newState) | 		switch (newState) | ||||||
| 		{ | 		{ | ||||||
| 		case entitystate_battle: | 		case entitystate_battle: | ||||||
| 			endAttack(world, entity); | 			endAttack(arena, assetManager, audioManager, world, entity); | ||||||
| 			entity_setActiveAnim(entity, animlist_hero_battlePose); | 			entity_setActiveAnim(entity, animlist_hero_battlePose); | ||||||
| 			entity->stats->actionTimer  = entity->stats->actionRate; | 			entity->stats->actionTimer  = entity->stats->actionRate; | ||||||
| 			entity->stats->busyDuration = 0; | 			entity->stats->busyDuration = 0; | ||||||
| @ -756,6 +770,7 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity, | |||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 			ASSERT(INVALID_CODE_PATH); | 			ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	case entitystate_dead: | 	case entitystate_dead: | ||||||
| @ -768,12 +783,14 @@ INTERNAL void entityStateSwitch(World *world, Entity *entity, | |||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 			ASSERT(INVALID_CODE_PATH); | 			ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 		ASSERT(INVALID_CODE_PATH); | 		ASSERT(INVALID_CODE_PATH); | ||||||
| #endif | #endif | ||||||
|  | 		break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	entity->state = newState; | 	entity->state = newState; | ||||||
| @ -790,6 +807,7 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 	Renderer *renderer         = &state->renderer; | 	Renderer *renderer         = &state->renderer; | ||||||
| 	World *const world         = &state->world[state->currWorldIndex]; | 	World *const world         = &state->world[state->currWorldIndex]; | ||||||
| 	Font *font                 = &assetManager->font; | 	Font *font                 = &assetManager->font; | ||||||
|  | 	MemoryArena *arena         = &state->arena; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 ****************************** | 	 ****************************** | ||||||
| @ -798,37 +816,55 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 	 */ | 	 */ | ||||||
| 	Entity *hero               = getHeroEntity(world); | 	Entity *hero               = getHeroEntity(world); | ||||||
| 	v4 cameraBounds            = createCameraBounds(world, renderer->size); | 	v4 cameraBounds            = createCameraBounds(world, renderer->size); | ||||||
|  | 	AudioManager *audioManager = &state->audioManager; | ||||||
| 	ASSERT(world->freeEntityIndex < world->maxEntities); | 	ASSERT(world->freeEntityIndex < world->maxEntities); | ||||||
| 	for (i32 i = 0; i < world->freeEntityIndex; i++) | 	for (i32 i = 0; i < world->freeEntityIndex; i++) | ||||||
| 	{ | 	{ | ||||||
| 		Entity *const entity = &world->entities[i]; | 		Entity *const entity = &world->entities[i]; | ||||||
| 
 | 
 | ||||||
| 		if (entity->audioRenderer) | 		if (entity->type == entitytype_soundscape) | ||||||
| 		{ | 		{ | ||||||
| 			AudioRenderer *audioRenderer = entity->audioRenderer; | 			AudioRenderer *audioRenderer = entity->audioRenderer; | ||||||
| 			if (world->numEntitiesInBattle > 0) | 			if (world->numEntitiesInBattle > 0) | ||||||
| 			{ | 			{ | ||||||
| 				AudioVorbis *battleTheme = | 				AudioVorbis *battleTheme = | ||||||
| 				    asset_getVorbis(assetManager, audiolist_battle); | 				    asset_getVorbis(assetManager, audiolist_battle); | ||||||
| 				if (audioRenderer->audio != battleTheme) | 				if (audioRenderer->audio) | ||||||
| 				{ | 				{ | ||||||
| 					audio_streamPlayVorbis(&state->audioManager, audioRenderer, | 					if (audioRenderer->audio->type != audiolist_battle) | ||||||
| 					                       battleTheme, AUDIO_REPEAT_INFINITE); | 					{ | ||||||
|  | 						audio_streamPlayVorbis(arena, &state->audioManager, | ||||||
|  | 						                       audioRenderer, battleTheme, | ||||||
|  | 						                       AUDIO_REPEAT_INFINITE); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					audio_streamPlayVorbis(arena, &state->audioManager, | ||||||
|  | 					                       audioRenderer, battleTheme, | ||||||
|  | 					                       AUDIO_REPEAT_INFINITE); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				AudioVorbis *overworldTheme = | 				AudioVorbis *overworldTheme = | ||||||
| 				    asset_getVorbis(assetManager, audiolist_overworld); | 				    asset_getVorbis(assetManager, audiolist_overworld); | ||||||
| 				if (audioRenderer->audio != overworldTheme) | 				if (audioRenderer->audio) | ||||||
| 				{ | 				{ | ||||||
| 					audio_streamPlayVorbis(&state->audioManager, audioRenderer, | 					if (audioRenderer->audio->type != audiolist_overworld) | ||||||
| 					                       overworldTheme, | 					{ | ||||||
|  | 						audio_streamPlayVorbis(arena, &state->audioManager, | ||||||
|  | 						                       audioRenderer, overworldTheme, | ||||||
|  | 						                       AUDIO_REPEAT_INFINITE); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					audio_streamPlayVorbis(arena, &state->audioManager, | ||||||
|  | 					                       audioRenderer, overworldTheme, | ||||||
| 					                       AUDIO_REPEAT_INFINITE); | 					                       AUDIO_REPEAT_INFINITE); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 			audio_updateAndPlay(&state->audioManager, entity->audioRenderer); |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (entity->state == entitystate_dead) | 		if (entity->state == entitystate_dead) | ||||||
| @ -849,6 +885,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 			// an entity dies
 | 			// an entity dies
 | ||||||
| #if 1 | #if 1 | ||||||
| 			i32 entityIndexInArray = i; | 			i32 entityIndexInArray = i; | ||||||
|  | 			audio_streamStopVorbis(arena, &state->audioManager, | ||||||
|  | 			                       entity->audioRenderer); | ||||||
| 			entity_delete(&state->arena, world, entityIndexInArray); | 			entity_delete(&state->arena, world, entityIndexInArray); | ||||||
| 
 | 
 | ||||||
| 			// TODO(doyle): DeleteEntity moves elements down 1, so account for i
 | 			// TODO(doyle): DeleteEntity moves elements down 1, so account for i
 | ||||||
| @ -888,7 +926,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 				newState = entitystate_idle; | 				newState = entitystate_idle; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			entityStateSwitch(world, entity, newState); | 			entityStateSwitch(arena, assetManager, audioManager, world, entity, | ||||||
|  | 			                  newState); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| @ -911,7 +950,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 						stats->queuedAttack = entityattack_tackle; | 						stats->queuedAttack = entityattack_tackle; | ||||||
| 
 | 
 | ||||||
| 					/* Launch up attack animation */ | 					/* Launch up attack animation */ | ||||||
| 					entityStateSwitch(world, entity, entitystate_attack); | 					entityStateSwitch(arena, assetManager, audioManager, world, | ||||||
|  | 					                  entity, entitystate_attack); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else if (entity->state == entitystate_attack) | 			else if (entity->state == entitystate_attack) | ||||||
| @ -922,7 +962,8 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 				if (stats->busyDuration <= 0) | 				if (stats->busyDuration <= 0) | ||||||
| 				{ | 				{ | ||||||
| 					/* Apply attack damage */ | 					/* Apply attack damage */ | ||||||
| 					entityStateSwitch(world, entity, entitystate_battle); | 					entityStateSwitch(arena, assetManager, audioManager, world, | ||||||
|  | 					                  entity, entitystate_battle); | ||||||
| 
 | 
 | ||||||
| 					/* Get target entity that was attacked */ | 					/* Get target entity that was attacked */ | ||||||
| 					Entity *defender = NULL; | 					Entity *defender = NULL; | ||||||
| @ -946,13 +987,21 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| #ifdef DENGINE_DEBUG | #ifdef DENGINE_DEBUG | ||||||
| 						DEBUG_LOG("Entity has died"); | 						DEBUG_LOG("Entity has died"); | ||||||
| #endif | #endif | ||||||
| 						entityStateSwitch(world, defender, entitystate_dead); | 						entityStateSwitch(arena, assetManager, audioManager, world, defender, | ||||||
| 						entityStateSwitch(world, attacker, entitystate_idle); | 						                  entitystate_dead); | ||||||
|  | 						entityStateSwitch(arena, assetManager, audioManager, world, attacker, | ||||||
|  | 						                  entitystate_idle); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (entity->audioRenderer) | ||||||
|  | 		{ | ||||||
|  | 			audio_updateAndPlay(&state->arena, &state->audioManager, | ||||||
|  | 			                    entity->audioRenderer); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 ************************************************** | 		 ************************************************** | ||||||
| 		 * Update animations and render entity | 		 * Update animations and render entity | ||||||
| @ -973,10 +1022,10 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt) | |||||||
| 		// NOTE(doyle): If battle entities is 1 then only the hero left
 | 		// NOTE(doyle): If battle entities is 1 then only the hero left
 | ||||||
| 		if (hero->state == entitystate_battle && | 		if (hero->state == entitystate_battle && | ||||||
| 		    world->numEntitiesInBattle == 1) | 		    world->numEntitiesInBattle == 1) | ||||||
| 			entityStateSwitch(world, hero, entitystate_idle); | 			entityStateSwitch(arena, assetManager, audioManager, world, hero, entitystate_idle); | ||||||
| 		else if (hero->state != entitystate_attack) | 		else if (hero->state != entitystate_attack) | ||||||
| 		{ | 		{ | ||||||
| 			entityStateSwitch(world, hero, entitystate_battle); | 			entityStateSwitch(arena, assetManager, audioManager, world, hero, entitystate_battle); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
|  | |||||||
| @ -62,17 +62,22 @@ enum AudioList | |||||||
| { | { | ||||||
| 	audiolist_battle, | 	audiolist_battle, | ||||||
| 	audiolist_overworld, | 	audiolist_overworld, | ||||||
|  | 	audiolist_tackle, | ||||||
| 	audiolist_count, | 	audiolist_count, | ||||||
| 	audiolist_invalid, | 	audiolist_invalid, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef struct AudioVorbis | typedef struct AudioVorbis | ||||||
| { | { | ||||||
|  | 	enum AudioList type; | ||||||
| 	stb_vorbis *file; | 	stb_vorbis *file; | ||||||
| 	stb_vorbis_info info; | 	stb_vorbis_info info; | ||||||
| 
 | 
 | ||||||
| 	u32 lengthInSamples; | 	u32 lengthInSamples; | ||||||
| 	f32 lengthInSeconds; | 	f32 lengthInSeconds; | ||||||
|  | 
 | ||||||
|  | 	u8 *data; | ||||||
|  | 	i32 size; | ||||||
| } AudioVorbis; | } AudioVorbis; | ||||||
| 
 | 
 | ||||||
| typedef struct TexAtlas | typedef struct TexAtlas | ||||||
|  | |||||||
| @ -5,20 +5,22 @@ | |||||||
| 
 | 
 | ||||||
| #include "Dengine/Common.h" | #include "Dengine/Common.h" | ||||||
| 
 | 
 | ||||||
|  | /* Forward Declaration */ | ||||||
|  | typedef struct MemoryArena MemoryArena; | ||||||
|  | 
 | ||||||
| #define AUDIO_NO_FREE_SOURCE -1 | #define AUDIO_NO_FREE_SOURCE -1 | ||||||
| typedef struct AudioSourceEntry | typedef struct AudioSourceEntry | ||||||
| { | { | ||||||
| 	u32 id; | 	u32 id; | ||||||
| 	i32 nextFreeIndex; | 	b32 isFree; | ||||||
| } AudioSourceEntry; | } AudioSourceEntry; | ||||||
| 
 | 
 | ||||||
|  | // TODO(doyle): Incorporate memory arena into managers?
 | ||||||
| #define AUDIO_MAX_SOURCES 32 | #define AUDIO_MAX_SOURCES 32 | ||||||
| typedef struct AudioManager | typedef struct AudioManager | ||||||
| { | { | ||||||
| 	// NOTE(doyle): Source entries point to the next free index
 | 	// NOTE(doyle): Source entries point to the next free index
 | ||||||
| 	AudioSourceEntry sourceList[AUDIO_MAX_SOURCES]; | 	AudioSourceEntry sourceList[AUDIO_MAX_SOURCES]; | ||||||
| 	i32 freeSourceIndex; |  | ||||||
| 
 |  | ||||||
| } AudioManager; | } AudioManager; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -36,15 +38,15 @@ typedef struct AudioRenderer | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| const i32 audio_init(AudioManager *audioManager); | const i32 audio_init(AudioManager *audioManager); | ||||||
| const i32 audio_streamPlayVorbis(AudioManager *audioManager, | const i32 audio_streamPlayVorbis(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                                  AudioRenderer *audioRenderer, |                                  AudioRenderer *audioRenderer, | ||||||
|                                  AudioVorbis *vorbis, i32 numPlays); |                                  AudioVorbis *vorbis, i32 numPlays); | ||||||
| const i32 audio_streamStopVorbis(AudioManager *audioManager, | const i32 audio_streamStopVorbis(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                                  AudioRenderer *audioRenderer); |                                  AudioRenderer *audioRenderer); | ||||||
| const i32 audio_streamPauseVorbis(AudioManager *audioManager, | const i32 audio_streamPauseVorbis(AudioManager *audioManager, | ||||||
|                                   AudioRenderer *audioRenderer); |                                   AudioRenderer *audioRenderer); | ||||||
| const i32 audio_streamResumeVorbis(AudioManager *audioManager, | const i32 audio_streamResumeVorbis(AudioManager *audioManager, | ||||||
|                                    AudioRenderer *audioRenderer); |                                    AudioRenderer *audioRenderer); | ||||||
| const i32 audio_updateAndPlay(AudioManager *audioManager, | const i32 audio_updateAndPlay(MemoryArena *arena, AudioManager *audioManager, | ||||||
|                               AudioRenderer *audioRenderer); |                               AudioRenderer *audioRenderer); | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -55,6 +55,11 @@ INTERNAL inline v2 V2(const f32 x, const f32 y) | |||||||
| 	v2 result = {x, y}; | 	v2 result = {x, y}; | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  | INTERNAL inline v3 V3i(const i32 x, const i32 y, const i32 z) | ||||||
|  | { | ||||||
|  | 	v3 result = {CAST(f32)x, CAST(f32)y, CAST(f32)z}; | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
| INTERNAL inline v3 V3(const f32 x, const f32 y, const f32 z) | INTERNAL inline v3 V3(const f32 x, const f32 y, const f32 z) | ||||||
| { | { | ||||||
| 	v3 result = {x, y, z}; | 	v3 result = {x, y, z}; | ||||||
|  | |||||||
| @ -15,7 +15,6 @@ typedef struct MemoryArena MemoryArena; | |||||||
| #define NUM_KEYS 1024 | #define NUM_KEYS 1024 | ||||||
| #define METERS_TO_PIXEL 240 | #define METERS_TO_PIXEL 240 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| typedef struct World | typedef struct World | ||||||
| { | { | ||||||
| 	Entity *entities; | 	Entity *entities; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user