Removed old/unfinished replay code.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@10898 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-02-27 05:58:42 +00:00
parent bce6113fd7
commit f190652fb0
12 changed files with 0 additions and 1168 deletions

View File

@ -321,15 +321,6 @@ supertuxkart_SOURCES = \
race/race_manager.hpp \
replay/replay.cpp \
replay/replay.hpp \
replay/replay_base.cpp \
replay/replay_base.hpp \
replay/replay_buffer_tpl.hpp \
replay/replay_buffers.cpp \
replay/replay_buffers.hpp \
replay/replay_player.cpp \
replay/replay_player.hpp \
replay/replay_recorder.cpp \
replay/replay_recorder.hpp \
states_screens/credits.cpp \
states_screens/credits.hpp \
states_screens/dialogs/add_device_dialog.cpp \

View File

@ -1112,22 +1112,6 @@
RelativePath="..\..\replay\replay.cpp"
>
</File>
<File
RelativePath="..\..\replay\replay_base.cpp"
>
</File>
<File
RelativePath="..\..\replay\replay_buffers.cpp"
>
</File>
<File
RelativePath="..\..\replay\replay_player.cpp"
>
</File>
<File
RelativePath="..\..\replay\replay_recorder.cpp"
>
</File>
</Filter>
<Filter
Name="io"
@ -2226,26 +2210,6 @@
RelativePath="..\..\replay\replay.hpp"
>
</File>
<File
RelativePath="..\..\replay\replay_base.hpp"
>
</File>
<File
RelativePath="..\..\replay\replay_buffer_tpl.hpp"
>
</File>
<File
RelativePath="..\..\replay\replay_buffers.hpp"
>
</File>
<File
RelativePath="..\..\replay\replay_player.hpp"
>
</File>
<File
RelativePath="..\..\replay\replay_recorder.hpp"
>
</File>
</Filter>
<Filter
Name="io"

View File

@ -1,3 +0,0 @@
Those files are an unfinished attempt from Mai Semder
and are not used atm - they are left in case that
someone wants implement a replay mode.

View File

@ -1,47 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_GHOST_REPLAY
#include "replay/replay_base.hpp"
const std::string ReplayBase::REPLAY_FOLDER = "replay";
const std::string ReplayBase::REPLAY_FILE_EXTENSION_HUMAN_READABLE = "rph";
const std::string ReplayBase::REPLAY_FILE_EXTENSION_BINARY = "rpb";
ReplayBase::ReplayBase()
: m_ReplayBuffers()
{
}
ReplayBase::~ReplayBase()
{
destroy();
}
void ReplayBase::destroy()
{
m_ReplayBuffers.destroy();
}
#endif // HAVE_GHOST_REPLAY

View File

@ -1,75 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_REPLAYBASE_HPP
#define HEADER_REPLAYBASE_HPP
#ifdef HAVE_GHOST_REPLAY
#include <string>
#include "replay/replay_buffers.hpp"
// the data stored for each kart in each frame
struct ReplayKartState
{
sgCoord position;
};
// the data stored for each frame
struct ReplayFrame
{
// absolute time of frame
float time;
// for each kart in frame, points to continious block
// in Buffers::m_pp_blocks_kart_states with m_number_karts items
ReplayKartState *p_kart_states;
};
class ReplayBase
{
public:
static const std::string REPLAY_FOLDER;
static const std::string REPLAY_FILE_EXTENSION_HUMAN_READABLE;
static const std::string REPLAY_FILE_EXTENSION_BINARY;
public:
ReplayBase();
virtual ~ReplayBase();
virtual void destroy();
bool saveReplayHumanReadable( FILE *fd ) const { return m_ReplayBuffers.saveReplayHumanReadable( fd ); }
private:
protected:
ReplayBuffers m_ReplayBuffers;
};
#endif // HAVE_GHOST_REPLAY
#endif // HEADER_REPLAYBASE_HPP

View File

