Initial THP import

Former-commit-id: 925d0a3b945e57ae1e366a48fd97b6eaf7bbf044
This commit is contained in:
Phillip Stephens 2023-10-20 15:35:06 -07:00
parent 0972b17732
commit bb7c4c10ae
12 changed files with 2967 additions and 0 deletions

88
include/dolphin/thp.h Normal file
View File

@ -0,0 +1,88 @@
#ifndef _DOLPHIN_THP
#define _DOLPHIN_THP
#include "dolphin/types.h"
#include "dolphin/thp/THPAudio.h"
#include "dolphin/thp/THPVideoDecode.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef u8 THPSample;
typedef s16 THPCoeff;
typedef f32 THPQuantTab[64];
typedef struct _THPHuffmanTab {
u8 quick[32];
u8 increment[32];
u8* Vij;
s32 maxCode[18];
s32 valPtr[18];
u8 Vij1;
u8 pad[11];
} THPHuffmanTab;
typedef struct _THPComponent {
u8 quantizationTableSelector;
u8 DCTableSelector;
u8 ACTableSelector;
THPCoeff predDC;
} THPComponent;
typedef struct _THPFileInfo {
THPQuantTab quantTabs[3];
THPHuffmanTab huffmanTabs[4];
THPComponent components[3];
u16 xPixelSize;
u16 yPixelSize;
u16 MCUsPerRow;
u16 decompressedY;
u8* c;
u32 currByte;
u32 cnt;
u8 validHuffmanTabs;
u8 RST;
u16 nMCU;
u16 currMCU;
u8* dLC[3];
} THPFileInfo;
s32 __THPAudioGetNewSample(THPAudioDecodeInfo*);
void __THPAudioInitialize(THPAudioDecodeInfo*, u8*);
static void __THPSetupBuffers(void);
static u8 __THPReadFrameHeader(void);
static u8 __THPReadScaneHeader(void);
static u8 __THPReadQuantizationTable(void);
static u8 __THPReadHuffmanTableSpecification(void);
static void __THPHuffGenerateSizeTable(void);
static void __THPHuffGenerateCodeTable(void);
static void __THPHuffGenerateDecoderTables(u8 tabIndex);
static void __THPRestartDefinition(void);
static void __THPPrepBitStream(void);
static void __THPDecompressYUV(void*, void*, void*);
static void __THPGQRRestore(void);
static void __THPDecompressiMCURow512x448(void);
static void __THPDecompressiMCURow640x480(void);
static void __THPDecompressiMCURowNxN(void);
static void __THPInverseDCTNoYPos(THPCoeff*, u32);
static void __THPHuffDecodeDCTCompY(THPFileInfo*, THPCoeff*);
static void __THPHuffDecodeDCTCompU(THPFileInfo*, THPCoeff*);
static void __THPHuffDecodeDCTCompV(THPFileInfo*, THPCoeff*);
static const u8 __THPJpegNaturalOrder[80] = {
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33,
40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54,
47, 55, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63};
static const f64 __THPAANScaleFactor[8] = {
1.0f, 1.387039845f, 1.306562965f, 1.175875602f, 1.0f, 0.785694958f, 0.541196100f, 0.275899379f,
};
#ifdef __cplusplus
}
#endif
#endif // _DOLPHIN_THP

View File

@ -0,0 +1,38 @@
#ifndef _DOLPHIN_THPAUDIO
#define _DOLPHIN_THPAUDIO
#include "dolphin/types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct THPAudioRecordHeader {
u32 offsetNextChannel;
u32 sampleSize;
s16 lCoef[8][2];
s16 rCoef[8][2];
s16 lYn1;
s16 lYn2;
s16 rYn1;
s16 rYn2;
} THPAudioRecordHeader;
typedef struct THPAudioDecodeInfo {
u8* encodeData;
u32 offsetNibbles;
u8 predictor;
u8 scale;
s16 yn1;
s16 yn2;
} THPAudioDecodeInfo;
u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag);
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info);
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr);
#ifdef __cplusplus
}
#endif
#endif // _DOLPHIN_THPAUDIO

View File

