#include <ultra64.h>
#include "functions.h"
#include "variables.h"
#include "version.h"
#include "core1/core1.h"
void func_8025AE50(s32, f32);
void func_8025AC20(enum comusic_e, s32, s32, f32, char*, s32);
void func_8025AC7C(enum comusic_e, s32, s32, f32, void *, const char *, s32);
void func_8025A7DC(enum comusic_e);
CoMusic *comusicTracks = NULL;
bool sProcessVolumeChange = FALSE;
* @brief returns a pointer to the CoMusic struct with the corresponding track_id
* if it exists OR the first free CoMusic struct. This also skips the first CoMusic in the search.
*
* @param track_id
* @return CoMusic*
*/
CoMusic *comusic_findTrack(enum comusic_e track_id) {
CoMusic *i_ptr, *first_free = NULL;
for (i_ptr = &comusicTracks[1]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS - 1]; i_ptr++) {
if (i_ptr->track_id == track_id) {
return i_ptr;
}
if ((first_free == NULL) && (i_ptr->track_id < 0)) {
first_free = i_ptr;
}
}
return first_free;
}
void comusic_func_80259914(CoMusic *this, s32 arg1, s32 arg2) {
s32 sp2C;
s32 i;
struct12s *tmp;
freelist_clear(this->unk18);
for(i = 0; i < 0xE; i++){
this->unk1C[i] = 0;
}
tmp = (struct12s *)freelist_next(&this->unk18, &sp2C);
tmp->volume_1 = arg1;
tmp->volume_2 = arg2;
}
void comusic_func_80259994(CoMusic *this, s32 volume) {
comusic_func_80259914(this, volume, volume);
}
void comusic_func_802599B4(CoMusic *this) {
comusic_func_80259994(this, gcMusic_getDefaultVolumeForTrack(this->track_id));
this->track_id = -1;
this->unk14 = 0;
this->unk15 = FALSE;
musicSlot_func_8024FC1C(this - comusicTracks, -1);
}
void coMusicPlayer_init(void) {
CoMusic *i_ptr;
int i;
if (comusicTracks != NULL) {
coMusicPlayer_free();
}
comusicTracks = (CoMusic *) bk_malloc(NUM_MUSIC_SLOTS * sizeof(CoMusic));
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
i_ptr->track_id = -1;
i_ptr->volume = 0;
i_ptr->volume_change = 0;
i_ptr->destination_volume = 0;
i_ptr->unk4 = 0.0f;
i_ptr->unk14 = 0;
i_ptr->unk15 = FALSE;
i_ptr->volume_change_wait_timer = 0.0f;
i_ptr->unk18 = (FREE_LIST(struct12s) *) freelist_new(sizeof(struct12s), 4);
for (i = 0; i < 0xE; i++) {
i_ptr->unk1C[i] = 0;
}
}
}
void coMusicPlayer_free(void) {
CoMusic *i_ptr;
musicSlot_stopAll();
musicTrack_releaseAll();
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
freelist_free(i_ptr->unk18);
}
bk_free(comusicTracks);
comusicTracks = NULL;
}
s32 coMusicPlayer_getTrackCount(void) {
CoMusic *i_ptr;
s32 count = 0;
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id >= 0) {
count++;
}
}
return count;
}
void coMusicPlayer_update(void) {
s32 music_slot;
CoMusic *i_ptr;
f32 dt;
dt = time_getDelta();
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id >= 0) {
music_slot = i_ptr - comusicTracks;
i_ptr->unk4 = ml_min_f(i_ptr->unk4 + dt, 600.0f);
if ((i_ptr->unk4 > 1.0f) && musicSlot_hasStopped(music_slot)) {
func_8025A7DC(i_ptr->track_id);
}
}
}
func_8024FF34();
if (!sProcessVolumeChange) {
return;
}
sProcessVolumeChange = FALSE;
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id < 0) {
continue;
}
if (i_ptr->volume_change != 0) {
music_slot = i_ptr - comusicTracks;
if (i_ptr->volume_change_wait_timer > 0.0f) {
i_ptr->volume_change_wait_timer -= time_getDelta();
sProcessVolumeChange = TRUE;
continue;
}
if (i_ptr->volume_change < 0) {
i_ptr->volume += i_ptr->volume_change;
if (i_ptr->unk15 && (i_ptr->destination_volume == 0) && (i_ptr->volume <= 0)) {
comusic_func_802599B4(i_ptr);
continue;
} else {
if (i_ptr->volume <= i_ptr->destination_volume) {
i_ptr->volume = i_ptr->destination_volume;
i_ptr->volume_change = 0;
} else {
sProcessVolumeChange = TRUE;
}
musicSlot_setVolume(music_slot, i_ptr->volume);
}
continue;
}
if (i_ptr->volume < i_ptr->destination_volume) {
if (i_ptr->volume == 0) {
i_ptr->unk4 = 0.0f;
}
i_ptr->volume += i_ptr->volume_change;
if (i_ptr->volume >= i_ptr->destination_volume) {
i_ptr->volume = i_ptr->destination_volume;
i_ptr->volume_change = 0;
} else {
sProcessVolumeChange = TRUE;
}
musicSlot_setVolume(music_slot, i_ptr->volume);
continue;
}
i_ptr->volume_change = 0;
}
}
}
void func_80259EA8(CoMusic *this, s32 *arg1, s32 *arg2){
int i;
int cnt = freelist_size(this->unk18);
s32 tmp_s1 = 0x7FFF;
s32 tmp_s2 = 0x40000000;
struct12s *tmp_ptr;
for(i = 1; i < cnt; i++){
if (freelist_elementIsAlive(this->unk18, i)) {
tmp_ptr = (struct12s*)freelist_at(this->unk18, i);
if (tmp_ptr->volume_1 < tmp_s1 || (tmp_s1 == tmp_ptr->volume_1 && tmp_ptr->volume_2 < tmp_s2)) {
tmp_s1 = tmp_ptr->volume_1;
tmp_s2 = tmp_ptr->volume_2;
}
}
}
*arg1 = tmp_s1;
*arg2 = tmp_s2;
}
void func_80259F7C(CoMusic *self, s32 *arg1, s32 *arg2, s32 *arg3) {
struct12s *temp_v0;
f32 pad;
s32 sp34;
s32 var_s2;
var_s2 = *arg1;
sp34 = *arg2;
if ((*arg3 != 0) && !freelist_elementIsAlive(self->unk18, *arg3)) {
*arg3 = 0;
}
if (var_s2 < 0) {
temp_v0 = (struct12s *)freelist_at(self->unk18, 1);
if (temp_v0->volume_1 < gcMusic_getDefaultVolumeForTrack(self->track_id)) {
var_s2 = gcMusic_getDefaultVolumeForTrack(self->track_id);
} else {
var_s2 = temp_v0->volume_1;
}
if (*arg3 != 0) {
temp_v0 = (struct12s *)freelist_at(self->unk18, *arg3);
*arg2 = temp_v0->volume_2;
freelist_freeElement(self->unk18, *arg3);
*arg3 = 0;
func_80259EA8(self, arg1, &sp34);
return;
}
}
if (*arg3 == 0) {
temp_v0 = (struct12s *)freelist_at(self->unk18, 1);
if ((temp_v0->volume_1 < var_s2) || ((var_s2 == temp_v0->volume_1) && (sp34 >= temp_v0->volume_2))) {
comusic_func_80259914(self, var_s2, sp34);
} else {
freelist_next(&self->unk18, arg3);
}
}
if (*arg3 != 0) {
temp_v0 = (struct12s *)freelist_at(self->unk18, *arg3);
temp_v0->volume_1 = var_s2;
temp_v0->volume_2 = sp34;
}
func_80259EA8(self, arg1, arg2);
}
void func_8025A104(enum comusic_e track_id, s32 volume) {
if (track_id != comusicTracks[0].track_id) {
musicSlot_func_8024FC1C(0, track_id);
}
musicSlot_setVolume(0, volume);
comusicTracks[0].track_id = (s16) track_id;
comusicTracks[0].volume = volume;
comusicTracks[0].volume_change_wait_timer = 0.0f;
comusicTracks[0].volume_change = 0;
comusicTracks[0].unk4 = 0.0f;
comusicTracks[0].unk15 = FALSE;
comusic_func_80259994(&comusicTracks[0], volume);
}
void func_8025A1A8(enum comusic_e arg0){
if (arg0 == comusicTracks[0].track_id) {
return;
}
musicSlot_func_8024FC1C(0, arg0);
comusicTracks[0].track_id = (s16) arg0;
comusicTracks[0].volume = gcMusic_getDefaultVolumeForTrack(arg0);
comusicTracks[0].volume_change_wait_timer = 0.0f;
comusicTracks[0].volume_change = 0;
comusicTracks[0].unk4 = 0.0f;
comusicTracks[0].unk15 = FALSE;
comusic_func_80259994(&comusicTracks[0], comusicTracks[0].volume);
}
void func_8025A23C(enum comusic_e track_id) {
CoMusic *last_music_track = &comusicTracks[NUM_MUSIC_SLOTS - 1];
s32 volume;
if (track_id == last_music_track->track_id){
return;
}
musicSlot_func_8024FC1C(NUM_MUSIC_SLOTS - 1, track_id);
last_music_track->track_id = (s16) track_id;
volume = gcMusic_getDefaultVolumeForTrack(track_id);
last_music_track->volume = volume;
last_music_track->volume_change = 0;
last_music_track->unk15 = FALSE;
last_music_track->volume_change_wait_timer = 0.0f;
last_music_track->unk4 = 0.0f;
comusic_func_80259994(last_music_track, volume);
}
void func_8025A2B0(void) {
comusic_func_802599B4(&comusicTracks[NUM_MUSIC_SLOTS - 1]);
}
void func_8025A2D8(void) {
comusic_func_802599B4(&comusicTracks[0]);
}
void func_8025A2FC(s32 arg0, s32 arg1){
s32 i;
func_8025A55C(arg0, arg1, 1);
for (i = 1; i < NUM_MUSIC_SLOTS - 1; i++){
s16 val = comusicTracks[i].track_id;
if (val >= 0){
func_8025ABB8(val, arg0, arg1, 1);
}
}
}
void func_8025A388(s32 arg0, s32 arg1) {
s32 i;
if (comusicTracks->unk14 == 0){
func_8025A55C(arg0, arg1, 1);
}
for (i = 1; i < NUM_MUSIC_SLOTS - 1; i++) {
if (comusicTracks[i].track_id >= 0 && comusicTracks[i].unk14 == 0) {
func_8025ABB8(comusicTracks[i].track_id, arg0, arg1, 1);
}
}
}
void func_8025A430(s32 arg0, s32 arg1, s32 arg2){
s32 i;
func_8025A55C(arg0, arg1, arg2);
for (i = 1; i < NUM_MUSIC_SLOTS - 1; i++) {
s16 val = comusicTracks[i].track_id;
if (val >= 0) {
func_8025ABB8(val, arg0, arg1, arg2);
}
}
}
void func_8025A4C4(s32 arg0, s32 arg1, s32 *arg2) {
if (comusicTracks[0].track_id < 0) {
return;
}
func_80259F7C(&comusicTracks[0], &arg0, &arg1, arg2);
if (arg0 != comusicTracks[0].volume) {
if (comusicTracks[0].volume < arg0) {
comusicTracks[0].volume_change = arg1;
} else {
comusicTracks[0].volume_change = -arg1;
}
comusicTracks[0].destination_volume = arg0;
sProcessVolumeChange = TRUE;
}
}
void func_8025A55C(s32 arg0, s32 arg1, s32 arg2) {
func_8025A4C4(arg0, arg1, &comusicTracks->unk1C[arg2]);
}
void func_8025A58C(u32 arg0, u32 arg1) {
func_8025A55C(arg0, arg1, 0);
}
void comusic_playMusic(enum comusic_e track_id, s32 volume, bool force_reinit) {
CoMusic *track;
s32 index;
if (volume == -1) {
volume = gcMusic_getDefaultVolumeForTrack(track_id);
}
track = comusic_findTrack(track_id);
if (track == NULL) {
return;
}
index = track - comusicTracks;
if (track->track_id < 0 || force_reinit) {
switch (track_id) {
case COMUSIC_15_EXTRA_LIFE_COLLECTED:
if (gsworld_getMap() == MAP_10_BGS_MR_VILE) {
break;
}
case COMUSIC_3B_MINIGAME_VICTORY:
case COMUSIC_3C_MINIGAME_LOSS:
func_8025AE50(4000, 2.0f);
}
track->track_id = track_id;
track->volume_change = 0;
track->unk15 = FALSE;
track->unk4 = 0.0f;
comusic_func_80259994(track, volume);
musicSlot_func_8024FC1C(index, track_id);
}
musicSlot_setVolume(index, volume);
track->volume = volume;
}
void coMusicPlayer_playMusicWeak(enum comusic_e track_id, s32 volume) {
comusic_playMusic(track_id, volume, FALSE);
}
void coMusicPlayer_playMusic(enum comusic_e track_id, s32 volume) {
comusic_playMusic(track_id, volume, TRUE);
}
void comusic_playTrack(enum comusic_e track_id) {
CoMusic *trackPtr;
s32 indx;
trackPtr = comusic_findTrack(track_id);
if (trackPtr == NULL) {
return;
}
indx = trackPtr - comusicTracks;
if (trackPtr->track_id < 0) {
trackPtr->track_id = track_id;
trackPtr->volume_change = 0;
trackPtr->unk4 = 0.0f;
musicSlot_func_8024FC1C( indx, track_id);
comusic_func_80259994(trackPtr, trackPtr->volume = gcMusic_getDefaultVolumeForTrack(track_id));
}
}
void func_8025A788(enum comusic_e track_id, f32 delay1, f32 delay2) {
timedFunc_set_1(delay1, (GenFunction_1) comusic_playTrack, track_id);
timedFunc_set_1(delay1 + delay2, (GenFunction_1) func_8025A7DC, track_id);
}
void func_8025A7DC(enum comusic_e track_id) {
CoMusic *trackPtr;
trackPtr = comusic_findTrack(track_id);
if (trackPtr != NULL && trackPtr->track_id >= 0){
comusic_func_802599B4(trackPtr);
}
}
s32 func_8025A818(void) {
if (comusicTracks[0].destination_volume == 0 && comusicTracks[0].volume <= 0){
comusic_func_802599B4(&comusicTracks[0]);
return 1;
}
return 0;
}
s32 func_8025A864(enum comusic_e track_id){
CoMusic *trackPtr;
trackPtr = comusic_findTrack(track_id);
if (trackPtr != NULL && trackPtr->destination_volume == 0 && trackPtr->volume <= 0){
comusic_func_802599B4(trackPtr);
return 1;
}
return 0;
}
void func_8025A8B8(enum comusic_e track_id, s32 arg1){
CoMusic *trackPtr = comusic_findTrack(track_id);
if (trackPtr != NULL){
trackPtr->unk14 = arg1;
}
}
void func_8025A8E4(s32 arg0) {
if (comusicTracks[0].track_id < 0) {
return;
}
comusicTracks[0].unk14 = arg0;
}
void func_8025A904(void){
CoMusic *i_ptr;
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id >= 0) {
comusic_func_802599B4(i_ptr);
}
}
}
void func_8025A96C(void){
CoMusic *i_ptr;
for (i_ptr = &comusicTracks[1]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id >= 0) {
comusic_func_802599B4(i_ptr);
}
}
}
void func_8025A9D4(void){
CoMusic *i_ptr;
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id >= 0 && !i_ptr->unk14) {
comusic_func_802599B4(i_ptr);
}
}
}
void func_8025AA48(void){
CoMusic *i_ptr;
for (i_ptr = &comusicTracks[1]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
if (i_ptr->track_id >= 0 && !i_ptr->unk14) {
comusic_func_802599B4(i_ptr);
}
}
}
void func_8025AABC(enum comusic_e track_id) {
CoMusic *trackPtr;
trackPtr = comusic_findTrack(track_id);
if (!trackPtr) {
return;
}
trackPtr->unk15 = TRUE;
if (!trackPtr->volume) {
comusic_func_802599B4(trackPtr);
}
}
void func_8025AB00(void) {
comusicTracks[0].unk15 = TRUE;
if (comusicTracks[0].volume){
return;
}
comusic_func_802599B4(&comusicTracks[0]);
}
void comusic_8025AB44(enum comusic_e track_id, s32 arg1, s32 arg2) {
func_8025AC20(track_id, arg1, arg2, 0.0f, "comusic.c", VER_SELECT(926, 927, 0, 0));
}
void comusic_8025AB78(enum comusic_e track_id, s32 arg1, s32 arg2, s32 *arg3) {
func_8025AC7C(track_id, arg1, arg2, 0.0f, arg3, "comusic.c", VER_SELECT(931, 932, 0, 0));
}
void func_8025ABB8(enum comusic_e track_id, s32 arg1, s32 arg2, s32 arg3) {
func_8025AC7C(track_id, arg1, arg2, 0.0f, &(comusic_findTrack(track_id)->unk1C[arg3]), "comusic.c", VER_SELECT(938, 939, 0, 0));
}
void func_8025AC20(enum comusic_e track_id, s32 arg1, s32 arg2, f32 arg3, char* arg4, s32 char5) {
func_8025AC7C(track_id, arg1, arg2, 0.0f, comusic_findTrack(track_id)->unk1C, "comusic.c", VER_SELECT(945, 946, 0, 0));
}
void func_8025AC7C(enum comusic_e track_id, s32 arg1, s32 arg2, f32 arg3, void *arg4, const char *filename, s32 arg6){
CoMusic *trackPtr;
u32 slot_index;
s32 *fadeSlot = (s32 *)arg4;
trackPtr = comusic_findTrack(track_id);
if(trackPtr == NULL)
return;
if(trackPtr->track_id < 0){
if(arg1 == 0)
return;
slot_index = (trackPtr - comusicTracks);
musicSlot_func_8024FC1C(slot_index, track_id);
trackPtr->track_id = track_id;
trackPtr->volume = 0;
trackPtr->unk15 = FALSE;
trackPtr->unk4 = 0.0f;
comusic_func_80259994(trackPtr, 0);
musicSlot_setVolume(slot_index, 0);
}
func_80259F7C(trackPtr,&arg1, &arg2, fadeSlot);
trackPtr->volume_change_wait_timer = arg3;
trackPtr->volume_change = (trackPtr->volume < arg1)? arg2: -arg2;
trackPtr->destination_volume = arg1;
sProcessVolumeChange = TRUE;
}
bool comusic_isTrackQueued(enum comusic_e track_id) {
CoMusic *track = comusic_findTrack(track_id);
return ((track == NULL) || (track->track_id == -1)) ? FALSE : TRUE;
}
bool comusic_isPrimaryTrack(enum comusic_e track_id) {
return comusicTracks[0].track_id == track_id;
}
s32 comusic_getTrackPosition(enum comusic_e track_id) {
CoMusic *track = comusic_findTrack(track_id);
return track - comusicTracks;
}
void func_8025AE0C(s32 arg0, f32 time) {
func_8025A58C(0, arg0);
timedFunc_set_2(time, (GenFunction_2)func_8025A58C, -1, arg0);
}
void func_8025AE50(s32 arg0, f32 time) {
func_8025A430(0, arg0, 6);
timedFunc_set_3(time, (GenFunction_3)func_8025A430, -1, arg0, 6);
}
void func_8025AEA0(enum comusic_e track_id, s32 arg1) {
CoMusic *track = comusic_findTrack(track_id);
if (!track) {
return;
}
musicSlot_setTempo(track - comusicTracks, arg1);
}
int func_8025AEEC(void) {
s32 out = musicSlot_func_802501A0(0, 0x6A, NULL);
if (out) {
musicSlot_func_80250170(0, 0x6A, 0);
}
return out;
}
void comusic_defrag(void) {
CoMusic *i_ptr;
if (!comusicTracks) {
return;
}
for (i_ptr = &comusicTracks[0]; i_ptr < &comusicTracks[NUM_MUSIC_SLOTS]; i_ptr++) {
i_ptr->unk18 = (FREE_LIST(struct12s) *) freelist_defrag(i_ptr->unk18);
}
comusicTracks = (CoMusic *) defrag(comusicTracks);
}