@ -1,327 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_REPLAYBUFFERTPL_HPP
#define HEADER_REPLAYBUFFERTPL_HPP
#ifdef HAVE_GHOST_REPLAY
#include <new>
// needed for MSVC-memory-leak-checks
#if defined( REPLAY_UNIT_TEST ) && defined( _MSC_VER )
# ifdef _DEBUG
# ifndef _DBG_NEW
# include <crtdbg.h>
inline void* __operator_new(size_t __n) { return ::operator
new(__n,_NORMAL_BLOCK,__FILE__,__LINE__); }
inline void* _cdecl operator new(size_t __n,const char* __fname,
int __line) {
return ::operator new(__n,_NORMAL_BLOCK,__fname,__line); }
inline void _cdecl operator delete(void* __p,const char*,int)
{ ::operator delete(__p);}
# define _DBG_NEW new(__FILE__,__LINE__)
# define new _DBG_NEW
# endif // _DBG_NEW
# else
# define __operator_new(__n) operator new(__n)
# endif
#endif
template<typename T> class ReplayBufferArray;
template<typename T>
class ReplayBuffer
{
friend class ReplayBufferArray<T>;
public:
ReplayBuffer() : m_pp_blocks(NULL),m_number_blocks(0),m_block_size(0),
m_number_objects_used(0),m_healthy(true) {}
~ReplayBuffer() { destroy(); }
private:
ReplayBuffer( ReplayBuffer<T> const &c );
ReplayBuffer<T> const &operator=( ReplayBuffer<T> const &c );
public:
bool init( size_t number_preallocated_objects );
void destroy();
// this is false, if a reallocation failed
bool isHealthy() const { return m_healthy; }
// returns a new *free* object, allocated memory if necessary
T* getNewObject();
// returs object at given position, like usual array access,
// does not allocate memory, index must be < getNumberObjectsUsed()
T const* getObjectAt( size_t index ) const;
T* getObjectAt( size_t index );
size_t getNumberObjectsUsed() const
{ return m_number_objects_used; }
size_t getNumberBlocks() const { return m_number_blocks; }
private:
// adds a new block of objects to m_pp_blocks with a size of m_block_size
bool addNewBlock();
// helper to make sure healthy bit is set, if new fails
template<typename TT>
TT* buffer_new_array( size_t n )
{
#if defined( REPLAY_UNIT_TEST ) && defined( _MSC_VER )
// the msvc-debug-new macros didnt like nothrow
TT *p = new TT[ n ];
#else
TT *p = new(std::nothrow) TT[ n ];
#endif
m_healthy = (NULL != p );
return p;
}
private:
T **m_pp_blocks;
// number of allocated blocks. we start with 1 for recording
// for showing a replay-file it is 1
size_t m_number_blocks;
// size of all blocks
size_t m_block_size;
// number of used objects
size_t m_number_objects_used;
// this flag indicates, that, if any reallocation happedened, it failed
// then recordings is blocked
bool m_healthy;
};
// does the same as ReplayBuffer<T>, but it returns an array of objects,
// rather than just one object ..
template<typename T>
class ReplayBufferArray
{
public:
ReplayBufferArray() : m_Buffer(), m_array_size(0) {}
~ReplayBufferArray() { destroy(); }
void destroy();
bool init( size_t number_preallocated_arrays,
size_t array_size );
// returns a new *free* array of objects with size of 2nd param in init
T* getNewArray();
// returs objects at given position, like usual array access,
// does not allocate memory
T const* getArrayAt( size_t index ) const
{ assert( m_array_size );
return m_Buffer.getObjectAt( m_array_size * index ); }
T* getArrayAt( size_t index )
{ assert( m_array_size );
return m_Buffer.getObjectAt( m_array_size * index ); }
size_t getNumberArraysUsed() const
{ return m_Buffer.getNumberObjectsUsed() / m_array_size; }
size_t getNumberBlocks() const
{ return m_Buffer.getNumberBlocks(); }
bool isHealthy() const
{ return m_Buffer.isHealthy(); }
private:
ReplayBuffer<T> m_Buffer;
size_t m_array_size;
};
template<typename T>
bool ReplayBuffer<T>::init( size_t number_preallocated_objects )
{
// make sure *clean* usage
assert( !m_pp_blocks );
assert( number_preallocated_objects );
m_block_size = number_preallocated_objects;
if( !addNewBlock() ) return false;
return true;
}
template<typename T>
void ReplayBuffer<T>::destroy()
{
size_t tmp;
if( m_pp_blocks )
{
for( tmp = 0; tmp < m_number_blocks; ++tmp ) delete[] m_pp_blocks[tmp];
delete[] m_pp_blocks; m_pp_blocks = NULL;
m_number_blocks = 0;
m_block_size = 0;
m_number_objects_used = 0;
m_healthy = true;
}
}
// returns a new *free* frame to be used to store the current frame-data into
// it used to *record* the replay
template<typename T>
T* ReplayBuffer<T>::getNewObject()
{
// make sure initialization was called properly
assert( m_pp_blocks );
assert( m_number_blocks );
if( !m_healthy ) return NULL;
// check, if we need a new block
if( m_number_objects_used == (m_block_size*m_number_blocks) )
{
// we need a new block
if( !addNewBlock() ) return NULL;
}
// get current frame
T* block_current = m_pp_blocks[ m_number_blocks-1 ];
size_t new_in_block_idx = m_number_objects_used % m_block_size;
T* current = block_current + new_in_block_idx;
++m_number_objects_used;
return current;
}
// returs frame at given position from replay data
// used to *show* the replay
template<typename T>
T const* ReplayBuffer<T>::getObjectAt( size_t index ) const
{
// make sure initialization was called properly
assert( m_pp_blocks );
assert( m_number_blocks );
assert( index < m_number_objects_used );
assert( (index / m_block_size) < m_number_blocks );
T const* block = m_pp_blocks[ index / m_block_size ];
return block + (index % m_block_size);
}
template<typename T>
T* ReplayBuffer<T>::getObjectAt( size_t index )
{
// make sure initialization was called properly
assert( m_pp_blocks );
assert( m_number_blocks );
assert( index < m_number_objects_used );
assert( (index / m_block_size) < m_number_blocks );
T* block = m_pp_blocks[ index / m_block_size ];
return block + (index % m_block_size);
}
// adds a new block of objects to m_pp_blocks with a size of m_block_size
template<typename T>
bool ReplayBuffer<T>::addNewBlock()
{
assert( m_block_size );
if( !m_healthy ) return false;
size_t number_blocks_new = m_number_blocks + 1;
T **pp_blocks_old = m_pp_blocks;
m_pp_blocks = buffer_new_array<T*>( number_blocks_new );
if( !m_pp_blocks )
{
// put back old blocks
m_pp_blocks = pp_blocks_old;
return false;
}
// copy old block pointers .. note: we dont copy the objects,
// only the pointers, to blocks of objects, which is supposed
// to be a very small number .. 2 is probably never reached
size_t tmp;
for( tmp = 0; tmp < m_number_blocks; ++tmp )
m_pp_blocks[tmp] = pp_blocks_old[tmp];
// create new objects at new block position
m_pp_blocks[m_number_blocks] = buffer_new_array<T>( m_block_size );
if( !m_pp_blocks[m_number_blocks] )
{
// delete and put back old blocks
delete[] m_pp_blocks;
m_pp_blocks = pp_blocks_old;
return false;
}
// everything went fine, we got new arrays of objects
delete[] pp_blocks_old; pp_blocks_old = NULL;
++m_number_blocks;
return true;
}
template<typename T>
void ReplayBufferArray<T>::destroy()
{
m_Buffer.destroy();
m_array_size = 0;
}
template<typename T>
bool ReplayBufferArray<T>::init( size_t number_preallocated_arrays,
size_t array_size )
{
assert( number_preallocated_arrays );
assert( array_size );
m_array_size = array_size;
return m_Buffer.init( number_preallocated_arrays * array_size );
}
// returns a new *free* array of objects
template<typename T>
T* ReplayBufferArray<T>::getNewArray()
{
if( !isHealthy() ) return NULL;
// check, if we need a new block
if( m_Buffer.m_number_objects_used ==
(m_Buffer.m_block_size*m_Buffer.m_number_blocks) )
{
// we need a new block
if( !m_Buffer.addNewBlock() ) return NULL;
}
// get current frame
T* block_current = m_Buffer.m_pp_blocks[ m_Buffer.m_number_blocks-1 ];
size_t new_in_block_idx =
m_Buffer.m_number_objects_used % m_Buffer.m_block_size;
T* current = block_current + new_in_block_idx;
assert( (current + m_array_size) <= (m_Buffer
.m_pp_blocks[ m_Buffer.m_number_blocks-1 ]
+ m_Buffer.m_block_size) );
m_Buffer.m_number_objects_used += m_array_size;
return current;
}
#endif // HAVE_GHOST_REPLAY
#endif // HEADER_REPLAYBUFFERTPL_HPP

