Match and link THPRead

This commit is contained in:
SwareJonge 2023-08-25 23:23:06 +02:00
parent a8d640de30
commit e1d2415f6e
8 changed files with 353 additions and 150 deletions

View File

@ -642,6 +642,11 @@ src/Kaneshige/THP/THPPlayer.c:
.sbss: [0x80416850, 0x80416868] .sbss: [0x80416850, 0x80416868]
.sdata2: [0x8041a690, 0x8041a6c0] .sdata2: [0x8041a690, 0x8041a6c0]
src/Kaneshige/THP/THPRead.c:
.text: [0x801dc4d4, 0x801dc7f0]
.bss: [0x803cd618, 0x803cea08]
.sbss: [0x80416870, 0x80416878]
src/Osako/clock.cpp: src/Osako/clock.cpp:
.text: [0x801f6e04, 0x801f6e9c] .text: [0x801f6e04, 0x801f6e9c]
.sbss: [0x804168c8, 0x804168d8] .sbss: [0x804168c8, 0x804168d8]

View File

@ -609,6 +609,11 @@ src/Kaneshige/THP/THPPlayer.c:
.sbss: [0x803d5ab8, 0x803d5ad0] .sbss: [0x803d5ab8, 0x803d5ad0]
.sdata2: [0x803d8ea0, 0x803d8ec0] .sdata2: [0x803d8ea0, 0x803d8ec0]
src/Kaneshige/THP/THPRead.c:
.text: [0x801b41dc, 0x801b44f8]
.bss: [0x8038d118, 0x8038e508]
.sbss: [0x803d5ad8, 0x803d5ae0]
src/Osako/clock.cpp: src/Osako/clock.cpp:
.text: [0x801cbe60, 0x801cbef8] .text: [0x801cbe60, 0x801cbef8]
.sbss: [0x803d5b30, 0x803d5b40] .sbss: [0x803d5b30, 0x803d5b40]

View File

