11#include " iSnd.h"
22
3- #include < types.h>
3+ #include " xSnd.h"
4+ #include " xstransvc.h"
5+ #include " xMath.h"
6+
7+ #include < dolphin/ar.h>
8+ #include < dolphin/ax.h>
9+ #include < dolphin/dvd/dvd.h>
410#include < dolphin/mix.h>
511
6- #include " intrin.h "
12+ #include < types.h >
713
8- #include " xCutscene.h"
9- #include " xSnd.h"
10- #include " xMath.h"
14+ // Size: 0x10c
15+ struct UNK_STREAMS
16+ {
17+ AXVPB* voice;
18+ U32 x4;
19+ U32 x8;
20+ U8 pad[0x8C ];
21+ DVDCommandBlock cb;
22+ U8 pad3[0x20 ];
23+ ARQRequest request;
24+ U8 pad2[0x4 ];
25+ };
26+
27+ UNK_STREAMS streams[6 ];
28+
29+ vinfo voices[58 ];
30+
31+ S32 SoundFlags;
32+ volatile S32 fc;
33+ static char soundInited;
34+ U32 houston_we_have_a_problem;
35+
36+ struct UNK_USERDATA
37+ {
38+ U32 x0;
39+ U32 flags;
40+ U32 aid;
41+ U8 pad5[0xC ];
42+ U32 x18;
43+ U8 pad[0x6C ];
44+ U32 x88;
45+ U32 x8c;
46+ U32 x90;
47+ U8 pad3[0x40 ];
48+ U32 source;
49+ U32 dest_a;
50+ U32 dest_b;
51+ U32 xe0;
52+ U32 xe4;
53+ ARQRequest request;
54+ };
55+ ARQRequest* last_ar;
56+
57+ static void dv_callback (void * userdata)
58+ {
59+ struct UNK_VOIDSTAR
60+ {
61+ U8 pad[0x14 ];
62+ U32 stream;
63+ };
64+
65+ UNK_VOIDSTAR* data = (UNK_VOIDSTAR*)userdata;
66+
67+ if (!soundInited)
68+ {
69+ return ;
70+ }
71+
72+ U32 stream = data->stream ;
73+ xSndVoiceInfo* info = &gSnd .voice [stream];
74+ info->sndID = 0 ;
75+ info->flags = 0 ;
76+ if (stream < sizeof (streams) / sizeof (UNK_STREAMS))
77+ {
78+ U32 idx = stream;
79+ if (streams[idx].voice == NULL )
80+ {
81+ return ;
82+ }
83+
84+ DVDCancelAsync (&streams[idx].cb , NULL );
85+ ARQRemoveRequest (&streams[idx].request );
86+ AXSetVoiceState (streams[idx].voice , 0 );
87+ MIXReleaseChannel (streams[idx].voice );
1188
12- extern vinfo voices[58 ];
13- extern char soundInited;
14- extern S32 SoundFlags;
15- extern F32 _1262;
16- extern F32 _1263;
17- extern volatile S32 fc;
89+ streams[idx].voice = NULL ;
90+ streams[idx].x4 = 0x40000 ;
91+ streams[idx].x8 = 0 ;
92+ }
93+ else
94+ {
95+ U32 idx = stream - sizeof (streams) / sizeof (UNK_STREAMS);
96+ if (voices[idx].voice == NULL )
97+ {
98+ return ;
99+ }
100+ MIXReleaseChannel (voices[idx].voice );
101+ AXSetVoiceState (voices[idx].voice , 0 );
102+
103+ voices[idx].voice = NULL ;
104+ voices[idx].x4 = 0 ;
105+ voices[idx].x8 = 0 ;
106+ }
107+ }
18108
19- void arq_callback (long )
109+ static void arq_callback (u32 )
20110{
21111 if (!soundInited)
22112 {
@@ -25,6 +115,144 @@ void arq_callback(long)
25115 SoundFlags = 0 ;
26116}
27117
118+ static const char * dump_flags (U32 flags)
119+ {
120+ static char str[0x40 ];
121+ memset (str, 0 , sizeof (str));
122+
123+ // TODO:
124+
125+ return str;
126+ }
127+
128+ static void arqcb (u32 pointerToARQRequest);
129+
130+ // FIXME: param name
131+ static void dvdcb (s32 r3, DVDFileInfo* info)
132+ {
133+ if (!soundInited)
134+ {
135+ return ;
136+ }
137+
138+ UNK_USERDATA* data = (UNK_USERDATA*)info->cb .userData ;
139+ xSTAssetName (data->aid );
140+ dump_flags (data->flags );
141+ if (data->x0 == 0 )
142+ {
143+ return ;
144+ }
145+
146+ if (r3 <= 0 )
147+ {
148+ return ;
149+ }
150+
151+ data->x88 += r3;
152+ data->x90 += r3;
153+ data->flags |= 0x800 ;
154+ data->flags &= ~0x100 ;
155+ if (data->flags & (0x200 | 0x400 ))
156+ {
157+ houston_we_have_a_problem = TRUE ;
158+ }
159+ if ((data->flags & 0x4 ) == 0 )
160+ {
161+ return ;
162+ }
163+
164+ U32 dest = 0 ;
165+ if ((data->flags & 0x1000 ) == 0 )
166+ {
167+ data->flags |= 0x200 ;
168+ dest = data->dest_a ;
169+ }
170+ else if ((data->flags & 0x2000 ) == 0 )
171+ {
172+ data->flags |= 0x400 ;
173+ dest = data->dest_b ;
174+ }
175+
176+ if (dest != 0 )
177+ {
178+ ARQPostRequest (&data->request , (u32 )data, 0 , 1 , data->source , dest, 0x4000 , arqcb);
179+ }
180+ }
181+
182+ static void arqcb (u32 pointerToARQRequest)
183+ {
184+ if (!soundInited)
185+ {
186+ return ;
187+ }
188+
189+ UNK_USERDATA* data = (UNK_USERDATA*)((ARQRequest*)pointerToARQRequest)->owner ;
190+
191+ xSTAssetName (data->aid );
192+ dump_flags (data->flags );
193+ last_ar = (ARQRequest*)pointerToARQRequest;
194+ if (last_ar->length == 0 )
195+ {
196+ return ;
197+ }
198+
199+ // FIXME: Missing redundant branch instruction here
200+ if (data->x0 == 0 )
201+ {
202+ return ;
203+ }
204+
205+ if (data->flags & 0x100 )
206+ {
207+ houston_we_have_a_problem = TRUE ;
208+ }
209+ if (data->flags & 0x1000000 )
210+ {
211+ if (data->flags & 0x200 )
212+ {
213+ data->flags |= 0x1000 ;
214+ data->flags &= ~0x200 ;
215+ }
216+ if (data->flags & 0x400 )
217+ {
218+ data->flags |= 0x2000 ;
219+ data->flags &= ~0x400 ;
220+ }
221+
222+ data->x90 += data->xe4 ;
223+ data->xe4 = 0 ;
224+ data->xe0 = 0 ;
225+ }
226+ else if (data->flags & 0x200 )
227+ {
228+ data->flags |= 0x1000 ;
229+ data->flags &= ~0x200 ;
230+ }
231+ else if (data->flags & 0x400 )
232+ {
233+ data->flags |= 0x2000 ;
234+ data->flags &= ~0x400 ;
235+ }
236+
237+ if (data->x8c - data->x90 == 0 )
238+ {
239+ xSTAssetName (data->aid );
240+ data->flags |= 0x20 ;
241+ }
242+ else if ((data->flags & 0x1000000 ) == 0 )
243+ {
244+ data->flags |= 0x200000 ;
245+ }
246+
247+ data->flags &= ~0x800 ;
248+ data->flags &= ~0x4000000 ;
249+ data->flags &= ~0x400000 ;
250+ if (data->flags & 0x4 ) {
251+ data->flags &= ~4 ;
252+ data->flags |= 0x8 ;
253+ }
254+ }
255+
28256void iSndExit ()
29257{
30258 soundInited = 0 ;
@@ -109,13 +337,14 @@ void iSndStereo(U32 i)
109337void iSndWaitForDeadSounds ()
110338{
111339 fc = 0 ;
112- int i = 0 ;
113- // Can't get 0x8c to get stored in r31
114- while ((i = fc) < 0x8c ) // for (int i = 0; (i = fc) < 0x8c; )
340+ for (int i = 0x8c ; fc < i;)
115341 {
342+ // `i` is weird, it's stored in a saved register but never mutated. However it needs to be mutated to put it in a saved register
116343 i = fc;
117344 while (fc < i + 0xe )
118345 ;
346+ // This adds the nonmatching instruction, but get's us back to the state `i`'s register should be in.
347+ i = 0x8c ;
119348 iSndUpdate ();
120349 }
121350}
@@ -150,7 +379,7 @@ void sndloadcb(tag_xFile* tag)
150379 SoundFlags = 0 ;
151380}
152381
153- void iSndSetExternalCallback (void (*func_ptr)(U32) )
382+ void iSndSetExternalCallback (iSndExternalCallback callback )
154383{
155384}
156385
0 commit comments