marioparty4/src/msm/msmmus.c
2025-01-15 23:40:36 -06:00

443 lines
14 KiB
C
Executable file

#include "msm/msmmus.h"
#include "msm/msmmem.h"
typedef struct MusPlayer_s {
/* 0x00 */ s16 musId;
/* 0x02 */ s8 baseVol;
/* 0x03 */ s8 vol;
/* 0x04 */ s8 status;
/* 0x05 */ s8 busyF;
/* 0x08 */ SND_SEQID seqId;
/* 0x0C */ void* songBuf;
/* 0x10 */ void* arrfile;
/* 0x14 */ volatile s32 fadeMaxTime;
/* 0x18 */ s32 fadeTime;
/* 0x1C */ s8 fadeVol;
/* 0x20 */ volatile s32 pauseOnMaxTime;
/* 0x24 */ s32 pauseOnTime;
/* 0x28 */ s8 pauseOnVol;
/* 0x2C */ volatile s32 pauseOffMaxTime;
/* 0x30 */ s32 pauseOffTime;
/* 0x28 */ s8 pauseOffVol;
/* 0x35 */ volatile s8 startVol;
/* 0x36 */ s8 targetVol;
/* 0x38 */ SND_PLAYPARA playPara;
} MUS_PLAYER; // Size 0x58
static struct {
/* 0x000 */ s16 musMax;
/* 0x002 */ s8 musChanMax;
/* 0x003 */ s8 baseGrpNumPlay;
/* 0x004 */ s8 numPlay;
/* 0x008 */ s32 msmEntryNum;
/* 0x00C */ MSM_MUS *musData;
/* 0x010 */ s32 dummyMusOfs;
/* 0x014 */ void* musBuf;
/* 0x018 */ MUS_PLAYER player[4];
} mus;
static void msmMusPauseSub(MUS_PLAYER* player, BOOL pause, s32 speed) {
s32 time;
time = speed / 15;
if (pause) {
if (player->status == MSM_MUS_PLAY) {
if (time != 0) {
player->pauseOnTime = time;
player->pauseOnMaxTime = time;
player->pauseOnVol = 127;
} else {
sndSeqPause(player->seqId);
player->pauseOnVol = 0;
}
player->status = MSM_MUS_PAUSE;
}
} else {
if (player->status == MSM_MUS_PAUSE) {
if (time != 0) {
if (player->pauseOnMaxTime != 0) {
player->pauseOnMaxTime = -time;
} else {
sndSeqContinue(player->seqId);
player->pauseOnMaxTime = -time;
player->pauseOnTime = 0;
player->pauseOnVol = 0;
}
} else {
sndSeqContinue(player->seqId);
player->pauseOnVol = 127;
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
player->status = MSM_MUS_PLAY;
}
}
}
static void msmMusPauseFade(MUS_PLAYER *player) {
if (player->pauseOnMaxTime > 0) {
if (--player->pauseOnTime == 0) {
player->pauseOnMaxTime = 0;
player->pauseOnVol = 0;
sndSeqPause(player->seqId);
} else {
player->pauseOnVol = player->pauseOnTime * 127 / player->pauseOnMaxTime;
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
} else if (player->pauseOnMaxTime < 0) {
if (++player->pauseOnTime >= -player->pauseOnMaxTime) {
player->pauseOnMaxTime = 0;
player->pauseOnVol = 127;
} else {
player->pauseOnVol = player->pauseOnTime * 127 / -player->pauseOnMaxTime;
}
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
}
static void msmMusFade(MUS_PLAYER *player) {
if (player->status != MSM_MUS_PLAY) {
return;
}
if (player->fadeMaxTime > 0) {
if (--player->fadeTime == 0) {
if (player->status != 0) {
player->fadeMaxTime = 0;
if (player->fadeMaxTime != 0) {
player->fadeTime = player->fadeMaxTime;
player->fadeVol = 127;
} else {
sndSeqStop(player->seqId);
player->status = 1;
}
}
} else {
player->fadeVol = player->fadeTime * 127 / player->fadeMaxTime;
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
} else if (player->fadeMaxTime < 0) {
if (++player->fadeTime >= -player->fadeMaxTime) {
player->fadeMaxTime = 0;
player->fadeVol = 127;
} else {
player->fadeVol = player->fadeTime * 127 / -player->fadeMaxTime;
}
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
}
void msmMusFdoutEnd(void) {
}
void msmMusPeriodicProc(void) {
s32 i;
MUS_PLAYER* player;
mus.numPlay = mus.baseGrpNumPlay = 0;
for (i = 0; i < mus.musChanMax; i++) {
player = &mus.player[i];
if (player->busyF != FALSE) {
continue;
}
switch (player->status) {
case MSM_MUS_STOP:
case MSM_MUS_PLAY:
if (sndSeqGetValid(player->seqId) == FALSE) {
player->status = 0;
}
break;
}
if (player->status == MSM_MUS_DONE) {
continue;
}
if (msmSysCheckBaseGroup(mus.musData[player->musId].sgid) != 0) {
mus.numPlay++;
} else {
mus.baseGrpNumPlay++;
}
msmMusPauseFade(player);
if (player->status == MSM_MUS_PLAY && player->pauseOffMaxTime != 0) {
if (++player->pauseOffTime >= player->pauseOffMaxTime) {
player->pauseOffMaxTime = 0;
player->baseVol = player->targetVol;
} else {
player->baseVol = player->startVol + player->pauseOffTime * (player->targetVol - player->startVol) / player->pauseOffMaxTime;
}
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
msmMusFade(player);
}
}
s32 msmMusGetMidiCtrl(int musNo, s32 channel, s32 ctrl) {
MUS_PLAYER *player;
if (musNo < 0 || musNo >= mus.musChanMax) {
return MSM_ERR_OUTOFMUS;
}
player = &mus.player[musNo];
if (sndSeqGetValid(player->seqId) == TRUE) {
return sndSeqGetMidiCtrl(player->seqId, channel & 0xF, ctrl);
}
return 0;
}
s32 msmMusGetNumPlay(BOOL baseGrp) {
switch (baseGrp) {
case FALSE:
return mus.baseGrpNumPlay + mus.numPlay;
default:
return mus.baseGrpNumPlay;
}
}
s32 msmMusGetStatus(int musNo) {
if (musNo < 0 || musNo >= mus.musChanMax) {
return MSM_ERR_OUTOFMUS;
}
return mus.player[musNo].status;
}
void msmMusSetMasterVolume(s32 vol) {
sndMasterVolume(vol & 127, 0, 1, 0);
}
s32 msmMusSetParam(s32 musNo, MSM_MUSPARAM *param) {
MUS_PLAYER* player;
if (musNo < 0 || musNo >= mus.musChanMax) {
return MSM_ERR_OUTOFMUS;
}
player = &mus.player[musNo];
if (param->flag & MSM_MUSPARAM_VOL) {
player->pauseOffMaxTime = param->fadeSpeed / 15;
if (player->pauseOffMaxTime != 0) {
player->busyF = 1;
player->pauseOffTime = 0;
player->startVol = player->baseVol;
player->targetVol = param->vol & 127;
player->busyF = 0;
} else {
player->baseVol = param->vol & 127;
sndSeqVolume(player->baseVol * player->vol * player->fadeVol * player->pauseOnVol / (127*127*127), 0, player->seqId, 0);
}
}
if (param->flag & MSM_MUSPARAM_SPEED) {
sndSeqSpeed(player->seqId, (param->speed << 8) / 100);
}
return 0;
}
void msmMusPauseAll(BOOL pause, s32 speed) {
s32 var_r27;
MUS_PLAYER* player;
for (var_r27 = 0; var_r27 < mus.musChanMax; var_r27++) {
player = &mus.player[var_r27];
if (player->status != MSM_MUS_DONE) {
player->busyF = TRUE;
msmMusPauseSub(player, pause, speed);
player->busyF = FALSE;
}
}
}
s32 msmMusPause(int musNo, BOOL pause, s32 speed) {
MUS_PLAYER *player;
if (musNo < 0 || musNo >= mus.musChanMax) {
return MSM_ERR_OUTOFMUS;
}
player = &mus.player[musNo];
player->busyF = TRUE;
msmMusPauseSub(player, pause, speed);
player->busyF = FALSE;
return 0;
}
void msmMusStopAll(BOOL checkGrp, s32 speed) {
s32 i;
MUS_PLAYER *player;
for (i = 0; i < mus.musChanMax; i++) {
player = &mus.player[i];
if (player->status == 0) {
continue;
}
player->busyF = TRUE;
switch (checkGrp) {
case FALSE:
if (player->status != 0) {
player->fadeMaxTime = speed / 15;
if (player->fadeMaxTime != 0) {
player->fadeTime = player->fadeMaxTime;
player->fadeVol = 127;
} else {
sndSeqStop(player->seqId);
player->status = 1;
}
}
break;
default:
if (msmSysCheckBaseGroup(mus.musData[player->musId].sgid) == 0 && player->status != 0) {
player->fadeMaxTime = speed / 15;
if (player->fadeMaxTime != 0) {
player->fadeTime = player->fadeMaxTime;
player->fadeVol = 127;
} else {
sndSeqStop(player->seqId);
player->status = 1;
}
}
break;
}
player->busyF = FALSE;
}
}
s32 msmMusStop(int musNo, s32 speed) {
MUS_PLAYER* player;
if (musNo < 0 || musNo >= mus.musChanMax) {
return MSM_ERR_OUTOFMUS;
}
player = &mus.player[musNo];
player->busyF = TRUE;
if (player->status != 0) {
player->fadeMaxTime = speed / 15;
if (player->fadeMaxTime != 0) {
player->fadeTime = player->fadeMaxTime;
player->fadeVol = 127;
} else {
sndSeqStop(player->seqId);
player->status = MSM_MUS_STOP;
}
}
player->busyF = FALSE;
return 0;
}
int msmMusPlay(int musId, MSM_MUSPARAM* musParam) {
s32 var_r30;
int var_r29;
s32 temp_r3_3;
MSM_GRP_HEAD* temp_r3_2;
MSM_MUS* temp_r28;
MUS_PLAYER* temp_r27;
DVDFileInfo sp10;
if (musId < 0 || musId >= mus.musMax) {
return MSM_ERR_INVALIDID;
}
temp_r28 = &mus.musData[musId];
if (temp_r28->sgid == 0xFFFF) {
return MSM_ERR_REMOVEDID;
}
if (msmSysCheckLoadGroupID(temp_r28->sgid) == 0) {
return MSM_ERR_GRP_NOTLOADED;
}
var_r30 = (musParam != NULL) ? musParam->flag : 0;
var_r29 = (var_r30 & MSM_MUSPARAM_CHAN) ? musParam->chan : 0;
if (var_r29 < 0 || var_r29 >= mus.musChanMax) {
return MSM_ERR_OUTOFMUS;
}
temp_r27 = &mus.player[var_r29];
if (temp_r27->status != 0) {
sndSeqStop(temp_r27->seqId);
}
if (temp_r28->songGrp < 0) {
if (temp_r27->musId != musId) {
if (msmFioOpen(mus.msmEntryNum, &sp10) != 1) {
return MSM_ERR_OPENFAIL;
}
if (msmFioRead(&sp10, temp_r27->songBuf, temp_r28->songSize, temp_r28->songOfs + mus.dummyMusOfs) < 0) {
msmFioClose(&sp10);
return MSM_ERR_READFAIL;
}
msmFioClose(&sp10);
temp_r27->arrfile = temp_r27->songBuf;
}
} else {
temp_r3_2 = msmSysGetGroupDataPtr(temp_r28->songGrp);
if (temp_r3_2 == NULL) {
return MSM_ERR_MUSGRP_NOTLOADED;
}
temp_r27->arrfile = (void*) ((u32) temp_r3_2 + temp_r3_2->sngOfs + temp_r28->songOfs);
}
temp_r27->busyF = 1;
temp_r27->vol = temp_r28->vol;
temp_r27->pauseOffMaxTime = 0;
temp_r27->pauseOnMaxTime = 0;
temp_r27->fadeMaxTime = 0;
temp_r27->pauseOnVol = 127;
temp_r27->fadeVol = 127;
temp_r27->playPara.flags = 4;
temp_r27->playPara.volume.time = 0;
temp_r27->baseVol = (var_r30 & MSM_MUSPARAM_VOL) ? musParam->vol : 127;
temp_r27->playPara.volume.target = temp_r27->vol * temp_r27->fadeVol * temp_r27->baseVol / 16129;
if (var_r30 & MSM_MUSPARAM_PAUSE) {
temp_r27->playPara.flags |= 0x10;
}
if (var_r30 & MSM_MUSPARAM_SPEED) {
temp_r27->playPara.flags |= 2;
temp_r27->playPara.speed = musParam->speed * 256 / 100;
}
if (var_r30 & MSM_MUSPARAM_FADESPEED) {
temp_r27->fadeMaxTime = -(musParam->fadeSpeed / 15);
if (temp_r27->fadeMaxTime != 0) {
temp_r27->fadeTime = 0;
temp_r27->fadeVol = 0;
temp_r27->playPara.volume.target = 0;
}
}
temp_r3_3 = sndSeqPlay(temp_r28->sgid, temp_r28->sid, temp_r27->arrfile, &temp_r27->playPara);
if (temp_r3_3 == SND_ID_ERROR) {
temp_r27->busyF = 0;
return MSM_ERR_PLAYFAIL;
}
temp_r27->seqId = temp_r3_3;
temp_r27->musId = musId;
temp_r27->status = (temp_r27->playPara.flags & 0x10) ? 3 : 2;
temp_r27->busyF = 0;
return var_r29;
}
s32 msmMusInit(MSM_SYS* arg0, DVDFileInfo* arg1) {
s32 temp_r4;
s32 var_r8;
mus.musMax = 0;
mus.musChanMax = 0;
mus.numPlay = 0;
mus.baseGrpNumPlay = 0;
if (arg0->info->musMax == 0) {
return 0;
}
temp_r4 = arg0->header->musSize;
if (temp_r4 == 0) {
return 0;
}
if ((mus.musData = msmMemAlloc(temp_r4)) == NULL) {
return MSM_ERR_OUTOFMEM;
}
if (msmFioRead(arg1, mus.musData, arg0->header->musSize, arg0->header->musOfs) < 0) {
return MSM_ERR_READFAIL;
}
temp_r4 = arg0->info->dummyMusSize;
if (temp_r4 != 0) {
if ((mus.musBuf = msmMemAlloc(temp_r4 * arg0->info->musChanMax)) == NULL) {
return MSM_ERR_OUTOFMEM;
}
} else {
mus.musBuf = NULL;
}
mus.musMax = arg0->info->musMax;
mus.musChanMax = arg0->info->musChanMax;
mus.dummyMusOfs = arg0->header->dummyMusOfs;
mus.msmEntryNum = arg0->msmEntryNum;
for (var_r8 = 0; var_r8 < mus.musChanMax; var_r8++) {
mus.player[var_r8].songBuf = (void*) ((u32) mus.musBuf + arg0->info->dummyMusSize * var_r8);
mus.player[var_r8].musId = -1;
mus.player[var_r8].busyF = 0;
}
return 0;
}