Code:
H03_GData.h
//The GSThread structure is wrong, but ignore it because you can create a new one. up to you But I'm too lazy to create a new structure.
struct CGSThread
{
void* vftable;
DWORD mID;
bool bIsStart;
HANDLE mHandle;
DWORD* d;
};
struct GSThread
{
void* vftable;
DWORD mID;
bool bIsStart;
HANDLE mHandle;
CGSThread gThread;
char unk[8];
int workNum;
char sset[32];
CRITICAL_SECTION mLock;
bool mRunning;
bool a;
bool b;
bool c;
};
class GDATA
{
public:
GSThread mMobjectLoaderThread;
GSThread mSoundLoaderThread;
GSThread mMotionLoaderThread;
GSThread mSobjectLoaderThread;
GSThread mSobjectOldLoaderThread;
};
Code:
//example load sound
#ifdef _USRDLL
#define THISS GSOUND *This
#define THISC GSOUND *This,
#endif
class GSOUND
{
public:
BOOL mCheckValidState;
char mFileName[100];
SOUNDDATA_FOR_GXD mDATA;
float mLastUsedTime;
CRITICAL_SECTION mLock;
GSOUND( void );
~GSOUND( void );
capi void Init( THISC int tValue01, int tValue02, int tValue03, int tValue04, int tValue05 );
capi void Free( THISS );
capi BOOL Load( THISC BOOL tLoadSort);
capi void ProcessForMemory( THISC float tPresentTime, float tValidTimeLength );
capi void Play( THISC BOOL tCheckLoop, int tVolumeSize, int tPan );
};
#undef THISC
#undef THISS
//S03_GSOUND.cpp
#include "H099_LoaderThread.h"
#ifdef _USRDLL
#define THISS GSOUND *This
#define THISC GSOUND *This,
#else
#define THISS
#define THISC
#define This
#endif
#ifndef USE_GSOUND_THREAD
#define EnterCriticalSection(...)
#define LeaveCriticalSection(...)
#endif
GSOUND::GSOUND( void )
{
mCheckValidState = FALSE;
mDATA.Init();
InitializeCriticalSection( &mLock );
}
GSOUND::~GSOUND( void )
{
DeleteCriticalSection( &mLock );
}
void GSOUND::Init( THISC int tValue01, int tValue02, int tValue03, int tValue04, int tValue05 )
{
switch ( tValue01 )
{
case 1:
sprintf( This->mFileName, "G03_GDATA\\D06_GSOUND\\001\\C%03d%03d%03d.ISN", tValue02 + 3 * tValue03 + 1, tValue04 + 1, tValue05 + 1 );
break;
case 2:
sprintf( This->mFileName, "G03_GDATA\\D06_GSOUND\\002\\N%03d001%03d.ISN", tValue02 + 1, tValue03 + 1 );
break;
case 3:
sprintf( This->mFileName, "G03_GDATA\\D06_GSOUND\\003\\M%03d001%03d.ISN", tValue02 + 1, tValue03 + 1 );
break;
case 4:
sprintf( This->mFileName, "G03_GDATA\\D06_GSOUND\\004\\E%03d001001.ISN", tValue02 + 1 );
break;
case 5:
sprintf( This->mFileName, "G03_GDATA\\D06_GSOUND\\005\\H%03d%03d%03d.ISN", tValue02 + 3 * tValue03 + 1, tValue04 + 1, tValue05 + 1 );
break;
case 6:
sprintf( This->mFileName, "G03_GDATA\\D06_GSOUND\\006\\X%03d%03d%03d.ISN", tValue02 + 3 * tValue03 + 1, tValue04 + 1, tValue05 + 1 );
break;
default:
strcpy( This->mFileName, aEmptyChar );
break;
}
}
void GSOUND::Free( THISS )
{
EnterCriticalSection( &This->mLock );
This->mCheckValidState = 0;
This->mDATA.Free();
LeaveCriticalSection( &This->mLock );
}
BOOL GSOUND::Load( THISC BOOL tLoadSort )
{
BOOL result;
#ifdef USE_GSOUND_THREAD
if ( !tLoadSort )
return CSoundLoaderThread__PushJob( This );
#endif
EnterCriticalSection( &This->mLock );
if ( This->mCheckValidState )
{
This->mLastUsedTime = mApp->hPostSecondsForLogic;
//LeaveCriticalSection(&This->mLock);
//result = 1;
}
else if ( This->mDATA.LoadFromOGG( This->mFileName, 3, 2, 1 ) )
{
This->mCheckValidState = 1;
This->mLastUsedTime = mApp->hPostSecondsForLogic;
//LeaveCriticalSection(&This->mLock);
//result = 1;
}
else
{
//LeaveCriticalSection(&This->mLock);
//result = 0;
}
LeaveCriticalSection( &This->mLock );
result = This->mCheckValidState;
return result;
}
void GSOUND::ProcessForMemory( THISC float tPresentTime, float tValidTimeLength )
{
if ( !This->mCheckValidState )
return;
if( ( tPresentTime - This->mLastUsedTime ) > tValidTimeLength )
GSOUND::Free( This );
}
void GSOUND::Play( THISC BOOL tCheckLoop, int tVolumeSize, int tPan )
{
if ( !This->mCheckValidState )
{
if( !GSOUND::Load( This, 0 ) )
{
return;
}
This->mCheckValidState = TRUE;
}
This->mLastUsedTime = mApp->hPresentElapsedSeconds;
This->mDATA.Play( tCheckLoop, (int) ( (float) ( tVolumeSize * mGAMEOPTION->mSoundOption[1] ) * 0.01f ), 0 );
// int tVolume = (int)( (float)tVolumeSize * mGAMEOPTION->mSoundOption[1] );
// mDATA.Play( tCheckLoop, (int) ( (float) ( tVolume * 100 ) * 0.01f ), 0 );
}
#undef THISC
#undef THISS
#undef This
Code:
//H099_LoaderThread.h #pragma once #include <set> struct GSThread; #define CGS_TH_CREATE (!bCreateNormal ? OPEN_ALWAYS : NULL) #define USE_MY_GMOBJECT_LOADER #define USE_GMOBJECT_THREAD #define USE_MY_GSOUND_LOADER #define USE_GSOUND_THREAD #define USE_MY_GMOTION_LOADER #define USE_GMOTION_THREAD #define USE_MY_GSOBJECT_LOADER #define USE_GSOBJECT_THREAD #define USE_MY_GSOBJECT_OLD_LOADER #define USE_GSOBJECT_OLD_THREAD #define CREATE_GS_EXTERN(cls) \ extern void cls##__TerminateThread(); \ extern BYTE cls##__Start(bool bIsStart, bool bCreateNormal); \ extern DWORD cls##__Wait(DWORD dwMilliseconds); \ extern BOOL cls##__PushJob(void*); CREATE_GS_EXTERN(CMobjectLoaderThread) CREATE_GS_EXTERN(CSoundLoaderThread) CREATE_GS_EXTERN(CMotionLoaderThread) CREATE_GS_EXTERN(CSobjectLoaderThread) CREATE_GS_EXTERN(CSobjectOldLoaderThread)
Code:
//S03_GThread.cpp
#include "H099_LoaderThread.h"
class CCGSThread
{
public:
CCGSThread()
{
}
CCGSThread(GSThread* This)
{
#ifndef _USREXE
CVOID_ARG0(GSThread, CCGSThread, 0x0074D710, This);
#endif
}
capi void DCCGSThread(GSThread* This)
{
#ifndef _USREXE
CVOID_ARG0(GSThread, DCCGSThread, 0x0074D730, This);
#endif
}
capi void Proc(GSThread* This)
{
#ifndef _USREXE
CVOID_ARG0(GSThread, DCGSThread, 0x0074D740, This);
#endif
}
capi DWORD CCGSThread::Wait(GSThread* This, DWORD dwMilliseconds)
{
//CRET_ARG1(GSThread, Start, 0x0074D790, This, DWORD, dwMilliseconds);
//return result;
return WaitForSingleObject(This->mHandle, dwMilliseconds);
}
capi BYTE Start(GSThread* This, bool bIsStart, bool bCreateNormal)
{
#ifndef _USREXE
CRET_ARG2(BYTE, GSThread, Start, 0x0074D7D0, This, bool, bIsStart, bool, bCreateNormal);
#else
BYTE result = 1;
#endif
return result;
}
};
#define CREATE_GSTHREAD( cls, ptr ) \
void cls##__TerminateThread() \
{\
cls##::TerminateThread( &ptr ); \
} \
BYTE cls##__Start( bool bIsStart, bool bCreateNormal ) \
{ \
return cls##::Start( &ptr, bIsStart, bCreateNormal ); \
} \
DWORD cls##__Wait( DWORD dwMilliseconds ) \
{ \
return CCGSThread::Wait( &ptr, dwMilliseconds ); \
} \
BOOL cls##__PushJob(void* data) \
{ \
return cls##::PushJob( &ptr, data ); \
}
#ifdef USE_MY_GSOUND_LOADER
#define set_ptr set_sou
#define set_std std::set<GSOUND*>
GSThread cSoundLoaderThread;
set_std set_sou;
#else
#define cSoundLoaderThread mGDATA[0].mSoundLoaderThread
#endif
class CSoundLoaderThread
{
public:
CSoundLoaderThread( void )
{
}
CSoundLoaderThread( GSThread* This )
{
#ifndef _USREXE
CVOID_ARG0( GSThread, CSoundLoaderThread, 0x004E2B00, This );
#endif
}
capi GSThread* ECSoundLoaderThread(GSThread* This, char a2)
{
#ifndef USE_MY_GSOUND_LOADER
CRET_ARG1( GSThread*, GSThread, ECSoundLoaderThread, 0x004E2BB0, This, char, a2 );
return result;
#else
CSoundLoaderThread::DCSoundLoaderThread(This);
if ((a2 & 1) != 0)
operator delete(This);
return This;
#endif
}
capi void GCSoundLoaderThread(GSThread* This)
{
#ifndef USE_MY_GSOUND_LOADER
CVOID_ARG0( GSThread, GCSoundLoaderThread, 0x004E2BE0, This );
#else
//sub_4E9680(This);
//operator delete(This->vftable);
#endif
}
capi void DCSoundLoaderThread(GSThread* This)
{
#ifndef USE_MY_GSOUND_LOADER
CVOID_ARG0( GSThread, DCSoundLoaderThread, 0x004E2C60, This );
#else
//This->vftable = &CSoundLoaderThreadVFTable;
CSoundLoaderThread::ExitThread(This);
//sub_4E8820(This->sset);
//operator delete(*This->sset);
//sub_4E8820(&This->gThread.vftable);
//operator delete(This->gThread.vftable);
//CGSThread::DCGSThread(This);
#endif
}
//CGSThread
capi BYTE Start(GSThread* This, bool bIsStart, bool bCreateNormal)
{
#ifndef USE_MY_GSOUND_LOADER
CCGSThread::Start(This, bIsStart, bCreateNormal);
#else
#ifdef USE_GSOUND_THREAD
//ZeroMemory(This, sizeof(*This));
This->bIsStart = bIsStart;
if ( CSoundLoaderThread::InitThread( This ) == 1 )
{
This->mHandle = CreateThread( NULL, NULL, (LPTHREAD_START_ROUTINE)CSoundLoaderThread::Run, This, CGS_TH_CREATE, &This->mID );
if( This->mHandle != INVALID_HANDLE_VALUE )
return 1;
}
CSoundLoaderThread::ExitThread( This );
if (This->bIsStart)
CSoundLoaderThread::ECSoundLoaderThread(This, 1);
#endif
#endif
return 0;
}
//
capi BOOL InitThread(GSThread* This)
{
#ifndef USE_MY_GSOUND_LOADER
CRET_ARG0( BOOL, GSThread, InitThread, 0x004E2D60, This );
#else
BOOL result = TRUE;
#ifdef USE_GSOUND_THREAD
InitializeCriticalSection( &This->mLock );
#endif
#endif
printf("CSoundLoaderThread::InitThread.\n");
return result;
}
capi DWORD Run(GSThread *This)
{
#ifndef USE_MY_GSOUND_LOADER
CRET_ARG0( DWORD, GSThread, Run, 0x004E2D90, This );
#else
printf("CSoundLoaderThread::Run.\n");
int wnum = 0;
This->mRunning = 1;
#ifdef USE_GSOUND_THREAD
while (This->mRunning)
{
EnterCriticalSection( &This->mLock );
wnum = set_ptr.size();
LeaveCriticalSection( &This->mLock );
if ( wnum > 0 )
{
EnterCriticalSection(&This->mLock);
//sub_4E5A20(&thiS->gThread, &v10);
set_std::iterator it = set_ptr.begin();
GSOUND* That = (*it);
LeaveCriticalSection(&This->mLock);
if ( GSOUND::Load(That, 1) )
{
//printf("CSoundLoaderThread::Load(%s,1)\n", That->mFileName );
GSOUND::SetUsedTime(That, mApp->hPostSecondsForLogic);
}
else
{
}
EnterCriticalSection(&This->mLock);
set_ptr.erase(it);
LeaveCriticalSection(&This->mLock);
}
Sleep(1);
}
#endif
printf("CSoundLoaderThread::Run finished.\n");
#endif
return 1;
}
capi char ExitThread(GSThread *This)
{
printf("CSoundLoaderThread::ExitThread.\n");
#ifndef USE_MY_GSOUND_LOADER
CRET_ARG0( char ,GSThread, ExitThread, 0x004E2F80, This );
#else
#ifdef USE_GSOUND_THREAD
EnterCriticalSection(&This->mLock);
//sub_4E58C0(&thiS->gThread.vftable);
set_ptr.clear();
LeaveCriticalSection(&This->mLock);
DeleteCriticalSection(&This->mLock);
#endif
#endif
return 1;
}
capi BOOL PushJob(GSThread *This, void *data)
{
GSOUND* That = (GSOUND*)data;
#ifndef USE_MY_GSOUND_LOADER
CRET_ARG1( BOOL, GSThread, PushJob, 0x004E2FE0, This, GSOUND *, That );
#else
#ifdef USE_GSOUND_THREAD
EnterCriticalSection( &This->mLock );
if ( That->mCheckValidState )
{
LeaveCriticalSection( &This->mLock );
return 1;
}
set_std::iterator it = set_ptr.find(That);
if ( it == set_ptr.end() ) {
set_ptr.insert(That);
}
LeaveCriticalSection(&This->mLock);
#endif
BOOL result = 0;
#endif
return result;
}
capi void TerminateThread(GSThread *This)
{
//CVOID_ARG0( GSThread, TerminateThread, 0x004E31B0, This );
This->mRunning = 0;
printf("CSoundLoaderThread::TerminateThread.\n");
}
};
CREATE_GSTHREAD(CSoundLoaderThread, cSoundLoaderThread)
#undef set_ptr
#undef set_std
//usage
Code:
//S03_GDATA.cpp
#include "H099_LoaderThread.h"
BOOL GDATA::Init(void)
{
CSoundLoaderThread__Start(0, 1);
}
void GDATA::Free()
{
CSoundLoaderThread__TerminateThread();
CSoundLoaderThread__Wait(INFINITE);
}
//use loader thread
GSOUND::Play(mGDATA->mSOUND_05, 0, 100, 1);






