diff options
author | Michael Panzlaff <michael.panzlaff@fau.de> | 2021-07-09 13:43:54 +0200 |
---|---|---|
committer | Michael Panzlaff <michael.panzlaff@fau.de> | 2021-08-25 18:03:48 +0200 |
commit | bedb58ea94b44f8b4168fd731339fec38ee21988 (patch) | |
tree | d4078faa96cf33be66c3b975d9ec6b57a97e0ceb /arm7/lib/src | |
parent | 5cc94282b5c8e2b991a443f9e64e91c466cb00f1 (diff) |
arm7: decompile SND_seq
Diffstat (limited to 'arm7/lib/src')
-rw-r--r-- | arm7/lib/src/SND_seq.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/arm7/lib/src/SND_seq.c b/arm7/lib/src/SND_seq.c new file mode 100644 index 00000000..3153c392 --- /dev/null +++ b/arm7/lib/src/SND_seq.c @@ -0,0 +1,266 @@ +#include "SND_seq.h" + +#include "SND_main.h" +#include "SND_work.h" +#include "SND_unk_037FD440.h" + +void SND_SeqInit(void) { + for (int i = 0; i < SND_PLAYER_COUNT; i++) { + struct SNDPlayer *ply = &SNDi_Work.players[i]; + + ply->flags.active = FALSE; + ply->playerId = (u8)i; + } + + for (int i = 0; i < SND_TRACK_COUNT; i++) { + struct SNDTrack *trk = &SNDi_Work.tracks[i]; + + trk->flags.active = FALSE; + } +} + +void SND_SeqMain(BOOL step) { + struct SNDPlayer *ply; + int i; + u32 playerStatus = 0; + + for (i = 0; i < SND_PLAYER_COUNT; i++) { + ply = &SNDi_Work.players[i]; + + if (!ply->flags.active) + continue; + + if (ply->flags.prepared) { + if (step && !ply->flags.paused) + PlayerSeqMain(ply); + PlayerUpdateChannelVolume(ply); + } + + if (ply->flags.active) + playerStatus |= 1 << i; + } + + if (SNDi_SharedWork) + SNDi_SharedWork->playerStatus = playerStatus; +} + +void SND_PrepareSeq(int player, const void *seq, u32 offset, struct SNDBankData *bankData) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + if (ply->flags.active) + PlayerStop(ply); + + PlayerSetBank(ply, bankData); + + int allocTrkIdx = AllocateTrack(); + + if (allocTrkIdx < 0) + return; + + struct SNDTrack *trk = &SNDi_Work.tracks[allocTrkIdx]; + TrackInit(trk); + TrackSetSeq(trk, seq, offset); + ply->tracks[0] = (u8)allocTrkIdx; + SeqCacheFetch(trk->cur); + + u8 cmd = SeqReadByte(trk->cur); + + trk->cur++; + + if (cmd != 0xFE) { + trk->cur--; + } else { + int track; + u16 trackMask; + + for (trackMask = (u16)(TrackReadHword(trk) >> 1), track = 1; trackMask != 0; track++, trackMask >>= 1) { + if (trackMask & 1) { + allocTrkIdx = AllocateTrack(); + if (allocTrkIdx < 0) + break; + TrackInit(&SNDi_Work.tracks[allocTrkIdx]); + ply->tracks[track] = (u8)allocTrkIdx; + } + } + } + + ply->flags.active = TRUE; + ply->flags.prepared = FALSE; + + if (SNDi_SharedWork) { + SNDi_SharedWork->playerStatus |= 1 << player; + } +} + +void SND_StartPreparedSeq(int player) { + SNDi_Work.players[player].flags.prepared = TRUE; +} + +void SND_StartSeq(int player, const void *seq, u32 offset, struct SNDBankData *bankData) { + SND_PrepareSeq(player, seq, offset, bankData); + SND_StartPreparedSeq(player); +} + +void SND_StopSeq(int player) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + if (ply->flags.active) { + PlayerStop(ply); + + if (SNDi_SharedWork) { + SNDi_SharedWork->playerStatus &= ~(1 << player); + } + } +} + +void SND_PauseSeq(int player, BOOL flag) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + ply->flags.paused = flag; + + if (flag) { + for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) { + struct SNDTrack *trk = PlayerGetTrack(ply, i); + + if (trk) { + TrackReleaseChannels(trk, ply, 127); + TrackFreeChannels(trk); + } + } + } +} + +void SND_SkipSeq(int player, u32 ticks) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER; i++) { + struct SNDTrack *trk = PlayerGetTrack(ply, i); + + if (trk) { + TrackReleaseChannels(trk, ply, 127); + TrackFreeChannels(trk); + } + } + + SND_StopIntervalTimer(); + + u32 i; + for (i = 0; i < ticks; i++) { + if (PlayerStepTicks(ply, 0)) { + PlayerStop(ply); + break; + } + } + + SND_StartIntervalTimer(); + + if (SNDi_SharedWork) { + SNDi_SharedWork->players[ply->playerId].tickCounter += i; + } +} + +void SND_SetTrackMute(int player, u32 trackMask, int muteMode) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER && trackMask != 0; i++, trackMask >>= 1) { + if (trackMask & 1) { + struct SNDTrack *trk = PlayerGetTrack(ply, i); + + if (trk) { + TrackMute(trk, ply, muteMode); + } + } + } +} + +void SND_SetTrackAllocatableChannel(int player, u32 trackMask, u32 channelMask) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER && trackMask != 0; i++, trackMask >>= 1) { + if (trackMask & 1) { + struct SNDTrack *trk = PlayerGetTrack(ply, i); + + if (trk) { + trk->channelMask = (u16)channelMask; + trk->flags.channelMask = TRUE; + } + } + } +} + +void SND_InvalidateSeq(const void *start, const void *end) { + struct SNDPlayer *ply; + struct SNDTrack *trk; + int i; + int j; + + for (i = 0; i < SND_PLAYER_COUNT; i++) { + ply = &SNDi_Work.players[i]; + + if (!ply->flags.active) + continue; + + for (j = 0; j < SND_TRACK_COUNT_PER_PLAYER; j++) { + trk = PlayerGetTrack(ply, j); + + if (!trk) + continue; + + if (start <= trk->cur && trk->cur <= end) { + PlayerStop(ply); + break; + } + } + } +} + +void SND_InvalidateBank(const void *start, const void *end) { + for (int i = 0; i < SND_PLAYER_COUNT; i++) { + struct SNDPlayer *ply = &SNDi_Work.players[i]; + + if (ply->flags.active && start <= ply->bank && ply->bank <= end) + PlayerStop(ply); + } +} + +void SNDi_SetPlayerParam(int player, u32 offset, u32 data, int size) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + switch (size) { + case 1: + *(u8 *)((u8 *)ply + offset) = (u8)data; + break; + case 2: + *(u16 *)((u8 *)ply + offset) = (u16)data; + break; + case 4: + *(u32 *)((u8 *)ply + offset) = (u32)data; + break; + } +} + +void SNDi_SetTrackParam(int player, u32 trackMask, u32 offset, u32 data, int size) { + struct SNDPlayer *ply = &SNDi_Work.players[player]; + + for (int i = 0; i < SND_TRACK_COUNT_PER_PLAYER && trackMask != 0; i++, trackMask >>= 1) { + if (!(trackMask & 1)) + continue; + + struct SNDTrack *trk = PlayerGetTrack(ply, i); + + if (!trk) + continue; + + switch (size) { + case 1: + *(u8 *)((u8 *)trk + offset) = (u8)data; + break; + case 2: + *(u16 *)((u8 *)trk + offset) = (u16)data; + break; + case 4: + *(u32 *)((u8 *)trk + offset) = (u32)data; + break; + } + } +} |