sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

port_eu.c (10057B)


      1 #include <ultra64.h>
      2 #include "internal.h"
      3 #include "load.h"
      4 #include "data.h"
      5 #include "seqplayer.h"
      6 #include "synthesis.h"
      7 
      8 #ifdef VERSION_EU
      9 
     10 #ifdef __sgi
     11 #define stubbed_printf
     12 #else
     13 #define stubbed_printf(...)
     14 #endif
     15 
     16 #define SAMPLES_TO_OVERPRODUCE 0x10
     17 #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x40
     18 
     19 #ifdef VERSION_JP
     20 typedef u16 FadeT;
     21 #else
     22 typedef s32 FadeT;
     23 #endif
     24 
     25 extern volatile u8 gAudioResetStatus;
     26 extern u8 gAudioResetPresetIdToLoad;
     27 extern OSMesgQueue *OSMesgQueues[];
     28 extern struct EuAudioCmd sAudioCmd[0x100];
     29 
     30 void func_8031D690(s32 player, FadeT fadeInTime);
     31 void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime);
     32 void decrease_sample_dma_ttls(void);
     33 s32 audio_shut_down_and_reset_step(void);
     34 void func_802ad7ec(u32);
     35 
     36 struct SPTask *create_next_audio_frame_task(void) {
     37     u32 samplesRemainingInAI;
     38     s32 writtenCmds;
     39     s32 index;
     40     OSTask_t *task;
     41     s32 flags;
     42     s16 *currAiBuffer;
     43     s32 oldDmaCount;
     44     OSMesg sp30;
     45     OSMesg sp2C;
     46 
     47     gAudioFrameCount++;
     48     if (gAudioFrameCount % gAudioBufferParameters.presetUnk4 != 0) {
     49         stubbed_printf("DAC:Lost 1 Frame.\n");
     50         return NULL;
     51     }
     52 
     53     osSendMesg(OSMesgQueues[0], (OSMesg) gAudioFrameCount, 0);
     54 
     55     gAudioTaskIndex ^= 1;
     56     gCurrAiBufferIndex++;
     57     gCurrAiBufferIndex %= NUMAIBUFFERS;
     58     index = (gCurrAiBufferIndex - 2 + NUMAIBUFFERS) % NUMAIBUFFERS;
     59     samplesRemainingInAI = osAiGetLength() / 4;
     60 
     61     if (gAiBufferLengths[index] != 0) {
     62         osAiSetNextBuffer(gAiBuffers[index], gAiBufferLengths[index] * 4);
     63     }
     64 
     65     oldDmaCount = gCurrAudioFrameDmaCount;
     66     if (oldDmaCount > AUDIO_FRAME_DMA_QUEUE_SIZE) {
     67         stubbed_printf("DMA: Request queue over.( %d )\n", oldDmaCount);
     68     }
     69     gCurrAudioFrameDmaCount = 0;
     70 
     71     decrease_sample_dma_ttls();
     72     if (osRecvMesg(OSMesgQueues[2], &sp30, 0) != -1) {
     73         gAudioResetPresetIdToLoad = (u8) (s32) sp30;
     74         gAudioResetStatus = 5;
     75     }
     76 
     77     if (gAudioResetStatus != 0) {
     78         if (audio_shut_down_and_reset_step() == 0) {
     79             if (gAudioResetStatus == 0) {
     80                 osSendMesg(OSMesgQueues[3], (OSMesg) (s32) gAudioResetPresetIdToLoad, OS_MESG_NOBLOCK);
     81             }
     82             return NULL;
     83         }
     84     }
     85 
     86     gAudioTask = &gAudioTasks[gAudioTaskIndex];
     87     gAudioCmd = gAudioCmdBuffers[gAudioTaskIndex];
     88     index = gCurrAiBufferIndex;
     89     currAiBuffer = gAiBuffers[index];
     90 
     91     gAiBufferLengths[index] = ((gAudioBufferParameters.samplesPerFrameTarget - samplesRemainingInAI +
     92          EXTRA_BUFFERED_AI_SAMPLES_TARGET) & ~0xf) + SAMPLES_TO_OVERPRODUCE;
     93     if (gAiBufferLengths[index] < gAudioBufferParameters.minAiBufferLength) {
     94         gAiBufferLengths[index] = gAudioBufferParameters.minAiBufferLength;
     95     }
     96     if (gAiBufferLengths[index] > gAudioBufferParameters.maxAiBufferLength) {
     97         gAiBufferLengths[index] = gAudioBufferParameters.maxAiBufferLength;
     98     }
     99 
    100     if (osRecvMesg(OSMesgQueues[1], &sp2C, OS_MESG_NOBLOCK) != -1) {
    101         func_802ad7ec((u32) sp2C);
    102     }
    103 
    104     flags = 0;
    105     gAudioCmd = synthesis_execute(gAudioCmd, &writtenCmds, currAiBuffer, gAiBufferLengths[index]);
    106     gAudioRandom = ((gAudioRandom + gAudioFrameCount) * gAudioFrameCount);
    107     gAudioRandom = gAudioRandom + writtenCmds / 8;
    108 
    109     index = gAudioTaskIndex;
    110     gAudioTask->msgqueue = NULL;
    111     gAudioTask->msg = NULL;
    112 
    113     task = &gAudioTask->task.t;
    114     task->type = M_AUDTASK;
    115     task->flags = flags;
    116     task->ucode_boot = rspF3DBootStart;
    117     task->ucode_boot_size = (u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart;
    118     task->ucode = rspAspMainStart;
    119     task->ucode_data = rspAspMainDataStart;
    120     task->ucode_size = 0x800; // (this size is ignored)
    121     task->ucode_data_size = (rspAspMainDataEnd - rspAspMainDataStart) * sizeof(u64);
    122     task->dram_stack = NULL;
    123     task->dram_stack_size = 0;
    124     task->output_buff = NULL;
    125     task->output_buff_size = NULL;
    126     task->data_ptr = gAudioCmdBuffers[index];
    127     task->data_size = writtenCmds * sizeof(u64);
    128     task->yield_data_ptr = NULL;
    129     task->yield_data_size = 0;
    130     return gAudioTask;
    131 }
    132 
    133 void eu_process_audio_cmd(struct EuAudioCmd *cmd) {
    134     s32 i;
    135 
    136     switch (cmd->u.s.op) {
    137         case 0x81:
    138             preload_sequence(cmd->u.s.arg2, 3);
    139             break;
    140 
    141         case 0x82:
    142         case 0x88:
    143             load_sequence(cmd->u.s.arg1, cmd->u.s.arg2, cmd->u.s.arg3);
    144             func_8031D690(cmd->u.s.arg1, cmd->u2.as_s32);
    145             break;
    146 
    147         case 0x83:
    148             if (gSequencePlayers[cmd->u.s.arg1].enabled != FALSE) {
    149                 if (cmd->u2.as_s32 == 0) {
    150                     sequence_player_disable(&gSequencePlayers[cmd->u.s.arg1]);
    151                 }
    152                 else {
    153                     seq_player_fade_to_zero_volume(cmd->u.s.arg1, cmd->u2.as_s32);
    154                 }
    155             }
    156             break;
    157 
    158         case 0xf0:
    159             gSoundMode = cmd->u2.as_s32;
    160             break;
    161 
    162         case 0xf1:
    163             for (i = 0; i < 4; i++) {
    164                 gSequencePlayers[i].muted = TRUE;
    165                 gSequencePlayers[i].recalculateVolume = TRUE;
    166             }
    167             break;
    168 
    169         case 0xf2:
    170             for (i = 0; i < 4; i++) {
    171                 gSequencePlayers[i].muted = FALSE;
    172                 gSequencePlayers[i].recalculateVolume = TRUE;
    173             }
    174             break;
    175     }
    176 }
    177 
    178 const char undefportcmd[] = "Undefined Port Command %d\n";
    179 
    180 extern OSMesgQueue *OSMesgQueues[];
    181 extern u8 D_EU_80302010;
    182 extern u8 D_EU_80302014;
    183 extern OSMesg OSMesg0;
    184 extern OSMesg OSMesg1;
    185 extern OSMesg OSMesg2;
    186 extern OSMesg OSMesg3;
    187 
    188 void seq_player_fade_to_zero_volume(s32 player, FadeT fadeOutTime) {
    189     if (fadeOutTime == 0) {
    190         fadeOutTime = 1;
    191     }
    192     gSequencePlayers[player].fadeVelocity = -(gSequencePlayers[player].fadeVolume / fadeOutTime);
    193     gSequencePlayers[player].state = 2;
    194     gSequencePlayers[player].fadeRemainingFrames = fadeOutTime;
    195 
    196 }
    197 
    198 void func_8031D690(s32 player, FadeT fadeInTime) {
    199     if (fadeInTime != 0) {
    200         gSequencePlayers[player].state = 1;
    201         gSequencePlayers[player].fadeTimerUnkEu = fadeInTime;
    202         gSequencePlayers[player].fadeRemainingFrames = fadeInTime;
    203         gSequencePlayers[player].fadeVolume = 0.0f;
    204         gSequencePlayers[player].fadeVelocity = 0.0f;
    205     }
    206 }
    207 
    208 void port_eu_init_queues(void) {
    209     D_EU_80302010 = 0;
    210     D_EU_80302014 = 0;
    211     osCreateMesgQueue(OSMesgQueues[0], &OSMesg0, 1);
    212     osCreateMesgQueue(OSMesgQueues[1], &OSMesg1, 4);
    213     osCreateMesgQueue(OSMesgQueues[2], &OSMesg2, 1);
    214     osCreateMesgQueue(OSMesgQueues[3], &OSMesg3, 1);
    215 }
    216 
    217 void func_802ad6f0(s32 arg0, s32 *arg1) {
    218     struct EuAudioCmd *cmd = &sAudioCmd[D_EU_80302010 & 0xff];
    219     cmd->u.first = arg0;
    220     cmd->u2.as_u32 = *arg1;
    221     D_EU_80302010++;
    222 }
    223 
    224 void func_802ad728(u32 arg0, f32 arg1) {
    225     func_802ad6f0(arg0, (s32*) &arg1);
    226 }
    227 
    228 void func_802ad74c(u32 arg0, u32 arg1) {
    229     func_802ad6f0(arg0, (s32*) &arg1);
    230 }
    231 
    232 void func_802ad770(u32 arg0, s8 arg1) {
    233     s32 sp1C = arg1 << 24;
    234     func_802ad6f0(arg0, &sp1C);
    235 }
    236 
    237 void func_802ad7a0(void) {
    238     osSendMesg(OSMesgQueues[1],
    239             (OSMesg)(u32)((D_EU_80302014 & 0xff) << 8 | (D_EU_80302010 & 0xff)),
    240             OS_MESG_NOBLOCK);
    241     D_EU_80302014 = D_EU_80302010;
    242 }
    243 
    244 void func_802ad7ec(u32 arg0) {
    245     struct EuAudioCmd *cmd;
    246     struct SequencePlayer *seqPlayer;
    247     struct SequenceChannel *chan;
    248     u8 end = arg0 & 0xff;
    249     u8 i = (arg0 >> 8) & 0xff;
    250 
    251     for (;;) {
    252         if (i == end) break;
    253         cmd = &sAudioCmd[i++ & 0xff];
    254 
    255         if (cmd->u.s.arg1 < SEQUENCE_PLAYERS) {
    256             seqPlayer = &gSequencePlayers[cmd->u.s.arg1];
    257             if ((cmd->u.s.op & 0x80) != 0) {
    258                 eu_process_audio_cmd(cmd);
    259             }
    260             else if ((cmd->u.s.op & 0x40) != 0) {
    261                 switch (cmd->u.s.op) {
    262                     case 0x41:
    263                         seqPlayer->fadeVolumeScale = cmd->u2.as_f32;
    264                         seqPlayer->recalculateVolume = TRUE;
    265                         break;
    266 
    267                     case 0x47:
    268                         seqPlayer->tempo = cmd->u2.as_s32 * TATUMS_PER_BEAT;
    269                         break;
    270 
    271                     case 0x48:
    272                         seqPlayer->transposition = cmd->u2.as_s8;
    273                         break;
    274 
    275                     case 0x46:
    276                         seqPlayer->seqVariationEu[cmd->u.s.arg3] = cmd->u2.as_s8;
    277                         break;
    278                 }
    279             }
    280             else if (seqPlayer->enabled != FALSE && cmd->u.s.arg2 < 0x10) {
    281                 chan = seqPlayer->channels[cmd->u.s.arg2];
    282                 if (IS_SEQUENCE_CHANNEL_VALID(chan)) {
    283                     switch (cmd->u.s.op) {
    284                         case 1:
    285                             chan->volumeScale = cmd->u2.as_f32;
    286                             chan->changes.as_bitfields.volume = TRUE;
    287                             break;
    288                         case 2:
    289                             chan->volume = cmd->u2.as_f32;
    290                             chan->changes.as_bitfields.volume = TRUE;
    291                             break;
    292                         case 3:
    293                             chan->newPan = cmd->u2.as_s8;
    294                             chan->changes.as_bitfields.pan = TRUE;
    295                             break;
    296                         case 4:
    297                             chan->freqScale = cmd->u2.as_f32;
    298                             chan->changes.as_bitfields.freqScale = TRUE;
    299                             break;
    300                         case 5:
    301                             chan->reverbVol = cmd->u2.as_s8;
    302                             break;
    303                         case 6:
    304                             if (cmd->u.s.arg3 < 8) {
    305                                 chan->soundScriptIO[cmd->u.s.arg3] = cmd->u2.as_s8;
    306                             }
    307                             break;
    308                         case 8:
    309                             chan->stopSomething2 = cmd->u2.as_s8;
    310                     }
    311                 }
    312             }
    313         }
    314 
    315         cmd->u.s.op = 0;
    316     }
    317 }
    318 
    319 void port_eu_init(void) {
    320     port_eu_init_queues();
    321 }
    322 
    323 #endif