@ -0,0 +1,29 @@
#ifndef _THP_THPAUDIODECODE_H
#define _THP_THPAUDIODECODE_H
#include "Dolphin/os.h"
#include "THP/THPAudio.h"
static void* AudioDecoderForOnMemory(void* bufPtr);
static void* AudioDecoder(void* _);
static void AudioDecode(THPReadBuffer* readBuffer);
#ifdef __cplusplus
extern "C" {
#endif
BOOL CreateAudioDecodeThread(OSPriority prio, void* param);
void AudioDecodeThreadStart();
void AudioDecodeThreadCancel();
void PushFreeAudioBuffer(void* buf);
void PushDecodedAudioBuffer(void* buf);
void* PopFreeAudioBuffer();
void* PopDecodedAudioBuffer(s32 flags);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,36 @@
#ifndef _THP_THPBUFFER_H
#define _THP_THPBUFFER_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Size 0x10
typedef struct THPTextureSet {
u8* mYTexture; // _00
u8* mUTexture; // _04
u8* mVTexture; // _08
s32 mFrameNumber; // _0C
} THPTextureSet;
// Size 0xC
typedef struct THPAudioBuffer {
s16* mBuffer; // _00
s16* mCurPtr; // _04
u32 mValidSample; // _08
} THPAudioBuffer;
// Size 0xC
typedef struct THPReadBuffer {
u8* mPtr; // _00
s32 mFrameNumber; // _04
BOOL mIsValid; // _08
} THPReadBuffer;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,21 @@
#ifndef _THP_THPDRAW_H
#define _THP_THPDRAW_H
#include "types.h"
#include "Dolphin/GX/GXTypes.h"
#ifdef __cplusplus
extern "C" {
#endif // ifdef __cplusplus
void THPGXRestore(void);
void THPGXYuv2RgbSetup(GXRenderModeObj* obj);
void THPGXYuv2RgbDraw(u32* yImage, u32* uImage, u32* vImage, s16 x, s16 y, s16 texWidth, s16 texHeight, s16 polyWidth, s16 polyHeight);
void THPPlayerStop();
BOOL THPPlayerSetVolume(int, int);
#ifdef __cplusplus
};
#endif // ifdef __cplusplus
#endif

View File

@ -0,0 +1,30 @@
#ifndef _THP_THPFILE_H
#define _THP_THPFILE_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Size 0x30
typedef struct THPHeader {
char mMagic[4]; // _00
u32 mVersion; // _04
u32 mBufferSize; // _08
u32 mAudioMaxSamples; // _0C
f32 mFrameRate; // _10
u32 mNumFrames; // _14
u32 mFirstFrameSize; // _18
u32 mMovieDataSize; // _1C
u32 mCompInfoDataOffsets; // _20
u32 mOffsetDataOffsets; // _24
u32 mMovieDataOffsets; // _28
u32 mFinalFrameDataOffsets; // _2C
} THPHeader;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,35 @@
#ifndef _THP_THPINFO_H
#define _THP_THPINFO_H
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
// Size 0xC
typedef struct THPVideoInfo {
u32 mXSize; // _00
u32 mYSize; // _04
u32 mVideoType; // _08
} THPVideoInfo;
// Size 0x10
typedef struct THPAudioInfo {
u32 mSndChannels; // _00
u32 mSndFrequency; // _04
u32 mSndNumSamples; // _08
u32 mSndNumTracks; // _0C
} THPAudioInfo;
// Size 0x14
typedef struct THPFrameCompInfo {
u32 mNumComponents; // _00
u8 mFrameComp[16]; // _04
} THPFrameCompInfo;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,91 @@
#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
// Size: 0x1D0
typedef struct THPPlayer {
DVDFileInfo mFileInfo; // _00
THPHeader mHeader; // _3C
THPFrameCompInfo mCompInfo; // _6C
THPVideoInfo mVideoInfo; // _80
THPAudioInfo mAudioInfo; // _8C
void* mThpWorkArea; // _9C
BOOL mIsOpen; // _A0
u8 mState; // _A4
u8 mInternalState; // _A5
u8 mPlayFlag; // _A6
u8 mAudioExist; // _A7
s32 mDvdError; // _A8
s32 mVideoError; // _AC
BOOL mIsOnMemory; // _B0
u8* mMovieData; // _B4
s32 mInitOffset; // _B8
s32 mInitReadSize; // _BC
s32 mInitReadFrame; // _C0
u32 mCurField; // _C4
s64 mRetraceCount; // _C8
s32 mPrevCount; // _D0
s32 mCurCount; // _D4
s32 mVideoDecodeCount; // _D8
f32 mCurVolume; // _DC
f32 mTargetVolume; // _E0
f32 mDeltaVolume; // _E4
s32 mRampCount; // _E8
s32 mCurAudioTrack; // _EC
s32 mCurVideoNumber; // _F0
s32 mCurAudioNumber; // _F4
THPTextureSet* mDispTextureSet; // _F8
THPAudioBuffer* mPlayAudioBuffer; // _FC
THPReadBuffer mReadBuffer[10]; // _100
THPTextureSet mTextureSet[3]; // _178
THPAudioBuffer mAudioBuffer[3]; // _1A8
} THPPlayer;
extern THPPlayer ActivePlayer;
BOOL THPPlayerInit(int _);
void THPPlayerQuit();
BOOL THPPlayerOpen(const char* fileName, BOOL onMemory);
BOOL THPPlayerClose();
BOOL THPPlayerPlay();
void THPPlayerStop();
BOOL THPPlayerPause();
BOOL THPPlayerPrepare(int offset, u8 flag, int audioTrack);
BOOL THPPlayerSetBuffer(u8* data);
u32 THPPlayerCalcNeedMemory();
BOOL THPPlayerGetVideoInfo(void* dst);
BOOL THPPlayerGetAudioInfo(void* dst);
// f32 THPPlayerGetFrameRate();
BOOL THPPlayerSetVolume(int vol, int duration);
int THPPlayerDrawCurrentFrame(GXRenderModeObj* obj, int x, int y, int polyWidth,
int polyHeight); // TODO, parameter names from dwarf info if it exists
u32 THPPlayerGetTotalFrame();
u8 THPPlayerGetState();
void THPPlayerDrawDone();
void THPPlayerPostDrawDone();
// this should go in a dolphin THP header eventually
BOOL THPInit(void);
#ifdef __cplusplus
}
#endif
void PrepareReady(int msg);
#endif /* _THP_THPPLAYER_H */

