mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
Quake 4 integrated with DoomRTX
This commit is contained in:
@@ -0,0 +1,420 @@
|
||||
#include "precompiled.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Game_local.h"
|
||||
#include "ai/AI.h"
|
||||
|
||||
#define RECORD_STATE_TRACE_LEN 2048.0f
|
||||
|
||||
class rvGamePlayback
|
||||
{
|
||||
public:
|
||||
rvGamePlayback( void );
|
||||
~rvGamePlayback( void );
|
||||
|
||||
void RecordData( const usercmd_t &cmd, idEntity *source );
|
||||
private:
|
||||
int mStartTime;
|
||||
byte mOldFlags;
|
||||
idStr mName;
|
||||
idClipModel *mClipModel;
|
||||
rvDeclPlayback *mPlayback;
|
||||
};
|
||||
|
||||
idCVar g_recordPlayback( "g_recordPlayback", "0", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "record the player movement in a playback" );
|
||||
idCVar g_playPlayback( "g_playPlayback", "0", CVAR_GAME | CVAR_INTEGER | CVAR_NOCHEAT, "plays the current playback in a camera path" );
|
||||
|
||||
rvGamePlayback *gamePlayback = NULL;
|
||||
rvCameraPlayback *playbackCamera = NULL;
|
||||
|
||||
rvGamePlayback::rvGamePlayback( void )
|
||||
{
|
||||
idStr newName;
|
||||
const idVec3 trace_mins( -1.0f, -1.0f, -1.0f );
|
||||
const idVec3 trace_maxs( 1.0f, 1.0f, 1.0f );
|
||||
const idBounds trace_bounds( trace_mins, trace_maxs );
|
||||
idTraceModel traceModel( trace_bounds );
|
||||
|
||||
mStartTime = gameLocal.time;
|
||||
mOldFlags = 0;
|
||||
mClipModel = new idClipModel( traceModel );
|
||||
// jmarshall - not used in retail workflow
|
||||
//if( !g_currentPlayback.GetInteger() )
|
||||
//{
|
||||
// newName = declManager->GetNewName( DECL_PLAYBACK, "playbacks/untitled" );
|
||||
// mPlayback = ( rvDeclPlayback * )declManager->CreateNewDecl( DECL_PLAYBACK, newName, newName + ".playback" );
|
||||
// mPlayback->ReplaceSourceFileText();
|
||||
// mPlayback->Invalidate();
|
||||
//
|
||||
// g_currentPlayback.SetInteger( mPlayback->Index() );
|
||||
//}
|
||||
//else
|
||||
// jmarshall end
|
||||
{
|
||||
mPlayback = ( rvDeclPlayback * )declManager->PlaybackByIndex( g_currentPlayback.GetInteger() );
|
||||
}
|
||||
|
||||
//declManager->StartPlaybackRecord( mPlayback );
|
||||
common->Printf( "Starting playback record to %s type %d\n", mPlayback->GetName(), g_recordPlayback.GetInteger() );
|
||||
}
|
||||
|
||||
rvGamePlayback::~rvGamePlayback( void )
|
||||
{
|
||||
//declManager->FinishPlayback( mPlayback );
|
||||
delete mClipModel;
|
||||
|
||||
common->Printf( "Stopping playback play/record\n" );
|
||||
}
|
||||
|
||||
void rvGamePlayback::RecordData( const usercmd_t &cmd, idEntity *source )
|
||||
{
|
||||
idPlayer *player;
|
||||
trace_t trace;
|
||||
idMat3 axis;
|
||||
idVec3 start, end;
|
||||
rvDeclPlaybackData info;
|
||||
|
||||
info.Init();
|
||||
|
||||
switch( g_recordPlayback.GetInteger() )
|
||||
{
|
||||
case 1:
|
||||
info.SetPosition( source->GetPhysics()->GetOrigin() );
|
||||
info.SetAngles( source->GetPhysics()->GetAxis().ToAngles() );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
gameLocal.GetPlayerView( start, axis );
|
||||
|
||||
end = start + axis[0] * RECORD_STATE_TRACE_LEN;
|
||||
|
||||
gameLocal.Translation( gameLocal.GetLocalPlayer(), trace, start, end, mClipModel, mat3_identity, CONTENTS_SOLID | CONTENTS_RENDERMODEL, source );
|
||||
|
||||
if( trace.fraction != 1.0f )
|
||||
{
|
||||
info.SetPosition( trace.endpos );
|
||||
info.SetAngles( trace.c.normal.ToAngles() );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
assert( source->IsType( idPlayer::GetClassType() ) );
|
||||
if( source->IsType( idPlayer::GetClassType() ) )
|
||||
{
|
||||
player = static_cast<idPlayer *>( source );
|
||||
info.SetPosition( player->GetEyePosition() );
|
||||
info.SetAngles( source->GetPhysics()->GetAxis().ToAngles() );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Record buttons
|
||||
info.SetButtons( cmd.buttons );
|
||||
|
||||
// Record impulses
|
||||
if( ( cmd.flags & UCF_IMPULSE_SEQUENCE ) != ( mOldFlags & UCF_IMPULSE_SEQUENCE ) )
|
||||
{
|
||||
info.SetImpulse( cmd.impulse );
|
||||
}
|
||||
else
|
||||
{
|
||||
info.SetImpulse( 0 );
|
||||
}
|
||||
mOldFlags = cmd.flags;
|
||||
|
||||
//declManager->SetPlaybackData( mPlayback, gameLocal.time - mStartTime, -1, &info );
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
|
||||
void idGameEdit::DrawPlaybackDebugInfo( void )
|
||||
{
|
||||
#if 0 // jmarshall
|
||||
int duration, time;
|
||||
rvDeclPlaybackData pbd, pbdOld;
|
||||
const rvDeclPlayback *pb;
|
||||
|
||||
pb = declManager->PlaybackByIndex( g_currentPlayback.GetInteger(), true );
|
||||
if( pb )
|
||||
{
|
||||
duration = SEC2MS( pb->GetDuration() );
|
||||
pbd.Init();
|
||||
pbdOld.Init();
|
||||
|
||||
declManager->GetPlaybackData( pb, -1, 0, 0, &pbdOld );
|
||||
for( time = gameLocal.GetMSec(); time < duration; time += gameLocal.GetMSec() * g_showPlayback.GetInteger() )
|
||||
{
|
||||
declManager->GetPlaybackData( pb, -1, time, time, &pbd );
|
||||
gameRenderWorld->DebugArrow( colorGreen, pbdOld.GetPosition(), pbd.GetPosition(), 2 );
|
||||
pbdOld = pbd;
|
||||
}
|
||||
|
||||
gameRenderWorld->DebugBounds( colorRed, pb->GetBounds(), pb->GetOrigin() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void idGameEdit::RecordPlayback( const usercmd_t &cmd, idEntity *source )
|
||||
{
|
||||
// Not recording - so instantly exit
|
||||
if( !g_recordPlayback.GetInteger() && !gamePlayback )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !gamePlayback )
|
||||
{
|
||||
gamePlayback = new rvGamePlayback();
|
||||
}
|
||||
|
||||
if( g_recordPlayback.GetInteger() )
|
||||
{
|
||||
gamePlayback->RecordData( cmd, source );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete gamePlayback;
|
||||
gamePlayback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
|
||||
bool idGameEdit::PlayPlayback( void )
|
||||
{
|
||||
// Not playing - so instantly exit
|
||||
if( !g_playPlayback.GetInteger() && !playbackCamera )
|
||||
{
|
||||
return( false );
|
||||
}
|
||||
|
||||
if( !playbackCamera )
|
||||
{
|
||||
playbackCamera = static_cast<rvCameraPlayback *>( gameLocal.SpawnEntityType( rvCameraPlayback::GetClassType() ) );
|
||||
SetCamera( playbackCamera );
|
||||
|
||||
common->Printf( "Starting playback play\n" );
|
||||
}
|
||||
|
||||
if( g_currentPlayback.IsModified() )
|
||||
{
|
||||
// Spawn is a misnomer - it should be init with new data
|
||||
playbackCamera->Spawn();
|
||||
g_currentPlayback.ClearModified();
|
||||
}
|
||||
|
||||
if( !g_playPlayback.GetInteger() )
|
||||
{
|
||||
playbackCamera->PostEventMS( &EV_Remove, 0 );
|
||||
playbackCamera = NULL;
|
||||
SetCamera( NULL );
|
||||
}
|
||||
|
||||
return( true );
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
|
||||
void idGameEdit::ShutdownPlaybacks( void )
|
||||
{
|
||||
g_recordPlayback.SetInteger( 0 );
|
||||
g_playPlayback.SetInteger( 0 );
|
||||
|
||||
if( gamePlayback )
|
||||
{
|
||||
delete gamePlayback;
|
||||
gamePlayback = NULL;
|
||||
}
|
||||
|
||||
if( playbackCamera )
|
||||
{
|
||||
playbackCamera->PostEventMS( &EV_Remove, 0 );
|
||||
playbackCamera = NULL;
|
||||
SetCamera( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
|
||||
/*
|
||||
============
|
||||
rvPlaybackDriver::Start
|
||||
|
||||
Start a new playback automatically blending with the old playback (if any) over numFrames
|
||||
============
|
||||
*/
|
||||
bool rvPlaybackDriver::Start( const char *playback, idEntity *owner, int flags, int numFrames )
|
||||
{
|
||||
idVec3 startPos;
|
||||
|
||||
if( !idStr::Length( playback ) )
|
||||
{
|
||||
mPlaybackDecl = NULL;
|
||||
mOldPlaybackDecl = NULL;
|
||||
return( true );
|
||||
}
|
||||
|
||||
const rvDeclPlayback *pb = declManager->FindPlayback( playback );
|
||||
|
||||
if( g_showPlayback.GetInteger() )
|
||||
{
|
||||
common->Printf( "Starting playback: %s\n", pb->GetName() );
|
||||
}
|
||||
|
||||
mOldPlaybackDecl = mPlaybackDecl;
|
||||
mOldFlags = mFlags;
|
||||
mOldStartTime = mStartTime;
|
||||
mOldOffset = mOffset;
|
||||
|
||||
mPlaybackDecl = pb;
|
||||
mFlags = flags;
|
||||
mStartTime = gameLocal.time;
|
||||
mOffset.Zero();
|
||||
|
||||
if( flags & PBFL_RELATIVE_POSITION )
|
||||
{
|
||||
mOffset = owner->GetPhysics()->GetOrigin() - pb->GetOrigin();
|
||||
}
|
||||
|
||||
mTransitionTime = numFrames * gameLocal.GetMSec();
|
||||
return( true );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
PlaybackCallback
|
||||
|
||||
Called whenever a button up or down, or an impulse event is found while getting the playback data
|
||||
============
|
||||
*/
|
||||
void PlaybackCallback( int type, float time, const void *data )
|
||||
{
|
||||
const rvDeclPlaybackData *pbd = ( const rvDeclPlaybackData * )data;
|
||||
idEntity *ent = pbd->GetEntity();
|
||||
|
||||
ent->PostEventSec( &EV_PlaybackCallback, time, type, pbd->GetChanged(), pbd->GetImpulse() );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
rvPlaybackDriver::UpdateFrame
|
||||
|
||||
Blend two playbacks together
|
||||
============
|
||||
*/
|
||||
bool rvPlaybackDriver::UpdateFrame( idEntity *ent, rvDeclPlaybackData &out )
|
||||
{
|
||||
rvDeclPlaybackData pbd, oldPbd;
|
||||
float blend, invBlend;
|
||||
idStr ret;
|
||||
bool expired, oldExpired;
|
||||
|
||||
// Get the current playback position
|
||||
pbd.Init();
|
||||
pbd.SetCallback( ent, PlaybackCallback );
|
||||
//expired = declManager->GetPlaybackData( mPlaybackDecl, mFlags, gameLocal.time - mStartTime, mLastTime - mStartTime, &pbd );
|
||||
pbd.SetPosition( pbd.GetPosition() + mOffset );
|
||||
|
||||
// Get the playback data we are merging from
|
||||
oldPbd.Init();
|
||||
//oldExpired = declManager->GetPlaybackData( mOldPlaybackDecl, mOldFlags, gameLocal.time - mOldStartTime, gameLocal.time - mOldStartTime, &oldPbd );
|
||||
oldPbd.SetPosition( oldPbd.GetPosition() + mOldOffset );
|
||||
|
||||
mLastTime = gameLocal.time;
|
||||
|
||||
if( g_showPlayback.GetInteger() && mPlaybackDecl )
|
||||
{
|
||||
common->Printf( "Running playback: %s at %.1f\n", mPlaybackDecl->GetName(), MS2SEC( gameLocal.time - mStartTime ) );
|
||||
}
|
||||
|
||||
// Fully merged - so delete the old one
|
||||
if( gameLocal.time > mStartTime + mTransitionTime )
|
||||
{
|
||||
oldExpired = true;
|
||||
}
|
||||
|
||||
// Interpolate the result
|
||||
if( expired && oldExpired )
|
||||
{
|
||||
out.Init();
|
||||
mPlaybackDecl = NULL;
|
||||
mOldPlaybackDecl = NULL;
|
||||
}
|
||||
else if( !expired && oldExpired )
|
||||
{
|
||||
out = pbd;
|
||||
mOldPlaybackDecl = NULL;
|
||||
}
|
||||
else if( expired && !oldExpired )
|
||||
{
|
||||
out = oldPbd;
|
||||
mPlaybackDecl = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Linear zero to one
|
||||
blend = idMath::ClampFloat( 0.0f, 1.0f, ( gameLocal.time - mStartTime ) / ( float )mTransitionTime );
|
||||
|
||||
// Sinusoidal
|
||||
blend = idMath::Sin( blend * idMath::HALF_PI );
|
||||
invBlend = 1.0f - blend;
|
||||
|
||||
out.SetPosition( blend * pbd.GetPosition() + invBlend * oldPbd.GetPosition() );
|
||||
out.SetAngles( blend * pbd.GetAngles() + invBlend * oldPbd.GetAngles() );
|
||||
out.SetButtons( pbd.GetButtons() );
|
||||
out.SetImpulse( pbd.GetImpulse() );
|
||||
}
|
||||
|
||||
return( expired );
|
||||
}
|
||||
|
||||
// cnicholson: Begin Added save/restore functionality
|
||||
/*
|
||||
============
|
||||
rvPlaybackDriver::Save
|
||||
|
||||
Save all member vars for save/load games
|
||||
============
|
||||
*/
|
||||
void rvPlaybackDriver::Save( idSaveGame *savefile ) const {
|
||||
|
||||
savefile->WriteInt( mLastTime ); // cnicholson: Added unsaved var
|
||||
savefile->WriteInt( mTransitionTime ); // cnicholson: Added unsaved var
|
||||
|
||||
savefile->WriteInt( mStartTime ); // cnicholson: Added unsaved var
|
||||
savefile->WriteInt( mFlags ); // cnicholson: Added unsaved var
|
||||
// TOSAVE: const rvDeclPlayback *mPlaybackDecl;
|
||||
savefile->WriteVec3( mOffset ); // cnicholson: Added unsaved var
|
||||
|
||||
savefile->WriteInt( mOldStartTime ); // cnicholson: Added unsaved var
|
||||
savefile->WriteInt( mOldFlags ); // cnicholson: Added unsaved var
|
||||
// TOSAVE: const rvDeclPlayback *mOldPlaybackDecl;
|
||||
savefile->WriteVec3( mOldOffset ); // cnicholson: Added unsaved var
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
rvPlaybackDriver::Restore
|
||||
|
||||
Restore all member vars for save/load games
|
||||
============
|
||||
*/
|
||||
void rvPlaybackDriver::Restore( idRestoreGame *savefile ) {
|
||||
|
||||
savefile->ReadInt( mLastTime ); // cnicholson: Added unrestored var
|
||||
savefile->ReadInt( mTransitionTime ); // cnicholson: Added unrestored var
|
||||
|
||||
savefile->ReadInt( mStartTime ); // cnicholson: Added unrestored var
|
||||
savefile->ReadInt( mFlags ); // cnicholson: Added unrestored var
|
||||
// TOSAVE: const rvDeclPlayback *mPlaybackDecl;
|
||||
savefile->ReadVec3( mOffset ); // cnicholson: Added unrestored var
|
||||
|
||||
savefile->ReadInt( mOldStartTime ); // cnicholson: Added unrestored var
|
||||
savefile->ReadInt( mOldFlags ); // cnicholson: Added unrestored var
|
||||
// TOSAVE: const rvDeclPlayback *mOldPlaybackDecl;
|
||||
savefile->ReadVec3( mOldOffset ); // cnicholson: Added unrestored var
|
||||
}
|
||||
// cnicholson: End Added save/restore functionality
|
||||
|
||||
// end
|
||||
|
||||
Reference in New Issue
Block a user