diff --git a/.vscode/settings.json b/.vscode/settings.json
index 19a3efea9..90013f285 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -18,6 +18,10 @@
"osbootinfo.h": "c",
"dvd.h": "c",
"osutil.h": "c",
- "hw_regs.h": "c"
+ "hw_regs.h": "c",
+ "thpread.h": "c",
+ "thpbuffer.h": "c",
+ "thpinfo.h": "c",
+ "thpfile.h": "c"
}
}
\ No newline at end of file
diff --git a/docs/recommended_todo.md b/docs/recommended_todo.md
index 1106c0015..5fb16bc16 100644
--- a/docs/recommended_todo.md
+++ b/docs/recommended_todo.md
@@ -184,9 +184,9 @@
| ---- | ---- | ---- | ---- |
| JSTObjectSpecialActor.cpp | 2289 | illustratedBookMessage.cpp | 2964 |
| captionMessage.cpp | 3528 | messageObj.cpp | 4504 |
-| aramMgr.cpp | 4920 | gameflow.cpp | 5333 |
-| messageMgr.cpp | 6825 | section.cpp | 7138 |
-| THPRead.c | 7147 | THPAudioDecode.c | 7366 |
+| THPAudioDecode.c | 4835 | aramMgr.cpp | 4920 |
+| gameflow.cpp | 5333 | messageMgr.cpp | 6825 |
+| section.cpp | 7138 | THPRead.c | 7147 |
| moviePlayerPauseAndDraw.cpp | 8587 | screenScene.cpp | 9274 |
| THPVideoDecode.c | 10029 | JSTObjectParticleActor.cpp | 11032 |
| loadResource.cpp | 11781 | heapStatus.cpp | 12405 |
diff --git a/include/THP/THPAudioDecode.h b/include/THP/THPAudioDecode.h
new file mode 100644
index 000000000..2d41c6e5c
--- /dev/null
+++ b/include/THP/THPAudioDecode.h
@@ -0,0 +1,25 @@
+#ifndef _THP_THPAUDIODECODE_H
+#define _THP_THPAUDIODECODE_H
+
+#include "Dolphin/os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int THPAudioDecode(s16* arg1, u8* arg2, int arg3); // TODO: determine args and name properly
+
+BOOL CreateAudioDecodeThread(OSPriority, void*);
+void AudioDecodeThreadStart();
+void AudioDecodeThreadCancel();
+
+void PushFreeAudioBuffer(void* buf);
+void PushDecodedAudioBuffer(void* buf);
+
+void* PopFreeAudioBuffer();
+void* PopDecodedAudioBuffer(s32 flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/THP/THPBuffer.h b/include/THP/THPBuffer.h
new file mode 100644
index 000000000..ce99ea65c
--- /dev/null
+++ b/include/THP/THPBuffer.h
@@ -0,0 +1,33 @@
+#ifndef _THP_THPBUFFER_H
+#define _THP_THPBUFFER_H
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct THPTextureSet {
+ u8* ytexture;
+ u8* utexture;
+ u8* vtexture;
+ s32 frameNumber;
+} THPTextureSet;
+
+typedef struct THPAudioBuffer {
+ s16* buffer;
+ s16* curPtr;
+ u32 validSample;
+} THPAudioBuffer;
+
+typedef struct THPReadBuffer {
+ u8* ptr;
+ s32 frameNumber;
+ BOOL isValid;
+} THPReadBuffer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/include/THP/THPFile.h b/include/THP/THPFile.h
new file mode 100644
index 000000000..ddd30c618
--- /dev/null
+++ b/include/THP/THPFile.h
@@ -0,0 +1,29 @@
+#ifndef _THP_THPFILE_H
+#define _THP_THPFILE_H
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct THPHeader {
+ char magic[4];
+ u32 version;
+ u32 bufsize;
+ u32 audioMaxSamples;
+ f32 frameRate;
+ u32 numFrames;
+ u32 firstFrameSize;
+ u32 movieDataSize;
+ u32 compInfoDataOffsets;
+ u32 offsetDataOffsets;
+ u32 movieDataOffsets;
+ u32 finalFrameDataOffsets;
+} THPHeader;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/include/THP/THPInfo.h b/include/THP/THPInfo.h
new file mode 100644
index 000000000..97066dd35
--- /dev/null
+++ b/include/THP/THPInfo.h
@@ -0,0 +1,32 @@
+#ifndef _THP_THPINFO_H
+#define _THP_THPINFO_H
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct THPVideoInfo {
+ u32 xSize;
+ u32 ySize;
+ u32 videoType;
+} THPVideoInfo;
+
+typedef struct THPAudioInfo {
+ u32 sndChannels;
+ u32 sndFrequency;
+ u32 sndNumSamples;
+ u32 sndNumTracks;
+} THPAudioInfo;
+
+typedef struct THPFrameCompInfo {
+ u32 numComponents;
+ u8 frameComp[16];
+} THPFrameCompInfo;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/THP/THPPlayer.h b/include/THP/THPPlayer.h
new file mode 100644
index 000000000..892e4197e
--- /dev/null
+++ b/include/THP/THPPlayer.h
@@ -0,0 +1,85 @@
+#ifndef _THP_THPPLAYER_H
+#define _THP_THPPLAYER_H
+
+#include "types.h"
+#include "Dolphin/os.h"
+#include "Dolphin/gx.h"
+#include "THP/THPBuffer.h"
+#include "THP/THPFile.h"
+#include "THP/THPInfo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct THPPlayer {
+ DVDFileInfo fileInfo;
+ THPHeader header;
+ THPFrameCompInfo compInfo;
+ THPVideoInfo videoInfo;
+ THPAudioInfo audioInfo;
+ void* thpWork;
+ BOOL open;
+ u8 state;
+ u8 internalState;
+ u8 playFlag;
+ u8 audioExist;
+ s32 dvdError;
+ s32 videoError;
+ BOOL onMemory;
+ u8* movieData;
+ s32 initOffset;
+ s32 initReadSize;
+ s32 initReadFrame;
+ u32 curField;
+ s64 retaceCount;
+ s32 prevCount;
+ s32 curCount;
+ s32 videoDecodeCount;
+ f32 curVolume;
+ f32 targetVolume;
+ f32 deltaVolume;
+ s32 rampCount;
+ s32 curAudioTrack;
+ s32 curVideoNumber;
+ s32 curAudioNumber;
+ THPTextureSet* dispTextureSet;
+ THPAudioBuffer* playAudioBuffer;
+ THPReadBuffer readBuffer[10];
+ THPTextureSet textureSet[3];
+ THPAudioBuffer audioBuffer[6];
+} THPPlayer; // Size: 0x1f0
+
+extern THPPlayer ActivePlayer;
+
+BOOL THPPlayerInit();
+void THPPlayerQuit();
+BOOL THPPlayerOpen(const char* fileName, BOOL onMemory);
+BOOL THPPlayerClose();
+BOOL THPPlayerPlay();
+void THPPlayerStop();
+BOOL THPPlayerPause();
+BOOL THPPlayerPrepare(s32 offset, u8 flag, s32 audioTrack);
+
+BOOL THPPlayerSetBuffer(u8* data);
+
+u32 THPPlayerCalcNeedMemory();
+
+BOOL THPPlayerGetVideoInfo(void* dst);
+// BOOL THPPlayerGetAudioInfo(void *dst);
+// f32 THPPlayerGetFrameRate();
+BOOL THPPlayerSetVolume(s32 vol, s32 duration);
+
+s32 THPPlayerDrawCurrentFrame(GXRenderModeObj* rmode, s32, s32, s32, s32); // TODO, parameter names from dwarf info if it exists
+u32 THPPlayerGetTotalFrame();
+u8 THPPlayerGetState();
+
+void THPPlayerPostDrawDone();
+
+#ifdef __cplusplus
+}
+#endif
+
+void PrepareReady(int msg);
+
+#endif /* _THP_THPPLAYER_H */
diff --git a/include/THP/THPRead.h b/include/THP/THPRead.h
index d87956833..dbab0c0a0 100644
--- a/include/THP/THPRead.h
+++ b/include/THP/THPRead.h
@@ -3,15 +3,12 @@
#include "Dolphin/os.h"
#include "types.h"
+#include "THP/THPBuffer.h"
#ifdef __cplusplus
extern "C" {
#endif // ifdef __cplusplus
-typedef struct THPReadBuffer {
- u32 _00;
-} THPReadBuffer;
-
BOOL CreateReadThread(int);
void ReadThreadStart();
void ReadThreadCancel();
diff --git a/src/sysGCU/THPAudioDecode.c b/src/sysGCU/THPAudioDecode.c
index 203a7e12c..95f04f43c 100644
--- a/src/sysGCU/THPAudioDecode.c
+++ b/src/sysGCU/THPAudioDecode.c
@@ -1,74 +1,45 @@
#include "THP/THPRead.h"
+#include "THP/THPAudioDecode.h"
+#include "THP/THPPlayer.h"
+
+#define STACK_SIZE 4096
+#define BUFFER_COUNT 3
+
+static OSThread AudioDecodeThread;
+static u8 AudioDecodeThreadStack[STACK_SIZE];
+static OSMessageQueue FreeAudioBufferQueue;
+static OSMessageQueue DecodedAudioBufferQueue;
+static OSMessage FreeAudioBufferMessage[BUFFER_COUNT];
+static OSMessage DecodedAudioBufferMessage[BUFFER_COUNT];
+
+static BOOL AudioDecodeThreadCreated;
+
+static void* AudioDecoderForOnMemory(void* arg);
+static void* AudioDecoder(void* arg);
+static void AudioDecode(THPReadBuffer* readBuffer);
/*
* --INFO--
* Address: 8044D2C4
* Size: 0000D4
*/
-void CreateAudioDecodeThread(void)
+BOOL CreateAudioDecodeThread(OSPriority prio, void* arg)
{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- cmplwi r4, 0
- lis r5, 0x8050
- stw r0, 0x14(r1)
- stw r31, 0xC(r1)
- addi r31, r5, 0x1D80
- beq- .loc_0x5C
- lis r5, 0x8045
- addi r6, r31, 0x318
- subi r0, r5, 0x2BD0
- mr r8, r3
- mr r5, r4
- addi r3, r31, 0
- mr r4, r0
- li r7, 0x1000
- li r9, 0x1
- addi r6, r6, 0x1000
- bl -0x35B340
- cmpwi r3, 0
- bne- .loc_0x94
- li r3, 0
- b .loc_0xC0
-
- .loc_0x5C:
- lis r4, 0x8045
- addi r6, r31, 0x318
- mr r8, r3
- addi r3, r31, 0
- subi r4, r4, 0x2BF8
- li r5, 0
- li r7, 0x1000
- li r9, 0x1
- addi r6, r6, 0x1000
- bl -0x35B378
- cmpwi r3, 0
- bne- .loc_0x94
- li r3, 0
- b .loc_0xC0
-
- .loc_0x94:
- addi r3, r31, 0x1318
- addi r4, r31, 0x1358
- li r5, 0x3
- bl -0x35DEA8
- addi r3, r31, 0x1338
- addi r4, r31, 0x1364
- li r5, 0x3
- bl -0x35DEB8
- li r0, 0x1
- li r3, 0x1
- stw r0, -0x63D0(r13)
-
- .loc_0xC0:
- lwz r0, 0x14(r1)
- lwz r31, 0xC(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
+ BOOL res;
+ if (arg) {
+ res = OSCreateThread(&AudioDecodeThread, AudioDecoderForOnMemory, arg, AudioDecodeThreadStack + STACK_SIZE, STACK_SIZE, prio, 1);
+ if (res == FALSE)
+ return FALSE;
+ } else {
+ res = OSCreateThread(&AudioDecodeThread, AudioDecoder, NULL, AudioDecodeThreadStack + STACK_SIZE, STACK_SIZE, prio, 1);
+ if (res == FALSE)
+ return FALSE;
+ }
+
+ OSInitMessageQueue(&FreeAudioBufferQueue, FreeAudioBufferMessage, BUFFER_COUNT);
+ OSInitMessageQueue(&DecodedAudioBufferQueue, DecodedAudioBufferMessage, BUFFER_COUNT);
+ AudioDecodeThreadCreated = TRUE;
+ return TRUE;
}
/*
@@ -76,26 +47,10 @@ void CreateAudioDecodeThread(void)
* Address: 8044D398
* Size: 000034
*/
-void AudioDecodeThreadStart(void)
+void AudioDecodeThreadStart()
{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- stw r0, 0x14(r1)
- lwz r0, -0x63D0(r13)
- cmpwi r0, 0
- beq- .loc_0x24
- lis r3, 0x8050
- addi r3, r3, 0x1D80
- bl -0x35AEC4
-
- .loc_0x24:
- lwz r0, 0x14(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
+ if (AudioDecodeThreadCreated)
+ OSResumeThread(&AudioDecodeThread);
}
/*
@@ -103,52 +58,27 @@ void AudioDecodeThreadStart(void)
* Address: 8044D3CC
* Size: 00003C
*/
-void AudioDecodeThreadCancel(void)
+void AudioDecodeThreadCancel()
{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- stw r0, 0x14(r1)
- lwz r0, -0x63D0(r13)
- cmpwi r0, 0
- beq- .loc_0x2C
- lis r3, 0x8050
- addi r3, r3, 0x1D80
- bl -0x35B154
- li r0, 0
- stw r0, -0x63D0(r13)
-
- .loc_0x2C:
- lwz r0, 0x14(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
+ if (AudioDecodeThreadCreated) {
+ OSCancelThread(&AudioDecodeThread);
+ AudioDecodeThreadCreated = FALSE;
+ }
}
-
+#pragma cplusplus on
/*
* --INFO--
* Address: 8044D408
* Size: 000028
*/
-void AudioDecoder(void*)
+static void* AudioDecoder(void* arg)
{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- stw r0, 0x14(r1)
- stw r31, 0xC(r1)
-
- .loc_0x10:
- bl 0x2370
- mr r31, r3
- bl 0xB8
- mr r3, r31
- bl 0x245C
- b .loc_0x10
- */
+ THPReadBuffer* buf;
+ while (TRUE) {
+ buf = (THPReadBuffer*)PopReadedBuffer();
+ AudioDecode(buf);
+ PushReadedBuffer2((OSMessage*)buf);
+ }
}
/*
@@ -156,63 +86,36 @@ void AudioDecoder(void*)
* Address: 8044D430
* Size: 0000A8
*/
-void AudioDecoderForOnMemory(void*)
+static void* AudioDecoderForOnMemory(void* arg)
{
- /*
- .loc_0x0:
- stwu r1, -0x30(r1)
- mflr r0
- lis r4, 0x8051
- stw r0, 0x34(r1)
- stw r31, 0x2C(r1)
- li r31, 0
- stw r30, 0x28(r1)
- addi r30, r4, 0x4490
- stw r29, 0x24(r1)
- stw r3, 0x8(r1)
- lwz r29, 0xBC(r30)
-
- .loc_0x2C:
- stw r31, 0xC(r1)
- addi r3, r1, 0x8
- bl .loc_0xA8
- lwz r0, 0xC0(r30)
- lwz r5, 0x50(r30)
- add r4, r31, r0
- divwu r3, r4, r5
- subi r0, r5, 0x1
- mullw r3, r3, r5
- sub r3, r4, r3
- cmplw r3, r0
- bne- .loc_0x8C
- lbz r0, 0xA6(r30)
- rlwinm. r0,r0,0,31,31
- beq- .loc_0x7C
- lwz r3, 0x8(r1)
- lwz r0, 0xB4(r30)
- lwz r29, 0x0(r3)
- stw r0, 0x8(r1)
- b .loc_0xA0
-
- .loc_0x7C:
- lis r3, 0x8050
- addi r3, r3, 0x1D80
- bl -0x35AD38
- b .loc_0xA0
-
- .loc_0x8C:
- lwz r3, 0x8(r1)
- lwz r4, 0x0(r3)
- add r0, r3, r29
- stw r0, 0x8(r1)
- mr r29, r4
-
- .loc_0xA0:
- addi r31, r31, 0x1
- b .loc_0x2C
-
- .loc_0xA8:
- */
+ s32 readSize;
+ s32 frame;
+ THPReadBuffer readBuffer;
+
+ frame = 0;
+ readSize = ActivePlayer.initReadSize;
+ readBuffer.ptr = (u8*)arg;
+
+ while (TRUE) {
+ readBuffer.frameNumber = frame;
+ AudioDecode(&readBuffer);
+
+ s32 remaining = (frame + ActivePlayer.initReadFrame) % ActivePlayer.header.numFrames;
+
+ if (remaining == ActivePlayer.header.numFrames - 1) {
+ if ((ActivePlayer.playFlag & 1)) {
+ readSize = *(s32*)readBuffer.ptr;
+ readBuffer.ptr = ActivePlayer.movieData;
+ } else {
+ OSSuspendThread(&AudioDecodeThread);
+ }
+ } else {
+ s32 size = *(s32*)readBuffer.ptr;
+ readBuffer.ptr += readSize;
+ readSize = size;
+ }
+ frame++;
+ }
}
/*
@@ -220,99 +123,42 @@ void AudioDecoderForOnMemory(void*)
* Address: 8044D4D8
* Size: 0000D4
*/
-void AudioDecode(THPReadBuffer*)
+static void AudioDecode(THPReadBuffer* readBuffer)
{
- /*
- .loc_0x0:
- stwu r1, -0x20(r1)
- mflr r0
- lis r4, 0x8051
- stw r0, 0x24(r1)
- stw r31, 0x1C(r1)
- addi r31, r4, 0x4490
- stw r30, 0x18(r1)
- stw r29, 0x14(r1)
- lwz r0, 0x6C(r31)
- lwz r5, 0x0(r3)
- rlwinm r3,r0,2,0,29
- addi r29, r3, 0x8
- addi r30, r5, 0x8
- add r29, r5, r29
- bl .loc_0xD4
- lwz r0, 0x6C(r31)
- lis r4, 0x8051
- addi r4, r4, 0x4490
- mr r31, r3
- mtctr r0
- cmplwi r0, 0
- ble- .loc_0xB8
-
- .loc_0x58:
- lbz r0, 0x70(r4)
- cmpwi r0, 0x1
- beq- .loc_0x68
- b .loc_0xA4
-
- .loc_0x68:
- lis r3, 0x8051
- lwz r6, 0x0(r30)
- addi r4, r3, 0x4490
- lwz r3, 0x0(r31)
- lwz r0, 0xEC(r4)
- li r5, 0
- mullw r0, r6, r0
- add r4, r29, r0
- bl -0x34EEB0
- stw r3, 0x8(r31)
- mr r3, r31
- lwz r0, 0x0(r31)
- stw r0, 0x4(r31)
- bl 0xE0
- b .loc_0xB8
-
- .loc_0xA4:
- lwz r0, 0x0(r30)
- addi r30, r30, 0x4
- addi r4, r4, 0x1
- add r29, r29, r0
- bdnz+ .loc_0x58
-
- .loc_0xB8:
- lwz r0, 0x24(r1)
- lwz r31, 0x1C(r1)
- lwz r30, 0x18(r1)
- lwz r29, 0x14(r1)
- mtlr r0
- addi r1, r1, 0x20
- blr
-
- .loc_0xD4:
- */
+ THPAudioBuffer* audioBuf;
+ s32 i;
+ u32* offsets;
+ u8* audioData;
+
+ offsets = (u32*)(readBuffer->ptr + 8);
+ audioData = &readBuffer->ptr[ActivePlayer.compInfo.numComponents * 4] + 8;
+ audioBuf = (THPAudioBuffer*)PopFreeAudioBuffer();
+
+ for (i = 0; i < ActivePlayer.compInfo.numComponents; i++) {
+ switch (ActivePlayer.compInfo.frameComp[i]) {
+ case 1: {
+ audioBuf->validSample = THPAudioDecode(audioBuf->buffer, (audioData + *offsets * ActivePlayer.curAudioTrack), 0);
+ audioBuf->curPtr = audioBuf->buffer;
+ PushDecodedAudioBuffer(audioBuf);
+ return;
+ }
+ }
+
+ audioData += *offsets;
+ offsets++;
+ }
}
-
+#pragma cplusplus off
/*
* --INFO--
* Address: 8044D5AC
* Size: 000034
*/
-void PopFreeAudioBuffer(void)
+void* PopFreeAudioBuffer()
{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- lis r3, 0x8050
- li r5, 0x1
- stw r0, 0x14(r1)
- addi r4, r1, 0x8
- addi r3, r3, 0x3098
- bl -0x35DFE4
- lwz r0, 0x14(r1)
- lwz r3, 0x8(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
+ void* buf;
+ OSReceiveMessage(&FreeAudioBufferQueue, &buf, 1);
+ return buf;
}
/*
@@ -320,56 +166,21 @@ void PopFreeAudioBuffer(void)
* Address: 8044D5E0
* Size: 000030
*/
-void PushFreeAudioBuffer(void)
-{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- lis r5, 0x8050
- mr r4, r3
- stw r0, 0x14(r1)
- addi r3, r5, 0x3098
- li r5, 0
- bl -0x35E0E0
- lwz r0, 0x14(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
-}
+void PushFreeAudioBuffer(void* buf) { OSSendMessage(&FreeAudioBufferQueue, buf, OS_MESSAGE_NOBLOCK); }
/*
* --INFO--
* Address: 8044D610
* Size: 000044
*/
-void PopDecodedAudioBuffer(void)
+void* PopDecodedAudioBuffer(s32 flags)
{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- lis r4, 0x8050
- mr r5, r3
- stw r0, 0x14(r1)
- addi r3, r4, 0x30B8
- addi r4, r1, 0x8
- bl -0x35E048
- cmpwi r3, 0x1
- bne- .loc_0x30
- lwz r3, 0x8(r1)
- b .loc_0x34
-
- .loc_0x30:
- li r3, 0
-
- .loc_0x34:
- lwz r0, 0x14(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
+ void* buf;
+ s32 res = OSReceiveMessage(&DecodedAudioBufferQueue, &buf, flags);
+ if (res == 1) {
+ return buf;
+ }
+ return NULL;
}
/*
@@ -377,21 +188,4 @@ void PopDecodedAudioBuffer(void)
* Address: 8044D654
* Size: 000030
*/
-void PushDecodedAudioBuffer(void)
-{
- /*
- .loc_0x0:
- stwu r1, -0x10(r1)
- mflr r0
- lis r5, 0x8050
- mr r4, r3
- stw r0, 0x14(r1)
- addi r3, r5, 0x30B8
- li r5, 0x1
- bl -0x35E154
- lwz r0, 0x14(r1)
- mtlr r0
- addi r1, r1, 0x10
- blr
- */
-}
+void PushDecodedAudioBuffer(void* buf) { OSSendMessage(&DecodedAudioBufferQueue, buf, 1); }