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); }