@ -12,7 +12,12 @@ BOOL CreateReadThread(OSPriority prio);
void ReadThreadStart(); void ReadThreadStart();
void ReadThreadCancel(); void ReadThreadCancel();
void PushFreeReadBuffer(OSMessage msg); void *PopReadedBuffer();
void *PopFreeReadBuffer();
void *PopReadedBuffer2();
void *PushReadedBuffer(void *buffer);
void PushFreeReadBuffer(void *buffer);
void PushReadedBuffer2(void *buffer);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -8,75 +8,80 @@ extern "C"
#include <dolphin/os/OSContext.h> #include <dolphin/os/OSContext.h>
typedef struct OSThread OSThread; #define OS_THREAD_SPECIFIC_MAX 2
typedef struct OSThreadQueue OSThreadQueue;
typedef struct OSThreadLink OSThreadLink;
typedef s32 OSPriority; // 0 highest, 31 lowest
typedef struct OSMutex OSMutex; typedef struct OSThread OSThread;
typedef struct OSMutexQueue OSMutexQueue; typedef struct OSThreadQueue OSThreadQueue;
typedef struct OSMutexLink OSMutexLink; typedef struct OSThreadLink OSThreadLink;
typedef struct OSCond OSCond; typedef s32 OSPriority; // 0 highest, 31 lowest
typedef void (*OSIdleFunction)(void *param); typedef struct OSMutex OSMutex;
typedef struct OSMutexQueue OSMutexQueue;
typedef struct OSMutexLink OSMutexLink;
typedef struct OSCond OSCond;
struct OSThreadQueue typedef void (*OSIdleFunction)(void *param);
{ typedef void *(*OSThreadFunc)(void *arg);
OSThread *head;
OSThread *tail;
};
struct OSThreadLink struct OSThreadQueue
{ {
OSThread *next; OSThread *head;
OSThread *prev; OSThread *tail;
}; };
struct OSMutexQueue struct OSThreadLink
{ {
OSMutex *head; OSThread *next;
OSMutex *tail; OSThread *prev;
}; };
struct OSMutexLink struct OSMutexQueue
{ {
OSMutex *next; OSMutex *head;
OSMutex *prev; OSMutex *tail;
}; };
struct OSThread struct OSMutexLink
{ {
OSContext context; // register context OSMutex *next;
OSMutex *prev;
};
u16 state; // OS_THREAD_STATE_* struct OSThread
u16 attr; // OS_THREAD_ATTR_* {
s32 suspend; // suspended if the count is greater than zero OSContext context; // register context
OSPriority priority; // effective scheduling priority
OSPriority base; // base scheduling priority
void *val; // exit value
OSThreadQueue *queue; // queue thread is on u16 state; // OS_THREAD_STATE_*
OSThreadLink link; // queue link u16 attr; // OS_THREAD_ATTR_*
s32 suspend; // suspended if the count is greater than zero
OSPriority priority; // effective scheduling priority
OSPriority base; // base scheduling priority
void *val; // exit value
OSThreadQueue queueJoin; // list of threads waiting for termination (join) OSThreadQueue *queue; // queue thread is on
OSThreadLink link; // queue link
OSMutex *mutex; // mutex trying to lock OSThreadQueue queueJoin; // list of threads waiting for termination (join)
OSMutexQueue queueMutex; // list of mutexes owned
OSThreadLink linkActive; // link of all threads for debugging OSMutex *mutex; // mutex trying to lock
OSMutexQueue queueMutex; // list of mutexes owned
u8 *stackBase; // the thread's designated stack (high address) OSThreadLink linkActive; // link of all threads for debugging
u32 *stackEnd; // last word of stack (low address)
};
// Thread states u8 *stackBase; // the thread's designated stack (high address)
enum OS_THREAD_STATE u32 *stackEnd; // last word of stack (low address)
{ s32 error;
OS_THREAD_STATE_READY = 1, void *specific[OS_THREAD_SPECIFIC_MAX];
OS_THREAD_STATE_RUNNING = 2, };
OS_THREAD_STATE_WAITING = 4,
OS_THREAD_STATE_MORIBUND = 8 // Thread states
}; enum OS_THREAD_STATE
{
OS_THREAD_STATE_READY = 1,
OS_THREAD_STATE_RUNNING = 2,
OS_THREAD_STATE_WAITING = 4,
OS_THREAD_STATE_MORIBUND = 8
};
// Thread priorities // Thread priorities
#define OS_PRIORITY_MIN 0 // highest #define OS_PRIORITY_MIN 0 // highest
@ -96,13 +101,8 @@ BOOL OSIsThreadTerminated(OSThread *thread);
s32 OSDisableScheduler(void); s32 OSDisableScheduler(void);
s32 OSEnableScheduler(void); s32 OSEnableScheduler(void);
void OSYieldThread(void); void OSYieldThread(void);
BOOL OSCreateThread(OSThread *thread, BOOL OSCreateThread(OSThread *thread, OSThreadFunc func, void *funcArg,
void *(*func)(void *), void *stackBegin, u32 stackSize, OSPriority prio, u16 flags);
void *param,
void *stack,
u32 stackSize,
OSPriority priority,
u16 attr);
void OSExitThread(void *val); void OSExitThread(void *val);
void OSCancelThread(OSThread *thread); void OSCancelThread(OSThread *thread);
BOOL OSJoinThread(OSThread *thread, void **val); BOOL OSJoinThread(OSThread *thread, void **val);
@ -115,9 +115,9 @@ void OSSleepThread(OSThreadQueue *queue);
void OSWakeupThread(OSThreadQueue *queue); void OSWakeupThread(OSThreadQueue *queue);
OSThread *OSSetIdleFunction(OSIdleFunction idleFunction, OSThread *OSSetIdleFunction(OSIdleFunction idleFunction,
void *param, void *param,
void *stack, void *stack,
u32 stackSize); u32 stackSize);
OSThread *OSGetIdleFunction(void); OSThread *OSGetIdleFunction(void);
long OSCheckActiveThreads(void); long OSCheckActiveThreads(void);

View File

@ -71,7 +71,7 @@ void JKRThread::setCommon_mesgQueue(JKRHeap* heap, int msgCount)
mMesgBuffer = (OSMessage*)JKRHeap::alloc(mMessageCount << 2, 0, heap); mMesgBuffer = (OSMessage*)JKRHeap::alloc(mMessageCount << 2, 0, heap);
JUT_ASSERT(mMesgBuffer); JUT_ASSERT(mMesgBuffer);
OSInitMessageQueue(&mMessageQueue, (void**)mMesgBuffer, mMessageCount); OSInitMessageQueue(&mMessageQueue, mMesgBuffer, mMessageCount);
JKRThread::sThreadList.append(&mThreadListLink); JKRThread::sThreadList.append(&mThreadListLink);
mCurrentHeap = nullptr; mCurrentHeap = nullptr;
mCurrentHeapError = nullptr; mCurrentHeapError = nullptr;
@ -85,8 +85,8 @@ BOOL JKRThread::setCommon_heapSpecified(JKRHeap* heap, unsigned long stackSize,
mStackMemory = JKRHeap::alloc(mStackSize, 0x20, mHeap); mStackMemory = JKRHeap::alloc(mStackSize, 0x20, mHeap);
JUT_ASSERT(mStackMemory); JUT_ASSERT(mStackMemory);
// maybe a custom struct is used here, investigate someday #line 167
mThreadRecord = (OSThread*)JKRHeap::alloc(sizeof(OSThread) + 8, 0x20, mHeap); mThreadRecord = (OSThread*)JKRHeap::alloc(sizeof(OSThread), 0x20, mHeap);
JUT_ASSERT(mThreadRecord); JUT_ASSERT(mThreadRecord);
return OSCreateThread(mThreadRecord, &JKRThread::start, this, (void*)((u32)mStackMemory + mStackSize), mStackSize, threadPriority, 1); return OSCreateThread(mThreadRecord, &JKRThread::start, this, (void*)((u32)mStackMemory + mStackSize), mStackSize, threadPriority, 1);
} }