View File

@ -1,175 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_GHOST_REPLAY
#include "replay/replay_buffers.hpp"
#include <cassert>
#include "replay/replay_base.hpp"
#define REPLAY_SAVE_STATISTIC
ReplayBuffers::ReplayBuffers()
: m_number_karts(0),
m_BufferFrame(),
m_BufferKartState()
{
}
ReplayBuffers::~ReplayBuffers()
{
destroy();
}
void ReplayBuffers::destroy()
{
m_BufferFrame.destroy();
m_BufferKartState.destroy();
m_number_karts = 0;
}
bool ReplayBuffers::init( unsigned int number_karts,
size_t number_preallocated_frames )
{
m_number_karts = number_karts;
if( !m_BufferFrame.init( number_preallocated_frames ) ) return false;
if( !m_BufferKartState.init( number_preallocated_frames, number_karts ) ) return false;
return true;
}
ReplayFrame*
ReplayBuffers::getNewFrame()
{
// make sure initialization was called properly
assert( m_BufferFrame.getNumberObjectsUsed() == m_BufferKartState.getNumberArraysUsed() );
if( !isHealthy() ) return NULL;
ReplayFrame* frame = m_BufferFrame.getNewObject();
if( !frame ) return NULL;
// get current karts-array
ReplayKartState* karts_array = m_BufferKartState.getNewArray();
if( !karts_array ) return NULL;
frame->p_kart_states = karts_array;
return frame;
}
bool ReplayBuffers::saveReplayHumanReadable( FILE *fd ) const
{
if( !isHealthy() ) return false;
if( fprintf( fd, "frames: %u\n", getNumberFrames() ) < 1 ) return false;
#ifdef REPLAY_SAVE_STATISTIC
float time_step_min = 9999999.0f, time_step_max = 0.0f, time_last;
#endif
unsigned int frame_idx, kart_idx;
ReplayFrame const *frame;
ReplayKartState const *kart;
for( frame_idx = 0; frame_idx < getNumberFrames(); ++frame_idx )
{
frame = getFrameAt( frame_idx );
if( fprintf( fd, "frame %u time %f\n", frame_idx, frame->time ) < 1 ) return false;
for( kart_idx = 0; kart_idx < m_number_karts; ++kart_idx )
{
kart = frame->p_kart_states + kart_idx;
if( fprintf( fd, "\tkart %u: %f,%f,%f,%f,%f,%f\n", kart_idx,
kart->position.xyz[0], kart->position.xyz[1], kart->position.xyz[2],
kart->position.hpr[0], kart->position.hpr[1], kart->position.hpr[2] ) < 1 ) return false;
}
#ifdef REPLAY_SAVE_STATISTIC
if( frame_idx )
{
float diff = frame->time - time_last;
if( diff < time_step_min ) time_step_min = diff;
if( diff > time_step_max ) time_step_max = diff;
}
time_last = frame->time;
#endif
}
#ifdef REPLAY_SAVE_STATISTIC
float time_step_avg;
if( getNumberFrames() > 1 )
{
time_step_avg = time_last / ( getNumberFrames() - 1 );
}
else
{
time_step_avg = -1.0f;
}
fprintf( fd, "\n# statistic time-steps:\n# \tmin: %f\n# \tmax: %f\n# \tavg: %f\n", time_step_min, time_step_max, time_step_avg );
#endif
return true;
}
bool ReplayBuffers::loadReplayHumanReadable( FILE *fd, unsigned int number_karts )
{
size_t frames;
if( fscanf( fd, "frames: %u\n", &frames ) != 1 ) return false;
if( !init( number_karts, frames ) ) return false;
assert( m_number_karts );
unsigned int frame_idx, kart_idx, tmp;
ReplayFrame *frame;
ReplayKartState *kart;
for( frame_idx = 0; frame_idx < frames; ++frame_idx )
{
// if we are here, it cant fail, since enough objects have to be allocated above
frame = getNewFrame();
assert( frame );
if( fscanf( fd, "frame %u time %f\n", &tmp, &frame->time ) != 2 ) return false;
for( kart_idx = 0; kart_idx < m_number_karts; ++kart_idx )
{
kart = frame->p_kart_states + kart_idx;
if( fscanf( fd, "\tkart %u: %f,%f,%f,%f,%f,%f\n", &tmp,
&kart->position.xyz[0], &kart->position.xyz[1], &kart->position.xyz[2],
&kart->position.hpr[0], &kart->position.hpr[1], &kart->position.hpr[2] ) != 7 ) return false;
}
}
assert( frames == getNumberFrames() );
assert( m_BufferFrame.getNumberObjectsUsed() == getNumberFrames() );
assert( m_BufferKartState.getNumberArraysUsed() == getNumberFrames() );
// there should be no reallocation ..
assert( m_BufferFrame.getNumberBlocks() == 1 );
assert( m_BufferKartState.getNumberBlocks() == 1 );
return true;
}
#endif // HAVE_GHOST_REPLAY

