summaryrefslogtreecommitdiffstats
path: root/game/code/loading
diff options
context:
space:
mode:
Diffstat (limited to 'game/code/loading')
-rw-r--r--game/code/loading/allloadmanager.cpp15
-rw-r--r--game/code/loading/cameradataloader.cpp168
-rw-r--r--game/code/loading/cameradataloader.h77
-rw-r--r--game/code/loading/cementfilehandler.cpp147
-rw-r--r--game/code/loading/cementfilehandler.h76
-rw-r--r--game/code/loading/choreofilehandler.cpp238
-rw-r--r--game/code/loading/choreofilehandler.h85
-rw-r--r--game/code/loading/consolefilehandler.cpp237
-rw-r--r--game/code/loading/consolefilehandler.h78
-rw-r--r--game/code/loading/filehandler.h105
-rw-r--r--game/code/loading/filehandlerenum.h46
-rw-r--r--game/code/loading/filehandlerfactory.cpp173
-rw-r--r--game/code/loading/filehandlerfactory.h41
-rw-r--r--game/code/loading/iconfilehandler.cpp200
-rw-r--r--game/code/loading/iconfilehandler.h79
-rw-r--r--game/code/loading/intersectionloader.cpp157
-rw-r--r--game/code/loading/intersectionloader.h29
-rw-r--r--game/code/loading/loadingmanager.cpp648
-rw-r--r--game/code/loading/loadingmanager.h213
-rw-r--r--game/code/loading/locatorloader.cpp1118
-rw-r--r--game/code/loading/locatorloader.h85
-rw-r--r--game/code/loading/p3dfilehandler.cpp196
-rw-r--r--game/code/loading/p3dfilehandler.h81
-rw-r--r--game/code/loading/pathloader.cpp214
-rw-r--r--game/code/loading/pathloader.h70
-rw-r--r--game/code/loading/roaddatasegmentloader.cpp140
-rw-r--r--game/code/loading/roaddatasegmentloader.h53
-rw-r--r--game/code/loading/roadloader.cpp544
-rw-r--r--game/code/loading/roadloader.h87
-rw-r--r--game/code/loading/scroobyfilehandler.cpp172
-rw-r--r--game/code/loading/scroobyfilehandler.h70
-rw-r--r--game/code/loading/soundfilehandler.cpp132
-rw-r--r--game/code/loading/soundfilehandler.h66
33 files changed, 5840 insertions, 0 deletions
diff --git a/game/code/loading/allloadmanager.cpp b/game/code/loading/allloadmanager.cpp
new file mode 100644
index 0000000..a820a6f
--- /dev/null
+++ b/game/code/loading/allloadmanager.cpp
@@ -0,0 +1,15 @@
+#include <loading/cameradataloader.cpp>
+#include <loading/cementfilehandler.cpp>
+#include <loading/choreofilehandler.cpp>
+#include <loading/consolefilehandler.cpp>
+#include <loading/filehandlerfactory.cpp>
+#include <loading/iconfilehandler.cpp>
+#include <loading/intersectionloader.cpp>
+#include <loading/loadingmanager.cpp>
+#include <loading/locatorloader.cpp>
+#include <loading/p3dfilehandler.cpp>
+#include <loading/roaddatasegmentloader.cpp>
+#include <loading/roadloader.cpp>
+#include <loading/scroobyfilehandler.cpp>
+#include <loading/soundfilehandler.cpp>
+#include <loading/pathloader.cpp>
diff --git a/game/code/loading/cameradataloader.cpp b/game/code/loading/cameradataloader.cpp
new file mode 100644
index 0000000..7adbc8c
--- /dev/null
+++ b/game/code/loading/cameradataloader.cpp
@@ -0,0 +1,168 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: CameraDataLoader.cpp
+//
+// Description: Implement CameraDataLoader
+//
+// History: 17/06/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/chunkfile.hpp>
+#include <p3d/utility.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/CameraDataLoader.h>
+
+#include <camera/followcamdatachunk.h>
+#include <camera/walkercamdatachunk.h>
+#include <camera/supercamcentral.h>
+
+#include <memory/srrmemory.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// CameraDataLoader::CameraDataLoader
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+CameraDataLoader::CameraDataLoader()
+{
+}
+
+//==============================================================================
+// CameraDataLoader::~CameraDataLoader
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+CameraDataLoader::~CameraDataLoader()
+{
+}
+
+//=============================================================================
+// CameraDataLoader::Load
+//=============================================================================
+// Description: Comment
+//
+// Parameters: (tChunkFile* f, tEntityStore* store)
+//
+// Return: tLoadStatus
+//
+//=============================================================================
+tLoadStatus CameraDataLoader::Load(tChunkFile* f, tEntityStore* store)
+{
+MEMTRACK_PUSH_GROUP( "Camera Data Loading" );
+
+ //This loads two types of chunks. Follow and walker cams.
+
+ unsigned int id = f->GetUInt();
+
+ char name[256];
+ sprintf( name, "CameraData%d", id );
+
+ HeapMgr()->PushHeap (GMA_LEVEL_OTHER);
+
+ if ( f->GetCurrentID() == SRR2::ChunkID::FOLLOWCAM )
+ {
+ if ( !SuperCamCentral::FindFCD( id ) )
+ {
+ //Load and create a FOLLOWCAM data chunk
+ FollowCamDataChunk& fcD = SuperCamCentral::GetNewFollowCamDataChunk();
+
+ fcD.SetName( name );
+
+ fcD.mID = id;
+ fcD.mRotation = f->GetFloat();
+ fcD.mElevation = f->GetFloat();
+ fcD.mMagnitude = f->GetFloat();
+
+ fcD.mTargetOffset.x = f->GetFloat();
+ fcD.mTargetOffset.y = f->GetFloat();
+ fcD.mTargetOffset.z = f->GetFloat();
+ }
+ }
+ else if ( f->GetCurrentID() == SRR2::ChunkID::WALKERCAM )
+ {
+ //Load and create a WALKERCAM data chunk
+ WalkerCamDataChunk* wcD = new WalkerCamDataChunk();
+
+ rAssert( wcD );
+
+ wcD->SetName( name );
+
+ wcD->mID = id;
+ wcD->mMinMagnitude = f->GetFloat();
+ wcD->mMaxMagnitude = f->GetFloat();
+ wcD->mElevation = f->GetFloat();
+
+ wcD->mTargetOffset.x = f->GetFloat();
+ wcD->mTargetOffset.y = f->GetFloat();
+ wcD->mTargetOffset.z = f->GetFloat();
+
+ //store->Store( wcD );
+ tEntity* camData = NULL;
+ camData = wcD;
+
+ if ( camData )
+ {
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( SuperCamCentral::CAMERA_INVENTORY_SECTION );
+ //const tName& name = camData->GetNameObject();
+ //p3d::inventory->find( name );
+ bool collision = p3d::inventory->TestCollision( camData );
+ if( !collision )
+ {
+ p3d::inventory->Store( camData );
+ }
+ else
+ {
+ camData->AddRef();
+ camData->Release();
+ }
+ p3d::inventory->PopSection();
+ }
+ }
+
+
+ HeapMgr()->PopHeap (GMA_LEVEL_OTHER);
+
+MEMTRACK_POP_GROUP("Camera Data Loading");
+
+ return LOAD_OK;
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/loading/cameradataloader.h b/game/code/loading/cameradataloader.h
new file mode 100644
index 0000000..be5b85f
--- /dev/null
+++ b/game/code/loading/cameradataloader.h
@@ -0,0 +1,77 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: cameradataloader.h
+//
+// Description: Blahblahblah
+//
+// History: 17/06/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+#ifndef CAMERADATALOADER_H
+#define CAMERADATALOADER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <constants/srrchunks.h>
+#include <p3d/loadmanager.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class CameraDataLoader : public tChunkHandler
+{
+public:
+ CameraDataLoader();
+ virtual ~CameraDataLoader();
+
+ // P3D chunk loader.
+ virtual tLoadStatus Load(tChunkFile* f, tEntityStore* store);
+
+ // P3D chunk id.
+ virtual bool CheckChunkID(unsigned id);
+ virtual unsigned int GetChunkID();
+
+private:
+
+ //Prevent wasteful constructor creation.
+ CameraDataLoader( const CameraDataLoader& cameradataloader );
+ CameraDataLoader& operator=( const CameraDataLoader& cameradataloader );
+};
+
+//******************************************************************************
+//
+// Inline Public Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// CameraDataLoader::CheckChunkID
+//=============================================================================
+// Description: Comment
+//
+// Parameters: (unsigned id)
+//
+// Return: bool
+//
+//=============================================================================
+inline bool CameraDataLoader::CheckChunkID(unsigned id)
+{
+ return( SRR2::ChunkID::FOLLOWCAM == id || SRR2::ChunkID::WALKERCAM == id );
+}
+
+inline unsigned int CameraDataLoader::GetChunkID()
+{
+ return SRR2::ChunkID::FOLLOWCAM | SRR2::ChunkID::WALKERCAM;
+}
+
+#endif //CAMERADATALOADER_H
diff --git a/game/code/loading/cementfilehandler.cpp b/game/code/loading/cementfilehandler.cpp
new file mode 100644
index 0000000..ac17aca
--- /dev/null
+++ b/game/code/loading/cementfilehandler.cpp
@@ -0,0 +1,147 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: cementfilehandler.cpp
+//
+// Description: Implements CementFileHandler class, which allows us to add
+// cement file registration to the loading manager file queue
+//
+// History: 30/07/2002 + Created -- Darren
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/cementfilehandler.h>
+
+#include <main/commandlineoptions.h>
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// CementFileHandler::CementFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: library - Cement library that we're waiting on for registration
+//
+// Return: N/A.
+//
+//==============================================================================
+CementFileHandler::CementFileHandler( LoadingManager::CementLibraryStruct* libraryStruct ) :
+ m_libraryStruct( libraryStruct )
+{
+}
+
+//==============================================================================
+// CementFileHandler::~CementFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+CementFileHandler::~CementFileHandler()
+{
+}
+
+//=============================================================================
+// CementFileHandler::LoadFile
+//=============================================================================
+// Description: Start looking at the cement library to see if it's registered
+//
+// Parameters: filename - ignored, since we're not really loading a file
+// pCallback - loading manager, to be signalled on registration
+// completion
+// pUserData - user data to be passed back in callback
+//
+// Return: void
+//
+//=============================================================================
+void CementFileHandler::LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap )
+{
+ radCementLibraryPriority priority;
+
+ mpCallback = pCallback;
+ mpUserData = pUserData;
+
+ if( CommandLineOptions::Get( CLO_CD_FILES_ONLY ) )
+ {
+ priority = radCementLibraryBeforeDrive;
+ }
+ else
+ {
+ priority = radCementLibraryAfterDrive;
+ }
+
+ ::radFileRegisterCementLibrary( &(m_libraryStruct->library),
+ filename,
+ priority,
+ 0,
+ GMA_PERSISTENT );
+
+ m_libraryStruct->library->SetCompletionCallback( this, NULL );
+}
+
+//=============================================================================
+// CementFileHandler::LoadFileSync
+//=============================================================================
+// Description: Unused synchronous loading function
+//
+// Parameters: Ignored
+//
+// Return: void
+//
+//=============================================================================
+void CementFileHandler::LoadFileSync( const char* filename )
+{
+ //
+ // RadFile doesn't offer synchronous cement file registration, so we shouldn't
+ // see this function called
+ //
+ rAssert( false );
+}
+
+//=============================================================================
+// CementFileHandler::OnCementLibraryRegistered
+//=============================================================================
+// Description: Called by the cement library when registration is complete
+//
+// Parameters: Unused
+//
+// Return: void
+//
+//=============================================================================
+void CementFileHandler::OnCementLibraryRegistered( void* pUserData )
+{
+ m_libraryStruct->isLoading = false;
+
+ mpCallback->OnLoadFileComplete( mpUserData );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/loading/cementfilehandler.h b/game/code/loading/cementfilehandler.h
new file mode 100644
index 0000000..5aa3440
--- /dev/null
+++ b/game/code/loading/cementfilehandler.h
@@ -0,0 +1,76 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: cementfilehandler.h
+//
+// Description: Declares CementFileHandler class, which allows us to add
+// cement file registration to the loading manager file queue
+//
+// History: 30/07/2002 + Created -- Darren
+//
+//=============================================================================
+
+#ifndef CEMENTFILEHANDLER_H
+#define CEMENTFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <radfile.hpp>
+
+#include <loading/filehandler.h>
+#include <loading/loadingmanager.h>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: CementFileHandler
+//
+//=============================================================================
+
+class CementFileHandler : public FileHandler,
+ public IRadCementLibraryCompletionCallback
+{
+ public:
+ CementFileHandler( LoadingManager::CementLibraryStruct* library );
+ virtual ~CementFileHandler();
+
+ //
+ // Load file asynchronously.
+ //
+ void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ //
+ // Load file synchronously (unused)
+ //
+ void LoadFileSync( const char* filename );
+
+ //
+ // Cement file registration callback
+ //
+ void OnCementLibraryRegistered( void* pUserData );
+
+ //
+ // Playin' fast and loose with reference counting
+ //
+ virtual void AddRef() {FileHandler::AddRef();}
+ virtual void Release() {FileHandler::Release();}
+
+ private:
+ // Prevent wasteful constructor creation.
+ CementFileHandler();
+ CementFileHandler( const CementFileHandler& original );
+ CementFileHandler& operator=( const CementFileHandler& rhs );
+
+ LoadingManager::CementLibraryStruct* m_libraryStruct;
+};
+
+
+#endif // CEMENTFILEHANDLER_H
+
diff --git a/game/code/loading/choreofilehandler.cpp b/game/code/loading/choreofilehandler.cpp
new file mode 100644
index 0000000..1197536
--- /dev/null
+++ b/game/code/loading/choreofilehandler.cpp
@@ -0,0 +1,238 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: choreofilehandler.cpp
+//
+// Description: Implement ChoreoFileHandler
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+#include <string.h>
+// Pure 3D
+#include <p3d/utility.hpp>
+// Foundation Tech
+#include <raddebug.hpp>
+// Choreo
+#include <choreo/load.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/choreofilehandler.h>
+#include <memory/srrmemory.h>
+#include <worldsim/character/charactermanager.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// ChoreoFileHandler::ChoreoFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+ChoreoFileHandler::ChoreoFileHandler()
+:
+m_state( NONE ),
+mScriptString( 0 ),
+mpScriptFile( 0 )
+{
+}
+
+//==============================================================================
+// ChoreoFileHandler::~ChoreoFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+ChoreoFileHandler::~ChoreoFileHandler()
+{
+}
+
+
+//==============================================================================
+// ChoreoFileHandler::LoadFile
+//==============================================================================
+//
+// Description: Load a choreo file asynchronously.
+//
+// Parameters: filename - fully qualified path and filename
+// pCallback - client callback to invoke when load is complete
+// pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void ChoreoFileHandler::LoadFile
+(
+ const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap
+)
+{
+ rAssert( filename );
+ rAssert( pCallback );
+
+ mpCallback = pCallback;
+
+ // by default, use FTT IRadFiles
+ //
+ m_state = OPENFILE;
+ choreo::RegisterDefaultScriptHandlers();
+ radFileOpen(&mpScriptFile,
+ filename,
+ false,
+ OpenExisting,
+ NormalPriority);
+ P3DASSERT(mpScriptFile != 0);
+ mpScriptFile->AddCompletionCallback( this, (void*)pUserData );
+
+
+}
+
+
+//==============================================================================
+// ChoreoFileHandler::OnFileOperationsComplete
+//==============================================================================
+//
+// Description: FTech invokes this callback when the async load
+// is complete.
+//
+// Parameters: pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void ChoreoFileHandler::OnFileOperationsComplete( void* pUserData )
+{
+ switch ( m_state )
+ {
+ case OPENFILE:
+ {
+
+MEMTRACK_PUSH_GROUP( "ChoreoFileHandler" );
+ unsigned length = mpScriptFile->GetSize();
+ mScriptString = new(GMA_TEMP) char [length + 1];
+ mpScriptFile->ReadAsync( mScriptString, length );
+ mpScriptFile->AddCompletionCallback( this, (void*)pUserData );
+ m_state = READDATA;
+MEMTRACK_POP_GROUP("ChoreoFileHandler");
+
+ break;
+ }
+ case READDATA:
+ {
+ unsigned length = mpScriptFile->GetSize();
+ mScriptString[length] = '\0';
+
+ p3d::inventory->PushSection( );
+ p3d::inventory->SelectSection( GetSectionName() );
+ HeapMgr()->PushHeap(GMA_LEVEL_ZONE);
+ bool rc = choreo::ReadFromScriptString(mScriptString, mpScriptFile->GetFilename(), p3d::inventory );
+ HeapMgr()->PopHeap(GMA_LEVEL_ZONE);
+ p3d::inventory->PopSection();
+ rAssertMsg( rc, "Choreo Script load error\n" );
+
+ delete[] mScriptString;
+ mScriptString = 0;
+ mpScriptFile->Release();
+ mpScriptFile = 0;
+ m_state = DONE;
+
+ //
+ // Percolate the callback up to the client. This must be done last!!!
+ //
+ mpCallback->OnLoadFileComplete( pUserData );
+
+ break;
+ }
+ default:
+ {
+ rAssert( 0 );
+ break;
+ }
+ }
+
+}
+
+
+//==============================================================================
+// ChoreoFileHandler::LoadFileSync
+//==============================================================================
+//
+// Description: Load a Pure3D file synchronously.
+//
+// Parameters: filename - fully qualified path and filename
+//
+// Return: None.
+//
+//==============================================================================
+void ChoreoFileHandler::LoadFileSync( const char* filename )
+{
+ rReleasePrintf("\n\n!!!!!! TRC VIOLATION, USE ASYNC!!!!!!!\n\n");
+ rAssert( false );
+
+ rAssert( filename );
+
+ p3d::inventory->PushSection();
+ p3d::inventory->SelectSection( GetSectionName() );
+ bool result = p3d::load( filename );
+ p3d::inventory->PopSection();
+
+ rAssert( result = true );
+}
+
+
+
+//==============================================================================
+// ChoreoFileHandler::SetSectionName
+//==============================================================================
+//
+// Description:
+//
+// Parameters:
+//
+// Return:
+//
+//==============================================================================
+void ChoreoFileHandler::SetSectionName( const char* sectionName )
+{
+ rAssert( sectionName );
+
+ strcpy( mcSectionName, sectionName );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+
+
+
+
+
diff --git a/game/code/loading/choreofilehandler.h b/game/code/loading/choreofilehandler.h
new file mode 100644
index 0000000..4370ed0
--- /dev/null
+++ b/game/code/loading/choreofilehandler.h
@@ -0,0 +1,85 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: Choreofilehandler.h
+//
+// Description: Declaration of ChoreoFileHandler class.
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+#ifndef CHOREOFILEHANDLER_H
+#define CHOREOFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandler.h>
+#include <radfile.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: File handler for loading Pure3D files.
+//
+//=============================================================================
+class ChoreoFileHandler : public FileHandler,
+ public IRadFileCompletionCallback
+{
+ public:
+
+ ChoreoFileHandler();
+ virtual ~ChoreoFileHandler();
+
+ //
+ // Implement FileHandler interface.
+ //
+ virtual void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ virtual void LoadFileSync( const char* filename );
+
+ //
+ // Implement IRadFileCompletionCallback interface.
+ //
+ virtual void OnFileOperationsComplete( void* pUserData );
+ virtual void AddRef() {FileHandler::AddRef();}
+ virtual void Release() {FileHandler::Release();}
+
+ //
+ // Specify which Choreo inventory section to load the file into.
+ //
+ void SetSectionName( const char* sectionName );
+ const char* GetSectionName() { return( mcSectionName ); }
+
+ private:
+ enum ChoreoFileState
+ {
+ NONE,
+ OPENFILE,
+ READDATA,
+ DONE
+ };
+ // Async Load State.
+ //
+ ChoreoFileState m_state;
+ // Data buffer.
+ //
+ char* mScriptString;
+
+ // Prevent wasteful constructor creation.
+ ChoreoFileHandler( const ChoreoFileHandler& Choreofilehandler );
+ ChoreoFileHandler& operator=( const ChoreoFileHandler& Choreofilehandler );
+
+ char mcSectionName[32];
+ IRadFile* mpScriptFile;
+};
+
+
+#endif //CHOREOFILEHANDLER_H \ No newline at end of file
diff --git a/game/code/loading/consolefilehandler.cpp b/game/code/loading/consolefilehandler.cpp
new file mode 100644
index 0000000..83fe727
--- /dev/null
+++ b/game/code/loading/consolefilehandler.cpp
@@ -0,0 +1,237 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: consolefilehandler.cpp
+//
+// Description: Implement ConsoleFileHandler
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+#include <string.h>
+// Pure 3D
+#include <p3d/utility.hpp>
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/consolefilehandler.h>
+#include <memory/srrmemory.h>
+#include <console/console.h>
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// ConsoleFileHandler::ConsoleFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+ConsoleFileHandler::ConsoleFileHandler()
+ :
+ mpConsoleFile( 0 ),
+ mAsyncLoadState( NONE ),
+ mFileDataBuffer( 0 )
+{
+}
+
+//==============================================================================
+// ConsoleFileHandler::~ConsoleFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+ConsoleFileHandler::~ConsoleFileHandler()
+{
+}
+
+
+//==============================================================================
+// ConsoleFileHandler::LoadFile
+//==============================================================================
+//
+// Description: Load a Pure3D file asynchronously.
+//
+// Parameters: filename - fully qualified path and filename
+// pCallback - client callback to invoke when load is complete
+// pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void ConsoleFileHandler::LoadFile
+(
+ const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap
+)
+{
+ rAssert( filename );
+ rAssert( pCallback );
+
+ mpCallback = pCallback;
+
+ // by default, use FTT IRadFiles
+ //
+ mAsyncLoadState = OPENFILE;
+
+ radFileOpen( &mpConsoleFile,
+ filename,
+ false,
+ OpenExisting,
+ NormalPriority,
+ 0,
+ GMA_TEMP );
+
+ rAssert( mpConsoleFile != 0 );
+
+ mpConsoleFile->AddCompletionCallback( this,
+ reinterpret_cast<void*>(pUserData) );
+}
+
+
+//==============================================================================
+// ConsoleFileHandler::OnFileOperationsComplete
+//==============================================================================
+//
+// Description: Pure3D (via FTech) invokes this callback when the async load
+// is complete.
+//
+// Parameters: pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void ConsoleFileHandler::OnFileOperationsComplete( void* pUserData )
+{
+ switch( mAsyncLoadState )
+ {
+ case OPENFILE:
+ {
+
+MEMTRACK_PUSH_GROUP( "ConsoleFileHandler" );
+ unsigned int length = mpConsoleFile->GetSize();
+ mFileDataBuffer = new(GMA_TEMP) char[length + 1];
+
+ mpConsoleFile->ReadAsync( mFileDataBuffer, length );
+ mpConsoleFile->AddCompletionCallback( this, (void*)pUserData );
+
+ mAsyncLoadState = READDATA;
+MEMTRACK_POP_GROUP("ConsoleFileHandler");
+ }
+ break;
+
+ case READDATA:
+ {
+ unsigned int length = mpConsoleFile->GetSize();
+ mFileDataBuffer[length] = '\0';
+
+ GetConsole()->Evaluate( mFileDataBuffer, mpConsoleFile->GetFilename() );
+
+
+ delete[]( GMA_TEMP, mFileDataBuffer );
+ mFileDataBuffer = 0;
+
+ mpConsoleFile->Release();
+ mpConsoleFile = 0;
+
+ mAsyncLoadState = DONE;
+
+ //
+ // Percolate the callback up to the client. This must be done last!!!
+ //
+ mpCallback->OnLoadFileComplete( pUserData );
+ }
+ break;
+
+ default:
+ {
+ rAssert( 0 );
+ }
+ }
+}
+
+
+//==============================================================================
+// ConsoleFileHandler::LoadFileSync
+//==============================================================================
+//
+// Description: Load a Pure3D file synchronously.
+//
+// Parameters: filename - fully qualified path and filename
+//
+// Return: None.
+//
+//==============================================================================
+void ConsoleFileHandler::LoadFileSync( const char* filename )
+{
+MEMTRACK_PUSH_GROUP( "ConsoleFileHandler" );
+ rAssert( filename );
+
+ radFileOpen( &mpConsoleFile,
+ filename,
+ false,
+ OpenExisting,
+ NormalPriority,
+ 0,
+ GMA_TEMP );
+
+ rAssert( mpConsoleFile != 0 );
+
+ mpConsoleFile->WaitForCompletion();
+
+ unsigned int length = mpConsoleFile->GetSize();
+ mFileDataBuffer = new(GMA_TEMP) char[length + 1];
+
+ mpConsoleFile->ReadAsync( mFileDataBuffer, length );
+ mpConsoleFile->WaitForCompletion();
+
+ mFileDataBuffer[length] = '\0';
+
+ GetConsole()->Evaluate( mFileDataBuffer, filename );
+
+ delete[]( GMA_TEMP, mFileDataBuffer );
+ mFileDataBuffer = 0;
+
+ mpConsoleFile->Release();
+ mpConsoleFile = 0;
+MEMTRACK_POP_GROUP("ConsoleFileHandler");
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+
+
+
+
+
diff --git a/game/code/loading/consolefilehandler.h b/game/code/loading/consolefilehandler.h
new file mode 100644
index 0000000..9d4c7d2
--- /dev/null
+++ b/game/code/loading/consolefilehandler.h
@@ -0,0 +1,78 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: consolefilehandler.h
+//
+// Description: Declaration of ConsoleFileHandler class.
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+#ifndef CONSOLEFILEHANDLER_H
+#define CONSOLEFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandler.h>
+#include <radfile.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: File handler for loading Pure3D files.
+//
+//=============================================================================
+class ConsoleFileHandler : public FileHandler,
+ public IRadFileCompletionCallback
+{
+ public:
+
+ ConsoleFileHandler();
+ virtual ~ConsoleFileHandler();
+
+ //
+ // Implement FileHandler interface.
+ //
+ virtual void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ virtual void LoadFileSync( const char* filename );
+
+ //
+ // Implement IRadFileCompletionCallback interface.
+ //
+ virtual void OnFileOperationsComplete( void* pUserData );
+
+ virtual void AddRef() {FileHandler::AddRef();}
+ virtual void Release() {FileHandler::Release();}
+
+ private:
+
+ // Prevent wasteful constructor creation.
+ ConsoleFileHandler( const ConsoleFileHandler& ConsoleFileHandler );
+ ConsoleFileHandler& operator=( const ConsoleFileHandler& ConsoleFileHandler );
+
+ IRadFile* mpConsoleFile;
+
+ enum AsyncLoadState
+ {
+ NONE,
+ OPENFILE,
+ READDATA,
+ DONE
+ };
+
+ AsyncLoadState mAsyncLoadState;
+
+ char* mFileDataBuffer;
+};
+
+
+#endif // CONSOLEFILEHANDLER_H \ No newline at end of file
diff --git a/game/code/loading/filehandler.h b/game/code/loading/filehandler.h
new file mode 100644
index 0000000..80050b2
--- /dev/null
+++ b/game/code/loading/filehandler.h
@@ -0,0 +1,105 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: filehandler.h
+//
+// Description: Declaration of FileHandler abstract base class.
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+#ifndef FILEHANDLER_H
+#define FILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <radobject.hpp>
+#include <radload/utility/object.hpp>
+#include "memory/srrmemory.h"
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Derive from this abstract base class to implement custom handlers
+// for loading specific file types.
+//
+//=============================================================================
+class FileHandler
+//:
+//public IRefCount
+{
+ public:
+
+ FileHandler(): m_RefCount( 0 ) {}
+ virtual ~FileHandler() {}
+
+ //----------------------------------------------------------------------
+ // ASYNCHRONOUS LOADING
+ //----------------------------------------------------------------------
+
+ //
+ // Clients must implement this callback to be notified when the
+ // async load completes.
+ //
+ struct LoadFileCallback
+ {
+ virtual void OnLoadFileComplete( void* pUserData ) = 0;
+ };
+
+ //
+ // Load file asynchronously.
+ //
+ virtual void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap ) = 0;
+
+ //----------------------------------------------------------------------
+ // SYNCHRONOUS LOADING
+ //----------------------------------------------------------------------
+
+ //
+ // Load file synchronously.
+ //
+ virtual void LoadFileSync( const char* filename ) = 0;
+
+ virtual void AddRef( void )
+ {
+ m_RefCount++;
+ }
+ virtual void Release( void )
+ {
+ // Copy and paste from radobject.hpp
+ //
+ rAssert( m_RefCount > 0 && m_RefCount < MAX_REFCOUNT );
+ m_RefCount--;
+ if (m_RefCount == 0 )
+ {
+ // Must avoid recursive destruction, set refcount to some high
+ // value.
+
+ m_RefCount = MAX_REFCOUNT / 2;
+
+ delete this;
+ }
+ }
+ protected:
+
+ LoadFileCallback* mpCallback;
+ void* mpUserData;
+
+ private:
+
+ // Declared but not defined to prevent copying and assignment.
+ FileHandler( const FileHandler& );
+ FileHandler& operator=( const FileHandler& );
+
+ int m_RefCount;
+};
+
+#endif // FILEHANDLER_H
diff --git a/game/code/loading/filehandlerenum.h b/game/code/loading/filehandlerenum.h
new file mode 100644
index 0000000..40eb3f2
--- /dev/null
+++ b/game/code/loading/filehandlerenum.h
@@ -0,0 +1,46 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: filehandlerenum.h
+//
+// Description: File handler types.
+//
+// History: + Created -- Darwin Chau
+//
+//=============================================================================
+
+#ifndef FILEHANDLERENUM_H
+#define FILEHANDLERENUM_H
+
+//========================================
+// System Includes
+//========================================
+
+//========================================
+// Project Includes
+//========================================
+
+//========================================
+// Forward References
+//========================================
+
+//========================================
+// Constants, Typedefs and Statics
+//========================================
+enum FileHandlerEnum
+{
+ FILEHANDLER_PURE3D,
+ FILEHANDLER_LEVEL,
+ FILEHANDLER_MISSION,
+ FILEHANDLER_ANIMATION,
+ FILEHANDLER_CHOREO,
+ FILEHANDLER_CONSOLE,
+ FILEHANDLER_SCROOBY,
+ FILEHANDLER_SOUND,
+ FILEHANDLER_TEMP,
+ FILEHANDLER_ICON,
+
+ NUM_FILEHANDLERS
+};
+
+#endif // FILEHANDLERENUM_H
diff --git a/game/code/loading/filehandlerfactory.cpp b/game/code/loading/filehandlerfactory.cpp
new file mode 100644
index 0000000..9edc285
--- /dev/null
+++ b/game/code/loading/filehandlerfactory.cpp
@@ -0,0 +1,173 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: filehandlerfactory.cpp
+//
+// Description: Implement FileHandlerFactory
+//
+// History: 3/27/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/filehandlerfactory.h>
+#include <loading/p3dfilehandler.h>
+#include <loading/choreofilehandler.h>
+#include <loading/consolefilehandler.h>
+#include <loading/iconfilehandler.h>
+#include <loading/scroobyfilehandler.h>
+#include <loading/soundfilehandler.h>
+#include <memory/srrmemory.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+
+//==============================================================================
+// FileHandlerFactory::CreateFileHandler
+//==============================================================================
+//
+// Description: Instantiates and returns a file handler of the specified type.
+//
+// Parameters: handlerType - the type of file handler to create
+// allocator - the memory heap to use
+//
+// secitonName - hack to allow p3d inventory sections to be created
+// based on filenames
+//
+// Return: pointer to the file handler
+//
+// Constraints: The client is responsible for deleting the returned file handler.
+//
+//==============================================================================
+FileHandler* FileHandlerFactory::CreateFileHandler
+(
+ FileHandlerEnum handlerType,
+ const char* sectionName
+)
+{
+MEMTRACK_PUSH_GROUP( "FileHandler Factory" );
+
+ FileHandler* pHandler = NULL;
+
+ HeapMgr()->PushHeap(GMA_TEMP);
+
+ switch( handlerType )
+ {
+ case FILEHANDLER_PURE3D:
+ {
+ pHandler = new P3DFileHandler();
+
+ if( sectionName != 0 )
+ {
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( sectionName );
+ }
+ else
+ {
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( "Default" );
+ }
+
+ break;
+ }
+
+ case FILEHANDLER_LEVEL:
+ {
+ pHandler = new P3DFileHandler();
+ if( sectionName != 0 )
+ {
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( sectionName );
+ }
+ else
+ {
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( "Level" );
+ }
+ break;
+ }
+ case FILEHANDLER_MISSION:
+ {
+ pHandler = new P3DFileHandler();
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( "Mission" );
+
+ break;
+ }
+ case FILEHANDLER_ANIMATION:
+ {
+ pHandler = new P3DFileHandler();
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( sectionName );
+
+ break;
+ }
+ case FILEHANDLER_CHOREO:
+ {
+ pHandler = new ChoreoFileHandler();
+ static_cast<ChoreoFileHandler*>(pHandler)->SetSectionName( sectionName );
+
+ break;
+ }
+ case FILEHANDLER_CONSOLE:
+ {
+ pHandler = new ConsoleFileHandler();
+
+ break;
+ }
+ case FILEHANDLER_SCROOBY:
+ {
+ pHandler = new ScroobyFileHandler();
+ static_cast<ScroobyFileHandler*>(pHandler)->SetSectionName( sectionName );
+
+ break;
+ }
+ case FILEHANDLER_SOUND:
+ {
+ pHandler = new SoundFileHandler();
+
+ break;
+ }
+ case FILEHANDLER_TEMP:
+ {
+ pHandler = new P3DFileHandler();
+ static_cast<P3DFileHandler*>(pHandler)->SetSectionName( "Temp" );
+
+ break;
+ }
+ case FILEHANDLER_ICON:
+ {
+ pHandler = new IconFileHandler();
+
+ break;
+ }
+ default:
+ {
+ rAssert( 0 );
+ }
+ }
+
+ HeapMgr()->PopHeap(GMA_TEMP);
+
+MEMTRACK_POP_GROUP("FileHandler Factory");
+ return( pHandler );
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/loading/filehandlerfactory.h b/game/code/loading/filehandlerfactory.h
new file mode 100644
index 0000000..e2b1bff
--- /dev/null
+++ b/game/code/loading/filehandlerfactory.h
@@ -0,0 +1,41 @@
+//==============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: filehandlerfactory.h
+//
+// Description: This factory shields its clients from the details of derived
+// FileHandler classes.
+//
+// History: 3/27/2002 + Created -- Darwin Chau
+//
+//==============================================================================
+
+#ifndef FILEHANDLERFACTORY_H
+#define FILEHANDLERFACTORY_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandlerenum.h>
+
+//========================================
+// Forward References
+//========================================
+class FileHandler;
+
+//==============================================================================
+//
+// Synopsis: Constructs and returns a FileHandler of the desired derived type.
+// Clients are responsible for deleting the FileHandler.
+//
+//==============================================================================
+
+class FileHandlerFactory
+{
+ public:
+
+ static FileHandler* CreateFileHandler( FileHandlerEnum handlerType, const char* sectionName = 0 );
+};
+
+
+#endif // FILEHANDLERFACTORY_H
diff --git a/game/code/loading/iconfilehandler.cpp b/game/code/loading/iconfilehandler.cpp
new file mode 100644
index 0000000..81bb8ae
--- /dev/null
+++ b/game/code/loading/iconfilehandler.cpp
@@ -0,0 +1,200 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: IconFileHandler.cpp
+//
+// Description: Implement IconFileHandler
+//
+// History: 01/21/2002 + Created -- Tony Chu
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+#include <string.h>
+// Pure 3D
+#include <p3d/utility.hpp>
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/iconfilehandler.h>
+#include <memory/srrmemory.h>
+
+#include <data/memcard/memorycardmanager.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// IconFileHandler::IconFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+IconFileHandler::IconFileHandler()
+ :
+ mpIconFile( 0 ),
+ mFileDataBuffer( 0 ),
+ mHeap( GMA_DEFAULT ),
+ mAsyncLoadState( NONE )
+{
+}
+
+//==============================================================================
+// IconFileHandler::~IconFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+IconFileHandler::~IconFileHandler()
+{
+}
+
+
+//==============================================================================
+// IconFileHandler::LoadFile
+//==============================================================================
+//
+// Description: Load a Pure3D file asynchronously.
+//
+// Parameters: filename - fully qualified path and filename
+// pCallback - client callback to invoke when load is complete
+// pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void IconFileHandler::LoadFile
+(
+ const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap
+)
+{
+ rAssert( filename );
+ rAssert( pCallback );
+
+ mpCallback = pCallback;
+ mHeap = heap;
+
+ // by default, use FTT IRadFiles
+ //
+ mAsyncLoadState = OPENFILE;
+
+ radFileOpen( &mpIconFile,
+ filename,
+ false,
+ OpenExisting,
+ NormalPriority,
+ 0,
+ heap );
+
+ rAssert( mpIconFile != 0 );
+
+ mpIconFile->AddCompletionCallback( this, pUserData );
+}
+
+
+//==============================================================================
+// IconFileHandler::OnFileOperationsComplete
+//==============================================================================
+//
+// Description: Pure3D (via FTech) invokes this callback when the async load
+// is complete.
+//
+// Parameters: pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void IconFileHandler::OnFileOperationsComplete( void* pUserData )
+{
+ switch( mAsyncLoadState )
+ {
+ case OPENFILE:
+ {
+MEMTRACK_PUSH_GROUP( "IconFileHandler" );
+ unsigned int length = mpIconFile->GetSize();
+ mFileDataBuffer = new( mHeap ) char[ length ];
+
+ mpIconFile->ReadAsync( mFileDataBuffer, length );
+ mpIconFile->AddCompletionCallback( this, pUserData );
+
+ mAsyncLoadState = READDATA;
+MEMTRACK_POP_GROUP("IconFileHandler");
+ }
+ break;
+
+ case READDATA:
+ {
+ unsigned int length = mpIconFile->GetSize();
+
+ GetMemoryCardManager()->SetMemcardIconData( mFileDataBuffer, length );
+
+ // it's up to the client to free the file data buffer!
+ //
+ mFileDataBuffer = 0;
+
+ mpIconFile->Release();
+ mpIconFile = 0;
+
+ mAsyncLoadState = DONE;
+
+ //
+ // Percolate the callback up to the client. This must be done last!!!
+ //
+ mpCallback->OnLoadFileComplete( pUserData );
+ }
+ break;
+
+ default:
+ {
+ rAssert( 0 );
+ }
+ }
+}
+
+
+//==============================================================================
+// IconFileHandler::LoadFileSync
+//==============================================================================
+//
+// Description: Load a Pure3D file synchronously.
+//
+// Parameters: filename - fully qualified path and filename
+//
+// Return: None.
+//
+//==============================================================================
+void IconFileHandler::LoadFileSync( const char* filename )
+{
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
diff --git a/game/code/loading/iconfilehandler.h b/game/code/loading/iconfilehandler.h
new file mode 100644
index 0000000..ea43dd7
--- /dev/null
+++ b/game/code/loading/iconfilehandler.h
@@ -0,0 +1,79 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: IconFileHandler.h
+//
+// Description: Declaration of IconFileHandler class.
+//
+// History: 01/21/2003 + Created -- Tony Chu
+//
+//=============================================================================
+
+#ifndef ICONFILEHANDLER_H
+#define ICONFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandler.h>
+#include <radfile.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: File handler for loading Pure3D files.
+//
+//=============================================================================
+class IconFileHandler : public FileHandler,
+ public IRadFileCompletionCallback
+{
+ public:
+
+ IconFileHandler();
+ virtual ~IconFileHandler();
+
+ //
+ // Implement FileHandler interface.
+ //
+ virtual void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ virtual void LoadFileSync( const char* filename );
+
+ //
+ // Implement IRadFileCompletionCallback interface.
+ //
+ virtual void OnFileOperationsComplete( void* pUserData );
+
+ virtual void AddRef() {FileHandler::AddRef();}
+ virtual void Release() {FileHandler::Release();}
+
+ private:
+
+ // Prevent wasteful constructor creation.
+ IconFileHandler( const IconFileHandler& iconFileHandler );
+ IconFileHandler& operator=( const IconFileHandler& iconFileHandler );
+
+ IRadFile* mpIconFile;
+ char* mFileDataBuffer;
+ GameMemoryAllocator mHeap;
+
+ enum AsyncLoadState
+ {
+ NONE,
+ OPENFILE,
+ READDATA,
+ DONE
+ };
+
+ AsyncLoadState mAsyncLoadState;
+
+};
+
+
+#endif // ICONFILEHANDLER_H
diff --git a/game/code/loading/intersectionloader.cpp b/game/code/loading/intersectionloader.cpp
new file mode 100644
index 0000000..22a7880
--- /dev/null
+++ b/game/code/loading/intersectionloader.cpp
@@ -0,0 +1,157 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: intersectionloader.cpp
+//
+// Description: Implement IntersectionLoader
+//
+// History: 14/03/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/chunkfile.hpp>
+#include <p3d/inventory.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/IntersectionLoader.h>
+#include <roads/intersection.h>
+
+#include <constants/srrchunks.h>
+
+//STUB!!
+#include <roads/roadmanager.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// IntersectionLoader::IntersectionLoader
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+IntersectionLoader::IntersectionLoader()
+{
+}
+
+//==============================================================================
+// IntersectionLoader::~IntersectionLoader
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+IntersectionLoader::~IntersectionLoader()
+{
+}
+
+//==============================================================================
+// IntersectionLoader::Load
+//==============================================================================
+// Description: This is a P3D chunk loader for Intersections. This will create
+// a simple intersection and put it in the inventory.
+//
+// Parameters: (tChunkFile* f, tEntityStore* store)
+//
+// Return: tLoadStatus
+//
+//==============================================================================
+tLoadStatus IntersectionLoader::Load(tChunkFile* f, tEntityStore* store)
+{
+ char name[256];
+ f->GetString( name );
+
+ rmt::Vector loc;
+ loc.x = f->GetFloat();
+ loc.y = f->GetFloat();
+ loc.z = f->GetFloat();
+
+ float radius = f->GetFloat();
+
+ unsigned int type = f->GetUInt();
+
+ RoadManager* rm = RoadManager::GetInstance();
+
+ Intersection* intersection = NULL;
+
+ //First see if we've already got this one!
+ intersection = rm->FindIntersection( name );
+
+ if ( NULL == intersection )
+ {
+ //Not here yet.
+ intersection = rm->GetFreeIntersectionMemory();
+ rAssert( intersection );
+
+ intersection->SetName( name );
+ intersection->SetType( (Intersection::Type)type );
+ intersection->SetRadius( radius );
+ intersection->SetLocation( loc );
+
+ rm->AddIntersection( intersection );
+ }
+
+#ifdef TOOLS
+ store->Store( intersection );
+ //HACK
+ intersection->AddRef();
+#endif
+
+ return LOAD_OK;
+}
+
+
+//==============================================================================
+// IntersectionLoader::CheckChunkID
+//==============================================================================
+// Description: Comment
+//
+// Parameters: (unsigned id)
+//
+// Return: bool
+//
+//==============================================================================
+bool IntersectionLoader::CheckChunkID(unsigned id)
+{
+ return SRR2::ChunkID::INTERSECTION == id;
+}
+
+unsigned int IntersectionLoader::GetChunkID()
+{
+ return SRR2::ChunkID::INTERSECTION;
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+
+
+
diff --git a/game/code/loading/intersectionloader.h b/game/code/loading/intersectionloader.h
new file mode 100644
index 0000000..7e48546
--- /dev/null
+++ b/game/code/loading/intersectionloader.h
@@ -0,0 +1,29 @@
+#ifndef INTERSECTION_LOADER_H
+#define INTERSECTION_LOADER_H
+
+// Pure 3D
+#include <p3d/loadmanager.hpp>
+#include <p3d/p3dtypes.hpp>
+
+class IntersectionLoader : public tChunkHandler
+{
+public:
+ IntersectionLoader();
+ virtual ~IntersectionLoader();
+
+ // P3D chunk loader.
+ virtual tLoadStatus Load(tChunkFile* f, tEntityStore* store);
+
+ // P3D chunk id.
+ virtual bool CheckChunkID(unsigned id);
+ virtual unsigned int GetChunkID();
+
+private:
+
+ // No copying or assignment. Declare but don't define.
+ //
+ IntersectionLoader( const IntersectionLoader& );
+ IntersectionLoader& operator= ( const IntersectionLoader& );
+};
+
+#endif \ No newline at end of file
diff --git a/game/code/loading/loadingmanager.cpp b/game/code/loading/loadingmanager.cpp
new file mode 100644
index 0000000..88b2923
--- /dev/null
+++ b/game/code/loading/loadingmanager.cpp
@@ -0,0 +1,648 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: loadingmanager.cpp
+//
+// Description: Implementation for the LoadingManager class.
+//
+// History: + Created -- Darwin Chau
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Ftech
+#include <raddebug.hpp>
+#include <radtime.hpp>
+#include <radfile.hpp>
+#include <string.h>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/loadingmanager.h>
+#include <loading/filehandlerfactory.h>
+#include <loading/cementfilehandler.h>
+#include <memory/srrmemory.h>
+#include <debug/profiler.h>
+#include <radtextdisplay.hpp>
+#include <main/game.h>
+
+#include <cheats/cheatinputsystem.h>
+
+#include <mission/gameplaymanager.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+// Static pointer to instance of singleton.
+LoadingManager* LoadingManager::spInstance = NULL;
+
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// LoadingManager::GetInstance
+//==============================================================================
+//
+// Description: Access point for the LoadingManager singleton.
+//
+// Parameters: None.
+//
+// Return: Pointer to the LoadingManager.
+//
+// Constraints: This is a singleton so only one instance is allowed.
+//
+//==============================================================================
+LoadingManager* LoadingManager::GetInstance()
+{
+ rAssert( spInstance != NULL );
+
+ return spInstance;
+}
+
+
+//==============================================================================
+// LoadingManager::CreateInstance
+//==============================================================================
+//
+// Description: Constructs the LoadingManager singleton.
+//
+// Parameters: None.
+//
+// Return: Pointer to the LoadingManager.
+//
+// Constraints: This is a singleton so only one instance is allowed.
+//
+//==============================================================================
+LoadingManager* LoadingManager::CreateInstance()
+{
+MEMTRACK_PUSH_GROUP( "LoadingManager" );
+ rAssert( spInstance == NULL );
+
+ #ifdef RAD_GAMECUBE
+ HeapMgr()->PushHeap( GMA_GC_VMM );
+ #else
+ HeapMgr()->PushHeap( GMA_PERSISTENT );
+ #endif
+ spInstance = new LoadingManager;
+ rAssert( spInstance );
+
+ #ifdef RAD_GAMECUBE
+ HeapMgr()->PopHeap( GMA_GC_VMM );
+ #else
+ HeapMgr()->PopHeap( GMA_PERSISTENT );
+ #endif
+MEMTRACK_POP_GROUP("LoadingManager");
+
+ return spInstance;
+}
+
+
+//==============================================================================
+// LoadingManager::DestroyInstance
+//==============================================================================
+//
+// Description: Destroy the LoadingManager.
+//
+// Parameters: None.
+//
+// Return: None.
+//
+//==============================================================================
+void LoadingManager::DestroyInstance()
+{
+ rAssert( spInstance != NULL );
+
+ delete spInstance;
+ spInstance = NULL;
+}
+
+
+
+void LoadingManager::AddCallback( LoadingManager::ProcessRequestsCallback* pCallback, void* pUserData)
+{
+ if ( mCancellingLoads )
+ {
+ return;
+ }
+
+ if(mRequestHead == mRequestTail && !mLoading )
+ {
+ pCallback->OnProcessRequestsComplete(pUserData);
+ return;
+ }
+
+ int newTail = (mRequestTail + 1) % MAX_REQUESTS;
+
+ rAssert( newTail != mRequestHead );
+
+ //rAssert(!mRequests[lastAddedRequest].pCallback);
+ mRequests[mRequestTail].pCallback = pCallback;
+ mRequests[mRequestTail].pUserData = pUserData;
+ mRequests[mRequestTail].filename[0] = '\0';
+
+ mRequestTail = newTail;
+}
+
+//==============================================================================
+// LoadingManager::AddRequest
+//==============================================================================
+//
+// Description: Clients use this method to submit a loading request.
+// This request is not serviced immediately. The request remains
+// queued until LoadingManager::ProcessRequests() is invoked.
+//
+// Parameters: handlerType - an enumeration is used to specify which
+// file handler to use for loading and processing the data
+// (the use of an enumeration keeps the clients of LoadingManager
+// from being dependant on any FileHandler classes.
+//
+// filename - fully qualified path and name of file.
+//
+// secitonName - hack to allow p3d inventory sections to be created
+// based on filenames
+//
+// groupName - this allows a memtag section to be declared.
+//
+// Return: true - on success
+// false - request queue is full or loading is in progress
+//
+//==============================================================================
+void LoadingManager::AddRequest
+(
+ FileHandlerEnum handlerType,
+ const char* filename,
+ GameMemoryAllocator heap,
+ const char* sectionName,
+ const char* groupTag,
+ LoadingManager::ProcessRequestsCallback* pCallback,
+ void* pUserData
+)
+{
+ if ( mCancellingLoads )
+ {
+ return;
+ }
+
+ unsigned newTail = (mRequestTail + 1) % MAX_REQUESTS;
+
+#ifndef FINAL
+ rReleaseAssertMsg( static_cast< int >( newTail ) != mRequestHead, "Too many load requests already!\n");
+
+ // Dusit [Dec 2, 2002]:
+ // Bad if we're overwriting the other load request. This is a fatal error.
+ if( static_cast<int>(newTail) == mRequestHead )
+ {
+ IRadTextDisplay* textDisplay;
+ ::radTextDisplayGet( &textDisplay, GMA_DEFAULT );
+ if ( textDisplay )
+ {
+ textDisplay->SetBackgroundColor( 0 );
+ textDisplay->SetTextColor( 0xffffffff );
+ textDisplay->Clear();
+ textDisplay->TextOutAt( "TOO MANY LOAD REQUESTS!", 20, 10 );
+ textDisplay->TextOutAt( ">:-8", 20, 14 );
+ if ( CommandLineOptions::Get( CLO_DEMO_TEST ) ||
+ GetCheatInputSystem()->IsCheatEnabled( CHEAT_ID_DEMO_TEST ) )
+ {
+ char buffy[32];
+ sprintf( buffy, "Demo Count: %d", GetGame()->GetDemoCount() );
+ textDisplay->TextOutAt( buffy, 20, 16 );
+
+ unsigned int time = GetGame()->GetTime();
+ unsigned int hours = time / 3600000;
+ unsigned int deltaTime = time % 3600000;
+
+ unsigned int minutes = deltaTime / 60000;
+ deltaTime = deltaTime % 60000;
+
+ unsigned int seconds = deltaTime / 1000;
+ deltaTime = deltaTime % 1000;
+ sprintf( buffy, "Time: %d:%d:%d.%d", hours, minutes, seconds, deltaTime );
+ textDisplay->TextOutAt( buffy, 20, 18 );
+
+ if ( GetGameplayManager() )
+ {
+ sprintf( buffy, "Level %d", GetGameplayManager()->GetCurrentLevelIndex() );
+ textDisplay->TextOutAt( buffy, 20, 20 );
+ }
+ }
+ textDisplay->SwapBuffers();
+ textDisplay->Release();
+ }
+ rReleaseBreak();
+ }
+#endif
+
+ //mRequests[mNumRequests].filename = filename;
+ rAssert( strlen( filename ) < LoadingRequest::LOADING_FILENAME_LENGTH );
+ strcpy( mRequests[mRequestTail].filename, filename );
+
+ mRequests[mRequestTail].pFileHandler = FileHandlerFactory::CreateFileHandler( handlerType, sectionName );
+ mRequests[mRequestTail].pFileHandler->AddRef();
+
+#ifdef MEMORYTRACKER_ENABLED
+ if( groupTag == NULL )
+ {
+ //
+ // Use the filename by default
+ //
+ rAssert( strlen( filename ) < LoadingRequest::LOADING_FILENAME_LENGTH );
+ strcpy( mRequests[mRequestTail].groupTag, filename );
+ }
+ else
+ {
+ rAssert( strlen( groupTag ) < LoadingRequest::LOADING_FILENAME_LENGTH );
+ strcpy( mRequests[mRequestTail].groupTag, groupTag );
+ }
+#endif
+
+ mRequests[mRequestTail].heap = heap;
+ mRequests[mRequestTail].pCallback = pCallback;
+ mRequests[mRequestTail].pUserData = pUserData;
+ mRequestTail = newTail;
+
+ this->ProcessNextRequest();
+}
+
+//==============================================================================
+// LoadingManager::OnLoadFileComplete
+//==============================================================================
+//
+// Description: FileHandler's will invoke this callback when an asynchronous
+// load completes.
+//
+// Parameters: pUserData - optional user data that was passed in when the
+// load was requested
+//
+// Return: None.
+//
+//==============================================================================
+void LoadingManager::OnLoadFileComplete( void* pUserData )
+{
+ rAssert( (int)pUserData == mRequestHead );
+
+ // Display some debug info.
+ LoadingRequest& request = mRequests[mRequestHead ];
+
+ extern bool gLoadingSpew;
+
+ if ( !(CommandLineOptions::Get( CLO_NO_LOADING_SPEW )) )
+ {
+ rReleasePrintf( "<< END >> Async Loading: %s (%u msecs)\n",
+ request.filename,
+ radTimeGetMilliseconds() - request.startTime );
+ }
+
+ // Continue onto the next request.
+ mRequestHead = (mRequestHead + 1) % MAX_REQUESTS;
+ mLoading = false;
+
+ if(request.pCallback)
+ {
+ request.pCallback->OnProcessRequestsComplete(request.pUserData);
+ }
+
+ request.pFileHandler->Release();
+
+ this->ProcessNextRequest();
+}
+
+
+//==============================================================================
+// LoadingManager::LoadSync
+//==============================================================================
+//
+// Description: Load a file synchronously.
+//
+// Parameters: handlerType - an enumeration is used to specify which
+// file handler to use for loading and processing the data
+// (the use of an enumeration keeps the clients of LoadingManager
+// from being dependant on any FileHandler classes.
+//
+// filename - fully qualified path and name of file.
+//
+// Return: None.
+//
+//==============================================================================
+void LoadingManager::LoadSync
+(
+ FileHandlerEnum handlerType,
+ const char* filename,
+ GameMemoryAllocator heap,
+ const char* sectionName
+)
+{
+ rReleasePrintf("\n\n!!!!!! TRC VIOLATION, USE ASYNC!!!!!!!\n\n");
+// rAssert( false );
+
+ unsigned int startTime = radTimeGetMilliseconds();
+
+ if ( !(CommandLineOptions::Get( CLO_NO_LOADING_SPEW )) )
+ {
+ rDebugPrintf( "<<START>> Sync Loading: %s\n", filename );
+ }
+
+
+ HeapMgr()->PushHeap( GMA_TEMP );
+ FileHandler* pHandler = FileHandlerFactory::CreateFileHandler( handlerType, sectionName );
+
+ HeapMgr()->PopHeap( GMA_TEMP );
+ pHandler->AddRef( );
+ rAssert( pHandler );
+
+ HeapMgr()->PushHeap( heap );
+ pHandler->LoadFileSync( filename );
+ HeapMgr()->PopHeap( heap );
+
+ pHandler->Release( );
+ pHandler = 0;
+
+ if ( !(CommandLineOptions::Get( CLO_NO_LOADING_SPEW )) )
+ {
+ rReleasePrintf( "<< END >> Sync Loading: %s (%u msecs)\n",
+ filename,
+ radTimeGetMilliseconds() - startTime );
+ }
+}
+
+//=============================================================================
+// LoadingManager::CancelPendingRequests
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: void
+//
+//=============================================================================
+void LoadingManager::CancelPendingRequests()
+{
+ if ( mRequestHead != mRequestTail )
+ {
+ mRequestTail = (mRequestHead + 1) % MAX_REQUESTS; //Catch up and lose the rest of the loads.
+ }
+
+ mCancellingLoads = true;
+
+ while ( mLoading )
+ {
+ ::radFileService();
+ p3d::loadManager->SwitchTask();
+ p3d::loadManager->TriggerCallbacks();
+ }
+
+ //Close all the open cement files.
+ CementFileHandle i;
+ for ( i = 0; i < MAX_CEMENT_LIBRARIES; ++i )
+ {
+ if ( mCementLibraries[ i ].library != NULL )
+ {
+ UnregisterCementLibrary( i );
+ }
+ }
+}
+
+//=============================================================================
+// LoadingManager::RegisterCementLibrary
+//=============================================================================
+// Description: Registers the named cement library with RadFile.
+//
+// Parameters: filename - name of cement file
+//
+// Return: CementFileHandle - internally, its the index of the cement
+// library pointer. Used for indicating which
+// cement library to release later on
+//
+//=============================================================================
+CementFileHandle LoadingManager::RegisterCementLibrary( const char* filename )
+{
+ if ( mCancellingLoads )
+ {
+ return 0;
+ }
+
+ int i;
+
+ for( i = 0; i < MAX_CEMENT_LIBRARIES; i++ )
+ {
+ if( ( mCementLibraries[i].library == NULL )
+ && ( mCementLibraries[i].isLoading == false ) )
+ {
+ break;
+ }
+ }
+
+ rAssertMsg( ( i < MAX_CEMENT_LIBRARIES ), "Too many cement libraries\n" );
+
+ //
+ // Put a file handler into the queue so that we'll wait until this
+ // thing is fully registered. This file handler is slightly different
+ // than the rest, and we're in a special-purpose function anyway, so don't
+ // go through the factory.
+ //
+ int newTail = (mRequestTail + 1) % MAX_REQUESTS;
+
+ if( newTail != mRequestHead)
+ {
+ rAssert( strlen( filename ) < LoadingRequest::LOADING_FILENAME_LENGTH );
+ strcpy( mRequests[mRequestTail].filename, filename );
+#ifdef MEMORYTRACKER_ENABLED
+ strcpy( mRequests[mRequestTail].groupTag, filename );
+#endif
+#ifdef RAD_GAMECUBE
+ mRequests[mRequestTail].heap = GMA_GC_VMM;
+#else
+ mRequests[mRequestTail].heap = GMA_PERSISTENT; // Cement library registrations should be around for the duration --jdy
+#endif
+
+MEMTRACK_PUSH_GROUP( "LoadingManager" );
+ HeapMgr()->PushHeap (GMA_TEMP);
+
+ mRequests[mRequestTail].pFileHandler = new(GMA_TEMP) CementFileHandler( &(mCementLibraries[i]) );
+ mRequests[mRequestTail].pFileHandler->AddRef();
+
+ mCementLibraries[i].isLoading = true;
+
+ HeapMgr()->PopHeap (GMA_TEMP);
+MEMTRACK_POP_GROUP("LoadingManager");
+
+ mRequests[mRequestTail].pCallback = NULL;
+
+ mRequestTail = newTail;
+
+ this->ProcessNextRequest();
+
+ return( i );
+ }
+ else
+ {
+ rWarningMsg( 0, "Failed to add cement library request" );
+ return( -1 );
+ }
+}
+
+//=============================================================================
+// LoadingManager::UnregisterCementLibrary
+//=============================================================================
+// Description: Unregister a cement library (hence the name)
+//
+// Parameters: handle - in practice, the array index for the cement library
+//
+// Return: void
+//
+//=============================================================================
+void LoadingManager::UnregisterCementLibrary( CementFileHandle handle )
+{
+ rAssert( handle >= 0 );
+ //rAssert( mCementLibraries[handle].library != NULL );
+
+ //
+ // Just to be safe, make sure that the cement library is inactive before
+ // we release it. Synchronous wait okay here?
+ //
+ if( mCementLibraries[handle].library != NULL )
+ {
+ mCementLibraries[handle].library->WaitForCompletion();
+
+ mCementLibraries[handle].library->Release();
+ mCementLibraries[handle].library = NULL;
+ }
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+
+//==============================================================================
+// LoadingManager::LoadingManager
+//==============================================================================
+//
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+LoadingManager::LoadingManager()
+:
+ mRequestHead( 0 ),
+ mRequestTail( 0 ),
+ mLoading(false),
+ mCancellingLoads( false )
+{
+ int i;
+
+ for( i = 0; i < MAX_CEMENT_LIBRARIES; i++ )
+ {
+ mCementLibraries[i].library = NULL;
+ mCementLibraries[i].isLoading = false;
+ }
+
+#ifdef RAD_WIN32
+ mRequestsProcessed = 0;
+#endif
+}
+
+
+//==============================================================================
+// LoadingManager::~LoadingManager
+//==============================================================================
+//
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+LoadingManager::~LoadingManager()
+{
+ int i;
+
+ for( i = 0; i < MAX_CEMENT_LIBRARIES; i++ )
+ {
+ if( mCementLibraries[i].library != NULL )
+ {
+ mCementLibraries[i].library->Release();
+ }
+ }
+}
+
+
+//==============================================================================
+// LoadingManager::ProcessNextRequest
+//==============================================================================
+//
+// Description: Handle the next load request in the queue.
+//
+// Parameters: None.
+//
+// Return: None.
+//
+//==============================================================================
+void LoadingManager::ProcessNextRequest()
+{
+ // Are we done?
+ if(!mLoading)
+ {
+ if(mRequestHead != mRequestTail)
+ {
+ // Start loading the next file.
+ LoadingRequest& request = mRequests[mRequestHead];
+
+ if ( request.filename[0] != '\0' )
+ {
+ if ( !(CommandLineOptions::Get( CLO_NO_LOADING_SPEW )) )
+ {
+ rReleasePrintf( "<<START>> Async Loading: %s\n", request.filename );
+ }
+#ifdef RAD_WIN32
+ mRequestsProcessed++;
+#endif
+
+ request.startTime = radTimeGetMilliseconds();
+ mLoading = true;
+ GameMemoryAllocator heap = request.heap;
+
+#ifndef RAD_RELEASE
+ if (HeapManager::s_bSpecialRoute)
+ {
+ heap = GMA_SPECIAL;
+ }
+#endif
+
+ request.pFileHandler->LoadFile( request.filename,
+ this,
+ (void*)mRequestHead,
+ heap );
+ }
+ else
+ {
+ rAssert( request.pCallback != NULL );
+
+ mRequestHead = (mRequestHead + 1) % MAX_REQUESTS;
+ mLoading = false;
+
+ request.pCallback->OnProcessRequestsComplete(request.pUserData);
+ ProcessNextRequest();
+ }
+ }
+ }
+}
+
+
diff --git a/game/code/loading/loadingmanager.h b/game/code/loading/loadingmanager.h
new file mode 100644
index 0000000..4b0cc7b
--- /dev/null
+++ b/game/code/loading/loadingmanager.h
@@ -0,0 +1,213 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: loadingmanager.h
+//
+// Description: Declaration of LoadingManager singleton class.
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+#ifndef LOADINGMANAGER_H
+#define LOADINGMANAGER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandlerenum.h>
+#include <loading/filehandler.h>
+
+#ifndef TOOLS
+#include <memory/srrmemory.h>
+#endif
+
+//========================================
+// Forward References
+//========================================
+class FileHandler;
+struct ILoadingListCallback;
+struct IRadCementLibrary;
+
+
+//
+// Types
+//
+typedef int CementFileHandle;
+
+
+//=============================================================================
+//
+// Synopsis: All non-streamed disc loads must be routed through this class.
+//
+//=============================================================================
+class LoadingManager : public FileHandler::LoadFileCallback
+{
+ public:
+
+ // Static Methods for accessing this singleton.
+ static LoadingManager* GetInstance();
+ static LoadingManager* CreateInstance();
+ static void DestroyInstance();
+
+ //
+ // Cement file registration functions. Should probably be called from
+ // context switch functions and the like
+ //
+ CementFileHandle RegisterCementLibrary( const char* filename );
+ void UnregisterCementLibrary( CementFileHandle handle );
+
+ //----------------------------------------------------------------------
+ // ASYNCHRONOUS LOADING
+ //----------------------------------------------------------------------
+
+ struct ProcessRequestsCallback
+ {
+ virtual void OnProcessRequestsComplete( void* pUserData ) = 0;
+ };
+
+ void AddCallback( LoadingManager::ProcessRequestsCallback* pCallback = NULL,
+ void* pUserData = 0 );
+
+ void AddRequest( FileHandlerEnum handlerType,
+ const char* filename,
+ GameMemoryAllocator heap,
+ const char* sectionName = 0,
+ const char* groupTag = NULL ,
+ LoadingManager::ProcessRequestsCallback* pCallback = NULL,
+ void* pUserData = 0 );
+
+ inline void AddRequest( FileHandlerEnum handlerType,
+ const char* filename,
+ GameMemoryAllocator heap,
+ LoadingManager::ProcessRequestsCallback* pCallback,
+ void* pUserData = 0 )
+ {
+ AddRequest( handlerType, filename, heap, 0, NULL, pCallback, pUserData);
+ }
+
+ //----------------------------------------------------------------------
+ // SYNCHRONOUS LOADING
+ //----------------------------------------------------------------------
+
+ void LoadSync( FileHandlerEnum handlerType, const char* filename, GameMemoryAllocator heap = GMA_DEFAULT,
+ const char* sectionName = NULL );
+
+
+ //----------------------------------------------------------------------
+ // Loading Accessor
+ //----------------------------------------------------------------------
+ bool IsLoading();
+
+ inline int GetRequestHead() const { return mRequestHead; }
+ inline int GetRequestTail() const { return mRequestTail; }
+
+ int GetNumCurrentRequests() const;
+
+ void CancelPendingRequests(); //This will not cancel the current request.
+
+#ifdef RAD_WIN32
+ int GetNumRequestsProcessed() const { return mRequestsProcessed; }
+ inline void ResetRequestsProcessed();
+#endif
+
+ //
+ // Used to hold a pointer to a cement library object. isLoading bool
+ // needed since registration is asynchronous.
+ //
+ struct CementLibraryStruct
+ {
+ IRadCementLibrary* library;
+ bool isLoading;
+ };
+
+ private:
+
+ // No public access to these, use singleton interface.
+ LoadingManager();
+ ~LoadingManager();
+
+ // Declared but not defined to prevent copying and assignment.
+ LoadingManager( const LoadingManager& loadingmanager );
+ LoadingManager& operator=( const LoadingManager& loadingmanager );
+
+ // Implement FileHandler::LoadFileCallback interface.
+ virtual void OnLoadFileComplete( void* pUserData );
+
+ void ProcessNextRequest();
+
+ // Pointer to the one and only instance of this singleton.
+ static LoadingManager* spInstance;
+
+ // Store loading requests here.
+ enum { MAX_REQUESTS = 200 };
+
+ struct LoadingRequest
+ {
+ enum { LOADING_FILENAME_LENGTH = 128 };
+ // Darwin: is 64 too big/big enough?
+ char filename[LOADING_FILENAME_LENGTH];
+ FileHandler* pFileHandler;
+ unsigned int startTime;
+ GameMemoryAllocator heap;
+ ProcessRequestsCallback* pCallback;
+ void* pUserData;
+#ifdef MEMORYTRACKER_ENABLED
+ // Since filenames go in here by default, use filename length for the size
+ char groupTag[LOADING_FILENAME_LENGTH];
+#endif
+ };
+ LoadingRequest mRequests[MAX_REQUESTS];
+ int mRequestHead;
+ int mRequestTail;
+
+ bool mLoading;
+
+ bool mCancellingLoads;
+
+#ifdef RAD_WIN32
+ int mRequestsProcessed;
+#endif
+
+ //
+ // Store cement libraries
+ //
+#ifdef RAD_XBOX
+ static const int MAX_CEMENT_LIBRARIES = 15;
+#else
+ static const int MAX_CEMENT_LIBRARIES = 10;
+#endif
+ CementLibraryStruct mCementLibraries[MAX_CEMENT_LIBRARIES];
+};
+
+// A little syntactic sugar for getting at this singleton.
+inline LoadingManager* GetLoadingManager() { return( LoadingManager::GetInstance() ); }
+
+//=============================================================================
+// LoadingManager::IsLoading
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ()
+//
+// Return: bool
+//
+//=============================================================================
+inline bool LoadingManager::IsLoading()
+{
+ return ( mLoading || mRequestTail != mRequestHead );
+}
+
+inline int LoadingManager::GetNumCurrentRequests() const
+{
+ return( (mRequestTail - mRequestHead + MAX_REQUESTS) % MAX_REQUESTS );
+}
+
+#ifdef RAD_WIN32
+ inline void LoadingManager::ResetRequestsProcessed()
+ {
+ mRequestsProcessed = 0;
+ }
+#endif // RAD_WIN32
+
+#endif //LOADINGMANAGER_H
diff --git a/game/code/loading/locatorloader.cpp b/game/code/loading/locatorloader.cpp
new file mode 100644
index 0000000..38432e4
--- /dev/null
+++ b/game/code/loading/locatorloader.cpp
@@ -0,0 +1,1118 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: LocatorLoader.cpp
+//
+// Description: Implement LocatorLoader
+//
+// History: 24/05/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <radmath/radmath.hpp>
+#include <p3d/chunkfile.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/LocatorLoader.h>
+
+#include <constants/srrchunks.h>
+
+#include <memory/srrmemory.h>
+
+#include <meta/carstartlocator.h>
+#include <meta/eventlocator.h>
+#include <meta/locator.h>
+#include <meta/locatortypes.h>
+#include <meta/recttriggervolume.h>
+#include <meta/spheretriggervolume.h>
+#include <meta/splinelocator.h>
+#include <meta/triggervolumetracker.h>
+#include <meta/zoneeventlocator.h>
+#include <meta/carstartlocator.h>
+#include <meta/occlusionlocator.h>
+#include <meta/interiorentrancelocator.h>
+#include <meta/directionallocator.h>
+#include <meta/actioneventlocator.h>
+#include <meta/fovlocator.h>
+#include <meta/staticcamlocator.h>
+#include <meta/pedgrouplocator.h>
+#include <meta/scriptlocator.h>
+
+#include <camera/railcam.h>
+#include <camera/staticcam.h>
+#include <camera/supercamcentral.h>
+#include <camera/supercammanager.h>
+
+#include <render/RenderManager/RenderManager.h>
+#include <render/Culling/WorldScene.h>
+
+#include <mission/AnimatedIcon.h>
+#include <mission/gameplaymanager.h>
+
+#include <worldsim/parkedcars/parkedcarmanager.h>
+#include <worldsim/coins/coinmanager.h>
+
+#include <render/rendermanager/rendermanager.h>
+#include <render/rendermanager/worldrenderlayer.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+void Swap(char* data_in, char* data_out, int n);
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+int LocatorLoader::msZoneNameCount = 0;
+
+//==============================================================================
+// LocatorLoader::LocatorLoader
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+LocatorLoader::LocatorLoader()
+: tSimpleChunkHandler( SRR2::ChunkID::LOCATOR )
+{
+ mpListenerCB = NULL;
+}
+
+//==============================================================================
+// LocatorLoader::~LocatorLoader
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+LocatorLoader::~LocatorLoader()
+{
+}
+
+//=============================================================================
+// LocatorLoader::LoadObject
+//=============================================================================
+// Description: Comment
+//
+// Parameters: (tChunkFile* f, tEntityStore* store)
+//
+// Return: tEntity
+//
+//=============================================================================
+tEntity* LocatorLoader::LoadObject(tChunkFile* f, tEntityStore* store)
+{
+MEMTRACK_PUSH_GROUP( "Locator Loading" );
+
+ #ifdef RAD_GAMECUBE
+ HeapMgr()->PushHeap (GMA_GC_VMM);
+ #else
+ HeapMgr()->PushHeap (GMA_LEVEL_OTHER);
+ #endif
+
+ char name[256];
+ f->GetPString( name );
+
+ LocatorType::Type type;
+ type = (LocatorType::Type)(f->GetUInt());
+
+ unsigned int numElements = f->GetUInt();
+ unsigned int* elements = new unsigned int[ numElements ];
+
+ unsigned int i;
+ for( i = 0; i < numElements; i++ )
+ {
+ elements[ i ] = f->GetUInt();
+ }
+
+ rmt::Vector pos;
+
+ pos.x = f->GetFloat();
+ pos.y = f->GetFloat();
+ pos.z = f->GetFloat();
+
+ Locator* locator = NULL;
+
+ unsigned int numTriggers = f->GetUInt();
+ bool hasSubChunks = true;
+
+ switch( type )
+ {
+ case LocatorType::GENERIC:
+ {
+ MEMTRACK_PUSH_GROUP("Generic Locator");
+ locator = new Locator();
+ rAssert( locator );
+
+ hasSubChunks = false;
+ MEMTRACK_POP_GROUP("Generic Locator");
+ break;
+ }
+ case LocatorType::EVENT:
+ {
+ MEMTRACK_PUSH_GROUP("Event Locator");
+ EventLocator* eventloc = new EventLocator();
+ rAssert( eventloc );
+
+ eventloc->SetEventType( (LocatorEvent::Event)elements[ 0 ] );
+
+ if ( eventloc->GetEventType() == LocatorEvent::CAMERA_CUT )
+ {
+ //Make this locator inactive if the wreckless cam is not active.
+ //Hackish
+ SuperCam* sc = GetSuperCamManager()->GetSCC( 0 )->GetActiveSuperCam();
+ if ( GetGameplayManager()->mIsDemo || (sc && sc->GetType() == SuperCam::WRECKLESS_CAM) )
+ {
+ eventloc->SetFlag( Locator::ACTIVE, true );
+ }
+ else
+ {
+ eventloc->SetFlag( Locator::ACTIVE, false );
+ }
+ }
+
+ if ( numElements == 2 )
+ {
+ rAssert( eventloc->GetEventType() == LocatorEvent::FAR_PLANE ||
+ eventloc->GetEventType() == LocatorEvent::GOO_DAMAGE ||
+ eventloc->GetEventType() == LocatorEvent::LIGHT_CHANGE ||
+ eventloc->GetEventType() == LocatorEvent::TRAP ||
+ eventloc->GetEventType() == LocatorEvent::CHECK_POINT );
+
+ eventloc->SetData( elements[1] );
+ }
+
+ locator = eventloc;
+ MEMTRACK_POP_GROUP("Event Locator");
+ break;
+ }
+ case LocatorType::SPLINE:
+ {
+ MEMTRACK_PUSH_GROUP("Spline Locator");
+ SplineLocator* splineloc = new SplineLocator();
+ rAssert( splineloc );
+
+ locator = splineloc;
+ MEMTRACK_POP_GROUP("Spline Locator");
+ break;
+ }
+ case LocatorType::DYNAMIC_ZONE:
+ {
+ MEMTRACK_PUSH_GROUP("Zone Locator");
+ ZoneEventLocator* eventloc = new ZoneEventLocator();
+ rAssert( eventloc );
+
+ //this is where we convert the data into a string... ba-dum-ching!
+ eventloc->SetZoneSize( numElements * 4 ); //This is to prevent fragmentation.
+
+ char* zone = new char[numElements * 4 + 4];
+ memcpy( zone, elements, numElements * 4 );
+ zone[numElements * 4] = '\0';
+
+#ifdef RAD_GAMECUBE
+ Swap( zone, zone, numElements * 4 + 4);
+#endif
+
+ eventloc->SetZone( zone );
+
+ delete[] zone;
+
+ locator = eventloc;
+ MEMTRACK_POP_GROUP("Zone Locator");
+ break;
+ }
+ case LocatorType::CAR_START:
+ {
+ MEMTRACK_PUSH_GROUP("Car Locator");
+ CarStartLocator* carStartloc = new CarStartLocator();
+ rAssert( carStartloc );
+
+ float rotation = 0;
+
+ memcpy( (void*)(&rotation), (const void*)&elements[0], sizeof(float) );
+
+ //HACK
+ if ( numElements >= 2 )
+ {
+ //There is parked car data.
+ if ( elements[1] == 1 )
+ {
+ if ( !GetGameplayManager()->mIsDemo )
+ {
+ //Should place a parked car here. Add to ParkedCarManager
+ GetPCM().AddLocator( carStartloc );
+ }
+ }
+
+ if ( numElements > 2 )
+ {
+ //We have a special car here.
+ char* carName = new char[(numElements - 2) * 4 + 4];
+ memcpy( carName, &elements[2], (numElements - 2) * 4 );
+ carName[(numElements - 2) * 4] = '\0';
+#ifdef RAD_GAMECUBE
+ Swap( carName, carName, (numElements - 2) * 4 + 4 );
+#endif
+
+ //Do something with the name
+ GetPCM().AddFreeCar( carName, carStartloc );
+
+ delete carName;
+ }
+ }
+
+ carStartloc->SetRotation( rotation );
+
+ locator = carStartloc;
+ hasSubChunks = false;
+ MEMTRACK_POP_GROUP("Car Locator");
+ break;
+ }
+ case LocatorType::OCCLUSION:
+ {
+ MEMTRACK_PUSH_GROUP("Occlusion Locator");
+ OcclusionLocator* occLoc = new OcclusionLocator();
+ rAssert( occLoc );
+
+ occLoc->SetNumTriggers( numTriggers, GMA_LEVEL_OTHER );
+
+ bool first = true;
+
+ while( f->ChunksRemaining() )
+ {
+ f->BeginChunk();
+
+ switch( f->GetCurrentID() )
+ {
+ case SRR2::ChunkID::TRIGGER_VOLUME:
+ {
+ //Only add the first one to the trigger tracker.
+ LoadTriggerVolume( f, occLoc, first );
+ first = false;
+ break;
+ }
+ }
+
+ f->EndChunk();
+ }
+
+ //How many of the locators are occlusion, the rest are visiblers - 1
+ if ( numElements )
+ {
+ occLoc->SetNumOccTriggers( elements[0] );
+ }
+ else
+ {
+ occLoc->SetNumOccTriggers( numTriggers - 1 );
+ }
+
+ locator = occLoc;
+ hasSubChunks = false; //Special case, already loaded.
+ MEMTRACK_POP_GROUP("Occlusion Locator");
+ break;
+ }
+ case LocatorType::INTERIOR_ENTRANCE:
+ {
+ MEMTRACK_PUSH_GROUP("Interior Locator");
+ InteriorEntranceLocator* intEntLoc = new InteriorEntranceLocator();
+ rAssert( intEntLoc );
+
+ rAssert( numElements * 4 < 256 );
+ unsigned int length = numElements * 4;
+
+ char charData[256];
+ memcpy( charData, elements, numElements * 4 );
+
+ #ifdef RAD_GAMECUBE
+ Swap( charData, charData, numElements * 4 );
+ #endif
+ unsigned int chari = 0;
+ for ( chari = 0; chari < length; ++chari )
+ {
+ if ( charData[chari] == '\0' )
+ {
+ //Found the null.
+ break;
+ }
+ }
+
+ //this is where we convert the data into a string... ba-dum-ching!
+ intEntLoc->SetInteriorFileNameSize( chari ); //This is to prevent fragmentation.
+ intEntLoc->SetInteriorFileName( charData );
+
+ //Now get the transform.
+ unsigned int index = chari / 4;
+
+ if ( chari % 4 != 0 )
+ {
+ index++; //Add one to cover the extra.
+ }
+
+ rmt::Matrix mat;
+ mat.Identity();
+
+ unsigned int i;
+ for ( i = 0; i < 3; ++i )
+ {
+ rmt::Vector v;
+ memcpy( &v.x, &elements[index + 3 * i], sizeof(float) * 3 );
+ mat.m[i][0] = v.x;
+ mat.m[i][1] = v.y;
+ mat.m[i][2] = v.z;
+ }
+
+ intEntLoc->SetTransform( mat );
+ locator = intEntLoc;
+ MEMTRACK_POP_GROUP("Interior Locator");
+ break;
+ }
+ case LocatorType::DIRECTIONAL:
+ {
+ MEMTRACK_PUSH_GROUP("Directional Locator");
+ DirectionalLocator* dirLoc = new DirectionalLocator();
+ rAssert( dirLoc );
+
+ rmt::Matrix mat;
+ mat.Identity();
+
+ unsigned int i;
+ for ( i = 0; i < 3; ++i )
+ {
+ rmt::Vector v;
+ memcpy( &v.x, &elements[3 * i], sizeof(float) * 3 );
+ mat.m[i][0] = v.x;
+ mat.m[i][1] = v.y;
+ mat.m[i][2] = v.z;
+ }
+
+ dirLoc->SetTransform( mat );
+
+ locator = dirLoc;
+ hasSubChunks = false;
+ MEMTRACK_POP_GROUP("Directional Locator");
+ break;
+ }
+ case LocatorType::ACTION:
+ {
+ MEMTRACK_PUSH_GROUP("Action Locator");
+ ActionEventLocator* actLoc = new ActionEventLocator();
+ rAssert( actLoc );
+
+ rAssert(numElements >= 5);
+ rAssert( (numElements - 2) * 4 < 256 );
+ unsigned int length = (numElements - 2) * 4;
+
+ char charData[256];
+ memcpy( charData, elements, (numElements - 2) * 4 );
+
+#ifdef RAD_GAMECUBE
+ Swap( charData, charData, (numElements - 2) * 4 );
+#endif
+
+ //Go through the charData until we find all 3 strings.
+ const unsigned int numStrings = 3;
+ char stringArray[numStrings][128]; //If the name is larger than 128, I'll shoot myself.
+
+ unsigned int i;
+ unsigned int startChari = 0;
+ unsigned int chari = 0;
+ for ( i = 0; i < numStrings; ++i )
+ {
+ while ( charData[chari] != '\0' && chari != length )
+ {
+ ++chari;
+ }
+
+ rAssertMsg( chari != length, "Missing text in action locator!" );
+
+ if ( chari != length )
+ {
+ rAssert( strlen(&charData[startChari]) < 128 );
+ strncpy( stringArray[i], &charData[startChari], chari - startChari );
+ stringArray[i][strlen(&charData[startChari])] = '\0';
+ ++chari;
+ if ( i == numStrings - 1 )
+ {
+ //We're done
+ break;
+ }
+ }
+
+ //move past the NULLS
+ while ( charData[chari] == '\0' && chari != length )
+ {
+ ++chari;
+ }
+
+ startChari = chari;
+ }
+
+ actLoc->SetObjNameSize( strlen(stringArray[0]) );
+ actLoc->SetObjName( stringArray[0] );
+
+ actLoc->SetJointNameSize( strlen(stringArray[1]) );
+ actLoc->SetJointName( stringArray[1] );
+
+ actLoc->SetActionNameSize( strlen(stringArray[2]) );
+ actLoc->SetActionName( stringArray[2] );
+
+ actLoc->SetButtonInput( (CharacterController::eIntention)elements[numElements - 2] );
+ actLoc->SetShouldTransform( elements[numElements - 1] == 1 ? true : false );
+
+ // TBJ [8/30/2002]
+ //
+ // I need to set the position of the locator before I add it to the game.
+ //
+ actLoc->SetLocation( pos );
+
+ // If AddToGame() fails, actLoc will be released.
+ // Hold on to it here.
+ //
+ actLoc->AddRef();
+ if ( actLoc->AddToGame( store ) )
+ {
+ locator = actLoc;
+ }
+ else
+ {
+ locator = NULL;
+ }
+ // If AddToGame() didn't addref the locator,
+ // this release will delete it.
+ //
+ actLoc->Release( );
+ MEMTRACK_POP_GROUP("Action Locator");
+ break;
+ }
+ case LocatorType::FOV:
+ {
+ MEMTRACK_PUSH_GROUP("FOV Locator");
+ FOVLocator* fovLoc = new FOVLocator();
+ rAssert( fovLoc );
+
+ float data[3];
+ memcpy( data, elements, sizeof(float) * 3 );
+
+ fovLoc->SetFOV( rmt::DegToRadian( data[0] ) );
+ fovLoc->SetTime( data[1] );
+ fovLoc->SetRate( data[2] );
+
+ locator = fovLoc;
+ hasSubChunks = true;
+ MEMTRACK_POP_GROUP("FOV Locator");
+ break;
+ }
+
+ case LocatorType::BREAKABLE_CAMERA:
+ {
+ MEMTRACK_PUSH_GROUP("Breakable Camera Locator");
+/*
+ //TODO: what do we do with these??
+ float data[10];
+ memcpy( data, elements, sizeof(float) * 10 );
+
+ rmt::Matrix mat;
+ mat.Identity();
+
+ unsigned int i;
+ for ( i = 0; i < 9;)
+ {
+ mat.m[i][0] = data[i];
+ mat.m[i][1] = data[i + 1];
+ mat.m[i][2] = data[i + 2];
+
+ i += 3;
+ }
+
+ float FOV = data[9];
+
+ // Create a new action event locator
+ ActionEventLocator* actLoc = new ActionEventLocator();
+ /*
+ actLoc->SetObjNameSize( strlen(stringArray[0]) );
+ actLoc->SetObjName( stringArray[0] );
+
+ actLoc->SetJointNameSize( strlen(stringArray[1]) );
+ actLoc->SetJointName( stringArray[1] );
+
+ actLoc->SetActionNameSize( strlen(stringArray[2]) );
+ actLoc->SetActionName( stringArray[2] );
+
+ actLoc->SetButtonInput( (CharacterController::eIntention)elements[numElements - 2] );
+ actLoc->SetShouldTransform( elements[numElements - 1] == 1 ? true : false );
+ */
+/*
+ actLoc->SetLocation( pos );
+
+ const char* ObjName = "Alien Camera Obj";
+ actLoc->SetObjNameSize( strlen( ObjName ) );
+ actLoc->SetObjName( ObjName );
+
+ const char* ActionName = "AlienCamera";
+
+ actLoc->SetActionNameSize( strlen( ActionName ) );
+ actLoc->SetActionName( ActionName );
+
+ actLoc->SetButtonInput( CharacterController::Attack );
+
+ bool addSuccess = actLoc->AddToGame( store );
+
+ // rAssertMsg( addSuccess, "Could not add camera locator to the game" );
+
+*/
+ MEMTRACK_POP_GROUP("Breakable Camera Locator");
+ break;
+ }
+ case LocatorType::STATIC_CAMERA:
+ {
+ MEMTRACK_PUSH_GROUP("Static Camera Locator");
+ StaticCamLocator* scLoc = new StaticCamLocator();
+
+ StaticCam* sCam = new StaticCam();
+
+ rAssert( numElements < 32 );
+ float data[32];
+ memcpy( data, elements, sizeof(float) * numElements );
+
+ rmt::Vector offset;
+ offset.x = data[0];
+ offset.y = data[1];
+ offset.z = data[2];
+
+ sCam->SetTargetOffset( offset );
+
+ float FOV = data[3];
+ sCam->SetMaxFOV( rmt::DegToRadian( FOV ) );
+
+ float lag = data[4];
+ sCam->SetTargetLag( lag );
+
+ int track;
+ memcpy( &track, &data[5], sizeof( int ) ); //This is sucky, sorry.
+ bool tracking = track == 1 ? true : false;
+
+ float trate = 0.04f;
+ if ( numElements >= 7 )
+ {
+ memcpy( &trate, &data[6], sizeof(float) );
+ }
+
+ if ( numElements >= 8 )
+ {
+ int flags = 0;
+ memcpy( &flags, &data[7], sizeof( int ) ); //This is sucky, sorry.
+
+ scLoc->SetOneShot( (flags & 1) > 0 );
+
+ if ( (flags & (1 << 1)) ) //This is the hacky way that I export this info.
+ {
+ //Disable fov on controller for this cam.
+ sCam->SetFOVLag( 0.0f );
+ }
+ }
+
+ if ( numElements >= 9 )
+ {
+ int inOut = 0;
+ memcpy( &inOut, &data[8], sizeof( int ) ); //This is sucky, sorry.
+
+ scLoc->SetCutInOut( inOut == 1 );
+
+ int intData = 0;
+ memcpy( &intData, &data[9], sizeof( int ) ); //This is sucky, sorry.
+
+ scLoc->SetCarOnly( (intData & 1) == 1 );
+ scLoc->SetOnFootOnly( (intData & (1 << 1)) == 1 << 1 );
+ }
+
+ sCam->SetTransitionPositionRate( trate );
+ sCam->SetTransitionTargetRate( trate );
+
+ sCam->SetTracking( tracking );
+
+ sCam->SetPosition( pos );
+
+ scLoc->SetStaticCam( sCam );
+
+ locator = scLoc;
+ hasSubChunks = true;
+ MEMTRACK_POP_GROUP( "Static Camera Locator" );
+ break;
+ }
+ case LocatorType::PED_GROUP:
+ {
+ MEMTRACK_PUSH_GROUP("Ped Group Locator");
+
+ PedGroupLocator* pgLoc = new PedGroupLocator();
+ rAssert( pgLoc );
+
+ unsigned int group = 0;
+
+ memcpy( (void*)(&group), (const void*)elements, sizeof(unsigned int) );
+
+ pgLoc->SetGroupNum( group );
+
+ locator = pgLoc;
+ hasSubChunks = true;
+ MEMTRACK_POP_GROUP( "Ped Group Locator" );
+ break;
+ }
+ case LocatorType::SCRIPT:
+ {
+ MEMTRACK_PUSH_GROUP("Script Locator");
+
+ ScriptLocator* sLoc = new ScriptLocator();
+ rAssert( sLoc );
+
+ char* text = new char[numElements * 4 + 4];
+ memcpy( text, elements, numElements * 4 );
+ text[numElements * 4] = '\0';
+
+#ifdef RAD_GAMECUBE
+ Swap( text, text, numElements * 4 + 4 );
+#endif
+
+ sLoc->SetString( text );
+
+ delete[] text;
+
+ locator = sLoc;
+ hasSubChunks = true;
+ MEMTRACK_POP_GROUP( "Script Locator" );
+ break;
+ }
+ case LocatorType::COIN:
+ {
+ MEMTRACK_PUSH_GROUP("Coin Locator");
+ //Adding world coin to coin manager
+ GetCoinManager()->AddWorldCoin( pos, GetRenderManager()->pWorldRenderLayer()->GetCurSectionName().GetUID() );
+ locator = NULL;
+ MEMTRACK_POP_GROUP( "Coin Locator" );
+ break;
+ }
+ default:
+ {
+ MEMTRACK_PUSH_GROUP("Unknown Locator");
+ rDebugString( "Bad locator loaded.. UNKNOWN type!\n" );
+ Locator* loc = new Locator();
+ rAssert( loc );
+ locator = loc;
+ MEMTRACK_POP_GROUP( "Unknown Locator" );
+ break;
+ }
+ }
+
+ // locator might be NULL if it was not successfully added to game.
+ //
+ // TBJ [8/30/2002]
+ //
+ if( locator != NULL )
+ {
+ if ( hasSubChunks )
+ {
+ locator->SetNumTriggers( numTriggers, HeapMgr()->GetCurrentHeap() );
+
+ while( f->ChunksRemaining() )
+ {
+ f->BeginChunk();
+
+ switch( f->GetCurrentID() )
+ {
+ case SRR2::ChunkID::TRIGGER_VOLUME:
+ {
+ LoadTriggerVolume( f, static_cast<TriggerLocator*>(locator) );
+ break;
+ }
+ case SRR2::ChunkID::SPLINE:
+ {
+ if ( locator->GetDataType() == LocatorType::SPLINE )
+ {
+ RailCam* railCam = LoadSpline( f, static_cast<SplineLocator*>(locator) );
+ rAssert( railCam );
+ static_cast<SplineLocator*>(locator)->SetRailCam( railCam );
+ }
+ else
+ {
+ RailCam* railCam = LoadSpline( f, NULL );
+ rAssert( railCam );
+ }
+ break;
+ }
+ case SRR2::ChunkID::EXTRA_MATRIX:
+ {
+ rmt::Matrix mat;
+ f->GetData(&(mat), 16, tFile::DWORD);
+
+ locator->SetMatrix( mat );
+
+ break;
+ }
+ }
+
+ f->EndChunk();
+ }
+ }
+
+ locator->SetName( name );
+ locator->SetLocation( pos );
+
+ //locator->SetFlag( Locator::ACTIVE, false );
+ }
+ delete[] elements;
+
+MEMTRACK_POP_GROUP("Locator Loading");
+
+ #ifdef RAD_GAMECUBE
+ HeapMgr()->PopHeap (GMA_GC_VMM);
+ #else
+ HeapMgr()->PopHeap (GMA_LEVEL_OTHER);
+ #endif
+
+ //
+ // Some locators should not be added to the inventory
+ //
+ if( type == LocatorType::DYNAMIC_ZONE )
+ {
+ //
+ // All the locators called load_something are never looked up
+ //
+ if( strncmp( name, "load", 4 ) == 0 )
+ {
+ msZoneNameCount++;
+ char tempName[256];
+ sprintf( tempName, "mfa%d%s", msZoneNameCount, name);
+ locator->SetName(tempName);
+ }
+ }
+
+ return locator;
+}
+
+///////////////////////////////////////////////////////////////////////
+// IWrappedLoader
+///////////////////////////////////////////////////////////////////////
+//========================================================================
+// LocatorLoader::SetRegdListener
+//========================================================================
+//
+// Description: Register a new listener/caretaker, notify old listener of
+// severed connection.
+//
+// Parameters: pListenerCB: Callback to call OnChunkLoaded
+// pUserData: Data to pass along for filtering, etc
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+void LocatorLoader::SetRegdListener
+(
+ ChunkListenerCallback* pListenerCB,
+ int iUserData
+)
+{
+ //
+ // Follow protocol; notify old Listener, that it has been
+ // "disconnected".
+ //
+ if( mpListenerCB != NULL )
+ {
+ mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 );
+ }
+ mpListenerCB = pListenerCB;
+ mUserData = iUserData;
+}
+
+//========================================================================
+// LocatorLoader::ModRegdListener
+//========================================================================
+//
+// Description: Just fuck with the current pUserData
+//
+// Parameters: None.
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+void LocatorLoader::ModRegdListener
+(
+ ChunkListenerCallback* pListenerCB,
+ int iUserData
+)
+{
+#if 0
+ char DebugBuf[255];
+ sprintf( DebugBuf, "GeometryWrappedLoader::ModRegdListener: pListenerCB %X vs mpListenerCB %X\n", pListenerCB, mpListenerCB );
+ rDebugString( DebugBuf );
+#endif
+ rAssert( pListenerCB == mpListenerCB );
+
+ mUserData = iUserData;
+}
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+//=============================================================================
+// LocatorLoader::LoadTriggerVolume
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( tChunkFile* f,
+// TriggerLocator* locator,
+// bool addToTracker )
+//
+// Return: void
+//
+//=============================================================================
+bool LocatorLoader::LoadTriggerVolume( tChunkFile* f,
+ TriggerLocator* locator,
+ bool addToTracker )
+{
+ bool good = true;
+
+ MEMTRACK_PUSH_GROUP("Trigger Volume Loading");
+
+ #ifdef RAD_GAMECUBE
+ HeapMgr()->PushHeap( GMA_GC_VMM );
+ #else
+ HeapMgr()->PushHeap (GMA_LEVEL_OTHER);
+ #endif
+
+
+ if( f->GetCurrentID() == SRR2::ChunkID::TRIGGER_VOLUME )
+ {
+ char volname[256];
+ rmt::Matrix mat;
+ rmt::Vector scale;
+ rmt::Vector pos;
+
+ TriggerVolume* vol = NULL;
+
+ f->GetPString( volname );
+ unsigned int voltype = f->GetUInt();
+
+ scale.x = f->GetFloat();
+ scale.y = f->GetFloat();
+ scale.z = f->GetFloat();
+
+ float val;
+
+ for( unsigned int v = 0; v < 4; v++ )
+ {
+ for( unsigned int u = 0; u < 4; u++ )
+ {
+ val = f->GetFloat();
+
+ mat.m[v][u] = val;
+ }
+ }
+ pos = mat.Row(3);
+
+ switch( voltype )
+ {
+ case TriggerVolume::SPHERE:
+ {
+ MEMTRACK_PUSH_GROUP("Sphere Trigger");
+ SphereTriggerVolume* sphere = new SphereTriggerVolume();
+
+ // this is a sphere, so the radii should be equal
+ sphere->SetSphereRadius( scale.x );
+ vol = sphere;
+ MEMTRACK_POP_GROUP("Sphere Trigger");
+ break;
+ }
+ case TriggerVolume::RECTANGLE:
+ {
+ MEMTRACK_PUSH_GROUP("Rectangle Trigger");
+ RectTriggerVolume* box = new RectTriggerVolume( pos,
+ mat.Row(0),
+ mat.Row(1),
+ mat.Row(2),
+ scale.x,
+ scale.y,
+ scale.z );
+ vol = box;
+ MEMTRACK_POP_GROUP("Rectangle Trigger");
+ break;
+ }
+ default:
+ {
+ // never come here again!
+ MEMTRACK_PUSH_GROUP("Unknown Trigger");
+ rAssert( false );
+ MEMTRACK_POP_GROUP("Unknown Trigger");
+ break;
+ }
+ }
+
+ vol->SetName( volname );
+
+ vol->SetLocator( locator );
+ locator->AddTriggerVolume( vol );
+
+ vol->SetPosition( pos );
+
+ if ( addToTracker )
+ {
+ GetTriggerVolumeTracker()->AddTrigger( vol );
+ // dont notify the render manager (listener), instead, circumvent and add directly to the tree
+ //mpListenerCB->OnChunkLoaded(vol, mUserData, _id);
+ //GetRenderManager()->pWorldScene()->Add(vol); //Now we are adding to the DSG.
+ }
+
+ good = true;
+ }
+ else
+ {
+ good = false;
+ }
+
+ MEMTRACK_POP_GROUP("Trigger Volume Loading");
+
+ #ifdef RAD_GAMECUBE
+ HeapMgr()->PopHeap( GMA_GC_VMM );
+ #else
+ HeapMgr()->PopHeap (GMA_LEVEL_OTHER);
+ #endif
+ return good;
+}
+
+//=============================================================================
+// LocatorLoader::LoadSpline
+//=============================================================================
+// Description: Comment
+//
+// Parameters: ( tChunkFile* f, SplineLocator* splineLoc )
+//
+// Return: RailCam*
+//
+//=============================================================================
+
+RailCam* LocatorLoader::LoadSpline( tChunkFile* f, SplineLocator* splineLoc )
+{
+ if( f->GetCurrentID() == SRR2::ChunkID::SPLINE )
+ {
+MEMTRACK_PUSH_GROUP("Rail Cam");
+
+ char name[256];
+ f->GetPString( name );
+
+ int numCVs = f->GetInt();
+
+ rmt::SplineCurve newSpline;
+ newSpline.SetNumVertices( numCVs );
+
+ for( int i = 0; i < numCVs; i++ )
+ {
+ rmt::Vector v;
+
+ v.x = f->GetFloat();
+ v.y = f->GetFloat();
+ v.z = f->GetFloat();
+
+ newSpline.SetCntrlVertex( i, v );
+ }
+
+ rAssert( f->ChunksRemaining() );
+
+ //Load the railcam...
+ RailCam* newRailCam = new RailCam();
+
+ f->BeginChunk();
+
+ f->GetString( name );
+ newRailCam->SetBehaviour( (RailCam::Behaviour)f->GetUInt() );
+ newRailCam->SetMinRadius( f->GetFloat() );
+ newRailCam->SetMaxRadius( f->GetFloat() );
+ newRailCam->SetTrackRail( f->GetUInt() == 1 ? true : false );
+ newRailCam->SetTrackDist( f->GetFloat() );
+ newRailCam->SetReverseSense( f->GetUInt() == 1 ? true : false );
+ newRailCam->SetMaxFOV( rmt::DegToRadian( f->GetFloat() ) );
+
+ rmt::Vector targetOffset;
+ f->GetData( &targetOffset.x, 3, tFile::DWORD );
+ newRailCam->SetTargetOffset( targetOffset );
+
+ rmt::Vector play;
+ f->GetData( &play.x, 3, tFile::DWORD );
+ //newRailCam->SetAxisPlay( play );
+ //Hack to get some data
+ if ( play.x > 0.001f )
+ {
+ newRailCam->SetTransitionPositionRate( play.x );
+ newRailCam->SetTransitionTargetRate( play.x );
+ }
+
+ if ( play.y == 1.0f ) //This is set to one when we want to disable the lag.
+ {
+ //Disable FOV lagging.
+ newRailCam->SetFOVLag( 0.0f );
+ }
+
+ if ( splineLoc )
+ {
+ //Play.z is hiding stuff too
+ int hiddenX = (int)play.z; //I hate this.
+
+ splineLoc->SetCarOnly( (hiddenX & 0x00000001) != 0 );
+ splineLoc->SetCutInOut( (hiddenX & 0x0000002) != 0 );
+ splineLoc->SetReset( (hiddenX & 0x00000004) != 0 );
+ splineLoc->SetOnFootOnly( (hiddenX & 0x00000008) != 0 );
+ }
+
+ newRailCam->SetPositionLag( f->GetFloat() );
+ newRailCam->SetTargetLag( f->GetFloat() );
+
+ newRailCam->SetSplineCurve( newSpline );
+
+ f->EndChunk();
+
+MEMTRACK_POP_GROUP("Rail Cam");
+
+ return newRailCam;
+ }
+
+ return NULL;
+}
+
+//Endian swap.
+inline void Swap( char* data_in, char* data_out, int n )
+{
+ rAssert( n % 4 == 0 );
+
+ char tmp1, tmp2, tmp3, tmp4;
+ for(int i = 0; i < n; i += 4)
+ {
+ tmp1 = data_in[i];
+ tmp2 = data_in[i+1];
+ tmp3 = data_in[i+2];
+ tmp4 = data_in[i+3];
+
+ data_out[i] = tmp4;
+ data_out[i+1] = tmp3;
+ data_out[i+2] = tmp2;
+ data_out[i+3] = tmp1;
+ }
+}
diff --git a/game/code/loading/locatorloader.h b/game/code/loading/locatorloader.h
new file mode 100644
index 0000000..65e703b
--- /dev/null
+++ b/game/code/loading/locatorloader.h
@@ -0,0 +1,85 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: locatorloader.h
+//
+// Description: Blahblahblah
+//
+// History: 24/05/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+#ifndef LOCATORLOADER_H
+#define LOCATORLOADER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <p3d/loadmanager.hpp>
+#include <p3d/p3dtypes.hpp>
+
+#include <constants/srrchunks.h>
+#include <render/Loaders/IWrappedLoader.h>
+//========================================
+// Forward References
+//========================================
+
+class TriggerLocator;
+class tEntity;
+class RailCam;
+class SplineLocator;
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class LocatorLoader
+: public tSimpleChunkHandler,
+ public IWrappedLoader
+{
+public:
+ LocatorLoader();
+ virtual ~LocatorLoader();
+
+ //////////////////////////////////////////////////////////////////////
+ // IWrappedLoader
+ //////////////////////////////////////////////////////////////////////
+ void SetRegdListener( ChunkListenerCallback* pListenerCB,
+ int iUserData );
+
+ void ModRegdListener( ChunkListenerCallback* pListenerCB,
+ int iUserData );
+
+private:
+
+ //////////////////////////////////////////////////////////////////////
+ // IWrappedLoader
+ //////////////////////////////////////////////////////////////////////
+
+ //Prevent wasteful constructor creation.
+ LocatorLoader( const LocatorLoader& locatorloader );
+ LocatorLoader& operator=( const LocatorLoader& locatorloader );
+
+ // P3D chunk loader.
+ virtual tEntity* LoadObject(tChunkFile* f, tEntityStore* store);
+
+ void LoadTriggerLocator( tChunkFile* f,
+ tEntityStore* store,
+ TriggerLocator* locator );
+ bool LoadTriggerVolume( tChunkFile* f,
+ TriggerLocator* locator,
+ bool addToTracker = true );
+ RailCam* LoadSpline( tChunkFile* f, SplineLocator* splineLoc );
+
+ static int msZoneNameCount;
+};
+
+//******************************************************************************
+//
+// Inline Public Member Functions
+//
+//******************************************************************************
+
+#endif //LOCATORLOADER_H
diff --git a/game/code/loading/p3dfilehandler.cpp b/game/code/loading/p3dfilehandler.cpp
new file mode 100644
index 0000000..f9b8fae
--- /dev/null
+++ b/game/code/loading/p3dfilehandler.cpp
@@ -0,0 +1,196 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: p3dfilehandler.cpp
+//
+// Description: Implement P3DFileHandler
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+#include <string.h>
+// Pure 3D
+#include <p3d/utility.hpp>
+// Foundation Tech
+#include <raddebug.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/p3dfilehandler.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// P3DFileHandler::P3DFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+P3DFileHandler::P3DFileHandler() : m_RefCount( 0 )
+{
+}
+
+//==============================================================================
+// P3DFileHandler::~P3DFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+P3DFileHandler::~P3DFileHandler()
+{
+}
+
+
+//==============================================================================
+// P3DFileHandler::LoadFile
+//==============================================================================
+//
+// Description: Load a Pure3D file asynchronously.
+//
+// Parameters: filename - fully qualified path and filename
+// pCallback - client callback to invoke when load is complete
+// pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void P3DFileHandler::LoadFile
+(
+ const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap
+)
+{
+ rAssert( filename );
+ rAssert( pCallback );
+
+ mpCallback = pCallback;
+ mpUserData = pUserData;
+
+ //
+ // Ensure that the specified inventory section exists before loading
+ //
+ HeapMgr()->PushHeap (heap);
+ HeapMgr()->PushHeap (GMA_TEMP);
+ p3d::inventory->AddSection( mcSectionName );
+ HeapMgr()->PopHeap (GMA_TEMP);
+ p3d::loadAsync( filename, mcSectionName, this, pUserData, heap );
+ HeapMgr()->PopHeap (heap);
+}
+
+
+//==============================================================================
+// P3DFileHandler::Done
+//==============================================================================
+//
+// Description: Pure3D (via FTech) invokes this callback when the async load
+// is complete.
+//
+// Parameters: tLoadStatus status, tLoadRequest *load
+//
+// Return: None.
+//
+//==============================================================================
+void P3DFileHandler::Done( tLoadStatus status, tLoadRequest *load )
+{
+ //
+ // Percolate the callback up to the client.
+ //
+ mpCallback->OnLoadFileComplete( mpUserData );
+}
+
+
+//==============================================================================
+// P3DFileHandler::LoadFileSync
+//==============================================================================
+//
+// Description: Load a Pure3D file synchronously.
+//
+// Parameters: filename - fully qualified path and filename
+//
+// Return: None.
+//
+//==============================================================================
+void P3DFileHandler::LoadFileSync( const char* filename )
+{
+ rAssert( filename );
+
+ rReleasePrintf("Synchronous File Load. Bastard! %s\n", filename);
+ rAssert( false );
+
+ p3d::inventory->PushSection();
+
+ //
+ // Ensure that the specified inventory section exists before loading
+ //
+ p3d::inventory->AddSection( mcSectionName );
+ p3d::inventory->SelectSection( mcSectionName );
+
+ // SetInventorySection(mcSectionName );
+
+ tLoadRequest* pLR = new tLoadRequest(p3d::openFile(filename));
+ pLR->SetInventorySection(mcSectionName);
+ tLoadStatus result = p3d::loadManager->Load(pLR);
+
+ // bool result = p3d::load( filename );
+
+ p3d::inventory->PopSection();
+
+ rAssert( result == LOAD_OK );
+}
+
+
+
+//==============================================================================
+// P3DFileHandler::SetSectionName
+//==============================================================================
+//
+// Description:
+//
+// Parameters:
+//
+// Return:
+//
+//==============================================================================
+void P3DFileHandler::SetSectionName( const char* sectionName )
+{
+ rAssert( sectionName );
+
+ strcpy( mcSectionName, sectionName );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+
+
+
+
+
diff --git a/game/code/loading/p3dfilehandler.h b/game/code/loading/p3dfilehandler.h
new file mode 100644
index 0000000..8f5e542
--- /dev/null
+++ b/game/code/loading/p3dfilehandler.h
@@ -0,0 +1,81 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: p3dfilehandler.h
+//
+// Description: Declaration of P3DFileHandler class.
+//
+// History: 3/25/2002 + Created -- Darwin Chau
+//
+//=============================================================================
+
+#ifndef P3DFILEHANDLER_H
+#define P3DFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <p3d/loadmanager.hpp>
+#include <loading/filehandler.h>
+#include <radfile.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: File handler for loading Pure3D files.
+//
+//=============================================================================
+class P3DFileHandler : public tLoadRequest::Callback,
+ public FileHandler
+
+{
+ public:
+
+ P3DFileHandler();
+ virtual ~P3DFileHandler();
+
+ //
+ // Implement FileHandler interface.
+ //
+ virtual void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ virtual void LoadFileSync( const char* filename );
+
+ //
+ // Implement tLoadRequest::Callback interface.
+ //
+ virtual void Done( tLoadStatus status, tLoadRequest *load );
+ virtual void AddRef( void )
+ {
+ radLoadObject::AddRef();
+ }
+ virtual void Release( void )
+ {
+ radLoadObject::Release();
+ }
+
+ //
+ // Specify which P3D inventory section to load the file into.
+ //
+ void SetSectionName( const char* sectionName );
+ const char* GetSectionName() { return( mcSectionName ); }
+
+ private:
+
+ // Prevent wasteful constructor creation.
+ P3DFileHandler( const P3DFileHandler& p3dfilehandler );
+ P3DFileHandler& operator=( const P3DFileHandler& p3dfilehandler );
+
+ char mcSectionName[32];
+ void* mpUserData;
+ int m_RefCount;
+};
+
+
+#endif //P3DFILEHANDLER_H \ No newline at end of file
diff --git a/game/code/loading/pathloader.cpp b/game/code/loading/pathloader.cpp
new file mode 100644
index 0000000..fb51ee7
--- /dev/null
+++ b/game/code/loading/pathloader.cpp
@@ -0,0 +1,214 @@
+//============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: pathloader.cpp
+//
+// Description: Implements PathLoader class
+//
+// History: 09/18/2002 + Created -- Dusit Eakkachaichanvet
+//
+//============================================================================
+
+#include <p3d/chunkfile.hpp>
+#include <loading/pathloader.h>
+#include <pedpaths/pathmanager.h>
+#include <pedpaths/path.h>
+#include <pedpaths/pathsegment.h>
+#include <constants/srrchunks.h>
+
+static unsigned int sNumPathsLoaded = 0;
+static unsigned int sNumPathSegmentsLoaded = 0;
+
+PathLoader::PathLoader() :
+ tSimpleChunkHandler(SRR2::ChunkID::PED_PATH)
+{
+ mpListenerCB = NULL;
+ mUserData = -1;
+}
+
+PathLoader::~PathLoader()
+{
+}
+
+bool PathLoader::CheckChunkID(unsigned id)
+{
+ unsigned int expectedID = SRR2::ChunkID::PED_PATH;
+ return expectedID == id;
+}
+
+tLoadStatus PathLoader::Load(tChunkFile* f, tEntityStore* store)
+{
+ // parse number of points (must be at least 2 points)
+ unsigned long int nPoints = f->GetUInt();
+ rAssert( nPoints >= 2 );
+
+ int nSegments = nPoints-1;
+
+ // Get path from PathManager, who keeps a list of Paths
+ // The manager should be a singleton, so do GetInstance
+ PathManager* pm = PathManager::GetInstance();
+ rAssert( pm != NULL );
+
+ // Get a free path & set up its segments
+ Path* path = pm->GetFreePath();
+ rAssert( path != NULL );
+
+ path->AllocateSegments( nSegments );
+
+
+
+ PathSegment* ps = NULL;
+ rmt::Vector first, start, end;
+
+ start.x = f->GetFloat();
+ start.y = f->GetFloat();
+ start.z = f->GetFloat();
+
+ first = start;
+
+ float myEpsilon = 0.001f;
+
+ long int i;
+ for( i=0; i<nSegments; i++ )
+ {
+ end.x = f->GetFloat();
+ end.y = f->GetFloat();
+ end.z = f->GetFloat();
+
+ // make sure that the points span a tangible distance
+ rAssert( !rmt::Epsilon( start.x, end.x, myEpsilon ) ||
+ !rmt::Epsilon( start.y, end.y, myEpsilon ) ||
+ !rmt::Epsilon( start.z, end.z, myEpsilon ) );
+
+ ps = path->GetPathSegmentByIndex( i );
+ ps->Initialize( path, i, start, end );
+
+ // DSG stuff
+ mpListenerCB->OnChunkLoaded( ps, mUserData, SRR2::ChunkID::PED_PATH_SEGMENT );
+ start = end;
+
+ sNumPathSegmentsLoaded++;
+ }
+ /*
+ int counter = 0;
+ long int i;
+ for( i=0; i<(nSegments-1); i = i+2 )
+ {
+ f->GetFloat(); f->GetFloat(); f->GetFloat();
+ end.x = f->GetFloat();
+ end.y = f->GetFloat();
+ end.z = f->GetFloat();
+
+ // make sure that the points span a tangible distance
+ rAssert( !rmt::Epsilon( start.x, end.x, myEpsilon ) ||
+ !rmt::Epsilon( start.y, end.y, myEpsilon ) ||
+ !rmt::Epsilon( start.z, end.z, myEpsilon ) );
+
+ ps = path->GetPathSegmentByIndex( counter );
+ ps->Initialize( path, counter, start, end );
+
+ // DSG stuff
+ mpListenerCB->OnChunkLoaded( ps, mUserData, SRR2::ChunkID::PED_PATH_SEGMENT );
+ start = end;
+
+ counter++;
+ sNumPathSegmentsLoaded++;
+ }
+ */
+
+ // determine if path is closed or open
+ if( rmt::Epsilon( first.x, end.x, myEpsilon ) &&
+ rmt::Epsilon( first.y, end.y, myEpsilon ) &&
+ rmt::Epsilon( first.z, end.z, myEpsilon ) )
+ {
+ path->SetIsClosed( true );
+ }
+
+ sNumPathsLoaded++;
+
+ /*
+ rDebugPrintf( "Pathsegments Loaded = %d, paths loaded = %d, sizeof segments = %d, sizeof paths = %d\n",
+ sNumPathSegmentsLoaded,
+ sNumPathsLoaded,
+ sizeof(PathSegment) * sNumPathSegmentsLoaded,
+ sizeof(Path) * sNumPathsLoaded );
+ */
+
+ return LOAD_OK;
+}
+
+
+
+
+tEntity* PathLoader::LoadObject(tChunkFile* f, tEntityStore* store)
+{
+ return NULL;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// IWrappedLoader
+///////////////////////////////////////////////////////////////////////
+//========================================================================
+// RoadLoader::SetRegdListener
+//========================================================================
+//
+// Description: Register a new listener/caretaker, notify old listener of
+// severed connection.
+//
+// Parameters: pListenerCB: Callback to call OnChunkLoaded
+// pUserData: Data to pass along for filtering, etc
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+void PathLoader::SetRegdListener
+(
+ ChunkListenerCallback* pListenerCB,
+ int iUserData
+)
+{
+ //
+ // Follow protocol; notify old Listener, that it has been
+ // "disconnected".
+ //
+ if( mpListenerCB != NULL )
+ {
+ mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 );
+ }
+ mpListenerCB = pListenerCB;
+ mUserData = iUserData;
+}
+
+//========================================================================
+// RoadLoader::ModRegdListener
+//========================================================================
+//
+// Description: Just fuck with the current pUserData
+//
+// Parameters: None.
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+void PathLoader::ModRegdListener
+(
+ ChunkListenerCallback* pListenerCB,
+ int iUserData
+)
+{
+#if 0
+ char DebugBuf[255];
+ sprintf( DebugBuf, "PathLoader::ModRegdListener: pListenerCB %X vs mpListenerCB %X\n",
+ pListenerCB, mpListenerCB );
+ rDebugString( DebugBuf );
+#endif
+ rAssert( pListenerCB == mpListenerCB );
+
+ mUserData = iUserData;
+}
+
diff --git a/game/code/loading/pathloader.h b/game/code/loading/pathloader.h
new file mode 100644
index 0000000..fb45bee
--- /dev/null
+++ b/game/code/loading/pathloader.h
@@ -0,0 +1,70 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: pathloader.h
+//
+// Description: Defines PathLoader class
+//
+// History: 09/18/2002 + Created -- Dusit Eakkachaichanvet
+//
+//=============================================================================
+
+#ifndef PATHLOADER_H
+#define PATHLOADER_H
+
+#include <p3d/loadmanager.hpp>
+#include <p3d/p3dtypes.hpp>
+#include <render/Loaders/IWrappedLoader.h>
+
+
+
+class PathLoader :
+ public tSimpleChunkHandler,
+ public IWrappedLoader
+{
+//MEMBERS
+public:
+
+//METHODS
+public:
+ PathLoader();
+ virtual ~PathLoader();
+
+ // P3D chunk loader.
+ virtual tLoadStatus Load(tChunkFile* f, tEntityStore* store);
+
+ // P3D chunk id.
+ virtual bool CheckChunkID(unsigned id);
+
+ ///////////////////////////////////////////////////////////////////////
+ // IWrappedLoader
+ ///////////////////////////////////////////////////////////////////////
+ void SetRegdListener( ChunkListenerCallback* pListenerCB,
+ int iUserData );
+
+ void ModRegdListener( ChunkListenerCallback* pListenerCB,
+ int iUserData );
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ // tSimpleChunkHandler
+ ///////////////////////////////////////////////////////////////////////
+ virtual tEntity* LoadObject(tChunkFile* f, tEntityStore* store);
+ ///////////////////////////////////////////////////////////////////////
+
+
+
+//MEMBERS
+private:
+
+ // prevent wasteful copy constructors
+ PathLoader( const PathLoader& );
+ PathLoader& operator= ( const PathLoader& );
+
+};
+
+// *********************************** INLINES *******************************
+
+
+
+
+#endif //PATHLOADER_H \ No newline at end of file
diff --git a/game/code/loading/roaddatasegmentloader.cpp b/game/code/loading/roaddatasegmentloader.cpp
new file mode 100644
index 0000000..e058850
--- /dev/null
+++ b/game/code/loading/roaddatasegmentloader.cpp
@@ -0,0 +1,140 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: RoadDataSegmentLoader.cpp
+//
+// Description: Implement RoadDataSegmentLoader
+//
+// History: 27/06/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/chunkfile.hpp>
+#include <p3d/inventory.hpp>
+#include <p3d/entity.hpp>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/RoadDataSegmentLoader.h>
+#include <constants/srrchunks.h>
+#include <roads/roadmanager.h>
+#include <roads/roadsegmentdata.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// RoadDataSegmentLoader::RoadDataSegmentLoader
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+RoadDataSegmentLoader::RoadDataSegmentLoader()
+{
+}
+
+//==============================================================================
+// RoadDataSegmentLoader::~RoadDataSegmentLoader
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+RoadDataSegmentLoader::~RoadDataSegmentLoader()
+{
+}
+
+//=============================================================================
+// RoadDataSegmentLoader::Load
+//=============================================================================
+// Description: Comment
+//
+// Parameters: (tChunkFile* f, tEntityStore* store)
+//
+// Return: tLoadStatus
+//
+//=============================================================================
+tLoadStatus RoadDataSegmentLoader::Load(tChunkFile* f, tEntityStore* store)
+{
+ char name[256];
+ f->GetString( name );
+ unsigned int type = f->GetUInt();
+ unsigned int numLanes = f->GetUInt();
+ bool hasShoulder = ( f->GetUInt() ? true : false );
+
+ rmt::Vector direction;
+ direction.x = f->GetFloat();
+ direction.y = f->GetFloat();
+ direction.z = f->GetFloat();
+
+ rmt::Vector top;
+ top.x = f->GetFloat();
+ top.y = f->GetFloat();
+ top.z = f->GetFloat();
+
+ rmt::Vector bottom;
+ bottom.x = f->GetFloat();
+ bottom.y = f->GetFloat();
+ bottom.z = f->GetFloat();
+
+ RoadManager* rm = RoadManager::GetInstance();
+
+ RoadSegmentData* rsd = rm->GetFreeRoadSegmentDataMemory();
+ rAssert( rsd );
+
+ rsd->SetName( name );
+ rsd->SetData( direction, top, bottom, numLanes );
+
+ rm->AddRoadSegmentData( rsd );
+
+ return LOAD_OK;
+}
+
+//=============================================================================
+// RoadDataSegmentLoader::CheckChunkID
+//=============================================================================
+// Description: Comment
+//
+// Parameters: (unsigned id)
+//
+// Return: bool
+//
+//=============================================================================
+bool RoadDataSegmentLoader::CheckChunkID(unsigned id)
+{
+ return ( SRR2::ChunkID::ROAD_SEGMENT_DATA == id );
+}
+
+unsigned int RoadDataSegmentLoader::GetChunkID()
+{
+ return SRR2::ChunkID::ROAD_SEGMENT_DATA;
+}
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/loading/roaddatasegmentloader.h b/game/code/loading/roaddatasegmentloader.h
new file mode 100644
index 0000000..7da74ba
--- /dev/null
+++ b/game/code/loading/roaddatasegmentloader.h
@@ -0,0 +1,53 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: roaddatasegmentloader.h
+//
+// Description: Blahblahblah
+//
+// History: 27/06/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+#ifndef ROADDATASEGMENTLOADER_H
+#define ROADDATASEGMENTLOADER_H
+
+//========================================
+// Nested Includes
+//========================================
+// Pure 3D
+#include <p3d/loadmanager.hpp>
+#include <p3d/p3dtypes.hpp>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: Blahblahblah
+//
+//=============================================================================
+
+class RoadDataSegmentLoader : public tChunkHandler
+{
+public:
+ RoadDataSegmentLoader();
+ virtual ~RoadDataSegmentLoader();
+
+ // P3D chunk loader.
+ virtual tLoadStatus Load(tChunkFile* f, tEntityStore* store);
+
+ // P3D chunk id.
+ virtual bool CheckChunkID(unsigned id);
+ virtual unsigned int GetChunkID();
+
+private:
+
+ //Prevent wasteful constructor creation.
+ RoadDataSegmentLoader( const RoadDataSegmentLoader& roaddatasegmentloader );
+ RoadDataSegmentLoader& operator=( const RoadDataSegmentLoader& roaddatasegmentloader );
+};
+
+
+#endif //ROADDATASEGMENTLOADER_H
diff --git a/game/code/loading/roadloader.cpp b/game/code/loading/roadloader.cpp
new file mode 100644
index 0000000..b600cd0
--- /dev/null
+++ b/game/code/loading/roadloader.cpp
@@ -0,0 +1,544 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: roadloader.cpp
+//
+// Description: Implement RoadLoader
+//
+// History: 15/03/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <p3d/chunkfile.hpp>
+#include <p3d/inventory.hpp>
+#include <p3d/entity.hpp>
+#include <radmath/radmath.hpp>
+
+
+#ifndef TOOLS
+#include <memory/srrmemory.h>
+#else
+#define MEMTRACK_PUSH_GROUP(x)
+#define MEMTRACK_POP_GROUP()
+#endif
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/roadloader.h>
+#include <roads/roadmanager.h>
+#include <roads/intersection.h>
+#include <roads/roadsegmentdata.h>
+#include <roads/roadsegment.h>
+#include <roads/road.h>
+
+#include <constants/srrchunks.h>
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+static unsigned int sNumRoadsLoaded = 0;
+static unsigned int sNumRoadSegmentsLoaded = 0;
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// RoadLoader::RoadLoader
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+RoadLoader::RoadLoader() :
+tSimpleChunkHandler(SRR2::ChunkID::ROAD)
+{
+ mpListenerCB = NULL;
+ mUserData = -1;
+
+}
+
+//==============================================================================
+// RoadLoader::~RoadLoader
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+RoadLoader::~RoadLoader()
+{
+}
+
+//==============================================================================
+// RoadLoader::Load
+//==============================================================================
+// Description: Comment
+//
+// Parameters: (tChunkFile* f, tEntityStore* store)
+//
+// Return: tLoadStatus
+//
+//==============================================================================
+tLoadStatus RoadLoader::Load(tChunkFile* f, tEntityStore* store)
+{
+MEMTRACK_PUSH_GROUP( "Road Loading" );
+
+ char name[256];
+ f->GetPString( name );
+ unsigned int type = f->GetUInt();
+
+ RoadManager* rm = RoadManager::GetInstance();
+ rAssert( rm );
+
+ char start[256];
+ f->GetString( start );
+ Intersection* startIntersection = rm->FindIntersection( tEntity::MakeUID( start ) );
+ rAssert( startIntersection );
+
+ char end[256];
+ f->GetString( end );
+ Intersection* endIntersection = rm->FindIntersection( tEntity::MakeUID( end ) );
+ rAssert( endIntersection );
+
+ unsigned int density = f->GetUInt();
+
+ unsigned int speed = f->GetUInt();
+
+
+ RoadList segments;
+
+ bool firstSeg = true;
+ unsigned int numLanes = 0;
+
+ if ( !f->ChunksRemaining() )
+ {
+ char error[256];
+ sprintf( error, "The Road: %s has no segments!\n", name );
+ rDebugString( error );
+MEMTRACK_POP_GROUP( "Road Loading" );
+ return LOAD_OK;
+ }
+
+ unsigned int segCount = 0;
+ while ( f->ChunksRemaining() )
+ {
+ f->BeginChunk();
+
+ unsigned int tmpNumLanes = 0;
+ RoadSegment* segment = LoadRoadSegment( f, tmpNumLanes );
+
+ if( firstSeg )
+ {
+ numLanes = tmpNumLanes;
+ }
+ else
+ {
+ rAssert( numLanes == tmpNumLanes ); //Should have the same number of lanes.
+ }
+
+ segments.push_back( segment );
+ ++segCount;
+
+ f->EndChunk();
+ }
+
+ Road* road = rm->GetFreeRoadMemory();
+ rAssert( road );
+
+#ifndef RAD_RELEASE
+ road->SetName( name );
+#endif
+
+ rm->AddRoad( road );
+
+ road->SetDestinationIntersection( endIntersection );
+ road->SetSourceIntersection( startIntersection );
+ road->SetNumLanes( numLanes );
+
+ //This works differently now.
+ //8 bits - speed
+ //8 bits - difficulty level
+ //1 bit - id Short cut
+ //15 bits - saved for later
+ const int SPEED_MASK = 0x000000FF;
+ const int DIFFIC_MASK = 0x0000FF00;
+ const int SC_MASK = 0x00010000;
+
+ road->SetSpeed( speed & SPEED_MASK );
+ road->SetDifficulty( (speed & DIFFIC_MASK) >> 8 );
+ road->SetShortCut( (speed & SC_MASK) ? true : false );
+ road->SetDensity( density );
+
+ startIntersection->AddRoadOut( road );
+ endIntersection->AddRoadIn( road );
+
+ road->AllocateSegments( segments.size() );
+
+
+ //Now we sort the road segments to make sure they are in order from the
+ //starting intersection...
+
+
+ RoadList::iterator i;
+
+ //Let's sort these.
+ float dist = 10000000000.0f;
+
+ RoadSegment* closest = NULL;
+ rmt::Vector startPoint;
+ startIntersection->GetLocation( startPoint );
+
+ for( i = segments.begin(); i != segments.end(); i++ )
+ {
+ RoadSegment* segment = (*i);
+
+ rmt::Vector origin;
+ segment->GetCorner( 0, origin );
+
+ origin.Sub( startPoint );
+ float segToInt = origin.MagnitudeSqr();
+
+ if ( segToInt < dist )
+ {
+ closest = segment;
+ dist = segToInt;
+ }
+ }
+
+ unsigned int numAllocated = 0;
+ RoadList allocatedSegments;
+
+ allocatedSegments.push_back( closest );
+ ++numAllocated;
+
+ //Now that we have the closest, let's find them in order....
+
+ RoadSegment* current = closest;
+
+ while ( allocatedSegments.size() < segments.size() )
+ {
+ bool found = false;
+
+ for ( i = segments.begin(); i != segments.end(); i++ )
+ {
+ RoadSegment* seg = *i;
+
+ rmt::Vector currentTrailingLeft;
+ rmt::Vector segOrigin;
+
+ current->GetCorner( 1, currentTrailingLeft );
+ seg->GetCorner( 0, segOrigin );
+
+ if ( rmt::Epsilon( currentTrailingLeft.x, segOrigin.x, 0.5f ) &&
+ rmt::Epsilon( currentTrailingLeft.y, segOrigin.y, 0.5f ) &&
+ rmt::Epsilon( currentTrailingLeft.z, segOrigin.z, 0.5f ) )
+ {
+ //This is the next segment.
+ current = seg;
+ allocatedSegments.push_back( seg );
+ ++numAllocated;
+
+ found = true;
+
+ break;
+ }
+ }
+
+
+ if ( !found )
+ {
+ bool error = true;
+ //This could be the case where the intersection is of the shape where the origin is further away than the next segments.
+ //If there is only on segment missing, then test this theory out.
+ if ( segCount - numAllocated == 1 )
+ {
+ //This is the strange case of the missing first segment.
+ //Find the missing segment and try to match it to the first element in the allocated segs list.
+ //if they match then add the found one to the start of the list.
+ for ( i = segments.begin(); i != segments.end(); i++ )
+ {
+ bool notTheMissingOne = false;
+ RoadList::iterator j;
+ for ( j = allocatedSegments.begin(); j != allocatedSegments.end(); j++ )
+ {
+ if ( (*i) == (*j) )
+ {
+ notTheMissingOne = true;
+ break;
+ }
+ }
+
+ if ( !notTheMissingOne )
+ {
+ //AHA!
+ //segment i is not allocated!
+ //Test it's trailing left against the first one's origin.
+ rmt::Vector trailingLeft;
+ rmt::Vector origin;
+
+ (*i)->GetCorner( 1, trailingLeft );
+ (*(allocatedSegments.begin()))->GetCorner( 0, origin );
+
+ if ( rmt::Epsilon( trailingLeft.x, origin.x, 0.5f ) &&
+ rmt::Epsilon( trailingLeft.y, origin.y, 0.5f ) &&
+ rmt::Epsilon( trailingLeft.z, origin.z, 0.5f ) )
+ {
+ //This is the next segment.
+ allocatedSegments.push_front( (*i) );
+ ++numAllocated;
+ error = false;
+ }
+ }
+ }
+ }
+
+ if ( error )
+ {
+ #ifndef RAD_RELEASE
+ char message[500];
+ sprintf( message,
+ "\b ERROR! The road segment \"%s\" is not touching any others...\n"
+ " Found: %d out of %d\n"
+ " Possibly due to duplicated segments\n"
+ " Please note the errors above and inform Cary/Dusit/Sheik\n"
+ " These errors are fatal! Skipping will result in crash\n"
+ " and/or lousy AI behaviour.\n",
+ current->GetName(),
+ numAllocated,
+ segCount );
+ rTuneAssertMsg( false, message );
+ #endif
+ }
+
+ break;
+ }
+ }
+
+ float roadLen = 0.0f;
+ for ( i = allocatedSegments.begin(); i != allocatedSegments.end(); i++ )
+ {
+ //
+ // Tell the segment which road it belongs to as well as tell the road
+ // it contains the segment.
+ //
+ RoadSegment* seg = *i;
+ seg->SetRoad( road );
+ road->AddRoadSegment( (*i) );
+
+ float segLen = seg->GetSegmentLength();
+ roadLen += segLen;
+
+#ifdef TOOLS
+ store->Store( seg );
+ seg->AddRef();
+#endif
+ }
+
+ rAssert( roadLen >= 0.0f );
+ road->SetRoadLength( roadLen );
+ road->CreateLanes();
+
+MEMTRACK_POP_GROUP( "Road Loading" );
+
+#ifdef TOOLS
+ road->SetName( name );
+ store->Store( road );
+ //HACK
+ road->AddRef();
+#endif
+
+ sNumRoadsLoaded++;
+
+ /*
+ rDebugPrintf( "*** RoadSegments loaded = %d, Roads loaded = %d, sizeof segments = %d, sizeof roads = %d\n",
+ sNumRoadSegmentsLoaded,
+ sNumRoadsLoaded,
+ sizeof(RoadSegment) * sNumRoadSegmentsLoaded,
+ sizeof(Road) * sNumRoadsLoaded );
+ */
+
+ return LOAD_OK;
+}
+
+//==============================================================================
+// RoadLoader::CheckChunkID
+//==============================================================================
+// Description: Comment
+//
+// Parameters: (unsigned id)
+//
+// Return: bool
+//
+//==============================================================================
+bool RoadLoader::CheckChunkID(unsigned id)
+{
+ return SRR2::ChunkID::ROAD == id;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////
+// tSimpleChunkHandler
+///////////////////////////////////////////////////////////////////////
+//========================================================================
+// RoadLoader::
+//========================================================================
+//
+// Description:
+//
+// Parameters: None.
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+tEntity* RoadLoader::LoadObject(tChunkFile* f, tEntityStore* store)
+{
+ return NULL;
+}
+
+
+///////////////////////////////////////////////////////////////////////
+// IWrappedLoader
+///////////////////////////////////////////////////////////////////////
+//========================================================================
+// RoadLoader::SetRegdListener
+//========================================================================
+//
+// Description: Register a new listener/caretaker, notify old listener of
+// severed connection.
+//
+// Parameters: pListenerCB: Callback to call OnChunkLoaded
+// pUserData: Data to pass along for filtering, etc
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+void RoadLoader::SetRegdListener
+(
+ ChunkListenerCallback* pListenerCB,
+ int iUserData
+)
+{
+ //
+ // Follow protocol; notify old Listener, that it has been
+ // "disconnected".
+ //
+ if( mpListenerCB != NULL )
+ {
+ mpListenerCB->OnChunkLoaded( NULL, iUserData, 0 );
+ }
+ mpListenerCB = pListenerCB;
+ mUserData = iUserData;
+}
+
+//========================================================================
+// RoadLoader::ModRegdListener
+//========================================================================
+//
+// Description: Just fuck with the current pUserData
+//
+// Parameters: None.
+//
+// Return: None.
+//
+// Constraints: None.
+//
+//========================================================================
+void RoadLoader::ModRegdListener
+(
+ ChunkListenerCallback* pListenerCB,
+ int iUserData
+)
+{
+#if 0
+ char DebugBuf[255];
+ sprintf( DebugBuf, "RoadLoader::ModRegdListener: pListenerCB %X vs mpListenerCB %X\n",
+ pListenerCB, mpListenerCB );
+ rDebugString( DebugBuf );
+#endif
+ rAssert( pListenerCB == mpListenerCB );
+
+ mUserData = iUserData;
+}
+
+
+
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
+RoadSegment* RoadLoader::LoadRoadSegment( tChunkFile* f, unsigned int& numLanes )
+{
+MEMTRACK_PUSH_GROUP( "RoadSeg Loader" );
+
+ rAssert( f->GetCurrentID() == SRR2::ChunkID::ROAD_SEGMENT );
+
+ char name[256];
+ f->GetString( name );
+
+ char segDataName[256];
+ f->GetString( segDataName );
+
+ // grab the matrix
+ rmt::Matrix hierarchy;
+ f->GetData( &hierarchy, 16, tFile::DWORD );
+
+ // grab the scale along facing
+ rmt::Matrix scale;
+ f->GetData( &scale, 16, tFile::DWORD );
+ rmt::Vector z( 0,0,1.0f );
+ z.Transform( scale );
+ float scaleAlongFacing = z.z;
+
+
+ RoadManager* rm = RoadManager::GetInstance();
+
+ RoadSegmentData* rsd = rm->FindRoadSegmentData( segDataName );
+ rAssert( rsd );
+
+ RoadSegment* rs = rm->GetFreeRoadSegmentMemory();
+ rAssert( rs );
+
+ rs->SetName( name );
+ rs->Init( rsd, hierarchy, scaleAlongFacing );
+
+ // increment count in road manager
+ rm->AddRoadSegment( rs );
+
+ numLanes = rsd->GetNumLanes();
+
+MEMTRACK_POP_GROUP( "RoadSeg Loader" );
+
+ // DSG stuff
+#ifndef TOOLS
+ mpListenerCB->OnChunkLoaded( rs, mUserData, SRR2::ChunkID::ROAD_SEGMENT );
+#endif
+
+ sNumRoadSegmentsLoaded++;
+
+ return rs;
+}
+
diff --git a/game/code/loading/roadloader.h b/game/code/loading/roadloader.h
new file mode 100644
index 0000000..9b0b711
--- /dev/null
+++ b/game/code/loading/roadloader.h
@@ -0,0 +1,87 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: roadloader.h
+//
+// Description: This is the P3D Loader class for Road chunks.
+//
+// History: 15/03/2002 + Created -- Cary Brisebois
+//
+//=============================================================================
+
+#ifndef ROADLOADER_H
+#define ROADLOADER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <p3d/loadmanager.hpp>
+#include <p3d/p3dtypes.hpp>
+#include <render/Loaders/IWrappedLoader.h>
+
+#include <list>
+#include <memory/stlallocators.h>
+
+
+//========================================
+// Forward References
+//========================================
+
+class RoadSegment;
+
+//=============================================================================
+//
+// Synopsis: This is the P3D Loader class for Road chunks.
+//
+//=============================================================================
+
+
+class RoadLoader :
+ public tSimpleChunkHandler,
+ public IWrappedLoader
+
+{
+public:
+ RoadLoader();
+ virtual ~RoadLoader();
+
+#ifndef TOOLS
+ typedef std::list< RoadSegment*, s2alloc<RoadSegment*> > RoadList;
+#else
+ typedef std::list< RoadSegment*> RoadList;
+#endif
+
+ // P3D chunk loader.
+ virtual tLoadStatus Load(tChunkFile* f, tEntityStore* store);
+
+ // P3D chunk id.
+ virtual bool CheckChunkID(unsigned id);
+
+
+ ///////////////////////////////////////////////////////////////////////
+ // IWrappedLoader
+ ///////////////////////////////////////////////////////////////////////
+ void SetRegdListener( ChunkListenerCallback* pListenerCB,
+ int iUserData );
+
+ void ModRegdListener( ChunkListenerCallback* pListenerCB,
+ int iUserData );
+
+ ///////////////////////////////////////////////////////////////////////
+ // tSimpleChunkHandler
+ ///////////////////////////////////////////////////////////////////////
+ virtual tEntity* LoadObject(tChunkFile* file, tEntityStore* store);
+
+
+
+private:
+
+ RoadSegment* LoadRoadSegment( tChunkFile* f, unsigned int& numLanes );
+
+ // No copying or assignment. Declare but don't define.
+ //
+ RoadLoader( const RoadLoader& );
+ RoadLoader& operator= ( const RoadLoader& );
+};
+
+#endif //ROADLOADER_H \ No newline at end of file
diff --git a/game/code/loading/scroobyfilehandler.cpp b/game/code/loading/scroobyfilehandler.cpp
new file mode 100644
index 0000000..49907a9
--- /dev/null
+++ b/game/code/loading/scroobyfilehandler.cpp
@@ -0,0 +1,172 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: ScroobyFileHandler.cpp
+//
+// Description: Implement ConsoleFileHandler
+//
+// History: 07/19/2002 + Created -- Tony Chu
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+// Foundation Tech
+#include <raddebug.hpp>
+#include <radtime.hpp>
+#include <string.h>
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/scroobyfilehandler.h>
+#include <presentation/gui/guisystem.h>
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// ScroobyFileHandler::ScroobyFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+ScroobyFileHandler::ScroobyFileHandler()
+{
+ mpCallback = NULL;
+ mpUserData = NULL;
+ mcSectionName[ 0 ] = '\0';
+}
+
+//==============================================================================
+// ScroobyFileHandler::~ScroobyFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+ScroobyFileHandler::~ScroobyFileHandler()
+{
+}
+
+
+//==============================================================================
+// ScroobyFileHandler::LoadFile
+//==============================================================================
+//
+// Description: Load a Pure3D file asynchronously.
+//
+// Parameters: filename - fully qualified path and filename
+// pCallback - client callback to invoke when load is complete
+// pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void ScroobyFileHandler::LoadFile
+(
+ const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap
+)
+{
+ rAssert( filename );
+ rAssert( pCallback );
+
+ mpCallback = pCallback;
+ mpUserData = pUserData;
+
+ HeapMgr()->PushHeap (GMA_PERSISTENT);
+
+ // load scrooby project
+ Scrooby::App::GetInstance()->LoadProject( filename, this, mcSectionName, heap );
+
+ HeapMgr()->PopHeap (GMA_PERSISTENT);
+}
+
+
+//==============================================================================
+// ScroobyFileHandler::OnProjectLoadComplete
+//==============================================================================
+//
+// Description: Scrooby invokes this callback when the async load
+// is complete.
+//
+// Parameters: pUserData - optional client supplied user data
+//
+// Return: None.
+//
+//==============================================================================
+void ScroobyFileHandler::OnProjectLoadComplete( Scrooby::Project* pProject )
+{
+ rAssert( mpCallback );
+
+ // notify GUI system that the project is loaded, and pass reference to
+ // project using the first message parameter
+ //
+ GetGuiSystem()->HandleMessage( GUI_MSG_PROJECT_LOAD_COMPLETE, (unsigned int)pProject );
+
+ // notify client that async loading is completed
+ mpCallback->OnLoadFileComplete( mpUserData );
+}
+
+
+//==============================================================================
+// ScroobyFileHandler::LoadFileSync
+//==============================================================================
+//
+// Description: Load a Pure3D file synchronously.
+//
+// Parameters: filename - fully qualified path and filename
+//
+// Return: None.
+//
+//==============================================================================
+void ScroobyFileHandler::LoadFileSync( const char* filename )
+{
+ rAssertMsg( 0, "ERROR: Synchronous loading not supported by Scrooby!\n" );
+}
+
+//==============================================================================
+// ScroobyFileHandler::SetSectionName
+//==============================================================================
+//
+// Description:
+//
+// Parameters:
+//
+// Return:
+//
+//==============================================================================
+void ScroobyFileHandler::SetSectionName( const char* sectionName )
+{
+ rAssert( sectionName );
+
+ strcpy( mcSectionName, sectionName );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
+
diff --git a/game/code/loading/scroobyfilehandler.h b/game/code/loading/scroobyfilehandler.h
new file mode 100644
index 0000000..1997fef
--- /dev/null
+++ b/game/code/loading/scroobyfilehandler.h
@@ -0,0 +1,70 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: ScroobyFileHandler.h
+//
+// Description: Declaration of ConsoleFileHandler class.
+//
+// History: 07/19/2002 + Created -- Tony Chu
+//
+//=============================================================================
+
+#ifndef SCROOBYFILEHANDLER_H
+#define SCROOBYFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandler.h>
+#include <app.h>
+
+//========================================
+// Forward References
+//========================================
+
+//=============================================================================
+//
+// Synopsis: File handler for loading Scrooby project files.
+//
+//=============================================================================
+class ScroobyFileHandler : public FileHandler,
+ public Scrooby::LoadProjectCallback
+{
+ public:
+
+ ScroobyFileHandler();
+ virtual ~ScroobyFileHandler();
+
+ //
+ // Implement FileHandler interface.
+ //
+ virtual void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ virtual void LoadFileSync( const char* filename );
+
+ //
+ // Implements Scrooby::LoadProjectCallback interface.
+ //
+ virtual void OnProjectLoadComplete( Scrooby::Project* pProject );
+
+ //
+ // Specify which Scrooby inventory section to load the project.
+ //
+ void SetSectionName( const char* sectionName );
+ const char* GetSectionName() { return( mcSectionName ); }
+
+ private:
+
+ // Prevent wasteful constructor creation.
+ ScroobyFileHandler( const ScroobyFileHandler& scroobyFileHandler );
+ ScroobyFileHandler& operator=( const ScroobyFileHandler& scroobyFileHandler );
+
+ char mcSectionName[ 32 ];
+
+};
+
+
+#endif // SCROOBYFILEHANDLER_H
diff --git a/game/code/loading/soundfilehandler.cpp b/game/code/loading/soundfilehandler.cpp
new file mode 100644
index 0000000..74b2110
--- /dev/null
+++ b/game/code/loading/soundfilehandler.cpp
@@ -0,0 +1,132 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: soundfilehandler.cpp
+//
+// Description: Implement SoundFileHandler, which represents sound in the
+// loading queue
+//
+// History: 19/07/2002 + Created -- Darren
+//
+//=============================================================================
+
+//========================================
+// System Includes
+//========================================
+
+//========================================
+// Project Includes
+//========================================
+#include <loading/soundfilehandler.h>
+
+#include <sound/soundmanager.h>
+#include <memory/srrmemory.h>
+
+
+
+//******************************************************************************
+//
+// Global Data, Local Data, Local Classes
+//
+//******************************************************************************
+
+//******************************************************************************
+//
+// Public Member Functions
+//
+//******************************************************************************
+
+//==============================================================================
+// SoundFileHandler::SoundFileHandler
+//==============================================================================
+// Description: Constructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+SoundFileHandler::SoundFileHandler()
+{
+}
+
+//==============================================================================
+// SoundFileHandler::~SoundFileHandler
+//==============================================================================
+// Description: Destructor.
+//
+// Parameters: None.
+//
+// Return: N/A.
+//
+//==============================================================================
+SoundFileHandler::~SoundFileHandler()
+{
+}
+
+//=============================================================================
+// SoundFileHandler::LoadFile
+//=============================================================================
+// Description: Load sound file asynchronously
+//
+// Parameters: filename - name of file to load
+// pCallback - callback to invoke when loading complete
+// pUserData - user data, unused
+//
+// Return: void
+//
+//=============================================================================
+void SoundFileHandler::LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap )
+{
+ mpCallback = pCallback;
+ mpUserData = pUserData;
+
+ //
+ // Pass the load request on to the sound system, giving it this object
+ // for notification of completion
+ //
+ GetSoundManager()->LoadSoundFile( filename, this );
+}
+
+//=============================================================================
+// SoundFileHandler::LoadFileSync
+//=============================================================================
+// Description: Load sound file synchronously
+//
+// Parameters: filename - name of file to load
+//
+// Return: void
+//
+//=============================================================================
+void SoundFileHandler::LoadFileSync( const char* filename )
+{
+ //
+ // This shouldn't get called. We don't do synchronous in sound.
+ //
+ rAssert( false );
+}
+
+//=============================================================================
+// SoundFileHandler::LoadCompleted
+//=============================================================================
+// Description: Inform loading manager when asynchronous load completed
+//
+// Parameters: None
+//
+// Return: void
+//
+//=============================================================================
+void SoundFileHandler::LoadCompleted()
+{
+ rAssert( mpCallback != NULL );
+ mpCallback->OnLoadFileComplete( mpUserData );
+}
+
+//******************************************************************************
+//
+// Private Member Functions
+//
+//******************************************************************************
diff --git a/game/code/loading/soundfilehandler.h b/game/code/loading/soundfilehandler.h
new file mode 100644
index 0000000..1ea661a
--- /dev/null
+++ b/game/code/loading/soundfilehandler.h
@@ -0,0 +1,66 @@
+//=============================================================================
+// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved.
+//
+// File: soundfilehandler.h
+//
+// Description: Declaration for sound file loader class
+//
+// History: 19/07/2002 + Created -- Darren
+//
+//=============================================================================
+
+#ifndef SOUNDFILEHANDLER_H
+#define SOUNDFILEHANDLER_H
+
+//========================================
+// Nested Includes
+//========================================
+#include <loading/filehandler.h>
+
+//========================================
+// Forward References
+//========================================
+
+class SoundAsyncFileLoader;
+
+//=============================================================================
+//
+// Synopsis: SoundFileHandler
+//
+//=============================================================================
+
+class SoundFileHandler : public FileHandler
+{
+ public:
+ SoundFileHandler();
+ virtual ~SoundFileHandler();
+
+ //
+ // Load file asynchronously.
+ //
+ void LoadFile( const char* filename,
+ FileHandler::LoadFileCallback* pCallback,
+ void* pUserData,
+ GameMemoryAllocator heap );
+
+ //
+ // Load file synchronously.
+ //
+ void LoadFileSync( const char* filename );
+
+ //
+ // Called by sound system on load completion
+ //
+ void LoadCompleted();
+
+ private:
+ //Prevent wasteful constructor creation.
+ SoundFileHandler( const SoundFileHandler& original );
+ SoundFileHandler& operator=( const SoundFileHandler& rhs );
+
+ SoundAsyncFileLoader* m_subtypeFileLoader;
+};
+
+
+#endif // SOUNDFILEHANDLER_H
+