View File

@ -0,0 +1,28 @@
#ifndef _THP_THPREAD_H
#define _THP_THPREAD_H
#include "dolphin/thp/THPBuffer.h"
#include "dolphin/os.h"
static void* Reader(void* arg);
#ifdef __cplusplus
extern "C" {
#endif // ifdef __cplusplus
BOOL CreateReadThread(OSPriority priority);
void ReadThreadStart();
void ReadThreadCancel();
OSMessage PopReadedBuffer();
BOOL PushReadedBuffer(OSMessage*);
OSMessage PopFreeReadBuffer();
BOOL PushFreeReadBuffer(OSMessage*);
OSMessage PopReadedBuffer2();
BOOL PushReadedBuffer2(OSMessage*);
extern u8 gTHPReaderDvdAccess;
#ifdef __cplusplus
};
#endif
#endif

View File

@ -0,0 +1,31 @@
#ifndef _DOLPHIN_THPVIDEODECODE
#define _DOLPHIN_THPVIDEODECODE
#include "dolphin/thp/THPRead.h"
static void* VideoDecoder(void*);
static void* VideoDecoderForOnMemory(void*);
static void VideoDecode(THPReadBuffer*);
#ifdef __cplusplus
extern "C" {
#endif // ifdef __cplusplus
s32 THPVideoDecode(void* file, void* tileY, void* tileU, void* tileV, void* work);
BOOL CreateVideoDecodeThread(OSPriority priority, void* task);
void VideoDecodeThreadStart();
void VideoDecodeThreadCancel();
OSMessage PopFreeTextureSet();
BOOL PushFreeTextureSet(OSMessage*);
OSMessage PopDecodedTextureSet(s32 flags);
BOOL PushDecodedTextureSet(OSMessage*);
extern BOOL VideoDecodeThreadCreated;
extern OSMessageQueue FreeTextureSetQueue;
extern OSMessageQueue DecodedTextureSetQueue;
extern OSThread VideoDecodeThread;
#ifdef __cplusplus
};
#endif
#endif // _DOLPHIN_THPVIDEODECODE

170
src/Dolphin/thp/THPAudio.c Normal file
View File