View File

@ -1,77 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_REPLAYBUFFERS_HPP
#define HEADER_REPLAYBUFFERS_HPP
#ifdef HAVE_GHOST_REPLAY
#include <cstdio>
#include "replay/replay_buffer_tpl.hpp"
struct ReplayKartState;
struct ReplayFrame;
// the worker-class .. administrates the memory-usage with no copy of
// previous replay-items when reallocation needed if buffers are full
class ReplayBuffers
{
public:
ReplayBuffers();
~ReplayBuffers();
bool init( unsigned int number_karts,
size_t number_preallocated_frames );
void destroy();
// returns a new *free* frame to be used to store the current frame-data into it
// used to *record* the replay
ReplayFrame* getNewFrame();
// returs frame at given position from replay data
// used to *show* the replay
// if frame_index >= num_frames -> returns NULL
ReplayFrame const* getFrameAt( size_t frame_index ) const { return m_BufferFrame.getObjectAt( frame_index ); }
size_t getNumberFrames() const { return m_BufferFrame.getNumberObjectsUsed(); }
unsigned int getNumberKarts() const { return m_number_karts; }
bool saveReplayHumanReadable( FILE *fd ) const;
bool loadReplayHumanReadable( FILE *fd, unsigned int number_karts );
private:
bool isHealthy() const { return m_BufferFrame.isHealthy() && m_BufferKartState.isHealthy(); }
private:
typedef ReplayBuffer<ReplayFrame> BufferFrame;
typedef ReplayBufferArray<ReplayKartState> BufferKartState;
unsigned int m_number_karts;
BufferFrame m_BufferFrame;
BufferKartState m_BufferKartState;
};
#endif // HAVE_GHOST_REPLAY
#endif // HEADER_REPLAYBUFFERS_HPP

