648 lines
16 KiB
C
648 lines
16 KiB
C
#include "sd_incl.h"
|
|
#include "sd_ext.h"
|
|
|
|
#include <stdio.h>
|
|
#include <libspu.h>
|
|
#include "common.h"
|
|
#include "mts/mts.h"
|
|
#include "mts/taskid.h"
|
|
#include "libfs/libfs.h"
|
|
|
|
int str_tick_count = -1;
|
|
char *dword_8009F7B8 = 0;
|
|
|
|
void StrFadeIn(unsigned int fade_speed)
|
|
{
|
|
str_fadein_time = str_volume / fade_speed;
|
|
if (!(str_volume / fade_speed))
|
|
{
|
|
str_fadein_time = 1;
|
|
}
|
|
str_fade_time = 0;
|
|
}
|
|
|
|
int StrFadeOut(unsigned int fade_speed)
|
|
{
|
|
if (str_status)
|
|
{
|
|
if (str_fade_value != str_volume)
|
|
{
|
|
str_fade_time = str_volume / fade_speed;
|
|
if (!(str_volume / fade_speed))
|
|
{
|
|
str_fade_time = 1;
|
|
}
|
|
str_fadein_time = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int StrFadeOutStop(unsigned int fade_speed)
|
|
{
|
|
if (str_status &&
|
|
(str_fade_value != str_volume || str_fadein_time))
|
|
{
|
|
str_fade_time = str_volume / fade_speed;
|
|
if (!(str_volume / fade_speed))
|
|
{
|
|
str_fade_time = 1;
|
|
}
|
|
str_fadein_time = 0;
|
|
str_load_code = -1;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
printf("Canceled STR FadeOut(%x:%x:%x)",
|
|
str_status,
|
|
str_fade_value,
|
|
str_volume);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int StartStream(void)
|
|
{
|
|
if (!str_fadein_fg)
|
|
{
|
|
str_fadein_time = 0;
|
|
str_fade_value = 0;
|
|
str_fade_time = 0;
|
|
}
|
|
str_fout_fg = 0;
|
|
str_tick_count = -1;
|
|
FS_StreamOpen();
|
|
|
|
str_header = FS_StreamGetData(2);
|
|
|
|
if (!str_header)
|
|
{
|
|
printf("Stream:File Pos Error\n");
|
|
FS_StreamClose();
|
|
return -1;
|
|
}
|
|
|
|
// Consume big-endian int from str_header
|
|
str_wave_size = str_header[0] << 24;
|
|
str_wave_size |= str_header[1] << 16;
|
|
str_wave_size |= str_header[2] << 8;
|
|
str_wave_size |= str_header[3];
|
|
|
|
str_unplay_size = str_unload_size = str_wave_size;
|
|
|
|
// Consume big-endian short from str_header
|
|
str_volume = str_header[4] << 8;
|
|
str_volume |= str_header[5];
|
|
|
|
// Consume big-endian short from str_header
|
|
str_freq = str_header[6] << 8;
|
|
str_freq |= str_header[7];
|
|
|
|
// Consume byte from str_header
|
|
if (str_header[8] == 1)
|
|
{
|
|
str_mono_fg = str_header[8];
|
|
}
|
|
else
|
|
{
|
|
str_mono_fg = 0;
|
|
}
|
|
|
|
// Consume byte from str_header
|
|
dword_800C0580 = str_header[9];
|
|
|
|
printf("StartStream(%x:vol=%x)\n", str_load_code, str_volume);
|
|
if (str_fadein_fg)
|
|
{
|
|
StrFadeWkSet();
|
|
}
|
|
|
|
keyOff(SPU_21CH | SPU_22CH);
|
|
str_mute_fg = NULL;
|
|
FS_StreamClear(str_header);
|
|
str_mute_ctr = NULL;
|
|
str_mute_status = NULL;
|
|
return 0;
|
|
}
|
|
|
|
void UserSpuIRQProc(void)
|
|
{
|
|
switch (str_status & 0x0f)
|
|
{
|
|
case 2: /* fallthrough */
|
|
case 3:
|
|
break;
|
|
|
|
case 4:
|
|
str_int_ctr = 0;
|
|
break;
|
|
|
|
case 5:
|
|
switch (str_freq)
|
|
{
|
|
case 0x800:
|
|
if ((str_int_ctr++ & 1) != 0)
|
|
{
|
|
dword_800BF270 += 0x100;
|
|
dword_800BF270 &= 0x1fff;
|
|
}
|
|
break;
|
|
|
|
case 0xc00:
|
|
if ((str_int_ctr++ & 3) != 0)
|
|
{
|
|
dword_800BF270 += 0x100;
|
|
dword_800BF270 &= 0x1fff;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dword_800BF270 += 0x100;
|
|
dword_800BF270 &= 0x1fff;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 6:
|
|
switch (str_freq)
|
|
{
|
|
case 0x800:
|
|
if ((str_int_ctr++ & 1) != 0)
|
|
{
|
|
dword_800BF270 += 0x100;
|
|
dword_800BF270 &= 0x1fff;
|
|
}
|
|
break;
|
|
|
|
case 0xc00:
|
|
if ((str_int_ctr++ & 3) != 0)
|
|
{
|
|
dword_800BF270 += 0x100;
|
|
dword_800BF270 &= 0x1fff;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
dword_800BF270 += 0x100;
|
|
dword_800BF270 &= 0x1fff;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
mts_isend(MTSID_SOUND_INT);
|
|
|
|
if ((dword_800BF1A8 & 1) == 0)
|
|
{
|
|
SpuSetIRQAddr(blank_data_addr + 256);
|
|
}
|
|
else
|
|
{
|
|
SpuSetIRQAddr(blank_data_addr);
|
|
}
|
|
|
|
dword_800BF1A8++;
|
|
SpuSetIRQ(SPU_RESET);
|
|
}
|
|
|
|
void sub_8008279C(void)
|
|
{
|
|
/* do nothing */
|
|
}
|
|
|
|
void sub_800827A4(void)
|
|
{
|
|
/* do nothing */
|
|
}
|
|
|
|
int StrSpuTransWithNoLoop(void)
|
|
{
|
|
SpuVoiceAttr attr;
|
|
int result;
|
|
int bVar1;
|
|
u_long start_addr;
|
|
|
|
result = 0;
|
|
|
|
if (dword_8009F7B8 != 0)
|
|
{
|
|
FS_StreamClear(dword_8009F7B8);
|
|
dword_8009F7B8 = 0;
|
|
}
|
|
|
|
switch (str_status & 0xf)
|
|
{
|
|
case 2:
|
|
if (dword_800BF1A4 == 0)
|
|
{
|
|
if ((se_rev_on != 0) && (str_vox_on != 0) && (vox_rev_on != 0))
|
|
{
|
|
SpuSetReverbVoice(SPU_ON, SPU_21CH | SPU_22CH);
|
|
}
|
|
else
|
|
{
|
|
SpuSetReverbVoice(SPU_OFF, SPU_21CH | SPU_22CH);
|
|
}
|
|
|
|
str_data_ptr = FS_StreamGetData(1);
|
|
|
|
if (str_data_ptr)
|
|
{
|
|
str_play_idx = 0;
|
|
str_play_offset = 0;
|
|
str_data_ptr[1] |= 0x4;
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_r);
|
|
SpuWrite(str_data_ptr, 4096);
|
|
|
|
if (str_mono_fg == 0)
|
|
{
|
|
str_play_offset = 4096;
|
|
str_unplay_size -= 4096;
|
|
}
|
|
|
|
dword_800BF1A4 = 1;
|
|
str_tick_count = -1;
|
|
}
|
|
else
|
|
{
|
|
str_status = 7;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
str_data_ptr[str_play_offset + 1] |= 0x4;
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_l);
|
|
SpuWrite(str_data_ptr + str_play_offset, 4096);
|
|
str_play_offset += 4096;
|
|
str_unplay_size -= 4096;
|
|
|
|
if (str_mono_fg == 0)
|
|
{
|
|
dword_8009F7B8 = str_data_ptr;
|
|
str_data_ptr = FS_StreamGetData(1);
|
|
|
|
if (!str_data_ptr)
|
|
{
|
|
str_status = 7;
|
|
break;
|
|
}
|
|
|
|
str_play_offset = 0;
|
|
}
|
|
|
|
dword_800BF1A4 = 0;
|
|
str_status++;
|
|
}
|
|
|
|
result = 1;
|
|
break;
|
|
|
|
case 3:
|
|
if ((str_unplay_size == 0) || (str_unplay_size < 0))
|
|
{
|
|
str_status++;
|
|
}
|
|
|
|
if (dword_800BF1A4 == 0)
|
|
{
|
|
str_data_ptr[str_play_offset + 4081] |= 0x1;
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_r + 4096);
|
|
SpuWrite(str_data_ptr + str_play_offset, 4096);
|
|
|
|
if (str_mono_fg == 0)
|
|
{
|
|
str_play_offset += 4096;
|
|
str_unplay_size -= 4096;
|
|
}
|
|
|
|
dword_800BF1A4 = 1;
|
|
result = 1;
|
|
}
|
|
else
|
|
{
|
|
str_data_ptr[str_play_offset + 4081] |= 0x1;
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_l + 4096);
|
|
SpuWrite(str_data_ptr + str_play_offset, 4096);
|
|
str_unplay_size -= 4096;
|
|
dword_8009F7B8 = str_data_ptr;
|
|
str_data_ptr = FS_StreamGetData(1);
|
|
str_play_offset = 0;
|
|
dword_800BF1A4 = 0;
|
|
result = 1;
|
|
str_status++;
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
attr.mask = SPU_VOICE_VOLL | SPU_VOICE_VOLR | SPU_VOICE_PITCH | SPU_VOICE_WDSA |
|
|
SPU_VOICE_ADSR_AMODE | SPU_VOICE_ADSR_SMODE | SPU_VOICE_ADSR_RMODE | SPU_VOICE_ADSR_AR |
|
|
SPU_VOICE_ADSR_DR | SPU_VOICE_ADSR_SR | SPU_VOICE_ADSR_RR | SPU_VOICE_ADSR_SL;
|
|
attr.voice = SPU_21CH;
|
|
attr.volume.left = 0;
|
|
attr.volume.right = 0;
|
|
attr.a_mode = SPU_VOICE_LINEARIncN;
|
|
attr.s_mode = SPU_VOICE_LINEARIncN;
|
|
attr.r_mode = SPU_VOICE_LINEARDecN;
|
|
attr.ar = 0x10;
|
|
attr.dr = 0;
|
|
attr.sr = 0;
|
|
attr.rr = 8;
|
|
attr.sl = 0xf;
|
|
attr.pitch = str_freq;
|
|
attr.addr = spu_bgm_start_ptr_r;
|
|
SpuSetVoiceAttr(&attr);
|
|
|
|
attr.mask = SPU_VOICE_VOLL | SPU_VOICE_VOLR | SPU_VOICE_PITCH | SPU_VOICE_WDSA |
|
|
SPU_VOICE_ADSR_AMODE | SPU_VOICE_ADSR_SMODE | SPU_VOICE_ADSR_RMODE | SPU_VOICE_ADSR_AR |
|
|
SPU_VOICE_ADSR_DR | SPU_VOICE_ADSR_SR | SPU_VOICE_ADSR_RR | SPU_VOICE_ADSR_SL;
|
|
attr.voice = SPU_22CH;
|
|
attr.volume.left = 0;
|
|
attr.volume.right = 0;
|
|
attr.a_mode = SPU_VOICE_LINEARIncN;
|
|
attr.s_mode = SPU_VOICE_LINEARIncN;
|
|
attr.r_mode = SPU_VOICE_LINEARDecN;
|
|
attr.ar = 0x10;
|
|
attr.dr = 0;
|
|
attr.sr = 0;
|
|
attr.rr = 8;
|
|
attr.sl = 0xf;
|
|
attr.pitch = (u_short)str_freq;
|
|
attr.addr = spu_bgm_start_ptr_l;
|
|
SpuSetVoiceAttr(&attr);
|
|
|
|
dword_800BF270 = 0;
|
|
keyOn(SPU_21CH | SPU_22CH);
|
|
str_next_idx = 4096;
|
|
mute_l_r_fg = 0;
|
|
str_tick_count = 0;
|
|
str_status++;
|
|
|
|
if ((str_unplay_size == 0) || (str_unplay_size < 0))
|
|
{
|
|
if ((str_wave_size < 0) || (str_wave_size > 768))
|
|
{
|
|
str_off_idx = (str_wave_size - 768) & ~0xff;
|
|
}
|
|
else
|
|
{
|
|
str_off_idx = 256;
|
|
}
|
|
|
|
str_status++;
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
if (str_data_ptr && (mute_l_r_fg == 0))
|
|
{
|
|
str_tick_count++;
|
|
}
|
|
|
|
if (((str_next_idx == (dword_800BF270 & 4096)) || (dword_800BF1A4 != 0)) ||
|
|
(mute_l_r_fg != 0))
|
|
{
|
|
result = 1;
|
|
|
|
if ((str_data_ptr) && (mute_l_r_fg == 0))
|
|
{
|
|
str_mute_fg = 0;
|
|
bVar1 = 0;
|
|
|
|
if (str_mono_fg != 0)
|
|
{
|
|
str_mono_offset = 0;
|
|
}
|
|
|
|
if (dword_800BF270 >= 4096u)
|
|
{
|
|
if (dword_800BF1A4 == 0)
|
|
{
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_r);
|
|
dword_800BF1A4 = 1;
|
|
}
|
|
else
|
|
{
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_l);
|
|
dword_800BF1A4 = 0;
|
|
str_next_idx = (str_next_idx + 4096) & 0x1fff;
|
|
|
|
if (str_mono_fg == 0)
|
|
{
|
|
bVar1 = 1;
|
|
}
|
|
else
|
|
{
|
|
str_mono_offset = 1;
|
|
}
|
|
}
|
|
|
|
(str_data_ptr + str_play_offset)[1] |= 4; // (temporary?) hack, maybe this was an inline like STOREL?
|
|
}
|
|
else
|
|
{
|
|
if (dword_800BF1A4 == 0)
|
|
{
|
|
dword_800BF1A4 = 1;
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_r + 4096);
|
|
}
|
|
else
|
|
{
|
|
dword_800BF1A4 = 0;
|
|
str_next_idx = (str_next_idx + 4096) & 0x1fff;
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_l + 4096);
|
|
bVar1 = 1;
|
|
|
|
if (str_mono_fg != 0)
|
|
{
|
|
str_mono_offset = 1;
|
|
}
|
|
}
|
|
|
|
(str_data_ptr + str_play_offset)[4081] |= 1; // (temporary?) hack
|
|
}
|
|
|
|
SpuWrite(str_data_ptr + str_play_offset, 4096);
|
|
|
|
if (str_mono_fg != 0)
|
|
{
|
|
if (str_mono_offset != 0)
|
|
{
|
|
str_play_offset = str_play_offset + 4096;
|
|
|
|
if (str_unplay_size > 4096u)
|
|
{
|
|
str_unplay_size -= 4096;
|
|
}
|
|
else
|
|
{
|
|
str_play_offset = 0;
|
|
|
|
str_off_idx = 4096 + dword_800BF270 + str_unplay_size;
|
|
str_off_idx &= 0xffffff00;
|
|
str_off_idx -= 0x300;
|
|
str_off_idx &= 0x1fff;
|
|
|
|
str_status++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
str_play_offset += 4096;
|
|
|
|
if (str_unplay_size > 4096u)
|
|
{
|
|
str_unplay_size -= 4096;
|
|
}
|
|
else
|
|
{
|
|
if (dword_800BF1A4 != 0)
|
|
{
|
|
printf("\nSOUND STREAMING ERROR:NO LAST LEFT DATA\n");
|
|
}
|
|
|
|
printf("str_unplay_size=%x\n", str_unplay_size);
|
|
|
|
str_play_offset = 0;
|
|
|
|
str_off_idx = 4096 + dword_800BF270 + str_unplay_size;
|
|
str_off_idx &= 0xffffff00;
|
|
str_off_idx -= 0x300;
|
|
str_off_idx &= 0x1fff;
|
|
|
|
str_status++;
|
|
}
|
|
}
|
|
|
|
if (bVar1)
|
|
{
|
|
dword_8009F7B8 = str_data_ptr;
|
|
str_data_ptr = FS_StreamGetData(1);
|
|
str_play_offset = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
str_mute_fg = 1;
|
|
printf("*");
|
|
|
|
if (dword_800BF270 >= 4096u)
|
|
{
|
|
if (mute_l_r_fg == 0)
|
|
{
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_r);
|
|
start_addr = spu_bgm_start_ptr_r;
|
|
mute_l_r_fg = 1;
|
|
}
|
|
else
|
|
{
|
|
SpuSetTransferStartAddr(spu_bgm_start_ptr_l);
|
|
start_addr = spu_bgm_start_ptr_l;
|
|
str_next_idx = (str_next_idx + 4096) & 0x1fff;
|
|
mute_l_r_fg = 0;
|
|
}
|
|
|
|
dummy_data[1] = 6;
|
|
dummy_data[4081] = 2;
|
|
SpuWrite(dummy_data, 4096);
|
|
}
|
|
else
|
|
{
|
|
if (mute_l_r_fg == 0)
|
|
{
|
|
start_addr = spu_bgm_start_ptr_r + 4096;
|
|
mute_l_r_fg = 1;
|
|
SpuSetTransferStartAddr(start_addr);
|
|
}
|
|
else
|
|
{
|
|
str_next_idx = (str_next_idx + 4096) & 0x1fff;
|
|
start_addr = spu_bgm_start_ptr_l + 4096;
|
|
mute_l_r_fg = 0;
|
|
SpuSetTransferStartAddr(start_addr);
|
|
}
|
|
|
|
dummy_data[1] = 2;
|
|
dummy_data[4081] = 3;
|
|
SpuWrite(dummy_data, 4096);
|
|
}
|
|
|
|
if ((mute_l_r_fg == 0) && (str_next_idx != 0))
|
|
{
|
|
dword_8009F7B8 = str_data_ptr;
|
|
str_data_ptr = FS_StreamGetData(1);
|
|
|
|
if ((str_data_ptr == NULL) && FS_StreamGetEndFlag())
|
|
{
|
|
str_off_idx = -1;
|
|
str_status++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FS_StreamIsForceStop())
|
|
{
|
|
str_off_idx = -1;
|
|
str_status++;
|
|
}
|
|
break;
|
|
|
|
case 6:
|
|
if ((dword_800BF270 == str_off_idx) || (str_off_idx == -1))
|
|
{
|
|
attr.mask = SPU_VOICE_ADSR_RR;
|
|
attr.voice = SPU_21CH;
|
|
attr.rr = 8;
|
|
SpuSetVoiceAttr(&attr);
|
|
|
|
attr.mask = SPU_VOICE_ADSR_RR;
|
|
attr.voice = SPU_22CH;
|
|
attr.rr = 8;
|
|
SpuSetVoiceAttr(&attr);
|
|
|
|
keyOff(SPU_21CH | SPU_22CH);
|
|
str_tick_count = -1;
|
|
str_status++;
|
|
}
|
|
else
|
|
{
|
|
str_tick_count++;
|
|
}
|
|
break;
|
|
|
|
case 7:
|
|
str_tick_count = -1;
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void StrSpuTransClose(void)
|
|
{
|
|
if (str_data_ptr)
|
|
{
|
|
FS_StreamClear(str_data_ptr);
|
|
str_data_ptr = NULL;
|
|
}
|
|
|
|
if (dword_8009F7B8)
|
|
{
|
|
FS_StreamClear(dword_8009F7B8);
|
|
dword_8009F7B8 = NULL;
|
|
}
|
|
|
|
str_mute_fg = 0;
|
|
FS_StreamClose();
|
|
}
|
|
|
|
void StrSpuTrans(void)
|
|
{
|
|
StrSpuTransWithNoLoop();
|
|
}
|