View File

@ -51,7 +51,7 @@ u16 VolumeTable[128] = {
}; };
// clang-format on // clang-format on
// static functions definitions // static function definitions
static s16 *audioCallback(s32 p1); static s16 *audioCallback(s32 p1);
static void MixAudio(s16 *, u32); static void MixAudio(s16 *, u32);
static void *PopUsedTextureSet(); static void *PopUsedTextureSet();
@ -89,7 +89,6 @@ static void quitAudio()
BOOL THPPlayerInit() BOOL THPPlayerInit()
{ {
memset(&ActivePlayer, 0, sizeof(THPPlayer)); memset(&ActivePlayer, 0, sizeof(THPPlayer));
LCEnable(); LCEnable();
OSInitMessageQueue(&UsedTextureSetQueue, UsedTextureSetMessage, 3); OSInitMessageQueue(&UsedTextureSetQueue, UsedTextureSetMessage, 3);
@ -121,7 +120,7 @@ void THPPlayerQuit()
BOOL THPPlayerOpen(const char *fileName, BOOL onMemory) BOOL THPPlayerOpen(const char *fileName, BOOL onMemory)
{ {
u32 readOffset; u32 readOffset;
int i; s32 i;
if (Initialized == FALSE) if (Initialized == FALSE)
{ {
@ -247,14 +246,16 @@ BOOL THPPlayerClose()
u32 THPPlayerCalcNeedMemory() u32 THPPlayerCalcNeedMemory()
{ {
if(ActivePlayer.open) { if (ActivePlayer.open)
{
u32 size = ActivePlayer.onMemory ? ALIGN_NEXT(ActivePlayer.header.movieDataSize, 32) : ALIGN_NEXT(ActivePlayer.header.bufsize, 32) * 10; u32 size = ActivePlayer.onMemory ? ALIGN_NEXT(ActivePlayer.header.movieDataSize, 32) : ALIGN_NEXT(ActivePlayer.header.bufsize, 32) * 10;
size += ALIGN_NEXT(ActivePlayer.videoInfo.xSize * ActivePlayer.videoInfo.ySize, 32) * 3; size += ALIGN_NEXT(ActivePlayer.videoInfo.xSize * ActivePlayer.videoInfo.ySize, 32) * 3;
size += ALIGN_NEXT(ActivePlayer.videoInfo.xSize * ActivePlayer.videoInfo.ySize / 4, 32) * 3; size += ALIGN_NEXT(ActivePlayer.videoInfo.xSize * ActivePlayer.videoInfo.ySize / 4, 32) * 3;
size += ALIGN_NEXT(ActivePlayer.videoInfo.xSize * ActivePlayer.videoInfo.ySize / 4, 32) * 3; size += ALIGN_NEXT(ActivePlayer.videoInfo.xSize * ActivePlayer.videoInfo.ySize / 4, 32) * 3;
if(ActivePlayer.audioExist) { if (ActivePlayer.audioExist)
{
size += ALIGN_NEXT(ActivePlayer.header.audioMaxSamples * 4, 32) * 6; size += ALIGN_NEXT(ActivePlayer.header.audioMaxSamples * 4, 32) * 6;
} }
return size + 0x1000; return size + 0x1000;
@ -268,13 +269,16 @@ BOOL THPPlayerSetBuffer(u8 *data)
u32 ySampleSize; u32 ySampleSize;
u32 uvSampleSize; u32 uvSampleSize;
s32 i; s32 i;
if(ActivePlayer.open && ActivePlayer.state == 0) { if (ActivePlayer.open && ActivePlayer.state == 0)
{
u8 *workPtr = data; u8 *workPtr = data;
if(ActivePlayer.onMemory) { if (ActivePlayer.onMemory)
{
ActivePlayer.movieData = data; ActivePlayer.movieData = data;
workPtr += ActivePlayer.header.movieDataSize; workPtr += ActivePlayer.header.movieDataSize;
} }
else { else
{
for (i = 0; i < ARRAY_SIZE(ActivePlayer.readBuffer); i++) for (i = 0; i < ARRAY_SIZE(ActivePlayer.readBuffer); i++)
{ {
ActivePlayer.readBuffer[i].ptr = workPtr; ActivePlayer.readBuffer[i].ptr = workPtr;
@ -295,14 +299,16 @@ BOOL THPPlayerSetBuffer(u8 *data)
ActivePlayer.textureSet[i].utexture = workPtr; ActivePlayer.textureSet[i].utexture = workPtr;
DCInvalidateRange(workPtr, uvSampleSize); DCInvalidateRange(workPtr, uvSampleSize);
workPtr += uvSampleSize; workPtr += uvSampleSize;
ActivePlayer.textureSet[i].vtexture = workPtr; ActivePlayer.textureSet[i].vtexture = workPtr;
DCInvalidateRange(workPtr, uvSampleSize); DCInvalidateRange(workPtr, uvSampleSize);
workPtr += uvSampleSize; workPtr += uvSampleSize;
} }
if(ActivePlayer.audioExist) { if (ActivePlayer.audioExist)
for(i = 0; i < ARRAY_SIZE(ActivePlayer.audioBuffer); i++) { {
for (i = 0; i < ARRAY_SIZE(ActivePlayer.audioBuffer); i++)
{
ActivePlayer.audioBuffer[i].buffer = (s16 *)workPtr; ActivePlayer.audioBuffer[i].buffer = (s16 *)workPtr;
ActivePlayer.audioBuffer[i].curPtr = (s16 *)workPtr; ActivePlayer.audioBuffer[i].curPtr = (s16 *)workPtr;
ActivePlayer.audioBuffer[i].validSample = 0; ActivePlayer.audioBuffer[i].validSample = 0;
@ -317,40 +323,58 @@ BOOL THPPlayerSetBuffer(u8 *data)
return FALSE; return FALSE;
} }
static void InitAllMessageQueue() { static void InitAllMessageQueue()
if(ActivePlayer.onMemory == FALSE) { {
for(int i = 0; i < 10; i++) { s32 i;
if (ActivePlayer.onMemory == FALSE)
{
for (i = 0; i < 10; i++)
{
PushFreeReadBuffer(&ActivePlayer.readBuffer[i]); PushFreeReadBuffer(&ActivePlayer.readBuffer[i]);
} }
} }
for (int i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
PushFreeTextureSet(&ActivePlayer.textureSet[i]); PushFreeTextureSet(&ActivePlayer.textureSet[i]);
} }
if(ActivePlayer.audioExist) { if (ActivePlayer.audioExist)
for (int i = 0; i < 6; i++) { {
for (i = 0; i < 6; i++)
{
PushFreeAudioBuffer(&ActivePlayer.audioBuffer[i]); PushFreeAudioBuffer(&ActivePlayer.audioBuffer[i]);
} }
} }
OSInitMessageQueue(&PrepareReadyQueue, &PrepareReadyMessage, 1); OSInitMessageQueue(&PrepareReadyQueue, &PrepareReadyMessage, 1);
} }
static BOOL WaitUntilPrepare() { static BOOL WaitUntilPrepare()
s32 msg; {
OSReceiveMessage(&PrepareReadyQueue, (OSMessage*)&msg, 1); OSMessage msg;
return msg ? TRUE : FALSE;
OSReceiveMessage(&PrepareReadyQueue, &msg, OS_MESSAGE_BLOCK);
if ((BOOL)msg)
{
return TRUE;
}
else
{
return FALSE;
}
} }
void PrepareReady(int msg) void PrepareReady(BOOL msg)
{ {
OSSendMessage(&PrepareReadyQueue, (OSMessage)msg, OS_MESSAGE_BLOCK); OSSendMessage(&PrepareReadyQueue, (OSMessage)msg, OS_MESSAGE_BLOCK);
} }
BOOL THPPlayerPrepare(s32 frame, u8 flag, s32 audioTrack) BOOL THPPlayerPrepare(s32 frame, u8 flag, s32 audioTrack)
{ {
if (ActivePlayer.open && ActivePlayer.state == 0) { u8 *threadData;
if (ActivePlayer.open && ActivePlayer.state == 0)
{
if (frame > 0) if (frame > 0)
{ {
if (ActivePlayer.header.offsetDataOffsets == 0) if (ActivePlayer.header.offsetDataOffsets == 0)
@ -365,18 +389,21 @@ BOOL THPPlayerPrepare(s32 frame, u8 flag, s32 audioTrack)
ActivePlayer.initReadSize = WorkBuffer[1] - WorkBuffer[0]; ActivePlayer.initReadSize = WorkBuffer[1] - WorkBuffer[0];
ActivePlayer.initReadFrame = frame; ActivePlayer.initReadFrame = frame;
} }
else { else
{
return FALSE; return FALSE;
} }
} }
else { else
{
ActivePlayer.initOffset = ActivePlayer.header.movieDataOffsets; ActivePlayer.initOffset = ActivePlayer.header.movieDataOffsets;
ActivePlayer.initReadSize = ActivePlayer.header.firstFrameSize; ActivePlayer.initReadSize = ActivePlayer.header.firstFrameSize;
ActivePlayer.initReadFrame = frame; ActivePlayer.initReadFrame = frame;
} }
if (ActivePlayer.audioExist) { if (ActivePlayer.audioExist)
{
if (audioTrack < 0 || audioTrack >= ActivePlayer.audioInfo.sndNumTracks) if (audioTrack < 0 || audioTrack >= ActivePlayer.audioInfo.sndNumTracks)
return FALSE; return FALSE;
ActivePlayer.curAudioTrack = audioTrack; ActivePlayer.curAudioTrack = audioTrack;
@ -385,18 +412,21 @@ BOOL THPPlayerPrepare(s32 frame, u8 flag, s32 audioTrack)
ActivePlayer.playFlag = flag & 1; ActivePlayer.playFlag = flag & 1;
ActivePlayer.videoDecodeCount = 0; ActivePlayer.videoDecodeCount = 0;
if(ActivePlayer.onMemory) { if (ActivePlayer.onMemory)
if (DVDReadPrio(&ActivePlayer.fileInfo, ActivePlayer.movieData, ActivePlayer.header.movieDataSize, ActivePlayer.header.movieDataOffsets, 2) < 0) { {
if (DVDReadPrio(&ActivePlayer.fileInfo, ActivePlayer.movieData, ActivePlayer.header.movieDataSize, ActivePlayer.header.movieDataOffsets, 2) < 0)
{
return FALSE; return FALSE;
} }
u8 *threadData = ActivePlayer.movieData + ActivePlayer.initOffset - ActivePlayer.header.movieDataOffsets; threadData = ActivePlayer.movieData + ActivePlayer.initOffset - ActivePlayer.header.movieDataOffsets;
CreateVideoDecodeThread(22, threadData); CreateVideoDecodeThread(22, threadData);
if (ActivePlayer.audioExist) if (ActivePlayer.audioExist)
CreateAudioDecodeThread(21, threadData); CreateAudioDecodeThread(21, threadData);
} }
else { else
{
CreateVideoDecodeThread(22, 0); CreateVideoDecodeThread(22, 0);
if (ActivePlayer.audioExist) if (ActivePlayer.audioExist)
CreateAudioDecodeThread(21, NULL); CreateAudioDecodeThread(21, NULL);
@ -405,7 +435,7 @@ BOOL THPPlayerPrepare(s32 frame, u8 flag, s32 audioTrack)
ActivePlayer.curVideoNumber = -1; ActivePlayer.curVideoNumber = -1;
ActivePlayer.curAudioNumber = 0; ActivePlayer.curAudioNumber = 0;
InitAllMessageQueue(); InitAllMessageQueue();
VideoDecodeThreadStart(); VideoDecodeThreadStart();
@ -431,7 +461,7 @@ BOOL THPPlayerPrepare(s32 frame, u8 flag, s32 audioTrack)
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }
@ -450,7 +480,8 @@ BOOL THPPlayerPlay()
void THPPlayerStop() void THPPlayerStop()
{ {
if(ActivePlayer.open && ActivePlayer.state != 0) { if (ActivePlayer.open && ActivePlayer.state != 0)
{
ActivePlayer.internalState = 0; ActivePlayer.internalState = 0;
ActivePlayer.state = 0; ActivePlayer.state = 0;
VISetPostRetraceCallback(OldVIPostCallback); VISetPostRetraceCallback(OldVIPostCallback);
@ -461,12 +492,15 @@ void THPPlayerStop()
} }
VideoDecodeThreadCancel(); VideoDecodeThreadCancel();
if(ActivePlayer.audioExist) { if (ActivePlayer.audioExist)
{
AudioDecodeThreadCancel(); AudioDecodeThreadCancel();
quitAudio(); quitAudio();
} }
while(PopUsedTextureSet() != 0) {} while (PopUsedTextureSet() != 0)
{
}
ActivePlayer.rampCount = 0; ActivePlayer.rampCount = 0;
ActivePlayer.curVolume = ActivePlayer.targetVolume; ActivePlayer.curVolume = ActivePlayer.targetVolume;
@ -486,25 +520,31 @@ BOOL THPPlayerPause()
return FALSE; return FALSE;
} }
static void PlayControl(u32 retraceCnt) { static void PlayControl(u32 retraceCnt)
{
THPTextureSet *decodedTexture;
if (OldVIPostCallback != NULL) if (OldVIPostCallback != NULL)
OldVIPostCallback(retraceCnt); OldVIPostCallback(retraceCnt);
THPTextureSet *decodedTexture = (THPTextureSet *)-1; decodedTexture = (THPTextureSet *)-1;
if (ActivePlayer.open && ActivePlayer.state == 2) if (ActivePlayer.open && ActivePlayer.state == 2)
{ {
if (ActivePlayer.dvdError || ActivePlayer.videoError) { if (ActivePlayer.dvdError || ActivePlayer.videoError)
{
ActivePlayer.state = 5; ActivePlayer.state = 5;
ActivePlayer.internalState = 5; ActivePlayer.internalState = 5;
return; return;
} }
if (++ActivePlayer.retaceCount == 0) if (++ActivePlayer.retaceCount == 0)
{ {
if(ProperTimingForStart()) { if (ProperTimingForStart())
if (ActivePlayer.audioExist) { {
if (ActivePlayer.curVideoNumber - ActivePlayer.curAudioNumber <= 1) { if (ActivePlayer.audioExist)
{
if (ActivePlayer.curVideoNumber - ActivePlayer.curAudioNumber <= 1)
{
decodedTexture = (THPTextureSet *)PopDecodedTextureSet(NULL); decodedTexture = (THPTextureSet *)PopDecodedTextureSet(NULL);
ActivePlayer.curVideoNumber++; ActivePlayer.curVideoNumber++;
@ -514,11 +554,13 @@ static void PlayControl(u32 retraceCnt) {
ActivePlayer.curField ^= 1; ActivePlayer.curField ^= 1;
} }
} }
else { else
{
ActivePlayer.internalState = 2; ActivePlayer.internalState = 2;
} }
} }
else { else
{
decodedTexture = (THPTextureSet *)PopDecodedTextureSet(NULL); decodedTexture = (THPTextureSet *)PopDecodedTextureSet(NULL);
if (ActivePlayer.videoInfo.videoType != 0 && if (ActivePlayer.videoInfo.videoType != 0 &&
(ActivePlayer.header.frameRate == 59.94f || ActivePlayer.header.frameRate == 50.0f)) (ActivePlayer.header.frameRate == 59.94f || ActivePlayer.header.frameRate == 50.0f))
@ -527,17 +569,20 @@ static void PlayControl(u32 retraceCnt) {
} }
} }
} }
else { else
{
ActivePlayer.retaceCount = -1; ActivePlayer.retaceCount = -1;
} }
} }
else { else
{
if (ActivePlayer.retaceCount == 1) if (ActivePlayer.retaceCount == 1)
{ {
ActivePlayer.internalState = 2; ActivePlayer.internalState = 2;
} }
if(ProperTimingForGettingNextFrame()) { if (ProperTimingForGettingNextFrame())
{
if (ActivePlayer.audioExist) if (ActivePlayer.audioExist)
{ {
if (ActivePlayer.curVideoNumber - ActivePlayer.curAudioNumber <= 1) if (ActivePlayer.curVideoNumber - ActivePlayer.curAudioNumber <= 1)
@ -570,9 +615,9 @@ static void PlayControl(u32 retraceCnt) {
PushUsedTextureSet(ActivePlayer.dispTextureSet); PushUsedTextureSet(ActivePlayer.dispTextureSet);
ActivePlayer.dispTextureSet = decodedTexture; ActivePlayer.dispTextureSet = decodedTexture;
} }
if ((ActivePlayer.playFlag & 1) == 0) { if ((ActivePlayer.playFlag & 1) == 0)
{
if (ActivePlayer.audioExist) if (ActivePlayer.audioExist)
{ {
s32 audioFrame = ActivePlayer.curAudioNumber + ActivePlayer.initReadFrame; s32 audioFrame = ActivePlayer.curAudioNumber + ActivePlayer.initReadFrame;
@ -582,9 +627,11 @@ static void PlayControl(u32 retraceCnt) {
ActivePlayer.state = 3; ActivePlayer.state = 3;
} }
} }
else { else
{
s32 curFrame = ActivePlayer.dispTextureSet != NULL ? ActivePlayer.dispTextureSet->frameNumber + ActivePlayer.initReadFrame : ActivePlayer.initReadFrame - 1; s32 curFrame = ActivePlayer.dispTextureSet != NULL ? ActivePlayer.dispTextureSet->frameNumber + ActivePlayer.initReadFrame : ActivePlayer.initReadFrame - 1;
if (curFrame == ActivePlayer.header.numFrames - 1 && decodedTexture == NULL) { if (curFrame == ActivePlayer.header.numFrames - 1 && decodedTexture == NULL)
{
ActivePlayer.internalState = 3; ActivePlayer.internalState = 3;
ActivePlayer.state = 3; ActivePlayer.state = 3;
} }
@ -606,10 +653,12 @@ static BOOL ProperTimingForGettingNextFrame()
if (ActivePlayer.videoInfo.videoType == 0) if (ActivePlayer.videoInfo.videoType == 0)
{ {
s32 rate = ActivePlayer.header.frameRate * 100.0f; s32 rate = ActivePlayer.header.frameRate * 100.0f;
if(VIGetTvFormat() == VI_PAL) { if (VIGetTvFormat() == VI_PAL)
{
ActivePlayer.curCount = ActivePlayer.retaceCount * rate / 5000; ActivePlayer.curCount = ActivePlayer.retaceCount * rate / 5000;
} }
else { else
{
ActivePlayer.curCount = ActivePlayer.retaceCount * rate / 5994; ActivePlayer.curCount = ActivePlayer.retaceCount * rate / 5994;
} }
@ -617,9 +666,10 @@ static BOOL ProperTimingForGettingNextFrame()
{ {
ActivePlayer.prevCount = ActivePlayer.curCount; ActivePlayer.prevCount = ActivePlayer.curCount;
return TRUE; return TRUE;
} }
} }
else { else
{
if (ActivePlayer.curField == VIGetNextField()) if (ActivePlayer.curField == VIGetNextField())
{ {
return TRUE; return TRUE;
@ -659,10 +709,9 @@ BOOL THPPlayerGetVideoInfo(void *dst)
u32 THPPlayerGetTotalFrame() u32 THPPlayerGetTotalFrame()
{ {
if (ActivePlayer.open != 0) if (ActivePlayer.open)
{
return ActivePlayer.header.numFrames; return ActivePlayer.header.numFrames;
}
return 0; return 0;
} }
@ -679,23 +728,26 @@ static void PushUsedTextureSet(OSMessage msg)
static OSMessage PopUsedTextureSet() static OSMessage PopUsedTextureSet()
{ {
OSMessage msg; // TODO: correct type OSMessage msg; // TODO: correct type
if(OSReceiveMessage(&UsedTextureSetQueue, &msg, OS_MESSAGE_NOBLOCK) == 1) { if (OSReceiveMessage(&UsedTextureSetQueue, &msg, OS_MESSAGE_NOBLOCK) == 1)
return msg; return msg;
}
return NULL; return NULL;
} }
void THPPlayerPostDrawDone() { void THPPlayerPostDrawDone()
if(Initialized) { {
if (Initialized)
{
OSMessage msg; OSMessage msg;
while(TRUE) while (TRUE)
{ {
msg = PopUsedTextureSet(); msg = PopUsedTextureSet();
if(msg == NULL) { if (msg == NULL)
{
break; break;
} }
PushFreeTextureSet(msg); PushFreeTextureSet(msg);
} }
} }
} }
@ -709,6 +761,10 @@ static void MixAudio(s16 *buf, u32 n)
s16 *aBuf; s16 *aBuf;
n2 = n; n2 = n;
aBuf = buf; aBuf = buf;
s16 *curPtr;
s32 vol2, vol1;
u16 volFromTable;
do do
{ {
do do
@ -730,7 +786,7 @@ static void MixAudio(s16 *buf, u32 n)
lastSample = n2; lastSample = n2;
} }
s16 *curPtr = ActivePlayer.playAudioBuffer->curPtr; curPtr = ActivePlayer.playAudioBuffer->curPtr;
for (i = 0; i < lastSample; i++) for (i = 0; i < lastSample; i++)
{ {
@ -743,8 +799,8 @@ static void MixAudio(s16 *buf, u32 n)
{ {
ActivePlayer.curVolume = ActivePlayer.targetVolume; ActivePlayer.curVolume = ActivePlayer.targetVolume;
} }
s32 vol2, vol1;
u16 volFromTable = VolumeTable[(s32)ActivePlayer.curVolume]; volFromTable = VolumeTable[(s32)ActivePlayer.curVolume];
vol1 = volFromTable * curPtr[0] >> 15; vol1 = volFromTable * curPtr[0] >> 15;
// clamp volume // clamp volume
@ -797,36 +853,40 @@ static void MixAudio(s16 *buf, u32 n)
BOOL THPPlayerSetVolume(s32 vol, s32 duration) BOOL THPPlayerSetVolume(s32 vol, s32 duration)
{ {
if(ActivePlayer.open && ActivePlayer.audioExist) { u32 numSamples;
u32 numSamples = AIGetDSPSampleRate() == 0 ? 32 : 48; BOOL interrupt;
if (ActivePlayer.open && ActivePlayer.audioExist)
{
numSamples = AIGetDSPSampleRate() == 0 ? 32 : 48;
// clamp volume // clamp volume
if (vol > 127) if (vol > 127)
vol = 127; vol = 127;
if(vol < 0) if (vol < 0)
vol = 0; vol = 0;
// clamp duration // clamp duration
if(duration > 60000) if (duration > 60000)
duration = 60000; duration = 60000;
if (duration < 0) if (duration < 0)
duration = 0; duration = 0;
BOOL interrupt = OSDisableInterrupts(); interrupt = OSDisableInterrupts();
ActivePlayer.targetVolume = vol; ActivePlayer.targetVolume = vol;
if(duration != 0) { if (duration != 0)
{
ActivePlayer.rampCount = numSamples * duration; ActivePlayer.rampCount = numSamples * duration;
ActivePlayer.deltaVolume = (ActivePlayer.targetVolume - ActivePlayer.curVolume) / ActivePlayer.rampCount; ActivePlayer.deltaVolume = (ActivePlayer.targetVolume - ActivePlayer.curVolume) / ActivePlayer.rampCount;
} }
else { else
{
ActivePlayer.rampCount = 0; ActivePlayer.rampCount = 0;
ActivePlayer.curVolume = ActivePlayer.targetVolume; ActivePlayer.curVolume = ActivePlayer.targetVolume;
} }
OSRestoreInterrupts(interrupt); OSRestoreInterrupts(interrupt);
return TRUE; return TRUE;
}
}
return FALSE; return FALSE;
} }

128
src/Kaneshige/THP/THPRead.c Normal file
View File

@ -0,0 +1,128 @@
#include "Kaneshige/THP/THPRead.h"
#include "Kaneshige/THP/THPPlayer.h"
#include "ppcdis.h"
#define STACK_SIZE 4096
#define MESSAGE_COUNT 10
static OSMessageQueue FreeReadBufferQueue;
static OSMessageQueue ReadedBufferQueue;
static OSMessageQueue ReadedBufferQueue2;
static OSMessage FreeReadBufferMessage[MESSAGE_COUNT];
static OSMessage ReadedBufferMessage[MESSAGE_COUNT];
static OSMessage ReadedBufferMessage2[MESSAGE_COUNT];
static OSThread ReadThread;
static u8 ReadThreadStack[STACK_SIZE];
static void *Reader(void *arg);
static BOOL ReadThreadCreated;
BOOL CreateReadThread(OSPriority prio)
{
if (OSCreateThread(&ReadThread, Reader, NULL, ReadThreadStack + STACK_SIZE, STACK_SIZE, prio, 1) == FALSE)
return FALSE;
OSInitMessageQueue(&FreeReadBufferQueue, FreeReadBufferMessage, MESSAGE_COUNT);
OSInitMessageQueue(&ReadedBufferQueue, ReadedBufferMessage, MESSAGE_COUNT);
OSInitMessageQueue(&ReadedBufferQueue2, ReadedBufferMessage2, MESSAGE_COUNT);
ReadThreadCreated = TRUE;
return TRUE;
}
void ReadThreadStart()
{
if (ReadThreadCreated)
OSResumeThread(&ReadThread);
}
void ReadThreadCancel()
{
if (ReadThreadCreated)
{
OSCancelThread(&ReadThread);
ReadThreadCreated = FALSE;
}
}
static void *Reader(void *arg)
{
THPReadBuffer *buf;
s32 curFrame;
s32 status;
s32 offset = ActivePlayer.initOffset;
s32 initReadSize = ActivePlayer.initReadSize;
s32 frame = 0;
while (TRUE)
{
buf = (THPReadBuffer *)PopFreeReadBuffer();
status = DVDReadPrio(&ActivePlayer.fileInfo, buf->ptr, initReadSize, offset, 2);
if (status != initReadSize)
{
if (status == -1)
ActivePlayer.dvdError = -1;
if (frame == 0)
PrepareReady(FALSE);
OSSuspendThread(&ReadThread);
}
buf->frameNumber = frame;
PushReadedBuffer(buf);
offset += initReadSize;
initReadSize = *(s32*)buf->ptr;
curFrame = (frame + ActivePlayer.initReadFrame) % ActivePlayer.header.numFrames;
if (curFrame == ActivePlayer.header.numFrames - 1)
{
if ((ActivePlayer.playFlag & 1))
offset = ActivePlayer.header.movieDataOffsets;
else
OSSuspendThread(&ReadThread);
}
frame++;
}
}
void *PopReadedBuffer()
{
void *buffer;
OSReceiveMessage(&ReadedBufferQueue, &buffer, OS_MESSAGE_BLOCK);
return buffer;
}
void *PushReadedBuffer(void *buffer)
{
OSSendMessage(&ReadedBufferQueue, buffer, 1);
}
void *PopFreeReadBuffer()
{
void *buffer;
OSReceiveMessage(&FreeReadBufferQueue, &buffer, OS_MESSAGE_BLOCK);
return buffer;
}
void PushFreeReadBuffer(void *buffer)
{
OSSendMessage(&FreeReadBufferQueue, buffer, 1);
}
void *PopReadedBuffer2()
{
void *buffer;
OSReceiveMessage(&ReadedBufferQueue2, &buffer, OS_MESSAGE_BLOCK);
return buffer;
}
void PushReadedBuffer2(void *buffer)
{
OSSendMessage(&ReadedBufferQueue2, buffer, 1);
}