View File

@ -1,186 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_GHOST_REPLAY
#include "replay/replay_player.hpp"
#include "karts/kart_properties_manager.hpp"
#include "karts/kart_properties.hpp"
ReplayKart::ReplayKart()
: m_kart_properties(NULL), m_model(NULL)
{
}
ReplayKart::~ReplayKart()
{
destroy();
}
void ReplayKart::destroy()
{
m_kart_properties = NULL;
}
bool ReplayKart::init( const std::string &strKartIdent )
{
assert( !m_kart_properties );
m_model = new ssgTransform();
m_model->ref();
m_kart_properties = kart_properties_manager->getKart( strKartIdent );
if( NULL == m_kart_properties ) return false;
ssgEntity *obj = m_kart_properties->getModel();
assert( obj );
// Optimize the model, this can't be done while loading the model
// because it seems that it removes the name of the wheels or something
// else needed to load the wheels as a separate object.
ssgFlatten(obj);
ssgRangeSelector *lod = new ssgRangeSelector;
float r [ 2 ] = { -10.0f, 100.0f } ;
lod -> addKid ( obj ) ;
lod -> setRanges ( r, 2 ) ;
m_model -> addKid ( lod ) ;
return true;
}
ReplayPlayer::ReplayPlayer()
: ReplayBase(), m_current_frame_index(-1)
{
}
ReplayPlayer::~ReplayPlayer()
{
destroy();
}
void ReplayPlayer::destroy()
{
m_current_frame_index = -1;
m_Karts.clear();
ReplayBase::destroy();
}
bool ReplayPlayer::loadReplayHumanReadable( FILE *fd )
{
destroy();
bool blnRet = false;
int intTemp;
char buff[1000];
size_t number_karts;
if( fscanf( fd, "Version: %s\n", buff ) != 1 ) return false;
if( fscanf( fd, "numkarts: %u\n", &number_karts ) != 1 ) return false;
if( fscanf( fd, "numplayers: %s\n", buff ) != 1 ) return false;
if( fscanf( fd, "difficulty: %s\n", buff ) != 1 ) return false;
if( fscanf( fd, "track: %s\n", buff ) != 1 ) return false;
for( size_t k = 0; k < number_karts; ++k )
{
if( fscanf( fd, "model %d: %s\n", &intTemp, buff ) != 2 ) return false;
m_Karts.resize( m_Karts.size() + 1 );
ReplayKart &kart = m_Karts[ m_Karts.size() - 1 ];
if( !kart.init( buff ) ) return false;
scene->add ( kart.getModel() );
}
if( !m_ReplayBuffers.loadReplayHumanReadable( fd, number_karts ) ) return false;
m_current_frame_index = 0;
return true;
}
void ReplayPlayer::showReplayAt( float abs_time )
{
assert( m_ReplayBuffers.getNumberFrames() );
assert( m_current_frame_index > -1 );
assert( (size_t)m_current_frame_index < m_ReplayBuffers.getNumberFrames() );
ReplayFrame const* frame;
// find the current frame, we only scroll forward ..
while(1)
{
// end reached?
if( (m_current_frame_index + 1) == m_ReplayBuffers.getNumberFrames() ) break;
// check time of next frame
frame = m_ReplayBuffers.getFrameAt( m_current_frame_index+1 );
if( frame->time > abs_time ) break;
++m_current_frame_index;
}
frame = m_ReplayBuffers.getFrameAt( m_current_frame_index );
// interpolate, if we are not at the end
if( (m_current_frame_index + 1) < (int)m_ReplayBuffers.getNumberFrames() )
{
ReplayFrame const* frame_next = m_ReplayBuffers.getFrameAt( m_current_frame_index+1 );
// calc scale factor based on time between frames
assert( frame_next->time > frame->time );
assert( frame_next->time != frame->time );
float scale = (abs_time - frame->time) / (frame_next->time - frame->time);
sgVec3 tmp_v3;
sgCoord pos;
// calc interpolations for all objects
for( size_t k = 0; k < m_Karts.size(); ++k )
{
// calc distance between next and current frame-position
sgCopyVec3( pos.xyz, frame->p_kart_states[k].position.xyz ) ;
sgCopyVec3( tmp_v3, frame_next->p_kart_states[k].position.xyz ) ;
sgSubVec3( tmp_v3, pos.xyz );
// scale it based on time between frames
sgScaleVec3( tmp_v3, scale );
// add interpolated vector
sgAddVec3( pos.xyz, tmp_v3 );
// no orientation-interpolation for starters
sgCopyVec3( pos.hpr, frame->p_kart_states[k].position.hpr );
m_Karts[ k ].setPosition( pos );
}
}
else
{
// replay finished, leave them at last known position
for( size_t k = 0; k < m_Karts.size(); ++k )
{
m_Karts[ k ].setPosition( frame->p_kart_states[ k ].position );
}
}
}
#endif // HAVE_GHOST_REPLAY

