openmohaa/code/cgame_hook/script/clientgamecommand.cpp
2016-03-27 11:49:47 +02:00

353 lines
7.4 KiB
C++

/*
* ClientGameCommandManager.cpp
*
* DESCRIPTION : Client Game Command Manager
*/
#include "clientgamecommand.h"
#include "cgame/cl_sound.h"
#include "archive.h"
uintptr_t *sndDriver = ( uintptr_t * )0x7F5D74;
typedef void( __cdecl *AIL_CLOSE_STREAM )( void *stream );
typedef void* ( __cdecl *AIL_OPEN_STREAM )( uintptr_t soundDriver, const char *pFilename, int channel );
typedef void ( __cdecl *AIL_SET_STREAM_LOOP_COUNT )( void *stream, int count );
typedef void( __cdecl *AIL_SET_STREAM_PLAYBACK_RATE )( void *stream, int rate );
typedef void( __cdecl *AIL_SET_STREAM_POSITION )( void *stream, int position );
typedef void( __cdecl *AIL_SET_STREAM_VOLUME )( void *stream, int volume );
typedef void ( __cdecl *AIL_START_STREAM )( void *stream );
typedef int( __cdecl *AIL_STREAM_PLAYBACK_RATE )( void *stream );
typedef int( __cdecl *AIL_STREAM_POSITION )( void *stream );
typedef int ( __cdecl *AIL_STREAM_STATUS )( void *stream );
typedef char * ( __cdecl *GETFILEPATH )( const char *game_path, const char *path, const char *filename );
AIL_CLOSE_STREAM AIL_close_stream = ( AIL_CLOSE_STREAM )0x00486C80;
AIL_OPEN_STREAM AIL_open_stream = ( AIL_OPEN_STREAM )0x00486C20;
AIL_SET_STREAM_LOOP_COUNT AIL_set_stream_loop_count = ( AIL_SET_STREAM_LOOP_COUNT )0x00487030;
AIL_SET_STREAM_PLAYBACK_RATE AIL_set_stream_playback_rate = ( AIL_SET_STREAM_PLAYBACK_RATE )0x00486E70;
AIL_SET_STREAM_POSITION AIL_set_stream_position = ( AIL_SET_STREAM_POSITION )0x00487100;
AIL_SET_STREAM_VOLUME AIL_set_stream_volume = ( AIL_SET_STREAM_VOLUME )0x00486EE0;
AIL_START_STREAM AIL_start_stream = ( AIL_START_STREAM )0x00486DA0;
AIL_STREAM_PLAYBACK_RATE AIL_stream_playback_rate = ( AIL_STREAM_PLAYBACK_RATE )0x00487230;
AIL_STREAM_POSITION AIL_stream_position = ( AIL_STREAM_POSITION )0x004873E0;
AIL_STREAM_STATUS AIL_stream_status = ( AIL_STREAM_STATUS )0x004871E0;
GETFILEPATH GetFilePath = ( GETFILEPATH )0x00450840;
char *gameDir = ( char * )0x00EC4EE0;
Container< LocalSound * > localSounds;
ClientGameCommandManager *commandManager = ( ClientGameCommandManager * )0x30117B90;
ClientSpecialEffectsManager *sfxManager = ( ClientSpecialEffectsManager * )0x3026AB78;
Event EV_LocalSound_Think
(
"localsound_think",
EV_CODEONLY,
NULL,
NULL,
"Internal event",
EV_NORMAL
);
LocalSound::LocalSound( str n, qboolean l )
{
path = GetFilePath( fs_basepath->string, gameDir, n );
stream = AIL_open_stream( *sndDriver, path, 0 );
name = n;
stopping = false;
loop = l;
if( loop ) {
AIL_set_stream_loop_count( stream, 0 );
} else {
AIL_set_stream_loop_count( stream, 1 );
}
volume = 0.0f;
rate = 1.0f;
localSounds.AddObject( this );
}
LocalSound::LocalSound()
{
stream = NULL;
stopping = false;
loop = false;
volume = 0.0f;
rate = 1.0f;
localSounds.AddObject( this );
}
LocalSound::~LocalSound()
{
CancelEventsOfType( &EV_LocalSound_Think );
if( stream ) {
AIL_close_stream( stream );
}
localSounds.RemoveObject( this );
}
void LocalSound::Archive( Archiver &arc )
{
Listener::Archive( arc );
arc.ArchiveString( &name );
arc.ArchiveBoolean( &stopping );
arc.ArchiveBoolean( &loop );
if( arc.Saving() ) {
position = AIL_stream_position( stream );
}
arc.ArchiveInteger( &position );
arc.ArchiveFloat( &volume );
arc.ArchiveFloat( &start_volume );
arc.ArchiveFloat( &target_volume );
arc.ArchiveFloat( &rate );
arc.ArchiveObject( &timer );
if( arc.Loading() )
{
path = GetFilePath( fs_basepath->string, gameDir, name );
stream = AIL_open_stream( *sndDriver, path, 0 );
if( stream )
{
AIL_start_stream( stream );
if( loop ) {
AIL_set_stream_loop_count( stream, 0 );
}
else {
AIL_set_stream_loop_count( stream, 1 );
}
AIL_set_stream_position( stream, position );
Event *ev = new Event( &EV_LocalSound_Think );
ProcessEvent( ev );
}
}
}
str LocalSound::GetName()
{
return name;
}
void LocalSound::Play( float time, float v )
{
stopping = false;
start_volume = volume;
if( time <= 0.0f ) {
volume = v;
} else {
volume = 0.0f;
AIL_set_stream_volume( stream, 0 );
}
target_volume = v;
timer.SetTime( time );
timer.Enable();
start_rate = 1.0f;
target_rate = 1.0f;
rate = 1.0f;
if( stream )
{
AIL_start_stream( stream );
baserate = AIL_stream_playback_rate( stream );
Event *ev = new Event( &EV_LocalSound_Think );
ProcessEvent( ev );
}
}
void LocalSound::Stop( float time )
{
if( time <= 0.0f )
{
delete this;
return;
}
start_volume = volume;
timer.SetTime( time );
timer.Enable();
stopping = true;
}
void LocalSound::SetRate( float r, float time )
{
target_rate = r;
start_rate = rate;
timer_rate.SetTime( time );
timer_rate.Enable();
if( time <= 0.0f )
{
rate = r;
if( stream )
{
int ra = ( int )( ( float )baserate * rate );
AIL_set_stream_playback_rate( stream, ra );
}
}
}
void LocalSound::Think( Event *ev )
{
if( stopping ) {
volume = timer.LerpValue( start_volume, 0.0f );
}
AIL_set_stream_volume( stream, ( int )( volume * s_volume->value * *sound_global_volume * 100.0f ) );
if( !timer_rate.Done() ) {
rate = timer_rate.LerpValue( start_rate, target_rate );
}
int r = ( int )( ( float )baserate * rate );
AIL_set_stream_playback_rate( stream, r );
if( ( stopping && timer.Done() ) || AIL_stream_status( stream ) != STREAM_PLAYING )
{
CancelEventsOfType( &EV_LocalSound_Think );
delete this;
return;
}
if( !stopping ) {
volume = timer.LerpValue( start_volume, target_volume );
}
CancelEventsOfType( &EV_LocalSound_Think );
PostEvent( EV_LocalSound_Think, level.frametime, 0 );
}
CLASS_DECLARATION( Listener, LocalSound, NULL )
{
{ &EV_LocalSound_Think, &LocalSound::Think },
{ NULL, NULL }
};
void ClientGameCommandManager::CleanUp()
{
Container< LocalSound * > local = localSounds;
for( int i = 0; i < local.NumObjects(); i++ )
{
LocalSound *localSound = local[ i ];
delete localSound;
}
localSounds.FreeObjectList();
}
void ClientGameCommandManager::ArchiveFunction( Archiver &arc )
{
int num = localSounds.NumObjects();
arc.ArchiveInteger( &num );
if( arc.Saving() )
{
for( int i = 0; i < num; i++ ) {
arc.ArchiveObject( localSounds[ i ] );
}
}
else
{
for( int i = 0; i < num; i++ ) {
arc.ReadObject();
}
}
}
void ClientGameCommandManager::Initialize()
{
}
void ClientGameCommandManager::PlaySound( str sound_name, float *origin, int channel, float volume, float min_distance, float pitch, int argstype )
{
JMPTO( 0x30015E0C );
}
void ClientGameCommandManager::PlayLocalSound( str sound_name, qboolean loop, float volume, float time )
{
// Don't play the same sound again
StopLocalSound( sound_name );
LocalSound *localSound = new LocalSound( sound_name, loop );
localSound->Play( time, volume );
}
void ClientGameCommandManager::SetLocalSoundRate( str sound_name, float rate, float time )
{
LocalSound *localSound = GetLocalSound( sound_name );
if( !localSound ) {
return;
}
localSound->SetRate( rate, time );
}
void ClientGameCommandManager::StopLocalSound( str sound_name, float time )
{
LocalSound *localSound = GetLocalSound( sound_name );
if( localSound ) {
localSound->Stop( time );
}
}
LocalSound *ClientGameCommandManager::GetLocalSound( str sound_name )
{
for( int i = 1; i <= localSounds.NumObjects(); i++ )
{
LocalSound *localSound = localSounds.ObjectAt( i );
if( localSound->GetName() == sound_name ) {
return localSound;
}
}
return NULL;
}
void ClientSpecialEffectsManager::MakeEffect_Normal( int iEffect, Vector position, Vector normal )
{
JMPTO( 0x3003524D );
}