diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index f4e353fd..623195e2 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -6288,7 +6288,7 @@ AudioSystem = .sbss:0x801D3E40; // type:object size:0x4 scope:local data:4byte bufIdx = .sbss:0x801D3E44; // type:object size:0x4 scope:local data:4byte CurAudioBuffer = .sbss:0x801D3E48; // type:object size:0x4 scope:local data:4byte LastAudioBuffer = .sbss:0x801D3E4C; // type:object size:0x4 scope:local data:4byte -SoundBufferIndex = .sbss:0x801D3E50; // type:object size:0x8 scope:local data:4byte +SoundBufferIndex = .sbss:0x801D3E50; // type:object size:0x4 scope:local data:4byte THPProc = .sbss:0x801D3E58; // type:object size:0x4 data:4byte THPStart = .sbss:0x801D3E5C; // type:object size:0x2 scope:local data:2byte THPFrame = .sbss:0x801D3E60; // type:object size:0x4 scope:local data:4byte @@ -6297,7 +6297,7 @@ THPLoopF = .sbss:0x801D3E66; // type:object size:0x2 scope:local data:2byte decodeThread = .sbss:0x801D3E68; // type:object size:0x4 scope:local data:4byte decodeStackP = .sbss:0x801D3E6C; // type:object size:0x4 scope:local data:4byte decodeRate = .sbss:0x801D3E70; // type:object size:0x4 scope:local data:4byte -audioTrack = .sbss:0x801D3E74; // type:object size:0xC scope:local data:4byte +audioTrack = .sbss:0x801D3E74; // type:object size:0x8 scope:local data:4byte lbl_801D3E80 = .sbss:0x801D3E80; // type:object size:0x4 lbl_801D3E84 = .sbss:0x801D3E84; // type:object size:0x4 lbl_801D3E88 = .sbss:0x801D3E88; // type:object size:0x4 data:4byte diff --git a/configure.py b/configure.py index 61c399ae..90faa600 100644 --- a/configure.py +++ b/configure.py @@ -352,9 +352,9 @@ config.libs = [ Object(Matching, "game/armem.c"), Object(NonMatching, "game/chrman.c"), Object(NonMatching, "game/mapspace.c"), - Object(NonMatching, "game/THPSimple.c"), - Object(NonMatching, "game/THPDraw.c"), - Object(NonMatching, "game/thpmain.c"), + Object(Matching, "game/THPSimple.c"), + Object(Matching, "game/THPDraw.c"), + Object(Matching, "game/thpmain.c"), Object(NonMatching, "game/objsub.c"), Object(Matching, "game/flag.c"), Object(Matching, "game/saveload.c"), diff --git a/include/game/THPDraw.h b/include/game/THPDraw.h new file mode 100755 index 00000000..dcaa8f3c --- /dev/null +++ b/include/game/THPDraw.h @@ -0,0 +1,10 @@ +#ifndef _GAME_THPDRAW_H +#define _GAME_THPDRAW_H + +#include "dolphin.h" + +void THPGXRestore(void); +void THPGXYuv2RgbSetup(GXRenderModeObj *obj, GXColor *arg1, Mtx arg2); +void THPGXYuv2RgbDraw(u32 *yImage, u32 *uImage, u32 *vImage, s16 x, s16 y, s16 texWidth, s16 texHeight, s16 polyWidth, s16 polyHeight); + +#endif diff --git a/include/game/THPSimple.h b/include/game/THPSimple.h new file mode 100755 index 00000000..dcc31892 --- /dev/null +++ b/include/game/THPSimple.h @@ -0,0 +1,84 @@ +#ifndef _GAME_THPSIMPLE_H +#define _GAME_THPSIMPLE_H + +#include "dolphin.h" +#include "dolphin/thp/THPFile.h" +#include "dolphin/thp/THPInfo.h" + +// THPReadBuffer? +typedef struct { + /* 0x00 */ s32 *unk00; + /* 0x04 */ s32 unk04; + /* 0x08 */ s32 unk08; +} UnkThpStruct01; // Size 0xC + +typedef struct { + /* 0x00 */ void *unk00; + /* 0x04 */ void *unk04; + /* 0x08 */ void *unk08; + /* 0x0C */ s32 unk0C; +} UnkThpStruct02; // Size 0x10 + +typedef struct { + /* 0x00 */ void *unk00; + /* 0x04 */ void *unk04; + /* 0x08 */ u32 unk08; +} UnkThpStruct03; // Size 0xC + +typedef struct { + /* 0x00 */ u32 unk00; + /* 0x04 */ u32 unk04; +} UnkThpStruct04; // Size 8 + +typedef struct { + /* 0x000 */ DVDFileInfo unk00; + /* 0x03C */ THPHeader unk3C; + /* 0x06C */ THPFrameCompInfo unk6C; + /* 0x080 */ UnkThpStruct04 unk80; + /* 0x088 */ u8 unk88[0xC]; + /* 0x094 */ void *unk94; + /* 0x098 */ s32 unk98; + /* 0x09C */ u8 unk9C; + /* 0x09D */ u8 unk9D; + /* 0x09E */ u8 unk9E; + /* 0x09F */ u8 unk9F; + /* 0x0A0 */ s32 unkA0; + /* 0x0A4 */ s32 unkA4; + /* 0x0A8 */ u32 unkA8; + /* 0x0AC */ s32 unkAC; + /* 0x0B0 */ s32 unkB0; + /* 0x0B4 */ s32 unkB4; + /* 0x0B8 */ s32 unkB8; + /* 0x0BC */ float unkBC; + /* 0x0C0 */ float unkC0; + /* 0x0C4 */ float unkC4; + /* 0x0C8 */ s32 unkC8; + /* 0x0CC */ UnkThpStruct01 unkCC[10]; + /* 0x144 */ UnkThpStruct02 unk144[2]; + /* 0x164 */ UnkThpStruct03 unk164[4]; + /* 0x194 */ s32 unk194; + /* 0x198 */ s32 unk198; + /* 0x19C */ u8 unk19C; + /* 0x19D */ char unk19D[1]; + /* 0x19E */ s16 unk19E; +} UnkThpStruct10; // Size 0x1A0 + +s32 THPSimpleInit(s32 arg0); +void THPSimpleQuit(void); +s32 THPSimpleOpen(char *arg0); +s32 THPSimpleClose(void); +s32 THPSimpleCalcNeedMemory(void); +s32 THPSimpleSetBuffer(void *arg0); +s32 THPSimplePreLoad(s32 arg0); +void THPSimpleAudioStart(void); +void THPSimpleAudioStop(void); +s32 THPSimpleLoadStop(void); +s32 THPSimpleDecode(void); +s32 THPSimpleDrawCurrentFrame(GXRenderModeObj *arg0, GXColor *arg1, Mtx arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6); +s32 THPSimpleGetVideoInfo(UnkThpStruct04 *arg0); +s32 THPSimpleGetTotalFrame(void); +s32 THPSimpleSetVolume(s32 left, s32 right); + +extern UnkThpStruct10 SimpleControl; + +#endif diff --git a/include/game/thpmain.h b/include/game/thpmain.h index 37ac9565..b0d5b0d1 100644 --- a/include/game/thpmain.h +++ b/include/game/thpmain.h @@ -10,9 +10,9 @@ s16 HuTHP3DCreate(char *path, s16 loop); void HuTHPStop(void); void HuTHPClose(void); void HuTHPRestart(void); -int HuTHPEndCheck(void); -int HuTHPFrameGet(void); -int HuTHPTotalFrameGet(void); -void HuTHPSetVolume(int left, int right); +BOOL HuTHPEndCheck(void); +s32 HuTHPFrameGet(void); +s32 HuTHPTotalFrameGet(void); +void HuTHPSetVolume(s32 left, s32 right); #endif \ No newline at end of file diff --git a/src/game/THPDraw.c b/src/game/THPDraw.c new file mode 100755 index 00000000..79eb5554 --- /dev/null +++ b/src/game/THPDraw.c @@ -0,0 +1,109 @@ +#include "game/THPDraw.h" + +void THPGXRestore(void) { + GXSetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); + GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET); + GXSetNumTexGens(1); + GXSetNumChans(0); + GXSetNumTevStages(1); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA); + GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_1); + GXSetTevKAlphaSel(GX_TEVSTAGE1, GX_TEV_KASEL_1); +} + +void THPGXYuv2RgbSetup(GXRenderModeObj *obj, GXColor *arg1, Mtx arg2) { + s32 sp2C = obj->fbWidth; + s32 sp28 = obj->efbHeight; + + GXLoadPosMtxImm(arg2, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_NOOP); + GXSetColorUpdate(GX_TRUE); + GXSetAlphaUpdate(GX_FALSE); + GXSetNumChans(0); + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, GX_FALSE, GX_PTIDENTITY); + GXInvalidateTexAll(); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT7, GX_VA_POS, GX_TEX_ST, GX_RGBA4, 0); + GXSetVtxAttrFmt(GX_VTXFMT7, GX_VA_TEX0, GX_TEX_ST, GX_RGBX8, 0); + GXSetNumTevStages(5); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_A0); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + GXSetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + GXSetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP2, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, GX_FALSE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, GX_FALSE, GX_TEVPREV); + GXSetTevKColorSel(GX_TEVSTAGE1, GX_TEV_KCSEL_K1); + GXSetTevKAlphaSel(GX_TEVSTAGE1, GX_TEV_KASEL_K1_A); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_APREV, GX_CC_CPREV, GX_CC_KONST, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_KONST, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevKColorSel(GX_TEVSTAGE3, GX_TEV_KCSEL_K2); + GXSetTevColor(GX_TEVREG1, *arg1); + GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE4, GX_CC_ZERO, GX_CC_CPREV, GX_CC_C1, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE4, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE4, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A1); + GXSetTevAlphaOp(GX_TEVSTAGE4, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevColorS10(GX_TEVREG0, (GXColorS10) { 0xFFA6, 0, 0xFF8E, 0x0087 }); + GXSetTevKColor(GX_KCOLOR0, (GXColor) { 0, 0, 0xE2, 0x58 }); + GXSetTevKColor(GX_KCOLOR1, (GXColor) { 0xB3, 0, 0, 0xB6 }); + GXSetTevKColor(GX_KCOLOR2, (GXColor) { 0xFF, 0, 0xFF, 0x80 }); + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); +} + +void THPGXYuv2RgbDraw(u32 *yImage, u32 *uImage, u32 *vImage, s16 x, s16 y, s16 texWidth, s16 texHeight, s16 polyWidth, s16 polyHeight) { + GXTexObj sp54; + GXTexObj sp34; + GXTexObj sp14; + + GXInitTexObj(&sp54, yImage, texWidth, texHeight, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GXInitTexObjLOD(&sp54, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + GXLoadTexObj(&sp54, GX_TEXMAP0); + GXInitTexObj(&sp34, uImage, texWidth >> 1, texHeight >> 1, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GXInitTexObjLOD(&sp34, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + GXLoadTexObj(&sp34, GX_TEXMAP1); + GXInitTexObj(&sp14, vImage, texWidth >> 1, texHeight >> 1, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GXInitTexObjLOD(&sp14, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); + GXLoadTexObj(&sp14, GX_TEXMAP2); + GXBegin(GX_QUADS, GX_VTXFMT7, 4); + GXPosition3s16(x, y, 0); + GXTexCoord2s16(0, 0); + GXPosition3s16(x + polyWidth, y, 0); + GXTexCoord2s16(1, 0); + GXPosition3s16(x + polyWidth, y + polyHeight, 0); + GXTexCoord2s16(1, 1); + GXPosition3s16(x, y + polyHeight, 0); + GXTexCoord2s16(0, 1); + GXEnd(); +} diff --git a/src/game/THPSimple.c b/src/game/THPSimple.c new file mode 100755 index 00000000..c48f2462 --- /dev/null +++ b/src/game/THPSimple.c @@ -0,0 +1,657 @@ +#include "game/THPSimple.h" +#include "game/THPDraw.h" + +#define ALIGN32(val) (((val) + 0x1F) & ~0x1F) + +static void __THPSimpleDVDCallback(s32 result, DVDFileInfo *fileInfo); +static s32 VideoDecode(void *arg0); +static void THPAudioMixCallback(void); + +UnkThpStruct10 SimpleControl; +static u8 SoundBuffer[2][0x280]; +static u8 WorkBuffer[0x40]; + +static s32 SoundBufferIndex; +static void *LastAudioBuffer; +static void *CurAudioBuffer; +static s32 bufIdx; +static s32 AudioSystem; +static void (*OldAIDCallback)(); +static s32 Initialized; + +s32 THPSimpleInit(s32 arg0) { + s32 temp_r31; + + memset(&SimpleControl, 0, sizeof(SimpleControl)); + LCEnable(); + if (THPInit() == 0) { + return 0; + } + temp_r31 = OSDisableInterrupts(); + AudioSystem = arg0; + SoundBufferIndex = 0; + LastAudioBuffer = NULL; + CurAudioBuffer = NULL; + OldAIDCallback = AIRegisterDMACallback(THPAudioMixCallback); + if (OldAIDCallback == NULL && AudioSystem != 0) { + AIRegisterDMACallback(NULL); + OSRestoreInterrupts(temp_r31); + return 0; + } + OSRestoreInterrupts(temp_r31); + if (AudioSystem == 0) { + memset(SoundBuffer, 0, sizeof(SoundBuffer)); + DCFlushRange(SoundBuffer, sizeof(SoundBuffer)); + AIInitDMA((u32) &SoundBuffer[SoundBufferIndex], sizeof(SoundBuffer[0])); + AIStartDMA(); + } + Initialized = 1; + return 1; +} + +void THPSimpleQuit(void) { + s32 temp_r31; + + LCDisable(); + temp_r31 = OSDisableInterrupts(); + if (OldAIDCallback) { + AIRegisterDMACallback(OldAIDCallback); + } + OSRestoreInterrupts(temp_r31); + Initialized = 0; +} + +s32 THPSimpleOpen(char *arg0) { + s32 var_r31; + s32 i; + + if (Initialized == 0) { + return 0; + } + if (SimpleControl.unk98 != 0) { + return 0; + } + memset(&SimpleControl.unk80, 0, sizeof(SimpleControl.unk80)); + memset(SimpleControl.unk88, 0, sizeof(SimpleControl.unk88)); + if (DVDOpen(arg0, &SimpleControl.unk00) == 0) { + return 0; + } + if (DVDReadPrio(&SimpleControl.unk00, &WorkBuffer, 0x40, 0, 2) < 0) { + DVDClose(&SimpleControl.unk00); + return 0; + } + memcpy(&SimpleControl.unk3C, &WorkBuffer, sizeof(SimpleControl.unk3C)); + if (strcmp(SimpleControl.unk3C.mMagic, "THP") != 0) { + DVDClose(&SimpleControl.unk00); + return 0; + } + if (SimpleControl.unk3C.mVersion != 0x10000) { + DVDClose(&SimpleControl.unk00); + return 0; + } + var_r31 = SimpleControl.unk3C.mCompInfoDataOffsets; + if (DVDReadPrio(&SimpleControl.unk00, &WorkBuffer, 0x20, var_r31, 2) < 0) { + DVDClose(&SimpleControl.unk00); + return 0; + } + memcpy(&SimpleControl.unk6C, &WorkBuffer, sizeof(SimpleControl.unk6C)); + var_r31 += sizeof(SimpleControl.unk6C); + SimpleControl.unk9F = 0; + for (i = 0; i < SimpleControl.unk6C.mNumComponents; i++) { + switch (SimpleControl.unk6C.mFrameComp[i]) { + case 0: + if (DVDReadPrio(&SimpleControl.unk00, &WorkBuffer, 0x20, var_r31, 2) < 0) { + DVDClose(&SimpleControl.unk00); + return 0; + } + memcpy(&SimpleControl.unk80, &WorkBuffer, sizeof(SimpleControl.unk80)); + var_r31 += sizeof(SimpleControl.unk80); + break; + case 1: + if (DVDReadPrio(&SimpleControl.unk00, &WorkBuffer, 0x20, var_r31, 2) < 0) { + DVDClose(&SimpleControl.unk00); + return 0; + } + memcpy(SimpleControl.unk88, &WorkBuffer, sizeof(SimpleControl.unk88)); + SimpleControl.unk9F = 1; + var_r31 += sizeof(SimpleControl.unk88); + break; + default: + return 0; + } + } + SimpleControl.unkA0 = SimpleControl.unk3C.mMovieDataOffsets; + SimpleControl.unkB4 = SimpleControl.unk3C.mFirstFrameSize; + SimpleControl.unkB0 = 0; + SimpleControl.unkB8 = 0; + SimpleControl.unkA4 = 0; + SimpleControl.unk144[0].unk0C = -1; + SimpleControl.unkAC = 0; + SimpleControl.unk194 = 0; + SimpleControl.unk198 = 0; + SimpleControl.unk9C = 0; + SimpleControl.unk9D = 0; + SimpleControl.unk9E = 0; + SimpleControl.unk98 = 1; + SimpleControl.unkC0 = SimpleControl.unkBC; + SimpleControl.unkC8 = 0; + return 1; +} + +s32 THPSimpleClose(void) { + if (SimpleControl.unk98 != 0 && SimpleControl.unk9C == 0) { + if (SimpleControl.unk9F != 0) { + if (SimpleControl.unk9D == 1) { + return 0; + } + } else { + SimpleControl.unk9D = 0; + } + if (SimpleControl.unkA8 == 0) { + SimpleControl.unk98 = 0; + DVDClose(&SimpleControl.unk00); + return 1; + } + } + return 0; +} + +s32 THPSimpleCalcNeedMemory(void) { + s32 var_r31; + + if (SimpleControl.unk98 != 0) { + var_r31 = ALIGN32(SimpleControl.unk3C.mBufferSize) * 10; + var_r31 += ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04); + var_r31 += ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04 / 4); + var_r31 += ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04 / 4); + var_r31 += ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04); + var_r31 += ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04 / 4); + var_r31 += ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04 / 4); + if (SimpleControl.unk9F != 0) { + var_r31 += ALIGN32(SimpleControl.unk3C.mAudioMaxSamples * 4) * 4; + } + var_r31 += 0x1000; + return var_r31; + } + return 0; +} + +s32 THPSimpleSetBuffer(void *arg0) { + u8 *var_r31; + u32 temp_r28; + u32 temp_r29; + u32 i; + + if (SimpleControl.unk98 != 0 && SimpleControl.unk9C == 0) { + if (SimpleControl.unk9D == 1) { + return 0; + } + temp_r28 = ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04); + temp_r29 = ALIGN32(SimpleControl.unk80.unk00 * SimpleControl.unk80.unk04 / 4); + var_r31 = arg0; + for (i = 0; i < 2; i++) { + SimpleControl.unk144[i].unk00 = var_r31; + DCInvalidateRange(var_r31, temp_r28); + var_r31 += temp_r28; + SimpleControl.unk144[i].unk04 = var_r31; + DCInvalidateRange(var_r31, temp_r29); + var_r31 += temp_r29; + SimpleControl.unk144[i].unk08 = var_r31; + DCInvalidateRange(var_r31, temp_r29); + var_r31 += temp_r29; + } + for (i = 0; i < 10; i++) { + SimpleControl.unkCC[i].unk00 = (s32*) var_r31; + var_r31 += ALIGN32(SimpleControl.unk3C.mBufferSize); + SimpleControl.unkCC[i].unk08 = 0; + } + if (SimpleControl.unk9F != 0) { + for (i = 0; i < 4; i++) { + SimpleControl.unk164[i].unk00 = var_r31; + SimpleControl.unk164[i].unk04 = var_r31; + SimpleControl.unk164[i].unk08 = 0; + var_r31 += ALIGN32(SimpleControl.unk3C.mAudioMaxSamples * 4); + } + } + SimpleControl.unk94 = var_r31; + } + return 1; +} + +static inline void THPSimpleInlineFunc(void) { + if (SimpleControl.unkB8 > SimpleControl.unk3C.mNumFrames - 1) { + if (SimpleControl.unk9E != 1) { + return; + } + SimpleControl.unkB8 = 0; + SimpleControl.unkA0 = SimpleControl.unk3C.mMovieDataOffsets; + SimpleControl.unkB4 = SimpleControl.unk3C.mFirstFrameSize; + } + SimpleControl.unkA8 = 1; + if (DVDReadAsyncPrio(&SimpleControl.unk00, SimpleControl.unkCC[SimpleControl.unkB0].unk00, SimpleControl.unkB4, SimpleControl.unkA0, __THPSimpleDVDCallback, 2) != 1) { + SimpleControl.unkA8 = 0; + SimpleControl.unkA4 = 1; + } +} + +static void __THPSimpleDVDCallback(s32 result, DVDFileInfo *fileInfo) { + s32 var_r31; + + if (result == -1) { + SimpleControl.unkA4 = 1; + return; + } + if (result != -3) { + SimpleControl.unkA8 = 0; + SimpleControl.unkCC[SimpleControl.unkB0].unk04 = SimpleControl.unkB8; + SimpleControl.unkB8++; + SimpleControl.unkCC[SimpleControl.unkB0].unk08 = 1; + SimpleControl.unkA0 += SimpleControl.unkB4; + SimpleControl.unkB4 = *SimpleControl.unkCC[SimpleControl.unkB0].unk00; + if (SimpleControl.unkB0 + 1 >= 10) { + var_r31 = 0; + } else { + var_r31 = SimpleControl.unkB0 + 1; + } + SimpleControl.unkB0 = var_r31; + if (SimpleControl.unkCC[SimpleControl.unkB0].unk08 == 0 && SimpleControl.unkA4 == 0 && SimpleControl.unk9C == 1) { + THPSimpleInlineFunc(); + } + } +} + +s32 THPSimplePreLoad(s32 arg0) { + u32 var_r30; + s32 var_r29; + s32 i; + + if (SimpleControl.unk98 != 0 && SimpleControl.unk9C == 0) { + var_r30 = 10; + if (arg0 == 0 && SimpleControl.unk3C.mNumFrames < 10) { + var_r30 = SimpleControl.unk3C.mNumFrames; + } + for (i = 0; i < var_r30; i++) { + if (DVDReadPrio(&SimpleControl.unk00, SimpleControl.unkCC[SimpleControl.unkB0].unk00, SimpleControl.unkB4, SimpleControl.unkA0, 2) < 0) { + SimpleControl.unkA4 = 1; + return 0; + } + SimpleControl.unkA0 += SimpleControl.unkB4; + SimpleControl.unkB4 = *SimpleControl.unkCC[SimpleControl.unkB0].unk00; + SimpleControl.unkCC[SimpleControl.unkB0].unk08 = 1; + SimpleControl.unkCC[SimpleControl.unkB0].unk04 = SimpleControl.unkB8; + if (SimpleControl.unkB0 + 1 >= 10) { + var_r29 = 0; + } else { + var_r29 = SimpleControl.unkB0 + 1; + } + SimpleControl.unkB0 = var_r29; + SimpleControl.unkB8++; + if (SimpleControl.unkB8 > SimpleControl.unk3C.mNumFrames - 1 && SimpleControl.unk9E == 1) { + SimpleControl.unkB8 = 0; + SimpleControl.unkA0 = SimpleControl.unk3C.mMovieDataOffsets; + SimpleControl.unkB4 = SimpleControl.unk3C.mFirstFrameSize; + } + } + SimpleControl.unk9E = arg0; + SimpleControl.unk9C = 1; + return 1; + } + return 0; +} + +void THPSimpleAudioStart(void) { + SimpleControl.unk9D = 1; +} + +void THPSimpleAudioStop(void) { + SimpleControl.unk9D = 0; +} + +s32 THPSimpleLoadStop(void) { + s32 i; + + if (SimpleControl.unk98 != 0 && SimpleControl.unk9D == 0) { + SimpleControl.unk9C = 0; + if (SimpleControl.unkA8 != 0) { + DVDCancel(&SimpleControl.unk00.cb); + SimpleControl.unkA8 = 0; + } + for (i = 0; i < 10; i++) { + SimpleControl.unkCC[i].unk08 = 0; + } + for (i = 0; i < 4; i++) { + SimpleControl.unk164[i].unk08 = 0; + } + SimpleControl.unk144[0].unk0C = -1; + SimpleControl.unkA0 = SimpleControl.unk3C.mMovieDataOffsets; + SimpleControl.unkB4 = SimpleControl.unk3C.mFirstFrameSize; + SimpleControl.unkB0 = 0; + SimpleControl.unkB8 = 0; + SimpleControl.unkA4 = 0; + SimpleControl.unkAC = 0; + SimpleControl.unk194 = 0; + SimpleControl.unk198 = 0; + SimpleControl.unkBC = SimpleControl.unkC0; + SimpleControl.unkC8 = 0; + return 1; + } + return 0; +} + +s32 THPSimpleDecode(void) { + u8 *var_r29; + s32 *var_r30; + s32 temp_r27; + s32 temp_r26; + s32 temp_r25; + s32 var_r28; + s32 i; + + if (SimpleControl.unkCC[SimpleControl.unkAC].unk08 != 0) { + var_r30 = SimpleControl.unkCC[SimpleControl.unkAC].unk00 + 2; + var_r29 = (u8*) (&SimpleControl.unkCC[SimpleControl.unkAC].unk00[SimpleControl.unk6C.mNumComponents] + 2); + if (SimpleControl.unk9F != 0) { + if (SimpleControl.unk164[SimpleControl.unk194].unk08 == 0) { + for (i = 0; i < SimpleControl.unk6C.mNumComponents; var_r29 += *var_r30, var_r30++, i++) { + switch (SimpleControl.unk6C.mFrameComp[i]) { + case 0: + if (VideoDecode(var_r29) == 0) { + return 1; + } + break; + case 1: + temp_r26 = THPAudioDecode(SimpleControl.unk164[SimpleControl.unk194].unk00, var_r29, 0); + temp_r27 = OSDisableInterrupts(); + SimpleControl.unk164[SimpleControl.unk194].unk08 = temp_r26; + SimpleControl.unk164[SimpleControl.unk194].unk04 = SimpleControl.unk164[SimpleControl.unk194].unk00; + OSRestoreInterrupts(temp_r27); + SimpleControl.unk194++; + if (SimpleControl.unk194 >= 4) { + SimpleControl.unk194 = 0; + } + break; + } + } + } else { + return 3; + } + } else { + for (i = 0; i < SimpleControl.unk6C.mNumComponents; var_r29 += *var_r30, var_r30++, i++) { + if ((s32) SimpleControl.unk6C.mFrameComp[i] != 0) { + (void) i; // required to match. Optimized out unreachable code? + } else if (VideoDecode(var_r29) == 0) { + return 1; + } + } + } + SimpleControl.unkCC[SimpleControl.unkAC].unk08 = 0; + if (SimpleControl.unkAC + 1 >= 10) { + var_r28 = 0; + } else { + var_r28 = SimpleControl.unkAC + 1; + } + SimpleControl.unkAC = var_r28; + temp_r25 = OSDisableInterrupts(); + if (SimpleControl.unkCC[SimpleControl.unkB0].unk08 == 0 && SimpleControl.unkA8 == 0 && SimpleControl.unkA4 == 0 && SimpleControl.unk9C == 1) { + THPSimpleInlineFunc(); + } + OSRestoreInterrupts(temp_r25); + return 0; + } else { + return 2; + } +} + +static s32 VideoDecode(void *arg0) { + s32 temp_r31; + + bufIdx = (bufIdx + 1) & 1; + temp_r31 = THPVideoDecode(arg0, SimpleControl.unk144[bufIdx].unk00, SimpleControl.unk144[bufIdx].unk04, SimpleControl.unk144[bufIdx].unk08, SimpleControl.unk94); + if (temp_r31 == 0) { + SimpleControl.unk144[0].unk0C = SimpleControl.unkCC[SimpleControl.unkAC].unk04; + return 1; + } + return 0; +} + +s32 THPSimpleDrawCurrentFrame(GXRenderModeObj *arg0, GXColor *arg1, Mtx arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6) { + if (SimpleControl.unk144[0].unk0C >= 0) { + THPGXYuv2RgbSetup(arg0, arg1, arg2); + THPGXYuv2RgbDraw(SimpleControl.unk144[bufIdx].unk00, SimpleControl.unk144[bufIdx].unk04, SimpleControl.unk144[bufIdx].unk08, arg3, arg4, SimpleControl.unk80.unk00, SimpleControl.unk80.unk04, arg5, arg6); + THPGXRestore(); + return SimpleControl.unk144[0].unk0C; + } + return -1; +} + +static u16 VolumeTable[] = { + 0x0000, 0x0002, 0x0008, 0x0012, 0x0020, 0x0032, 0x0049, 0x0063, + 0x0082, 0x00A4, 0x00CB, 0x00F5, 0x0124, 0x0157, 0x018E, 0x01C9, + 0x0208, 0x024B, 0x0292, 0x02DD, 0x032C, 0x037F, 0x03D7, 0x0432, + 0x0492, 0x04F5, 0x055D, 0x05C9, 0x0638, 0x06AC, 0x0724, 0x07A0, + 0x0820, 0x08A4, 0x092C, 0x09B8, 0x0A48, 0x0ADD, 0x0B75, 0x0C12, + 0x0CB2, 0x0D57, 0x0DFF, 0x0EAC, 0x0F5D, 0x1012, 0x10CA, 0x1187, + 0x1248, 0x130D, 0x13D7, 0x14A4, 0x1575, 0x164A, 0x1724, 0x1801, + 0x18E3, 0x19C8, 0x1AB2, 0x1BA0, 0x1C91, 0x1D87, 0x1E81, 0x1F7F, + 0x2081, 0x2187, 0x2291, 0x239F, 0x24B2, 0x25C8, 0x26E2, 0x2801, + 0x2923, 0x2A4A, 0x2B75, 0x2CA3, 0x2DD6, 0x2F0D, 0x3048, 0x3187, + 0x32CA, 0x3411, 0x355C, 0x36AB, 0x37FF, 0x3956, 0x3AB1, 0x3C11, + 0x3D74, 0x3EDC, 0x4048, 0x41B7, 0x432B, 0x44A3, 0x461F, 0x479F, + 0x4923, 0x4AAB, 0x4C37, 0x4DC7, 0x4F5C, 0x50F4, 0x5290, 0x5431, + 0x55D6, 0x577E, 0x592B, 0x5ADC, 0x5C90, 0x5E49, 0x6006, 0x61C7, + 0x638C, 0x6555, 0x6722, 0x68F4, 0x6AC9, 0x6CA2, 0x6E80, 0x7061, + 0x7247, 0x7430, 0x761E, 0x7810, 0x7A06, 0x7C00, 0x7DFE, 0x8000 +}; + +static void MixAudio(void *arg0, void *arg1, u32 arg2) { + s32 var_r31; + u32 var_r27; + u32 var_r28; + s32 i; + u16 temp_r24; + s16 *var_r26; + s16 *var_r30; + s16 *var_r29; + + if (arg1) { + if (SimpleControl.unk98 != 0 && SimpleControl.unk9D == 1 && SimpleControl.unk9F != 0) { + var_r28 = arg2; + var_r30 = arg0; + var_r26 = arg1; + while (1) { + if (SimpleControl.unk164[SimpleControl.unk198].unk08 == 0) { + break; + } + if (SimpleControl.unk164[SimpleControl.unk198].unk08 >= var_r28) { + var_r27 = var_r28; + } else { + var_r27 = SimpleControl.unk164[SimpleControl.unk198].unk08; + } + var_r29 = SimpleControl.unk164[SimpleControl.unk198].unk04; + for (i = 0; i < var_r27; i++) { + if (SimpleControl.unkC8 != 0) { + SimpleControl.unkC8--; + SimpleControl.unkBC += SimpleControl.unkC4; + } else { + SimpleControl.unkBC = SimpleControl.unkC0; + } + temp_r24 = VolumeTable[(s32) SimpleControl.unkBC]; + var_r31 = *var_r26 + ((temp_r24 * *var_r29) >> 0xF); + if (var_r31 < -0x8000) { + var_r31 = -0x8000; + } + if (var_r31 > 0x7FFF) { + var_r31 = 0x7FFF; + } + *var_r30 = var_r31; + var_r30++; + var_r26++; + var_r29++; + var_r31 = *var_r26 + ((temp_r24 * *var_r29) >> 0xF); + if (var_r31 < -0x8000) { + var_r31 = -0x8000; + } + if (var_r31 > 0x7FFF) { + var_r31 = 0x7FFF; + } + *var_r30 = var_r31; + var_r30++; + var_r26++; + var_r29++; + } + var_r28 -= var_r27; + SimpleControl.unk164[SimpleControl.unk198].unk08 -= var_r27; + SimpleControl.unk164[SimpleControl.unk198].unk04 = var_r29; + if (SimpleControl.unk164[SimpleControl.unk198].unk08 == 0) { + SimpleControl.unk198++; + if (SimpleControl.unk198 >= 4) { + SimpleControl.unk198 = 0; + } + } + if (var_r28 == 0) { + return; + } + } + memcpy(var_r30, var_r26, var_r28 * 4); + } else { + memcpy(arg0, arg1, arg2 * 4); + } + } else if (SimpleControl.unk98 != 0 && SimpleControl.unk9D == 1 && SimpleControl.unk9F != 0) { + var_r28 = arg2; + var_r30 = arg0; + while (1) { + if (SimpleControl.unk164[SimpleControl.unk198].unk08 == 0) { + break; + } + if (SimpleControl.unk164[SimpleControl.unk198].unk08 >= var_r28) { + var_r27 = var_r28; + } else { + var_r27 = SimpleControl.unk164[SimpleControl.unk198].unk08; + } + var_r29 = SimpleControl.unk164[SimpleControl.unk198].unk04; + for (i = 0; i < var_r27; i++) { + if (SimpleControl.unkC8 != 0) { + SimpleControl.unkC8--; + SimpleControl.unkBC += SimpleControl.unkC4; + } else { + SimpleControl.unkBC = SimpleControl.unkC0; + } + temp_r24 = VolumeTable[(s32) SimpleControl.unkBC]; + var_r31 = (temp_r24 * *var_r29) >> 0xF; + if (var_r31 < -0x8000) { + var_r31 = -0x8000; + } + if (var_r31 > 0x7FFF) { + var_r31 = 0x7FFF; + } + *var_r30 = var_r31; + var_r30++; + var_r29++; + var_r31 = (temp_r24 * *var_r29) >> 0xF; + if (var_r31 < -0x8000) { + var_r31 = -0x8000; + } + if (var_r31 > 0x7FFF) { + var_r31 = 0x7FFF; + } + *var_r30 = var_r31; + var_r30++; + var_r29++; + } + var_r28 -= var_r27; + SimpleControl.unk164[SimpleControl.unk198].unk08 -= var_r27; + SimpleControl.unk164[SimpleControl.unk198].unk04 = var_r29; + if (SimpleControl.unk164[SimpleControl.unk198].unk08 == 0) { + SimpleControl.unk198++; + if (SimpleControl.unk198 >= 4) { + SimpleControl.unk198 = 0; + } + } + if (var_r28 == 0) { + return; + } + } + memset(var_r30, 0, var_r28 * 4); + } else { + memset(arg0, 0, arg2 * 4); + } +} + +s32 THPSimpleGetVideoInfo(UnkThpStruct04 *arg0) { + if (SimpleControl.unk98 != 0) { + memcpy(arg0, &SimpleControl.unk80, 8); + return 1; + } + return 0; +} + +s32 THPSimpleGetTotalFrame(void) { + if (SimpleControl.unk98 != 0) { + return SimpleControl.unk3C.mNumFrames; + } + return 0; +} + +static void THPAudioMixCallback(void) { + s32 temp_r31; + + if (AudioSystem == 0) { + SoundBufferIndex ^= 1; + AIInitDMA((u32) SoundBuffer[SoundBufferIndex], sizeof(SoundBuffer[0])); + temp_r31 = OSEnableInterrupts(); + MixAudio(SoundBuffer[SoundBufferIndex], 0, 0xA0); + DCFlushRange(SoundBuffer[SoundBufferIndex], sizeof(SoundBuffer[0])); + OSRestoreInterrupts(temp_r31); + } else { + if (AudioSystem == 1) { + if (LastAudioBuffer) { + CurAudioBuffer = LastAudioBuffer; + } + OldAIDCallback(); + LastAudioBuffer = (u8*) AIGetDMAStartAddr() + 0x80000000; + } else { + OldAIDCallback(); + CurAudioBuffer = (u8*) AIGetDMAStartAddr() + 0x80000000; + } + SoundBufferIndex ^= 1; + AIInitDMA((u32) SoundBuffer[SoundBufferIndex], sizeof(SoundBuffer[0])); + temp_r31 = OSEnableInterrupts(); + if (CurAudioBuffer) { + DCInvalidateRange(CurAudioBuffer, sizeof(SoundBuffer[0])); + } + MixAudio(SoundBuffer[SoundBufferIndex], CurAudioBuffer, 0xA0); + DCFlushRange(SoundBuffer[SoundBufferIndex], sizeof(SoundBuffer[0])); + OSRestoreInterrupts(temp_r31); + } +} + +s32 THPSimpleSetVolume(s32 left, s32 right) { + s32 temp_r29; + + if (SimpleControl.unk98 != 0 && SimpleControl.unk9F != 0) { + if (left > 127) { + left = 127; + } + if (left < 0) { + left = 0; + } + if (right > 60000) { + right = 60000; + } + if (right < 0) { + right = 0; + } + temp_r29 = OSDisableInterrupts(); + SimpleControl.unkC0 = left; + if (right != 0) { + SimpleControl.unkC8 = (right << 5); + SimpleControl.unkC4 = (SimpleControl.unkC0 - SimpleControl.unkBC) / SimpleControl.unkC8; + } else { + SimpleControl.unkC8 = 0; + SimpleControl.unkBC = SimpleControl.unkC0; + } + OSRestoreInterrupts(temp_r29); + return 1; + } + return 0; +} diff --git a/src/game/thpmain.c b/src/game/thpmain.c new file mode 100755 index 00000000..1f8a68a9 --- /dev/null +++ b/src/game/thpmain.c @@ -0,0 +1,252 @@ +#include "game/thpmain.h" +#include "game/hsfdraw.h" +#include "game/hsfman.h" +#include "game/init.h" +#include "game/process.h" +#include "game/sprite.h" +#include "game/THPSimple.h" + +#include "string.h" + +static void THPTestProc(void); +static void THPViewFunc(ModelData *arg0, Mtx arg1); +static void THPViewSprFunc(SpriteData *arg0); +static void THPDecodeFunc(void *param); + +static char THPFileName[64]; + +static UnkThpStruct04 audioTrack; +static s32 decodeRate; +static u8 *decodeStackP; +static OSThread *decodeThread; +static s16 THPLoopF; +static s16 THPStat; +static u32 THPFrame; +static s16 THPStart; +Process *THPProc; + +s16 HuTHPSprCreateVol(char *path, s16 loop, s16 prio, float volume) { + s16 temp_r31; + + if (THPProc) { + return -1; + } + THPStart = 0; + THPProc = HuPrcCreate(THPTestProc, 0x64, 0x3000, 0); + if (THPProc == 0) { + return -1; + } + temp_r31 = HuSprFuncCreate(THPViewSprFunc, prio); + if (temp_r31 == -1) { + return -1; + } + THPSimpleInit(2); + SimpleControl.unk19C = 0; + SimpleControl.unk19E = temp_r31; + SimpleControl.unkBC = volume; + strcpy(THPFileName, path); + THPLoopF = loop; + THPStat = 0; + THPFrame = 0; + return temp_r31; +} + +s16 HuTHPSprCreate(char *path, s16 loop, s16 prio) { + return HuTHPSprCreateVol(path, loop, prio, 110.0f); +} + +s16 HuTHP3DCreateVol(char *path, s16 loop, float volume) { + s16 temp_r31; + + if (THPProc) { + return; + } + THPStart = 0; + THPProc = HuPrcCreate(THPTestProc, 0x64, 0x3000, 0); + if (THPProc == 0) { + return -1; + } + THPSimpleInit(2); + SimpleControl.unk19C = 1; + temp_r31 = Hu3DHookFuncCreate(&THPViewFunc); + SimpleControl.unk19E = temp_r31; + SimpleControl.unkBC = volume; + strcpy(THPFileName, path); + THPLoopF = loop; + THPStat = 0; + THPFrame = 0; + Hu3DModelAttrSet(SimpleControl.unk19E, 1); + return temp_r31; +} + +s16 HuTHP3DCreate(char *path, s16 loop) { + return HuTHP3DCreateVol(path, loop, 110.0f); +} + +void HuTHPStop(void) { + THPStat = 1; +} + +void HuTHPClose(void) { + THPStat = 2; +} + +void HuTHPRestart(void) { + THPStat = 3; +} + +BOOL HuTHPEndCheck(void) { + s32 temp_r31; + + temp_r31 = THPSimpleGetTotalFrame() - 1; + if (temp_r31 <= 0) { + return FALSE; + } + return (temp_r31 <= THPFrame); +} + +s32 HuTHPFrameGet(void) { + return THPFrame; +} + +s32 HuTHPTotalFrameGet(void) { + return THPSimpleGetTotalFrame(); +} + +void HuTHPSetVolume(s32 left, s32 right) { + THPSimpleSetVolume(left, right); +} + +static void THPTestProc(void) { + s32 temp_r29; + u32 var_r28; + void *temp_r30; + + while (THPSimpleOpen(THPFileName) == 0) { + OSReport("THPSimpleOpen fail"); + HuPrcVSleep(); + } + THPSimpleGetVideoInfo(&audioTrack); + temp_r29 = THPSimpleCalcNeedMemory(); + OSReport("Size %x\n", temp_r29); + temp_r30 = HuMemDirectMalloc(HEAP_DATA, temp_r29); + memset(temp_r30, 0, temp_r29); + DCFlushRange(temp_r30, temp_r29); + if (temp_r30 == 0) { + OSReport("Can't allocate the memory\n"); + } + THPSimpleSetBuffer(temp_r30); + while (THPSimplePreLoad(THPLoopF) == 0) { + OSReport("THPSimplePreLoad fail"); + HuPrcVSleep(); + } + HuPrcVSleep(); + decodeStackP = HuMemDirectMalloc(HEAP_SYSTEM, 0x2000); + decodeThread = OSSetIdleFunction(THPDecodeFunc, NULL, decodeStackP + 0x2000, 0x2000); + decodeRate = 0; + THPStart = 1; + if (SimpleControl.unk19C == 1) { + Hu3DModelAttrReset(SimpleControl.unk19E, 1); + } else { + HuSprAttrReset(SimpleControl.unk19E, 0, 4); + } + while (1) { + if (THPStat == 2) { + break; + } + switch (THPStat) { + case 0: + var_r28 = 1; + THPStat = 4; + break; + case 1: + THPSimpleAudioStop(); + THPSimpleLoadStop(); + break; + case 3: + THPSimpleAudioStop(); + THPSimpleLoadStop(); + while (THPSimplePreLoad(THPLoopF) == 0) { + OSReport("THPSimplePreLoad fail"); + HuPrcVSleep(); + } + THPStat = 0; + var_r28 = 1; + break; + } + if (var_r28 != 0) { + THPSimpleAudioStart(); + var_r28 = 0; + } + HuPrcVSleep(); + } + if (SimpleControl.unk19C == 1) { + Hu3DModelKill(SimpleControl.unk19E); + } else { + HuSprKill(SimpleControl.unk19E); + } + OSCancelThread(decodeThread); + HuMemDirectFree(decodeStackP); + THPSimpleAudioStop(); + THPSimpleLoadStop(); + THPSimpleClose(); + HuMemDirectFree(temp_r30); + THPSimpleQuit(); + THPProc = NULL; + HuPrcKill(HuPrcCurrentGet()); + while (1) { + HuPrcVSleep(); + } +} + +static void THPViewFunc(ModelData *arg0, Mtx arg1) { + GXColor spC = { 0xFF, 0xFF, 0xFF, 0xFF }; + + if (THPStart != 0) { + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + GXSetCullMode(GX_CULL_NONE); + THPFrame = THPSimpleDrawCurrentFrame(RenderMode, &spC, arg1, -audioTrack.unk00 / 2, audioTrack.unk04 / 2, audioTrack.unk00, -audioTrack.unk04); + THPSimpleAudioStart(); + } +} + +static void THPViewSprFunc(SpriteData *arg0) { + Vec spC = { 0.0f, 0.0f, 1.0f }; + GXColor sp8; + s32 temp_r30; + s32 temp_r29; + Mtx sp48; + Mtx sp18; + + if (THPStart != 0) { + sp8.r = arg0->r; + sp8.g = arg0->g; + sp8.b = arg0->b; + sp8.a = arg0->a; + if (arg0->z_rot != 0.0f) { + PSMTXRotAxisRad(sp18, &spC, MTXDegToRad(arg0->z_rot)); + PSMTXScale(sp48, arg0->scale_x, arg0->scale_y, 1.0f); + PSMTXConcat(sp18, sp48, sp48); + } else { + PSMTXScale(sp48, arg0->scale_x, arg0->scale_y, 1.0f); + } + mtxTransCat(sp48, arg0->x, arg0->y, 0.0f); + PSMTXConcat(*arg0->group_mtx, sp48, sp48); + temp_r30 = -((s32) audioTrack.unk00 / 2); + temp_r29 = -((s32) audioTrack.unk04 / 2); + GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE); + THPFrame = THPSimpleDrawCurrentFrame(RenderMode, &sp8, sp48, temp_r30, temp_r29, audioTrack.unk00, audioTrack.unk04); + } +} + +static void THPDecodeFunc(void *param) { + while (1) { + if (THPStat == 2) { + break; + } + if (THPSimpleDecode() == 1) { + OSReport("Fail to decode video data"); + } + VIWaitForRetrace(); + } +}