View File

@ -1,86 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_REPLAYPLAYER_HPP
#define HEADER_REPLAYPLAYER_HPP
#ifdef HAVE_GHOST_REPLAY
#include <vector>
#include "replay/replay_base.hpp"
class KartProperties;
class ReplayKart
{
public:
ReplayKart();
~ReplayKart();
ReplayKart( ReplayKart const &kart ) { *this = kart; }
ReplayKart& operator=( ReplayKart const &kart )
{
assert( this != &kart );
m_kart_properties = kart.m_kart_properties;
m_model = kart.m_model;
sgCopyCoord ( &m_position, &kart.m_position );
return *this;
}
bool init( const std::string &strKartIdent );
void destroy();
ssgTransform* getModel() { return m_model; }
void setPosition( const sgCoord &pos ) { sgCopyCoord ( &m_position, &pos ); m_model->setTransform(&m_position); }
private:
const KartProperties *m_kart_properties;
sgCoord m_position;
ssgTransform *m_model;
};
// class managing:
// - the loading of replay-file
// - the rendering of the replay (interpolation if needed)
class ReplayPlayer : public ReplayBase
{
public:
ReplayPlayer();
virtual ~ReplayPlayer();
void destroy();
bool loadReplayHumanReadable( FILE *fd );
// calc state of replay-objects at given time
void showReplayAt( float abs_time );
void reset() { m_current_frame_index = 0; }
private:
typedef std::vector<ReplayKart> ReplayKarts;
int m_current_frame_index;
ReplayKarts m_Karts;
};
#endif // HAVE_GHOST_REPLAY
#endif // HEADER_REPLAYPLAYER_HPP