@ -0,0 +1,170 @@
#include <dolphin/thp.h>
/*
* --INFO--
* Address: 800FE6B0
* Size: 0003B0
*/
u32 THPAudioDecode(s16* audioBuffer, u8* audioFrame, s32 flag) {
THPAudioRecordHeader* header;
THPAudioDecodeInfo decInfo;
u8 *left, *right;
s16 *decLeftPtr, *decRightPtr;
s16 yn1, yn2;
s32 i;
s32 step;
s32 sample;
s64 yn;
if (audioBuffer == NULL || audioFrame == NULL) {
return 0;
}
header = (THPAudioRecordHeader*)audioFrame;
left = audioFrame + sizeof(THPAudioRecordHeader);
right = left + header->offsetNextChannel;
if (flag == 1) {
decRightPtr = audioBuffer;
decLeftPtr = audioBuffer + header->sampleSize;
step = 1;
} else {
decRightPtr = audioBuffer;
decLeftPtr = audioBuffer + 1;
step = 2;
}
if (header->offsetNextChannel == 0) {
__THPAudioInitialize(&decInfo, left);
yn1 = header->lYn1;
yn2 = header->lYn2;
for (i = 0; i < header->sampleSize; i++) {
sample = __THPAudioGetNewSample(&decInfo);
yn = header->lCoef[decInfo.predictor][1] * yn2;
yn += header->lCoef[decInfo.predictor][0] * yn1;
yn += (sample << decInfo.scale) << 11;
yn <<= 5;
if (sample > 0x8000) {
yn += 0x10000;
} else if ((sample == 0x8000) && ((yn & 0x10000) != 0)) {
yn += 0x10000;
}
yn += 0x8000;
if (yn > 2147483647LL) {
yn = 2147483647LL;
}
if (yn < -2147483648LL) {
yn = -2147483648LL;
}
*decLeftPtr = (s16)(yn >> 16);
decLeftPtr += step;
*decRightPtr = (s16)(yn >> 16);
decRightPtr += step;
yn2 = yn1;
yn1 = (s16)(yn >> 16);
}
} else {
__THPAudioInitialize(&decInfo, left);
yn1 = header->lYn1;
yn2 = header->lYn2;
for (i = 0; i < header->sampleSize; i++) {
sample = __THPAudioGetNewSample(&decInfo);
yn = header->lCoef[decInfo.predictor][1] * yn2;
yn += header->lCoef[decInfo.predictor][0] * yn1;
yn += (sample << decInfo.scale) << 11;
yn <<= 5;
yn += 0x8000;
if (yn > 2147483647LL) {
yn = 2147483647LL;
}
if (yn < -2147483648LL) {
yn = -2147483648LL;
}
*decLeftPtr = (s16)(yn >> 16);
decLeftPtr += step;
yn2 = yn1;
yn1 = (s16)(yn >> 16);
}
__THPAudioInitialize(&decInfo, right);
yn1 = header->rYn1;
yn2 = header->rYn2;
for (i = 0; i < header->sampleSize; i++) {
sample = __THPAudioGetNewSample(&decInfo);
yn = header->rCoef[decInfo.predictor][1] * yn2;
yn += header->rCoef[decInfo.predictor][0] * yn1;
yn += (sample << decInfo.scale) << 11;
yn <<= 5;
yn += 0x8000;
if (yn > 2147483647LL) {
yn = 2147483647LL;
}
if (yn < -2147483648LL) {
yn = -2147483648LL;
}
*decRightPtr = (s16)(yn >> 16);
decRightPtr += step;
yn2 = yn1;
yn1 = (s16)(yn >> 16);
}
}
return header->sampleSize;
}
/*
* --INFO--
* Address: 800FEA60
* Size: 000090
*/
static s32 __THPAudioGetNewSample(THPAudioDecodeInfo* info) {
s32 sample;
if (!(info->offsetNibbles & 0x0f)) {
info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4);
info->scale = (u8)((*(info->encodeData) & 0xF));
info->encodeData++;
info->offsetNibbles += 2;
}
if (info->offsetNibbles & 0x1) {
sample = (s32)((*(info->encodeData) & 0xF) << 28) >> 28;
info->encodeData++;
} else {
sample = (s32)((*(info->encodeData) & 0xF0) << 24) >> 28;
}
info->offsetNibbles++;
return sample;
}
/*
* --INFO--
* Address: 800FEAF0
* Size: 00003C
*/
static void __THPAudioInitialize(THPAudioDecodeInfo* info, u8* ptr) {
info->encodeData = ptr;
info->offsetNibbles = 2;
info->predictor = (u8)((*(info->encodeData) & 0x70) >> 4);
info->scale = (u8)((*(info->encodeData) & 0xF));
info->encodeData++;
}

2370
src/Dolphin/thp/THPDec.c Normal file

File diff suppressed because it is too large Load Diff