View File

@ -1,85 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef HAVE_GHOST_REPLAY
#include "replay/replay_recorder.hpp"
#include <cassert>
#include "modes/world.hpp"
const float ReplayRecorder::REPLAY_TIME_STEP_MIN = 1.0f / (float)ReplayRecorder::REPLAY_FREQUENCY_MAX;
ReplayRecorder::ReplayRecorder()
: ReplayBase()
{
}
ReplayRecorder::~ReplayRecorder()
{
destroy();
}
void ReplayRecorder::destroy()
{
ReplayBase::destroy();
}
bool ReplayRecorder::initRecorder( unsigned int number_karts, size_t number_preallocated_frames )
{
assert( number_karts );
destroy();
if( !m_ReplayBuffers.init( number_karts, number_preallocated_frames ) ) return false;
return true;
}
bool ReplayRecorder::pushFrame()
{
// we dont record the startphase ..
assert( RaceManager::getWorld()->getPhase() != World::START_PHASE );
assert( RaceManager::getWorld()->getNumKarts() == m_ReplayBuffers.getNumberKarts() );
// make sure we're not under time-step-min
if( m_ReplayBuffers.getNumberFrames() )
{
ReplayFrame const *last_Frame = m_ReplayBuffers.getFrameAt( m_ReplayBuffers.getNumberFrames() - 1 );
if( (RaceManager::getWorld()->getTime() - last_Frame->time) < REPLAY_TIME_STEP_MIN ) return true;
}
ReplayFrame *pFrame = getNewFrame();
if( !pFrame ) return false;
pFrame->time = RaceManager::getWorld()->getClock();
Kart const *kart;
int number_karts = RaceManager::getWorld()->getNumKarts();
for( int kart_index = 0; kart_index < number_karts; ++kart_index )
{
kart = RaceManager::getKart( kart_index );
sgCopyCoord( &( pFrame->p_kart_states[ kart_index ].position ),
kart->getCoord() );
}
return true;
}
#endif // HAVE_GHOST_REPLAY

View File

@ -1,62 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2007 Maik Semder <ikework@gmx.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_REPLAYRECORDER_HPP
#define HEADER_REPLAYRECORDER_HPP
#ifdef HAVE_GHOST_REPLAY
#include "replay/replay_base.hpp"
// class managing:
// - the recording of the replay
// - the serializing to file
class ReplayRecorder : public ReplayBase
{
private:
// assuming 10 minutes with 50 frames per second
enum { BUFFER_PREALLOCATE_FRAMES = 10 * 50 * 60, };
enum { REPLAY_FREQUENCY_MAX = 30 };
// calculated from REPLAY_FREQUENCY_MAX
static const float REPLAY_TIME_STEP_MIN;
public:
ReplayRecorder();
virtual ~ReplayRecorder();
void destroy();
bool initRecorder( unsigned int number_karts,
size_t number_preallocated_frames = BUFFER_PREALLOCATE_FRAMES );
// something might go wrong, since a new buffer may be allocated, so false means
// no memory available
bool pushFrame();
private:
// returns a new *free* frame to be used to store the current frame-data into it
// used to *record* the replay
ReplayFrame* getNewFrame() { return m_ReplayBuffers.getNewFrame(); }
};
#endif // HAVE_GHOST_REPLAY
#endif // HEADER_REPLAYRECORDER_HPP