mirror of
https://github.com/thug1src/thug.git
synced 2025-01-21 13:23:47 +00:00
thug1src
This commit is contained in:
commit
d8eb714766
145
Code/Core/Debug.h
Normal file
145
Code/Core/Debug.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 mjb **
|
||||||
|
** **
|
||||||
|
** File name: core/debug.h **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_H
|
||||||
|
#define __CORE_DEBUG_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
// for now - always turn on messages and assertion
|
||||||
|
#define __NOPT_MESSAGES__
|
||||||
|
#define __NOPT_ASSERT__
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Mick - added assertions always on, regardless of debug mode.
|
||||||
|
#define __NOPT_ASSERT__
|
||||||
|
|
||||||
|
// Gary - ... unless you're working on the tools,
|
||||||
|
// in which case the asserts prevent the code from compiling...
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
#ifndef _CONSOLE // Ken: Asserts now compile for console apps. (see levelassetlister project)
|
||||||
|
#undef __NOPT_ASSERT__
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#ifdef __NOPT_CDROM__OLD
|
||||||
|
#undef __NOPT_ASSERT__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Temporary switch off assertions flag
|
||||||
|
#ifdef __NOPT_NOASSERTIONS__
|
||||||
|
#undef __NOPT_ASSERT__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// no assertions on final build ("final=")
|
||||||
|
#ifdef __NOPT_FINAL__
|
||||||
|
#undef __NOPT_ASSERT__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
#define __DEBUG_CODE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/mem/memdbg.h>
|
||||||
|
|
||||||
|
#include "debug/messages.h"
|
||||||
|
#include "debug/checks.h"
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void SetUp( void );
|
||||||
|
void CloseDown( void );
|
||||||
|
|
||||||
|
#ifdef __NOPT_FULL_DEBUG__
|
||||||
|
void* NewClassNode( size_t size );
|
||||||
|
void DeleteClassNode( void* pMem );
|
||||||
|
void* NewInstanceNode( size_t size );
|
||||||
|
void DeleteInstanceNode( void* pMem );
|
||||||
|
#endif // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define Dbg_Code(X) X
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Stubs **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#else // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#ifndef __NOPT_ASSERT__
|
||||||
|
inline void SetUp( void ) {};
|
||||||
|
inline void CloseDown( void ) {};
|
||||||
|
#else
|
||||||
|
void SetUp( void );
|
||||||
|
void CloseDown( void );
|
||||||
|
#endif // __NOPT_ASSERT
|
||||||
|
|
||||||
|
#define Dbg_Code(X)
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_H
|
314
Code/Core/Debug/Assert.cpp
Normal file
314
Code/Core/Debug/Assert.cpp
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: assert.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Assert support code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <core/debug.h>
|
||||||
|
|
||||||
|
#include <sys/config/config.h>
|
||||||
|
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
#include <gfx/gfxman.h>
|
||||||
|
#endif // __PLAT_WN32__
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
int DumpUnwindStack( int iMaxDepth, int *pDest );
|
||||||
|
#include <libdev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
#include <dolphin.h>
|
||||||
|
#define _output OSReport
|
||||||
|
#else
|
||||||
|
#define _output printf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static const int vASSERT_BUFFER_SIZE = 512;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static AssertTrap* assert_trap_handler = NULL;
|
||||||
|
static bool screen_assert_active = false;
|
||||||
|
|
||||||
|
// made public for Dbg_ Macros
|
||||||
|
char* msg_null_pointer = "Null Pointer";
|
||||||
|
char* msg_misaligned_pointer = "Pointer not aligned";
|
||||||
|
char* msg_pointer_to_free_mem = "Pointer to free mem";
|
||||||
|
char* msg_unknown_reason = "No reason supplied";
|
||||||
|
char* msg_type_mismatch = "Type Mismatch: \"%s\" is of type \"%s\" - not a valid \"%s\"";
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void set_trap( AssertTrap* trap )
|
||||||
|
{
|
||||||
|
assert_trap_handler = trap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void screen_assert( bool on )
|
||||||
|
{
|
||||||
|
screen_assert_active = on;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
void Assert( char* file, uint line, Signature& sig, char* reason )
|
||||||
|
#else
|
||||||
|
void Assert( char* file, uint line, char* reason )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
static char assert_buffer1[vASSERT_BUFFER_SIZE];
|
||||||
|
#ifdef __NOPT_DEBUG
|
||||||
|
static char assert_buffer2[vASSERT_BUFFER_SIZE];
|
||||||
|
#endif
|
||||||
|
static char assert_buffer3[vASSERT_BUFFER_SIZE];
|
||||||
|
static char* tmp1 = assert_buffer1;
|
||||||
|
#ifdef __NOPT_DEBUG
|
||||||
|
static char* tmp2 = assert_buffer2;
|
||||||
|
#endif
|
||||||
|
static char* tmp3 = assert_buffer3;
|
||||||
|
|
||||||
|
|
||||||
|
#if !( defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ ))
|
||||||
|
|
||||||
|
static int again = 0;
|
||||||
|
if (again)
|
||||||
|
{
|
||||||
|
_output ("MEM CONTEXT: %s\n",Mem::Manager::sHandle().GetContextName());
|
||||||
|
|
||||||
|
_output( "LOOPED ASSERTION: %s(%d)\n%s\n\n",
|
||||||
|
file, line, reason );
|
||||||
|
_output ("Real Assertion: %s\n%s\n",tmp1,tmp3);
|
||||||
|
while (1); // and hang...
|
||||||
|
}
|
||||||
|
again = 1;
|
||||||
|
|
||||||
|
_output ("\n--------------------------------------------------\nPLEASE COPY FROM A FEW LINES ABOVE HERE\n\nCURRENT MEM CONTEXT: %s\n\n"
|
||||||
|
,Mem::Manager::sHandle().GetContextName());
|
||||||
|
Mem::Manager& mem_man = Mem::Manager::sHandle();
|
||||||
|
// Mem::Heap* heap = mem_man.TopDownHeap();
|
||||||
|
// Mem::Region* region = heap->ParentRegion();
|
||||||
|
// _output ("TopDown Fragmentation %7dK, in %5d Blocks\n",heap->mFreeMem.m_count / 1024, heap->mFreeBlocks.m_count);
|
||||||
|
// _output (" used %7dK, in %5d Blocks\n",heap->mUsedMem.m_count / 1024, heap->mUsedBlocks.m_count);
|
||||||
|
// heap = mem_man.BottomUpHeap();
|
||||||
|
// _output ("BottomUp Fragmentation %7dK, in %5d Blocks\n",heap->mFreeMem.m_count / 1024, heap->mFreeBlocks.m_count);
|
||||||
|
// _output (" used %7dK, in %5d Blocks\n",heap->mUsedMem.m_count / 1024, heap->mUsedBlocks.m_count);
|
||||||
|
// _output ("Shared Region %dK free out of %d K available\n", region->MemAvailable() / 1024, region->TotalSize() / 1024 );
|
||||||
|
|
||||||
|
_output("Name Used Frag Free Min Blocks\n");
|
||||||
|
_output("--------------- ----- ----- ---- ------ ------\n");
|
||||||
|
Mem::Heap* heap;
|
||||||
|
for (heap = mem_man.FirstHeap(); heap != NULL; heap = mem_man.NextHeap(heap))
|
||||||
|
{
|
||||||
|
Mem::Region* region = heap->ParentRegion();
|
||||||
|
_output( "%12s: %5dK %4dK %4dK %4dK %5d \n",
|
||||||
|
heap->GetName(),
|
||||||
|
heap->mUsedMem.m_count / 1024,
|
||||||
|
heap->mFreeMem.m_count / 1024,
|
||||||
|
region->MemAvailable() / 1024,
|
||||||
|
region->MinMemAvailable() / 1024,
|
||||||
|
heap->mUsedBlocks.m_count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_output( "FILE: %s(%d)\nASSERTION: %s\n\n",
|
||||||
|
file, line, reason );
|
||||||
|
_output( tmp1, "FILE: %s(%d) ", file, line );
|
||||||
|
_output( tmp3, "ASSERTION: %s", reason );
|
||||||
|
// attempt to dump the call stack
|
||||||
|
// requires that you have the correct .map file, along with the executable
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
MemView_FindLeaks();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_output( "\nCALL STACK ..........................\n\n");
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
DumpUnwindStack( 40, NULL );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sprintf( tmp1, "FILE: %s(%d) ", file, line );
|
||||||
|
sprintf( tmp3, "ASSERTION: %s", reason );
|
||||||
|
|
||||||
|
#ifndef __PLAT_NGC__
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
// Mick: Attempt to save a screenshot
|
||||||
|
// Dbg_Printf("Attempting to save screenshot 'screens\\Assert???.bmp'\n");
|
||||||
|
if (!Config::CD())
|
||||||
|
{
|
||||||
|
Gfx::Manager * gfx_manager = Gfx::Manager::Instance();
|
||||||
|
gfx_manager->ScreenShot( "Assert" );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( screen_assert_active )
|
||||||
|
{
|
||||||
|
screen_assert_active = false;
|
||||||
|
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
Gfx::Manager* gfx_man = Gfx::Manager::Instance();
|
||||||
|
|
||||||
|
gfx_man->AssertText ( 0, tmp1 );
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG
|
||||||
|
sprintf( tmp2, "%s", &sig.GetName() );
|
||||||
|
gfx_man->AssertText ( 1, tmp2 );
|
||||||
|
#endif
|
||||||
|
gfx_man->AssertText ( 2, tmp3 );
|
||||||
|
|
||||||
|
gfx_man->AssertFlush();
|
||||||
|
#endif // __PLAT_WN32__
|
||||||
|
}
|
||||||
|
#endif // __PLAT_NGC__
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG
|
||||||
|
sprintf( tmp1, "ASSERTION: %s(%d) %s\n%s\n\n",
|
||||||
|
file, line, &sig.GetName(), reason );
|
||||||
|
#else
|
||||||
|
sprintf( tmp1, "FILE: %s(%d)\nASSERTION: %s\n\n",
|
||||||
|
file, line, reason );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
#if 0 // does not seem to output anything...
|
||||||
|
sceDevConsInit(); // Initialise screen console output
|
||||||
|
int console = sceDevConsOpen(
|
||||||
|
(2048 - 640/2 + 20) << 4, // top left GS X primitive coord
|
||||||
|
(2048 - 448/2 + 20) << 4, // top left GS Y primitive coord
|
||||||
|
80, // Number of chars (X)
|
||||||
|
5); // Number of chars (Y)
|
||||||
|
sceDevConsAttribute(console, 7); // Output in white (default colours can be
|
||||||
|
// redefined by sceDevConsSetColor)
|
||||||
|
sceDevConsClear(console);
|
||||||
|
sceDevConsPrintf(console, tmp1);
|
||||||
|
sceDevConsPrintf(console, "blah \n");
|
||||||
|
sceDevConsPrintf(console, "blah2 \n");
|
||||||
|
sceDevConsPrintf(console, "blah3 \n");
|
||||||
|
sceDevConsDraw(console);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if ( assert_trap_handler != NULL )
|
||||||
|
{
|
||||||
|
_output ("MEM CONTEXT: %s\n",Mem::Manager::sHandle().GetContextName());
|
||||||
|
|
||||||
|
Dbg_Printf( "%s\n", tmp1 );
|
||||||
|
assert_trap_handler( tmp1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dbg_Printf( "%s\n", tmp1 );
|
||||||
|
Dbg_Printf( "!!NO TRAP HANDLER SET!!\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#if ( defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ ))
|
||||||
|
void assert_vcc( char* file, uint line, char* reason )
|
||||||
|
{
|
||||||
|
static char assert_buffer[vASSERT_BUFFER_SIZE];
|
||||||
|
static char* tmp = assert_buffer;
|
||||||
|
|
||||||
|
sprintf( tmp, "ASSERTION: %s(%d)\n%s\n\n",
|
||||||
|
file, line, reason );
|
||||||
|
|
||||||
|
if ( assert_trap_handler != NULL )
|
||||||
|
{
|
||||||
|
Dbg_Printf( "%s\n", tmp );
|
||||||
|
assert_trap_handler( tmp );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dbg_Printf( "%s\n", tmp );
|
||||||
|
Dbg_Printf( "!!NO TRAP HANDLER SET!!\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // #ifdef __PLAT_XBOX__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif //__NOPT_DEBUG__
|
319
Code/Core/Debug/Checks.h
Normal file
319
Code/Core/Debug/Checks.h
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (Dbg_) **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 mjb **
|
||||||
|
** **
|
||||||
|
** File name: core/debug/checks.h **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_CHECKS_H
|
||||||
|
#define __CORE_DEBUG_CHECKS_H
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_LOG_H
|
||||||
|
#include <core/log.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "signatrs.h"
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
typedef void ( AssertTrap ) ( char* message );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern char* msg_unknown_reason; // message strings
|
||||||
|
extern char* msg_null_pointer;
|
||||||
|
extern char* msg_misaligned_pointer;
|
||||||
|
extern char* msg_pointer_to_free_mem;
|
||||||
|
extern char* msg_type_mismatch;
|
||||||
|
|
||||||
|
extern AssertTrap default_trap;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
void Assert ( char* file, uint line, Signature& sig, char* reason = msg_unknown_reason );
|
||||||
|
#else
|
||||||
|
void Assert ( char* file, uint line, char* reason = msg_unknown_reason );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void pad_printf ( const char* text, ... );
|
||||||
|
void set_trap( AssertTrap* trap = default_trap );
|
||||||
|
void screen_assert( bool on = false );
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define Dbg_SetTrap(A) { Dbg::set_trap(A); }
|
||||||
|
#define Dbg_SetScreenAssert(A) { Dbg::screen_assert(A); }
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Assertions */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
|
||||||
|
#define Dbg_Assert(_c) \
|
||||||
|
\
|
||||||
|
if ( !(_c)) \
|
||||||
|
{ \
|
||||||
|
Dbg::Assert( __FILE__, __LINE__, Dbg_signature ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define Dbg_MsgAssert( _c, _params ) \
|
||||||
|
\
|
||||||
|
if( !( _c )) \
|
||||||
|
{ \
|
||||||
|
Dbg::pad_printf _params; \
|
||||||
|
Dbg::Assert( __FILE__, __LINE__, Dbg_signature, \
|
||||||
|
Dbg::sprintf_pad ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
// Mick: If we have assertions, but are not in DEBUG mode
|
||||||
|
// then we don not have the Dbg_signature thing
|
||||||
|
// so we just pass NULL to assert()
|
||||||
|
|
||||||
|
#define Dbg_Assert(_c) \
|
||||||
|
\
|
||||||
|
if ( !(_c)) \
|
||||||
|
{ \
|
||||||
|
Dbg::Assert ( __FILE__, __LINE__, NULL ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
|
||||||
|
#ifdef _CONSOLE
|
||||||
|
#define Dbg_MsgAssert( _c, _params ) \
|
||||||
|
\
|
||||||
|
if( !( _c )) \
|
||||||
|
{ \
|
||||||
|
printf("\nGame code assert!\n"); \
|
||||||
|
printf("File %s, line %d\n",__FILE__,__LINE__); \
|
||||||
|
printf _params; \
|
||||||
|
printf("\nPress CTRL-C to quit ... "); \
|
||||||
|
while(1); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define Dbg_MsgAssert( _c, _params )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define Dbg_MsgAssert( _c, _params ) \
|
||||||
|
\
|
||||||
|
if( !( _c )) \
|
||||||
|
{ \
|
||||||
|
Dbg::pad_printf _params; \
|
||||||
|
Dbg::Assert( __FILE__, __LINE__, Dbg::sprintf_pad ); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
#define Dbg_MsgLog( _params ) \
|
||||||
|
{ \
|
||||||
|
Dbg::pad_printf _params; \
|
||||||
|
Log::AddEntry(__FILE__,__LINE__,__PRETTY_FUNCTION__,Dbg::sprintf_pad); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Dbg_Log( ) \
|
||||||
|
{ \
|
||||||
|
Log::AddEntry(__FILE__,__LINE__,__PRETTY_FUNCTION__); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define Dbg_MsgLog( _params ) \
|
||||||
|
{ \
|
||||||
|
Dbg::pad_printf _params; \
|
||||||
|
Log::AddEntry(__FILE__,__LINE__,__FUNCTION__,Dbg::sprintf_pad); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Dbg_Log( ) \
|
||||||
|
{ \
|
||||||
|
Log::AddEntry(__FILE__,__LINE__,__FUNCTION__); \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_MEM_DEBUG__
|
||||||
|
|
||||||
|
#define Dbg_AssertPtr(_p) \
|
||||||
|
{ \
|
||||||
|
if ((_p) == NULL ) \
|
||||||
|
{ \
|
||||||
|
Dbg::Assert ( __FILE__, __LINE__, \
|
||||||
|
Dbg_signature, Dbg::msg_null_pointer ); \
|
||||||
|
} \
|
||||||
|
else if ( *((uint64*)(nAlignDown(_p))) == Mem::vFREE_BLOCK ) \
|
||||||
|
{ \
|
||||||
|
Dbg::Assert ( __FILE__, __LINE__, \
|
||||||
|
Dbg_signature, Dbg::msg_pointer_to_free_mem ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else // __NOPT_MEM_DEBUG__
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#define Dbg_AssertPtr(_p) \
|
||||||
|
{ \
|
||||||
|
if ((_p) == NULL ) \
|
||||||
|
{ \
|
||||||
|
Dbg::Assert ( __FILE__, __LINE__, \
|
||||||
|
Dbg_signature, Dbg::msg_null_pointer ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
#define Dbg_AssertPtr(_p) \
|
||||||
|
{ \
|
||||||
|
if ((_p) == NULL ) \
|
||||||
|
{ \
|
||||||
|
Dbg::Assert ( __FILE__, __LINE__, \
|
||||||
|
Dbg::msg_null_pointer ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //__NOPT_DEBUG__
|
||||||
|
|
||||||
|
#endif // __NOPT_MEM_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* Type Checking */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
#define Dbg_AssertType(_c,_t) \
|
||||||
|
{ \
|
||||||
|
Dbg_AssertPtr(_c); \
|
||||||
|
Dbg_MsgAssert( nAligned(_c), Dbg::msg_misaligned_pointer ); \
|
||||||
|
Dbg_MsgAssert(((_c)->classStamp != Spt::Class::vDELETED_CLASS ),"Deleted Class" ); \
|
||||||
|
Dbg_MsgAssert(((_c)->classStamp == Spt::Class::vREGISTERED_CLASS ), "Corrupt Class" ); \
|
||||||
|
Dbg_MsgAssert(((_c)->vClassNode()->IsDerivedOrSame(*_t::sClassNode())), \
|
||||||
|
Dbg::msg_type_mismatch,#_c,(_c)->vClassNode()->GetName(),#_t); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Dbg_AssertThis \
|
||||||
|
{ \
|
||||||
|
Dbg_AssertPtr(this); \
|
||||||
|
Dbg_MsgAssert( nAligned(this), Dbg::msg_misaligned_pointer ); \
|
||||||
|
Dbg_MsgAssert((classStamp != Spt::Class::vDELETED_CLASS ),"Deleted Class" ); \
|
||||||
|
Dbg_MsgAssert((classStamp == Spt::Class::vREGISTERED_CLASS ), "Corrupt Class" ); \
|
||||||
|
Dbg_MsgAssert((vClassNode()->IsDerivedOrSame(*sClassNode())), \
|
||||||
|
Dbg::msg_type_mismatch,"this", vClassNode()->GetName(),sClassNode()->GetName()); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
#define Dbg_AssertType(_c,_t) Dbg_AssertPtr(_c)
|
||||||
|
#define Dbg_AssertThis Dbg_AssertPtr(this)
|
||||||
|
|
||||||
|
#endif // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Stubs **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define Dbg_MsgAssert( _c, _params )
|
||||||
|
|
||||||
|
#define Dbg_SetTrap(_f)
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
#define Dbg_SetScreenAssert(A) { Dbg::screen_assert(A); }
|
||||||
|
#else
|
||||||
|
#define Dbg_SetScreenAssert(_b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define Dbg_Assert(_c)
|
||||||
|
#define Dbg_AssertPtr(_p)
|
||||||
|
#define Dbg_AssertType(_c,_t)
|
||||||
|
#define Dbg_AssertThis
|
||||||
|
|
||||||
|
#define Dbg_MsgLog( _params )
|
||||||
|
#define Dbg_Log( )
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __NOPT_ASSERT__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_CHECKS_H
|
||||||
|
|
||||||
|
|
454
Code/Core/Debug/Debug.cpp
Normal file
454
Code/Core/Debug/Debug.cpp
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: debug.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Debug message support. **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define __ERROR_STRINGS__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/debug.h>
|
||||||
|
#include <sys/config/config.h>
|
||||||
|
#include <sys/timer.h>
|
||||||
|
#include <sys/mem/memman.h>
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
#include <dolphin.h>
|
||||||
|
#endif __PLAT_NGC__
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Dbg_DefineProject( Core, "Core Library")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern void set_up ( void );
|
||||||
|
extern void close_down ( void );
|
||||||
|
extern OutputCode default_print;
|
||||||
|
extern AssertTrap default_trap;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static const int vBUFFER_SIZE = 512;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static char s_sprintf_buffer[vBUFFER_SIZE];
|
||||||
|
static char s_printf_buffer[vBUFFER_SIZE];
|
||||||
|
static Flags< Level > s_level_mask = mNONE;
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
static char* s_typename[] =
|
||||||
|
{
|
||||||
|
"ERROR!!",
|
||||||
|
"WARNING",
|
||||||
|
"Notify ",
|
||||||
|
"Message"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static OutputCode* output;
|
||||||
|
|
||||||
|
|
||||||
|
// public for Dbg_ Macros
|
||||||
|
char* sprintf_pad = s_sprintf_buffer;
|
||||||
|
char* printf_pad = s_printf_buffer;
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
Signature* current_sig;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
Project* RegisteredProjects = NULL;
|
||||||
|
Module* RegisteredModules = NULL;
|
||||||
|
#endif
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void print( char* text );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static void s_prefixed_output( Level level, char* text, va_list args )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( text );
|
||||||
|
Dbg_Assert( level >= vERROR );
|
||||||
|
Dbg_Assert( level <= vMESSAGE );
|
||||||
|
|
||||||
|
if ( s_level_mask.Test( level ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
printf( "[%s] %s - ",
|
||||||
|
s_typename[level],
|
||||||
|
¤t_sig->GetName());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vsprintf( printf_pad, text, args);
|
||||||
|
|
||||||
|
Dbg::print( printf_pad );
|
||||||
|
Dbg::print( "\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void pad_printf( const char* text, ... )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( text );
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, text );
|
||||||
|
|
||||||
|
vsprintf( sprintf_pad, text, args);
|
||||||
|
|
||||||
|
va_end( args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void print( char* text )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( output )
|
||||||
|
{
|
||||||
|
output( text );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void message ( char *text, ... )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( text );
|
||||||
|
|
||||||
|
|
||||||
|
if ( s_level_mask.TestMask ( mMESSAGE ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, text );
|
||||||
|
s_prefixed_output( vMESSAGE, text, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void notify( char *text, ... )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( text );
|
||||||
|
|
||||||
|
if ( s_level_mask.TestMask ( mNOTIFY ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, text );
|
||||||
|
s_prefixed_output( vNOTIFY, text, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void warning( char *text, ... )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( text );
|
||||||
|
|
||||||
|
if ( s_level_mask.TestMask ( mWARNING ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, text );
|
||||||
|
s_prefixed_output( vWARNING, text, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void error( char *text, ... )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( text );
|
||||||
|
|
||||||
|
if ( s_level_mask.TestMask ( mERROR ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start( args, text );
|
||||||
|
s_prefixed_output( vERROR, text, args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void set_output( OutputCode* handler )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( handler );
|
||||||
|
|
||||||
|
output = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void level_mask( Flags< Mask > mask )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
s_level_mask.SetMask( mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void SetUp( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
set_trap( default_trap );
|
||||||
|
set_output( Dbg::default_print );
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
set_up(); // platform specific setup
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CloseDown( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
close_down(); // platform specific closedown
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
int snputs(const char* pszStr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Need to do this, cos otherwise the printf inside OurPrintf will get converted to
|
||||||
|
// an OurPrintf, & it will infinitely recurse.
|
||||||
|
#undef printf
|
||||||
|
|
||||||
|
int OurPrintf ( const char* fmt, ... )
|
||||||
|
{
|
||||||
|
// Don't want printf's in some builds.
|
||||||
|
# if defined( __PLAT_XBOX__ ) && !defined( __NOPT_ASSERT__ )
|
||||||
|
return 0;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
int ret=-1;
|
||||||
|
|
||||||
|
char p_buffer[1024];
|
||||||
|
|
||||||
|
char *p_buf = p_buffer;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
p_buf[0]=0;
|
||||||
|
#else
|
||||||
|
sprintf (p_buf,"%6d: ",(int)Tmr::GetRenderFrame());
|
||||||
|
p_buf+=strlen(p_buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start( args, fmt );
|
||||||
|
vsprintf(p_buf,fmt,args);
|
||||||
|
va_end( args );
|
||||||
|
|
||||||
|
switch (Config::GetHardware())
|
||||||
|
{
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
case Config::HARDWARE_PS2_PROVIEW:
|
||||||
|
ret=snputs(p_buffer);
|
||||||
|
break;
|
||||||
|
case Config::HARDWARE_PS2_DEVSYSTEM:
|
||||||
|
case Config::HARDWARE_PS2:
|
||||||
|
// If we are capturing to a file, then redirect there
|
||||||
|
if (dumping_printfs == 1)
|
||||||
|
{
|
||||||
|
dump_printf(p_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s",p_buffer);
|
||||||
|
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
case Config::HARDWARE_NGC:
|
||||||
|
OSReport("%s",p_buffer);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
case Config::HARDWARE_XBOX:
|
||||||
|
OutputDebugString(p_buffer);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32 quick_check_checksum(uint32 _i, const char *_s, const char *f, int line);
|
||||||
|
|
||||||
|
uint32 check_checksum(uint32 _i, const char *_s, const char *f, int line)
|
||||||
|
{
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
uint32* ra;
|
||||||
|
asm ( "daddu %0, $31, $0" : "=r" (ra) );
|
||||||
|
|
||||||
|
Dbg_MsgAssert(_i == Crc::GenerateCRCFromString(_s),("%s:%d: Checksum 0x%x does not match %s, should be 0x%x",f,line,_i,_s,Crc::GenerateCRCFromString(_s)));
|
||||||
|
|
||||||
|
// After the assert has been run once, there is no need to run it again, so
|
||||||
|
// patch up the calling code to call quick_check_checksum instead
|
||||||
|
// we just need to inspect the code just before ra,
|
||||||
|
// make sure it contains the instructions for calling "check_checksum"
|
||||||
|
// and replace it with the equivalent for "quick_check_checksum"
|
||||||
|
// This will still all get compiled out for the release build
|
||||||
|
// but this method lets us validata all usages of CRCD that get called.
|
||||||
|
|
||||||
|
// Note, due to I-Cache, this code might still be executed several times
|
||||||
|
// as the routine will continue to be called until the cache entry for the
|
||||||
|
// call is overwritten
|
||||||
|
|
||||||
|
|
||||||
|
uint32 JAL_check_checksum = 0x0c000000 + ((uint32)check_checksum >> 2);
|
||||||
|
uint32 JAL_quick_check_checksum = 0x0c000000 + ((uint32)quick_check_checksum >> 2);
|
||||||
|
|
||||||
|
if (ra[-2] == JAL_check_checksum)
|
||||||
|
{
|
||||||
|
ra[-2] = JAL_quick_check_checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return quick_check_checksum(_i,_s,f,line);
|
||||||
|
#else
|
||||||
|
return _i;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 quick_check_checksum(uint32 _i, const char *_s, const char *f, int line)
|
||||||
|
{
|
||||||
|
return _i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
102
Code/Core/Debug/Mem_stat.h
Normal file
102
Code/Core/Debug/Mem_stat.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Host (HOST_) **
|
||||||
|
** **
|
||||||
|
** File name: core/host.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_MEM_STAT_H
|
||||||
|
#define __CORE_DEBUG_MEM_STAT_H
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Dbg_MEMORY_STATS
|
||||||
|
{
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
Dbg_MEMORY_STATS ( uint total = 0, uint spike = 0,
|
||||||
|
uint system = 0, uint fixed = 0 );
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
uint total; // total memory currently allocated on behalf of this module/project
|
||||||
|
uint spike; // peak total memory allocated on behalf of this module/project
|
||||||
|
uint system; // current module/project private memory that is adjustable by the user
|
||||||
|
uint fixed; // current module/project private memory that is a fixed overhead
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline Dbg_MEMORY_STATS::Dbg_MEMORY_STATS ( uint total, uint spike,
|
||||||
|
uint system, uint fixed )
|
||||||
|
: total ( total ), spike ( spike ),
|
||||||
|
system ( system ), fixed ( fixed )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_SIGNATRS_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
199
Code/Core/Debug/Messages.h
Normal file
199
Code/Core/Debug/Messages.h
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (Dbg_) **
|
||||||
|
** **
|
||||||
|
** File name: core/debug/messages.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_MESSAGES_H
|
||||||
|
#define __CORE_DEBUG_MESSAGES_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/flags.h>
|
||||||
|
|
||||||
|
#include <core/debug/signatrs.h>
|
||||||
|
#include <core/debug/project.h>
|
||||||
|
#include <core/debug/module.h>
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
enum Level
|
||||||
|
{
|
||||||
|
vERROR,
|
||||||
|
vWARNING,
|
||||||
|
vNOTIFY,
|
||||||
|
vMESSAGE,
|
||||||
|
vPRINTF
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Mask
|
||||||
|
{
|
||||||
|
mERROR = (1<<vERROR),
|
||||||
|
mWARNING = (1<<vWARNING),
|
||||||
|
mNOTIFY = (1<<vNOTIFY),
|
||||||
|
mMESSAGE = (1<<vMESSAGE),
|
||||||
|
mPRINTF = (1<<vPRINTF),
|
||||||
|
mALL = ( mERROR |
|
||||||
|
mWARNING |
|
||||||
|
mNOTIFY |
|
||||||
|
mMESSAGE |
|
||||||
|
mPRINTF ),
|
||||||
|
mNONE = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
typedef void ( OutputCode )( char* );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern char* sprintf_pad;
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
extern Signature* current_sig;
|
||||||
|
#endif
|
||||||
|
extern OutputCode default_print;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void set_output( OutputCode* handler = default_print );
|
||||||
|
void level_mask( Flags< Mask > mask );
|
||||||
|
void message( char* text, ...);
|
||||||
|
void notify ( char* text, ...);
|
||||||
|
void warning( char* text, ...);
|
||||||
|
void error ( char* text, ...);
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#if (defined ( __PLAT_XBOX__ ) || defined( __PLAT_WN32__ ))
|
||||||
|
|
||||||
|
inline void Dbg_SetOutput( const char* A ... ) {};
|
||||||
|
#define Dbg_LevelMask(A) { Dbg::level_mask(A); }
|
||||||
|
|
||||||
|
inline void Dbg_Printf( const char* A ... ) {};
|
||||||
|
inline void Dbg_Message( const char* A ... ) {};
|
||||||
|
inline void Dbg_Notify( const char* A ... ) {};
|
||||||
|
inline void Dbg_Warning( const char* A ... ) {};
|
||||||
|
inline void Dbg_Error( const char* A ... ) {};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define Dbg_SetOutput(A...) { Dbg::set_output(##A); }
|
||||||
|
#define Dbg_LevelMask(A) { Dbg::level_mask(A); }
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
#define Dbg_Printf(A...) { printf(##A); }
|
||||||
|
#define Dbg_Message(A...) { Dbg::current_sig = &Dbg_signature; Dbg::message(##A); }
|
||||||
|
#define Dbg_Notify(A...) { Dbg::current_sig = &Dbg_signature; Dbg::notify(##A); }
|
||||||
|
#define Dbg_Warning(A...) { Dbg::current_sig = &Dbg_signature; Dbg::warning(##A); }
|
||||||
|
#define Dbg_Error(A...) { Dbg::current_sig = &Dbg_signature; Dbg::error(##A); }
|
||||||
|
#else
|
||||||
|
#define Dbg_Printf(A...) { printf(##A); }
|
||||||
|
#define Dbg_Message(A...) { Dbg::message(##A); }
|
||||||
|
#define Dbg_Notify(A...) { Dbg::notify(##A); }
|
||||||
|
#define Dbg_Warning(A...) { Dbg::warning(##A); }
|
||||||
|
#define Dbg_Error(A...) { Dbg::error(##A); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __PLAT_XBOX__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Stubs **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if ( defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ ))
|
||||||
|
inline void Dbg_SetOutput( const char* A ... ) {};
|
||||||
|
#define Dbg_LevelMask(A)
|
||||||
|
inline void Dbg_Printf( const char* A ... ) {};
|
||||||
|
inline void Dbg_Message( const char* A ... ) {};
|
||||||
|
inline void Dbg_Notify( const char* A ... ) {};
|
||||||
|
inline void Dbg_Warning( const char* A ... ) {};
|
||||||
|
inline void Dbg_Error( const char* A ... ) {};
|
||||||
|
#else
|
||||||
|
#define Dbg_SetOutput(A...)
|
||||||
|
#define Dbg_LevelMask(A)
|
||||||
|
#define Dbg_Printf(A...)
|
||||||
|
#define Dbg_Message(A...)
|
||||||
|
#define Dbg_Notify(A...)
|
||||||
|
#define Dbg_Warning(A...)
|
||||||
|
#define Dbg_Error(A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __NOPT_MESSAGES__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
// A special printf function that only works for Ryan
|
||||||
|
// (since I love them so much)
|
||||||
|
|
||||||
|
#if defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ )
|
||||||
|
inline void Ryan(const char* A ...) {};
|
||||||
|
inline void Ken(const char* A ...) {};
|
||||||
|
inline void Matt(const char* A ...) {};
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef __USER_RYAN__
|
||||||
|
#define Ryan(A...) printf(##A)
|
||||||
|
#else
|
||||||
|
#define Ryan(A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__USER_KEN__) && defined(__NOPT_DEBUG__)
|
||||||
|
#define Ken(A...) printf(##A)
|
||||||
|
#else
|
||||||
|
#define Ken(A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__USER_MATT__) && defined(__NOPT_DEBUG__)
|
||||||
|
#define Matt(A...) printf(##A)
|
||||||
|
#else
|
||||||
|
#define Matt(A...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_MESSAGES_H
|
183
Code/Core/Debug/Module.h
Normal file
183
Code/Core/Debug/Module.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Confidential Information **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (Dbg_) **
|
||||||
|
** **
|
||||||
|
** File name: core/debug/module.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_MODULE_H
|
||||||
|
#define __CORE_DEBUG_MODULE_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "mem_stat.h"
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// Unfortunately, Visual C++ does not support the __PRETTY_FUNCTION__ predefined
|
||||||
|
// name. The most information we can get at is __FILE__.
|
||||||
|
#if ( defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ ))
|
||||||
|
#define __PRETTY_FUNCTION__ __FILE__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
class Project;
|
||||||
|
|
||||||
|
class Module
|
||||||
|
{
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
Module ( Project& proj, const char& prefix, const char& description );
|
||||||
|
|
||||||
|
void SetNext ( const Module* next );
|
||||||
|
void SetSibling ( const Module* sibling );
|
||||||
|
|
||||||
|
const Module* GetNext ( void ) const;
|
||||||
|
const Module* GetSibling ( void ) const;
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
const Module* m_next; // pointer to next registered module
|
||||||
|
const Module* m_sibling; // pointer to next module in same project
|
||||||
|
|
||||||
|
const char& m_prefix; // module prefix
|
||||||
|
const char& m_description; // module description
|
||||||
|
|
||||||
|
Project& m_project; // project that this modules belongs to
|
||||||
|
Dbg_MEMORY_STATS m_stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern Module* RegisteredModules;
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
inline Module::Module( Project& proj, const char& pref, const char& desc )
|
||||||
|
: m_prefix ( pref ),
|
||||||
|
m_description ( desc ),
|
||||||
|
m_project ( proj )
|
||||||
|
|
||||||
|
{
|
||||||
|
m_next = Dbg::RegisteredModules; // add module to main registration list
|
||||||
|
Dbg::RegisteredModules = this;
|
||||||
|
|
||||||
|
m_sibling = m_project.GetChildren(); // add module to its project parent
|
||||||
|
m_project.SetChildren( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Module::SetNext( const Module* next )
|
||||||
|
{
|
||||||
|
m_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Module::SetSibling( const Module* sibling )
|
||||||
|
{
|
||||||
|
m_sibling = sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline const Module* Module::GetNext( void ) const
|
||||||
|
{
|
||||||
|
return m_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline const Module* Module::GetSibling( void ) const
|
||||||
|
{
|
||||||
|
return m_sibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Stubs **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif //__NOPT_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_MODULE_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
341
Code/Core/Debug/NGPS/P_debug.cpp
Normal file
341
Code/Core/Debug/NGPS/P_debug.cpp
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: p_debug.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Platform specific debug code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <core/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern char _dbg_start[];
|
||||||
|
extern char _dbg_end[];
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vMAX_CLASS_NODES = 28000,
|
||||||
|
vMAX_INSTANCE_NODES = 100000
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int vFREE_CLASS_BLOCK_ID = 0x02030405;
|
||||||
|
static const int vFREE_INST_BLOCK_ID = 0x27354351;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct FreeNode
|
||||||
|
{
|
||||||
|
FreeNode* next;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
union ClassNodeBlock
|
||||||
|
{
|
||||||
|
char pad[sizeof(Spt::ClassNode)];
|
||||||
|
FreeNode free_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
union InstanceNodeBlock
|
||||||
|
{
|
||||||
|
char pad[sizeof(Spt::ClassNode::InstanceNode)];
|
||||||
|
FreeNode free_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static ClassNodeBlock* spClassNodeFreeList = NULL;
|
||||||
|
static InstanceNodeBlock* spInstanceNodeFreeList = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void set_up( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)_dbg_start;
|
||||||
|
|
||||||
|
ClassNodeBlock* p_class_node = spClassNodeFreeList;
|
||||||
|
|
||||||
|
for( int i = 0; i < ( vMAX_CLASS_NODES - 1 ); i++ )
|
||||||
|
{
|
||||||
|
p_class_node->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
p_class_node->free_node.next = (FreeNode*)(++p_class_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_class_node->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
(p_class_node++)->free_node.next = (FreeNode*)spClassNodeFreeList;
|
||||||
|
|
||||||
|
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)(++p_class_node);
|
||||||
|
InstanceNodeBlock* p_inst_node = spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
for( int i = 0; i < ( vMAX_INSTANCE_NODES - 1 ) ; i++ )
|
||||||
|
{
|
||||||
|
p_inst_node->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
p_inst_node->free_node.next = (FreeNode*)(++p_inst_node);
|
||||||
|
}
|
||||||
|
p_inst_node->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
(p_inst_node++)->free_node.next = (FreeNode*)spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( (int)p_inst_node <= (int)_dbg_end,
|
||||||
|
"Dbg Mem Block not big enough (%d bytes too small)", (int)p_inst_node - (int)_dbg_end );
|
||||||
|
|
||||||
|
if ( (int)p_inst_node < ((int)_dbg_end))
|
||||||
|
{
|
||||||
|
Dbg_Warning ( "%dbytes unused in Dbg mem block",((int)_dbg_end - (int)p_inst_node));
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_Notify ( "Dbg Mem Block Allocated successfully" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
ClassNodeBlock* p_class_node = spClassNodeFreeList;
|
||||||
|
InstanceNodeBlock* p_inst_node = spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( p_class_node->free_node.id == vFREE_CLASS_BLOCK_ID, "Block not free" );
|
||||||
|
p_class_node = (ClassNodeBlock*)p_class_node->free_node.next;
|
||||||
|
count++;
|
||||||
|
} while ( p_class_node != spClassNodeFreeList );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( count == vMAX_CLASS_NODES,
|
||||||
|
"%d Class Nodes still registered", vMAX_CLASS_NODES - count );
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( p_inst_node->free_node.id == vFREE_INST_BLOCK_ID, "Block not free" );
|
||||||
|
p_inst_node = (InstanceNodeBlock*)p_inst_node->free_node.next;
|
||||||
|
count++;
|
||||||
|
} while ( p_inst_node != spInstanceNodeFreeList );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( count == vMAX_INSTANCE_NODES,
|
||||||
|
"%d Instance Nodes still registered", vMAX_INSTANCE_NODES - count );
|
||||||
|
|
||||||
|
Dbg_Notify ( "Dbg Mem Block Released successfully" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void* NewClassNode( size_t size )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void* p_ret = (void*)spClassNodeFreeList;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (int)spClassNodeFreeList != (int)(spClassNodeFreeList->free_node.next),
|
||||||
|
"ClassNode pool full" );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( spClassNodeFreeList->free_node.id == vFREE_CLASS_BLOCK_ID, "Not a Free Class Node" );
|
||||||
|
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)spClassNodeFreeList->free_node.next;
|
||||||
|
// printf("NewClassNode %p next %p\n",p_ret, spClassNodeFreeList);
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void DeleteClassNode( void* pMem )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (((int)pMem >= (int)_dbg_start ) && (((int)pMem < (int)_dbg_end ))),
|
||||||
|
"Memory not in Debug block (%p)",pMem );
|
||||||
|
|
||||||
|
ClassNodeBlock* p_freeblock = (ClassNodeBlock*)pMem;
|
||||||
|
p_freeblock->free_node.next = (FreeNode*)spClassNodeFreeList;
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)p_freeblock;
|
||||||
|
|
||||||
|
spClassNodeFreeList->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
|
||||||
|
|
||||||
|
// printf("DeleteClassNode %p next %p\n",spClassNodeFreeList, p_freeblock->free_node.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* NewInstanceNode( size_t size )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
void* p_ret = (void*)spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (int)spInstanceNodeFreeList != (int)(spInstanceNodeFreeList->free_node.next),
|
||||||
|
"InstanceNode pool full" );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( spInstanceNodeFreeList->free_node.id == vFREE_INST_BLOCK_ID, "Not a Free Instance Node" );
|
||||||
|
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)spInstanceNodeFreeList->free_node.next;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// printf("NewInstanceNode %p next %p\n",p_ret, spInstanceNodeFreeList);
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void DeleteInstanceNode( void* pMem )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (((int)pMem >= (int)_dbg_start ) && (((int)pMem < (int)_dbg_end ))),
|
||||||
|
"Memory not in Debug block (%p)",pMem );
|
||||||
|
|
||||||
|
InstanceNodeBlock* p_freeblock = (InstanceNodeBlock*)pMem;
|
||||||
|
p_freeblock->free_node.next = (FreeNode*)spInstanceNodeFreeList;
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)p_freeblock;
|
||||||
|
|
||||||
|
spInstanceNodeFreeList->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
|
||||||
|
|
||||||
|
// printf("DeleteInstanceNode %p next %p\n",spInstanceNodeFreeList, p_freeblock->free_node.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#else // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
void set_up( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_print( char *text )
|
||||||
|
{
|
||||||
|
std::printf( text );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_trap( char* mess )
|
||||||
|
{
|
||||||
|
uint* ptr = reinterpret_cast< uint* >( 0x00000001 );
|
||||||
|
|
||||||
|
*ptr = 0;
|
||||||
|
}
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif
|
159
Code/Core/Debug/Project.h
Normal file
159
Code/Core/Debug/Project.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Confidential Information **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (Dbg_) **
|
||||||
|
** **
|
||||||
|
** File name: core/debug/project.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_PROJECT_H
|
||||||
|
#define __CORE_DEBUG_PROJECT_H
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "mem_stat.h"
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
class Project
|
||||||
|
{
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
Project ( const char& name, const char& description );
|
||||||
|
|
||||||
|
void SetChildren ( Dbg::Module* children );
|
||||||
|
Dbg::Module* GetChildren ( void ) const;
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
const char& name;
|
||||||
|
const char& description;
|
||||||
|
|
||||||
|
Project* next; // pointer to next registered project
|
||||||
|
Dbg::Module* children; // pointer to children modules
|
||||||
|
|
||||||
|
Dbg_MEMORY_STATS stats;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern Dbg::Project* RegisteredProjects;
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define Dbg_DefineProject(proj,des) \
|
||||||
|
\
|
||||||
|
Dbg::Project& Dbg_project_##proj ( void ) \
|
||||||
|
{ \
|
||||||
|
static Dbg::Project project ( *#proj, *des ); \
|
||||||
|
\
|
||||||
|
return project; \
|
||||||
|
}
|
||||||
|
\
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
inline Project::Project ( const char& name, const char& description )
|
||||||
|
: name ( name ), description ( description )
|
||||||
|
{
|
||||||
|
next = RegisteredProjects;
|
||||||
|
RegisteredProjects = this;
|
||||||
|
children = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Project::SetChildren ( Dbg::Module* children_in )
|
||||||
|
{
|
||||||
|
children = children_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Dbg::Module* Project::GetChildren ( void ) const
|
||||||
|
{
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Stubs **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define Dbg_DefineProject(proj,des)
|
||||||
|
|
||||||
|
#endif //__NOPT_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_PROJECT_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
124
Code/Core/Debug/Signatrs.h
Normal file
124
Code/Core/Debug/Signatrs.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (Dbg_) **
|
||||||
|
** **
|
||||||
|
** File name: core/debug/signatrs.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEBUG_SIGNATRS_H
|
||||||
|
#define __CORE_DEBUG_SIGNATRS_H
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Module;
|
||||||
|
|
||||||
|
class Signature
|
||||||
|
{
|
||||||
|
|
||||||
|
public :
|
||||||
|
Signature( char* name, const Module& module );
|
||||||
|
Signature( const char* cl, char* name, const Module& module );
|
||||||
|
|
||||||
|
const char& GetName( void ) const ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
char* m_name; // function's name
|
||||||
|
const Module& m_module; // function's module
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline Signature::Signature( char* name, const Module& module )
|
||||||
|
: m_name ( name ),
|
||||||
|
m_module ( module )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline const char& Signature::GetName( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
return *m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
extern Dbg::Module& Dbg_module;
|
||||||
|
extern Dbg::Signature Dbg_signature;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NOPT_STRICT_SIGNATURES__
|
||||||
|
|
||||||
|
extern Dbg::Module& Dbg_module;
|
||||||
|
extern Dbg::Signature Dbg_signature;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_DEBUG_SIGNATRS_H
|
155
Code/Core/Debug/Wn32/P_debug.cpp
Normal file
155
Code/Core/Debug/Wn32/P_debug.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: p_debug.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Platform specific debug code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
void set_up ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_print ( char *text )
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
|
||||||
|
OutputDebugString ( text );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
printf ( text );
|
||||||
|
|
||||||
|
#endif // __CC_VISUALC__
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_trap ( char* message )
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef __CC_VISUALC__
|
||||||
|
#ifdef __ALLOW_CONTINUE__
|
||||||
|
|
||||||
|
switch ( MessageBox ( GetActiveWindow(), message, "Assertion Failure - Trigger Debugger ?",
|
||||||
|
MB_DEFBUTTON1 | MB_YESNO | MB_ICONEXCLAMATION ))
|
||||||
|
{
|
||||||
|
case IDYES:
|
||||||
|
|
||||||
|
__asm int 3; // trigger the debugger
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // __ALLOW_CONTINUE__
|
||||||
|
|
||||||
|
MessageBox ( GetActiveWindow(), message, "Assertion Failure",
|
||||||
|
MB_DEFBUTTON1 | MB_ICONEXCLAMATION );
|
||||||
|
|
||||||
|
__asm int 3;
|
||||||
|
|
||||||
|
#endif // __ALLOW_CONTINUE__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else // __CC_VISUALC__
|
||||||
|
|
||||||
|
exit(-10);
|
||||||
|
|
||||||
|
#endif // __CC_VISUALC__
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
}
|
||||||
|
|
341
Code/Core/Debug/XBox/p_debug.cpp
Normal file
341
Code/Core/Debug/XBox/p_debug.cpp
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: p_debug.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 09/25/00 - dc **
|
||||||
|
** **
|
||||||
|
** Description: Platform specific debug code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <xtl.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <core/debug.h>
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern char _dbg_start[];
|
||||||
|
extern char _dbg_end[];
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_Module // module this code belongs to
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vMAX_CLASS_NODES = 28000,
|
||||||
|
vMAX_INSTANCE_NODES = 100000
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int vFREE_CLASS_BLOCK_ID = 0x02030405;
|
||||||
|
static const int vFREE_INST_BLOCK_ID = 0x27354351;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct FreeNode
|
||||||
|
{
|
||||||
|
FreeNode* next;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
union ClassNodeBlock
|
||||||
|
{
|
||||||
|
char pad[sizeof(Spt::ClassNode)];
|
||||||
|
FreeNode free_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
union InstanceNodeBlock
|
||||||
|
{
|
||||||
|
char pad[sizeof(Spt::ClassNode::InstanceNode)];
|
||||||
|
FreeNode free_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static ClassNodeBlock* spClassNodeFreeList = NULL;
|
||||||
|
static InstanceNodeBlock* spInstanceNodeFreeList = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void set_up( void )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)_dbg_start;
|
||||||
|
|
||||||
|
ClassNodeBlock* p_class_node = spClassNodeFreeList;
|
||||||
|
|
||||||
|
for( int i = 0; i < ( vMAX_CLASS_NODES - 1 ); i++ )
|
||||||
|
{
|
||||||
|
p_class_node->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
p_class_node->free_node.next = (FreeNode*)(++p_class_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_class_node->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
(p_class_node++)->free_node.next = (FreeNode*)spClassNodeFreeList;
|
||||||
|
|
||||||
|
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)(++p_class_node);
|
||||||
|
InstanceNodeBlock* p_inst_node = spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
for( int i = 0; i < ( vMAX_INSTANCE_NODES - 1 ) ; i++ )
|
||||||
|
{
|
||||||
|
p_inst_node->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
p_inst_node->free_node.next = (FreeNode*)(++p_inst_node);
|
||||||
|
}
|
||||||
|
p_inst_node->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
(p_inst_node++)->free_node.next = (FreeNode*)spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( (int)p_inst_node <= (int)_dbg_end,
|
||||||
|
"Dbg Mem Block not big enough (%d bytes too small)", (int)p_inst_node - (int)_dbg_end );
|
||||||
|
|
||||||
|
if ( (int)p_inst_node < ((int)_dbg_end))
|
||||||
|
{
|
||||||
|
Dbg_Warning ( "%dbytes unused in Dbg mem block",((int)_dbg_end - (int)p_inst_node));
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_Notify ( "Dbg Mem Block Allocated successfully" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down( void )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
ClassNodeBlock* p_class_node = spClassNodeFreeList;
|
||||||
|
InstanceNodeBlock* p_inst_node = spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( p_class_node->free_node.id == vFREE_CLASS_BLOCK_ID, "Block not free" );
|
||||||
|
p_class_node = (ClassNodeBlock*)p_class_node->free_node.next;
|
||||||
|
count++;
|
||||||
|
} while ( p_class_node != spClassNodeFreeList );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( count == vMAX_CLASS_NODES,
|
||||||
|
"%d Class Nodes still registered", vMAX_CLASS_NODES - count );
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( p_inst_node->free_node.id == vFREE_INST_BLOCK_ID, "Block not free" );
|
||||||
|
p_inst_node = (InstanceNodeBlock*)p_inst_node->free_node.next;
|
||||||
|
count++;
|
||||||
|
} while ( p_inst_node != spInstanceNodeFreeList );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( count == vMAX_INSTANCE_NODES,
|
||||||
|
"%d Instance Nodes still registered", vMAX_INSTANCE_NODES - count );
|
||||||
|
|
||||||
|
Dbg_Notify ( "Dbg Mem Block Released successfully" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void* NewClassNode( size_t size )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
|
||||||
|
void* p_ret = (void*)spClassNodeFreeList;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (int)spClassNodeFreeList != (int)(spClassNodeFreeList->free_node.next),
|
||||||
|
"ClassNode pool full" );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( spClassNodeFreeList->free_node.id == vFREE_CLASS_BLOCK_ID, "Not a Free Class Node" );
|
||||||
|
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)spClassNodeFreeList->free_node.next;
|
||||||
|
// printf("NewClassNode %p next %p\n",p_ret, spClassNodeFreeList);
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void DeleteClassNode( void* pMem )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (((int)pMem >= (int)_dbg_start ) && (((int)pMem < (int)_dbg_end ))),
|
||||||
|
"Memory not in Debug block (%p)",pMem );
|
||||||
|
|
||||||
|
ClassNodeBlock* p_freeblock = (ClassNodeBlock*)pMem;
|
||||||
|
p_freeblock->free_node.next = (FreeNode*)spClassNodeFreeList;
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)p_freeblock;
|
||||||
|
|
||||||
|
spClassNodeFreeList->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
|
||||||
|
|
||||||
|
// printf("DeleteClassNode %p next %p\n",spClassNodeFreeList, p_freeblock->free_node.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* NewInstanceNode( size_t size )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
|
||||||
|
void* p_ret = (void*)spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (int)spInstanceNodeFreeList != (int)(spInstanceNodeFreeList->free_node.next),
|
||||||
|
"InstanceNode pool full" );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( spInstanceNodeFreeList->free_node.id == vFREE_INST_BLOCK_ID, "Not a Free Instance Node" );
|
||||||
|
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)spInstanceNodeFreeList->free_node.next;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// printf("NewInstanceNode %p next %p\n",p_ret, spInstanceNodeFreeList);
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void DeleteInstanceNode( void* pMem )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (((int)pMem >= (int)_dbg_start ) && (((int)pMem < (int)_dbg_end ))),
|
||||||
|
"Memory not in Debug block (%p)",pMem );
|
||||||
|
|
||||||
|
InstanceNodeBlock* p_freeblock = (InstanceNodeBlock*)pMem;
|
||||||
|
p_freeblock->free_node.next = (FreeNode*)spInstanceNodeFreeList;
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)p_freeblock;
|
||||||
|
|
||||||
|
spInstanceNodeFreeList->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
|
||||||
|
|
||||||
|
// printf("DeleteInstanceNode %p next %p\n",spInstanceNodeFreeList, p_freeblock->free_node.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#else // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
void set_up( void )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down( void )
|
||||||
|
{
|
||||||
|
Dbg_Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_print( char *text )
|
||||||
|
{
|
||||||
|
OutputDebugString( text );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_trap( char* message )
|
||||||
|
{
|
||||||
|
OutputDebugString( message );
|
||||||
|
uint* ptr = reinterpret_cast< uint* >( 0x00000001 );
|
||||||
|
*ptr = NULL;
|
||||||
|
}
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
205
Code/Core/Debug/log.cpp
Normal file
205
Code/Core/Debug/log.cpp
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: log.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 09/25/02 - ksh **
|
||||||
|
** **
|
||||||
|
** Description: Logging code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <core/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/config/config.h>
|
||||||
|
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
#include <gfx/gfxman.h>
|
||||||
|
#endif // __PLAT_WN32__
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
#include <dolphin.h>
|
||||||
|
#define _output OSReport
|
||||||
|
#else
|
||||||
|
#define _output printf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
// 128 bytes each (sizeof(SLogEntry)) and they come off the debug heap.
|
||||||
|
#define MAX_LOG_ENTRIES 20000
|
||||||
|
|
||||||
|
extern char _log_info_start[];
|
||||||
|
extern char _log_info_end[];
|
||||||
|
|
||||||
|
namespace Log
|
||||||
|
{
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// Chosen just to make sizeof(SLogEntry) a nice round 128
|
||||||
|
#define MAX_MESSAGE_LENGTH 107
|
||||||
|
struct SLogEntry
|
||||||
|
{
|
||||||
|
Tmr::CPUCycles mCPUTime;
|
||||||
|
const char *mpSourceFileName;
|
||||||
|
const char *mpFunctionName;
|
||||||
|
int mLineNumber;
|
||||||
|
char mpMessage[MAX_MESSAGE_LENGTH+1];
|
||||||
|
};
|
||||||
|
//char p_foo[sizeof(SLogEntry)/0];
|
||||||
|
|
||||||
|
struct SLogBufferInfo
|
||||||
|
{
|
||||||
|
// Pointer to the start of the big log buffer, which will be in the debug heap somewhere.
|
||||||
|
SLogEntry *mpBuffer;
|
||||||
|
// The total number of entries in the buffer.
|
||||||
|
int mTotalEntries;
|
||||||
|
// The number of entries written to so far. This starts at 0 when the game starts,
|
||||||
|
// and increases till it hits mTotalEntries, then stays at that value.
|
||||||
|
int mNumEntries;
|
||||||
|
|
||||||
|
// Points to just after the last entry that got added to the buffer.
|
||||||
|
// So it may not point to a valid SLogEntry, for example when the buffer is filling
|
||||||
|
// up, or when pTop points to the end of pBuffer.
|
||||||
|
SLogEntry *mpTop;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
static bool sInitialised=false;
|
||||||
|
static SLogBufferInfo *spLogInfo=NULL;
|
||||||
|
static SLogEntry *spNotALeak=NULL;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (Config::GotExtraMemory())
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(!sInitialised,("Tried to call Log::Init twice"));
|
||||||
|
|
||||||
|
Dbg_MsgAssert((uint32)(_log_info_end-_log_info_start) >= sizeof(SLogBufferInfo),("log_info section too small, got=%d, required=%d",(uint32)(_log_info_end-_log_info_start),sizeof(SLogBufferInfo)));
|
||||||
|
spLogInfo=(SLogBufferInfo*)_log_info_start;
|
||||||
|
|
||||||
|
Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().DebugHeap());
|
||||||
|
|
||||||
|
spLogInfo->mNumEntries=0;
|
||||||
|
spLogInfo->mTotalEntries=MAX_LOG_ENTRIES;
|
||||||
|
spLogInfo->mpBuffer=(SLogEntry*)Mem::Malloc(MAX_LOG_ENTRIES*sizeof(SLogEntry));
|
||||||
|
spNotALeak=spLogInfo->mpBuffer;
|
||||||
|
spLogInfo->mpTop=spLogInfo->mpBuffer;
|
||||||
|
|
||||||
|
uint32 *p_long=(uint32*)spLogInfo->mpBuffer;
|
||||||
|
Dbg_MsgAssert((sizeof(SLogEntry)&3)==0,("sizeof(SLogEntry) not a multiple of 4"));
|
||||||
|
for (uint32 i=0; i<MAX_LOG_ENTRIES*sizeof(SLogEntry)/4; ++i)
|
||||||
|
{
|
||||||
|
*p_long++=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mem::Manager::sHandle().PopContext();
|
||||||
|
|
||||||
|
sInitialised=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddEntry(char *p_fileName, int lineNumber, char *p_functionName, char *p_message)
|
||||||
|
{
|
||||||
|
if (Config::GotExtraMemory())
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(sInitialised,("Log::AddEntry called before Log::Init called"));
|
||||||
|
|
||||||
|
SLogEntry *p_new=NULL;
|
||||||
|
if (spLogInfo->mNumEntries < MAX_LOG_ENTRIES)
|
||||||
|
{
|
||||||
|
p_new=spLogInfo->mpTop++;
|
||||||
|
++spLogInfo->mNumEntries;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spLogInfo->mpTop >= spLogInfo->mpBuffer+MAX_LOG_ENTRIES)
|
||||||
|
{
|
||||||
|
spLogInfo->mpTop=spLogInfo->mpBuffer;
|
||||||
|
}
|
||||||
|
p_new=spLogInfo->mpTop++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_new->mCPUTime=Tmr::GetTimeInCPUCycles();
|
||||||
|
p_new->mLineNumber=lineNumber;
|
||||||
|
p_new->mpFunctionName=p_functionName;
|
||||||
|
p_new->mpSourceFileName=p_fileName;
|
||||||
|
if (p_message)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(strlen(p_message)<=MAX_MESSAGE_LENGTH,("Log message '%s' too long",p_message));
|
||||||
|
strcpy(p_new->mpMessage,p_message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p_new->mpMessage[0]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Log
|
||||||
|
|
||||||
|
#else
|
||||||
|
namespace Log
|
||||||
|
{
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddEntry(char *p_fileName, int lineNumber, char *p_functionName, char *p_message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} // namespace Log
|
||||||
|
#endif // #ifdef __PLAT_NGPS__
|
||||||
|
|
||||||
|
#endif //__NOPT_ASSERT__
|
||||||
|
|
328
Code/Core/Debug/ngc/P_debug.cpp
Normal file
328
Code/Core/Debug/ngc/P_debug.cpp
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Debug (DBG) **
|
||||||
|
** **
|
||||||
|
** File name: p_debug.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Platform specific debug code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <core/debug.h>
|
||||||
|
#include <libsn.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_DEBUG__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
extern char _dbg_start[];
|
||||||
|
extern char _dbg_end[];
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vMAX_CLASS_NODES = 28000,
|
||||||
|
vMAX_INSTANCE_NODES = 100000
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int vFREE_CLASS_BLOCK_ID = 0x02030405;
|
||||||
|
static const int vFREE_INST_BLOCK_ID = 0x27354351;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
struct FreeNode
|
||||||
|
{
|
||||||
|
FreeNode* next;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
} ;
|
||||||
|
|
||||||
|
union ClassNodeBlock
|
||||||
|
{
|
||||||
|
char pad[sizeof(Spt::ClassNode)];
|
||||||
|
FreeNode free_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
union InstanceNodeBlock
|
||||||
|
{
|
||||||
|
char pad[sizeof(Spt::ClassNode::InstanceNode)];
|
||||||
|
FreeNode free_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static ClassNodeBlock* spClassNodeFreeList = NULL;
|
||||||
|
static InstanceNodeBlock* spInstanceNodeFreeList = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void set_up( void )
|
||||||
|
{
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)_dbg_start;
|
||||||
|
|
||||||
|
ClassNodeBlock* p_class_node = spClassNodeFreeList;
|
||||||
|
|
||||||
|
for( int i = 0; i < ( vMAX_CLASS_NODES - 1 ); i++ )
|
||||||
|
{
|
||||||
|
p_class_node->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
p_class_node->free_node.next = (FreeNode*)(++p_class_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
p_class_node->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
(p_class_node++)->free_node.next = (FreeNode*)spClassNodeFreeList;
|
||||||
|
|
||||||
|
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)(++p_class_node);
|
||||||
|
InstanceNodeBlock* p_inst_node = spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
for( int i = 0; i < ( vMAX_INSTANCE_NODES - 1 ) ; i++ )
|
||||||
|
{
|
||||||
|
p_inst_node->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
p_inst_node->free_node.next = (FreeNode*)(++p_inst_node);
|
||||||
|
}
|
||||||
|
p_inst_node->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
(p_inst_node++)->free_node.next = (FreeNode*)spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( (int)p_inst_node <= (int)_dbg_end,
|
||||||
|
"Dbg Mem Block not big enough (%d bytes too small)", (int)p_inst_node - (int)_dbg_end );
|
||||||
|
|
||||||
|
if ( (int)p_inst_node < ((int)_dbg_end))
|
||||||
|
{
|
||||||
|
Dbg_Warning ( "%dbytes unused in Dbg mem block",((int)_dbg_end - (int)p_inst_node));
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_Notify ( "Dbg Mem Block Allocated successfully" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down( void )
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
ClassNodeBlock* p_class_node = spClassNodeFreeList;
|
||||||
|
InstanceNodeBlock* p_inst_node = spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( p_class_node->free_node.id == vFREE_CLASS_BLOCK_ID, "Block not free" );
|
||||||
|
p_class_node = (ClassNodeBlock*)p_class_node->free_node.next;
|
||||||
|
count++;
|
||||||
|
} while ( p_class_node != spClassNodeFreeList );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( count == vMAX_CLASS_NODES,
|
||||||
|
"%d Class Nodes still registered", vMAX_CLASS_NODES - count );
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( p_inst_node->free_node.id == vFREE_INST_BLOCK_ID, "Block not free" );
|
||||||
|
p_inst_node = (InstanceNodeBlock*)p_inst_node->free_node.next;
|
||||||
|
count++;
|
||||||
|
} while ( p_inst_node != spInstanceNodeFreeList );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( count == vMAX_INSTANCE_NODES,
|
||||||
|
"%d Instance Nodes still registered", vMAX_INSTANCE_NODES - count );
|
||||||
|
|
||||||
|
Dbg_Notify ( "Dbg Mem Block Released successfully" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void* NewClassNode( size_t size )
|
||||||
|
{
|
||||||
|
void* p_ret = (void*)spClassNodeFreeList;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (int)spClassNodeFreeList != (int)(spClassNodeFreeList->free_node.next),
|
||||||
|
"ClassNode pool full" );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( spClassNodeFreeList->free_node.id == vFREE_CLASS_BLOCK_ID, "Not a Free Class Node" );
|
||||||
|
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)spClassNodeFreeList->free_node.next;
|
||||||
|
// printf("NewClassNode %p next %p\n",p_ret, spClassNodeFreeList);
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void DeleteClassNode( void* pMem )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( (((int)pMem >= (int)_dbg_start ) && (((int)pMem < (int)_dbg_end ))),
|
||||||
|
"Memory not in Debug block (%p)",pMem );
|
||||||
|
|
||||||
|
ClassNodeBlock* p_freeblock = (ClassNodeBlock*)pMem;
|
||||||
|
p_freeblock->free_node.next = (FreeNode*)spClassNodeFreeList;
|
||||||
|
spClassNodeFreeList = (ClassNodeBlock*)p_freeblock;
|
||||||
|
|
||||||
|
spClassNodeFreeList->free_node.id = vFREE_CLASS_BLOCK_ID;
|
||||||
|
|
||||||
|
|
||||||
|
// printf("DeleteClassNode %p next %p\n",spClassNodeFreeList, p_freeblock->free_node.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* NewInstanceNode( size_t size )
|
||||||
|
{
|
||||||
|
void* p_ret = (void*)spInstanceNodeFreeList;
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( (int)spInstanceNodeFreeList != (int)(spInstanceNodeFreeList->free_node.next),
|
||||||
|
"InstanceNode pool full" );
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( spInstanceNodeFreeList->free_node.id == vFREE_INST_BLOCK_ID, "Not a Free Instance Node" );
|
||||||
|
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)spInstanceNodeFreeList->free_node.next;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// printf("NewInstanceNode %p next %p\n",p_ret, spInstanceNodeFreeList);
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void DeleteInstanceNode( void* pMem )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert ( (((int)pMem >= (int)_dbg_start ) && (((int)pMem < (int)_dbg_end ))),
|
||||||
|
"Memory not in Debug block (%p)",pMem );
|
||||||
|
|
||||||
|
InstanceNodeBlock* p_freeblock = (InstanceNodeBlock*)pMem;
|
||||||
|
p_freeblock->free_node.next = (FreeNode*)spInstanceNodeFreeList;
|
||||||
|
spInstanceNodeFreeList = (InstanceNodeBlock*)p_freeblock;
|
||||||
|
|
||||||
|
spInstanceNodeFreeList->free_node.id = vFREE_INST_BLOCK_ID;
|
||||||
|
|
||||||
|
|
||||||
|
// printf("DeleteInstanceNode %p next %p\n",spInstanceNodeFreeList, p_freeblock->free_node.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#else // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
void set_up( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void close_down( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __NOPT_FULL_DEBUG__
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif // __NOPT_DEBUG__
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
|
||||||
|
namespace Dbg
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_print( char *text )
|
||||||
|
{
|
||||||
|
std::printf( text );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void default_trap( char* message )
|
||||||
|
{
|
||||||
|
// uint* ptr = reinterpret_cast< uint* >( 0x00000001 );
|
||||||
|
//
|
||||||
|
// *ptr = NULL;
|
||||||
|
|
||||||
|
snPause();
|
||||||
|
}
|
||||||
|
} // namespace Dbg
|
||||||
|
|
||||||
|
#endif
|
559
Code/Core/Defines.h
Normal file
559
Code/Core/Defines.h
Normal file
@ -0,0 +1,559 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Standard Header **
|
||||||
|
** **
|
||||||
|
** File name: core/defines.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** All code depends on the definitions in this files **
|
||||||
|
** It should be included in every file **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#define __CORE_DEFINES_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
//#include <strstream>
|
||||||
|
//#include <fstream.h>
|
||||||
|
#ifdef __USE_OLD_STREAMS__
|
||||||
|
#include <iostream.h>
|
||||||
|
#else
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#pragma warning( disable : 4800 )
|
||||||
|
#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
|
||||||
|
#pragma warning( disable : 4291 ) // no matching operator delete found
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <eetypes.h>
|
||||||
|
//#include <iostream.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#else
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <typeinfo>
|
||||||
|
#else
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
#include <stdio.h>
|
||||||
|
//#include <iostream.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#pragma warning( disable : 4800 )
|
||||||
|
#pragma warning( disable : 4291 ) // no matching operator delete found
|
||||||
|
#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
|
||||||
|
#pragma warning( disable : 4995 ) // name was marked as #pragma deprecated
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
//#ifdef __NOPT_ASSERT__
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
#ifdef __NOPT_FINAL__
|
||||||
|
#define printf(A...)
|
||||||
|
#else
|
||||||
|
int OurPrintf(const char *fmt, ...);
|
||||||
|
#define printf OurPrintf
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
int OurPrintf(const char *fmt, ...);
|
||||||
|
#define printf OurPrintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#else
|
||||||
|
// inline void NullPrintf(const char *fmt, ...){}
|
||||||
|
// #define printf NullPrintf
|
||||||
|
//#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define vINT8_MAX 0x7F
|
||||||
|
#define vINT8_MIN 0x81
|
||||||
|
#define vINT16_MAX 0x7FFF
|
||||||
|
#define vINT16_MIN 0x8001
|
||||||
|
#define vINT32_MAX 0x7FFFFFFF
|
||||||
|
#define vINT32_MIN 0x80000001
|
||||||
|
#define vINT64_MAX 0x7FFFFFFFFFFFFFFF
|
||||||
|
#define vINT64_MIN 0x8000000000000001
|
||||||
|
|
||||||
|
#define vUINT8_MAX 0xFF
|
||||||
|
#define vUINT16_MAX 0xFFFF
|
||||||
|
#define vUINT32_MAX 0xFFFFFFFF
|
||||||
|
#define vUINT64_MAX 0xFFFFFFFFFFFFFFFF
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
typedef char int8;
|
||||||
|
typedef short int16;
|
||||||
|
|
||||||
|
typedef unsigned int uint;
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
|
||||||
|
typedef signed int sint;
|
||||||
|
typedef signed char sint8;
|
||||||
|
typedef signed short sint16;
|
||||||
|
|
||||||
|
#define vINT_MAX vINT32_MAX
|
||||||
|
#define vINT_MIN vINT32_MIN
|
||||||
|
#define vUINT_MAX vUINT32_MAX
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
typedef long int32;
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
typedef signed long sint32;
|
||||||
|
typedef __int64 int64;
|
||||||
|
typedef unsigned __int64 uint64;
|
||||||
|
typedef signed __int64 sint64;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
typedef int int32;
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef signed int sint32;
|
||||||
|
typedef long int64;
|
||||||
|
typedef unsigned long uint64;
|
||||||
|
typedef signed long sint64;
|
||||||
|
typedef long128 int128;
|
||||||
|
typedef u_long128 uint128;
|
||||||
|
typedef long128 sint128;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
typedef long int32;
|
||||||
|
typedef unsigned long uint32;
|
||||||
|
typedef signed long sint32;
|
||||||
|
typedef __int64 int64;
|
||||||
|
typedef unsigned __int64 uint64;
|
||||||
|
typedef signed __int64 sint64;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
typedef int int32;
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef signed int sint32;
|
||||||
|
typedef long long int64;
|
||||||
|
typedef unsigned long long uint64;
|
||||||
|
typedef signed long long sint64;
|
||||||
|
// Paul: No GameCube 128-bit types.
|
||||||
|
//typedef long128 int128;
|
||||||
|
//typedef u_long128 uint128;
|
||||||
|
//typedef long128 sint128;
|
||||||
|
typedef long long int128;
|
||||||
|
typedef unsigned long long uint128;
|
||||||
|
typedef signed long long sint128;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__PLAT_NGPS__) || defined(__PLAT_XBOX__) || defined(__PLAT_NGC__)
|
||||||
|
|
||||||
|
class ostream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ostream& operator<< ( char* str ) { printf ( str ); return *this; }
|
||||||
|
ostream& operator<< ( const char* str ) { printf ( str ); return *this; }
|
||||||
|
ostream& operator<< ( sint i ) { printf ( "%d", i ); return *this; }
|
||||||
|
ostream& operator<< ( uint i ) { printf ( "%u", i ); return *this; }
|
||||||
|
ostream& operator<< ( float f ) { printf ( "%f", f ); return *this; }
|
||||||
|
ostream& operator<< ( void* p ) { printf ( "%p", p ); return *this; }
|
||||||
|
ostream& operator<< ( const void* p ) { printf ( "%p", p ); return *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define vINT_BITS 32
|
||||||
|
#define vPTR_BITS 32
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
// Alignment macros
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
#define nAlign(bits) __attribute__((aligned((bits>>3))))
|
||||||
|
#else
|
||||||
|
#define nAlign(bits)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define nPad64(X) uint64 _pad##X;
|
||||||
|
#define nPad32(X) uint32 _pad##X;
|
||||||
|
#define nPad16(X) uint16 _pad##X;
|
||||||
|
#define nPad8(X) uint8 _pad##X;
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
// version stamping
|
||||||
|
|
||||||
|
#define __nTIME__ __TIME__
|
||||||
|
#define __nDATE__ __DATE__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define nBit(b) ( 1 << (b) )
|
||||||
|
|
||||||
|
typedef sint nID;
|
||||||
|
typedef sint8 nID8;
|
||||||
|
typedef sint16 nID16;
|
||||||
|
typedef sint32 nID32;
|
||||||
|
typedef sint64 nID64;
|
||||||
|
|
||||||
|
#define nMakeID(a,b,c,d) ( (nID) ( ( (nID) (a) ) << 24 | ( (nID) (b) ) << 16 | \
|
||||||
|
( (nID) (c) ) << 8 | ( (nID) (d) ) ) )
|
||||||
|
|
||||||
|
|
||||||
|
// nMakeStructID() differs from nMakeID in that struct IDs are always
|
||||||
|
// readable from a memory dump, where as IDs would be reversed on little
|
||||||
|
// endian machines
|
||||||
|
|
||||||
|
#if __CPU_BIG_ENDIAN__
|
||||||
|
#define nMakeStructID(a,b,c,d) ( (nID) ( ((nID)(a))<<24 | ((nID)(b))<<16 | \
|
||||||
|
((nID)(c))<<8 | ((nID)(d)) ))
|
||||||
|
#else
|
||||||
|
#define nMakeStructID(a,b,c,d) ( (ID) ( ((nID)(d))<<24 | ((nID)(c))<<16 | \
|
||||||
|
((nID)(b))<<8 | ((nID)(a)) ))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define nReverse32(L) ( (( (L)>>24 ) & 0xff) | (((L)>>8) &0xff00) | (((L)<<8)&0xff0000) | (((L)<<24)&0xff000000))
|
||||||
|
#define nReverse16(L) ( (( (L)>>8 ) & 0xff) | (((L)<<8)&0xff00) )
|
||||||
|
|
||||||
|
#if __CPU_BIG_ENDIAN__
|
||||||
|
|
||||||
|
#define nBgEn32(L) (L)
|
||||||
|
#define nBgEn16(L) (L)
|
||||||
|
|
||||||
|
#define nLtEn32(L) nReverse32(L)
|
||||||
|
#define nLtEn16(L) nReverse16(L)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define nBgEn32(L) nReverse32(L)
|
||||||
|
#define nBgEn16(L) nReverse16(L)
|
||||||
|
|
||||||
|
#define nLtEn32(L) (L)
|
||||||
|
#define nLtEn16(L) (L)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
#define __PRETTY_FUNCTION__ "?"
|
||||||
|
|
||||||
|
#define isnanf _isnan
|
||||||
|
#define isinff _isnan
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define __CPU_WORD_BALIGN__ 4 // Memory word byte alignment
|
||||||
|
|
||||||
|
#define PTR_ALIGNMASK ( vUINT_MAX << __CPU_WORD_BALIGN__)
|
||||||
|
|
||||||
|
// The alignment macros align elements for fastest access
|
||||||
|
|
||||||
|
#define nAligned(P) ( !( (uint) (P) & (~PTR_ALIGNMASK) ) )
|
||||||
|
#define nAlignDown(P) (void*)( (uint) (P) & PTR_ALIGNMASK )
|
||||||
|
#define nAlignUp(P) (void*)( ( (uint) (P) + ( 1 << __CPU_WORD_BALIGN__ ) - 1 ) & PTR_ALIGNMASK )
|
||||||
|
#define nAlignedBy(P,A) ( !( (uint) (P) & ( ~(vUINT_MAX << (A) ) ) ) )
|
||||||
|
#define nAlignDownBy(P,A) (void*)( (uint) (P) & (vUINT_MAX << (A) ) )
|
||||||
|
#define nAlignUpBy(P,A) (void*)( ( (uint) (P) + ( 1 << (A) ) - 1 ) & ( vUINT_MAX <<( A ) ) )
|
||||||
|
#define nStorage(X) nAlignUp ( (X) + 1 )
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#define nAddPointer(P,X) (void*) ( (uint) (P) + (uint) (X) )
|
||||||
|
#define nSubPointer(P,X) (void*) ( (uint) (P) - (uint) (X) )
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
// Converts a string into a checksum. This macro can be used for readability.
|
||||||
|
// Later, for speed, some application can scan all .cpp and .h files, and
|
||||||
|
// replace all instances of CRCX(...) with corresponding CRCD(...) instances
|
||||||
|
//
|
||||||
|
// Example: CRCX("object_id")
|
||||||
|
#define CRCX(_s) Script::GenerateCRC(_s)
|
||||||
|
// This macro exists simply for readability. Whenever you see a CRCD(...) instance,
|
||||||
|
// you will know what string the checksum maps to. CRCD(...) instances in the code
|
||||||
|
// can be generated from CRCX(...), and can be reverse mapped if desired.
|
||||||
|
//
|
||||||
|
// Example: CRCD(0xdcd2a9d4, "object_id")
|
||||||
|
|
||||||
|
#include <core/debug.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <sys/mem/memman.h>
|
||||||
|
|
||||||
|
#include <core/crc.h>
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
#include <gfx/ngps/p_memview.h>
|
||||||
|
#include "libsn.h"
|
||||||
|
#elif defined( __PLAT_NGC__ )
|
||||||
|
#include <gfx/ngc/p_memview.h>
|
||||||
|
//#include "libsn.h"
|
||||||
|
#elif defined( __PLAT_XBOX__ )
|
||||||
|
#include <gfx/xbox/p_memview.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Mick: This check slows the game down quite a bit
|
||||||
|
#if 1 && defined( __NOPT_ASSERT__ )
|
||||||
|
|
||||||
|
extern uint32 check_checksum(uint32 _i, const char *_s, const char *f, int line);
|
||||||
|
|
||||||
|
#define CRCD(_i, _s) check_checksum(_i, _s, __FILE__, __LINE__)
|
||||||
|
#else
|
||||||
|
#define CRCD(_i, _s) _i
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// CRC-C, for use only in switch statements, where you want to use the same syntax as CRCD
|
||||||
|
#define CRCC(_i, _s) _i
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#ifdef __PLAT_NGC__
|
||||||
|
//class TCPPInit
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// static bool IsHeapInitialized ;
|
||||||
|
//} ;
|
||||||
|
//
|
||||||
|
//// these definitions override the new and delete operators.
|
||||||
|
//
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
static inline void* operator new ( size_t blocksize ) ;
|
||||||
|
|
||||||
|
static inline void* operator new[] ( size_t blocksize ) ;
|
||||||
|
|
||||||
|
static inline void operator delete ( void* block ) ;
|
||||||
|
|
||||||
|
static inline void operator delete[] ( void* block ) ;
|
||||||
|
#endif // __PLAT_NGC__
|
||||||
|
//
|
||||||
|
//#else
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
inline void* operator new( size_t size, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
return new char[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifndef __PLAT_NGC__
|
||||||
|
/******************************************************************/
|
||||||
|
/* Global new/delete operators */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
inline void* operator new( size_t size )
|
||||||
|
{
|
||||||
|
return Mem::Manager::sHandle().New( size, true );
|
||||||
|
}
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new[] ( size_t size )
|
||||||
|
{
|
||||||
|
return Mem::Manager::sHandle().New( size, true );
|
||||||
|
}
|
||||||
|
#endif // __PLAT_NGC__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new( size_t size, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
return Mem::Manager::sHandle().New( size, assert_on_fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new[] ( size_t size, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
return Mem::Manager::sHandle().New( size, assert_on_fail );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new( size_t size, Mem::Allocator* pAlloc, bool assert_on_fail = true )
|
||||||
|
{
|
||||||
|
return Mem::Manager::sHandle().New( size, assert_on_fail, pAlloc );
|
||||||
|
}
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new[]( size_t size, Mem::Allocator* pAlloc, bool assert_on_fail = true )
|
||||||
|
{
|
||||||
|
return Mem::Manager::sHandle().New( size, assert_on_fail, pAlloc );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new( size_t size, void* pLocation )
|
||||||
|
{
|
||||||
|
return pLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void* operator new[]( size_t size, void* pLocation )
|
||||||
|
{
|
||||||
|
return pLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef __PLAT_NGC__
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void operator delete( void* pAddr )
|
||||||
|
{
|
||||||
|
Mem::Manager::sHandle().Delete( pAddr );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void operator delete[]( void* pAddr )
|
||||||
|
{
|
||||||
|
Mem::Manager::sHandle().Delete( pAddr );
|
||||||
|
}
|
||||||
|
#endif // __PLAT_NGC__
|
||||||
|
|
||||||
|
//#ifdef __PLAT_NGC__
|
||||||
|
/******************************************************************/
|
||||||
|
/* only used when exception is thrown in constructor */
|
||||||
|
/* */
|
||||||
|
/******************************************************************
|
||||||
|
|
||||||
|
inline void operator delete( void* pAddr, Mem::Allocator* pAlloc )
|
||||||
|
{
|
||||||
|
Mem::Manager * mem_man = Mem::Manager::Instance();
|
||||||
|
Mem::Manager::sHandle().Delete( pAddr );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************
|
||||||
|
|
||||||
|
inline void operator delete[]( void* pAddr, Mem::Allocator* pAlloc )
|
||||||
|
{
|
||||||
|
Mem::Manager * mem_man = Mem::Manager::Instance();
|
||||||
|
Mem::Manager::sHandle().Delete( pAddr );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************
|
||||||
|
|
||||||
|
inline void operator delete( void*, void* pLocation )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
//#endif // __PLAT_NGC__
|
||||||
|
#endif // __PLAT_WN32__
|
||||||
|
#endif // __CORE_DEFINES_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
87
Code/Core/DynamicTable.cpp
Normal file
87
Code/Core/DynamicTable.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: List **
|
||||||
|
** **
|
||||||
|
** File name: **
|
||||||
|
** **
|
||||||
|
** Created by: **
|
||||||
|
** **
|
||||||
|
** Description: **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/DynamicTable.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Function:
|
||||||
|
*
|
||||||
|
* Description: Default constructor
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
274
Code/Core/DynamicTable.h
Normal file
274
Code/Core/DynamicTable.h
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: DynamicTable **
|
||||||
|
** **
|
||||||
|
** File name: Core\DynamicTable.h **
|
||||||
|
** **
|
||||||
|
** Created by: 12/14/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A handy DynamicTable class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_DYNAMICTABLE_H
|
||||||
|
#define __CORE_LIST_DYNAMICTABLE_H
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
nTemplateBaseClass(_V, DynamicTable)
|
||||||
|
{
|
||||||
|
Dbg_TemplateBaseClass(_V, DynamicTable);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DynamicTable(int size, int grow_increment = 8);
|
||||||
|
~DynamicTable();
|
||||||
|
|
||||||
|
// it goes on the end of the table
|
||||||
|
void Add(_V *pItem);
|
||||||
|
int GetSize();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
_V &Last();
|
||||||
|
|
||||||
|
void Replace(int index, _V *pNewItem);
|
||||||
|
void Remove(int index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool IsEmpty(int index);
|
||||||
|
*/
|
||||||
|
|
||||||
|
_V &operator[](int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
_V ** mpp_table;
|
||||||
|
int m_size;
|
||||||
|
int m_entriesFilled;
|
||||||
|
int m_growIncrement;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
class DynamicTableDestroyer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DynamicTableDestroyer(DynamicTable<_V> *pTable);
|
||||||
|
|
||||||
|
void DeleteTableContents();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DynamicTable<_V> * mp_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
DynamicTable<_V>::DynamicTable(int size, int grow_increment)
|
||||||
|
{
|
||||||
|
m_size = size;
|
||||||
|
m_growIncrement = grow_increment;
|
||||||
|
mpp_table = (_V**) Mem::Malloc(sizeof(_V *) * m_size);
|
||||||
|
//mpp_table = new _V*[m_size];
|
||||||
|
for (int i = 0; i < m_size; i++)
|
||||||
|
mpp_table[i] = NULL;
|
||||||
|
|
||||||
|
m_entriesFilled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
DynamicTable<_V>::~DynamicTable()
|
||||||
|
{
|
||||||
|
Mem::Free(mpp_table);
|
||||||
|
//delete [] mpp_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
void DynamicTable<_V>::Add(_V* pItem)
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_MsgAssert(pItem,( "can't add NULL item to table"));
|
||||||
|
|
||||||
|
// do we need to create a new table?
|
||||||
|
if (m_size <= m_entriesFilled)
|
||||||
|
{
|
||||||
|
// create new table
|
||||||
|
int new_size = m_size + m_growIncrement;
|
||||||
|
_V **ppTemp = (_V**) Mem::Malloc(sizeof(_V *) * new_size);
|
||||||
|
//_V **ppTemp = new _V*[new_size];
|
||||||
|
|
||||||
|
// copy contents of old one
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_size; i++)
|
||||||
|
ppTemp[i] = mpp_table[i];
|
||||||
|
for (i = m_size; i < new_size; i++)
|
||||||
|
ppTemp[i] = NULL;
|
||||||
|
|
||||||
|
Mem::Free(mpp_table);
|
||||||
|
//delete [] mpp_table;
|
||||||
|
mpp_table = ppTemp;
|
||||||
|
m_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_table[m_entriesFilled++] = pItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
int DynamicTable<_V>::GetSize()
|
||||||
|
{
|
||||||
|
return m_entriesFilled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
void DynamicTable<_V>::Reset()
|
||||||
|
{
|
||||||
|
m_entriesFilled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
void DynamicTable<_V>::Replace(int index, _V *pNewItem)
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_MsgAssert(index >= 0 && index < m_entriesFilled,( "index out of bounds in DynamicTable"));
|
||||||
|
Dbg_AssertPtr(pNewItem);
|
||||||
|
mpp_table[index] = pNewItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
void DynamicTable<_V>::Remove(int index)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(index >= 0 && index < m_entriesFilled,( "index out of bounds in DynamicTable"));
|
||||||
|
|
||||||
|
delete mpp_table[index];
|
||||||
|
|
||||||
|
for ( int i = index; i < m_entriesFilled-1; i++ )
|
||||||
|
{
|
||||||
|
mpp_table[i] = mpp_table[i+1];
|
||||||
|
}
|
||||||
|
mpp_table[m_entriesFilled-1] = NULL;
|
||||||
|
m_entriesFilled--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
template<class _V>
|
||||||
|
bool DynamicTable<_V>::IsEmpty(int index)
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_MsgAssert(index >= 0 && index < m_entriesFilled,( "index out of bounds in DynamicTable"));
|
||||||
|
if (mpp_table[index]) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
_V &DynamicTable<_V>::operator[](int index)
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_MsgAssert(index >= 0 && index < m_entriesFilled,( "index %d out of bounds in DynamicTable", index));
|
||||||
|
Dbg_MsgAssert(mpp_table[index],( "table entry is NULL"));
|
||||||
|
Dbg_AssertPtr(mpp_table[index]);
|
||||||
|
|
||||||
|
return *mpp_table[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
_V &DynamicTable<_V>::Last()
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_MsgAssert(m_entriesFilled > 0,( "empty list"));
|
||||||
|
|
||||||
|
return *mpp_table[m_entriesFilled-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
DynamicTableDestroyer<_V>::DynamicTableDestroyer(DynamicTable<_V> *pTable)
|
||||||
|
{
|
||||||
|
mp_table = pTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
void DynamicTableDestroyer<_V>::DeleteTableContents()
|
||||||
|
{
|
||||||
|
int size = mp_table->GetSize();
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
//if (!mp_table->IsEmpty())
|
||||||
|
delete &(*mp_table)[i];
|
||||||
|
}
|
||||||
|
mp_table->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_DYNAMICTABLE_H
|
||||||
|
|
||||||
|
|
515
Code/Core/HashTable.h
Normal file
515
Code/Core/HashTable.h
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: HashTable **
|
||||||
|
** **
|
||||||
|
** File name: Core\HashTable.h **
|
||||||
|
** **
|
||||||
|
** Created by: 9/22/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A handy Hashtable class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_HASHTABLE_H
|
||||||
|
#define __CORE_LIST_HASHTABLE_H
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
#include <sys/mem/PoolManager.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
template< class _V > class HashTable;
|
||||||
|
|
||||||
|
|
||||||
|
template< class _V > class HashItem
|
||||||
|
{
|
||||||
|
friend class HashTable<_V>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
HashItem();
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
uint32 m_key;
|
||||||
|
_V * mp_value;
|
||||||
|
HashItem<_V> * mp_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class _V> class HashTable
|
||||||
|
{
|
||||||
|
typedef void (*HashCallback)(_V*, void*);
|
||||||
|
|
||||||
|
public:
|
||||||
|
HashTable(uint32 numBits);
|
||||||
|
~HashTable();
|
||||||
|
|
||||||
|
// if any item exists with the same key, replace it
|
||||||
|
bool PutItem(const uint32 &key, _V *item);
|
||||||
|
// delete the item, and remove it from the table
|
||||||
|
void FlushItem(const uint32 &key);
|
||||||
|
// print all instances of an item (debugging)
|
||||||
|
void PrintItem(const uint32 &key);
|
||||||
|
// gets a pointer to requested item, returns NULL if item not in table
|
||||||
|
_V * GetItem(const uint32 &key, bool assert_if_clash = true);
|
||||||
|
_V * GetNextItemWithSameKey(const uint32 &key, _V *p_item);
|
||||||
|
void FlushAllItems(void);
|
||||||
|
void HandleCallback(HashCallback, void* pData);
|
||||||
|
int GetSize(){return m_size;}
|
||||||
|
|
||||||
|
void IterateStart();
|
||||||
|
_V * IterateNext(uint32 *pRetKey = NULL);
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
void PrintContents();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void AllowDuplicateKeys(bool allowed)
|
||||||
|
{
|
||||||
|
m_allowDuplicateKeys = allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint32 m_numBits; // resolution of hash table
|
||||||
|
HashItem<_V> * mp_hash_table;
|
||||||
|
int m_size; // number of entries in the table
|
||||||
|
|
||||||
|
int m_iterator_index;
|
||||||
|
HashItem<_V> * mp_iterator_item;
|
||||||
|
bool m_allowDuplicateKeys;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
HashTable<_V>::HashTable(uint32 numBits)
|
||||||
|
{
|
||||||
|
//Ryan("Creating HashTable");
|
||||||
|
|
||||||
|
m_numBits = numBits;
|
||||||
|
mp_hash_table = new HashItem<_V>[1<<m_numBits];
|
||||||
|
m_size = 0;
|
||||||
|
m_allowDuplicateKeys = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
HashTable<_V>::~HashTable()
|
||||||
|
{
|
||||||
|
|
||||||
|
//Ryan("Destroying HashTable");
|
||||||
|
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
if (!mp_hash_table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FlushAllItems();
|
||||||
|
|
||||||
|
// Remove the table.
|
||||||
|
// Mem::Free(mp_hash_table);
|
||||||
|
delete[] mp_hash_table;
|
||||||
|
mp_hash_table=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
bool HashTable<_V>::PutItem(const uint32 &key, _V *item)
|
||||||
|
{
|
||||||
|
Dbg_AssertPtr(item);
|
||||||
|
//Ryan("putting item in Hash table\n");
|
||||||
|
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
|
||||||
|
// sometimes, we want to allow checksum conflicts
|
||||||
|
// (for instance, ConvertAssets' file database)
|
||||||
|
if ( !m_allowDuplicateKeys )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(!GetItem(key), ("item 0x%x already in hash table", key));
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't add an item of 0,NULL, as that is used to indicate an empty head slot
|
||||||
|
Dbg_MsgAssert(key || item, ("Both key and item are 0 (NULL) in hash table"));
|
||||||
|
// can have a value of NULL either, as the the test below uses pEntry->mp_value == NULL
|
||||||
|
// to indicate an an empty head slot
|
||||||
|
// We could just change it to ( pEntry->mp_value || pEntry->m_key ) if NULL values are desirable
|
||||||
|
Dbg_MsgAssert( item, ("NULL item added to hash table"));
|
||||||
|
|
||||||
|
HashItem<_V> *pEntry=&mp_hash_table[key&((1<<m_numBits)-1)];
|
||||||
|
if ( pEntry->mp_value )
|
||||||
|
{
|
||||||
|
// The main table entry is already occupied, so create a new HashEntry and
|
||||||
|
// link it in between the first and the rest.
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
HashItem<_V> *pNew = new (Mem::PoolManager::SCreateItem(Mem::PoolManager::vHASH_ITEM_POOL)) HashItem<_V>();
|
||||||
|
#else
|
||||||
|
HashItem<_V> *pNew = new HashItem<_V>;
|
||||||
|
#endif
|
||||||
|
pNew->m_key = key;
|
||||||
|
pNew->mp_value = item;
|
||||||
|
pNew->mp_next = pEntry->mp_next;
|
||||||
|
pEntry->mp_next = pNew;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Main table entry is not occupied, so wack it in there.
|
||||||
|
pEntry->m_key = key;
|
||||||
|
pEntry->mp_value = item;
|
||||||
|
// leave pEntry->mp_next untouched
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V *HashTable<_V>::GetNextItemWithSameKey(const uint32 &key, _V *p_item)
|
||||||
|
{
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
|
||||||
|
// Jump to the linked list of all entries with similar checksums.
|
||||||
|
HashItem<_V> *pEntry=&mp_hash_table[key&((1<<m_numBits)-1)];
|
||||||
|
|
||||||
|
// Look for p_item
|
||||||
|
while (pEntry)
|
||||||
|
{
|
||||||
|
if (pEntry->m_key == key && pEntry->mp_value==p_item)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pEntry=pEntry->mp_next;
|
||||||
|
}
|
||||||
|
if (!pEntry)
|
||||||
|
{
|
||||||
|
// p_item was not found.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found p_item, so search the rest of the list for the next element with the same key.
|
||||||
|
pEntry=pEntry->mp_next;
|
||||||
|
while (pEntry)
|
||||||
|
{
|
||||||
|
if (pEntry->m_key == key && pEntry->mp_value)
|
||||||
|
{
|
||||||
|
return pEntry->mp_value;
|
||||||
|
}
|
||||||
|
pEntry=pEntry->mp_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V *HashTable<_V>::GetItem(const uint32 &key, bool assert_if_clash)
|
||||||
|
{
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
|
||||||
|
// Jump to the linked list of all entries with similar checksums.
|
||||||
|
HashItem<_V> *pEntry=&mp_hash_table[key&((1<<m_numBits)-1)];
|
||||||
|
// Scan through the small list until the matching entry is found.
|
||||||
|
|
||||||
|
// Note: the main table entry might be empty, so we still want to scan
|
||||||
|
// the linked ones
|
||||||
|
|
||||||
|
while (pEntry)
|
||||||
|
{
|
||||||
|
if (pEntry->m_key == key && pEntry->mp_value)
|
||||||
|
{
|
||||||
|
return (_V *) pEntry->mp_value;
|
||||||
|
}
|
||||||
|
pEntry=pEntry->mp_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashTable<_V>::PrintItem(const uint32 &key)
|
||||||
|
{
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
|
||||||
|
// Jump to the linked list of all entries with similar checksums.
|
||||||
|
HashItem<_V> *pEntry=&mp_hash_table[key&((1<<m_numBits)-1)];
|
||||||
|
// Scan through the small list until the matching entry is found.
|
||||||
|
|
||||||
|
int n =0;
|
||||||
|
|
||||||
|
// Note: the main table entry might be empty, so we still want to scan
|
||||||
|
// the linked ones
|
||||||
|
|
||||||
|
while (pEntry)
|
||||||
|
{
|
||||||
|
if (pEntry->m_key == key && pEntry->mp_value)
|
||||||
|
{
|
||||||
|
printf ("%d: Entry for 0x%x at %p\n", n ,key,(_V *) pEntry->mp_value);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
pEntry=pEntry->mp_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashTable<_V>::FlushItem(const uint32 &key)
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
if (!mp_hash_table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Jump to the linked list of all entries with similar checksums.
|
||||||
|
HashItem<_V> *pEntry=&mp_hash_table[key&((1<<m_numBits)-1)];
|
||||||
|
HashItem<_V> *pLast = NULL;
|
||||||
|
|
||||||
|
// Scan through the small list until the matching entry is found.
|
||||||
|
while (pEntry)
|
||||||
|
{
|
||||||
|
HashItem<_V> *p_next_entry = pEntry->mp_next;
|
||||||
|
if (pEntry->m_key==key && pEntry->mp_value) // to allow keys of value 0, we have to skip head nodes that are 0,NULL
|
||||||
|
{
|
||||||
|
if (pLast)
|
||||||
|
{
|
||||||
|
// this is not a main table entry; this is a linked entry
|
||||||
|
pLast->mp_next = pEntry->mp_next;
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
Mem::PoolManager::SFreeItem(Mem::PoolManager::vHASH_ITEM_POOL, pEntry);
|
||||||
|
#else
|
||||||
|
delete pEntry;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is a main table entry, it still might be linked to something
|
||||||
|
// clear the entry to 0,NULL (see comment above about keys of value 0)
|
||||||
|
pEntry->m_key = 0;
|
||||||
|
pEntry->mp_value = NULL;
|
||||||
|
}
|
||||||
|
m_size--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLast = pEntry;
|
||||||
|
pEntry = p_next_entry;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashTable<_V>::FlushAllItems()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( mp_hash_table );
|
||||||
|
if (!mp_hash_table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Run through the table and delete any of the extra
|
||||||
|
// HashItem<_V>s.
|
||||||
|
HashItem<_V> *pMainEntry = mp_hash_table;
|
||||||
|
uint32 hashTableSize = (1<<m_numBits);
|
||||||
|
for (uint32 i=0; i<hashTableSize; ++i)
|
||||||
|
{
|
||||||
|
HashItem<_V> *pLinkedEntry = pMainEntry->mp_next;
|
||||||
|
while (pLinkedEntry)
|
||||||
|
{
|
||||||
|
HashItem<_V> *pNext = pLinkedEntry->mp_next;
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
Mem::PoolManager::SFreeItem(Mem::PoolManager::vHASH_ITEM_POOL, pLinkedEntry);
|
||||||
|
#else
|
||||||
|
delete pLinkedEntry;
|
||||||
|
#endif
|
||||||
|
pLinkedEntry = pNext;
|
||||||
|
}
|
||||||
|
pMainEntry->Init();
|
||||||
|
++pMainEntry;
|
||||||
|
}
|
||||||
|
m_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashTable<_V>::HandleCallback(HashCallback hashCallback, void* pData)
|
||||||
|
{
|
||||||
|
HashItem<_V> *pMainEntry = mp_hash_table;
|
||||||
|
uint32 hashTableSize=(1<<m_numBits);
|
||||||
|
for (uint32 i=0; i<hashTableSize; ++i)
|
||||||
|
{
|
||||||
|
HashItem<_V> *pLinkedEntry = pMainEntry->mp_next;
|
||||||
|
while (pLinkedEntry)
|
||||||
|
{
|
||||||
|
HashItem<_V> *pNext = pLinkedEntry->mp_next;
|
||||||
|
// Mem::Free(pLinkedEntry);
|
||||||
|
if (pLinkedEntry->mp_value)
|
||||||
|
(hashCallback)((_V *) pLinkedEntry->mp_value, pData);
|
||||||
|
pLinkedEntry = pNext;
|
||||||
|
}
|
||||||
|
if (pMainEntry->mp_value)
|
||||||
|
(hashCallback)((_V *) pMainEntry->mp_value, pData);
|
||||||
|
++pMainEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashTable<_V>::IterateStart()
|
||||||
|
{
|
||||||
|
m_iterator_index = -1;
|
||||||
|
mp_iterator_item = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V * HashTable<_V>::IterateNext(uint32 *pRetKey)
|
||||||
|
{
|
||||||
|
uint32 hashTableSize=(1<<m_numBits);
|
||||||
|
|
||||||
|
// time to go to the next entry, or the first if we're just starting
|
||||||
|
|
||||||
|
if (mp_iterator_item)
|
||||||
|
// next entry in list
|
||||||
|
mp_iterator_item = mp_iterator_item->mp_next;
|
||||||
|
else if (m_iterator_index >= 0)
|
||||||
|
// we've exhausted all the lists
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!mp_iterator_item)
|
||||||
|
{
|
||||||
|
// no entry in list, move on to next list
|
||||||
|
do
|
||||||
|
{
|
||||||
|
m_iterator_index++;
|
||||||
|
if (m_iterator_index >= (int) hashTableSize)
|
||||||
|
return NULL;
|
||||||
|
mp_iterator_item = mp_hash_table + m_iterator_index;
|
||||||
|
} // main entry has to contain something, or be part of a list
|
||||||
|
while (!mp_iterator_item->mp_value && !mp_iterator_item->mp_next);
|
||||||
|
if (!mp_iterator_item->mp_value)
|
||||||
|
// this must be an empty main entry, skip ahead
|
||||||
|
mp_iterator_item = mp_iterator_item->mp_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ken: Added this because it was hanging here once when loading the junkyard
|
||||||
|
// off CD. It was trying to dereference mp_iterator_item. Added the printf
|
||||||
|
// so we can at least see when it happens without having to go into the debugger.
|
||||||
|
if (!mp_iterator_item)
|
||||||
|
{
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
printf("Error!! NULL mp_iterator_item in IterateNext()\n");
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (pRetKey)
|
||||||
|
*pRetKey = mp_iterator_item->m_key;
|
||||||
|
return mp_iterator_item->mp_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashTable<_V>::PrintContents()
|
||||||
|
{
|
||||||
|
printf("Items in Hash Table:\n");
|
||||||
|
uint32 hashTableSize=(1<<m_numBits);
|
||||||
|
for (uint32 i = 0; i < hashTableSize; ++i)
|
||||||
|
{
|
||||||
|
HashItem<_V> *pEntry = mp_hash_table + i;
|
||||||
|
while(pEntry)
|
||||||
|
{
|
||||||
|
if (pEntry->mp_value)
|
||||||
|
printf(" 0x%x [%d]\n", pEntry->m_key, i);
|
||||||
|
pEntry = pEntry->mp_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
HashItem<_V>::HashItem<_V>()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void HashItem<_V>::Init()
|
||||||
|
{
|
||||||
|
m_key = 0;
|
||||||
|
mp_value = NULL;
|
||||||
|
mp_next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_HASHTABLE_H
|
||||||
|
|
||||||
|
|
64
Code/Core/List.h
Normal file
64
Code/Core/List.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: List (Lst) **
|
||||||
|
** **
|
||||||
|
** File name: core/list.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_H
|
||||||
|
#define __CORE_LIST_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/list/node.h>
|
||||||
|
#include <core/list/head.h>
|
||||||
|
#include <core/list/search.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_H
|
419
Code/Core/List/Head.h
Normal file
419
Code/Core/List/Head.h
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: List (LST_) **
|
||||||
|
** **
|
||||||
|
** File name: core/list/head.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_HEAD_H
|
||||||
|
#define __CORE_LIST_HEAD_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/list/node.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Class: Head
|
||||||
|
*
|
||||||
|
* Description: Linked-list head node.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
nTemplateSubClass( _T, Head, Node< _T > )
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Head( void );
|
||||||
|
virtual ~Head( void );
|
||||||
|
|
||||||
|
void Merge( Head< _T >* dest ); // Source list will be empty after merge
|
||||||
|
uint CountItems( void );
|
||||||
|
Node< _T >* GetItem( uint number ); // Zero-based ( 0 will return first node )
|
||||||
|
|
||||||
|
void AddNode( Node< _T >* node ); // Using priority
|
||||||
|
void AddNodeFromTail( Node< _T >* node ); // Using priority, search backwards from tail (i.e same-priorties are appended rather than pre-pended)
|
||||||
|
bool AddUniqueSequence( Node< _T >* node ); // Only add if priority is unique
|
||||||
|
// and priority decreases
|
||||||
|
void AddToTail( Node< _T >* node );
|
||||||
|
void AddToHead( Node< _T >* node );
|
||||||
|
|
||||||
|
void RemoveAllNodes( void );
|
||||||
|
void DestroyAllNodes( void ); // ONLY USE FOR INHERITED LISTS
|
||||||
|
bool IsEmpty( void );
|
||||||
|
|
||||||
|
Node< _T >* FirstItem(); // get first node, or NULL if none
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Head< _T >::Head( void )
|
||||||
|
: Node< _T > ( reinterpret_cast < _T* >( vHEAD_NODE ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Head< _T >::~Head( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( IsEmpty(),( "List is not empty" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Head< _T >::AddNode( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
Dbg_MsgAssert( !node->InList (),( "Object is already in a list" ));
|
||||||
|
|
||||||
|
Node< _T >* node_ptr = this;
|
||||||
|
Priority new_pri = node->GetPri();
|
||||||
|
|
||||||
|
while (( node_ptr = node_ptr->GetNext() ))
|
||||||
|
{
|
||||||
|
if ( node_ptr->GetPri() <= new_pri )
|
||||||
|
{
|
||||||
|
node_ptr->Insert( node );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Insert( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Head< _T >::AddNodeFromTail( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
Dbg_MsgAssert( !node->InList (),( "Object is already in a list" ));
|
||||||
|
|
||||||
|
Node< _T >* node_ptr = this;
|
||||||
|
Priority new_pri = node->GetPri();
|
||||||
|
|
||||||
|
while (( node_ptr = node_ptr->GetPrev() ))
|
||||||
|
{
|
||||||
|
if ( node_ptr->GetPri() >= new_pri )
|
||||||
|
{
|
||||||
|
node_ptr->Append( node );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Append( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Head< _T >::AddUniqueSequence( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
Dbg_MsgAssert( !node->InList (),( "Object is already in a list" ));
|
||||||
|
|
||||||
|
Node< _T >* node_ptr = this;
|
||||||
|
Priority new_pri = node->GetPri();
|
||||||
|
|
||||||
|
while (( node_ptr = node_ptr->GetNext() ))
|
||||||
|
{
|
||||||
|
if ( node_ptr->GetPri() == new_pri )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if ( node_ptr->GetPri() > new_pri )
|
||||||
|
{
|
||||||
|
node_ptr->Insert( node );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Insert( node );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Head< _T >::Merge( Head< _T >* dest )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( dest, Head< _T > );
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
Dbg_MsgAssert( dest->is_head (),( "Object is not a list" ));
|
||||||
|
|
||||||
|
Node< _T >* first = next;
|
||||||
|
Node< _T >* last = prev;
|
||||||
|
Node< _T >* node = dest->GetPrev();
|
||||||
|
|
||||||
|
if ( this == first ) // source list is empty
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->SetNext( first );
|
||||||
|
first->SetPrev( node );
|
||||||
|
|
||||||
|
last->SetNext( dest );
|
||||||
|
dest->SetPrev( last );
|
||||||
|
|
||||||
|
node_init(); // make the source list empty
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >* Head< _T >::GetItem( uint number )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
|
||||||
|
Node< _T >* node = GetNext();
|
||||||
|
|
||||||
|
while ( node )
|
||||||
|
{
|
||||||
|
if ( number-- == 0 )
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_Warning( "Item requested (%d) out of range (%d)", number, CountItems() );
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
// Return the firs node in the list that this is the head of
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >* Head< _T >::FirstItem( )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
|
||||||
|
return GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T > inline
|
||||||
|
uint Head< _T >::CountItems( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
|
||||||
|
uint count = 0;
|
||||||
|
Node< _T >* node = GetNext();
|
||||||
|
|
||||||
|
while ( node )
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
void Head< _T >::RemoveAllNodes( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
|
||||||
|
Node< _T >* next_nd;
|
||||||
|
Node< _T >* node = GetNext();
|
||||||
|
|
||||||
|
while ( node )
|
||||||
|
{
|
||||||
|
next_nd = node->GetNext();
|
||||||
|
node->Remove();
|
||||||
|
node = next_nd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
void Head< _T >::DestroyAllNodes( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
|
||||||
|
Node< _T >* next_nd;
|
||||||
|
Node< _T >* node = GetNext();
|
||||||
|
|
||||||
|
while ( node )
|
||||||
|
{
|
||||||
|
next_nd = node->GetNext();
|
||||||
|
// node->Remove();
|
||||||
|
delete node;
|
||||||
|
node = next_nd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
template <class _T> inline
|
||||||
|
void Head< _T >::AddToTail( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( this->is_head (),( "Object is not a list" ));
|
||||||
|
Dbg_MsgAssert( !node->InList (),( "Node is already in a list" ));
|
||||||
|
|
||||||
|
Insert ( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
void Head< _T >::AddToHead ( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( this->is_head(),(( "Object is not a list" )));
|
||||||
|
Dbg_MsgAssert( !node->InList(),(( "Node is already in a list" )));
|
||||||
|
|
||||||
|
Append( node );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
bool Head< _T >::IsEmpty( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert ( this->is_head(),( "Object is not a list" ));
|
||||||
|
|
||||||
|
return ( !InList() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_HEAD_H
|
456
Code/Core/List/Node.h
Normal file
456
Code/Core/List/Node.h
Normal file
@ -0,0 +1,456 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: List (LST_) **
|
||||||
|
** **
|
||||||
|
** File name: core/list/node.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_Node_H
|
||||||
|
#define __CORE_LIST_Node_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Class: Lst::Node
|
||||||
|
*
|
||||||
|
* Description: Linked-list node.
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
nTemplateBaseClass( _T, Node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// GJ: Note we have to cast vINT_MIN to an sint
|
||||||
|
// ( ((sint)vINT_MIN) / 2 ) ends up positive.
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vNORMAL_PRIORITY = 0,
|
||||||
|
vHEAD_NODE = vUINT32_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vSYSTEM_TASK_PRIORITY_PROCESS_MODULES = -1000,
|
||||||
|
vSYSTEM_TASK_PRIORITY_FLUSH_DEAD_OBJECTS = 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vLOGIC_TASK_PRIORITY_REPLAY_END_FRAME = -3000,
|
||||||
|
vLOGIC_TASK_PRIORITY_PROCESS_NETWORK_METRICS = -2500,
|
||||||
|
vLOGIC_TASK_PRIORITY_SERVER_SEND_NETWORK_DATA = -2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_CLIENT_SEND_NETWORK_DATA = -2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_TIMEOUT_CONNECTIONS = -2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_CLIENT_ADD_NEW_PLAYERS = -2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_SERVER_ADD_NEW_PLAYERS = -2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_FRONTEND = -2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_SCRIPT_DEBUGGER = -1500,
|
||||||
|
vLOGIC_TASK_PRIORITY_LOCKED_OBJECT_MANAGER_LOGIC = -1100,
|
||||||
|
vLOGIC_TASK_PRIORITY_PARTICLE_MANAGER_LOGIC = -1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_HANDLE_KEYBOARD = -1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_OBJECT_UPDATE = -1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_SCORE_UPDATE = -1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_COMPOSITE_MANAGER = -900,
|
||||||
|
vLOGIC_TASK_PRIORITY_PROCESS_NETWORK_DATA = 0,
|
||||||
|
vLOGIC_TASK_PRIORITY_SKATER_SERVER = 1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_TRANSFER_NETWORK_DATA = 1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_RECEIVE_NETWORK_DATA = 1000,
|
||||||
|
vLOGIC_TASK_PRIORITY_PROCESS_HANDLERS = 2000,
|
||||||
|
vLOGIC_TASK_PRIORITY_REPLAY_START_FRAME = 3000,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vDISPLAY_TASK_PRIORITY_PARK_EDITOR_DISPLAY = -1000,
|
||||||
|
vDISPLAY_TASK_PRIORITY_CPARKEDITOR_DISPLAY = -1000,
|
||||||
|
vDISPLAY_TASK_PRIORITY_IMAGE_VIEWER_DISPLAY = -1000,
|
||||||
|
vDISPLAY_TASK_PRIORITY_PANEL_DISPLAY = -500,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
vHANDLER_PRIORITY_OBSERVER_INPUT_LOGIC = -1000,
|
||||||
|
vHANDLER_PRIORITY_FRONTEND_INPUT_LOGIC0 = -1000,
|
||||||
|
vHANDLER_PRIORITY_FRONTEND_INPUT_LOGIC1 = -1000,
|
||||||
|
vHANDLER_PRIORITY_IMAGE_VIEWER_INPUT_LOGIC = 1000,
|
||||||
|
vHANDLER_PRIORITY_VIEWER_SHIFT_INPUT_LOGIC = 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef sint Priority;
|
||||||
|
|
||||||
|
Node ( _T* d, Priority p = vNORMAL_PRIORITY );
|
||||||
|
virtual ~Node ( void );
|
||||||
|
|
||||||
|
void Insert ( Node< _T >* node );
|
||||||
|
void Append ( Node< _T >* node );
|
||||||
|
void Remove ( void );
|
||||||
|
|
||||||
|
void SetPri ( const Priority priority );
|
||||||
|
void SetNext ( Node< _T >* node );
|
||||||
|
void SetPrev ( Node< _T >* node );
|
||||||
|
|
||||||
|
Priority GetPri ( void ) const;
|
||||||
|
Node< _T >* GetNext ( void ) const;
|
||||||
|
Node< _T >* GetPrev ( void ) const;
|
||||||
|
_T* GetData ( void ) const;
|
||||||
|
|
||||||
|
Node< _T >* LoopNext ( void ) const;
|
||||||
|
Node< _T >* LoopPrev ( void ) const;
|
||||||
|
|
||||||
|
bool InList ( void ) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool is_head ( void ) const;
|
||||||
|
void node_init ( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
_T* data;
|
||||||
|
Priority pri;
|
||||||
|
Node< _T >* next;
|
||||||
|
Node< _T >* prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::node_init( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
next = this;
|
||||||
|
prev = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Node< _T >::is_head( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return ( data == reinterpret_cast<void*>( vHEAD_NODE ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >::Node( _T* d, Priority p )
|
||||||
|
: data( d ), pri( p )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
node_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
// Must define inline functions before they are used
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::Remove( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
prev->next = next;
|
||||||
|
next->prev = prev;
|
||||||
|
|
||||||
|
node_init(); // so we know that the node is not in a list
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >::~Node( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
// Mick: Moved this here from the end of the file
|
||||||
|
// as it's intended to b inline
|
||||||
|
// yet it is used by other functions below
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Node< _T >::InList( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return ( prev != this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::Insert ( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( !node->InList(),("node is already in a list" ));
|
||||||
|
|
||||||
|
node->prev = prev;
|
||||||
|
node->next = this;
|
||||||
|
prev->next = node;
|
||||||
|
prev = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::Append( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
Dbg_MsgAssert( !node->InList(),( "node is already in a list" ));
|
||||||
|
|
||||||
|
node->prev = this;
|
||||||
|
node->next = next;
|
||||||
|
next->prev = node;
|
||||||
|
next = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::SetPri( const Priority priority )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
pri = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::SetNext( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
|
||||||
|
next = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Node< _T >::SetPrev( Node< _T >* node )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node< _T > );
|
||||||
|
|
||||||
|
prev = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
typename Node< _T >::Priority Node< _T >::GetPri( void ) const
|
||||||
|
{
|
||||||
|
return pri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >* Node< _T >::GetNext( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( next->is_head() )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >* Node< _T >::GetPrev( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( prev->is_head() )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_T* Node< _T >::GetData( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >* Node< _T >::LoopNext( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Node< _T >* next_node = next;
|
||||||
|
|
||||||
|
if ( next_node->is_head() )
|
||||||
|
{
|
||||||
|
next_node = next_node->next; // skip head node
|
||||||
|
|
||||||
|
if ( next_node->is_head() )
|
||||||
|
{
|
||||||
|
return NULL; // list is empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Node< _T >* Node< _T >::LoopPrev( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Node< _T >* prev_node = prev;
|
||||||
|
|
||||||
|
if ( prev_node->is_head() )
|
||||||
|
{
|
||||||
|
prev_node = prev_node->prev; // skip head node
|
||||||
|
|
||||||
|
if ( prev_node->is_head() )
|
||||||
|
{
|
||||||
|
return NULL; // list is empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prev_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_Node_H
|
192
Code/Core/List/Search.h
Normal file
192
Code/Core/List/Search.h
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: List (LST_) **
|
||||||
|
** **
|
||||||
|
** File name: core/list/search.h **
|
||||||
|
** **
|
||||||
|
** Created: 04/02/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_SEARCH_H
|
||||||
|
#define __CORE_LIST_SEARCH_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/list/node.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
nTemplateBaseClass ( _T, Search )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Search ( void );
|
||||||
|
virtual ~Search ( void );
|
||||||
|
|
||||||
|
|
||||||
|
_T* FirstItem ( Head<_T>& head );
|
||||||
|
_T* LastItem ( Head<_T>& head );
|
||||||
|
_T* NextItem ( void );
|
||||||
|
_T* PrevItem ( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Node< _T >* node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
Search<_T>::Search ( void )
|
||||||
|
: node ( NULL )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
Search<_T>::~Search ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
_T* Search<_T>::FirstItem ( Head<_T>& head )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType ( &head, Head<_T> );
|
||||||
|
|
||||||
|
node = &head;
|
||||||
|
|
||||||
|
return ( NextItem () );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
_T* Search<_T>::LastItem ( Head<_T>& head )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType ( &head, Head<_T> );
|
||||||
|
|
||||||
|
node = &head;
|
||||||
|
|
||||||
|
return ( PrevItem () );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
_T* Search<_T>::NextItem ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType ( node, Node< _T > );
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
|
||||||
|
if ( !node )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_AssertType ( node, Node<_T> );
|
||||||
|
|
||||||
|
return ( node->GetData() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template <class _T> inline
|
||||||
|
_T* Search<_T>::PrevItem ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType ( node, Node< _T > );
|
||||||
|
|
||||||
|
node = node->GetPrev();
|
||||||
|
|
||||||
|
if ( !node )
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_AssertType ( node, Node<_T> );
|
||||||
|
|
||||||
|
return ( node->GetData() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_SEARCH_H
|
73
Code/Core/List/list.cpp
Normal file
73
Code/Core/List/list.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: List (Lst) **
|
||||||
|
** **
|
||||||
|
** File name: list.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: List management code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
88
Code/Core/LookupTable.cpp
Normal file
88
Code/Core/LookupTable.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: List **
|
||||||
|
** **
|
||||||
|
** File name: Core\List\LookupTable.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 9/22/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A Lookuptable **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/string/cstring.h>
|
||||||
|
#include <core/lookuptable.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Function:
|
||||||
|
*
|
||||||
|
* Description: Default constructor
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
426
Code/Core/LookupTable.h
Normal file
426
Code/Core/LookupTable.h
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: LookupTable **
|
||||||
|
** **
|
||||||
|
** File name: Core\LookupTable.h **
|
||||||
|
** **
|
||||||
|
** Created by: 9/22/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A handy Lookuptable class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_LOOKUPTABLE_H
|
||||||
|
#define __CORE_LIST_LOOKUPTABLE_H
|
||||||
|
|
||||||
|
#ifndef __CORE_CRC_H
|
||||||
|
#include <core/crc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: LookupItem
|
||||||
|
*
|
||||||
|
* Description: Used to represent an item in a Lookup table.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
// forward declaration
|
||||||
|
template< class _V > class LookupTable;
|
||||||
|
|
||||||
|
//nTemplateBaseClass2(_K, _V, LookupItem)
|
||||||
|
template< class _V > class LookupItem
|
||||||
|
{
|
||||||
|
// Dbg_TemplateBaseClass2(_K, _V, LookupItem);
|
||||||
|
|
||||||
|
friend class LookupTable<_V>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LookupItem();
|
||||||
|
|
||||||
|
int m_key;
|
||||||
|
_V * mp_value;
|
||||||
|
LookupItem<_V> * mp_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
nTemplateBaseClass(_V, LookupTable)
|
||||||
|
{
|
||||||
|
Dbg_TemplateBaseClass(_V, LookupTable);
|
||||||
|
|
||||||
|
public:
|
||||||
|
LookupTable(int size=0); // Mick, size is not used, so give it default until we get rid of it
|
||||||
|
~LookupTable();
|
||||||
|
|
||||||
|
// if any item exists with the same key, replace it
|
||||||
|
bool PutItem(const int &key, _V *item);
|
||||||
|
// gets a pointer to requested item, returns NULL if item not in table
|
||||||
|
_V *GetItem(const int &key);
|
||||||
|
// gets a pointer to requested item, returns NULL if item not in table
|
||||||
|
_V *GetItemByIndex(const int &index, int *pKey = NULL);
|
||||||
|
int getSize() {return m_size;}
|
||||||
|
|
||||||
|
// removes item from table, calls its destructor if requested
|
||||||
|
void FlushItem(const int &key);
|
||||||
|
void flushAllItems();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_size;
|
||||||
|
LookupItem<_V> * mp_list; // first item in list
|
||||||
|
LookupItem<_V> * mp_last; // last item in list
|
||||||
|
LookupItem<_V> * mp_current; // Pointer to current item in this table, NULL if invalid
|
||||||
|
int m_currentIndex; // the index of this item. Only valid if mp_current is not NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
class StringLookupTable : public LookupTable<_V>
|
||||||
|
{
|
||||||
|
//Dbg_TemplateBaseClass2(_K, _V, LookupItem);
|
||||||
|
|
||||||
|
public:
|
||||||
|
StringLookupTable(int size);
|
||||||
|
|
||||||
|
bool PutItem(const char *stringKey, _V *item);
|
||||||
|
_V *GetItem(const char *stringKey);
|
||||||
|
void FlushItem(const char *stringKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
class LookupTableDestroyer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LookupTableDestroyer(LookupTable<_V> *pTable);
|
||||||
|
|
||||||
|
void DeleteTableContents();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LookupTable<_V> * mp_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
LookupItem<_V>::LookupItem()
|
||||||
|
{
|
||||||
|
mp_value = NULL;
|
||||||
|
mp_next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
LookupTable<_V>::LookupTable(int size=0)
|
||||||
|
{
|
||||||
|
m_size = 0;
|
||||||
|
mp_list = NULL;
|
||||||
|
mp_current = NULL; // initialized invalid, so we don't try to use it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
LookupTable<_V>::~LookupTable()
|
||||||
|
{
|
||||||
|
flushAllItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
bool LookupTable<_V>::PutItem(const int &key, _V *item)
|
||||||
|
{
|
||||||
|
|
||||||
|
Dbg_AssertPtr(item);
|
||||||
|
//Ryan("putting item in lookup table\n");
|
||||||
|
|
||||||
|
# ifdef __NOPT_DEBUG__
|
||||||
|
if (GetItem(key)) return false;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
LookupItem<_V> *pItem = new LookupItem<_V>;
|
||||||
|
pItem->mp_value = item;
|
||||||
|
pItem->m_key = key;
|
||||||
|
|
||||||
|
if (!mp_list)
|
||||||
|
mp_list = pItem;
|
||||||
|
else
|
||||||
|
mp_last->mp_next = pItem;
|
||||||
|
mp_last = pItem;
|
||||||
|
m_size++;
|
||||||
|
mp_current = NULL; // no longer valid
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V *LookupTable<_V>::GetItem(const int &key)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
LookupItem<_V> *pItem = mp_list;
|
||||||
|
mp_current = NULL; // set invalid now, so if not found, then it will be correctly invalid
|
||||||
|
m_currentIndex = 0; // index should be 0, for the first item
|
||||||
|
while(pItem)
|
||||||
|
{
|
||||||
|
if (pItem->m_key == key)
|
||||||
|
{
|
||||||
|
mp_current = pItem; // we have a valid current, and hence index
|
||||||
|
return pItem->mp_value;
|
||||||
|
}
|
||||||
|
m_currentIndex++; // update index, in case we find the item
|
||||||
|
pItem = pItem->mp_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("returning NULL from GetItem()\n");
|
||||||
|
|
||||||
|
// warning should be given by calling function, if necessary
|
||||||
|
//Dbg_Warning("Item not found in lookup table");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V *LookupTable<_V>::GetItemByIndex(const int &index, int *pKey)
|
||||||
|
{
|
||||||
|
|
||||||
|
// size must be at least 1
|
||||||
|
Dbg_MsgAssert(index >= 0 && index < m_size,( "bad index %d", index));
|
||||||
|
|
||||||
|
// if we have a valid mp_current, then check if we can use that (for speed)
|
||||||
|
if (mp_current)
|
||||||
|
{
|
||||||
|
// is it the same as last time?
|
||||||
|
if (m_currentIndex == index)
|
||||||
|
{
|
||||||
|
// It's this one, so just leave it alone
|
||||||
|
}
|
||||||
|
else if (m_currentIndex < index)
|
||||||
|
{
|
||||||
|
// need to step forward until we find the correct one
|
||||||
|
// this is the most likely scenario if
|
||||||
|
// we are using GetItemByIndex in a for loop
|
||||||
|
// really we need an interator access class
|
||||||
|
// but this should be similar, in terms of code speed
|
||||||
|
while (m_currentIndex < index)
|
||||||
|
{
|
||||||
|
m_currentIndex++;
|
||||||
|
mp_current = mp_current->mp_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// otherwise, we need to start again, so invalidate mp_current
|
||||||
|
mp_current = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't have a valid mp_current at this point, then we need
|
||||||
|
// to start searching from the start again
|
||||||
|
if (!mp_current)
|
||||||
|
{
|
||||||
|
LookupItem<_V> *pItem = mp_list;
|
||||||
|
for (int i = 0; i < index; i++)
|
||||||
|
{
|
||||||
|
pItem = pItem->mp_next;
|
||||||
|
}
|
||||||
|
m_currentIndex = index;
|
||||||
|
mp_current = pItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if they want us to returnt he key, then poke it into the supplied destination
|
||||||
|
if ( pKey )
|
||||||
|
*pKey = mp_current->m_key;
|
||||||
|
|
||||||
|
// the current value is correct
|
||||||
|
return mp_current->mp_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void LookupTable<_V>::FlushItem(const int &key)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
mp_current = NULL; // No longer valid
|
||||||
|
|
||||||
|
LookupItem<_V> *pItem = mp_list;
|
||||||
|
LookupItem<_V> *prev = NULL;
|
||||||
|
while(pItem)
|
||||||
|
{
|
||||||
|
if (pItem->m_key == key)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
prev->mp_next = pItem->mp_next;
|
||||||
|
else
|
||||||
|
mp_list = pItem->mp_next;
|
||||||
|
|
||||||
|
if (mp_last == pItem)
|
||||||
|
mp_last = prev;
|
||||||
|
|
||||||
|
delete pItem;
|
||||||
|
m_size--;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
prev = pItem;
|
||||||
|
pItem = pItem->mp_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void LookupTable<_V>::flushAllItems()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
LookupItem<_V> *pItem = mp_list;
|
||||||
|
while(pItem)
|
||||||
|
{
|
||||||
|
LookupItem<_V> *pNext = pItem->mp_next;
|
||||||
|
delete pItem;
|
||||||
|
pItem = pNext;
|
||||||
|
}
|
||||||
|
mp_list = NULL;
|
||||||
|
mp_current = NULL;
|
||||||
|
m_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int m_size;
|
||||||
|
LookupItem<_K, _V> *m_array;
|
||||||
|
|
||||||
|
_K m_key;
|
||||||
|
_V *mp_value;
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
StringLookupTable<_V>::StringLookupTable(int size) :
|
||||||
|
LookupTable<_V>(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
bool StringLookupTable<_V>::PutItem(const char *stringKey, _V *item)
|
||||||
|
{
|
||||||
|
int key = Crc::GenerateCRCFromString(stringKey);
|
||||||
|
return LookupTable<_V>::PutItem(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V *StringLookupTable<_V>::GetItem(const char *stringKey)
|
||||||
|
{
|
||||||
|
int key = Crc::GenerateCRCFromString(stringKey);
|
||||||
|
return LookupTable<_V>::GetItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void StringLookupTable<_V>::FlushItem(const char *stringKey)
|
||||||
|
{
|
||||||
|
int key = Crc::GenerateCRCFromString(stringKey);
|
||||||
|
LookupTable<_V>::FlushItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
LookupTableDestroyer<_V>::LookupTableDestroyer(LookupTable<_V> *pTable)
|
||||||
|
{
|
||||||
|
mp_table = pTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> inline
|
||||||
|
void LookupTableDestroyer<_V>::DeleteTableContents()
|
||||||
|
{
|
||||||
|
int num_items = mp_table->getSize();
|
||||||
|
|
||||||
|
for (int i = 0; i < num_items; i++)
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
// since we are flushing items out of the table as we go,
|
||||||
|
// we should always grab the first one
|
||||||
|
_V *pItem = mp_table->GetItemByIndex(0, &key);
|
||||||
|
mp_table->FlushItem(key);
|
||||||
|
if (pItem) delete pItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_LOOKUPTABLE_H
|
||||||
|
|
||||||
|
|
158
Code/Core/Math/Xbox/sse.h
Normal file
158
Code/Core/Math/Xbox/sse.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// File: SSE.h
|
||||||
|
//
|
||||||
|
// Desc: P3 SSE conversions and estimates
|
||||||
|
//
|
||||||
|
// Hist: 1.7.03 - Created
|
||||||
|
//
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef P3_SSE
|
||||||
|
#define P3_SSE
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: Ftoi_ASM
|
||||||
|
// Desc: SSE float to int conversion. Note that no control word needs to be
|
||||||
|
// set to round down
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline int Ftoi_ASM( const float f )
|
||||||
|
{
|
||||||
|
__asm cvttss2si eax, f // return int(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: ReciprocalEstimate_ASM
|
||||||
|
// Desc: SSE reciprocal estimate, accurate to 12 significant bits of
|
||||||
|
// the mantissa
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline float ReciprocalEstimate_ASM( const float f )
|
||||||
|
{
|
||||||
|
float rec;
|
||||||
|
__asm rcpss xmm0, f // xmm0 = rcpss(f)
|
||||||
|
__asm movss rec , xmm0 // return xmm0
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: ReciprocalSqrtEstimate_ASM
|
||||||
|
// Desc: SSE reciprocal square root estimate, accurate to 12 significant
|
||||||
|
// bits of the mantissa
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline float ReciprocalSqrtEstimate_ASM( const float f )
|
||||||
|
{
|
||||||
|
float recsqrt;
|
||||||
|
__asm rsqrtss xmm0, f // xmm0 = rsqrtss(f)
|
||||||
|
__asm movss recsqrt, xmm0 // return xmm0
|
||||||
|
return recsqrt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: SqrtEstimae_ASM
|
||||||
|
// Desc: SSE square root estimate, accurate to 12 significant bits of
|
||||||
|
// the mantissa. Note that a check for zero must be made since
|
||||||
|
// sqrt(0) == 0 but 1/sqrt(0) = inf
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline float SqrtEstimate_ASM( const float f )
|
||||||
|
{
|
||||||
|
float recsqrt;
|
||||||
|
__asm movss xmm0,f // xmm0 = f
|
||||||
|
__asm rsqrtss xmm1, xmm0 // xmm1 = rsqrtss(f)
|
||||||
|
__asm mulss xmm1, xmm0 // xmm1 = rsqrtss(f) * f = sqrt(f)
|
||||||
|
__asm xorps xmm2, xmm2 // xmm2 = 0
|
||||||
|
__asm cmpneqss xmm2, xmm0 // xmm2 = (f != 0 ? 1s : 0s)
|
||||||
|
__asm andps xmm1, xmm2 // xmm1 = xmm1 & xmm2
|
||||||
|
__asm movss recsqrt, xmm1 // return xmm1
|
||||||
|
return recsqrt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: ReciprocalEstimateNR_ASM
|
||||||
|
// Desc: SSE Newton-Raphson reciprocal estimate, accurate to 23 significant
|
||||||
|
// bits of the mantissa
|
||||||
|
// One Newtown-Raphson Iteration:
|
||||||
|
// f(i+1) = 2 * rcpss(f) - f * rcpss(f) * rcpss(f)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline float ReciprocalEstimateNR_ASM( const float f )
|
||||||
|
{
|
||||||
|
float rec;
|
||||||
|
__asm rcpss xmm0, f // xmm0 = rcpss(f)
|
||||||
|
__asm movss xmm1, f // xmm1 = f
|
||||||
|
__asm mulss xmm1, xmm0 // xmm1 = f * rcpss(f)
|
||||||
|
__asm mulss xmm1, xmm0 // xmm2 = f * rcpss(f) * rcpss(f)
|
||||||
|
__asm addss xmm0, xmm0 // xmm0 = 2 * rcpss(f)
|
||||||
|
__asm subss xmm0, xmm1 // xmm0 = 2 * rcpss(f)
|
||||||
|
// - f * rcpss(f) * rcpss(f)
|
||||||
|
__asm movss rec, xmm0 // return xmm0
|
||||||
|
return rec;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Newton-Rapson square root iteration constants
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
const float g_SqrtNRConst[2] = {0.5f, 3.0f};
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: ReciprocalSqrtEstimateNR_ASM
|
||||||
|
// Desc: SSE Newton-Raphson reciprocal square root estimate, accurate to 23
|
||||||
|
// significant bits of the mantissa
|
||||||
|
// One Newtown-Raphson Iteration:
|
||||||
|
// f(i+1) = 0.5 * rsqrtss(f) * (3.0 - (f * rsqrtss(f) * rsqrtss(f))
|
||||||
|
// NOTE: rsqrtss(f) * rsqrtss(f) != rcpss(f) (presision is not maintained)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline float ReciprocalSqrtEstimateNR_ASM( const float f )
|
||||||
|
{
|
||||||
|
float recsqrt;
|
||||||
|
__asm rsqrtss xmm0, f // xmm0 = rsqrtss(f)
|
||||||
|
__asm movss xmm1, f // xmm1 = f
|
||||||
|
__asm mulss xmm1, xmm0 // xmm1 = f * rsqrtss(f)
|
||||||
|
__asm movss xmm2, g_SqrtNRConst+4 // xmm2 = 3.0f
|
||||||
|
__asm mulss xmm1, xmm0 // xmm1 = f * rsqrtss(f) * rsqrtss(f)
|
||||||
|
__asm mulss xmm0, g_SqrtNRConst // xmm0 = 0.5f * rsqrtss(f)
|
||||||
|
__asm subss xmm2, xmm1 // xmm2 = 3.0f -
|
||||||
|
// f * rsqrtss(f) * rsqrtss(f)
|
||||||
|
__asm mulss xmm0, xmm2 // xmm0 = 0.5 * rsqrtss(f)
|
||||||
|
// * (3.0 - (f * rsqrtss(f) * rsqrtss(f))
|
||||||
|
__asm movss recsqrt, xmm0 // return xmm0
|
||||||
|
return recsqrt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Name: SqrtEstimateNR_ASM
|
||||||
|
// Desc: SSE Newton-Raphson square root estimate, accurate to 23 significant
|
||||||
|
// bits of the mantissa
|
||||||
|
// NOTE: x/sqrt(x) = sqrt(x)
|
||||||
|
// One Newtown-Raphson Iteration (for 1/sqrt(x)) :
|
||||||
|
// f(i+1) = 0.5 * rsqrtss(f) * (3.0 - (f * rsqrtss(f) * rsqrtss(f))
|
||||||
|
// NOTE: rsqrtss(f) * rsqrtss(f) != rcpss(f) (presision is not maintained)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
__forceinline float SqrtEstimateNR_ASM( const float f )
|
||||||
|
{
|
||||||
|
float recsqrt;
|
||||||
|
__asm rsqrtss xmm0, f // xmm0 = rsqrtss(f)
|
||||||
|
__asm movss xmm1, f // xmm1 = f
|
||||||
|
__asm mulss xmm1, xmm0 // xmm1 = f * rsqrtss(f)
|
||||||
|
__asm movss xmm2, g_SqrtNRConst+4 // xmm2 = 3.0f
|
||||||
|
__asm mulss xmm1, xmm0 // xmm1 = f * rsqrtss(f) * rsqrtss(f)
|
||||||
|
__asm mulss xmm0, g_SqrtNRConst // xmm0 = 0.5f * rsqrtss(f)
|
||||||
|
__asm subss xmm2, xmm1 // xmm2 = 3.0f -
|
||||||
|
// f * rsqrtss(f) * rsqrtss(f)
|
||||||
|
__asm mulss xmm0, xmm2 // xmm0 = 0.5 * rsqrtss(f)
|
||||||
|
// * (3.0 - (f * rsqrtss(f) * rsqrtss(f))
|
||||||
|
__asm xorps xmm1, xmm1 // xmm1 = 0
|
||||||
|
__asm mulss xmm0, f // xmm0 = sqrt(f)
|
||||||
|
__asm cmpneqss xmm1, f // xmm1 = (f != 0 ? 1s : 0s)
|
||||||
|
__asm andps xmm0, xmm1 // xmm0 = xmm1 & xmm2
|
||||||
|
__asm movss recsqrt, xmm0 // return xmm0
|
||||||
|
return recsqrt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // P3_SSE
|
562
Code/Core/Math/geometry.cpp
Normal file
562
Code/Core/Math/geometry.cpp
Normal file
@ -0,0 +1,562 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Geometry (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: Geometry.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 11/14/00 - Mick **
|
||||||
|
** **
|
||||||
|
** Description: Math **
|
||||||
|
// This module handles the representation and manipulation of line segements
|
||||||
|
// and planes
|
||||||
|
//
|
||||||
|
// a line segment (Mth::Line) is defined by two points, m_start and m_end
|
||||||
|
//
|
||||||
|
// a plane is defined by a point and a normal
|
||||||
|
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/math.h>
|
||||||
|
#include <core/math/geometry.h>
|
||||||
|
|
||||||
|
#include <gfx/debuggfx.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Line::Line()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Line::Line ( const Vector &start, const Vector &end )
|
||||||
|
{
|
||||||
|
m_start = start;
|
||||||
|
m_end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
Plane::Plane()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Plane::Plane (const Vector &point, const Vector &normal)
|
||||||
|
{
|
||||||
|
m_point = point;
|
||||||
|
m_normal = normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle::Rectangle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle::Rectangle ( const Vector& corner, const Vector& first_edge, const Vector& second_edge )
|
||||||
|
{
|
||||||
|
m_corner = corner;
|
||||||
|
m_first_edge = first_edge;
|
||||||
|
m_second_edge = second_edge;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate the line segment PaPb that is the shortest route between
|
||||||
|
two lines P1P2 and P3P4. Calculate also the values of mua and mub where
|
||||||
|
Pa = P1 + mua (P2 - P1)
|
||||||
|
Pb = P3 + mub (P4 - P3)
|
||||||
|
Return FALSE if no solution exists.
|
||||||
|
original algorithm from http://www.swin.edu.au/astronomy/pbourke/geometry/lineline3d/
|
||||||
|
note that I (Mick) modified it to clamp the points to within the line segments
|
||||||
|
if you remove the "Clamp" calls below, then the lines will be assumed to be
|
||||||
|
of infinite length
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EPS 0.00001f
|
||||||
|
|
||||||
|
bool LineLineIntersect( Line & l1, Line & l2, Vector *pa, Vector *pb, float *mua, float *mub, bool clamp )
|
||||||
|
{
|
||||||
|
|
||||||
|
Vector &p1 = l1.m_start;
|
||||||
|
Vector &p2 = l1.m_end;
|
||||||
|
Vector &p3 = l2.m_start;
|
||||||
|
Vector &p4 = l2.m_end;
|
||||||
|
|
||||||
|
Vector p13,p43,p21;
|
||||||
|
|
||||||
|
float d1343,d4321,d1321,d4343,d2121;
|
||||||
|
float numer,denom;
|
||||||
|
|
||||||
|
p13 = p1 - p3;
|
||||||
|
p43 = p4 - p3;
|
||||||
|
|
||||||
|
if (Abs(p43[X]) < EPS && Abs(p43[Y]) < EPS && Abs(p43[Z]) < EPS)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
p21 = p2 - p1;
|
||||||
|
|
||||||
|
if (Abs(p21[X]) < EPS && Abs(p21[Y]) < EPS && Abs(p21[Z]) < EPS)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
d1343 = DotProduct(p13,p43);
|
||||||
|
d4321 = DotProduct(p43,p21);
|
||||||
|
d1321 = DotProduct(p13,p21);
|
||||||
|
d4343 = DotProduct(p43,p43);
|
||||||
|
d2121 = DotProduct(p21,p21);
|
||||||
|
|
||||||
|
denom = d2121 * d4343 - d4321 * d4321;
|
||||||
|
if (Abs(denom) < EPS)
|
||||||
|
return(false);
|
||||||
|
numer = d1343 * d4321 - d1321 * d4343;
|
||||||
|
|
||||||
|
*mua = numer / denom;
|
||||||
|
if( clamp )
|
||||||
|
{
|
||||||
|
*mua = Clamp(*mua,0.0f,1.0f);
|
||||||
|
}
|
||||||
|
*mub = (d1343 + d4321 * (*mua)) / d4343;
|
||||||
|
|
||||||
|
if( clamp )
|
||||||
|
{
|
||||||
|
*mub = Clamp(*mub,0.0f,1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
*pa = p1 + (*mua * p21);
|
||||||
|
*pb = p3 + (*mub * p43);
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
CBBox::CBBox()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
CBBox::CBBox(const Vector &point)
|
||||||
|
{
|
||||||
|
Set(point, point);
|
||||||
|
}
|
||||||
|
|
||||||
|
CBBox::CBBox(const Vector &min, const Vector &max)
|
||||||
|
{
|
||||||
|
Set(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBBox::AddPoint(const Vector &point)
|
||||||
|
{
|
||||||
|
// Adjust min/max points
|
||||||
|
if (point[X] < m_min[X])
|
||||||
|
m_min[X] = point[X];
|
||||||
|
if (point[Y] < m_min[Y])
|
||||||
|
m_min[Y] = point[Y];
|
||||||
|
if (point[Z] < m_min[Z])
|
||||||
|
m_min[Z] = point[Z];
|
||||||
|
|
||||||
|
if (point[X] > m_max[X])
|
||||||
|
m_max[X] = point[X];
|
||||||
|
if (point[Y] > m_max[Y])
|
||||||
|
m_max[Y] = point[Y];
|
||||||
|
if (point[Z] > m_max[Z])
|
||||||
|
m_max[Z] = point[Z];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns number of axes within and flags for which ones
|
||||||
|
int CBBox::WithinAxes(const Vector &point, uint32 &axis_flags) const
|
||||||
|
{
|
||||||
|
int number_of_axes = 0;
|
||||||
|
axis_flags = 0;
|
||||||
|
|
||||||
|
if ((point[X] >= m_min[X]) && (point[X] <= m_max[X]))
|
||||||
|
{
|
||||||
|
number_of_axes++;
|
||||||
|
axis_flags |= 1 << X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((point[Y] >= m_min[Y]) && (point[Y] <= m_max[Y]))
|
||||||
|
{
|
||||||
|
number_of_axes++;
|
||||||
|
axis_flags |= 1 << Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((point[Z] >= m_min[Z]) && (point[Z] <= m_max[Z]))
|
||||||
|
{
|
||||||
|
number_of_axes++;
|
||||||
|
axis_flags |= 1 << Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
return number_of_axes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBBox::DebugRender(uint32 rgba, int frames) const
|
||||||
|
{
|
||||||
|
// Min YZ square
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_min[Y],m_min[Z]),Mth::Vector(m_min[X],m_min[Y],m_max[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_min[Y],m_max[Z]),Mth::Vector(m_min[X],m_max[Y],m_max[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_max[Y],m_max[Z]),Mth::Vector(m_min[X],m_max[Y],m_min[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_max[Y],m_min[Z]),Mth::Vector(m_min[X],m_min[Y],m_min[Z]),rgba,rgba,frames);
|
||||||
|
|
||||||
|
// Max YZ square
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_max[X],m_min[Y],m_min[Z]),Mth::Vector(m_max[X],m_min[Y],m_max[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_max[X],m_min[Y],m_max[Z]),Mth::Vector(m_max[X],m_max[Y],m_max[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_max[X],m_max[Y],m_max[Z]),Mth::Vector(m_max[X],m_max[Y],m_min[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_max[X],m_max[Y],m_min[Z]),Mth::Vector(m_max[X],m_min[Y],m_min[Z]),rgba,rgba,frames);
|
||||||
|
|
||||||
|
// lines joining corners
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_min[Y],m_min[Z]),Mth::Vector(m_max[X],m_min[Y],m_min[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_min[Y],m_max[Z]),Mth::Vector(m_max[X],m_min[Y],m_max[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_max[Y],m_max[Z]),Mth::Vector(m_max[X],m_max[Y],m_max[Z]),rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(Mth::Vector(m_min[X],m_max[Y],m_min[Z]),Mth::Vector(m_max[X],m_max[Y],m_min[Z]),rgba,rgba,frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBBox::DebugRender(const Mth::Matrix & transform, uint32 rgba, int frames) const
|
||||||
|
{
|
||||||
|
uint32 rgba_min = 0xFF000080;
|
||||||
|
uint32 rgba_max = 0x0000FF80;
|
||||||
|
|
||||||
|
Mth::Vector min_yz_1(m_min[X], m_min[Y], m_min[Z]);
|
||||||
|
Mth::Vector min_yz_2(m_min[X], m_min[Y], m_max[Z]);
|
||||||
|
Mth::Vector min_yz_3(m_min[X], m_max[Y], m_max[Z]);
|
||||||
|
Mth::Vector min_yz_4(m_min[X], m_max[Y], m_min[Z]);
|
||||||
|
|
||||||
|
Mth::Vector max_yz_1(m_max[X], m_min[Y], m_min[Z]);
|
||||||
|
Mth::Vector max_yz_2(m_max[X], m_min[Y], m_max[Z]);
|
||||||
|
Mth::Vector max_yz_3(m_max[X], m_max[Y], m_max[Z]);
|
||||||
|
Mth::Vector max_yz_4(m_max[X], m_max[Y], m_min[Z]);
|
||||||
|
|
||||||
|
// Transform
|
||||||
|
min_yz_1 = transform.Transform(min_yz_1);
|
||||||
|
min_yz_2 = transform.Transform(min_yz_2);
|
||||||
|
min_yz_3 = transform.Transform(min_yz_3);
|
||||||
|
min_yz_4 = transform.Transform(min_yz_4);
|
||||||
|
|
||||||
|
max_yz_1 = transform.Transform(max_yz_1);
|
||||||
|
max_yz_2 = transform.Transform(max_yz_2);
|
||||||
|
max_yz_3 = transform.Transform(max_yz_3);
|
||||||
|
max_yz_4 = transform.Transform(max_yz_4);
|
||||||
|
|
||||||
|
// Min YZ square
|
||||||
|
Gfx::AddDebugLine(min_yz_1, min_yz_2,rgba_min,rgba_min,frames);
|
||||||
|
Gfx::AddDebugLine(min_yz_2, min_yz_3,rgba_min,rgba_min,frames);
|
||||||
|
Gfx::AddDebugLine(min_yz_3, min_yz_4,rgba_min,rgba_min,frames);
|
||||||
|
Gfx::AddDebugLine(min_yz_4, min_yz_1,rgba_min,rgba_min,frames);
|
||||||
|
|
||||||
|
// Max YZ square
|
||||||
|
Gfx::AddDebugLine(max_yz_1, max_yz_2,rgba_max,rgba_max,frames);
|
||||||
|
Gfx::AddDebugLine(max_yz_2, max_yz_3,rgba_max,rgba_max,frames);
|
||||||
|
Gfx::AddDebugLine(max_yz_3, max_yz_4,rgba_max,rgba_max,frames);
|
||||||
|
Gfx::AddDebugLine(max_yz_4, max_yz_1,rgba_max,rgba_max,frames);
|
||||||
|
|
||||||
|
// lines joining corners
|
||||||
|
Gfx::AddDebugLine(min_yz_1, max_yz_1,rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(min_yz_2, max_yz_2,rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(min_yz_3, max_yz_3,rgba,rgba,frames);
|
||||||
|
Gfx::AddDebugLine(min_yz_4, max_yz_4,rgba,rgba,frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBBox::LineIntersect( const Mth::Line &line, Mth::Vector &point, Mth::Vector &normal ) const
|
||||||
|
{
|
||||||
|
bool start_point_within = Within(line.m_start);
|
||||||
|
bool end_point_within = Within(line.m_end);
|
||||||
|
|
||||||
|
// Doesn't intersect side if both points within
|
||||||
|
if (start_point_within && end_point_within)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trivial rejection.
|
||||||
|
if ((line.m_start[Y] > m_max[Y]) && (line.m_end[Y] > m_max[Y])) return false;
|
||||||
|
if ((line.m_start[Y] < m_min[Y]) && (line.m_end[Y] < m_min[Y])) return false;
|
||||||
|
if ((line.m_start[X] > m_max[X]) && (line.m_end[X] > m_max[X])) return false;
|
||||||
|
if ((line.m_start[X] < m_min[X]) && (line.m_end[X] < m_min[X])) return false;
|
||||||
|
if ((line.m_start[Z] > m_max[Z]) && (line.m_end[Z] > m_max[Z])) return false;
|
||||||
|
if ((line.m_start[Z] < m_min[Z]) && (line.m_end[Z] < m_min[Z])) return false;
|
||||||
|
|
||||||
|
float dx = line.m_end[X] - line.m_start[X];
|
||||||
|
float dy = line.m_end[Y] - line.m_start[Y];
|
||||||
|
float dz = line.m_end[Z] - line.m_start[Z];
|
||||||
|
|
||||||
|
// avoid divide by zeros.
|
||||||
|
if ( !dx )
|
||||||
|
{
|
||||||
|
dx = ( 0.000001f );
|
||||||
|
}
|
||||||
|
if ( !dy )
|
||||||
|
{
|
||||||
|
dy = ( 0.000001f );
|
||||||
|
}
|
||||||
|
if ( !dz )
|
||||||
|
{
|
||||||
|
dz = ( 0.000001f );
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Garrett: I back-face cull 3 of the sides to reduce the calculations and keep
|
||||||
|
// the collisions down to one side.
|
||||||
|
|
||||||
|
// Check the max-x face.
|
||||||
|
if (line.m_start[X] > m_max[X] && line.m_end[X] < m_max[X] && (dx < 0.0f))
|
||||||
|
{
|
||||||
|
// It crosses the plane of the face, so calculate the y & z coords
|
||||||
|
// of the intersection and see if they are in the face,
|
||||||
|
float d=m_max[X] - line.m_start[X];
|
||||||
|
float y=d*dy/dx + line.m_start[Y];
|
||||||
|
float z=d*dz/dx + line.m_start[Z];
|
||||||
|
if (y < m_max[Y] && y > m_min[Y] && z < m_max[Z] && z > m_min[Z])
|
||||||
|
{
|
||||||
|
// It does collide!
|
||||||
|
point = Mth::Vector(m_max[X], y, z, 1.0f);
|
||||||
|
normal = Mth::Vector(1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the min-x face.
|
||||||
|
if (line.m_start[X] < m_min[X] && line.m_end[X] > m_min[X] && (dx > 0.0f))
|
||||||
|
{
|
||||||
|
// It crosses the plane of the face, so calculate the y & z coords
|
||||||
|
// of the intersection and see if they are in the face,
|
||||||
|
float d=m_min[X] - line.m_start[X];
|
||||||
|
float y=d*dy/dx + line.m_start[Y];
|
||||||
|
float z=d*dz/dx + line.m_start[Z];
|
||||||
|
if (y < m_max[Y] && y > m_min[Y] && z < m_max[Z] && z > m_min[Z])
|
||||||
|
{
|
||||||
|
// It does collide!
|
||||||
|
point = Mth::Vector(m_min[X], y, z, 1.0f);
|
||||||
|
normal = Mth::Vector(-1.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the max-y face.
|
||||||
|
if (line.m_start[Y] > m_max[Y] && line.m_end[Y] < m_max[Y] && (dy < 0.0f))
|
||||||
|
{
|
||||||
|
// It crosses the plane of the face, so calculate the x & z coords
|
||||||
|
// of the intersection and see if they are in the face,
|
||||||
|
float d=m_max[Y] - line.m_start[Y];
|
||||||
|
float x=d*dx/dy + line.m_start[X];
|
||||||
|
float z=d*dz/dy + line.m_start[Z];
|
||||||
|
if (x < m_max[X] && x > m_min[X] && z < m_max[Z] && z > m_min[Z])
|
||||||
|
{
|
||||||
|
// It does collide!
|
||||||
|
point = Mth::Vector(x, m_max[Y], z, 1.0f);
|
||||||
|
normal = Mth::Vector(0.0f, 1.0f, 0.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the min-y face.
|
||||||
|
if (line.m_start[Y] < m_min[Y] && line.m_end[Y] > m_min[Y] && (dy > 0.0f))
|
||||||
|
{
|
||||||
|
// It crosses the plane of the face, so calculate the x & z coords
|
||||||
|
// of the intersection and see if they are in the face,
|
||||||
|
float d=m_min[Y] - line.m_start[Y];
|
||||||
|
float x=d*dx/dy + line.m_start[X];
|
||||||
|
float z=d*dz/dy + line.m_start[Z];
|
||||||
|
if (x < m_max[X] && x > m_min[X] && z < m_max[Z] && z > m_min[Z])
|
||||||
|
{
|
||||||
|
// It does collide!
|
||||||
|
point = Mth::Vector(x, m_min[Y], z, 1.0f);
|
||||||
|
normal = Mth::Vector(0.0f, -1.0f, 0.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the max-z face.
|
||||||
|
if (line.m_start[Z] > m_max[Z] && line.m_end[Z] < m_max[Z] && (dz < 0.0f))
|
||||||
|
{
|
||||||
|
// It crosses the plane of the face, so calculate the x & y coords
|
||||||
|
// of the intersection and see if they are in the face,
|
||||||
|
float d=m_max[Z] - line.m_start[Z];
|
||||||
|
float x=d*dx/dz + line.m_start[X];
|
||||||
|
float y=d*dy/dz + line.m_start[Y];
|
||||||
|
if (x < m_max[X] && x > m_min[X] && y < m_max[Y] && y > m_min[Y])
|
||||||
|
{
|
||||||
|
// It does collide!
|
||||||
|
point = Mth::Vector(x, y, m_max[Z], 1.0f);
|
||||||
|
normal = Mth::Vector(0.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check the min-z face.
|
||||||
|
if (line.m_start[Z] < m_min[Z] && line.m_end[Z] > m_min[Z] && (dz > 0.0f))
|
||||||
|
{
|
||||||
|
// It crosses the plane of the face, so calculate the x & y coords
|
||||||
|
// of the intersection and see if they are in the face,
|
||||||
|
float d=m_min[Z] - line.m_start[Z];
|
||||||
|
float x=d*dx/dz + line.m_start[X];
|
||||||
|
float y=d*dy/dz + line.m_start[Y];
|
||||||
|
if (x < m_max[X] && x > m_min[X] && y < m_max[Y] && y > m_min[Y])
|
||||||
|
{
|
||||||
|
// It does collide!
|
||||||
|
point = Mth::Vector(x, y, m_min[Z], 1.0f);
|
||||||
|
normal = Mth::Vector(0.0f, 0.0f, -1.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBBox::GetClosestIntersectPoint(const Mth::Vector &pos, Mth::Vector &point) const
|
||||||
|
{
|
||||||
|
uint32 axes_within_flags;
|
||||||
|
int axes_within = WithinAxes(pos, axes_within_flags);
|
||||||
|
|
||||||
|
if (axes_within == 3)
|
||||||
|
{
|
||||||
|
float closest_dist = -1.0f;
|
||||||
|
int closest_axis = -1;
|
||||||
|
float closest_axis_coord = 0.0f; // Value of the minimum axis coordinate
|
||||||
|
|
||||||
|
// Find the closest rectangle and move the point to that rectangle to find the intersection
|
||||||
|
// point.
|
||||||
|
for (int axis = X; axis <= Z; axis++)
|
||||||
|
{
|
||||||
|
float min_to_pos_dist = pos[axis] - m_min[axis];
|
||||||
|
float max_to_pos_dist = m_max[axis] - pos[axis];
|
||||||
|
|
||||||
|
Dbg_Assert(min_to_pos_dist >= 0.0f);
|
||||||
|
Dbg_Assert(max_to_pos_dist >= 0.0f);
|
||||||
|
|
||||||
|
float min_dist;
|
||||||
|
float min_coord;
|
||||||
|
|
||||||
|
// Figure out the closest distance
|
||||||
|
if (min_to_pos_dist < max_to_pos_dist)
|
||||||
|
{
|
||||||
|
min_dist = min_to_pos_dist;
|
||||||
|
min_coord = m_min[axis];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min_dist = max_to_pos_dist;
|
||||||
|
min_coord = m_max[axis];
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if this is the first axis or if this one is closer
|
||||||
|
if ((axis == X) || (min_dist < closest_dist))
|
||||||
|
{
|
||||||
|
closest_axis = axis;
|
||||||
|
closest_dist = min_dist;
|
||||||
|
closest_axis_coord = min_coord;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_Assert((closest_axis >= X) && (closest_axis <= Z));
|
||||||
|
Dbg_Assert(closest_dist >= 0.0f);
|
||||||
|
|
||||||
|
// Calc the intersection point
|
||||||
|
point = pos; // Start with position
|
||||||
|
point[closest_axis] = closest_axis_coord;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int print_now;
|
||||||
|
if ((print_now++ % 60) == 0)
|
||||||
|
{
|
||||||
|
Dbg_Message("Closest axis %d, (min - max) pos (%f - %f) %f, closest dist %f, closest coord %f", closest_axis,
|
||||||
|
m_min[closest_axis], m_max[closest_axis], pos[closest_axis], closest_dist, closest_axis_coord);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
point[W] = 1.0f; // Homogeneous
|
||||||
|
|
||||||
|
// Go through each axis. If the pos coordinate is between the min and max, use that
|
||||||
|
// coordinate. Otherwise, use the min or max coordinate that is closest.
|
||||||
|
for (int axis = X; axis <= Z; axis++)
|
||||||
|
{
|
||||||
|
if (axes_within_flags & (1 << axis))
|
||||||
|
{
|
||||||
|
// Within, use pos coord
|
||||||
|
point[axis] = pos[axis];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Figure out which end we need
|
||||||
|
if (pos[axis] <= m_min[axis])
|
||||||
|
{
|
||||||
|
point[axis] = m_min[axis];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
point[axis] = m_max[axis];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
354
Code/Core/Math/geometry.h
Normal file
354
Code/Core/Math/geometry.h
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/geometry.h **
|
||||||
|
** **
|
||||||
|
** Created: 11/29/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Vector Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_GEOMETRY_H
|
||||||
|
#define __CORE_MATH_GEOMETRY_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/math.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: Vector
|
||||||
|
*
|
||||||
|
* Description: Vector math class
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class Plane;
|
||||||
|
|
||||||
|
class Line
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
friend class Plane;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Line();
|
||||||
|
Line ( const Vector &start, const Vector &end );
|
||||||
|
// Line& operator+= ( const Vector& v );
|
||||||
|
|
||||||
|
inline void MirrorAboutStart();
|
||||||
|
inline void FlipDirection();
|
||||||
|
|
||||||
|
bool operator== ( const Line& l ) const;
|
||||||
|
bool operator!= ( const Line& l ) const;
|
||||||
|
Line& operator+= ( const Vector& v );
|
||||||
|
Line& operator-= ( const Vector& v );
|
||||||
|
|
||||||
|
float Length() const {return (m_end-m_start).Length();}
|
||||||
|
|
||||||
|
Vector m_start, m_end;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Plane
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
friend class Line;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Plane();
|
||||||
|
Plane (const Vector &point, const Vector &normal);
|
||||||
|
Vector m_point, m_normal;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class Rectangle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Rectangle ( );
|
||||||
|
Rectangle ( const Vector& corner, const Vector& first_edge, const Vector& second_edge );
|
||||||
|
Vector m_corner, m_first_edge, m_second_edge;
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: CBBox
|
||||||
|
*
|
||||||
|
* Description: Axis-aligned Bounding Box
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class CBBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
CBBox();
|
||||||
|
CBBox(const Vector &point);
|
||||||
|
CBBox(const Vector &min, const Vector &max);
|
||||||
|
|
||||||
|
//
|
||||||
|
inline void Set(const Vector &min, const Vector &max);
|
||||||
|
inline void Reset();
|
||||||
|
|
||||||
|
//
|
||||||
|
inline const Vector &GetMin() const;
|
||||||
|
inline const Vector &GetMax() const;
|
||||||
|
inline void SetMin(const Vector &min);
|
||||||
|
inline void SetMax(const Vector &max);
|
||||||
|
|
||||||
|
//
|
||||||
|
void AddPoint(const Vector &point);
|
||||||
|
inline bool Intersect(const CBBox &bbox) const;
|
||||||
|
inline bool CouldIntersect(const Vector &v0, const Vector &v1, const Vector &v2) const; // Intersect w/ triangle
|
||||||
|
inline bool Within(const Vector &point) const;
|
||||||
|
inline bool Within(const CBBox &bbox) const;
|
||||||
|
int WithinAxes(const Vector &point, uint32 &axis_flags) const; // Returns number of axes within and flags for which ones
|
||||||
|
|
||||||
|
// Checks to see if the line intersects any of the sides
|
||||||
|
bool LineIntersect( const Mth::Line &line, Mth::Vector &point, Mth::Vector &normal ) const;
|
||||||
|
|
||||||
|
// Finds the closest point on the bounding box to a position
|
||||||
|
void GetClosestIntersectPoint(const Mth::Vector &pos, Mth::Vector &point) const;
|
||||||
|
|
||||||
|
void DebugRender(uint32 rgba, int frames = 0) const;
|
||||||
|
void DebugRender(const Mth::Matrix & transform, uint32 rgba, int frames = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//
|
||||||
|
Vector m_min, m_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
bool LineLineIntersect( Line & l1, Line & l2, Vector *pa, Vector *pb, float *mua, float *mub, bool clamp = true );
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool Line::operator== ( const Line& l ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return ( m_start == l.m_start) && ( m_end == l.m_end );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool Line::operator!= ( const Line& l ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return !( *this == l );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Line& Line::operator+= ( const Vector& v )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_start += v;
|
||||||
|
m_end += v;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Line& Line::operator-= ( const Vector& v )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_start -= v;
|
||||||
|
m_end -= v;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// A->B becomes B<-A, where A is unchanged
|
||||||
|
inline void Line::MirrorAboutStart()
|
||||||
|
{
|
||||||
|
m_end = m_start - 2.0f * ( m_end - m_start );
|
||||||
|
}
|
||||||
|
|
||||||
|
// A->B becores B->A (A and B swap positions)
|
||||||
|
inline void Line::FlipDirection()
|
||||||
|
{
|
||||||
|
Mth::Vector temp = m_end;
|
||||||
|
m_end = m_start;
|
||||||
|
m_start = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void CBBox::Reset()
|
||||||
|
{
|
||||||
|
// m_min = Vector( (float)HUGE_VAL, (float)HUGE_VAL, (float)HUGE_VAL);
|
||||||
|
// m_max = Vector((float)-HUGE_VAL, (float)-HUGE_VAL, (float)-HUGE_VAL);
|
||||||
|
m_min = Vector( 10000000.0f, 10000000.0f, 10000000.0f);
|
||||||
|
m_max = Vector(-10000000.0f, -10000000.0f, -10000000.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CBBox::Set(const Vector &min, const Vector &max)
|
||||||
|
{
|
||||||
|
m_min = min;
|
||||||
|
m_max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector &CBBox::GetMin() const
|
||||||
|
{
|
||||||
|
return m_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Vector &CBBox::GetMax() const
|
||||||
|
{
|
||||||
|
return m_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CBBox::SetMin(const Vector &min)
|
||||||
|
{
|
||||||
|
m_min = min;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CBBox::SetMax(const Vector &max)
|
||||||
|
{
|
||||||
|
m_max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for intersection test, we do X and Z first,
|
||||||
|
// as we war aer more likely to be intersecting in the Y
|
||||||
|
// as everyhting is about the same height
|
||||||
|
// so this eliminates thigns quicker
|
||||||
|
inline bool CBBox::Intersect(const CBBox &bbox) const
|
||||||
|
{
|
||||||
|
if ((m_min[X] > bbox.m_max[X]) || (bbox.m_min[X] > m_max[X]) ||
|
||||||
|
(m_min[Z] > bbox.m_max[Z]) || (bbox.m_min[Z] > m_max[Z]) ||
|
||||||
|
(m_min[Y] > bbox.m_max[Y]) || (bbox.m_min[Y] > m_max[Y]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CBBox::Within(const Vector &point) const
|
||||||
|
{
|
||||||
|
return ((point[X] >= m_min[X]) && (point[Y] >= m_min[Y]) && (point[Z] >= m_min[Z]) &&
|
||||||
|
(point[X] <= m_max[X]) && (point[Y] <= m_max[Y]) && (point[Z] <= m_max[Z]));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool CBBox::Within(const CBBox &bbox) const
|
||||||
|
{
|
||||||
|
if ((bbox.m_min[X] >= m_min[X]) && (bbox.m_max[X] <= m_max[X]) &&
|
||||||
|
(bbox.m_min[Y] >= m_min[Y]) && (bbox.m_max[Y] <= m_max[Y]) &&
|
||||||
|
(bbox.m_min[Z] >= m_min[Z]) && (bbox.m_max[Z] <= m_max[Z]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not So Quick & Dirty Intersection w/ Triangle
|
||||||
|
inline bool CBBox::CouldIntersect(const Vector &v0, const Vector &v1, const Vector &v2) const
|
||||||
|
{
|
||||||
|
if ( ( v0[X] > m_max[X] ) &&
|
||||||
|
( v1[X] > m_max[X] ) &&
|
||||||
|
( v2[X] > m_max[X] ) ) return false;
|
||||||
|
if ( ( v0[X] < m_min[X] ) &&
|
||||||
|
( v1[X] < m_min[X] ) &&
|
||||||
|
( v2[X] < m_min[X] ) ) return false;
|
||||||
|
if ( ( v0[Y] > m_max[Y] ) &&
|
||||||
|
( v1[Y] > m_max[Y] ) &&
|
||||||
|
( v2[Y] > m_max[Y] ) ) return false;
|
||||||
|
if ( ( v0[Y] < m_min[Y] ) &&
|
||||||
|
( v1[Y] < m_min[Y] ) &&
|
||||||
|
( v2[Y] < m_min[Y] ) ) return false;
|
||||||
|
if ( ( v0[Z] > m_max[Z] ) &&
|
||||||
|
( v1[Z] > m_max[Z] ) &&
|
||||||
|
( v2[Z] > m_max[Z] ) ) return false;
|
||||||
|
if ( ( v0[Z] < m_min[Z] ) &&
|
||||||
|
( v1[Z] < m_min[Z] ) &&
|
||||||
|
( v2[Z] < m_min[Z] ) ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_GEOMETRY_H
|
||||||
|
|
374
Code/Core/Math/math.cpp
Normal file
374
Code/Core/Math/math.cpp
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: math.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 11/24/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Math Library code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
#include <math.h>
|
||||||
|
#endif
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
#include <math.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/math/math.h>
|
||||||
|
|
||||||
|
#if DEBUGGING_REPLAY_RND
|
||||||
|
|
||||||
|
#include <sys\timer.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
extern int *gReplayTestRndLine;
|
||||||
|
extern uint64 *gReplayTestRndFunc;
|
||||||
|
static int gRndIndex = 0;
|
||||||
|
static int gTestMode = 0;
|
||||||
|
#define MAX_RND_TEST_INDEX 3666
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static int RandSeed;
|
||||||
|
static int RandA;
|
||||||
|
static int RandB;
|
||||||
|
|
||||||
|
static int RandSeed2;
|
||||||
|
static int RandC;
|
||||||
|
static int RandD;
|
||||||
|
|
||||||
|
void InitialRand(int a)
|
||||||
|
{
|
||||||
|
RandSeed = a;
|
||||||
|
RandA = 314159265;
|
||||||
|
RandB = 178453311;
|
||||||
|
RandSeed2 = a;
|
||||||
|
RandC = 314159265;
|
||||||
|
RandD = 178453311;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUGGING_REPLAY_RND
|
||||||
|
|
||||||
|
static bool gFuckedUp = false;
|
||||||
|
|
||||||
|
bool RndFuckedUp( void )
|
||||||
|
{
|
||||||
|
if ( gTestMode != 2 )
|
||||||
|
return ( false );
|
||||||
|
return ( gFuckedUp );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Rnd_DbgVersion(int n, int line, char *file)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( gRndIndex < MAX_RND_TEST_INDEX )
|
||||||
|
{
|
||||||
|
if ( gTestMode == 1 )
|
||||||
|
{
|
||||||
|
// record:
|
||||||
|
gReplayTestRndLine[ gRndIndex ] = line;
|
||||||
|
strncpy( ( char * )( &gReplayTestRndFunc[ gRndIndex ] ), file, 8 );
|
||||||
|
gRndIndex++;
|
||||||
|
}
|
||||||
|
else if ( gTestMode == 2 )
|
||||||
|
{
|
||||||
|
// compare:
|
||||||
|
if ( line != gReplayTestRndLine[ gRndIndex ] )
|
||||||
|
{
|
||||||
|
char temp[ 9 ];
|
||||||
|
strncpy( temp, ( char * )( &gReplayTestRndFunc[ gRndIndex ] ), 8 );
|
||||||
|
temp[ 8 ] = '\0';
|
||||||
|
Dbg_Message( "********Rnd Fuckup!********* num %d time %d\ncurrent line %d file %s conflicts with prev line %d file %s",
|
||||||
|
Tmr::GetTime( ), gRndIndex, line, file, gReplayTestRndLine[ gRndIndex ], temp );
|
||||||
|
gFuckedUp = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gFuckedUp = false;
|
||||||
|
}
|
||||||
|
gRndIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RandSeed=RandSeed*RandA+RandB;
|
||||||
|
RandA = (RandA ^ RandSeed) + (RandSeed>>4);
|
||||||
|
RandB += (RandSeed>>3) - 0x10101010L;
|
||||||
|
return (int)((RandSeed&0xffff) * n)>>16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRndTestMode( int mode )
|
||||||
|
{
|
||||||
|
gTestMode = mode;
|
||||||
|
gRndIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
int Rnd(int n)
|
||||||
|
{
|
||||||
|
RandSeed=RandSeed*RandA+RandB;
|
||||||
|
RandA = (RandA ^ RandSeed) + (RandSeed>>4);
|
||||||
|
RandB += (RandSeed>>3) - 0x10101010L;
|
||||||
|
return (int)((RandSeed&0xffff) * n)>>16;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int Rnd2(int n)
|
||||||
|
{
|
||||||
|
RandSeed2=RandSeed2*RandC+RandD;
|
||||||
|
RandC = (RandC ^ RandSeed2) + (RandSeed2>>4);
|
||||||
|
RandD += (RandSeed2>>3) - 0x10101010L;
|
||||||
|
return (int)((RandSeed2&0xffff) * n)>>16;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a random number in the range +/- n
|
||||||
|
float PlusOrMinus(float n)
|
||||||
|
{
|
||||||
|
float range = (float)(Rnd(10000));
|
||||||
|
range -= 5000.0f;
|
||||||
|
return n * range / 5000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// 8192 makes Kensinf and sinf match to all 6 decimal places, (when x is in the range -2pi to 2pi)
|
||||||
|
// apart from very occassionally where there might be a .000001 difference.
|
||||||
|
// The table size must be a power of two.
|
||||||
|
#define SINF_NUM_DIVISIONS 8192
|
||||||
|
static float pSinLookup[SINF_NUM_DIVISIONS+5]; // +5 for good measure, since sometimes we look one beyond the end.
|
||||||
|
void InitSinLookupTable()
|
||||||
|
{
|
||||||
|
// The lookup table covers a whole period (0 to 2pi) of the sin function.
|
||||||
|
// This saves a few if's in the sin function.
|
||||||
|
for (int i=0; i<SINF_NUM_DIVISIONS+5; ++i)
|
||||||
|
{
|
||||||
|
pSinLookup[i]=sinf(i*2.0f*3.141592654f/SINF_NUM_DIVISIONS); // Mth::PI won't compile for some reason??
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Kensinf(float x)
|
||||||
|
{
|
||||||
|
// Get the index into the table as a floating point value. This value may be negative
|
||||||
|
// or out of bounds of the array, but don't worry about that yet.
|
||||||
|
float r=(x*(SINF_NUM_DIVISIONS/2))/3.141592654f;
|
||||||
|
// Get the integer part.
|
||||||
|
int i=(int)r;
|
||||||
|
// Make r be the fractional part, so that r is a value between 0 and 1 (or 0 and -1)
|
||||||
|
// that indicates how far we are between the two adjacent entries in the table.
|
||||||
|
r-=i;
|
||||||
|
|
||||||
|
// Make i be in range, which can be done with an integer 'and' because the table size
|
||||||
|
// is chosen to be a power of two.
|
||||||
|
// Note that this still works the way we want it to if i is negative.
|
||||||
|
// If i is a certain distance below 0, anding it will map it to that distance below the
|
||||||
|
// end of the table, which is what we want because the lookup table covers a whole
|
||||||
|
// period of the sine function.
|
||||||
|
// (Generally, -x & (n-1) is n-x when n is a power of 2, eg -3&7 = 5 = (8-3) )
|
||||||
|
i&=(SINF_NUM_DIVISIONS-1);
|
||||||
|
|
||||||
|
float *pPoo=pSinLookup+i;
|
||||||
|
|
||||||
|
// Hmmm, the following is technically wrong, it should be -- not ++ for when x is negative.
|
||||||
|
// However, always using ++ does not appear to affect the accuracy at all, so there's no need to fix it!
|
||||||
|
// Doing a -- for when x is negative would mean having to do another if, and yet another to
|
||||||
|
// check in case pPoo points to the first element, yuk.
|
||||||
|
// Using ++ even when x is negative works because the gradient does not change
|
||||||
|
// much between points. When x is negative, r will be negative, and using the next gradient
|
||||||
|
// to move back gives roughly the same answer as using the previous gradient. Wahay!!
|
||||||
|
float a=*pPoo++;
|
||||||
|
float b=*pPoo;
|
||||||
|
return a+(b-a)*r;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Kencosf(float x)
|
||||||
|
{
|
||||||
|
float r=(x*(SINF_NUM_DIVISIONS/2))/3.141592654f;
|
||||||
|
int i=(int)r;
|
||||||
|
r-=i;
|
||||||
|
|
||||||
|
// This is the only difference from Kensinf.
|
||||||
|
i+=(SINF_NUM_DIVISIONS/4); // Add a quarter period.
|
||||||
|
|
||||||
|
i&=(SINF_NUM_DIVISIONS-1);
|
||||||
|
|
||||||
|
float *pPoo=pSinLookup+i;
|
||||||
|
|
||||||
|
float a=*pPoo++;
|
||||||
|
float b=*pPoo;
|
||||||
|
return a+(b-a)*r;
|
||||||
|
/*
|
||||||
|
float sqr = x*x;
|
||||||
|
float result = 0.03705f;
|
||||||
|
result *= sqr;
|
||||||
|
result -= 0.4967;
|
||||||
|
result *= sqr;
|
||||||
|
result += 1.0f;
|
||||||
|
return result;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float Kenacosf(float x)
|
||||||
|
{
|
||||||
|
// Got this formula off the internet, forgot where though ...
|
||||||
|
if (x<0.0f)
|
||||||
|
{
|
||||||
|
x=-x;
|
||||||
|
float root = sqrtf(1.0f-x);
|
||||||
|
|
||||||
|
float result = -0.0187293f;
|
||||||
|
result *= x;
|
||||||
|
result += 0.0742610f;
|
||||||
|
result *= x;
|
||||||
|
result -= 0.2121144f;
|
||||||
|
result *= x;
|
||||||
|
result += 1.5707288f;
|
||||||
|
result *= root;
|
||||||
|
return 3.141592654f-result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float root = sqrtf(1.0f-x);
|
||||||
|
|
||||||
|
float result = -0.0187293f;
|
||||||
|
result *= x;
|
||||||
|
result += 0.0742610f;
|
||||||
|
result *= x;
|
||||||
|
result -= 0.2121144f;
|
||||||
|
result *= x;
|
||||||
|
result += 1.5707288f;
|
||||||
|
result *= root;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float FRunFilter( float target, float current, float delta )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( target < current )
|
||||||
|
{
|
||||||
|
if ( ( current - target ) > fabsf( delta ) )
|
||||||
|
{
|
||||||
|
return ( current - fabsf( delta ) );
|
||||||
|
}
|
||||||
|
return ( target );
|
||||||
|
}
|
||||||
|
if ( ( target - current ) > fabsf( delta ) )
|
||||||
|
{
|
||||||
|
return ( current + fabsf( delta ) );
|
||||||
|
}
|
||||||
|
return ( target );
|
||||||
|
}
|
||||||
|
|
||||||
|
int RunFilter( int target, int current, int delta )
|
||||||
|
{
|
||||||
|
if ( target < current )
|
||||||
|
{
|
||||||
|
if ( current - target > abs( delta ) )
|
||||||
|
return ( target );
|
||||||
|
return ( current - abs( delta ) );
|
||||||
|
}
|
||||||
|
if ( target - current > abs( delta ) )
|
||||||
|
return ( target );
|
||||||
|
return ( current + abs( delta ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns atan(y/x) with appropiate sign determinations
|
||||||
|
// although it does not work, as we cant; find atan .....
|
||||||
|
|
||||||
|
/*
|
||||||
|
float Atan2 (float y, float x)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (x == 0.0f)
|
||||||
|
{
|
||||||
|
if (y < 0.0f) return(-PI/2.0f);
|
||||||
|
|
||||||
|
else return( PI/2.0f);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (x < 0.0f) {
|
||||||
|
if (y < 0.0f)
|
||||||
|
return(atan(y/x)-PI);
|
||||||
|
else
|
||||||
|
return(atan(y/x)+PI);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return(atan(y/x));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
} // namespace Mth
|
473
Code/Core/Math/math.h
Normal file
473
Code/Core/Math/math.h
Normal file
@ -0,0 +1,473 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/math.h **
|
||||||
|
** **
|
||||||
|
** Created: 11/23/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Math Library **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_MATH_H
|
||||||
|
#define __CORE_MATH_MATH_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
#include <math.h> // Required for fabsf().
|
||||||
|
#include <core\math\xbox\sse.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
#include <math.h> // Required for fabsf().
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __USER_MATT__
|
||||||
|
#define DEBUGGING_REPLAY_RND 0
|
||||||
|
#else
|
||||||
|
#define DEBUGGING_REPLAY_RND 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUGGING_REPLAY_RND
|
||||||
|
|
||||||
|
#define Rnd( x ) Rnd_DbgVersion( ( x ), __LINE__, __FILE__ )
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define Rnd( x ) Rnd( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void InitialRand(int a);
|
||||||
|
|
||||||
|
#if DEBUGGING_REPLAY_RND
|
||||||
|
|
||||||
|
int Rnd_DbgVersion(int n, int line, char *file);
|
||||||
|
void SetRndTestMode( int mode );
|
||||||
|
bool RndFuckedUp( void );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int Rnd(int n);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// use for non-deterministic things
|
||||||
|
// especially for CD-timing reliant stuff that would throw off our random number dealy whopper.
|
||||||
|
int Rnd2(int n);
|
||||||
|
|
||||||
|
float PlusOrMinus(float n);
|
||||||
|
void InitSinLookupTable();
|
||||||
|
float Kensinf(float x);
|
||||||
|
float Kencosf(float x);
|
||||||
|
float Kenacosf(float x);
|
||||||
|
float Atan2 (float y, float x); // replaces atan2, much faster
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline int Abs ( int x )
|
||||||
|
{
|
||||||
|
return ( x>=0?x:-x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline float Abs ( float x )
|
||||||
|
{
|
||||||
|
return float ( fabsf ( x ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// round down to nearest whole number
|
||||||
|
inline float Whole ( float x )
|
||||||
|
{
|
||||||
|
return (float) ( (int) ( x ));
|
||||||
|
}
|
||||||
|
|
||||||
|
// round to nearest whole number
|
||||||
|
inline float Round ( float x )
|
||||||
|
{
|
||||||
|
return (float) ( (int) ( x + 0.499999f));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Calculate the "Parabolic Lerp" value for a set of parameters
|
||||||
|
// (Note: made-up name, by Mick)
|
||||||
|
//
|
||||||
|
// A lerp (Linear intERPalotion) value is always in the range 0.0 to 1.0
|
||||||
|
// and is used to move one value (A) towards another (B)
|
||||||
|
// usually the lerp value is fixed.
|
||||||
|
//
|
||||||
|
// A new value C is calculated as C = A + lerp * (B - A)
|
||||||
|
//
|
||||||
|
// a "ParaLerp" is a lerp value that varies based on the distance apart of the two values
|
||||||
|
//
|
||||||
|
// The purpose of this function is to be able to smoothly change a value
|
||||||
|
// that really only needs lerping when the values are within a small range
|
||||||
|
// The result of this equation is a parabolic curve that quickly tends
|
||||||
|
// towards lerp = 1.0, as x increases
|
||||||
|
// The valeu "Rate" is the value of x for which lerp half way between Min and 1.0
|
||||||
|
// Min is the value of lerp when x is 0
|
||||||
|
inline float ParaLerp(float x, float Rate = 1.0f, float Minimum = 0.0f)
|
||||||
|
{
|
||||||
|
float lerp = Minimum + (1 - 1 / (1 + x / Rate) ) * (1 - Minimum);
|
||||||
|
return lerp;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float ClampMin ( float v, float min )
|
||||||
|
{
|
||||||
|
if ( v < min )
|
||||||
|
{
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float ClampMax ( float v, float max )
|
||||||
|
{
|
||||||
|
if ( v > max )
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Clamp ( float v, float min, float max )
|
||||||
|
{
|
||||||
|
return ClampMin ( ClampMax ( v, max ), min );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Lerp ( float a, float b, float value )
|
||||||
|
{
|
||||||
|
return a + ( b - a ) * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float LinearMap ( float a, float b, float value, float value_min, float value_max )
|
||||||
|
{
|
||||||
|
return Lerp(a, b, (value - value_min) / (value_max - value_min));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float SmoothStep ( float value )
|
||||||
|
{
|
||||||
|
// interpolates from zero to one with a zero derivative at the end-points
|
||||||
|
return -2.0f * value * value * ( value - (3.0f / 2.0f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float SmoothInterp ( float a, float b, float value )
|
||||||
|
{
|
||||||
|
return Lerp(a, b, SmoothStep(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float SmoothMap ( float a, float b, float value, float value_min, float value_max )
|
||||||
|
{
|
||||||
|
return Lerp(a, b, SmoothStep((value - value_min) / (value_max - value_min)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Max ( float a, float b )
|
||||||
|
{
|
||||||
|
return ( a > b ) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Min ( float a, float b )
|
||||||
|
{
|
||||||
|
return ( a < b ) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Sgn ( float x )
|
||||||
|
{
|
||||||
|
if ( x < 0.f )
|
||||||
|
{
|
||||||
|
return -1.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Sqr ( float x )
|
||||||
|
{
|
||||||
|
return ( x * x );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Swap ( float& a, float& b )
|
||||||
|
{
|
||||||
|
float t = a;
|
||||||
|
a = b;
|
||||||
|
b = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool Equal ( const float a, const float b, const float perc )
|
||||||
|
{
|
||||||
|
return ( Abs ( a - b ) <= (( Abs ( a ) + Abs ( b )) * perc ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline sint Max ( sint a, sint b )
|
||||||
|
{
|
||||||
|
return ( a > b ) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline sint Min ( sint a, sint b )
|
||||||
|
{
|
||||||
|
return ( a < b ) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Max3 ( float a, float b, float c )
|
||||||
|
{
|
||||||
|
return Max(a, Max(b,c));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Min3 ( float a, float b, float c )
|
||||||
|
{
|
||||||
|
return Min(a, Min(b,c));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Determinant ( float a, float b, float c, float d )
|
||||||
|
{
|
||||||
|
return ( a * d ) - ( b * c );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Determinant3 ( float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3 )
|
||||||
|
{
|
||||||
|
return a1 * (b2 * c3 - b3 * c2) -
|
||||||
|
b1 * (a2 * c3 - a3 * c2) +
|
||||||
|
c1 * (a2 * b3 - a3 * b2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline int WeightedRnd ( float min_val, float max_val )
|
||||||
|
{
|
||||||
|
// This random function uses the West distribution
|
||||||
|
// to return values that favor the midpoint.
|
||||||
|
|
||||||
|
// For example, WeightedRnd( 10, 20 ) returns:
|
||||||
|
// Bucket[10] = 2.12 percent
|
||||||
|
// Bucket[11] = 5.72 percent
|
||||||
|
// Bucket[12] = 9.44 percent
|
||||||
|
// Bucket[13] = 13.87 percent
|
||||||
|
// Bucket[14] = 18.16 percent
|
||||||
|
// Bucket[15] = 15.70 percent
|
||||||
|
// Bucket[16] = 14.52 percent
|
||||||
|
// Bucket[17] = 10.16 percent
|
||||||
|
// Bucket[18] = 6.05 percent
|
||||||
|
// Bucket[19] = 2.26 percent
|
||||||
|
// Bucket[20] = 2.00 percent
|
||||||
|
|
||||||
|
float range = ( max_val - min_val ) / 2;
|
||||||
|
float midpoint = min_val + range;
|
||||||
|
|
||||||
|
float random_val = range - (float)sqrtf((float)Rnd( (int)(range * range) ) );
|
||||||
|
|
||||||
|
// negate it half of the time
|
||||||
|
if ( Rnd(2) )
|
||||||
|
{
|
||||||
|
random_val = -random_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)( random_val + midpoint );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
// Trig
|
||||||
|
|
||||||
|
const float EPSILON = 0.000001f;
|
||||||
|
const float PI = 3.141592654f;
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float DegToRad ( float degrees )
|
||||||
|
{
|
||||||
|
return degrees * ( PI / 180.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float RadToDeg ( float radians )
|
||||||
|
{
|
||||||
|
return radians * ( 180.0f / PI );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int RunFilter( int target, int current, int delta );
|
||||||
|
float FRunFilter( float target, float current, float delta );
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_MATH_H
|
1049
Code/Core/Math/matrix.cpp
Normal file
1049
Code/Core/Math/matrix.cpp
Normal file
File diff suppressed because it is too large
Load Diff
191
Code/Core/Math/matrix.h
Normal file
191
Code/Core/Math/matrix.h
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/Matrix.h **
|
||||||
|
** **
|
||||||
|
** Created: 11/29/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: 4x4 Matrix Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_MATRIX_H
|
||||||
|
#define __CORE_MATH_MATRIX_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RIGHT, UP, AT, POS
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: Matrix
|
||||||
|
*
|
||||||
|
* Description: 4x4 Matrix math class
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class Matrix
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Matrix ( void );
|
||||||
|
Matrix ( const Matrix& src );
|
||||||
|
Matrix ( const Vector& axis, const float angle );
|
||||||
|
Matrix ( int axis, const float angle );
|
||||||
|
Matrix ( float p, float h, float r ); // Euler to Matrix
|
||||||
|
Matrix ( const Mth::Quat& orientaion );
|
||||||
|
|
||||||
|
Matrix& operator= ( const Matrix& src );
|
||||||
|
Matrix& operator+= ( const Matrix& n );
|
||||||
|
Matrix& operator*= ( const Matrix& n );
|
||||||
|
Matrix& operator*= ( const float f );
|
||||||
|
bool operator== ( const Matrix& n ) const;
|
||||||
|
bool operator!= ( const Matrix& n ) const;
|
||||||
|
|
||||||
|
float Determinant ( void ) const;
|
||||||
|
bool IsIdent ( void ) const;
|
||||||
|
Matrix& Ident ( void ); // set to 4x4 identity
|
||||||
|
Matrix& Identity ( void ); // same, but better name
|
||||||
|
Matrix& Zero ( void ); // set to all 0's
|
||||||
|
Matrix& Adjoint ( const Matrix& src );
|
||||||
|
Matrix& Invert ( const Matrix& src ); // this = Invert ( src )
|
||||||
|
Matrix& Invert ( void ); // this = Invert ( this )
|
||||||
|
Matrix& InvertUniform ( void );
|
||||||
|
Matrix& Transpose ( const Matrix& src );
|
||||||
|
Matrix& Transpose ( void );
|
||||||
|
|
||||||
|
Vector Transform ( const Vector& src ) const;
|
||||||
|
Vector TransformAsPos ( const Vector& src ) const;
|
||||||
|
Vector Rotate ( const Vector& src ) const;
|
||||||
|
|
||||||
|
Matrix& OrthoNormalize ( const Matrix& src ); // this = OrthoNornalize ( src )
|
||||||
|
Matrix& OrthoNormalize ( void ); // this = OrthoNormalize ( this )
|
||||||
|
|
||||||
|
void RotateLocal ( const Vector& src );
|
||||||
|
Matrix& Translate ( const Vector& trans );
|
||||||
|
Matrix& TranslateLocal ( const Vector& trans );
|
||||||
|
|
||||||
|
Matrix& Rotate ( const Vector& axis, const float angle );
|
||||||
|
Matrix& RotateLocal ( const Vector& axis, const float angle );
|
||||||
|
Matrix& RotateLocal ( int axis, float angle );
|
||||||
|
Matrix& RotateX ( const float angle );
|
||||||
|
Matrix& RotateXLocal ( const float angle );
|
||||||
|
Matrix& RotateY ( const float angle );
|
||||||
|
Matrix& RotateYLocal ( const float angle );
|
||||||
|
Matrix& RotateZ ( const float angle );
|
||||||
|
Matrix& RotateZLocal ( const float angle );
|
||||||
|
|
||||||
|
Matrix& Scale ( const Vector& scale );
|
||||||
|
Matrix& ScaleLocal ( const Vector& scale );
|
||||||
|
|
||||||
|
Vector& GetRight ( void ) { return *(Vector*)(&row[RIGHT]); }
|
||||||
|
Vector& GetUp ( void ) { return *(Vector*)(&row[UP]); }
|
||||||
|
Vector& GetAt ( void ) { return *(Vector*)(&row[AT]); }
|
||||||
|
Vector& GetPos ( void ) { return *(Vector*)(&row[POS]); }
|
||||||
|
void SetPos ( const Vector& trans );
|
||||||
|
|
||||||
|
|
||||||
|
Matrix& SetColumn ( sint i, const Vector& v );
|
||||||
|
Vector GetColumn ( sint i ) const;
|
||||||
|
const Vector& operator[] ( sint i ) const;
|
||||||
|
Vector& operator[] ( sint i );
|
||||||
|
|
||||||
|
Matrix& OrthoNormalizeAbout(int r0);
|
||||||
|
void PrintContents() const;
|
||||||
|
|
||||||
|
void GetEulers( Vector& euler ) const;
|
||||||
|
void GetRotationAxisAndAngle( Vector* pAxis, float* pRadians );
|
||||||
|
|
||||||
|
bool PatchOrthogonality ( );
|
||||||
|
|
||||||
|
Matrix& SetFromAngles ( const Vector& angles );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NUM_ELEMENTS = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vector row[NUM_ELEMENTS]; // Old style, an array of vectors
|
||||||
|
float row[NUM_ELEMENTS][4]; // New style, an array of float, for constructor optimization
|
||||||
|
|
||||||
|
} nAlign(128);
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
void xsceVu0MulMatrix(Mth::Matrix* m0, Mth::Matrix* m1, const Mth::Matrix* m2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
void Swap ( Matrix& a, Matrix& b );
|
||||||
|
void Slerp ( Matrix& result, const Matrix& s1, const Matrix& s2, float t );
|
||||||
|
Matrix operator* ( const Matrix& m1, const Matrix& m2 );
|
||||||
|
ostream& operator<< ( ostream& os, const Matrix& m );
|
||||||
|
|
||||||
|
Matrix& CreateRotateMatrix ( Matrix& mat, const Vector& axis, const float angle );
|
||||||
|
Matrix& CreateRotateMatrix ( Matrix& mat, int axis, const float angle );
|
||||||
|
Matrix& CreateRotateXMatrix ( Matrix& mat, const float angle );
|
||||||
|
Matrix& CreateRotateYMatrix ( Matrix& mat, const float angle );
|
||||||
|
Matrix& CreateRotateZMatrix ( Matrix& mat, const float angle );
|
||||||
|
Matrix& CreateFromToMatrix( Matrix &mtx, Vector from, Vector to );
|
||||||
|
|
||||||
|
Matrix& CreateMatrixLookAt( Matrix& mat, const Vector& pos, const Vector& lookat, const Vector& up );
|
||||||
|
Matrix& CreateMatrixOrtho( Matrix& mat, float width, float height, float f_near, float f_far );
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_MATRIX_H
|
||||||
|
|
1053
Code/Core/Math/matrix.inl
Normal file
1053
Code/Core/Math/matrix.inl
Normal file
File diff suppressed because it is too large
Load Diff
143
Code/Core/Math/quat.h
Normal file
143
Code/Core/Math/quat.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/Quat.h **
|
||||||
|
** **
|
||||||
|
** Created: 11/23/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Quaternion Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_QUAT_H
|
||||||
|
#define __CORE_MATH_QUAT_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/math/vector.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Matrix; // forward declaration
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: Quat
|
||||||
|
*
|
||||||
|
* Description: Quaternion math class
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class Quat //: public Spt::Class
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
friend bool quat_equal ( const Quat& q1, const Quat& q2, const float tol );
|
||||||
|
|
||||||
|
Quat ( float cx = 0.0f, float cy = 0.0f, float cz = 0.0f, float cw = 1.0f );
|
||||||
|
|
||||||
|
Quat ( const Vector& axis, float angle );
|
||||||
|
Quat ( const Matrix& mat );
|
||||||
|
|
||||||
|
Quat& Invert ( void );
|
||||||
|
Quat& Invert ( const Quat& src );
|
||||||
|
float Modulus ( void );
|
||||||
|
float ModulusSqr ( void ) const;
|
||||||
|
Quat& Normalize ( float len = 1.0f );
|
||||||
|
Vector Rotate ( const Vector& vec ) const;
|
||||||
|
|
||||||
|
void SetScalar ( const float w );
|
||||||
|
void SetVector ( const float x, const float y, const float z );
|
||||||
|
void SetVector ( const Vector& v );
|
||||||
|
const float& GetScalar ( void ) const;
|
||||||
|
const Vector& GetVector ( void ) const { return quat; }
|
||||||
|
|
||||||
|
void GetMatrix ( Matrix& mat ) const;
|
||||||
|
|
||||||
|
Quat& operator= ( const Quat& q );
|
||||||
|
Quat& operator+= ( const Quat& q );
|
||||||
|
Quat& operator-= ( const Quat& q );
|
||||||
|
Quat& operator*= ( const Quat& q );
|
||||||
|
Quat& operator*= ( float s );
|
||||||
|
Quat& operator/= ( float s );
|
||||||
|
const float& operator[] ( sint i ) const;
|
||||||
|
float& operator[] ( sint i );
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Vector quat; // X,Y,Z : Imaginary (Vector) component
|
||||||
|
// W : Real (Scalar) component
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Quat operator+ ( const Quat& q1, const Quat& q2 );
|
||||||
|
Quat operator- ( const Quat& q1, const Quat& q2 );
|
||||||
|
Quat operator* ( const Quat& q1, const Quat& q2 );
|
||||||
|
Quat operator* ( const Quat& q, const float s );
|
||||||
|
Quat operator* ( const float s, const Quat& q );
|
||||||
|
Quat operator- ( const Quat& q ); // negate all elements -> equilavent rotation
|
||||||
|
float DotProduct ( const Quat& v1, const Quat& v2 );
|
||||||
|
Quat Slerp ( const Quat& q1, const Quat& q2, const float t );
|
||||||
|
Quat FastSlerp( Quat& qIn1, Quat& qIn2, const float t );
|
||||||
|
bool Equal ( const Quat& q1, const Quat& q2, const float tol = 0.0001f );
|
||||||
|
ostream& operator<< ( ostream& os, const Quat& v );
|
||||||
|
Quat EulerToQuat( const Vector& v );
|
||||||
|
|
||||||
|
// converts a quat+vector xform into a matrix xform
|
||||||
|
void QuatVecToMatrix( Mth::Quat* pQ, Mth::Vector* pT, Mth::Matrix* pMatrix );
|
||||||
|
void SCacheQuatVecToMatrix( Mth::Quat* pQ, Mth::Vector* pT, Mth::Matrix* pMatrix );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_QUAT_H
|
||||||
|
|
||||||
|
|
815
Code/Core/Math/quat.inl
Normal file
815
Code/Core/Math/quat.inl
Normal file
@ -0,0 +1,815 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (Mth) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/Quat.inl **
|
||||||
|
** **
|
||||||
|
** Created: 11/23/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Quaternion Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_QUAT_INL
|
||||||
|
#define __CORE_MATH_QUAT_INL
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline const float& Quat::operator[] ( sint i ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return quat[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline bool quat_equal( const Quat& q1, const Quat& q2, const float tol )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return ( Equal( q1.quat, q2.quat, tol ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline Quat::Quat( float cx, float cy, float cz, float cw )
|
||||||
|
: quat( cx, cy, cz, cw )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat::Quat( const Vector& axis, float angle )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float mod = axis.Length();
|
||||||
|
float ang = angle / 2.0f;
|
||||||
|
|
||||||
|
mod = ( mod > 0.0f ) ? ( 1.0f / mod ) : 0.0f;
|
||||||
|
mod *= sinf( ang );
|
||||||
|
|
||||||
|
SetVector( mod * axis[X], mod * axis[Y], mod * axis[Z] );
|
||||||
|
SetScalar( cosf ( ang ));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float& Quat::operator[] ( sint i )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return quat[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat::Quat( const Matrix& m )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float t = m[X][X] + m[Y][Y] + m[Z][Z];
|
||||||
|
float trace;
|
||||||
|
|
||||||
|
if ( t > 0.0f )
|
||||||
|
{
|
||||||
|
trace = sqrtf( t + 1.0f );
|
||||||
|
|
||||||
|
SetScalar( trace * 0.5f );
|
||||||
|
trace = 0.5f / trace;
|
||||||
|
|
||||||
|
SetVector(( m[Z][Y] - m[Y][Z] ) * trace,
|
||||||
|
( m[X][Z] - m[Z][X] ) * trace,
|
||||||
|
( m[Y][X] - m[X][Y] ) * trace );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// find greatest element in Matrix diagonal
|
||||||
|
sint i = X;
|
||||||
|
if ( m[Y][Y] > m[X][X] ) i = Y;
|
||||||
|
if ( m[Z][Z] > m[i][i] ) i = Z;
|
||||||
|
|
||||||
|
sint j = ( i + 1 ) % W;
|
||||||
|
sint k = ( j + 1 ) % W;
|
||||||
|
|
||||||
|
trace = sqrtf(( m[i][i] - (m[j][j] + m[k][k] )) + 1.0f );
|
||||||
|
|
||||||
|
quat[i] = ( trace * 0.5f );
|
||||||
|
trace = 0.5f / trace;
|
||||||
|
quat[j] = ( m[j][i] + m[i][j] ) * trace;
|
||||||
|
quat[k] = ( m[k][i] + m[i][k] ) * trace;
|
||||||
|
quat[W] = ( m[k][j] - m[j][k] ) * trace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::Invert( void ) // this = Invert ( this )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat.Negate();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::Invert( const Quat& src ) // this = Invert ( src )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat.Negate( src.quat );
|
||||||
|
quat[W] = src.quat[W];
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Quat::Modulus( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return sqrtf( ModulusSqr () );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float Quat::ModulusSqr ( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return (( quat[X] * quat[X] ) +
|
||||||
|
( quat[Y] * quat[Y] ) +
|
||||||
|
( quat[Z] * quat[Z] ) +
|
||||||
|
( quat[W] * quat[W] ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::Normalize( float len )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float mod = Modulus();
|
||||||
|
|
||||||
|
if ( mod > 0.0f )
|
||||||
|
{
|
||||||
|
mod = len / mod;
|
||||||
|
|
||||||
|
quat *= mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Vector Quat::Rotate( const Vector& vec ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Quat inv;
|
||||||
|
// Quat pt( vec[X], vec[Y], vec[Z], vec[W] );
|
||||||
|
Quat pt( vec[X], vec[Y], vec[Z], 1.0f ); // Mick: Setting W to sensible value, otherwise can cause overflow
|
||||||
|
Quat res = *this;
|
||||||
|
|
||||||
|
inv.Invert( *this );
|
||||||
|
res *= pt;
|
||||||
|
res *= inv;
|
||||||
|
|
||||||
|
return Vector( res[X], res[Y], res[Z], res[W] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Quat::SetScalar( const float w )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat[W] = w;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Quat::SetVector( const float x, const float y, const float z )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat[X] = x;
|
||||||
|
quat[Y] = y;
|
||||||
|
quat[Z] = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Quat::SetVector( const Vector& v )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat[X] = v[X];
|
||||||
|
quat[Y] = v[Y];
|
||||||
|
quat[Z] = v[Z];
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::operator= ( const Quat& q )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat = q.quat;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::operator+= ( const Quat& q )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat += q.quat;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::operator-= ( const Quat& q )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat -= q.quat;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const float& Quat::GetScalar ( void ) const
|
||||||
|
{
|
||||||
|
return quat[W];
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::operator*= ( const Quat& q )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float s1 = GetScalar();
|
||||||
|
float s2 = q.GetScalar();
|
||||||
|
|
||||||
|
Vector v1 = GetVector();
|
||||||
|
Vector v2 = q.GetVector();
|
||||||
|
|
||||||
|
SetVector (( v2 * s1 ) + ( v1 * s2 ) + CrossProduct ( v1, v2 ));
|
||||||
|
SetScalar (( s1 * s2 ) - DotProduct ( v1, v2 ));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::operator*= ( float s )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat *= s;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat& Quat::operator/= ( float s )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
quat /= s;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Quat::GetMatrix ( Matrix& mat ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float xs, ys, zs,
|
||||||
|
wx, wy, wz,
|
||||||
|
xx, xy, xz,
|
||||||
|
yy, yz, zz, ss;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// our original version. Seems essentially broken, as LengthSqr ignores W
|
||||||
|
ss = 2.0f / quat.LengthSqr();
|
||||||
|
#else
|
||||||
|
// version suggested by Andre at Left Field
|
||||||
|
// uses proper Modulus, and clamps 2.0/0.0f to zero
|
||||||
|
ss = ModulusSqr();
|
||||||
|
ss = ( ss>0.0f ? 2.0f/ss : 0.0f);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xs = quat[X] * ss;
|
||||||
|
ys = quat[Y] * ss;
|
||||||
|
zs = quat[Z] * ss;
|
||||||
|
|
||||||
|
wx = quat[W] * xs;
|
||||||
|
wy = quat[W] * ys;
|
||||||
|
wz = quat[W] * zs;
|
||||||
|
|
||||||
|
xx = quat[X] * xs;
|
||||||
|
xy = quat[X] * ys;
|
||||||
|
xz = quat[X] * zs;
|
||||||
|
|
||||||
|
yy = quat[Y] * ys;
|
||||||
|
yz = quat[Y] * zs;
|
||||||
|
|
||||||
|
zz = quat[Z] * zs;
|
||||||
|
|
||||||
|
mat[X][X] = 1.0f - (yy + zz);
|
||||||
|
mat[Y][X] = xy + wz;
|
||||||
|
mat[Z][X] = xz - wy;
|
||||||
|
|
||||||
|
mat[X][Y] = xy - wz;
|
||||||
|
mat[Y][Y] = 1.0f - (xx + zz);
|
||||||
|
mat[Z][Y] = yz + wx;
|
||||||
|
|
||||||
|
mat[X][Z] = xz + wy;
|
||||||
|
mat[Y][Z] = yz - wx;
|
||||||
|
mat[Z][Z] = 1.0f - (xx + yy );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat operator+ ( const Quat& q1, const Quat& q2 )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Quat sum = q1;
|
||||||
|
|
||||||
|
sum += q2;
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat operator- ( const Quat& q1, const Quat& q2 )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Quat diff = q1;
|
||||||
|
|
||||||
|
diff -= q2;
|
||||||
|
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat operator* ( const Quat& q1, const Quat& q2 )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Quat prod = q1;
|
||||||
|
|
||||||
|
prod *= q2;
|
||||||
|
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat operator* ( const Quat& q, const float s )
|
||||||
|
{
|
||||||
|
Quat prod = q;
|
||||||
|
|
||||||
|
prod *= s;
|
||||||
|
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat operator* ( const float s, const Quat& q )
|
||||||
|
{
|
||||||
|
return q * s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat operator- ( const Quat& q )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return Quat ( -q[X], -q[Y], -q[Z], -q[W] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float DotProduct ( const Quat& v1, const Quat& v2 )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return ( v1[X] * v2[X] ) + ( v1[Y] * v2[Y] ) + ( v1[Z] * v2[Z] ) + ( v1[W] * v2[W] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Quat Slerp ( const Quat& q1, const Quat& q3, float t )
|
||||||
|
{
|
||||||
|
float sclp, sclq;
|
||||||
|
|
||||||
|
// GJ: Need to possibly negate the second quaternion,
|
||||||
|
// to avoid spinning in the wrong direction.
|
||||||
|
Quat q2 = q3;
|
||||||
|
if ( DotProduct( q1, q3 ) < 0.0f )
|
||||||
|
{
|
||||||
|
q2 = -q2;
|
||||||
|
}
|
||||||
|
|
||||||
|
float coso = q1.GetScalar() * q2.GetScalar() +
|
||||||
|
DotProduct ( q1.GetVector(), q2.GetVector());
|
||||||
|
|
||||||
|
Quat q;
|
||||||
|
|
||||||
|
if (( 1.0f + coso + 1.0f ) > EPSILON )
|
||||||
|
{
|
||||||
|
if (( 1.0f - coso ) > EPSILON ) // slerp
|
||||||
|
{
|
||||||
|
float omega = acosf ( coso );
|
||||||
|
float sino = sinf ( omega );
|
||||||
|
|
||||||
|
sclp = sinf (( 1.0f - t ) * omega ) / sino;
|
||||||
|
sclq = sinf ( t * omega ) / sino;
|
||||||
|
}
|
||||||
|
else // lerp ( angle tends to 0 )
|
||||||
|
{
|
||||||
|
sclp = 1.0f - t;
|
||||||
|
sclq = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
q = ( sclp * q1 ) + ( sclq * q2 );
|
||||||
|
}
|
||||||
|
else // angle tends to 2*PI
|
||||||
|
{
|
||||||
|
q.SetVector ( -q1[Y], q1[X], -q1[W] );
|
||||||
|
q.SetScalar ( q1[Z] );
|
||||||
|
|
||||||
|
sclp = sinf (( 1.0f - t ) * PI / 2.0f );
|
||||||
|
sclq = sinf ( t * PI / 2.0f );
|
||||||
|
|
||||||
|
q.SetVector (( sclp * q1.GetVector()) + ( sclq * q.GetVector()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool Equal ( const Quat& q1, const Quat& q2, const float tol )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (( quat_equal ( q1, q2, tol )) ||
|
||||||
|
( quat_equal ( -q1, q2, tol )))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline ostream& operator<< ( ostream& os, const Quat& q )
|
||||||
|
{
|
||||||
|
return os << "(( " << q[X] << ", " << q[Y] << ", " << q[Z] << ") , " << q[W] << " )";
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void QuatVecToMatrix( Mth::Quat* pQ, Mth::Vector* pT, Mth::Matrix* pMatrix )
|
||||||
|
{
|
||||||
|
Dbg_Assert( pQ );
|
||||||
|
Dbg_Assert( pT );
|
||||||
|
Dbg_Assert( pMatrix );
|
||||||
|
|
||||||
|
pQ->Invert();
|
||||||
|
|
||||||
|
Mth::Vector square;
|
||||||
|
Mth::Vector cross;
|
||||||
|
Mth::Vector wimag;
|
||||||
|
|
||||||
|
square[X] = (*pQ)[X] * (*pQ)[X];
|
||||||
|
square[Y] = (*pQ)[Y] * (*pQ)[Y];
|
||||||
|
square[Z] = (*pQ)[Z] * (*pQ)[Z];
|
||||||
|
|
||||||
|
cross[X] = (*pQ)[Y] * (*pQ)[Z];
|
||||||
|
cross[Y] = (*pQ)[Z] * (*pQ)[X];
|
||||||
|
cross[Z] = (*pQ)[X] * (*pQ)[Y];
|
||||||
|
|
||||||
|
wimag[X] = (*pQ)[W] * (*pQ)[X];
|
||||||
|
wimag[Y] = (*pQ)[W] * (*pQ)[Y];
|
||||||
|
wimag[Z] = (*pQ)[W] * (*pQ)[Z];
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::RIGHT][X] = 1 - 2 * (square[Y] + square[Z]);
|
||||||
|
(*pMatrix)[Mth::RIGHT][Y] = 2 * (cross[Z] + wimag[Z]);
|
||||||
|
(*pMatrix)[Mth::RIGHT][Z] = 2 * (cross[Y] - wimag[Y]);
|
||||||
|
(*pMatrix)[Mth::RIGHT][W] = 0.0f;
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::UP][X] = 2 * (cross[Z] - wimag[Z]);
|
||||||
|
(*pMatrix)[Mth::UP][Y] = 1 - 2 * (square[X] + square[Z]);
|
||||||
|
(*pMatrix)[Mth::UP][Z] = 2 * (cross[X] + wimag[X]);
|
||||||
|
(*pMatrix)[Mth::UP][W] = 0.0f;
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::AT][X] = 2 * (cross[Y] + wimag[Y]);
|
||||||
|
(*pMatrix)[Mth::AT][Y] = 2 * (cross[X] - wimag[X]);
|
||||||
|
(*pMatrix)[Mth::AT][Z] = 1 - 2 * (square[X] + square[Y]);
|
||||||
|
(*pMatrix)[Mth::AT][W] = 0.0f;
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::POS] = *pT;
|
||||||
|
(*pMatrix)[Mth::POS][W] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SCacheQuatVecToMatrix( Mth::Quat* pQ, Mth::Vector* pT, Mth::Matrix* pMatrix )
|
||||||
|
{
|
||||||
|
Dbg_Assert( pQ );
|
||||||
|
Dbg_Assert( pT );
|
||||||
|
Dbg_Assert( pMatrix );
|
||||||
|
|
||||||
|
pQ->Invert();
|
||||||
|
|
||||||
|
Mth::Vector *p_square = ((Mth::Vector*)0x7000000)+0;
|
||||||
|
Mth::Vector *p_cross = ((Mth::Vector*)0x7000000)+1;
|
||||||
|
Mth::Vector *p_wimag = ((Mth::Vector*)0x7000000)+2;
|
||||||
|
|
||||||
|
(*p_square)[X] = (*pQ)[X] * (*pQ)[X];
|
||||||
|
(*p_square)[Y] = (*pQ)[Y] * (*pQ)[Y];
|
||||||
|
(*p_square)[Z] = (*pQ)[Z] * (*pQ)[Z];
|
||||||
|
|
||||||
|
(*p_cross)[X] = (*pQ)[Y] * (*pQ)[Z];
|
||||||
|
(*p_cross)[Y] = (*pQ)[Z] * (*pQ)[X];
|
||||||
|
(*p_cross)[Z] = (*pQ)[X] * (*pQ)[Y];
|
||||||
|
|
||||||
|
(*p_wimag)[X] = (*pQ)[W] * (*pQ)[X];
|
||||||
|
(*p_wimag)[Y] = (*pQ)[W] * (*pQ)[Y];
|
||||||
|
(*p_wimag)[Z] = (*pQ)[W] * (*pQ)[Z];
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::RIGHT][X] = 1 - 2 * ((*p_square)[Y] + (*p_square)[Z]);
|
||||||
|
(*pMatrix)[Mth::RIGHT][Y] = 2 * ((*p_cross)[Z] + (*p_wimag)[Z]);
|
||||||
|
(*pMatrix)[Mth::RIGHT][Z] = 2 * ((*p_cross)[Y] - (*p_wimag)[Y]);
|
||||||
|
(*pMatrix)[Mth::RIGHT][W] = 0.0f;
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::UP][X] = 2 * ((*p_cross)[Z] - (*p_wimag)[Z]);
|
||||||
|
(*pMatrix)[Mth::UP][Y] = 1 - 2 * ((*p_square)[X] + (*p_square)[Z]);
|
||||||
|
(*pMatrix)[Mth::UP][Z] = 2 * ((*p_cross)[X] + (*p_wimag)[X]);
|
||||||
|
(*pMatrix)[Mth::UP][W] = 0.0f;
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::AT][X] = 2 * ((*p_cross)[Y] + (*p_wimag)[Y]);
|
||||||
|
(*pMatrix)[Mth::AT][Y] = 2 * ((*p_cross)[X] - (*p_wimag)[X]);
|
||||||
|
(*pMatrix)[Mth::AT][Z] = 1 - 2 * ((*p_square)[X] + (*p_square)[Y]);
|
||||||
|
(*pMatrix)[Mth::AT][W] = 0.0f;
|
||||||
|
|
||||||
|
(*pMatrix)[Mth::POS] = *pT;
|
||||||
|
(*pMatrix)[Mth::POS][W] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Slerp ( Matrix& result, const Matrix& s1, const Matrix& s2, float t )
|
||||||
|
{
|
||||||
|
Slerp ( Quat(s1), Quat(s2), t).GetMatrix ( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline float counter_warp(float t, float cos_alpha)
|
||||||
|
{
|
||||||
|
const float ATTENUATION = 0.82279687f;
|
||||||
|
const float WORST_CASE_SLOPE = 0.58549219f;
|
||||||
|
|
||||||
|
float factor = 1.0f - ATTENUATION * cos_alpha;
|
||||||
|
factor *= factor;
|
||||||
|
float k = WORST_CASE_SLOPE * factor;
|
||||||
|
|
||||||
|
return t*(k*t*(2.0f*t - 3.0f) + 1.0f + k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Mth::Quat FastSlerp( Mth::Quat& qIn1, Mth::Quat& qIn2, const float t )
|
||||||
|
{
|
||||||
|
if ( Mth::DotProduct( qIn1, qIn2 ) < 0.0f )
|
||||||
|
{
|
||||||
|
qIn2 = -qIn2;
|
||||||
|
}
|
||||||
|
|
||||||
|
# if 0
|
||||||
|
float cos_a = v1[X]*v2[X] + v1[Y]*v2[Y] + v1[Z]*v2[Z] + v1[W]*v2[W];
|
||||||
|
if (t <= 0.5f)
|
||||||
|
{
|
||||||
|
t = counter_warp(t, cos_a);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = 1.0f - counter_warp(1.0f - t, cos_a);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
float xxx_x = qIn1[X] + ( qIn2[X] - qIn1[X] ) * t;
|
||||||
|
float xxx_y = qIn1[Y] + ( qIn2[Y] - qIn1[Y] ) * t;
|
||||||
|
float xxx_z = qIn1[Z] + ( qIn2[Z] - qIn1[Z] ) * t;
|
||||||
|
float xxx_w = qIn1[W] + ( qIn2[W] - qIn1[W] ) * t;
|
||||||
|
|
||||||
|
float len = 1.0f / sqrtf( xxx_x * xxx_x + xxx_y * xxx_y + xxx_z * xxx_z + xxx_w * xxx_w );
|
||||||
|
|
||||||
|
qIn2.SetVector( xxx_x * len, xxx_y * len, xxx_z * len );
|
||||||
|
qIn2.SetScalar( xxx_w * len );
|
||||||
|
|
||||||
|
return qIn2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Mth::Quat EulerToQuat( const Mth::Vector& euler )
|
||||||
|
{
|
||||||
|
// This code is a modified version of Left Field's
|
||||||
|
// MakeQuatFromEuler() function.
|
||||||
|
|
||||||
|
Mth::Quat q;
|
||||||
|
|
||||||
|
float roll = euler[X];
|
||||||
|
float pitch = euler[Y];
|
||||||
|
float yaw = euler[Z];
|
||||||
|
|
||||||
|
float cyaw, cpitch, croll, syaw, spitch, sroll;
|
||||||
|
float cyawcpitch, syawspitch, cyawspitch, syawcpitch;
|
||||||
|
|
||||||
|
cyaw = cosf(0.5f * yaw);
|
||||||
|
cpitch = cosf(0.5f * pitch);
|
||||||
|
croll = cosf(0.5f * roll);
|
||||||
|
|
||||||
|
syaw = sinf(0.5f * yaw);
|
||||||
|
spitch = sinf(0.5f * pitch);
|
||||||
|
sroll = sinf(0.5f * roll);
|
||||||
|
|
||||||
|
cyawcpitch = cyaw * cpitch;
|
||||||
|
syawspitch = syaw * spitch;
|
||||||
|
cyawspitch = cyaw * spitch;
|
||||||
|
syawcpitch = syaw * cpitch;
|
||||||
|
|
||||||
|
q[W] = cyawcpitch * croll + syawspitch * sroll;
|
||||||
|
q[X] = cyawcpitch * sroll - syawspitch * croll;
|
||||||
|
q[Y] = cyawspitch * croll + syawcpitch * sroll;
|
||||||
|
q[Z] = syawcpitch * croll - cyawspitch * sroll;
|
||||||
|
|
||||||
|
return q;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_QUAT_INL
|
||||||
|
|
235
Code/Core/Math/rect.h
Normal file
235
Code/Core/Math/rect.h
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/Rect.h **
|
||||||
|
** **
|
||||||
|
** Created: 01/31/00 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Math Library Rectangle class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_RECT_H
|
||||||
|
#define __CORE_MATH_RECT_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
nTemplateBaseClass ( _T, _Rect )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
_Rect ( const _T x, const _T y, const _T w, const _T h );
|
||||||
|
~_Rect ( );
|
||||||
|
|
||||||
|
void SetOriginX ( const _T ) ;
|
||||||
|
void SetOriginY ( const _T ) ;
|
||||||
|
void SetWidth ( const _T ) ;
|
||||||
|
void SetHeight ( const _T ) ;
|
||||||
|
|
||||||
|
const _T GetOriginX ( void ) const;
|
||||||
|
const _T GetOriginY ( void ) const;
|
||||||
|
const _T GetWidth ( void ) const;
|
||||||
|
const _T GetHeight ( void ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
_T x, y, w, h;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
typedef _Rect < float > Rect;
|
||||||
|
typedef _Rect < sint > IRect;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_Rect< _T >::_Rect ( const _T _x, const _T _y, const _T _w, const _T _h )
|
||||||
|
: x (_x), y (_y), w(_w), h(_h)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_Rect< _T >::~_Rect ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void _Rect< _T >::SetOriginX ( const _T xval )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
x = xval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void _Rect< _T >::SetOriginY ( const _T yval )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
y = yval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void _Rect< _T >::SetWidth ( const _T width )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
w = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void _Rect< _T >::SetHeight ( const _T height )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
h = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
const _T _Rect< _T >::GetOriginX ( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
const _T _Rect< _T >::GetOriginY ( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
const _T _Rect< _T >::GetWidth ( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
const _T _Rect< _T >::GetHeight ( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
ostream& operator<< ( ostream& str, const _Rect< _T >& r )
|
||||||
|
{
|
||||||
|
str << "(( " << r.GetOriginX() << ", " << r.GetOriginY() << " ),( "
|
||||||
|
<< r.GetWidth() << ", " << r.GetHeight() << " ))";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_RECT_H
|
105
Code/Core/Math/rot90.cpp
Normal file
105
Code/Core/Math/rot90.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/rot90.cpp **
|
||||||
|
** **
|
||||||
|
** Created: 07/17/02 - grj **
|
||||||
|
** **
|
||||||
|
** Description: Rotation 90 Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/math.h>
|
||||||
|
#include <core/math/rot90.h>
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void RotateY90( ERot90 angle, int32& x, int32& y, int32& z )
|
||||||
|
{
|
||||||
|
int32 temp;
|
||||||
|
|
||||||
|
switch (angle)
|
||||||
|
{
|
||||||
|
case ROT_0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROT_90:
|
||||||
|
temp = x;
|
||||||
|
x = z;
|
||||||
|
z = -temp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROT_180:
|
||||||
|
x = -x;
|
||||||
|
z = -z;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROT_270:
|
||||||
|
temp = x;
|
||||||
|
x = -z;
|
||||||
|
z = temp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Dbg_MsgAssert(0, ("RotateY90() out of range: %d", angle));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
26
Code/Core/Math/rot90.h
Normal file
26
Code/Core/Math/rot90.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// rot90.h
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __CORE_ROT90_H
|
||||||
|
#define __CORE_ROT90_H
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
// Rotation values for 90 degree increment Rotation (uses no multiplication)
|
||||||
|
enum ERot90 {
|
||||||
|
ROT_0 = 0,
|
||||||
|
ROT_90,
|
||||||
|
ROT_180,
|
||||||
|
ROT_270,
|
||||||
|
NUM_ROTS
|
||||||
|
};
|
||||||
|
|
||||||
|
// Integer rotate
|
||||||
|
void RotateY90( ERot90 angle, int32& x, int32& y, int32& z );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
274
Code/Core/Math/slerp.cpp
Normal file
274
Code/Core/Math/slerp.cpp
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/slerp.cpp **
|
||||||
|
** **
|
||||||
|
** Created: 12/20/01 - gj **
|
||||||
|
** **
|
||||||
|
** Description: Slerp Interpolator Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/math.h>
|
||||||
|
#include <core/math/slerp.h>
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const float USE_LERP_INSTEAD_DEGREES = 2.0f;
|
||||||
|
const float USE_LERP_INSTEAD_RADIANS = USE_LERP_INSTEAD_DEGREES * PI / 180.0f;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
SlerpInterpolator::SlerpInterpolator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
SlerpInterpolator::SlerpInterpolator( const Matrix * start, const Matrix * end )
|
||||||
|
{
|
||||||
|
setMatrices( start, end );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void SlerpInterpolator::setMatrices( const Matrix * start, const Matrix * end )
|
||||||
|
{
|
||||||
|
Matrix inv;
|
||||||
|
|
||||||
|
m_start = *start;
|
||||||
|
m_end = *end;
|
||||||
|
|
||||||
|
// Calculate the inverse transformation.
|
||||||
|
inv = m_start;
|
||||||
|
inv.Invert();
|
||||||
|
inv = inv * m_end;
|
||||||
|
|
||||||
|
// Get the axis and angle.
|
||||||
|
inv.GetRotationAxisAndAngle( &m_axis, &m_radians );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Debugging stuff
|
||||||
|
static int print_x_times = 50;
|
||||||
|
|
||||||
|
if ( print_x_times > 0 )
|
||||||
|
{
|
||||||
|
print_x_times--;
|
||||||
|
printf("Start mat\n");
|
||||||
|
m_start.PrintContents();
|
||||||
|
printf("Inv mat\n");
|
||||||
|
inv.PrintContents();
|
||||||
|
printf("End mat\n");
|
||||||
|
m_end.PrintContents();
|
||||||
|
printf("Start * Inv mat\n");
|
||||||
|
Mth::Matrix siMat = m_start;
|
||||||
|
siMat = siMat * inv;
|
||||||
|
siMat.PrintContents();
|
||||||
|
{
|
||||||
|
printf("Rotated mat w=0\n");
|
||||||
|
Mth::Matrix tempMatrix = m_start;
|
||||||
|
m_axis[W] = 0.0f;
|
||||||
|
tempMatrix.Rotate( m_axis, m_radians );
|
||||||
|
tempMatrix.PrintContents();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
printf("Rotated mat w=1\n");
|
||||||
|
Mth::Matrix tempMatrix2 = m_start;
|
||||||
|
m_axis[W] = 1.0f;
|
||||||
|
tempMatrix2.Rotate( m_axis, m_radians );
|
||||||
|
tempMatrix2.PrintContents();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
printf("Rotated local mat w=0\n");
|
||||||
|
Mth::Matrix tempMatrix = m_start;
|
||||||
|
m_axis[W] = 0.0f;
|
||||||
|
tempMatrix.RotateLocal( m_axis, m_radians );
|
||||||
|
tempMatrix.PrintContents();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
printf("Rotated local mat w=1\n");
|
||||||
|
Mth::Matrix tempMatrix2 = m_start;
|
||||||
|
m_axis[W] = 1.0f;
|
||||||
|
tempMatrix2.RotateLocal( m_axis, m_radians );
|
||||||
|
tempMatrix2.PrintContents();
|
||||||
|
}
|
||||||
|
printf( "Slerp axis=(%f %f %f %f) angle=%f\n", m_axis[X], m_axis[Y], m_axis[Z], m_axis[W], m_radians );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dbg_Assert( 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If angle is too small, use lerp.
|
||||||
|
m_useLerp = m_radians < USE_LERP_INSTEAD_RADIANS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void SlerpInterpolator::getMatrix( Matrix * result, float delta )
|
||||||
|
{
|
||||||
|
/* Cap and floor the delta */
|
||||||
|
/* If we are at one end the solution is easy */
|
||||||
|
if (delta <= 0.0f)
|
||||||
|
{
|
||||||
|
// delta = 0.0f;
|
||||||
|
*result = m_start;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (delta >= 1.0f)
|
||||||
|
{
|
||||||
|
// delta = 1.0f;
|
||||||
|
*result = m_end;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// GJ: always lerp, used while slerp was being debugged
|
||||||
|
// m_useLerp = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Do the lerp if we are, else... */
|
||||||
|
if ( m_useLerp )
|
||||||
|
{
|
||||||
|
/* Get the lerp matrix */
|
||||||
|
Matrix lerp;
|
||||||
|
Vector lpos;
|
||||||
|
Vector spos;
|
||||||
|
Vector epos;
|
||||||
|
Vector rpos;
|
||||||
|
|
||||||
|
lerp.Ident();
|
||||||
|
|
||||||
|
spos = m_start[Mth::POS];
|
||||||
|
epos = m_end[Mth::POS];
|
||||||
|
|
||||||
|
lerp[Mth::RIGHT] = m_end[Mth::RIGHT] - m_start[Mth::RIGHT];
|
||||||
|
lerp[Mth::UP] = m_end[Mth::UP] - m_start[Mth::UP];
|
||||||
|
lerp[Mth::AT] = m_end[Mth::AT] - m_start[Mth::AT];
|
||||||
|
lpos = epos - spos;
|
||||||
|
|
||||||
|
/* Do lerp */
|
||||||
|
lerp[Mth::RIGHT].Scale( delta );
|
||||||
|
lerp[Mth::UP].Scale( delta );
|
||||||
|
lerp[Mth::AT].Scale( delta );
|
||||||
|
lpos.Scale( delta );
|
||||||
|
|
||||||
|
(*result)[Mth::RIGHT] = m_start[Mth::RIGHT] + lerp[Mth::RIGHT];
|
||||||
|
(*result)[Mth::UP] = m_start[Mth::UP] + lerp[Mth::UP];
|
||||||
|
(*result)[Mth::AT] = m_start[Mth::AT] + lerp[Mth::AT];
|
||||||
|
rpos = spos + lpos;
|
||||||
|
|
||||||
|
(*result)[Mth::RIGHT].Normalize();
|
||||||
|
(*result)[Mth::UP].Normalize();
|
||||||
|
(*result)[Mth::AT].Normalize();
|
||||||
|
|
||||||
|
(*result)[Mth::POS] = rpos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector rpos;
|
||||||
|
Vector spos;
|
||||||
|
Vector epos;
|
||||||
|
Vector lpos;
|
||||||
|
|
||||||
|
spos = m_start[Mth::POS];
|
||||||
|
epos = m_end[Mth::POS];
|
||||||
|
|
||||||
|
/* Remove the translation for now */
|
||||||
|
*result = m_start;
|
||||||
|
(*result)[Mth::POS] = Mth::Vector( 0.0f, 0.0f, 0.0f );
|
||||||
|
|
||||||
|
/* Rotate the new matrix */
|
||||||
|
// m_axis[W] = 0.0f;
|
||||||
|
result->Rotate( m_axis, m_radians * delta );
|
||||||
|
|
||||||
|
/* Do linear interpolation on position */
|
||||||
|
lpos = epos - spos;
|
||||||
|
lpos.Scale( delta );
|
||||||
|
rpos = spos + lpos;
|
||||||
|
|
||||||
|
(*result)[Mth::POS] = rpos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void SlerpInterpolator::invertDirection ( )
|
||||||
|
{
|
||||||
|
m_axis = -m_axis;
|
||||||
|
m_radians = (2.0f * Mth::PI) - m_radians;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Obj
|
||||||
|
|
102
Code/Core/Math/slerp.h
Normal file
102
Code/Core/Math/slerp.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/slerp.h **
|
||||||
|
** **
|
||||||
|
** Created: 12/20/01 - gj **
|
||||||
|
** **
|
||||||
|
** Description: Slerp Interpolator Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_SLERP_H
|
||||||
|
#define __CORE_MATH_SLERP_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <core/math/vector.h>
|
||||||
|
#include <core/math/matrix.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: Slerp Interpolator
|
||||||
|
*
|
||||||
|
* Description: Slerp Interpolator math class
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class SlerpInterpolator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SlerpInterpolator();
|
||||||
|
SlerpInterpolator( const Matrix* pStart, const Matrix* pEnd );
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setMatrices( const Matrix* pStart, const Matrix* pEnd );
|
||||||
|
void getMatrix( Matrix* result, float delta );
|
||||||
|
|
||||||
|
void invertDirection ( );
|
||||||
|
|
||||||
|
float getRadians ( ) { return m_radians; }
|
||||||
|
const Mth::Vector& getAxis ( ) { return m_axis; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Matrix m_start;
|
||||||
|
Matrix m_end;
|
||||||
|
Vector m_axis;
|
||||||
|
float m_radians;
|
||||||
|
bool m_useLerp; // do linear-interpolation, rather than slerping
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_SLERP_H
|
432
Code/Core/Math/vector.cpp
Normal file
432
Code/Core/Math/vector.cpp
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Vector (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: vector.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 11/24/99 - Mick **
|
||||||
|
** **
|
||||||
|
** Description: Math Library code **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <core/math.h>
|
||||||
|
#include <core/defines.h>
|
||||||
|
//#include <core/math.h>
|
||||||
|
#include <core/math/math.h>
|
||||||
|
#include <core/math/vector.h>
|
||||||
|
#include <core/math/matrix.h>
|
||||||
|
#include <core/macros.h>
|
||||||
|
|
||||||
|
#include <core/math/quat.h>
|
||||||
|
#include <core/math/vector.inl>
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Vector& Vector::RotateY90( ERot90 angle )
|
||||||
|
{
|
||||||
|
float temp;
|
||||||
|
|
||||||
|
switch (angle)
|
||||||
|
{
|
||||||
|
case ROT_0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROT_90:
|
||||||
|
temp = col[X];
|
||||||
|
col[X] = col[Z];
|
||||||
|
col[Z] = -temp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROT_180:
|
||||||
|
col[X] = -col[X];
|
||||||
|
col[Z] = -col[Z];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ROT_270:
|
||||||
|
temp = col[X];
|
||||||
|
col[X] = -col[Z];
|
||||||
|
col[Z] = temp;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Dbg_MsgAssert(0, ("Vector::RotateY90() out of range: %d", angle));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
// Project the vector onto the plane define by a normal
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Vector& Vector::ProjectToPlane(const Vector& normal)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
float perp_component = Mth::DotProduct(*this,normal);
|
||||||
|
|
||||||
|
*this -= normal * perp_component;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector& Vector::RotateToPlane(const Vector& normal)
|
||||||
|
{
|
||||||
|
// get the length of the vector
|
||||||
|
float length = Length();
|
||||||
|
|
||||||
|
// Project the vector onto the plane
|
||||||
|
ProjectToPlane(normal);
|
||||||
|
|
||||||
|
// now we've projected it ontot he plane
|
||||||
|
// we need to handle the case where it dissapears into a point
|
||||||
|
// which would indicate that we were perpendicular to the plane
|
||||||
|
// so need to get an arbitary vector in the plane
|
||||||
|
float projected_length = Length();
|
||||||
|
if (projected_length == 0.0f) // is this a valid comparision?
|
||||||
|
{
|
||||||
|
// Rotate vector through -90 degrees about Y then +90 about X
|
||||||
|
col[X] = -normal[Z];
|
||||||
|
col[Y] = normal[X];
|
||||||
|
col[Z] = -normal[Y];
|
||||||
|
}
|
||||||
|
|
||||||
|
// get unit vector in this direction
|
||||||
|
Normalize();
|
||||||
|
|
||||||
|
// multiply by original speed to rotate velocity onto plane
|
||||||
|
*this *= length;
|
||||||
|
|
||||||
|
col[W] = 0.0f; // clean up W, otherwise multilications will accumelate over time...
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector& Vector::RotateToNormal(const Vector& normal)
|
||||||
|
{
|
||||||
|
|
||||||
|
*this = normal*Length();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector& Vector::ProjectToNormal(const Vector& normal)
|
||||||
|
{
|
||||||
|
|
||||||
|
float dot = Mth::DotProduct(*this,normal);
|
||||||
|
*this = normal * dot;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finds the largest contributor to the length of the vector...
|
||||||
|
If you pass in whichAxis, it will fill it in with which axis
|
||||||
|
is the max...
|
||||||
|
*/
|
||||||
|
float Vector::GetMaxAxis( int *whichAxis )
|
||||||
|
{
|
||||||
|
int which_axis;
|
||||||
|
if ( !whichAxis )
|
||||||
|
{
|
||||||
|
whichAxis = &which_axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
*whichAxis = X;
|
||||||
|
|
||||||
|
if ( Abs( this->col[ Y ] ) > Abs( this->col[ X ] ) )
|
||||||
|
{
|
||||||
|
if ( Abs( this->col[ Z ] ) > Abs( this->col[ Y ] ) )
|
||||||
|
*whichAxis = Z;
|
||||||
|
else
|
||||||
|
*whichAxis = Y;
|
||||||
|
}
|
||||||
|
else if ( Abs( this->col[ Z ] ) > Abs( this->col[ X ] ) )
|
||||||
|
{
|
||||||
|
*whichAxis = Z;
|
||||||
|
}
|
||||||
|
return ( this->col[ *whichAxis ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector::DegreesToRadians( void )
|
||||||
|
{
|
||||||
|
this->col[ X ] = DEGREES_TO_RADIANS( this->col[ X ] );
|
||||||
|
this->col[ Y ] = DEGREES_TO_RADIANS( this->col[ Y ] );
|
||||||
|
this->col[ Z ] = DEGREES_TO_RADIANS( this->col[ Z ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector::RadiansToDegrees( void )
|
||||||
|
{
|
||||||
|
this->col[ X ] = RADIANS_TO_DEGREES( this->col[ X ] );
|
||||||
|
this->col[ Y ] = RADIANS_TO_DEGREES( this->col[ Y ] );
|
||||||
|
this->col[ Z ] = RADIANS_TO_DEGREES( this->col[ Z ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vector::FeetToInches( void )
|
||||||
|
{
|
||||||
|
this->col[ X ] = FEET_TO_INCHES( this->col[ X ] );
|
||||||
|
this->col[ Y ] = FEET_TO_INCHES( this->col[ Y ] );
|
||||||
|
this->col[ Z ] = FEET_TO_INCHES( this->col[ Z ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to 3d studio max coords ( Z+ up, Y- forward, X to the right... )
|
||||||
|
void Vector::ConvertToMaxCoords( void )
|
||||||
|
{
|
||||||
|
this->col[ X ] = -this->col[ X ];
|
||||||
|
float temp = this->col[ Y ];
|
||||||
|
this->col[ Y ] = -this->col[ Z ];
|
||||||
|
this->col[ Z ] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert to 3d studio max coords ( Z+ up, Y- forward, X to the right... )
|
||||||
|
void Vector::ConvertFromMaxCoords( void )
|
||||||
|
{
|
||||||
|
this->col[ X ] = -this->col[ X ];
|
||||||
|
float temp = this->col[ Y ];
|
||||||
|
this->col[ Y ] = this->col[ Z ];
|
||||||
|
this->col[ Z ] = -temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetAngle( const Matrix ¤tOrientation, const Vector &desiredHeading, int headingAxis, int rotAxis )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( headingAxis == X || headingAxis == Y || headingAxis == Z,( "Improper heading axis." ));
|
||||||
|
Dbg_MsgAssert( rotAxis == X || rotAxis == Y || rotAxis == Z,( "Improper rot axis." ));
|
||||||
|
Dbg_MsgAssert( rotAxis != headingAxis,( "Can't use heading axis as rot axis." ));
|
||||||
|
|
||||||
|
Mth::Vector tempHeading = desiredHeading;
|
||||||
|
tempHeading.ProjectToPlane( currentOrientation[ rotAxis ] );
|
||||||
|
if ( !tempHeading.Length( ) )
|
||||||
|
{
|
||||||
|
// If our rot axis is along Y, for example, the
|
||||||
|
// target heading is right above us... Can't pick
|
||||||
|
// a rotation!
|
||||||
|
return ( 0.0f );
|
||||||
|
}
|
||||||
|
tempHeading.Normalize( );
|
||||||
|
|
||||||
|
// while we have these two vectors, find the angle between them...
|
||||||
|
float angCos = DotProduct( currentOrientation[ headingAxis ], tempHeading );
|
||||||
|
|
||||||
|
// Mick: contrain Dot product to range -1.0f to +1.0f, since FP innacuracies might
|
||||||
|
// make it go outside this range
|
||||||
|
// (previously this was done only on NGC. Not sure why it has started failing now
|
||||||
|
// but it seems logical that it would fail occasionally, so this check is necessary)
|
||||||
|
float ang = angCos;
|
||||||
|
if ( ang > 1.0f ) ang = 1.0f;
|
||||||
|
if ( ang < -1.0f ) ang = -1.0f;
|
||||||
|
float retVal = -acosf( ang );
|
||||||
|
|
||||||
|
Mth::Vector temp = Mth::CrossProduct( currentOrientation[ headingAxis ], tempHeading );
|
||||||
|
|
||||||
|
// check to see if the cross product is in the same quatrant as our rot axis...
|
||||||
|
// if so, gots to rotate the other way and shit like that...
|
||||||
|
int whichAxis;
|
||||||
|
float tempMax = temp.GetMaxAxis( &whichAxis );
|
||||||
|
if ( ( tempMax > 0 ) == ( currentOrientation[ rotAxis ][ whichAxis ] > 0 ) )
|
||||||
|
{
|
||||||
|
return ( -retVal );
|
||||||
|
}
|
||||||
|
return ( retVal );
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetAngle(Vector &v1, Vector &v2)
|
||||||
|
{
|
||||||
|
Vector a=v1;
|
||||||
|
Vector b=v2;
|
||||||
|
a.Normalize();
|
||||||
|
b.Normalize();
|
||||||
|
float dot = Mth::DotProduct(a,b);
|
||||||
|
if ( dot > 1.0f ) dot = 1.0f;
|
||||||
|
if ( dot < -1.0f ) dot = -1.0f;
|
||||||
|
return Mth::RadToDeg(acosf(dot));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the angle between a and b is greater than the passed Angle.
|
||||||
|
bool AngleBetweenGreaterThan(const Vector& a, const Vector& b, float Angle)
|
||||||
|
{
|
||||||
|
float dot=Mth::DotProduct(a,b);
|
||||||
|
float len=a.Length();
|
||||||
|
if (len<0.5f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dot/=len;
|
||||||
|
|
||||||
|
len=b.Length();
|
||||||
|
if (len<0.5f)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dot/=len;
|
||||||
|
|
||||||
|
float TestAngleCosine=cosf(Mth::DegToRad(Angle));
|
||||||
|
|
||||||
|
if (dot>=0.0f)
|
||||||
|
{
|
||||||
|
return dot<TestAngleCosine;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (TestAngleCosine>=0.0f)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return dot<TestAngleCosine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mick:
|
||||||
|
// Given two vectors, v1 and v2 and an Axis vector
|
||||||
|
// return the amount that v1 would have to rotate about the Axis
|
||||||
|
// in order to be pointing in the same direction as v2
|
||||||
|
// when viewed along the Axis
|
||||||
|
//
|
||||||
|
// Typically, "Axis" will be the Y axis of the object (Like the skater)
|
||||||
|
// and v1 will be the Z direction
|
||||||
|
// which we want to rotate toward v2 (about Y)
|
||||||
|
//
|
||||||
|
// retunr value will be in the range -PI .. PI (-180 to 180 degrees)
|
||||||
|
float GetAngleAbout(Vector &v1, Vector &v2, Vector &Axis)
|
||||||
|
{
|
||||||
|
Axis.Normalize();
|
||||||
|
v1.ProjectToPlane(Axis);
|
||||||
|
v2.ProjectToPlane(Axis);
|
||||||
|
v1.Normalize();
|
||||||
|
v2.Normalize();
|
||||||
|
Vector v3 = Mth::CrossProduct(Axis,v1);
|
||||||
|
float v1_dot = Mth::DotProduct(v1,v2);
|
||||||
|
float v3_dot = Mth::DotProduct(v3,v2);
|
||||||
|
|
||||||
|
float angle = acosf(Mth::Clamp(v1_dot, -1.0f, 1.0f));
|
||||||
|
|
||||||
|
if (v3_dot < 0.0f)
|
||||||
|
{
|
||||||
|
angle = -angle;
|
||||||
|
}
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_OVERFLOW_VECTORS
|
||||||
|
|
||||||
|
const float& Vector::operator[] ( sint i ) const
|
||||||
|
{
|
||||||
|
// Dbg_MsgAssert (Abs(col[i]) < 1000000000.0f || col[i]==1.0e+30f,("vector component (%f) over a billion!!!",col[i]));
|
||||||
|
Dbg_MsgAssert (!isnanf(col[i]),("vector component [%d] (%f) not a number!!!!",i,col[i]));
|
||||||
|
// Dbg_MsgAssert (!isinff(col[i]),("vector component [%d] (%f) infinite!!!!",i,col[i]));
|
||||||
|
return col[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_UNINIT_VECTORS
|
||||||
|
|
||||||
|
const float& Vector::operator[] ( sint i ) const
|
||||||
|
{
|
||||||
|
// This assertion will catch any of the predefined NaN values that we initilize the vectors and matrix to
|
||||||
|
// when DEBUG_UNINIT_VECTORS is defined.
|
||||||
|
Dbg_MsgAssert ( (*(uint32*)(&col[i]) & 0xffffff00) != 0x7F800000,("uninitialized vector[%d] = 0x%x",i,(*(uint32*)(&col[i]))));
|
||||||
|
return col[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for debugging purposes, this function is not inline when we want the
|
||||||
|
// uninitialized vector debugging
|
||||||
|
// as it makes it easier to track down wehre the problem is
|
||||||
|
Vector& Vector::operator= ( const Vector& v )
|
||||||
|
{
|
||||||
|
|
||||||
|
col[X] = v[X];
|
||||||
|
col[Y] = v[Y];
|
||||||
|
col[Z] = v[Z];
|
||||||
|
col[W] = v[W];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Vector::PrintContents() const
|
||||||
|
{
|
||||||
|
// printf( "-----------------\n" );
|
||||||
|
printf( "[%f %f %f %f]\n", col[X], col[Y], col[Z], col[W] );
|
||||||
|
// printf( "-----------------\n" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
242
Code/Core/Math/vector.h
Normal file
242
Code/Core/Math/vector.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math/Vector.h **
|
||||||
|
** **
|
||||||
|
** Created: 11/29/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Vector Math Class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_VECTOR_H
|
||||||
|
#define __CORE_MATH_VECTOR_H
|
||||||
|
|
||||||
|
// (Mick) If this is defined, then vectors will be initialized to (0,0,0,1), and
|
||||||
|
// matrices to:
|
||||||
|
// (1,0,0,0)
|
||||||
|
// (0,1,0,0)
|
||||||
|
// (0,0,1,0)
|
||||||
|
// (0,0,0,1)
|
||||||
|
// This is sligtly differnet to before, where mats were intialized to all (0,0,0,1)
|
||||||
|
// since they were defined as an Array of vecotors
|
||||||
|
// This makes the code run about 3% slower (on PS2), which is why we don't use it
|
||||||
|
//#define __INITIALIZE_VECTORS__
|
||||||
|
|
||||||
|
// you can catch code that used to rely on this (and other bugs)
|
||||||
|
// by uncommenting the following line
|
||||||
|
// this will initilize the vectors to garbage values
|
||||||
|
// and check all accesses of vectors to see if these values
|
||||||
|
// have been left before using....
|
||||||
|
// (this requires a full recompile, and makes the code run really slow)
|
||||||
|
//#define DEBUG_UNINIT_VECTORS
|
||||||
|
|
||||||
|
|
||||||
|
// we also might want to catch situations where a component of a vector is very large
|
||||||
|
// which could indicate some potential overflow, especially if the W components is
|
||||||
|
// accumalating errors, getting unseemly large, then getting incorporated
|
||||||
|
// into an equation that involves X,Y,Z
|
||||||
|
// (see Quat::Rotate for an example)
|
||||||
|
//#define DEBUG_OVERFLOW_VECTORS
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/math/rot90.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
X, Y, Z, W
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Mth
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Quat; // forward refs
|
||||||
|
class Matrix;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: Vector
|
||||||
|
*
|
||||||
|
* Description: Vector math class
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class Vector
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Made special enum so we can have a constructor that does not initialize
|
||||||
|
enum ENoInitType
|
||||||
|
{
|
||||||
|
NO_INIT
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector ( );
|
||||||
|
Vector ( ENoInitType ); /// A constructor that doesn't init the members.
|
||||||
|
Vector ( float cx, float cy, float cz );
|
||||||
|
Vector ( float cx, float cy, float cz, float cw );
|
||||||
|
// Vector ( float cx = 0.0f, float cy = 0.0f, float cz = 0.0f, float cw = 1.0f );
|
||||||
|
Vector ( const Vector& v );
|
||||||
|
|
||||||
|
|
||||||
|
Vector& operator= ( const Vector& v );
|
||||||
|
bool operator== ( const Vector& v ) const;
|
||||||
|
bool operator!= ( const Vector& v ) const;
|
||||||
|
Vector& operator+= ( const Vector& v );
|
||||||
|
Vector& operator-= ( const Vector& v );
|
||||||
|
Vector& operator*= ( const float s );
|
||||||
|
Vector& operator/= ( float s );
|
||||||
|
Vector& operator*= ( const Vector& v );
|
||||||
|
Vector& operator/= ( const Vector& v );
|
||||||
|
Vector& operator*= ( const Matrix& mat );
|
||||||
|
const float& operator[] ( sint i ) const;
|
||||||
|
float& operator[] ( sint i );
|
||||||
|
|
||||||
|
Vector& Set ( float cx = 0.0f, float cy = 0.0f, float cz = 0.0f, float cw = 1.0f );
|
||||||
|
float Length ( void ) const;
|
||||||
|
float LengthSqr ( void ) const;
|
||||||
|
Vector& Negate ( void ); // this = -this
|
||||||
|
Vector& Negate ( const Vector& src ); // this = -src
|
||||||
|
Vector& Normalize ( ); // faster version normlaizes to 1
|
||||||
|
Vector& Normalize ( float len);
|
||||||
|
|
||||||
|
Vector& ShearX ( float shy, float shz );
|
||||||
|
Vector& ShearY ( float shx, float shz );
|
||||||
|
Vector& ShearZ ( float shx, float shy );
|
||||||
|
|
||||||
|
Vector& RotateX ( float s, float c );
|
||||||
|
Vector& RotateY ( float s, float c );
|
||||||
|
Vector& RotateZ ( float s, float c );
|
||||||
|
|
||||||
|
Vector& RotateX ( float angle );
|
||||||
|
Vector& RotateY ( float angle );
|
||||||
|
Vector& RotateZ ( float angle );
|
||||||
|
|
||||||
|
Vector& Rotate ( const Quat& quat );
|
||||||
|
Vector& Rotate ( const Matrix& matrix );
|
||||||
|
Vector& Rotate ( const Vector& axis, const float angle );
|
||||||
|
|
||||||
|
// 90 degree increment Rotation (uses no multiplication)
|
||||||
|
Vector& RotateY90 ( ERot90 angle );
|
||||||
|
|
||||||
|
Vector& Scale ( float scale );
|
||||||
|
Vector& Scale ( const Vector& scale );
|
||||||
|
|
||||||
|
Vector& RotateToPlane(const Vector& normal);
|
||||||
|
Vector& RotateToNormal(const Vector& normal);
|
||||||
|
Vector& ProjectToPlane(const Vector& normal);
|
||||||
|
Vector& ProjectToNormal(const Vector& normal);
|
||||||
|
|
||||||
|
Vector& ZeroIfShorterThan ( float length );
|
||||||
|
|
||||||
|
Vector& ClampMin ( float min );
|
||||||
|
Vector& ClampMax ( float max );
|
||||||
|
Vector& Clamp ( float min = 0.0f, float max = 1.0f );
|
||||||
|
Vector& ClampMin ( Vector& min );
|
||||||
|
Vector& ClampMax ( Vector& max );
|
||||||
|
Vector& Clamp ( Vector& min, Vector& max );
|
||||||
|
|
||||||
|
float GetX ( void ) const;
|
||||||
|
float GetY ( void ) const;
|
||||||
|
float GetZ ( void ) const;
|
||||||
|
float GetW ( void ) const;
|
||||||
|
float GetMaxAxis ( int *whichAxis = NULL );
|
||||||
|
|
||||||
|
void DegreesToRadians( void );
|
||||||
|
void RadiansToDegrees( void );
|
||||||
|
void FeetToInches( void );
|
||||||
|
// convert to 3d studio max coords ( Z+ up, Y- forward, X to the right... )
|
||||||
|
void ConvertToMaxCoords( void );
|
||||||
|
void ConvertFromMaxCoords( void );
|
||||||
|
|
||||||
|
// debug info
|
||||||
|
void PrintContents() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
NUM_ELEMENTS = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
float col[NUM_ELEMENTS];
|
||||||
|
} nAlign(128);
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Vector operator+ ( const Vector& v1, const Vector& v2 );
|
||||||
|
Vector operator- ( const Vector& v1, const Vector& v2 );
|
||||||
|
Vector operator* ( const Vector& v, const float s );
|
||||||
|
Vector operator* ( const float s, const Vector& v );
|
||||||
|
Vector operator* ( const Vector& v, const Matrix& m );
|
||||||
|
Vector operator/ ( const Vector& v, const float s );
|
||||||
|
Vector operator- ( const Vector& v );
|
||||||
|
float DotProduct ( const Vector& v1, const Vector& v2 );
|
||||||
|
Vector CrossProduct ( const Vector& v1, const Vector& v2 );
|
||||||
|
Vector Clamp ( const Vector& v, float min = 0.0f, float max = 1.0f );
|
||||||
|
Vector Clamp ( const Vector& v, Vector& min, Vector& max );
|
||||||
|
float Distance ( const Vector& v1, const Vector& v2 );
|
||||||
|
float DistanceSqr ( const Vector& v1, const Vector& v2 );
|
||||||
|
float GetAngle ( const Matrix ¤tOrientation, const Vector &desiredHeading, int headingAxis = Z, int rotAxis = Y );
|
||||||
|
float GetAngle(Vector &v1, Vector &v2);
|
||||||
|
bool AngleBetweenGreaterThan(const Vector& a, const Vector& b, float Angle);
|
||||||
|
float GetAngleAbout(Vector &v1, Vector &v2, Vector &Axis);
|
||||||
|
bool Equal ( const Vector& v1, const Vector& v2, const float tol = 0.0001f );
|
||||||
|
Vector Lerp ( const Vector& v1, const Vector& v2, const float val );
|
||||||
|
Vector Min ( const Vector& v1, const Vector& v2 );
|
||||||
|
Vector Max ( const Vector& v1, const Vector& v2 );
|
||||||
|
Vector Min ( const Vector& v, float c );
|
||||||
|
Vector Max ( const Vector& v, float c );
|
||||||
|
void Swap ( Vector& a, Vector& b );
|
||||||
|
ostream& operator<< ( ostream& os, const Vector& v );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Mth
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_VECTOR_H
|
||||||
|
|
1205
Code/Core/Math/vector.inl
Normal file
1205
Code/Core/Math/vector.inl
Normal file
File diff suppressed because it is too large
Load Diff
346
Code/Core/String/CString.cpp
Normal file
346
Code/Core/String/CString.cpp
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: String **
|
||||||
|
** **
|
||||||
|
** File name: Core\String\CString.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 9/20/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A handy, safe class to represent a string **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/string/cstring.h>
|
||||||
|
#include <sys/mem/memman.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Str
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const int String::s_max_size = 256;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
int String::sDumbCount = 0;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Function:
|
||||||
|
*
|
||||||
|
* Description: Default constructor
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
String::String( void )
|
||||||
|
: mp_string( NULL )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
m_dumbNum = sDumbCount;
|
||||||
|
sDumbCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Description: First copy constructor
|
||||||
|
* (called by: String x = "blah";)
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
String::String( const char* string )
|
||||||
|
: mp_string ( NULL )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
m_dumbNum = sDumbCount;
|
||||||
|
sDumbCount++;
|
||||||
|
|
||||||
|
// call operator= function
|
||||||
|
*this = string;
|
||||||
|
|
||||||
|
//Ryan("copy successful\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Description: Second copy constructor
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
String::String( const String& string )
|
||||||
|
: mp_string ( NULL )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
// call operator= function
|
||||||
|
*this = string;
|
||||||
|
|
||||||
|
m_dumbNum = sDumbCount;
|
||||||
|
sDumbCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Description: destructor
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
String::~String( void )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//Ryan("Am deleting string");
|
||||||
|
|
||||||
|
if (mp_string)
|
||||||
|
{
|
||||||
|
delete [] mp_string;
|
||||||
|
mp_string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ryan("\n");
|
||||||
|
sDumbCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
String & String::operator= (const char * string)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
int last_char = 0;
|
||||||
|
if ( string )
|
||||||
|
{
|
||||||
|
last_char = strlen(string) - 1;
|
||||||
|
|
||||||
|
// Fix the case where "string" is the empty string
|
||||||
|
if( last_char < 0 )
|
||||||
|
{
|
||||||
|
last_char = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
copy(string, 0, last_char);
|
||||||
|
|
||||||
|
//Ryan("Copying %s to String\n", mp_string);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
String & String::operator= (const String & string)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert(this != &string,( "can't assign a String to itself"));
|
||||||
|
|
||||||
|
// call other operator= function
|
||||||
|
*this = string.mp_string;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool String::operator== (const char * string)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//Ryan("comparing String to string: %s to %s\n", mp_string, string);
|
||||||
|
if (mp_string && string)
|
||||||
|
{
|
||||||
|
return (strcmp(mp_string, string) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (!mp_string && !string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool String::operator== (const String & string)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//Ryan("comparing String to String: %s to %s\n", mp_string, string.mp_string);
|
||||||
|
return (*this == string.mp_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool String::operator!()
|
||||||
|
{
|
||||||
|
return (mp_string == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Description: Returns pointer to internal char * array. Maybe should be const.
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const char * String::getString() const
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
return mp_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void String::copy(const char *pChar, int first_char, int last_char)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( pChar && last_char >= first_char)
|
||||||
|
{
|
||||||
|
// GJ: The following handles 1-byte long strings incorrectly:
|
||||||
|
// if ( first_char == last_char )
|
||||||
|
|
||||||
|
if ( pChar[first_char] == 0 )
|
||||||
|
{
|
||||||
|
if (mp_string)
|
||||||
|
{
|
||||||
|
delete [] mp_string;
|
||||||
|
}
|
||||||
|
mp_string = new char[1];
|
||||||
|
mp_string[0] = 0;
|
||||||
|
m_length = 2; // MICK-GJ: Set length to 2, so it matches what we have below
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int length = last_char - first_char + 2;
|
||||||
|
if (length < 4) length = 4;
|
||||||
|
Dbg_MsgAssert (length <= s_max_size,( "string too long for String object"));
|
||||||
|
|
||||||
|
// if current string exists and is smaller than new string, delete it
|
||||||
|
if ( mp_string && ( length > m_length ))
|
||||||
|
{
|
||||||
|
delete [] mp_string;
|
||||||
|
mp_string = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if current string doesn't exist, or has been deleted, make a new one
|
||||||
|
if ( !mp_string )
|
||||||
|
{
|
||||||
|
m_length = length;
|
||||||
|
mp_string = new char[m_length];
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform string copy
|
||||||
|
int i = 0;
|
||||||
|
int j;
|
||||||
|
for (j = first_char; j <= last_char; j++)
|
||||||
|
{
|
||||||
|
mp_string[i] = pChar[j];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
mp_string[i] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( mp_string )
|
||||||
|
{
|
||||||
|
delete [] mp_string;
|
||||||
|
mp_string = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ryan("copied string %s\n", pChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace String
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
113
Code/Core/String/CString.h
Normal file
113
Code/Core/String/CString.h
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: String **
|
||||||
|
** **
|
||||||
|
** File name: Core\String\CString.h **
|
||||||
|
** **
|
||||||
|
** Created by: 9/20/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A handy, safe class to represent a string **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_STRING_STRING_H
|
||||||
|
#define __CORE_STRING_STRING_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_SUPPORT_CLASS_H
|
||||||
|
#include <core/support/class.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Str
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Class: String
|
||||||
|
*
|
||||||
|
* Description: A handy, safe class for representing a string.
|
||||||
|
*
|
||||||
|
* Usage: String x = "try our new diet of pinecones";
|
||||||
|
* String y = x;
|
||||||
|
* printf("%s\n", y.getString());
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
class String : public Spt::Class // fix bug delete[] !!!
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
String();
|
||||||
|
String(const char *string);
|
||||||
|
String(const String &string);
|
||||||
|
~String();
|
||||||
|
|
||||||
|
String& operator= (const char * string);
|
||||||
|
String& operator= (const String & string);
|
||||||
|
bool operator== (const char * string);
|
||||||
|
bool operator== (const String & string);
|
||||||
|
bool operator!();
|
||||||
|
|
||||||
|
const char* getString() const;
|
||||||
|
void copy(const char *pChar, int first_char, int last_char);
|
||||||
|
|
||||||
|
int m_dumbNum;
|
||||||
|
static int sDumbCount;
|
||||||
|
|
||||||
|
private:
|
||||||
|
char* mp_string;
|
||||||
|
int m_length;
|
||||||
|
|
||||||
|
|
||||||
|
static const int s_max_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace String
|
||||||
|
|
||||||
|
#endif // __CORE_STRING_STRING_H
|
||||||
|
|
||||||
|
|
247
Code/Core/String/stringutils.cpp
Normal file
247
Code/Core/String/stringutils.cpp
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: **
|
||||||
|
** **
|
||||||
|
** Module: String **
|
||||||
|
** **
|
||||||
|
** File name: stringutils.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/31/01 - Mick **
|
||||||
|
** **
|
||||||
|
** Description: useful string (char *) utilities **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <sys/config/config.h>
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Str
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define Caseless(letter) (((letter)>='A' && (letter)<='Z')?((letter)+'a'-'A'):letter)
|
||||||
|
|
||||||
|
// Returns location of Needle in the Haystack
|
||||||
|
const char * StrStr (const char *pHay, const char *pNeedle)
|
||||||
|
{
|
||||||
|
register char First = *pNeedle++; // get first letter in needle
|
||||||
|
if (!First) return 0; // if end of needle, then return NULL
|
||||||
|
First = Caseless(First);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
while (1) // scan Haystack one letter at a time
|
||||||
|
{
|
||||||
|
char FirstHay = *pHay++; // get first letter of haystack
|
||||||
|
FirstHay = Caseless(FirstHay);
|
||||||
|
if (FirstHay == First) break; // first letter matches, so drop into other code
|
||||||
|
if (!FirstHay) return 0; // if end of haystack, then return NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pH = pHay; // second letter of hay
|
||||||
|
const char *pN = pNeedle; // second letter of needle
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
char n = *pN++; // get a needle letter
|
||||||
|
if (!n) return pHay-1; // end of needle, so return pointer to start of string in haystack
|
||||||
|
char h = *pH++; // get a hay letter
|
||||||
|
if (Caseless(n) != Caseless(h)) break; // difference, so stop looping (could be end of haystack, which is valid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LowerCase(char *p)
|
||||||
|
{
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
char letter = *p;
|
||||||
|
if (letter>='A' && letter<='Z')
|
||||||
|
letter+='a'-'A';
|
||||||
|
*p++ = letter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpperCase(char *p)
|
||||||
|
{
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
char letter = *p;
|
||||||
|
if (letter>='a' && letter<='z')
|
||||||
|
letter-='a'-'A';
|
||||||
|
*p++ = letter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WhiteSpace(char *p)
|
||||||
|
{
|
||||||
|
if (*p == 0x20 || *p== 0x09)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *PrintThousands(int n, char c)
|
||||||
|
{
|
||||||
|
static char buffer[32]; // enough for any int
|
||||||
|
char normal[32]; // printf in here without commas
|
||||||
|
char *p = buffer;
|
||||||
|
|
||||||
|
if (n<0)
|
||||||
|
{
|
||||||
|
*p++ = '-';
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
sprintf (normal, "%d", n);
|
||||||
|
int digits = strlen(normal);
|
||||||
|
char *p_digit = normal;
|
||||||
|
|
||||||
|
// Since other countries deliminate their successive kilos differently
|
||||||
|
switch (Config::GetLanguage())
|
||||||
|
{
|
||||||
|
case Config::LANGUAGE_FRENCH:
|
||||||
|
c=' ';
|
||||||
|
break;
|
||||||
|
case Config::LANGUAGE_SPANISH:
|
||||||
|
c='.';
|
||||||
|
break;
|
||||||
|
case Config::LANGUAGE_GERMAN:
|
||||||
|
c='.';
|
||||||
|
break;
|
||||||
|
case Config::LANGUAGE_ITALIAN:
|
||||||
|
c='.';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
c=',';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (digits)
|
||||||
|
{
|
||||||
|
*p++ = *p_digit++;
|
||||||
|
digits--;
|
||||||
|
if ( digits && ( digits % 3) == 0)
|
||||||
|
{
|
||||||
|
*p++ = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p++ = 0;
|
||||||
|
// printf ("%s\n",buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// helper function for SText::Draw(), SFont::QueryString()
|
||||||
|
uint DehexifyDigit(const char *pLetter)
|
||||||
|
{
|
||||||
|
uint digit = 0;
|
||||||
|
if (*pLetter >= '0' && *pLetter <= '9')
|
||||||
|
digit = *pLetter - '0';
|
||||||
|
else if (*pLetter >= 'a' && *pLetter <= 'v')
|
||||||
|
digit = *pLetter - 'a' + 10;
|
||||||
|
else if (*pLetter >= 'A' && *pLetter <= 'V')
|
||||||
|
digit = *pLetter - 'A' + 10;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0, ("Non Hex digit"));
|
||||||
|
}
|
||||||
|
return digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns
|
||||||
|
// -1 if a<b
|
||||||
|
// 0 -f a==b
|
||||||
|
// 1 if a>b
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if
|
||||||
|
int Compare(const char *p_a, const char *p_b)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char a = *p_a++;
|
||||||
|
char b = *p_b++;
|
||||||
|
a = Caseless(a);
|
||||||
|
b = Caseless(b);
|
||||||
|
if (a < b)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a > b)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!a && !b)
|
||||||
|
{
|
||||||
|
// strings are identical
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!a)
|
||||||
|
{
|
||||||
|
// a is shorter, so a < b
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
|
// b is shorter, so b < a
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Str
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
80
Code/Core/String/stringutils.h
Normal file
80
Code/Core/String/stringutils.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: **
|
||||||
|
** **
|
||||||
|
** Module: String **
|
||||||
|
** **
|
||||||
|
** File name: stringutils.h **
|
||||||
|
** **
|
||||||
|
** Created by: 05/31/01 - Mick **
|
||||||
|
** **
|
||||||
|
** Description: useful string (char *) utilities **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_STRING_STRINGUTILS_H
|
||||||
|
#define __CORE_STRING_STRINGUTILS_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Str
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const char* StrStr(const char* pHay, const char* pNeedle);
|
||||||
|
void LowerCase(char* p);
|
||||||
|
void UpperCase(char* p);
|
||||||
|
int WhiteSpace(char* p);
|
||||||
|
char * PrintThousands(int n, char c = ',');
|
||||||
|
uint DehexifyDigit(const char *pLetter);
|
||||||
|
int Compare(const char *p_a, const char *p_b);
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Str
|
||||||
|
|
||||||
|
#endif // __DIR_SUBDIR_FILE_H
|
||||||
|
|
||||||
|
|
127
Code/Core/StringHashTable.h
Normal file
127
Code/Core/StringHashTable.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core library **
|
||||||
|
** **
|
||||||
|
** Module: HashTable **
|
||||||
|
** **
|
||||||
|
** File name: Core\HashTable.h **
|
||||||
|
** **
|
||||||
|
** Created by: 9/22/2000 - rjm **
|
||||||
|
** **
|
||||||
|
** Description: A handy Hashtable class **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LIST_STRINGHASHTABLE_H
|
||||||
|
#define __CORE_LIST_STRINGHASHTABLE_H
|
||||||
|
|
||||||
|
#ifndef __PLAT_WN32__
|
||||||
|
#include <sys/mem/PoolManager.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "HashTable.h"
|
||||||
|
|
||||||
|
namespace Crc
|
||||||
|
{
|
||||||
|
uint32 GenerateCRCFromString( const char *pName );
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Script
|
||||||
|
{
|
||||||
|
// So as not to require inclusion of checksum.h
|
||||||
|
#ifdef __NOPT_ASSERT__
|
||||||
|
const char *FindChecksumName(uint32 checksum);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template<class _V>
|
||||||
|
class StringHashTable : public HashTable<_V>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
StringHashTable(int numBits);
|
||||||
|
|
||||||
|
bool PutItem(const char *stringKey, _V *item);
|
||||||
|
_V * GetItem(const char *stringKey, bool assert_if_clash = true);
|
||||||
|
void FlushItem(const char *stringKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
StringHashTable<_V>::StringHashTable(int numBits) :
|
||||||
|
HashTable<_V>(numBits)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
bool StringHashTable<_V>::PutItem(const char *stringKey, _V *item)
|
||||||
|
{
|
||||||
|
uint32 key = Crc::GenerateCRCFromString(stringKey);
|
||||||
|
return HashTable<_V>::PutItem(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
_V *StringHashTable<_V>::GetItem(const char *stringKey, bool assert_if_clash)
|
||||||
|
{
|
||||||
|
uint32 key = Crc::GenerateCRCFromString(stringKey);
|
||||||
|
return HashTable<_V>::GetItem(key, assert_if_clash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class _V> //inline
|
||||||
|
void StringHashTable<_V>::FlushItem(const char *stringKey)
|
||||||
|
{
|
||||||
|
uint32 key = Crc::GenerateCRCFromString(stringKey);
|
||||||
|
HashTable<_V>::FlushItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Lst
|
||||||
|
|
||||||
|
#endif // __CORE_LIST_STRINGHASHTABLE_H
|
||||||
|
|
||||||
|
|
149
Code/Core/Support/Lock.h
Normal file
149
Code/Core/Support/Lock.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Support (SPT) **
|
||||||
|
** **
|
||||||
|
** File name: core/support/lock.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_LOCK_H
|
||||||
|
#define __CORE_LOCK_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
namespace Spt
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Access : public Spt::Class
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
Access();
|
||||||
|
|
||||||
|
void Forbid( void );
|
||||||
|
void Permit( void );
|
||||||
|
void Enable( void );
|
||||||
|
bool HaveAccess( void );
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
sint m_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline Access::Access()
|
||||||
|
: m_count( 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Access::Forbid( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Access::Permit( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Access::Enable( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool Access::HaveAccess ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return( m_count == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Spt
|
||||||
|
|
||||||
|
#endif // __CORE_LOCK_H
|
||||||
|
|
150
Code/Core/Support/Ref.h
Normal file
150
Code/Core/Support/Ref.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Support (SPT) **
|
||||||
|
** **
|
||||||
|
** File name: core/support/lock.h **
|
||||||
|
** **
|
||||||
|
** Created: 03/16/00 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_REF_H
|
||||||
|
#define __CORE_REF_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Spt
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Ref : public Spt::Class
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
Ref();
|
||||||
|
Ref( const Ref& rhs );
|
||||||
|
|
||||||
|
void Acquire( void );
|
||||||
|
void Release( void );
|
||||||
|
bool InUse( void );
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
sint m_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline Ref::Ref ()
|
||||||
|
: m_count( 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
inline Ref::Ref( const Ref& rhs )
|
||||||
|
: m_count( 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Ref::Acquire ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void Ref::Release ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert(m_count>0,("Tried to call Release when m_count was already zero"));
|
||||||
|
m_count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool Ref::InUse ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return ( m_count != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Spt
|
||||||
|
|
||||||
|
#endif // __CORE_REF_H
|
||||||
|
|
272
Code/Core/Support/class.cpp
Normal file
272
Code/Core/Support/class.cpp
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Support (SPT) **
|
||||||
|
** **
|
||||||
|
** File name: class.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 06/10/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Base class from which all other classes are derived. **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <sys/mem/memman.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define NUM_ADDRESS 0 // Change this to 8 to have a handy list of addresses to check.
|
||||||
|
// If set to 0, no extra code/data will be generated.
|
||||||
|
// Remember to change to 8, compile, then get the addresses in question
|
||||||
|
// as the act of adding this code/data will change your addresses.
|
||||||
|
#if NUM_ADDRESS > 0
|
||||||
|
uint32 gAddress[NUM_ADDRESS] =
|
||||||
|
{
|
||||||
|
0x81701061,
|
||||||
|
0x81700ee1,
|
||||||
|
0x81700d61,
|
||||||
|
0x81700be1,
|
||||||
|
0x81700a61,
|
||||||
|
0x817008e1,
|
||||||
|
0x81700761,
|
||||||
|
0x817005e1
|
||||||
|
};
|
||||||
|
|
||||||
|
static void check_address( void * p, int size )
|
||||||
|
{
|
||||||
|
for ( int lp = 0; lp < 8; lp++ )
|
||||||
|
{
|
||||||
|
if ( gAddress[lp] == ((uint32)p) ) {
|
||||||
|
Dbg_Message( "We found the address we're looing for: 0x%08x (%d)\n", (uint32)p, size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define check_address(a,b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGC__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
static inline void* operator new( size_t size )
|
||||||
|
{
|
||||||
|
// Dbg_SetPlacementNew( false );
|
||||||
|
void * rv = Mem::Manager::sHandle().New( size, true );
|
||||||
|
check_address( rv, size );
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
static inline void* operator new[] ( size_t size )
|
||||||
|
{
|
||||||
|
// Dbg_SetPlacementNew( false );
|
||||||
|
void * rv = Mem::Manager::sHandle().New( size, true );
|
||||||
|
check_address( rv, size );
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
static inline void operator delete( void* pAddr )
|
||||||
|
{
|
||||||
|
Mem::Manager::sHandle().Delete( pAddr );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
static inline void operator delete[]( void* pAddr )
|
||||||
|
{
|
||||||
|
Mem::Manager::sHandle().Delete( pAddr );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __PLAT_NGC__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Spt
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* new operators - same as global + zero-ed memory */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#if (defined ( ZERO_CLASS_MEM ) && !defined ( __PLAT_WN32__ ))
|
||||||
|
|
||||||
|
void* Class::operator new( size_t size )
|
||||||
|
{
|
||||||
|
void* p_ret = Mem::Manager::sHandle().New( size );
|
||||||
|
|
||||||
|
if ( p_ret )
|
||||||
|
{
|
||||||
|
memset ( p_ret, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
check_address( p_ret, size );
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new[] ( size_t size )
|
||||||
|
{
|
||||||
|
void* p_ret = Mem::Manager::sHandle().New( size );
|
||||||
|
|
||||||
|
if ( p_ret )
|
||||||
|
{
|
||||||
|
memset ( p_ret, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
check_address( p_ret, size );
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new( size_t size, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
void* p_ret = Mem::Manager::sHandle().New( size, assert_on_fail );
|
||||||
|
|
||||||
|
if ( p_ret )
|
||||||
|
{
|
||||||
|
memset ( p_ret, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
check_address( p_ret, size );
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new[] ( size_t size, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
void* p_ret = Mem::Manager::sHandle().New( size, assert_on_fail );
|
||||||
|
|
||||||
|
if ( p_ret )
|
||||||
|
{
|
||||||
|
memset ( p_ret, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
check_address( p_ret, size );
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new( size_t size, Mem::Allocator* pAlloc, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
void* p_ret = Mem::Manager::sHandle().New( size, assert_on_fail, pAlloc );
|
||||||
|
|
||||||
|
if ( p_ret )
|
||||||
|
{
|
||||||
|
memset ( p_ret, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
check_address( p_ret, size );
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new[]( size_t size, Mem::Allocator* pAlloc, bool assert_on_fail )
|
||||||
|
{
|
||||||
|
void* p_ret = Mem::Manager::sHandle().New( size, assert_on_fail, pAlloc );
|
||||||
|
|
||||||
|
if ( p_ret )
|
||||||
|
{
|
||||||
|
memset ( p_ret, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
check_address( p_ret, size );
|
||||||
|
return p_ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new( size_t size, void* pLocation )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( pLocation )
|
||||||
|
{
|
||||||
|
memset ( pLocation, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return pLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* Class::operator new[]( size_t size, void* pLocation )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( pLocation )
|
||||||
|
{
|
||||||
|
memset ( pLocation, 0, size );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return pLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
#endif
|
||||||
|
} // namespace Spt
|
||||||
|
|
63
Code/Core/Support/class.h
Normal file
63
Code/Core/Support/class.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Support (SPT) **
|
||||||
|
** **
|
||||||
|
** Created: 06/10/99 mjb **
|
||||||
|
** **
|
||||||
|
** File name: core/support/class.h **
|
||||||
|
** **
|
||||||
|
** Description: Base class from which classes are derived if they want **
|
||||||
|
** their memory zeroed when instantiated (via new) **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_SUPPORT_CLASS_H
|
||||||
|
#define __CORE_SUPPORT_CLASS_H
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define ZERO_CLASS_MEM TRUE
|
||||||
|
|
||||||
|
namespace Mem
|
||||||
|
{
|
||||||
|
class Allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Spt
|
||||||
|
{
|
||||||
|
|
||||||
|
class Class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
#if (defined ( ZERO_CLASS_MEM ) && !defined ( __PLAT_WN32__ ))
|
||||||
|
void* operator new( size_t size );
|
||||||
|
void* operator new[] ( size_t size );
|
||||||
|
void* operator new( size_t size, bool assert_on_fail );
|
||||||
|
void* operator new[] ( size_t size, bool assert_on_fail );
|
||||||
|
void* operator new( size_t size, Mem::Allocator* pAlloc, bool assert_on_fail = true );
|
||||||
|
void* operator new[]( size_t size, Mem::Allocator* pAlloc, bool assert_on_fail = true );
|
||||||
|
void* operator new( size_t size, void* pLocation );
|
||||||
|
void* operator new[]( size_t size, void* pLocation );
|
||||||
|
|
||||||
|
#endif // ZERO_CLASS_MEM
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Spt
|
||||||
|
|
||||||
|
#endif // __CORE_SUPPORT_CLASS_H
|
||||||
|
|
76
Code/Core/Support/support.h
Normal file
76
Code/Core/Support/support.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Support (SPT) **
|
||||||
|
** **
|
||||||
|
** Created: 06/10/99 mjb **
|
||||||
|
** **
|
||||||
|
** File name: core/support/support.h **
|
||||||
|
** **
|
||||||
|
** Description: template class for tracking class hierarchy **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_SUPPORT_SUPPORT_H
|
||||||
|
#define __CORE_SUPPORT_SUPPORT_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
#include <typeinfo.h>
|
||||||
|
#else
|
||||||
|
#include <typeinfo>
|
||||||
|
#endif
|
||||||
|
#include <core/support/class.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
//#define class _c : public Spt::Class class _c : public Spt::Class
|
||||||
|
//#define class _c : public _b class _c : public _b
|
||||||
|
|
||||||
|
#define nTemplateBaseClass(_t,_c) \
|
||||||
|
template< class _t > \
|
||||||
|
class _c : public Spt::Class \
|
||||||
|
|
||||||
|
#define nTemplateBaseClass2(_t1,_t2,_c) \
|
||||||
|
template< class _t1, class _t2 > \
|
||||||
|
class _c : public Spt::Class \
|
||||||
|
|
||||||
|
#define nTemplateBaseClass3(_t1,_t2,_t3,_c) \
|
||||||
|
template< class _t1, class _t2, class _t3 > \
|
||||||
|
class _c : public Spt::Class \
|
||||||
|
|
||||||
|
#define nTemplateSubClass(_t,_c,_b) \
|
||||||
|
template< class _t > \
|
||||||
|
class _c : public _b \
|
||||||
|
|
||||||
|
#define nTemplateSubClass2(_t1,_t2,_c,_b) \
|
||||||
|
template< class _t1, class _t2 > \
|
||||||
|
class _c : public _b \
|
||||||
|
|
||||||
|
#define nTemplateSubClass3(_t1,_t2,_t3,_c,_b) \
|
||||||
|
template< class _t1, class _t2, class _t3 > \
|
||||||
|
class _c : public _b \
|
||||||
|
|
||||||
|
|
||||||
|
#define Dbg_TemplateBaseClass(_t1,_c)
|
||||||
|
#define Dbg_TemplateSubClass(_t1,_c,_b)
|
||||||
|
|
||||||
|
#define Dbg_TemplateBaseClass(_t1,_c)
|
||||||
|
#define Dbg_TemplateSubClass(_t1,_c,_b)
|
||||||
|
|
||||||
|
#define Dbg_TemplateBaseClass2(_t1,_t2,_c)
|
||||||
|
#define Dbg_TemplateSubClass2(_t1,_t2,_c,_b)
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __CORE_SUPPORT_SUPPORT_H
|
67
Code/Core/Task.h
Normal file
67
Code/Core/Task.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task (TSK) **
|
||||||
|
** **
|
||||||
|
** File name: core/task.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_TASK_H
|
||||||
|
#define __CORE_TASK_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/task/task.h>
|
||||||
|
#include <core/task/list.h>
|
||||||
|
#include <core/task/stack.h>
|
||||||
|
#include <core/task/hook.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#endif // __CORE_TASK_H
|
||||||
|
|
||||||
|
|
158
Code/Core/Task/Hook.h
Normal file
158
Code/Core/Task/Hook.h
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task (TSK_) **
|
||||||
|
** **
|
||||||
|
** File name: core/task/hook.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_TASK_HOOK_H
|
||||||
|
#define __CORE_TASK_HOOK_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Class: BaseHook
|
||||||
|
*
|
||||||
|
* Description: abstract base class for code hook
|
||||||
|
* defines minimal interface
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
class BaseHook : public Spt::Class
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
virtual void Call( void ) const = 0;
|
||||||
|
|
||||||
|
protected :
|
||||||
|
|
||||||
|
BaseHook( void ) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* Class: Hook< _T >
|
||||||
|
*
|
||||||
|
* Description: derived template class for hook with typed data field
|
||||||
|
*
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
nTemplateSubClass( _T, Hook, BaseHook )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
typedef void ( Code )( const Hook< _T >& );
|
||||||
|
|
||||||
|
Hook( Code* code, _T& data );
|
||||||
|
|
||||||
|
void Call( void ) const;
|
||||||
|
_T& GetData( void ) const;
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
Code* const code;
|
||||||
|
_T& data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Hook< _T >::Hook( Code* _code, _T& _data )
|
||||||
|
: code( _code ), data( _data )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Hook< _T >::Call( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( code );
|
||||||
|
code( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_T& Hook< _T >::GetData( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( &data, _T );
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Tsk
|
||||||
|
|
||||||
|
#endif // __CORE_TASK_HOOK_H
|
||||||
|
|
||||||
|
|
108
Code/Core/Task/List.h
Normal file
108
Code/Core/Task/List.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task (TSK_) **
|
||||||
|
** **
|
||||||
|
** File name: core/task/list.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_TASK_LIST_H
|
||||||
|
#define __CORE_TASK_LIST_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
#include <core/list.h>
|
||||||
|
#include "core/support/lock.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class BaseTask; // forward declaration
|
||||||
|
|
||||||
|
class List : public Spt::Access
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
List ( void );
|
||||||
|
~List ( void );
|
||||||
|
|
||||||
|
void RemoveAllTasks ( void );
|
||||||
|
void Process ( bool time, uint mask );
|
||||||
|
void Dump ( void );
|
||||||
|
void AddTask ( BaseTask& task );
|
||||||
|
bool IsEmpty ( void );
|
||||||
|
void SignalListChange( void );
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
Lst::Head<BaseTask> list;
|
||||||
|
uint stamp;
|
||||||
|
bool list_changed;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline bool List::IsEmpty ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return list.IsEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Tsk
|
||||||
|
|
||||||
|
#endif // __CORE_TASK_LIST_H
|
||||||
|
|
||||||
|
|
112
Code/Core/Task/Stack.h
Normal file
112
Code/Core/Task/Stack.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task (TSK_) **
|
||||||
|
** **
|
||||||
|
** File name: core/task/stack.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_TASK_STACK_H
|
||||||
|
#define __CORE_TASK_STACK_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/task/task.h>
|
||||||
|
#include <core/task/list.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Stack : public Spt::Access
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public :
|
||||||
|
Stack ( void );
|
||||||
|
~Stack ( void );
|
||||||
|
|
||||||
|
void Push ( void );
|
||||||
|
void Pop ( void );
|
||||||
|
void Process ( bool time = false);
|
||||||
|
void Dump ( void );
|
||||||
|
void AddTask ( BaseTask& task );
|
||||||
|
void AddPushTask ( BaseTask& task );
|
||||||
|
void RemoveAllPushTasks ( void );
|
||||||
|
void RemoveAllTasks ( void );
|
||||||
|
void SetMask(uint mask);
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
uint m_mask_off; // mask to supress execution of tasks
|
||||||
|
|
||||||
|
void remove_dead_entries( void );
|
||||||
|
|
||||||
|
class StackElement; // forward declaration
|
||||||
|
|
||||||
|
Lst::Head< StackElement > m_stack;
|
||||||
|
Lst::Head< StackElement > m_dead; // dead element list
|
||||||
|
StackElement* m_run; // current run task list
|
||||||
|
StackElement* m_add; // current add task list
|
||||||
|
|
||||||
|
// these get reset when Process() is called
|
||||||
|
bool m_pushedList;
|
||||||
|
bool m_poppedList;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
inline void Stack::SetMask(uint mask)
|
||||||
|
{
|
||||||
|
m_mask_off = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Tsk
|
||||||
|
|
||||||
|
#endif // __CORE_TASK_STACK_H
|
||||||
|
|
||||||
|
|
162
Code/Core/Task/Task.cpp
Normal file
162
Code/Core/Task/Task.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task Manager (TSK) **
|
||||||
|
** **
|
||||||
|
** File name: task.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Task Support **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/task.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
BaseTask::BaseTask( Node::Priority priority )
|
||||||
|
: tlist(NULL), stamp(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_mask = 0; // default to "No type of thing", so it will always run
|
||||||
|
node = new Node( this, priority );
|
||||||
|
Dbg_AssertType( node, Node );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
BaseTask::~BaseTask ()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( tlist )
|
||||||
|
{
|
||||||
|
Remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_AssertType( node, Node );
|
||||||
|
delete node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void BaseTask::Remove( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( tlist )
|
||||||
|
{
|
||||||
|
tlist->Forbid();
|
||||||
|
|
||||||
|
tlist->SignalListChange();
|
||||||
|
node->Remove();
|
||||||
|
|
||||||
|
tlist->Permit();
|
||||||
|
tlist = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Dbg_Warning( "Task is not in a List" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool BaseTask::InList( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return node->InList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void BaseTask::SetPriority( Node::Priority pri ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
node->SetPri( pri );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Tsk
|
206
Code/Core/Task/Task.h
Normal file
206
Code/Core/Task/Task.h
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task (TSK_) **
|
||||||
|
** **
|
||||||
|
** File name: core/task/task.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_TASK_TASK_H
|
||||||
|
#define __CORE_TASK_TASK_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
#include <core/list.h>
|
||||||
|
#include <core/task/list.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
class BaseTask : public Spt::Access
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
friend class List;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Lst::Node< BaseTask > Node;
|
||||||
|
|
||||||
|
bool InList( void ) const;
|
||||||
|
void Remove( void );
|
||||||
|
|
||||||
|
virtual void vCall( void ) const = 0;
|
||||||
|
virtual void * GetCode(void) const = 0;
|
||||||
|
|
||||||
|
void SetPriority( Node::Priority pri ) const;
|
||||||
|
virtual ~BaseTask( void );
|
||||||
|
void SetMask(uint mask);
|
||||||
|
uint GetMask();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseTask( Node::Priority pri );
|
||||||
|
|
||||||
|
Node* node; // link node
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
List* tlist; // task list to which we belong
|
||||||
|
uint stamp; // process stamp
|
||||||
|
uint m_mask; // mask indicating what types of thing this is
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
nTemplateSubClass( _T, Task, BaseTask )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef void (Code)( const Task< _T >& );
|
||||||
|
|
||||||
|
Task( Code* const code, _T& data, Node::Priority pri = Lst::Node< BaseTask >::vNORMAL_PRIORITY );
|
||||||
|
|
||||||
|
virtual void vCall( void ) const;
|
||||||
|
_T& GetData( void ) const;
|
||||||
|
virtual void * GetCode(void) const;
|
||||||
|
|
||||||
|
private :
|
||||||
|
Code* const code; // tasks entry point
|
||||||
|
_T& data; // task defined data
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Task< _T >::Task ( Code* const _code, _T& _data, Node::Priority pri )
|
||||||
|
: BaseTask( pri ), code( _code ), data( _data )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Task< _T >::vCall( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertPtr( code );
|
||||||
|
code( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_T& Task< _T >::GetData( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( &data, _T );
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void * Task< _T >::GetCode( void ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return (void*)code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void BaseTask::SetMask( uint mask )
|
||||||
|
{
|
||||||
|
|
||||||
|
m_mask = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint BaseTask::GetMask( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
return m_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Tsk
|
||||||
|
|
||||||
|
#endif // __CORE_TASK_TASK_H
|
||||||
|
|
||||||
|
|
291
Code/Core/Task/Tlist.cpp
Normal file
291
Code/Core/Task/Tlist.cpp
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task Manager (TSK) **
|
||||||
|
** **
|
||||||
|
** File name: tlist.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Task List Support **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/task.h>
|
||||||
|
|
||||||
|
#include <sys/profiler.h> // Including for debugging
|
||||||
|
#include <sys/timer.h> // Including for debugging
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
List* TSK_BkGndTasks = NULL;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
List::List( void )
|
||||||
|
: stamp( 0 ), list_changed( false )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
List::~List ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( list.IsEmpty(),( "Task List Not Empty" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void List::Process( bool time, uint mask )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if ( !HaveAccess ())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stamp++;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Lst::Search<BaseTask> iterator;
|
||||||
|
BaseTask* next = iterator.FirstItem( list );
|
||||||
|
|
||||||
|
list_changed = false;
|
||||||
|
|
||||||
|
while ( next )
|
||||||
|
{
|
||||||
|
BaseTask* task = next;
|
||||||
|
|
||||||
|
Dbg_AssertType( task, BaseTask );
|
||||||
|
Dbg_AssertPtr( task );
|
||||||
|
Dbg_AssertPtr( task->node );
|
||||||
|
Dbg_MsgAssert( task->node->InList(),( "Task was removed from list by previous task" ));
|
||||||
|
|
||||||
|
next = iterator.NextItem(); // get next task before we execute the current
|
||||||
|
// one as the task might remove itself
|
||||||
|
|
||||||
|
Dbg_MsgAssert(!list_changed,( "list changed, you fucker"));
|
||||||
|
|
||||||
|
if ( task->HaveAccess() )
|
||||||
|
{
|
||||||
|
if ( task->stamp != stamp )
|
||||||
|
{
|
||||||
|
task->stamp = stamp;
|
||||||
|
|
||||||
|
#ifdef __USE_PROFILER__
|
||||||
|
Tmr::MicroSeconds start_time=0;
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
Tmr::MicroSeconds end_time=0;
|
||||||
|
#endif
|
||||||
|
if (time)
|
||||||
|
{
|
||||||
|
start_time = Tmr::GetTimeInUSeconds();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// only call the task if it is not masked off
|
||||||
|
if (! (task->GetMask() & mask))
|
||||||
|
{
|
||||||
|
task->vCall();
|
||||||
|
}
|
||||||
|
#ifdef __USE_PROFILER__
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
if (time)
|
||||||
|
{
|
||||||
|
end_time = Tmr::GetTimeInUSeconds();
|
||||||
|
|
||||||
|
int length = (int)(end_time - start_time);
|
||||||
|
int size;
|
||||||
|
printf ("%6d %s\n",length,MemView_GetFunctionName((int)task->GetCode(), &size));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( list_changed )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while ( list_changed );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
// Mick Debugging: Dump out the contents of the task list
|
||||||
|
//
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void List::Dump( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Lst::Search<BaseTask> iterator;
|
||||||
|
BaseTask* next = iterator.FirstItem( list );
|
||||||
|
|
||||||
|
list_changed = false;
|
||||||
|
|
||||||
|
while ( next )
|
||||||
|
{
|
||||||
|
BaseTask* task = next;
|
||||||
|
|
||||||
|
Dbg_AssertType( task, BaseTask );
|
||||||
|
Dbg_AssertPtr( task );
|
||||||
|
Dbg_AssertPtr( task->node );
|
||||||
|
|
||||||
|
next = iterator.NextItem(); // get next task before we execute the current
|
||||||
|
// one as the task might remove itself
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
if ( task->HaveAccess() )
|
||||||
|
{
|
||||||
|
// char *MemView_GetFunctionName(int pc, int *p_size);
|
||||||
|
// task->vCall();
|
||||||
|
int size;
|
||||||
|
printf ("Task %p %s\n",task->GetCode(),
|
||||||
|
MemView_GetFunctionName((int)task->GetCode(), &size));
|
||||||
|
}
|
||||||
|
#elif defined( __PLAT_NGC__ )
|
||||||
|
if ( task->HaveAccess() )
|
||||||
|
{
|
||||||
|
// char *MemView_GetFunctionName(int pc, int *p_size);
|
||||||
|
// task->vCall();
|
||||||
|
Dbg_Printf ("Task %p\n",task->GetCode() );
|
||||||
|
// MemView_GetFunctionName((int)task->GetCode(), &size));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void List::AddTask( BaseTask& task )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( &task, BaseTask );
|
||||||
|
Dbg_MsgAssert( !task.node->InList(),( "Task is already in a list" ));
|
||||||
|
|
||||||
|
Forbid (); // stop any processing while list is modified
|
||||||
|
|
||||||
|
list.AddNode( task.node );
|
||||||
|
task.tlist = this;
|
||||||
|
task.stamp = stamp - 1;
|
||||||
|
list_changed = true;
|
||||||
|
|
||||||
|
Permit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void List::RemoveAllTasks( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Lst::Search<BaseTask> iterator;
|
||||||
|
BaseTask* next;
|
||||||
|
|
||||||
|
Forbid();
|
||||||
|
|
||||||
|
while (( next = iterator.FirstItem( list ) ))
|
||||||
|
{
|
||||||
|
next->Remove();
|
||||||
|
list_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Permit();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void List::SignalListChange( void )
|
||||||
|
{
|
||||||
|
list_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
} // namespace Tsk
|
||||||
|
|
377
Code/Core/Task/Tstack.cpp
Normal file
377
Code/Core/Task/Tstack.cpp
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Task Manager (TSK) **
|
||||||
|
** **
|
||||||
|
** File name: tstack.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Task Stack Support **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/task.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Tsk
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class Stack::StackElement : public List
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
friend class Stack;
|
||||||
|
|
||||||
|
public :
|
||||||
|
|
||||||
|
StackElement( void );
|
||||||
|
~StackElement( void );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Lst::Node< StackElement >* m_node;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void Stack::remove_dead_entries( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Lst::Search< StackElement > iterator;
|
||||||
|
StackElement* dead_entry;
|
||||||
|
|
||||||
|
Dbg_MsgAssert( HaveAccess(),( "List currently being processed" ));
|
||||||
|
|
||||||
|
while (( dead_entry = iterator.FirstItem( m_dead )))
|
||||||
|
{
|
||||||
|
delete dead_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
Stack::StackElement::StackElement( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_node = new Lst::Node< StackElement >( this );
|
||||||
|
Dbg_AssertType( m_node, Lst::Node< StackElement > );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
Stack::StackElement::~StackElement ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( m_node, Lst::Node< StackElement > );
|
||||||
|
delete m_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
Stack::Stack ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
m_pushedList = false;
|
||||||
|
m_poppedList = false;
|
||||||
|
|
||||||
|
Push(); // create initial list
|
||||||
|
m_add = m_run;
|
||||||
|
|
||||||
|
m_pushedList = false;
|
||||||
|
m_poppedList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
Stack::~Stack ( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( HaveAccess(),( "List currently being processed" ));
|
||||||
|
|
||||||
|
Dbg_Code
|
||||||
|
(
|
||||||
|
if ( m_stack.CountItems() != 1 )
|
||||||
|
{
|
||||||
|
Dbg_Warning( "Task Stack contains %d Task Lists", m_stack.CountItems());
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
while ( m_stack.CountItems() )
|
||||||
|
{
|
||||||
|
Pop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_dead_entries();
|
||||||
|
|
||||||
|
Dbg_MsgAssert (( m_run == NULL ),( "Task Stack not empty" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::Push( void )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
On entry:
|
||||||
|
m_add -> top list on stack (the one being processed)
|
||||||
|
m_run -> probably the same
|
||||||
|
|
||||||
|
On exit:
|
||||||
|
m_run -> new top list
|
||||||
|
m_add -> old top list (the one being processed)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert(!m_pushedList,( "push already called this frame"));
|
||||||
|
|
||||||
|
m_run = new StackElement;
|
||||||
|
|
||||||
|
Dbg_AssertType( m_run, StackElement );
|
||||||
|
|
||||||
|
m_stack.AddToHead( m_run->m_node ); // deferred push
|
||||||
|
m_pushedList = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::Pop( void )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
On entry:
|
||||||
|
m_add -> top list on stack (the one being processed)
|
||||||
|
m_run -> top list on stack
|
||||||
|
|
||||||
|
On exit:
|
||||||
|
m_run and m_add -> the new top list (originally second to top)
|
||||||
|
m_dead -> list to be destroyed (still being processed)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( m_run, StackElement );
|
||||||
|
// this assert is problematic because the task system does not call Process() on the input
|
||||||
|
// task list stacks for inactive devices, though Push() and Pop() are called
|
||||||
|
//Dbg_MsgAssert(!m_poppedList,( "pop already called this frame"));
|
||||||
|
|
||||||
|
// remove item
|
||||||
|
|
||||||
|
Lst::Search< StackElement > iterator;
|
||||||
|
iterator.FirstItem( m_stack );
|
||||||
|
|
||||||
|
// must use this test, m_pushedList is not reliable
|
||||||
|
if (m_add == m_run)
|
||||||
|
m_add = iterator.NextItem();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// otherwise, current list is retained, m_add stays the same
|
||||||
|
m_pushedList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// m_run may have been just added this frame, but that shouldn't matter
|
||||||
|
Dbg_MsgAssert( m_run->IsEmpty(),( "Tasks List not Empty" ));
|
||||||
|
if( HaveAccess() )
|
||||||
|
{
|
||||||
|
delete m_run;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_run->m_node->Remove();
|
||||||
|
m_dead.AddToHead( m_run->m_node ); // deferred kill
|
||||||
|
}
|
||||||
|
|
||||||
|
m_run = m_add;
|
||||||
|
m_poppedList = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::Process( bool time )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Forbid();
|
||||||
|
|
||||||
|
Dbg_AssertType( m_run, StackElement );
|
||||||
|
|
||||||
|
m_add = m_run; // push now in effect
|
||||||
|
m_run->Process( time, m_mask_off );
|
||||||
|
|
||||||
|
Permit();
|
||||||
|
|
||||||
|
remove_dead_entries();
|
||||||
|
|
||||||
|
m_pushedList = false;
|
||||||
|
m_poppedList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stack::Dump( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Forbid();
|
||||||
|
|
||||||
|
Dbg_AssertType( m_run, StackElement );
|
||||||
|
|
||||||
|
m_add = m_run; // push now in effect
|
||||||
|
m_run->Dump();
|
||||||
|
|
||||||
|
Permit();
|
||||||
|
|
||||||
|
remove_dead_entries();
|
||||||
|
|
||||||
|
m_pushedList = false;
|
||||||
|
m_poppedList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::AddTask( BaseTask& task )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( &task, BaseTask );
|
||||||
|
Dbg_AssertType( m_add, StackElement );
|
||||||
|
|
||||||
|
m_add->AddTask( task );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::AddPushTask( BaseTask& task )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( &task, BaseTask );
|
||||||
|
Dbg_AssertType( m_run, StackElement );
|
||||||
|
|
||||||
|
m_run->AddTask( task );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::RemoveAllTasks( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// we may really be removing all tasks in list about to be pushed
|
||||||
|
if (m_pushedList)
|
||||||
|
{
|
||||||
|
RemoveAllPushTasks();
|
||||||
|
Dbg_MsgAssert( m_run->IsEmpty(),( "should now be empty" ));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_AssertType( m_add, StackElement );
|
||||||
|
|
||||||
|
m_add->RemoveAllTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void Stack::RemoveAllPushTasks( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_AssertType( m_run, StackElement );
|
||||||
|
|
||||||
|
m_run->RemoveAllTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Tsk
|
||||||
|
|
70
Code/Core/Thread/ngc/t_thread.cpp
Normal file
70
Code/Core/Thread/ngc/t_thread.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
///******************************************************************
|
||||||
|
//*
|
||||||
|
//* DESCRIPTION: thread/ngps/t_thread.cpp
|
||||||
|
//*
|
||||||
|
//* AUTHOR: JAB
|
||||||
|
//*
|
||||||
|
//* HISTORY:
|
||||||
|
//*
|
||||||
|
//* DATE:9/1/2000
|
||||||
|
//*
|
||||||
|
//*******************************************************************/
|
||||||
|
//
|
||||||
|
///** include files **/
|
||||||
|
//
|
||||||
|
//#include <core/defines.h>
|
||||||
|
//#include <core/target.h>
|
||||||
|
//#include <core/task.h>
|
||||||
|
////#include <eekernel.h>
|
||||||
|
//
|
||||||
|
//#include "t_thread.h"
|
||||||
|
//
|
||||||
|
////#ifdef __NOPT_STD_MEM__
|
||||||
|
//extern "C" int _std_stack[1];
|
||||||
|
//static int* _stack = _std_stack;
|
||||||
|
////#else
|
||||||
|
////extern "C" int _dbg_stack[1];
|
||||||
|
////static int* _stack = _dbg_stack;
|
||||||
|
////#endif
|
||||||
|
//
|
||||||
|
//extern "C" int _stack_size[1];
|
||||||
|
//extern "C" int _start(void);
|
||||||
|
//
|
||||||
|
//Thread::PerThreadStruct _rootThreadStruct =
|
||||||
|
//{
|
||||||
|
// "ROOT",
|
||||||
|
// 0,
|
||||||
|
// 0,
|
||||||
|
// _start, // m_pEntry
|
||||||
|
// _stack, // m_pStackBase
|
||||||
|
// (int)_stack_size, // m_iStackSize
|
||||||
|
// 0,
|
||||||
|
// 0
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//int Thread::dummy = -1;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//namespace Thread
|
||||||
|
//{
|
||||||
|
// Dbg_Module
|
||||||
|
//
|
||||||
|
//// PJR - Commented out.
|
||||||
|
//// HTHREAD CreateThread( PerThreadStruct* pPTS )
|
||||||
|
//// {
|
||||||
|
//// ThreadParam sParam;
|
||||||
|
//// sParam.entry = pPTS->m_pEntry;
|
||||||
|
//// sParam.stack = pPTS->m_pStackBase;
|
||||||
|
//// sParam.stackSize = pPTS->m_iStackSize;
|
||||||
|
//// //ps2memset( pPTS->m_pStackBase, 0xca, pPTS->m_iStackSize);
|
||||||
|
//// sParam.initPriority = pPTS->m_iInitialPriority;
|
||||||
|
//// sParam.gpReg = pPTS;
|
||||||
|
////#ifdef __THREAD_DEBUGGING_PRINTS__
|
||||||
|
//// Dbg_Message( "T::CrThread: %s, entry 0x%x, stack 0x%x, size 0x%x\n",pPTS->m_cID, (unsigned int) pPTS->m_pEntry, (unsigned int) pPTS->m_pStackBase, (unsigned int) pPTS->m_iStackSize );
|
||||||
|
////#endif
|
||||||
|
//// pPTS->m_osId = ::CreateThread( &sParam );
|
||||||
|
//// return (HTHREAD) pPTS;
|
||||||
|
//// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
70
Code/Core/Thread/ngc/t_thread.h
Normal file
70
Code/Core/Thread/ngc/t_thread.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION: thread/ngc/t_thread.h
|
||||||
|
*
|
||||||
|
* AUTHOR: JAB
|
||||||
|
*
|
||||||
|
* HISTORY:
|
||||||
|
*
|
||||||
|
* DATE:9/1/2000
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/** include files **/
|
||||||
|
#ifndef __CORE_THREAD_NGC_T_THREAD_H__
|
||||||
|
#define __CORE_THREAD_NGC_T_THREAD_H__
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
//#include <eekernel.h>
|
||||||
|
|
||||||
|
namespace Thread {
|
||||||
|
typedef int THREADID; // Id for use and assigned by application
|
||||||
|
typedef int OSTHREADID; // Id assigned by the OS.
|
||||||
|
typedef unsigned int HTHREAD; // A value that is easy to determine from the OS
|
||||||
|
|
||||||
|
class PerThreadStruct {
|
||||||
|
public:
|
||||||
|
char m_cID[16]; // a text name so its easy to
|
||||||
|
THREADID m_utid; // an id that the use can assign
|
||||||
|
OSTHREADID m_osId; // an id that the OS assigns
|
||||||
|
void* m_pEntry;
|
||||||
|
void* m_pStackBase;
|
||||||
|
int m_iStackSize;
|
||||||
|
int m_iInitialPriority;
|
||||||
|
void* m_pRpcData; // ptr to rpc specific data.
|
||||||
|
};
|
||||||
|
|
||||||
|
// PJR - Not sure...
|
||||||
|
// register PerThreadStruct* g_pCurrThread asm ("gp"); // Gotta fucking love that, eh?
|
||||||
|
|
||||||
|
// inline THREADID GetCurrentThreadId() { return (g_pCurrThread) ? g_pCurrThread->m_utid : 0; }
|
||||||
|
// inline HTHREAD GetCurrentHandle() { return (HTHREAD) g_pCurrThread; } // This is fastest, so use it if you want to get data fast;
|
||||||
|
//inline void StartThread( HTHREAD hthr, void* arg = NULL ) { ::StartThread( ((PerThreadStruct*)hthr)->m_osId, arg ); }
|
||||||
|
// So you must set up the stack, and the perthreadstruct.
|
||||||
|
HTHREAD CreateThread( PerThreadStruct* pPTS );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Commentary on data for submodules (eg m_pRpcData):
|
||||||
|
Yes there are less data dependent ways of doing this. For example,
|
||||||
|
by having an array of pointers and the subsystem requests an index
|
||||||
|
that it can use. But the extra work (small tho it is) seems a bit
|
||||||
|
pointless when the penalty for hardcoding it is having to recompile
|
||||||
|
lots of things if it changes. Not a big deal.
|
||||||
|
*/
|
||||||
|
extern int dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PTS{
|
||||||
|
char m_cID[16]; // a text name so its easy to
|
||||||
|
Thread::THREADID m_utid; // an id that the use can assign
|
||||||
|
Thread::OSTHREADID m_osId; // an id that the OS assigns
|
||||||
|
void* m_pEntry;
|
||||||
|
void* m_pStackBase;
|
||||||
|
int m_iStackSize;
|
||||||
|
int m_iInitialPriority;
|
||||||
|
void* m_pRpcData; // ptr to rpc specific data.
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" Thread::PerThreadStruct _rootThreadStruct;
|
||||||
|
|
||||||
|
#endif // __CORE_THREAD_NGC_T_THREAD_H__
|
71
Code/Core/Thread/ngps/t_thread.cpp
Normal file
71
Code/Core/Thread/ngps/t_thread.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION: thread/ngps/t_thread.cpp
|
||||||
|
*
|
||||||
|
* AUTHOR: JAB
|
||||||
|
*
|
||||||
|
* HISTORY:
|
||||||
|
*
|
||||||
|
* DATE:9/1/2000
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/** include files **/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/task.h>
|
||||||
|
#include <eekernel.h>
|
||||||
|
|
||||||
|
#include "t_thread.h"
|
||||||
|
|
||||||
|
extern "C" int _std_stack[8];
|
||||||
|
static int* _stack = _std_stack;
|
||||||
|
|
||||||
|
extern "C" int _stack_size[8];
|
||||||
|
extern "C" int _start(void);
|
||||||
|
|
||||||
|
Thread::PerThreadStruct _rootThreadStruct =
|
||||||
|
{
|
||||||
|
"ROOT",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
_start, // m_pEntry
|
||||||
|
_stack, // m_pStackBase
|
||||||
|
(int)_stack_size, // m_iStackSize
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
int Thread::dummy = -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*VOID_CB)(void*); // pointer to function that takes a void pointer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Thread
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
HTHREAD CreateThread( PerThreadStruct* pPTS )
|
||||||
|
{
|
||||||
|
|
||||||
|
ThreadParam sParam;
|
||||||
|
/*sParam.entry = pPTS->m_pEntry;*/
|
||||||
|
sParam.entry = (VOID_CB) (pPTS->m_pEntry);
|
||||||
|
sParam.stack = pPTS->m_pStackBase;
|
||||||
|
sParam.stackSize = pPTS->m_iStackSize;
|
||||||
|
//ps2memset( pPTS->m_pStackBase, 0xca, pPTS->m_iStackSize);
|
||||||
|
sParam.initPriority = pPTS->m_iInitialPriority;
|
||||||
|
sParam.gpReg = &_gp;
|
||||||
|
#ifdef __THREAD_DEBUGGING_PRINTS__
|
||||||
|
Dbg_Message( "T::CrThread: %s, entry 0x%x, stack 0x%x, size 0x%x\n",pPTS->m_cID, (unsigned int) pPTS->m_pEntry, (unsigned int) pPTS->m_pStackBase, (unsigned int) pPTS->m_iStackSize );
|
||||||
|
#endif
|
||||||
|
pPTS->m_osId = ::CreateThread( &sParam );
|
||||||
|
return (HTHREAD) pPTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
67
Code/Core/Thread/ngps/t_thread.h
Normal file
67
Code/Core/Thread/ngps/t_thread.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION: thread/ngps/t_thread.h
|
||||||
|
*
|
||||||
|
* AUTHOR: JAB
|
||||||
|
*
|
||||||
|
* HISTORY:
|
||||||
|
*
|
||||||
|
* DATE:9/1/2000
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/** include files **/
|
||||||
|
#ifndef __CORE_THREAD_NGPS_T_THREAD_H__
|
||||||
|
#define __CORE_THREAD_NGPS_T_THREAD_H__
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <eekernel.h>
|
||||||
|
|
||||||
|
namespace Thread {
|
||||||
|
|
||||||
|
|
||||||
|
typedef int THREADID; // Id for use and assigned by application
|
||||||
|
typedef int OSTHREADID; // Id assigned by the OS.
|
||||||
|
typedef unsigned int HTHREAD; // A value that is easy to determine from the OS
|
||||||
|
|
||||||
|
class PerThreadStruct {
|
||||||
|
public:
|
||||||
|
char m_cID[16]; // a text name so its easy to
|
||||||
|
THREADID m_utid; // an id that the use can assign
|
||||||
|
OSTHREADID m_osId; // an id that the OS assigns
|
||||||
|
void* m_pEntry;
|
||||||
|
void* m_pStackBase;
|
||||||
|
int m_iStackSize;
|
||||||
|
int m_iInitialPriority;
|
||||||
|
void* m_pRpcData; // ptr to rpc specific data.
|
||||||
|
};
|
||||||
|
|
||||||
|
//inline void StartThread( HTHREAD hthr, void* arg = NULL ) { ::StartThread( ((PerThreadStruct*)hthr)->m_osId, arg ); }
|
||||||
|
// So you must set up the stack, and the perthreadstruct.
|
||||||
|
HTHREAD CreateThread( PerThreadStruct* pPTS );
|
||||||
|
|
||||||
|
/*
|
||||||
|
Commentary on data for submodules (eg m_pRpcData):
|
||||||
|
Yes there are less data dependent ways of doing this. For example,
|
||||||
|
by having an array of pointers and the subsystem requests an index
|
||||||
|
that it can use. But the extra work (small tho it is) seems a bit
|
||||||
|
pointless when the penalty for hardcoding it is having to recompile
|
||||||
|
lots of things if it changes. Not a big deal.
|
||||||
|
*/
|
||||||
|
extern int dummy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PTS{
|
||||||
|
char m_cID[16]; // a text name so its easy to
|
||||||
|
Thread::THREADID m_utid; // an id that the use can assign
|
||||||
|
Thread::OSTHREADID m_osId; // an id that the OS assigns
|
||||||
|
void* m_pEntry;
|
||||||
|
void* m_pStackBase;
|
||||||
|
int m_iStackSize;
|
||||||
|
int m_iInitialPriority;
|
||||||
|
void* m_pRpcData; // ptr to rpc specific data.
|
||||||
|
};
|
||||||
|
|
||||||
|
extern "C" Thread::PerThreadStruct _rootThreadStruct;
|
||||||
|
|
||||||
|
#endif // __CORE_THREAD_NGPS_T_THREAD_H__
|
36
Code/Core/Thread/wn32/t_thread.cpp
Normal file
36
Code/Core/Thread/wn32/t_thread.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION: t_target.h
|
||||||
|
*
|
||||||
|
* AUTHOR: JAB
|
||||||
|
*
|
||||||
|
* HISTORY:
|
||||||
|
*
|
||||||
|
* DATE:9/5/2000
|
||||||
|
*
|
||||||
|
|
||||||
|
This is a dummy file, because its in the NGPS version
|
||||||
|
it has to be here too.
|
||||||
|
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/** include files **/
|
||||||
|
|
||||||
|
/** local definitions **/
|
||||||
|
|
||||||
|
/* default settings */
|
||||||
|
|
||||||
|
/** external functions **/
|
||||||
|
|
||||||
|
/** external data **/
|
||||||
|
|
||||||
|
/** internal functions **/
|
||||||
|
|
||||||
|
/** public data **/
|
||||||
|
|
||||||
|
/** private data **/
|
||||||
|
|
||||||
|
/** public functions **/
|
||||||
|
|
||||||
|
/** private functions **/
|
||||||
|
|
36
Code/Core/Thread/wn32/t_thread.h
Normal file
36
Code/Core/Thread/wn32/t_thread.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION: t_target.h
|
||||||
|
*
|
||||||
|
* AUTHOR: JAB
|
||||||
|
*
|
||||||
|
* HISTORY:
|
||||||
|
*
|
||||||
|
* DATE:9/5/2000
|
||||||
|
*
|
||||||
|
|
||||||
|
This is a dummy file, because its in the NGPS version
|
||||||
|
it has to be here too.
|
||||||
|
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/** include files **/
|
||||||
|
|
||||||
|
/** local definitions **/
|
||||||
|
|
||||||
|
/* default settings */
|
||||||
|
|
||||||
|
/** external functions **/
|
||||||
|
|
||||||
|
/** external data **/
|
||||||
|
|
||||||
|
/** internal functions **/
|
||||||
|
|
||||||
|
/** public data **/
|
||||||
|
|
||||||
|
/** private data **/
|
||||||
|
|
||||||
|
/** public functions **/
|
||||||
|
|
||||||
|
/** private functions **/
|
||||||
|
|
173
Code/Core/TimestampedFlag.h
Normal file
173
Code/Core/TimestampedFlag.h
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Standard Header **
|
||||||
|
** **
|
||||||
|
** File name: core/TimestampedFlag.h **
|
||||||
|
** **
|
||||||
|
** Created: 3/3/3 - Dan **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_TIMESTAMPEDFLAG_H
|
||||||
|
#define __CORE_TIMESTAMPEDFLAG_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <sys/timer.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Class: TimestampedFlag *
|
||||||
|
* *
|
||||||
|
* Description: Flag which remembers the time of its last *
|
||||||
|
* modification *
|
||||||
|
* Extracted from skater.h *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
class CTimestampedFlag : public Spt::Class
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Set ( bool state );
|
||||||
|
void SetTrue ( );
|
||||||
|
void SetFalse ( );
|
||||||
|
void Toggle ( );
|
||||||
|
|
||||||
|
bool Get ( );
|
||||||
|
Tmr::Time GetTime ( );
|
||||||
|
Tmr::Time GetElapsedTime ( );
|
||||||
|
|
||||||
|
operator bool ( ) { return Get(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_state; // flag state
|
||||||
|
Tmr::Time m_time; // time of last state change
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void CTimestampedFlag::Set ( bool state )
|
||||||
|
{
|
||||||
|
if (m_state == state)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_state = state;
|
||||||
|
m_time = Tmr::GetTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void CTimestampedFlag::SetTrue ( )
|
||||||
|
{
|
||||||
|
Set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void CTimestampedFlag::SetFalse ( )
|
||||||
|
{
|
||||||
|
Set(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void CTimestampedFlag::Toggle ( )
|
||||||
|
{
|
||||||
|
Set(!m_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline bool CTimestampedFlag::Get ( )
|
||||||
|
{
|
||||||
|
return m_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Tmr::Time CTimestampedFlag::GetTime ( )
|
||||||
|
{
|
||||||
|
return m_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline Tmr::Time CTimestampedFlag::GetElapsedTime ( )
|
||||||
|
{
|
||||||
|
return Tmr::GetTime() - GetTime();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __CORE_TIMESTAMPEDFLAG_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
392
Code/Core/compress.cpp
Normal file
392
Code/Core/compress.cpp
Normal file
@ -0,0 +1,392 @@
|
|||||||
|
#include <core/compress.h>
|
||||||
|
|
||||||
|
#define N 4096 /* size of ring buffer */
|
||||||
|
#define F 18 /* upper limit for match_length */
|
||||||
|
#define THRESHOLD 2 /* encode string into position and length
|
||||||
|
if match_length is greater than this */
|
||||||
|
#define NIL N /* index for root of binary search trees */
|
||||||
|
|
||||||
|
unsigned long int
|
||||||
|
textsize = 0, /* text size counter */
|
||||||
|
codesize = 0, /* code size counter */
|
||||||
|
printcount = 0; /* counter for reporting progress every 1K bytes */
|
||||||
|
|
||||||
|
|
||||||
|
//unsigned char text_buf[N + F - 1]; //ring buffer of size N, with extra F-1 bytes to facilitate string comparison
|
||||||
|
int match_position, match_length; // of longest match. These are set by the InsertNode() procedure.
|
||||||
|
//int lson[N + 1], rson[N + 257], dad[N + 1]; // left & right children & parents -- These constitute binary search trees.
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char *text_buf;
|
||||||
|
int *lson;
|
||||||
|
int *rson;
|
||||||
|
int *dad;
|
||||||
|
|
||||||
|
|
||||||
|
#define readc() *pIn++
|
||||||
|
#define writec(x) *pOut++ = x
|
||||||
|
|
||||||
|
|
||||||
|
void InitTree(void) /* initialize trees */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
Mem::Manager::sHandle().PushContext(Mem::Manager::sHandle().TopDownHeap());
|
||||||
|
text_buf = new unsigned char[N + F - 1];
|
||||||
|
lson = new int[N+1];
|
||||||
|
rson = new int[N+257];
|
||||||
|
dad = new int[N+1];
|
||||||
|
Mem::Manager::sHandle().PopContext(); //Mem::Manager::sHandle().TopDownHeap());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* For i = 0 to N - 1, rson[i] and lson[i] will be the right and
|
||||||
|
left children of node i. These nodes need not be initialized.
|
||||||
|
Also, dad[i] is the parent of node i. These are initialized to
|
||||||
|
NIL (= N), which stands for 'not used.'
|
||||||
|
For i = 0 to 255, rson[N + i + 1] is the root of the tree
|
||||||
|
for strings that begin with character i. These are initialized
|
||||||
|
to NIL. Note there are 256 trees. */
|
||||||
|
|
||||||
|
for ( i = N + 1; i <= N + 256; i++ ) rson[i] = NIL;
|
||||||
|
for ( i = 0; i < N; i++ ) dad[i] = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeInitTree(void) /* free up the memory */
|
||||||
|
{
|
||||||
|
delete [] text_buf;
|
||||||
|
delete [] lson;
|
||||||
|
delete [] rson;
|
||||||
|
delete [] dad;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertNode(int r)
|
||||||
|
/* Inserts string of length F, text_buf[r..r+F-1], into one of the
|
||||||
|
trees (text_buf[r]'th tree) and returns the longest-match position
|
||||||
|
and length via the global variables match_position and match_length.
|
||||||
|
If match_length = F, then removes the old node in favor of the new
|
||||||
|
one, because the old one will be deleted sooner.
|
||||||
|
Note r plays double role, as tree node and position in buffer. */
|
||||||
|
{
|
||||||
|
int i, p, cmp;
|
||||||
|
unsigned char *key;
|
||||||
|
|
||||||
|
cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
|
||||||
|
rson[r] = lson[r] = NIL; match_length = 0;
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
if ( cmp >= 0 )
|
||||||
|
{
|
||||||
|
if ( rson[p] != NIL )
|
||||||
|
{
|
||||||
|
p = rson[p];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rson[p] = r; dad[r] = p; return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( lson[p] != NIL )
|
||||||
|
{
|
||||||
|
p = lson[p];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lson[p] = r; dad[r] = p; return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 1; i < F; i++ )
|
||||||
|
{
|
||||||
|
if ( (cmp = key[i] - text_buf[p + i]) != 0 ) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i > match_length )
|
||||||
|
{
|
||||||
|
match_position = p;
|
||||||
|
if ( (match_length = i) >= F )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
|
||||||
|
dad[lson[p]] = r; dad[rson[p]] = r;
|
||||||
|
if ( rson[dad[p]] == p )
|
||||||
|
{
|
||||||
|
rson[dad[p]] = r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lson[dad[p]] = r;
|
||||||
|
}
|
||||||
|
dad[p] = NIL; /* remove p */
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteNode(int p) /* deletes node p from tree */
|
||||||
|
{
|
||||||
|
int q;
|
||||||
|
|
||||||
|
if ( dad[p] == NIL ) return; /* not in tree */
|
||||||
|
if ( rson[p] == NIL ) q = lson[p];
|
||||||
|
else if ( lson[p] == NIL ) q = rson[p];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q = lson[p];
|
||||||
|
if ( rson[q] != NIL )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
q = rson[q];
|
||||||
|
} while ( rson[q] != NIL );
|
||||||
|
rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
|
||||||
|
lson[q] = lson[p]; dad[lson[p]] = q;
|
||||||
|
}
|
||||||
|
rson[q] = rson[p]; dad[rson[p]] = q;
|
||||||
|
}
|
||||||
|
dad[q] = dad[p];
|
||||||
|
if ( rson[dad[p]] == p ) rson[dad[p]] = q;
|
||||||
|
else lson[dad[p]] = q;
|
||||||
|
dad[p] = NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Encode(char *pIn, char *pOut, int bytes_to_read, bool print_progress)
|
||||||
|
{
|
||||||
|
int i, c, len, r, s, last_match_length, code_buf_ptr;
|
||||||
|
unsigned char code_buf[17], mask;
|
||||||
|
|
||||||
|
textsize = 0; /* text size counter */
|
||||||
|
codesize = 0; /* code size counter */
|
||||||
|
printcount = 0; /* counter for reporting progress every 1K bytes */
|
||||||
|
|
||||||
|
InitTree(); /* initialize trees */
|
||||||
|
code_buf[0] = 0; /* code_buf[1..16] saves eight units of code, and
|
||||||
|
code_buf[0] works as eight flags, "1" representing that the unit
|
||||||
|
is an unencoded letter (1 byte), "0" a position-and-length pair
|
||||||
|
(2 bytes). Thus, eight units require at most 16 bytes of code. */
|
||||||
|
code_buf_ptr = mask = 1;
|
||||||
|
s = 0; r = N - F;
|
||||||
|
for ( i = s; i < r; i++ ) text_buf[i] = ' '; /* Clear the buffer with
|
||||||
|
any character that will appear often. */
|
||||||
|
for ( len = 0; len < F && bytes_to_read; len++ )
|
||||||
|
{
|
||||||
|
c = readc();
|
||||||
|
bytes_to_read--;
|
||||||
|
text_buf[r + len] = c; /* Read F bytes into the last F bytes of
|
||||||
|
the buffer */
|
||||||
|
}
|
||||||
|
if ( (textsize = len) == 0 )
|
||||||
|
{
|
||||||
|
DeInitTree();
|
||||||
|
return 0; /* text of size zero */
|
||||||
|
}
|
||||||
|
for ( i = 1; i <= F; i++ ) InsertNode(r - i); /* Insert the F strings,
|
||||||
|
each of which begins with one or more 'space' characters. Note
|
||||||
|
the order in which these strings are inserted. This way,
|
||||||
|
degenerate trees will be less likely to occur. */
|
||||||
|
InsertNode(r); /* Finally, insert the whole string just read. The
|
||||||
|
global variables match_length and match_position are set. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( match_length > len ) match_length = len; /* match_length
|
||||||
|
may be spuriously long near the end of text. */
|
||||||
|
if ( match_length <= THRESHOLD )
|
||||||
|
{
|
||||||
|
match_length = 1; /* Not long enough match. Send one byte. */
|
||||||
|
code_buf[0] |= mask; /* 'send one byte' flag */
|
||||||
|
code_buf[code_buf_ptr++] = text_buf[r]; /* Send uncoded. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code_buf[code_buf_ptr++] = (unsigned char) match_position;
|
||||||
|
code_buf[code_buf_ptr++] = (unsigned char)
|
||||||
|
(((match_position >> 4) & 0xf0)
|
||||||
|
| (match_length - (THRESHOLD + 1))); /* Send position and
|
||||||
|
length pair. Note match_length > THRESHOLD. */
|
||||||
|
}
|
||||||
|
if ( (mask <<= 1) == 0 )
|
||||||
|
{ /* Shift mask left one bit. */
|
||||||
|
for ( i = 0; i < code_buf_ptr; i++ ) /* Send at most 8 units of */
|
||||||
|
writec(code_buf[i]); /* code together */
|
||||||
|
codesize += code_buf_ptr;
|
||||||
|
code_buf[0] = 0; code_buf_ptr = mask = 1;
|
||||||
|
}
|
||||||
|
last_match_length = match_length;
|
||||||
|
for ( i = 0; i < last_match_length &&
|
||||||
|
bytes_to_read; i++ )
|
||||||
|
{
|
||||||
|
c = readc();
|
||||||
|
bytes_to_read--;
|
||||||
|
DeleteNode(s); /* Delete old strings and */
|
||||||
|
text_buf[s] = c; /* read new bytes */
|
||||||
|
if ( s < F - 1 ) text_buf[s + N] = c; /* If the position is
|
||||||
|
near the end of buffer, extend the buffer to make
|
||||||
|
string comparison easier. */
|
||||||
|
s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
|
||||||
|
/* Since this is a ring buffer, increment the position
|
||||||
|
modulo N. */
|
||||||
|
InsertNode(r); /* Register the string in text_buf[r..r+F-1] */
|
||||||
|
}
|
||||||
|
if ( (textsize += i) > printcount )
|
||||||
|
{
|
||||||
|
// printf("%12ld\r", textsize); printcount += 1024;
|
||||||
|
/* Reports progress each time the textsize exceeds
|
||||||
|
multiples of 1024. */
|
||||||
|
}
|
||||||
|
while ( i++ < last_match_length )
|
||||||
|
{ /* After the end of text, */
|
||||||
|
DeleteNode(s); /* no need to read, but */
|
||||||
|
s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
|
||||||
|
if ( --len ) InsertNode(r); /* buffer may not be empty. */
|
||||||
|
}
|
||||||
|
} while ( len > 0 ); /* until length of string to be processed is zero */
|
||||||
|
if ( code_buf_ptr > 1 )
|
||||||
|
{ /* Send remaining code. */
|
||||||
|
for ( i = 0; i < code_buf_ptr; i++ ) writec(code_buf[i]);
|
||||||
|
codesize += code_buf_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( print_progress )
|
||||||
|
{
|
||||||
|
printf(" In : %ld bytes\n", textsize); /* Encoding is done. */
|
||||||
|
printf(" Out: %ld bytes\n", codesize);
|
||||||
|
printf(" Out/In: %.3f\n", (double)codesize / textsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeInitTree();
|
||||||
|
return codesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Decompression code, cut & pasted from pre.cpp
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define RINGBUFFERSIZE 4096 /* N size of ring buffer */
|
||||||
|
#define MATCHLIMIT 18 /* F upper limit for match_length */
|
||||||
|
#define THRESHOLD 2 /* encode string into position and length */
|
||||||
|
|
||||||
|
//#define WriteOut(x) {Dbg_MsgAssert(pOut<pIn,("Oops! Decompression overlap!\nIncrease IN_PLACE_DECOMPRESSION_MARGIN in sys\\file\\pip.cpp")); *pOut++ = x;}
|
||||||
|
#define WriteOut(x) {*pOut++ = x;}
|
||||||
|
|
||||||
|
#define USE_BUFFER 1 // we don't need no stinking buffer!!!!
|
||||||
|
|
||||||
|
#if USE_BUFFER
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
// ring buffer is just over 4K 4096+17),
|
||||||
|
// so fits nicely in the PS2's 8K scratchpad
|
||||||
|
static unsigned char sTextBuf[RINGBUFFERSIZE + MATCHLIMIT - 1];
|
||||||
|
// Note: if we try to use the scratchpad, like this
|
||||||
|
// then the code actually runs slower
|
||||||
|
// if we want to optimize this, then it should
|
||||||
|
// be hand crafted in assembly, using 128bit registers
|
||||||
|
// const unsigned char * sTextBuf = (unsigned char*) 0x70000000;
|
||||||
|
#else
|
||||||
|
static unsigned char
|
||||||
|
sTextBuf[RINGBUFFERSIZE + MATCHLIMIT - 1]; /* ring buffer of size N,
|
||||||
|
with extra F-1 bytes to facilitate string comparison */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define ReadInto(x) if (!Len) break; Len--; x = *pIn++
|
||||||
|
#define ReadInto2(x) Len--; x = *pIn++ // version that knows Len is Ok
|
||||||
|
|
||||||
|
|
||||||
|
// Decode an LZSS encoded stream
|
||||||
|
// Runs at approx 12MB/s on PS2 without scratchpad (which slows it down in C)
|
||||||
|
// a 32x CD would run at 4.8MB/sec, although we seem to get a lot less than this
|
||||||
|
// with our current file system, more like 600K per seconds.....
|
||||||
|
// Need to write a fast streaming file system....
|
||||||
|
|
||||||
|
// Ken: Made this return the new pOut so I can do some asserts to make sure it has
|
||||||
|
// written the expected number of bytes.
|
||||||
|
unsigned char *DecodeLZSS(unsigned char *pIn, unsigned char *pOut, int Len) /* Just the reverse of Encode(). */
|
||||||
|
{
|
||||||
|
int i, j, k, r, c;
|
||||||
|
// uint64 LongWord;
|
||||||
|
// int bytes = 0;
|
||||||
|
// unsigned char *pScratch;
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// int basetime = (int) Tmr::ElapsedTime(0);
|
||||||
|
// int len = Len;
|
||||||
|
|
||||||
|
// int OutBytes = 4;
|
||||||
|
// int OutWord = 0;
|
||||||
|
|
||||||
|
#if USE_BUFFER
|
||||||
|
for ( i = 0; i < RINGBUFFERSIZE - MATCHLIMIT; i++ )
|
||||||
|
sTextBuf[i] = ' ';
|
||||||
|
r = RINGBUFFERSIZE - MATCHLIMIT;
|
||||||
|
#else
|
||||||
|
r = RINGBUFFERSIZE - MATCHLIMIT;
|
||||||
|
#endif
|
||||||
|
flags = 0;
|
||||||
|
for ( ; ; )
|
||||||
|
{
|
||||||
|
if ( ((flags >>= 1) & 256) == 0 )
|
||||||
|
{
|
||||||
|
ReadInto(c);
|
||||||
|
flags = c | 0xff00; /* uses higher byte cleverly */
|
||||||
|
} /* to count eight */
|
||||||
|
if ( flags & 1 )
|
||||||
|
{
|
||||||
|
ReadInto(c);
|
||||||
|
// putc(c, outfile);
|
||||||
|
WriteOut(c);
|
||||||
|
#if USE_BUFFER
|
||||||
|
sTextBuf[r++] = c;
|
||||||
|
r &= (RINGBUFFERSIZE - 1);
|
||||||
|
#else
|
||||||
|
r++;
|
||||||
|
// r &= (RINGBUFFERSIZE - 1); // don't need to wrap r until it is used
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ReadInto(i);
|
||||||
|
ReadInto2(j); // note, don't need to check len on this one....
|
||||||
|
|
||||||
|
i |= ((j & 0xf0) << 4); // i is 12 bit offset
|
||||||
|
|
||||||
|
#if !USE_BUFFER
|
||||||
|
j = (j & 0x0f) + THRESHOLD+1; // j is 4 bit length (above the threshold)
|
||||||
|
unsigned char *pStream;
|
||||||
|
r &= (RINGBUFFERSIZE - 1); // wrap r around before it is used
|
||||||
|
pStream = pOut - r; // get base of block
|
||||||
|
if ( i>=r ) // if offset > r, then
|
||||||
|
pStream -= RINGBUFFERSIZE; // it's the previous block
|
||||||
|
pStream += i; // add in the offset to the base
|
||||||
|
r+=j; // add size to r
|
||||||
|
while ( j-- ) // copy j bytes
|
||||||
|
WriteOut(*pStream++);
|
||||||
|
#else
|
||||||
|
|
||||||
|
j = (j & 0x0f) + THRESHOLD; // j is 4 bit length (above the threshold)
|
||||||
|
for ( k = 0; k <= j; k++ ) // just copy the bytes
|
||||||
|
{
|
||||||
|
c = sTextBuf[(i+k) & (RINGBUFFERSIZE - 1)];
|
||||||
|
WriteOut(c);
|
||||||
|
sTextBuf[r++] = c;
|
||||||
|
r &= (RINGBUFFERSIZE - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// int Time = (int) Tmr::ElapsedTime(basetime);
|
||||||
|
// if (Time > 5)
|
||||||
|
// {
|
||||||
|
// printf("decomp time is %d ms, for %d bytes, %d bytes/second\n", Time,len, len * 1000 /Time );
|
||||||
|
// }
|
||||||
|
return pOut;
|
||||||
|
}
|
||||||
|
|
12
Code/Core/compress.h
Normal file
12
Code/Core/compress.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef __CORE_COMPRESS_H
|
||||||
|
#define __CORE_COMPRESS_H
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int Encode(char *pIn, char *pOut, int bytes_to_read, bool print_progress);
|
||||||
|
unsigned char *DecodeLZSS(unsigned char *pIn, unsigned char *pOut, int Len);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
338
Code/Core/crc.cpp
Normal file
338
Code/Core/crc.cpp
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: PS2 **
|
||||||
|
** **
|
||||||
|
** Module: Core **
|
||||||
|
** **
|
||||||
|
** File name: Core/crc.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 03/05/01 - spg **
|
||||||
|
** **
|
||||||
|
** Description: Crc functionality **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Crc
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Externals **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Types **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static uint32 CRCTable[256] = // CRC polynomial 0xedb88320
|
||||||
|
{
|
||||||
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||||
|
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||||
|
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||||
|
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||||
|
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||||
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||||
|
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||||
|
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||||
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||||
|
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||||
|
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||||
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||||
|
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||||
|
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||||
|
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||||
|
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||||
|
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||||
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||||
|
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||||
|
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||||
|
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||||
|
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||||
|
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||||
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||||
|
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||||
|
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||||
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||||
|
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||||
|
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||||
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||||
|
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||||
|
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||||
|
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||||
|
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||||
|
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||||
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||||
|
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||||
|
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||||
|
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||||
|
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||||
|
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||||
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||||
|
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||||
|
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||||
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||||
|
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||||
|
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||||
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||||
|
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||||
|
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||||
|
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||||
|
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||||
|
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||||
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||||
|
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||||
|
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||||
|
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||||
|
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||||
|
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||||
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||||
|
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||||
|
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Data **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Generates a checksum from raw data, given pointer to that data, and the size
|
||||||
|
//
|
||||||
|
// input:
|
||||||
|
// const char *stream = pointer to data
|
||||||
|
// int size = number of bytes to CRC
|
||||||
|
//
|
||||||
|
// output:
|
||||||
|
// returns uint32 = checksum of the data
|
||||||
|
// if NULL pointer passed in, or zero size is given, then will return 0
|
||||||
|
//
|
||||||
|
uint32 GenerateCRCCaseSensitive( const char *stream, int size )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// A checksum of zero is used to mean no name.
|
||||||
|
if(( !stream ) || ( size <= 0 ))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializing the CRC to all one bits avoids failure of detection
|
||||||
|
// should entire data stream get cyclically bit-shifted by one position.
|
||||||
|
// The calculation of the probability of this happening is left as
|
||||||
|
// an exercise for the reader.
|
||||||
|
uint32 rc = 0xffffffff;
|
||||||
|
for (int i=0; i<size; i++)
|
||||||
|
{
|
||||||
|
rc = CRCTable[(rc^stream[i]) & 0xff] ^ ((rc>>8) & 0x00ffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
// For use when calculating a total checksum of a bunch of chunks of data.
|
||||||
|
// Currently used when saving out the replay buffer to mem card.
|
||||||
|
uint32 UpdateCRC( const char *p_stream, int size, uint32 rc )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(p_stream,("NULL p_stream"));
|
||||||
|
|
||||||
|
for (int i=0; i<size; i++)
|
||||||
|
{
|
||||||
|
rc = CRCTable[(rc^p_stream[i]) & 0xff] ^ ((rc>>8) & 0x00ffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
// Generates a checksum from a name, case insensitive.
|
||||||
|
uint32 GenerateCRC( const char *stream, int size )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
// A checksum of zero is used to mean no name.
|
||||||
|
if(( !stream ) || ( size <= 0 ))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializing the CRC to all one bits avoids failure of detection
|
||||||
|
// should entire data stream get cyclically bit-shifted by one position.
|
||||||
|
// The calculation of the probability of this happening is left as
|
||||||
|
// an exercise for the reader.
|
||||||
|
uint32 rc = 0xffffffff;
|
||||||
|
for (int i=0; i<size; i++)
|
||||||
|
{
|
||||||
|
char ch=stream[i];
|
||||||
|
// Convert to lower case.
|
||||||
|
if (ch>='A' && ch<='Z')
|
||||||
|
{
|
||||||
|
ch='a'+ch-'A';
|
||||||
|
}
|
||||||
|
// Convert forward slashes to backslashes, otherwise two filenames which are
|
||||||
|
// effectively the same but with different slashes will give different checksums.
|
||||||
|
if (ch=='/')
|
||||||
|
{
|
||||||
|
ch='\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = CRCTable[(rc^ch) & 0xff] ^ ((rc>>8) & 0x00ffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
uint32 GenerateCRCFromString( const char *pName )
|
||||||
|
{
|
||||||
|
|
||||||
|
// A checksum of zero is used to mean no name.
|
||||||
|
if (!pName)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializing the CRC to all one bits avoids failure of detection
|
||||||
|
// should entire data stream get cyclically bit-shifted by one position.
|
||||||
|
// The calculation of the probability of this happening is left as
|
||||||
|
// an exercise for the reader.
|
||||||
|
uint32 rc = 0xffffffff;
|
||||||
|
const char *pCh=pName;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char ch=*pCh++;
|
||||||
|
if (!ch)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to lower case.
|
||||||
|
if (ch>='A' && ch<='Z')
|
||||||
|
{
|
||||||
|
ch='a'+ch-'A';
|
||||||
|
}
|
||||||
|
// Convert forward slashes to backslashes, otherwise two filenames which are
|
||||||
|
// effectively the same but with different slashes will give different checksums.
|
||||||
|
if (ch=='/')
|
||||||
|
{
|
||||||
|
ch='\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = CRCTable[(rc^ch) & 0xff] ^ ((rc>>8) & 0x00ffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Same as above, but it's calculating the CRC of two strings added together
|
||||||
|
// but the first string is already CRCed
|
||||||
|
// essentially it's like jumping into GenerateGRCFromString halfway through
|
||||||
|
uint32 ExtendCRCWithString( uint32 rc, const char *pName )
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!pName)
|
||||||
|
{
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pCh=pName;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char ch=*pCh++;
|
||||||
|
if (!ch)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to lower case.
|
||||||
|
if (ch>='A' && ch<='Z')
|
||||||
|
{
|
||||||
|
ch='a'+ch-'A';
|
||||||
|
}
|
||||||
|
// Convert forward slashes to backslashes, otherwise two filenames which are
|
||||||
|
// effectively the same but with different slashes will give different checksums.
|
||||||
|
if (ch=='/')
|
||||||
|
{
|
||||||
|
ch='\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = CRCTable[(rc^ch) & 0xff] ^ ((rc>>8) & 0x00ffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
uint32 GetCRCTableEntry( int entry )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_Assert(( entry < 256 ) && ( entry >= 0 ));
|
||||||
|
|
||||||
|
return CRCTable[entry];
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Crc
|
||||||
|
|
73
Code/Core/crc.h
Normal file
73
Code/Core/crc.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Crc (CRC) **
|
||||||
|
** **
|
||||||
|
** Created: 03/05/01 spg **
|
||||||
|
** **
|
||||||
|
** File name: core/crc.h **
|
||||||
|
** **
|
||||||
|
** Description: Crc Functionality **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_CRC_H
|
||||||
|
#define __CORE_CRC_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Crc
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint32 GenerateCRC( const char *stream, int size );
|
||||||
|
uint32 GenerateCRCCaseSensitive( const char *stream, int size );
|
||||||
|
uint32 UpdateCRC( const char *p_stream, int size, uint32 rc=0xffffffff );
|
||||||
|
uint32 GenerateCRCFromString( const char *pName );
|
||||||
|
uint32 ExtendCRCWithString( uint32 rc, const char *pName );
|
||||||
|
uint32 GetCRCTableEntry( int entry );
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Crc
|
||||||
|
|
||||||
|
#endif // __CORE_CRC_H
|
||||||
|
|
334
Code/Core/flags.h
Normal file
334
Code/Core/flags.h
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Standard Header **
|
||||||
|
** **
|
||||||
|
** File name: core/flags.h **
|
||||||
|
** **
|
||||||
|
** Created: 10/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_FLAGS_H
|
||||||
|
#define __CORE_FLAGS_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Class: flags *
|
||||||
|
* *
|
||||||
|
* Description: Template class for flags. *
|
||||||
|
* *
|
||||||
|
* *
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
template < class _T >
|
||||||
|
class Flags
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Flags ( void );
|
||||||
|
Flags ( const uint val );
|
||||||
|
|
||||||
|
void ClearAll ( void );
|
||||||
|
void Clear ( _T flag_index );
|
||||||
|
void ClearMask ( const uint& f );
|
||||||
|
void Set ( _T flag_index, bool on = true );
|
||||||
|
void SetAll ( void );
|
||||||
|
void SetMask ( const uint& mask );
|
||||||
|
void SetVal ( const uint& f );
|
||||||
|
bool TestAny ( void ) const;
|
||||||
|
bool Test ( _T flag_index ) const;
|
||||||
|
bool TestMask ( const uint& mask ) const;
|
||||||
|
bool TestMaskAny ( const uint& mask ) const;
|
||||||
|
bool TestMaskAll ( const uint& mask ) const;
|
||||||
|
void Toggle ( _T flag_index );
|
||||||
|
|
||||||
|
operator uint (void) const;
|
||||||
|
Flags& operator= ( const Flags& src );
|
||||||
|
Flags& operator= ( const uint& val );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uint flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Flags< _T >::Flags ( void )
|
||||||
|
: flag ( 0 )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Flags< _T >::Flags ( const uint val )
|
||||||
|
: flag ( val )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::ClearAll ( void )
|
||||||
|
{
|
||||||
|
flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::Clear ( _T flag_index )
|
||||||
|
{
|
||||||
|
flag &= ~( 1 << static_cast< uint >( flag_index ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::ClearMask ( const uint& f )
|
||||||
|
{
|
||||||
|
flag &= ~f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::Set ( _T flag_index, bool on )
|
||||||
|
{
|
||||||
|
if ( on )
|
||||||
|
{
|
||||||
|
flag |= ( 1 << static_cast< uint >( flag_index ));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flag &= ~( 1 << static_cast< uint >( flag_index ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::SetAll ( void )
|
||||||
|
{
|
||||||
|
flag = vUINT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::SetMask ( const uint& mask )
|
||||||
|
{
|
||||||
|
flag |= mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::SetVal ( const uint& f )
|
||||||
|
{
|
||||||
|
flag = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Flags< _T >::TestAny ( void ) const
|
||||||
|
{
|
||||||
|
return ( flag != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Flags< _T >::Test ( _T flag_index ) const
|
||||||
|
{
|
||||||
|
return (( flag & ( 1 << static_cast< uint >( flag_index ))) != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Flags< _T >::TestMask ( const uint& mask ) const
|
||||||
|
{
|
||||||
|
return TestMaskAny(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Flags< _T >::TestMaskAny ( const uint& mask ) const
|
||||||
|
{
|
||||||
|
return (( flag & mask ) != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
bool Flags< _T >::TestMaskAll ( const uint& mask ) const
|
||||||
|
{
|
||||||
|
return (( flag & mask ) == mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
void Flags< _T >::Toggle ( _T flag_index )
|
||||||
|
{
|
||||||
|
flag ^= ( 1 << static_cast< uint >( flag_index ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Flags< _T >::operator uint (void) const
|
||||||
|
{
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Flags< _T >& Flags< _T >::operator= ( const Flags< _T >& src )
|
||||||
|
{
|
||||||
|
flag = static_cast< uint >( src.flag );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
Flags< _T >& Flags< _T >::operator= ( const uint& val )
|
||||||
|
{
|
||||||
|
flag = val;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
template < class _T > inline
|
||||||
|
ostream& operator<< ( ostream& os, const Flags< _T >& src )
|
||||||
|
{
|
||||||
|
return os << static_cast< uint >( src );
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
#endif // __CORE_FLAGS_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
5
Code/Core/glue.h
Normal file
5
Code/Core/glue.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#ifndef __GLUE_H__
|
||||||
|
#define __GLUE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __GLUE_H__
|
11
Code/Core/log.h
Normal file
11
Code/Core/log.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __CORE_DEBUG_LOG_H
|
||||||
|
#define __CORE_DEBUG_LOG_H
|
||||||
|
|
||||||
|
namespace Log
|
||||||
|
{
|
||||||
|
void Init();
|
||||||
|
void AddEntry(char *p_fileName, int lineNumber, char *p_functionName, char *p_message=NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef __CORE_DEBUG_LOG_H
|
||||||
|
|
61
Code/Core/macros.h
Normal file
61
Code/Core/macros.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/* Useful little macros...
|
||||||
|
|
||||||
|
Add any macros you want into this:
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __USEFUL_LITTLE_MACROS_H__
|
||||||
|
#define __USEFUL_LITTLE_MACROS_H__
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
#define PERCENT_MULT ( ( 1.0f ) / 100.0f )
|
||||||
|
#define PERCENT( x, percent ) ( ( ( ( ( float )( x ) ) * ( ( float )( percent ) ) ) * PERCENT_MULT ) )
|
||||||
|
|
||||||
|
#define IPU (1.0f) // Inches per unit
|
||||||
|
|
||||||
|
#define INCHES(x) ((float)(x))
|
||||||
|
#define INCHES_PER_SECOND(x) ((float)(x))
|
||||||
|
#define INCHES_PER_SECOND_SQUARED(x) ((float)(x))
|
||||||
|
|
||||||
|
#define FEET_TO_INCHES( x ) ( x * 12.0f )
|
||||||
|
#define FEET(x) ((float)(x*12.0f))
|
||||||
|
|
||||||
|
#define FEET_PER_MILE 5280.0f
|
||||||
|
#define MPH_TO_INCHES_PER_SECOND( x ) ( ( ( x ) * FEET_PER_MILE * 12.0f ) / ( 60.0f * 60.0f ) )
|
||||||
|
#define MPH_TO_IPS( x ) MPH_TO_INCHES_PER_SECOND( x )
|
||||||
|
#define INCHES_PER_SECOND_TO_MPH( x ) ( ( x ) / 12.0f / FEET_PER_MILE * 60.0f * 60.0f )
|
||||||
|
#define IPS_TO_MPH( x ) INCHES_PER_SECOND_TO_MPH( x )
|
||||||
|
|
||||||
|
#define RADIANS_PER_SECOND_TO_RPM( x ) (9.5496f * ( x ))
|
||||||
|
#define RPM_TO_RADIANS_PER_SECOND( x ) (0.10472f * ( x ))
|
||||||
|
|
||||||
|
#define DEGREES_TO_RADIANS( x ) ( ( x ) * ( 2.0f * Mth::PI / 360.0f ) )
|
||||||
|
#define RADIANS_TO_DEGREES( x ) ( ( x ) / ( DEGREES_TO_RADIANS( 1.0f ) ) )
|
||||||
|
#define THE_NUMBER_OF_THE_BEAST 666
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Takes screen coordinates in 'default' screen space - 640x448 - and converts them based on PAL and system defines.
|
||||||
|
|
||||||
|
// Convert from logical to SCREEN coordinates
|
||||||
|
#ifdef __PLAT_XBOX__
|
||||||
|
// Unfortunately, this has to be a platform-specific macro, since it references Xbox specific global structures to determine
|
||||||
|
// the width and height of the back buffer.
|
||||||
|
#include <gfx/xbox/nx/nx_init.h>
|
||||||
|
#define SCREEN_CONV_X( x ) ((( x ) * NxXbox::EngineGlobals.screen_conv_x_multiplier ) + NxXbox::EngineGlobals.screen_conv_x_offset )
|
||||||
|
#define SCREEN_CONV_Y( y ) ((( y ) * NxXbox::EngineGlobals.screen_conv_y_multiplier ) + NxXbox::EngineGlobals.screen_conv_y_offset )
|
||||||
|
#else
|
||||||
|
#define SCREEN_CONV_X( x ) (Config::GetHardware()==Config::HARDWARE_XBOX ? (int)((( x ) * ( 640.0f / 704.0f )) + 32 ) : Config::PAL() ? (( x ) * 512 ) / 640 : (x) )
|
||||||
|
#define SCREEN_CONV_Y( y ) (Config::GetHardware()==Config::HARDWARE_XBOX ? (( y ) + 16 ) : Config::PAL() ? (( y ) * 512 ) / 448 : (y) )
|
||||||
|
#endif // __PLAT_XBOX__
|
||||||
|
|
||||||
|
// Convert from screen to LOGICAL coordinates
|
||||||
|
#define LOGICAL_CONV_X( x ) (Config::GetHardware()==Config::HARDWARE_XBOX ? (x) : Config::PAL() ? (( x ) * 640 ) / 512 : (x) )
|
||||||
|
#define LOGICAL_CONV_Y( y ) (Config::GetHardware()==Config::HARDWARE_XBOX ? (y) : Config::PAL() ? (( y ) * 448 ) / 512 : (y) )
|
||||||
|
|
||||||
|
#endif // __USEFUL_LITTLE_MACROS_H__
|
||||||
|
|
68
Code/Core/math.h
Normal file
68
Code/Core/math.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Math (MTH) **
|
||||||
|
** **
|
||||||
|
** File name: core/math.h **
|
||||||
|
** **
|
||||||
|
** Created: 11/23/99 - mjb **
|
||||||
|
** **
|
||||||
|
** Description: Math Library **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_MATH_H
|
||||||
|
#define __CORE_MATH_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
// The following overlaoded functions will make sure that if you accidently call a double version of
|
||||||
|
// a trig function with a float argument, then it will simply call the float version
|
||||||
|
// (double precision is very very slow on the PS2)
|
||||||
|
#ifndef __PLAT_XBOX__
|
||||||
|
inline float acos( float x ) {return acosf( x );}
|
||||||
|
inline float asin( float x ) {return asinf( x );}
|
||||||
|
inline float atan( float x ) {return atanf( x );}
|
||||||
|
inline float atan2( float x, float y){return atan2f( x , y );}
|
||||||
|
inline float cos( float x ) {return cosf( x );}
|
||||||
|
inline float sin( float x ) {return sinf( x );}
|
||||||
|
inline float tan( float x ) {return tanf( x );}
|
||||||
|
inline float fabs( float x ) {return fabsf( x );}
|
||||||
|
#endif // ifndef __PLAT_XBOX__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
#include <core/support.h>
|
||||||
|
#include <core/math/math.h>
|
||||||
|
#include <core/math/vector.h>
|
||||||
|
#include <core/math/matrix.h>
|
||||||
|
#include <core/math/quat.h> // need quat.h before matrix, but after vector (for the GetScalar function)
|
||||||
|
|
||||||
|
#include <core/math/vector.inl>
|
||||||
|
#include <core/math/matrix.inl>
|
||||||
|
#include <core/math/quat.inl>
|
||||||
|
#include <core/math/rect.h>
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __CORE_MATH_H
|
365
Code/Core/singleton.h
Normal file
365
Code/Core/singleton.h
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2000 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Template Singleton class **
|
||||||
|
** **
|
||||||
|
** File name: core/singleton.h **
|
||||||
|
** **
|
||||||
|
** Created: 10/17/00 - mjb **
|
||||||
|
** **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_SINGLETON_H
|
||||||
|
#define __CORE_SINGLETON_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Singletons
|
||||||
|
(Documentation by Mick)
|
||||||
|
|
||||||
|
A singleton is a single instance of a class which is dynamically
|
||||||
|
allocated just once.
|
||||||
|
|
||||||
|
To make a class such as CStats a singleton class, you do this:
|
||||||
|
|
||||||
|
|
||||||
|
class CStats
|
||||||
|
{
|
||||||
|
// Normal Class definition goes here...
|
||||||
|
...
|
||||||
|
|
||||||
|
// Constructor and destructor MUST BE PRIVATE, for it to be a singleton
|
||||||
|
private:
|
||||||
|
CStats( void );
|
||||||
|
~CStats( void );
|
||||||
|
|
||||||
|
// Macro to include the singleton code
|
||||||
|
DeclareSingletonClass( CStats );
|
||||||
|
}
|
||||||
|
|
||||||
|
This macro just places some static functions in the class, and a static pointer to
|
||||||
|
the single instance of class itself (initially NULL)
|
||||||
|
|
||||||
|
You can then initialize the singleton by the line
|
||||||
|
|
||||||
|
Spt::SingletonPtr< CStats > p_stats( true );
|
||||||
|
|
||||||
|
This is somewhere at a high level in the code (currently they are all in main())
|
||||||
|
|
||||||
|
The original design of our singletons had in mind that there would be reference counting
|
||||||
|
of the references tot he singleton, and when it was no longer referenced, it would
|
||||||
|
delete itself. So, in many places in the code, the singletons are reference by creating a
|
||||||
|
"Spt::SingletonPtr", which is a smart pointer to the instance of the singleton.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
Spt::SingletonPtr< CStats > p_stats;
|
||||||
|
p_stats->Update();
|
||||||
|
|
||||||
|
In the ultimate version of this idea, the game would be comprised of many modules,
|
||||||
|
systems and subsystems. Each would be a singleton. Each could be dependent on
|
||||||
|
other singletons, but more that one module could depend on a particular singleton,
|
||||||
|
so you coudl not rely on a module to de-initialize the singletons it needed
|
||||||
|
as they might be needed elsewhere.
|
||||||
|
|
||||||
|
So, each module would include a Spt::SingletonPtr for each of the modules that it
|
||||||
|
needed, so when a module was created it would increase the reference on the singletons
|
||||||
|
and create any that did not exists. Then when it shut down, the pointers would automatically
|
||||||
|
go out of scope, and any singleton that was not referenced would automatically be deleted,
|
||||||
|
so there would never be more systems active than there needed to be.
|
||||||
|
|
||||||
|
However, it turned out that this was generally overkill. Most systems were initialized at the start,
|
||||||
|
and those that were not, we wanted to have control over the initialization of them.
|
||||||
|
The use of smart pointers here also obfuscated the code, and introduced a significant
|
||||||
|
execution overhead that was totally unnecessary.
|
||||||
|
|
||||||
|
So, the prefered method to access a singleton now is:
|
||||||
|
|
||||||
|
CStats::Instance()->Update();
|
||||||
|
|
||||||
|
This simply references the instance directly (as it's inline), and so
|
||||||
|
does no addition processing. It's easier to type as well.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
#ifndef __SYS_MEM_MEMPTR_H
|
||||||
|
#include <sys/mem/memptr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Spt
|
||||||
|
{
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
template< class _T >
|
||||||
|
class SingletonPtr : public Spt::Class
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SingletonPtr( bool create = false );
|
||||||
|
virtual ~SingletonPtr( void );
|
||||||
|
|
||||||
|
|
||||||
|
#if ( defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ ))
|
||||||
|
SingletonPtr( const SingletonPtr< _T > & rhs );
|
||||||
|
SingletonPtr< _T >& operator= ( const SingletonPtr< _T >& rhs );
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template < class _NewT > // template copy contructor
|
||||||
|
SingletonPtr( const SingletonPtr< _NewT >& rhs ); // needed to support inheritance correctly
|
||||||
|
|
||||||
|
template < class _NewT >
|
||||||
|
SingletonPtr< _T >& operator= ( const SingletonPtr< _NewT >& rhs ); // template assignment operator
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_T* operator-> () const;
|
||||||
|
_T& operator* () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Mem::Ptr< _T > mp_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
SingletonPtr< _T >::SingletonPtr( bool create )
|
||||||
|
: mp_instance ( _T::sSgltnInstance( create ) )
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef __NOPT_FULL_DEBUG__
|
||||||
|
SetName( const_cast< char* >( sClassNode()->GetName() ));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
SingletonPtr< _T >::~SingletonPtr()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
mp_instance->sSgltnDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ( defined ( __PLAT_XBOX__ ) || defined ( __PLAT_WN32__ ))
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
SingletonPtr< _T >::SingletonPtr ( const SingletonPtr< _T >& rhs )
|
||||||
|
: mp_instance ( _T::sSgltnInstance() )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
SingletonPtr< _T >& SingletonPtr< _T >::operator= ( const SingletonPtr< _T >& rhs )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > template < class _NewT > inline
|
||||||
|
SingletonPtr< _T >::SingletonPtr< _T >( const SingletonPtr< _NewT >& rhs )
|
||||||
|
: mp_instance ( _NewT::sSgltnInstance() )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( false,( "Microsoft VC++ sucks - don't do this (yet)" ));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > template < class _NewT > inline
|
||||||
|
SingletonPtr< _T >& SingletonPtr< _T >::operator= ( const SingletonPtr< _NewT >& rhs )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert( false,( "Microsoft VC++ sucks - don't do this (yet)" ));
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_T* SingletonPtr< _T >::operator-> () const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return mp_instance.Addr();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
template < class _T > inline
|
||||||
|
_T& SingletonPtr< _T >::operator* () const
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return *mp_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
#define DeclareSingletonClass(_T) \
|
||||||
|
private: \
|
||||||
|
static _T* sSgltnInstance( bool create = false ); \
|
||||||
|
static void sSgltnDelete( void ); \
|
||||||
|
\
|
||||||
|
static _T* sp_sgltn_instance; \
|
||||||
|
static uint s_sgltn_count; \
|
||||||
|
public: \
|
||||||
|
inline static void Create(void) {sp_sgltn_instance = new _T;} \
|
||||||
|
inline static _T* Instance(void) {return sp_sgltn_instance;} \
|
||||||
|
inline bool Initilized(void) {return (sp_sgltn_instance!=NULL);} \
|
||||||
|
\
|
||||||
|
friend class Spt::SingletonPtr< _T >; \
|
||||||
|
|
||||||
|
|
||||||
|
#define DefinePlacementSingletonClass(_T, _P, _N ) \
|
||||||
|
\
|
||||||
|
_T* _T::sp_sgltn_instance = NULL; \
|
||||||
|
uint _T::s_sgltn_count = 0; \
|
||||||
|
\
|
||||||
|
_T* _T::sSgltnInstance( bool create ) \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
if ( !sp_sgltn_instance && create ) \
|
||||||
|
{ \
|
||||||
|
sp_sgltn_instance = new (_P) _T; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
Dbg_AssertType( sp_sgltn_instance, _T ); \
|
||||||
|
\
|
||||||
|
++s_sgltn_count; \
|
||||||
|
return sp_sgltn_instance; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void _T::sSgltnDelete( void ) \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
Dbg_MsgAssert(( s_sgltn_count > 0 ),( "Reference count imbalance" )); \
|
||||||
|
\
|
||||||
|
if ( s_sgltn_count > 1 ) \
|
||||||
|
{ \
|
||||||
|
s_sgltn_count--; \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
delete sp_sgltn_instance; \
|
||||||
|
sp_sgltn_instance = NULL; \
|
||||||
|
s_sgltn_count = 0; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
#define DefineSingletonClass(_T,_N) \
|
||||||
|
DefinePlacementSingletonClass(_T, (Mem::Allocator*)NULL, _N )
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Macros **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Spt
|
||||||
|
|
||||||
|
#endif // __CORE_SINGLETON_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
40
Code/Core/support.h
Normal file
40
Code/Core/support.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: Core Library **
|
||||||
|
** **
|
||||||
|
** Module: Support (SPT) **
|
||||||
|
** **
|
||||||
|
** File name: core/support.h **
|
||||||
|
** **
|
||||||
|
** Created: 05/27/99 - mjb **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_SUPPORT_H
|
||||||
|
#define __CORE_SUPPORT_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/support/class.h>
|
||||||
|
#include <core/support/support.h>
|
||||||
|
#include "sk/language.h"
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// #define PAL for PAL mode build.
|
||||||
|
#define PALx
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __CORE_TASK_H
|
||||||
|
|
||||||
|
|
32
Code/Core/thread.h
Normal file
32
Code/Core/thread.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
*
|
||||||
|
* DESCRIPTION: thread.h
|
||||||
|
*
|
||||||
|
* AUTHOR: JAB
|
||||||
|
*
|
||||||
|
* HISTORY:
|
||||||
|
*
|
||||||
|
* DATE:9/1/2000
|
||||||
|
*
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
/** include files **/
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __PLAT_WN32__
|
||||||
|
#else
|
||||||
|
# ifdef __PLAT_XBOX__
|
||||||
|
# else
|
||||||
|
# ifdef __PLAT_NGPS__
|
||||||
|
# include "thread/ngps/t_thread.h"
|
||||||
|
# elif defined( __PLAT_NGC__ )
|
||||||
|
# include "thread/ngc/t_thread.h"
|
||||||
|
# else
|
||||||
|
# error Unsupported Platform
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
147
Code/GameFlow.txt
Normal file
147
Code/GameFlow.txt
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
Flow of control
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
"autolaunch level=Load_Sch game=career"
|
||||||
|
|
||||||
|
script autolaunch
|
||||||
|
script request_level level=<level>
|
||||||
|
ScriptRequestLevel
|
||||||
|
-set Skate::m_requested_level
|
||||||
|
script cleanup_before_loading_level
|
||||||
|
ScriptCleanup
|
||||||
|
-skate_mod->Cleanup( )
|
||||||
|
-skate_mod->GetGoalManager()->RemoveAllGoals()
|
||||||
|
-particle_manager->DestroyAllSystems();
|
||||||
|
-ParticleFX::BloodSplatDestroy();
|
||||||
|
-SkateScript::ClearNodeNameHashTable();
|
||||||
|
-ParticleFX::DestroyTerrainEffectProperties();
|
||||||
|
-gfx_man->DisableFog();
|
||||||
|
-Script::KillStoppedScripts();
|
||||||
|
-sk3_sfx_manager->Reset( );
|
||||||
|
|
||||||
|
-sfx_manager->CleanUp( );
|
||||||
|
|
||||||
|
-ass_manager->UnloadAllTables( );
|
||||||
|
|
||||||
|
-Script::CSymbolTableEntry *p_sym=Script::LookUpSymbol("NodeArray");
|
||||||
|
-if (p_sym)
|
||||||
|
SkateScript::UnloadQB(p_sym->mSourceFileNameChecksum);
|
||||||
|
|
||||||
|
-SkateScript::UnloadQB(s_level_specific_qb);
|
||||||
|
-ScriptUnloadAllLevelGeometry(NULL,NULL);
|
||||||
|
|
||||||
|
-skate_mod->UnloadSkaters();
|
||||||
|
-Mem::Manager::sHandle().DeleteSkaterHeaps();
|
||||||
|
|
||||||
|
script load_requested_level level=load_sch
|
||||||
|
script LoadLevel
|
||||||
|
script PreLevelLoad
|
||||||
|
-does nothing
|
||||||
|
ScriptLaunchLevel level=load_sch
|
||||||
|
-Skate::OpenLevel()
|
||||||
|
-Script::RunScript(level_script);
|
||||||
|
script Load_Sch
|
||||||
|
script load_level level_sch
|
||||||
|
-see below....
|
||||||
|
PostLevelLoad
|
||||||
|
-does nothing
|
||||||
|
gameflow StandardGameFlow
|
||||||
|
skate_mod->mp_gameFlow->Reset( ScriptChecksum )
|
||||||
|
-set m_requestedScript
|
||||||
|
|
||||||
|
Later...
|
||||||
|
|
||||||
|
CGameFlow::Update()
|
||||||
|
GameFlow_Startup
|
||||||
|
-reset panel, sound stuff
|
||||||
|
-maybe enter free skate in network game
|
||||||
|
-choose game mode
|
||||||
|
-Put skaters in world
|
||||||
|
-Set screen mode
|
||||||
|
-Run intro script
|
||||||
|
-repeat:
|
||||||
|
GameFlow_StartRun
|
||||||
|
GameFlow_PlayRun
|
||||||
|
GameFlow_WaitEnd
|
||||||
|
-and other shit
|
||||||
|
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
"load_level level_sch"
|
||||||
|
|
||||||
|
Level_Sch = {
|
||||||
|
loading_screen = "loadscrn_generic"
|
||||||
|
pre = "sch.pre"
|
||||||
|
scnpre = "schscn.pre"
|
||||||
|
Level = "sch"
|
||||||
|
Sky = "sf2_Sky"
|
||||||
|
qb = "levels\sch\sch.qb"
|
||||||
|
colpre = "schcol.pre"
|
||||||
|
level_qb = "levels\sch\sch_scripts.qb"
|
||||||
|
startup_script = sch_Startup
|
||||||
|
default_stats = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Level_Sk4Ed = {
|
||||||
|
loading_screen = "loadscrn_generic"
|
||||||
|
pre = "sk4ed.pre"
|
||||||
|
scnpre = "sk4edscn.pre"
|
||||||
|
Level = "sk4ed"
|
||||||
|
Sky = "can_Sky"
|
||||||
|
qb = "levels\sk4ed\sk4ed.qb"
|
||||||
|
colpre = "sk4edcol.pre"
|
||||||
|
level_qb = "levels\sk4ed\sk4ed_scripts.qb"
|
||||||
|
startup_script = Sk4Ed_Startup
|
||||||
|
default_stats = 8
|
||||||
|
level_number = LevelNum_Lon
|
||||||
|
park_editor
|
||||||
|
}
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
|
||||||
|
script load_level level_sch
|
||||||
|
DisplayLoadingScreen <loading_screen>
|
||||||
|
|
||||||
|
*** Park editor yes ***
|
||||||
|
script LoadLevelPreFile <scnpre>
|
||||||
|
ScriptLoadPreFile
|
||||||
|
*** Park editor, need special flag ***
|
||||||
|
ScriptLoadScene scene=<level> (for sky, then world)
|
||||||
|
Nx::CTexDictManager::sLoadTextureDictionary(p_scene_name)
|
||||||
|
Nx::CEngine::sLoadScene(p_scene_name, p_tex_dict);
|
||||||
|
ScriptUnloadPreFile
|
||||||
|
|
||||||
|
*** Park editor maybe ***
|
||||||
|
script LoadLevelPreFile <colpre>
|
||||||
|
ScriptLoadCollision scene=<level>
|
||||||
|
p_scene->LoadCollision(p_scene_name)
|
||||||
|
ScriptUnloadPreFile
|
||||||
|
|
||||||
|
*** Park editor yes ***
|
||||||
|
script LoadLevelPreFile <pre>
|
||||||
|
ScriptLoadQB <level_qb>
|
||||||
|
SkateScript::LoadQB
|
||||||
|
Script::LoadQB
|
||||||
|
-load it into memory
|
||||||
|
ParseQB()
|
||||||
|
-restart all scripts referring to symbols
|
||||||
|
-do symbol table processing
|
||||||
|
-do following just for NodeArray symbol
|
||||||
|
- can reference nodes by name or prefix
|
||||||
|
CreateNodeNameHashTab
|
||||||
|
GeneratePrefixInfo();
|
||||||
|
*** don't call ScriptParseNodeArray for park editor, I don't think ***
|
||||||
|
*** duplicate some functionality ***
|
||||||
|
ScriptLoadNodeArray <qb>
|
||||||
|
SkateScript::LoadQB (see above)
|
||||||
|
ScriptParseNodeArray
|
||||||
|
-does a lot of stuff...
|
||||||
|
LoadTerrain
|
||||||
|
-doesn't seem to exist
|
||||||
|
CC_Startup
|
||||||
|
-loads some test camera stuff
|
||||||
|
run <startup_script> (sch_startup)
|
||||||
|
ScriptUnloadPreFile
|
||||||
|
|
||||||
|
|
898
Code/Gel/AssMan/AssMan.cpp
Normal file
898
Code/Gel/AssMan/AssMan.cpp
Normal file
@ -0,0 +1,898 @@
|
|||||||
|
//****************************************************************************
|
||||||
|
//* MODULE: Gel/AssMan
|
||||||
|
//* FILENAME: AssMan.cpp
|
||||||
|
//* OWNER: Matt Duncan
|
||||||
|
//* CREATION DATE: 11/17/2000
|
||||||
|
//****************************************************************************
|
||||||
|
|
||||||
|
// start autoduck documentation
|
||||||
|
// @DOC Assman
|
||||||
|
// @module Assman | None
|
||||||
|
// @subindex Scripting Database
|
||||||
|
// @index script | Assman
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Assets are generally binary files that are processed in some way when loaded
|
||||||
|
(although they might simply be loaded).
|
||||||
|
|
||||||
|
They are always referenced by the 32-bit checksum of the name of the file
|
||||||
|
|
||||||
|
Design and art guidelines already require that all filenames in the project
|
||||||
|
are unique names.
|
||||||
|
|
||||||
|
The asset manager should handle generic assets... (it shouldn't need
|
||||||
|
to know anything about texture dictionaries or clumps or anims...)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <gel/assman/assman.h>
|
||||||
|
|
||||||
|
#include <core/singleton.h>
|
||||||
|
#include <core/string/stringutils.h>
|
||||||
|
|
||||||
|
#include <sys/file/AsyncFilesys.h>
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
#include <gel/assman/animasset.h>
|
||||||
|
#include <gel/assman/cutsceneasset.h>
|
||||||
|
#include <gel/assman/skeletonasset.h>
|
||||||
|
#include <gel/assman/skinasset.h>
|
||||||
|
#include <gel/assman/refasset.h>
|
||||||
|
#include <gel/assman/nodearrayasset.h>
|
||||||
|
|
||||||
|
#include <gel/scripting/checksum.h>
|
||||||
|
#include <gel/scripting/script.h>
|
||||||
|
#include <gel/scripting/struct.h>
|
||||||
|
#include <gel/scripting/symboltable.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
DefineSingletonClass( CAssMan, "Shared Asset Manager" );
|
||||||
|
|
||||||
|
struct SAssetLookup
|
||||||
|
{
|
||||||
|
char* p_extension;
|
||||||
|
EAssetType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static SAssetLookup s_asset_lookup[] =
|
||||||
|
{
|
||||||
|
{"BIN", ASSET_BINARY},
|
||||||
|
{"CLD", ASSET_COLLISION},
|
||||||
|
{"SCN", ASSET_SCENE},
|
||||||
|
{"MDL", ASSET_SKIN},
|
||||||
|
{"SKA", ASSET_ANIM},
|
||||||
|
{"FAM", ASSET_ANIM}, // facial anims
|
||||||
|
{"SKE", ASSET_SKELETON},
|
||||||
|
{"SKIN", ASSET_SKIN},
|
||||||
|
{"TEX", ASSET_TEXTURES},
|
||||||
|
{"CUT", ASSET_CUTSCENE},
|
||||||
|
{"QB", ASSET_NODEARRAY},
|
||||||
|
|
||||||
|
// Insert new types above this line
|
||||||
|
{NULL, ASSET_UNKNOWN} // terminator;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
CAssMan::CAssMan()
|
||||||
|
{
|
||||||
|
mp_asset_table = new Lst::HashTable<Ass::CAsset>( 10 );
|
||||||
|
|
||||||
|
// for debugging
|
||||||
|
mp_assetlist_head = new CAsset;
|
||||||
|
mp_assetlist_head->SetText("Asset List Head (Possible error here?)");
|
||||||
|
|
||||||
|
mp_assetlist_head->mp_next = mp_assetlist_head;
|
||||||
|
mp_assetlist_head->mp_prev = mp_assetlist_head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
CAssMan::~CAssMan()
|
||||||
|
{
|
||||||
|
UnloadAllTables( true );
|
||||||
|
|
||||||
|
delete mp_asset_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
EAssetType CAssMan::FindAssetType( const char *p_assetName )
|
||||||
|
{
|
||||||
|
// given a file name, then find the type of asset that this represents
|
||||||
|
|
||||||
|
// the asset type is determined by the file extension
|
||||||
|
// so first, find the last . in the assetName
|
||||||
|
const char *p_ext = p_assetName + strlen(p_assetName);
|
||||||
|
while ( p_ext > p_assetName && *p_ext != '.' )
|
||||||
|
{
|
||||||
|
p_ext--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( *p_ext != '.' )
|
||||||
|
{
|
||||||
|
return ASSET_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_ext++;
|
||||||
|
// p_ext now points to the extension for the file name
|
||||||
|
|
||||||
|
SAssetLookup *p_lookup = &s_asset_lookup[0];
|
||||||
|
while ( p_lookup->p_extension != NULL )
|
||||||
|
{
|
||||||
|
// note, ignoring case
|
||||||
|
if ( strcmpi( p_lookup->p_extension, p_ext ) == 0 )
|
||||||
|
{
|
||||||
|
return p_lookup->type;
|
||||||
|
}
|
||||||
|
p_lookup++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ASSET_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::LoadAssetFromStream(uint32 asset_name, uint32 asset_type, uint32* p_data, int data_size, bool permanent, uint32 group)
|
||||||
|
{
|
||||||
|
// Note: There's no reason to support async loads when
|
||||||
|
// loading an asset from a data stream...
|
||||||
|
|
||||||
|
// load an asset, and return a pointer to the asset data
|
||||||
|
|
||||||
|
// given an asset name checksum, find the type of the asset, and then load it
|
||||||
|
|
||||||
|
Dbg_MsgAssert(!AssetAllocated(asset_name),("Asset %08x already loaded",asset_name));
|
||||||
|
|
||||||
|
CAsset* p_asset = NULL;
|
||||||
|
|
||||||
|
// based on the asset type, create an asset of the correct type
|
||||||
|
switch (asset_type)
|
||||||
|
{
|
||||||
|
case ASSET_ANIM:
|
||||||
|
p_asset = new CAnimAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_SKIN:
|
||||||
|
p_asset = new CSkinAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// right now, the only file type that's supported
|
||||||
|
// for data streams is the "cutscene model"
|
||||||
|
Dbg_MsgAssert(0,("Asset %08x is of unsupported type %d",asset_name,asset_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
p_asset->m_permanent = permanent;
|
||||||
|
p_asset->m_group = group;
|
||||||
|
p_asset->m_dead = false; // it is not dead
|
||||||
|
|
||||||
|
// fake an asset name for debugging
|
||||||
|
char pDebugAssetString[256];
|
||||||
|
sprintf( pDebugAssetString, "%08x from data stream", asset_name );
|
||||||
|
p_asset->SetText(pDebugAssetString);
|
||||||
|
|
||||||
|
// finally, call the asset's Load member function to load it
|
||||||
|
int error = p_asset->Load(p_data, data_size);
|
||||||
|
if ( error != 0 )
|
||||||
|
{
|
||||||
|
if ( Script::GetInteger( CRCD(0x25dc7904,"AssertOnMissingAssets") ) )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("Loading asset %08x returned error %d",asset_name,error));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete p_asset;
|
||||||
|
p_asset = NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// only add it to the table once we're sure there's no error
|
||||||
|
uint32 checksum = asset_name;
|
||||||
|
Dbg_MsgAssert(!mp_asset_table->GetItem( checksum ),("Asset %08x already in table",asset_name));
|
||||||
|
mp_asset_table->PutItem( checksum, p_asset);
|
||||||
|
p_asset->SetID(checksum);
|
||||||
|
|
||||||
|
// link in at the end, so things are added in order
|
||||||
|
p_asset->mp_next = mp_assetlist_head;
|
||||||
|
p_asset->mp_prev = mp_assetlist_head->mp_prev;
|
||||||
|
mp_assetlist_head->mp_prev->mp_next = p_asset;
|
||||||
|
mp_assetlist_head->mp_prev = p_asset;
|
||||||
|
|
||||||
|
Dbg_MsgAssert(mp_asset_table->GetItem( checksum ) == p_asset,("Asset does not match entry in table"));
|
||||||
|
Dbg_Assert( p_asset );
|
||||||
|
return p_asset->GetData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::LoadAsset(const char *p_assetName, bool async_load, bool use_pip, bool permanent, uint32 group, void* pExtraData, Script::CStruct *pParams)
|
||||||
|
{
|
||||||
|
// load an asset, and return a pointer to the asset data
|
||||||
|
|
||||||
|
// given an asset filename, find the type of the asset, and then load it
|
||||||
|
|
||||||
|
Dbg_MsgAssert(!AssetAllocated(p_assetName),("Asset %s already loaded",p_assetName));
|
||||||
|
|
||||||
|
CAsset * p_asset = NULL;
|
||||||
|
|
||||||
|
// Find the asset type
|
||||||
|
EAssetType asset_type = FindAssetType(p_assetName);
|
||||||
|
Dbg_MsgAssert(asset_type != ASSET_UNKNOWN,("Asset %s is of unknown type",p_assetName));
|
||||||
|
|
||||||
|
// based on that, create an asset of the correct type
|
||||||
|
switch (asset_type)
|
||||||
|
{
|
||||||
|
case ASSET_ANIM:
|
||||||
|
p_asset = new CAnimAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_SKELETON:
|
||||||
|
p_asset = new CSkeletonAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_SKIN:
|
||||||
|
p_asset = new CSkinAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_CUTSCENE:
|
||||||
|
p_asset = new CCutsceneAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_NODEARRAY:
|
||||||
|
p_asset = new CNodeArrayAsset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASSET_SCENE:
|
||||||
|
case ASSET_TEXTURES:
|
||||||
|
case ASSET_COLLISION:
|
||||||
|
case ASSET_BINARY:
|
||||||
|
default:
|
||||||
|
Dbg_MsgAssert(0,("Asset %s is of unsupported type %d",p_assetName,asset_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
p_asset->m_permanent = permanent;
|
||||||
|
p_asset->m_group = group;
|
||||||
|
p_asset->m_dead = false; // it is not dead
|
||||||
|
|
||||||
|
p_asset->SetText(p_assetName); // record asset name for debugging
|
||||||
|
|
||||||
|
// Garrett: Make sure that we only set async on the things that can handle them
|
||||||
|
if (async_load)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(asset_type == ASSET_ANIM, ("Can't load this asset type asynchronously: %d", asset_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, call the asset's Load member function to load it
|
||||||
|
int error = p_asset->Load(p_assetName, async_load, use_pip, pExtraData, pParams);
|
||||||
|
if ( error != 0 )
|
||||||
|
{
|
||||||
|
if ( Script::GetInteger( CRCD(0x25dc7904,"AssertOnMissingAssets") ) )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("Loading asset %s returned error %d",p_assetName,error));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete p_asset;
|
||||||
|
p_asset = NULL;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// only add it to the table once we're sure there's no error
|
||||||
|
uint32 checksum = Script::GenerateCRC( p_assetName );
|
||||||
|
Dbg_MsgAssert(!mp_asset_table->GetItem( checksum ),("Asset %s already in table",p_assetName));
|
||||||
|
mp_asset_table->PutItem( checksum, p_asset);
|
||||||
|
p_asset->SetID(checksum);
|
||||||
|
|
||||||
|
// link in at the end, so things are added in order
|
||||||
|
p_asset->mp_next = mp_assetlist_head;
|
||||||
|
p_asset->mp_prev = mp_assetlist_head->mp_prev;
|
||||||
|
mp_assetlist_head->mp_prev->mp_next = p_asset;
|
||||||
|
mp_assetlist_head->mp_prev = p_asset;
|
||||||
|
|
||||||
|
Dbg_MsgAssert(mp_asset_table->GetItem( Script::GenerateCRC( p_assetName )) == p_asset,("Asset does not match entry in table"));
|
||||||
|
Dbg_Assert( p_asset );
|
||||||
|
return p_asset->GetData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::GetFirstInGroup( uint32 group )
|
||||||
|
{
|
||||||
|
// return the first asset in the asset manager that is in this group
|
||||||
|
// will return NULL if there are none of teh specified group
|
||||||
|
|
||||||
|
return GetNthInGroup(group,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::GetNthInGroup( uint32 group, int n )
|
||||||
|
{
|
||||||
|
// return the nth asset in the asset manager that is in this group
|
||||||
|
// will return NULL if there are none of the specified group
|
||||||
|
|
||||||
|
CAsset* p_asset = mp_assetlist_head->mp_next;
|
||||||
|
while (p_asset != mp_assetlist_head)
|
||||||
|
{
|
||||||
|
// printf ("%d: Checkingfor %x, group = %x\n",n,group,p_asset->m_group);
|
||||||
|
CAsset *p_next = p_asset->mp_next;
|
||||||
|
if (p_asset->m_group == group)
|
||||||
|
{
|
||||||
|
// printf ("%d: GROUP MATCH %x, group = %x\n",n,group,p_asset->m_group);
|
||||||
|
if (n==0)
|
||||||
|
{
|
||||||
|
// printf ("%d: COUNT MATCH %x, group = %x\n",n,group,p_asset->m_group);
|
||||||
|
return p_asset->GetData();
|
||||||
|
}
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
p_asset = p_next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAssMan::GetGroup(uint32 checksum)
|
||||||
|
{
|
||||||
|
CAsset* p_actual = mp_asset_table->GetItem(checksum);
|
||||||
|
Dbg_MsgAssert(p_actual, ("GetIndexInGroup with asset not found\n"));
|
||||||
|
return p_actual->GetGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAssMan::GetIndexInGroup(uint32 checksum)
|
||||||
|
{
|
||||||
|
// find this entry, and see which number it is in the group
|
||||||
|
// i.e, returns the intex into the group
|
||||||
|
|
||||||
|
CAsset* p_actual = mp_asset_table->GetItem(checksum);
|
||||||
|
Dbg_MsgAssert(p_actual, ("GetIndexInGroup with asset not found\n"));
|
||||||
|
|
||||||
|
int n = 0; // index starts at 0
|
||||||
|
CAsset* p_asset = mp_assetlist_head->mp_next;
|
||||||
|
while (p_asset != mp_assetlist_head)
|
||||||
|
{
|
||||||
|
CAsset *p_next = p_asset->mp_next;
|
||||||
|
if (p_asset == p_actual)
|
||||||
|
{
|
||||||
|
return n; // if we've found it, then return the asset
|
||||||
|
}
|
||||||
|
if (p_asset->m_group == p_actual->m_group) // if in same group
|
||||||
|
{
|
||||||
|
n++; // increment index
|
||||||
|
}
|
||||||
|
p_asset = p_next;
|
||||||
|
}
|
||||||
|
Dbg_MsgAssert(0, ("ERROR IN GetIndexInGroup\n"));
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAssMan::CountGroup(uint32 group)
|
||||||
|
{
|
||||||
|
int n = 0; // index starts at 0
|
||||||
|
CAsset* p_asset = mp_assetlist_head->mp_next;
|
||||||
|
while (p_asset != mp_assetlist_head)
|
||||||
|
{
|
||||||
|
CAsset *p_next = p_asset->mp_next;
|
||||||
|
if (p_asset->m_group == group) // if in same group
|
||||||
|
{
|
||||||
|
n++; // increment index
|
||||||
|
}
|
||||||
|
p_asset = p_next;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAssMan::CountSameGroup(uint32 checksum)
|
||||||
|
{
|
||||||
|
// a utility function to count the assets in the same group as another asset
|
||||||
|
|
||||||
|
return CountGroup(GetGroup(checksum));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::DestroyReferences( CAsset* pAsset )
|
||||||
|
{
|
||||||
|
// Destroys an asset's references
|
||||||
|
|
||||||
|
Dbg_Assert( pAsset );
|
||||||
|
|
||||||
|
while (pAsset->mp_ref_asset)
|
||||||
|
{
|
||||||
|
// destroying a reference is similar to an asset, except we
|
||||||
|
// do not need to call unload
|
||||||
|
|
||||||
|
// printf ("Deleting Reference %p of type %d, <%s>, <%s>\n",p_asset->mp_ref_asset,p_asset->mp_ref_asset->GetType(),p_asset->mp_ref_asset->Name(), p_asset->mp_ref_asset->GetText());
|
||||||
|
uint32 id = pAsset->mp_ref_asset->m_id;
|
||||||
|
pAsset->mp_ref_asset->Unlink();
|
||||||
|
delete pAsset->mp_ref_asset;
|
||||||
|
mp_asset_table->FlushItem(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::UnloadAsset( CAsset* pAsset )
|
||||||
|
{
|
||||||
|
// Unload an asset and delete it
|
||||||
|
// note the current pairing of create/load, and unload/delete
|
||||||
|
// in the future, we might need to seperate them out into two distinct stages
|
||||||
|
|
||||||
|
Dbg_Assert( pAsset );
|
||||||
|
|
||||||
|
uint32 id = pAsset->m_id;
|
||||||
|
|
||||||
|
Dbg_MsgAssert(pAsset->LoadFinished(), ("UnloadAsset(): Asset not finished loading"));
|
||||||
|
|
||||||
|
pAsset->Unlink();
|
||||||
|
pAsset->Unload();
|
||||||
|
delete pAsset;
|
||||||
|
mp_asset_table->FlushItem(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::ReloadAsset( uint32 assetID, const char* pFileName, bool assertOnFail )
|
||||||
|
{
|
||||||
|
Ass::CAsset* pAsset;
|
||||||
|
|
||||||
|
pAsset = this->GetAssetNode( assetID, assertOnFail );
|
||||||
|
|
||||||
|
if ( pAsset )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(pAsset->LoadFinished(), ("ReloadAsset(): Asset not finished loading"));
|
||||||
|
|
||||||
|
return pAsset->Reload( pFileName );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
CAsset* CAssMan::GetAssetNode( uint32 assetID, bool assertOnFail )
|
||||||
|
{
|
||||||
|
CAsset *p_asset = mp_asset_table->GetItem(assetID);
|
||||||
|
|
||||||
|
if ( assertOnFail )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(p_asset, ("Asset Not found <%s>", Script::FindChecksumName(assetID)));
|
||||||
|
//Dbg_MsgAssert(p_asset->LoadFinished(), ("Asset not finished loading (%s)", Script::FindChecksumName(assetID)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't return pointer if it isn't done loading
|
||||||
|
if ( p_asset && !p_asset->LoadFinished() )
|
||||||
|
{
|
||||||
|
//p_asset = NULL;
|
||||||
|
|
||||||
|
// Wait if not done loading
|
||||||
|
while (!p_asset->LoadFinished())
|
||||||
|
{
|
||||||
|
Dbg_Message("Waiting for async asset load to finish...");
|
||||||
|
File::CAsyncFileLoader::sWaitForIOEvent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::GetAsset(uint32 assetID, bool assertOnFail )
|
||||||
|
{
|
||||||
|
// Return a pointer to the asset data, or NULL if not found
|
||||||
|
|
||||||
|
CAsset *p_asset = mp_asset_table->GetItem(assetID);
|
||||||
|
|
||||||
|
if (p_asset /*&& p_asset->LoadFinished()*/)
|
||||||
|
{
|
||||||
|
// Wait if not done loading
|
||||||
|
while (!p_asset->LoadFinished())
|
||||||
|
{
|
||||||
|
Dbg_Message("Waiting for async asset load to finish...");
|
||||||
|
File::CAsyncFileLoader::sWaitForIOEvent(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *p_asset_data = p_asset->GetData();
|
||||||
|
Dbg_MsgAssert(p_asset_data,("Asset has no data"));
|
||||||
|
return p_asset_data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( assertOnFail )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(p_asset, ("Asset 0x%x Not found (%s)",assetID,Script::FindChecksumName(assetID)));
|
||||||
|
//Dbg_MsgAssert(p_asset->LoadFinished(), ("Asset 0x%x not finished loading (%s)",assetID,Script::FindChecksumName(assetID)));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::GetAsset(const char *p_assetName, bool assertOnFail)
|
||||||
|
{
|
||||||
|
//returns a pointer to the asset data, does not load it if not found
|
||||||
|
|
||||||
|
if ( assertOnFail )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(AssetAllocated(p_assetName),("asset %s is not loaded in GetAsset",p_assetName));
|
||||||
|
}
|
||||||
|
void *p_asset_data = GetAsset(Script::GenerateCRC( p_assetName ), assertOnFail );
|
||||||
|
|
||||||
|
if ( assertOnFail )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(p_asset_data,("Asset has NULL data %s",p_assetName));
|
||||||
|
}
|
||||||
|
return p_asset_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void* CAssMan::LoadOrGetAsset(const char *p_assetName, bool async_load, bool use_pip, bool permanent, uint32 group, void* pExtraData, Script::CStruct * pParams)
|
||||||
|
{
|
||||||
|
//returns a pointer to the asset data, and loads the asset if not found
|
||||||
|
|
||||||
|
void *p_asset_data;
|
||||||
|
CAsset *p_asset = mp_asset_table->GetItem(Script::GenerateCRC( p_assetName ));
|
||||||
|
if (p_asset)
|
||||||
|
{
|
||||||
|
p_asset_data = p_asset->GetData();
|
||||||
|
Dbg_MsgAssert(p_asset_data,("Asset has NULL data %s",p_assetName));
|
||||||
|
//Dbg_MsgAssert(p_asset->LoadFinished(), ("Asset not finished loading (%s)", p_assetName));
|
||||||
|
|
||||||
|
// Wait if not done loading
|
||||||
|
while (!p_asset->LoadFinished())
|
||||||
|
{
|
||||||
|
Dbg_Message("Waiting for async asset load to finish...");
|
||||||
|
File::CAsyncFileLoader::sWaitForIOEvent(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p_asset_data = LoadAsset(p_assetName, async_load, use_pip, permanent, 0, pExtraData,pParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Script::GetInteger( CRCD(0x25dc7904,"AssertOnMissingAssets") ) )
|
||||||
|
{
|
||||||
|
// do some extra checks here if we're asserting on missing assets
|
||||||
|
Dbg_MsgAssert(p_asset_data,("Could not load asset %s",p_assetName));
|
||||||
|
Dbg_MsgAssert(AssetAllocated(p_assetName),("asset %s is not loaded after LoadOrGetAsset",p_assetName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_asset_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::AssetAllocated(uint32 assetID)
|
||||||
|
{
|
||||||
|
// Return true if the asset has at least started loading
|
||||||
|
|
||||||
|
return (NULL != mp_asset_table->GetItem(assetID));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::AssetAllocated(const char *p_assetName)
|
||||||
|
{
|
||||||
|
// Return true if the asset has at least started loading
|
||||||
|
|
||||||
|
return (AssetAllocated(Script::GenerateCRC( p_assetName )));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::AssetLoaded(uint32 assetID)
|
||||||
|
{
|
||||||
|
// Return true if the asset is done loading
|
||||||
|
CAsset *p_asset = mp_asset_table->GetItem(assetID);
|
||||||
|
|
||||||
|
if (p_asset && p_asset->LoadFinished())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::AssetLoaded(const char *p_assetName)
|
||||||
|
{
|
||||||
|
// Return true if the asset is done loading
|
||||||
|
|
||||||
|
return (AssetLoaded(Script::GenerateCRC( p_assetName )));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::AddRef(uint32 asset_id, uint32 ref_id, uint32 group)
|
||||||
|
{
|
||||||
|
// Add a reference to an asset, so we can access it via a new id
|
||||||
|
|
||||||
|
Dbg_MsgAssert(AssetAllocated(asset_id),("Adding ref to unloaded asset\n"));
|
||||||
|
CAsset *p_asset = new CRefAsset(mp_asset_table->GetItem(asset_id));
|
||||||
|
Dbg_MsgAssert(!mp_asset_table->GetItem( ref_id ),("ref already in table/n"));
|
||||||
|
mp_asset_table->PutItem( ref_id, p_asset);
|
||||||
|
p_asset->SetID(ref_id);
|
||||||
|
p_asset->SetGroup(group);
|
||||||
|
|
||||||
|
// link it to the end of the list
|
||||||
|
p_asset->mp_next = mp_assetlist_head;
|
||||||
|
p_asset->mp_prev = mp_assetlist_head->mp_prev;
|
||||||
|
mp_assetlist_head->mp_prev->mp_next = p_asset;
|
||||||
|
mp_assetlist_head->mp_prev = p_asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::AddRef(const char *p_assetName, uint32 ref_id, uint32 group)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(!mp_asset_table->GetItem( ref_id ),("ref %lx already in table\nwhen adding to %s\n",ref_id,p_assetName));
|
||||||
|
Dbg_MsgAssert(AssetAllocated(p_assetName),("Adding ref to unloaded asset %s\n",p_assetName));
|
||||||
|
uint32 checksum = Script::GenerateCRC( p_assetName );
|
||||||
|
AddRef(checksum,ref_id, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::UnloadAllTables( bool destroy_permanent )
|
||||||
|
{
|
||||||
|
// printf ( "Unloading all tables" );
|
||||||
|
|
||||||
|
CAsset* p_asset;
|
||||||
|
|
||||||
|
p_asset = mp_assetlist_head->mp_next;
|
||||||
|
while (p_asset != mp_assetlist_head)
|
||||||
|
{
|
||||||
|
CAsset *p_next = p_asset->mp_next;
|
||||||
|
if ( destroy_permanent || !p_asset->m_permanent )
|
||||||
|
{
|
||||||
|
// First destroy any references to this asset
|
||||||
|
DestroyReferences( p_asset );
|
||||||
|
|
||||||
|
// Need to update p_next, in case it was change by destroying above code
|
||||||
|
p_next = p_asset->mp_next;
|
||||||
|
|
||||||
|
UnloadAsset( p_asset );
|
||||||
|
}
|
||||||
|
p_asset = p_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::SetDefaultPermanent(bool permanent)
|
||||||
|
{
|
||||||
|
// set the default permanent state of loaded assets
|
||||||
|
// (generally this will be false)
|
||||||
|
|
||||||
|
m_default_permanent = permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::GetDefaultPermanent() const
|
||||||
|
{
|
||||||
|
return m_default_permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following functions are kind of kludge for referencing anims
|
||||||
|
// Ideally, I'd like to remove these kludges and simplify the
|
||||||
|
// asset manager
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAssMan::LoadAnim(const char* pFileName, uint32 animName, uint32 referenceChecksum, bool async_load, bool use_pip)
|
||||||
|
{
|
||||||
|
// If the asset was previously loaded, then we are just creating a reference to it
|
||||||
|
// so the m_permanent flag should be set based on m_default_permanent, and NOT INHERITED
|
||||||
|
|
||||||
|
if (AssetAllocated(pFileName))
|
||||||
|
{
|
||||||
|
// if descChecksum was supplied, then adding a reference
|
||||||
|
if (animName && !AssetAllocated(animName + referenceChecksum))
|
||||||
|
{
|
||||||
|
// adding a reference
|
||||||
|
AddRef(pFileName, animName + referenceChecksum, referenceChecksum);
|
||||||
|
// the m_permanent will have been inherited from the parent asset
|
||||||
|
// Now get the reference asset, and set the permanent flag to m_defualt_permanet
|
||||||
|
CAsset *p_asset = mp_asset_table->GetItem(animName + referenceChecksum);
|
||||||
|
Dbg_MsgAssert(p_asset,("(Mick) Error re-getting asset ref for %s\n",pFileName));
|
||||||
|
//p_asset->SetPermanent(m_default_permanent); // <<<< this would also set the perm flag on the parent
|
||||||
|
|
||||||
|
p_asset->m_permanent = m_default_permanent; // just in the reference!!!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Dbg_MsgAssert( 0, ( "This file was already loaded %s", pFileName ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!LoadOrGetAsset(pFileName, async_load, use_pip, m_default_permanent, 0))
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("Failed to load anim %s",pFileName));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now add the reference to it, if one was requested
|
||||||
|
// this gets combined with the "reference checksum"
|
||||||
|
if (animName && !AssetAllocated(animName + referenceChecksum))
|
||||||
|
{
|
||||||
|
AddRef(pFileName, animName + referenceChecksum, referenceChecksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::SetReferenceChecksum(uint32 reference_checksum)
|
||||||
|
{
|
||||||
|
// kind of a kludge for anims
|
||||||
|
|
||||||
|
m_reference_checksum = reference_checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
uint32 CAssMan::GetReferenceChecksum() const
|
||||||
|
{
|
||||||
|
return m_reference_checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
} // namespace Ass
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CAssMan::DumpAssets()
|
||||||
|
{
|
||||||
|
CAsset * p_asset = mp_assetlist_head->mp_next;
|
||||||
|
int i=0;
|
||||||
|
while (p_asset != mp_assetlist_head)
|
||||||
|
{
|
||||||
|
CAsset *p_next = p_asset->mp_next;
|
||||||
|
printf ("Asset %3d: perm=%d %s\n",i,p_asset->m_permanent, p_asset->GetText());
|
||||||
|
i++;
|
||||||
|
p_asset = p_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
124
Code/Gel/AssMan/AssMan.h
Normal file
124
Code/Gel/AssMan/AssMan.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
//****************************************************************************
|
||||||
|
//* MODULE: Gel/AssMan
|
||||||
|
//* FILENAME: AssMan.h
|
||||||
|
//* OWNER: Gary Jesdanun
|
||||||
|
//* CREATION DATE: 11/17/2000
|
||||||
|
//****************************************************************************
|
||||||
|
|
||||||
|
#ifndef __GEL_ASSMAN_H
|
||||||
|
#define __GEL_ASSMAN_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
|
||||||
|
#include <core/hashtable.h>
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
namespace Lst
|
||||||
|
{
|
||||||
|
template<class _V> class HashTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Script
|
||||||
|
{
|
||||||
|
class CStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
class CAsset;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Type Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class CAssMan : public Spt::Class
|
||||||
|
{
|
||||||
|
DeclareSingletonClass( CAssMan );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CAssMan( void );
|
||||||
|
~CAssMan( void );
|
||||||
|
|
||||||
|
// New generic functions
|
||||||
|
EAssetType FindAssetType(const char *p_assetName);
|
||||||
|
|
||||||
|
void* LoadAssetFromStream(uint32 asset_name, uint32 asset_type, uint32* p_data, int data_size, bool permanent, uint32 group);
|
||||||
|
void* LoadAsset(const char *p_assetName, bool async_load, bool use_pip = false, bool permanent = false, uint32 group = 0, void* pExtraData = NULL, Script::CStruct * pParams = NULL);
|
||||||
|
bool ReloadAsset( uint32 assetID, const char* pFileName, bool assertOnFail );
|
||||||
|
void* GetAsset(const char *p_assetName, bool assertOnFail = true);
|
||||||
|
void* GetAsset(uint32 assetID, bool assertOnFail = true);
|
||||||
|
void* LoadOrGetAsset(const char *p_assetName, bool async_load, bool use_pip, bool permanent = false, uint32 group = 0, void* pExtraData = NULL, Script::CStruct *pParams = NULL);
|
||||||
|
|
||||||
|
bool AssetAllocated(uint32 assetID);
|
||||||
|
bool AssetAllocated(const char *p_assetName);
|
||||||
|
|
||||||
|
bool AssetLoaded(uint32 assetID);
|
||||||
|
bool AssetLoaded(const char *p_assetName);
|
||||||
|
|
||||||
|
void AddRef(uint32 asset_id, uint32 ref_id, uint32 group = 0);
|
||||||
|
void AddRef(const char *p_assetName, uint32 ref_id, uint32 group = 0);
|
||||||
|
|
||||||
|
void SetReferenceChecksum(uint32 reference_checksum);
|
||||||
|
uint32 GetReferenceChecksum() const;
|
||||||
|
|
||||||
|
void SetDefaultPermanent(bool permanent);
|
||||||
|
bool GetDefaultPermanent() const;
|
||||||
|
|
||||||
|
void* GetFirstInGroup(uint32 group);
|
||||||
|
void* GetNthInGroup(uint32 group, int n);
|
||||||
|
|
||||||
|
int GetIndexInGroup(uint32 checksum);
|
||||||
|
int GetGroup(uint32 checksum);
|
||||||
|
int CountGroup(uint32 group);
|
||||||
|
int CountSameGroup(uint32 checksum);
|
||||||
|
|
||||||
|
void UnloadAllTables( bool destroy_permanent = false );
|
||||||
|
void DestroyReferences( CAsset* pAsset );
|
||||||
|
void UnloadAsset( CAsset* pAsset );
|
||||||
|
CAsset* GetAssetNode( uint32 assetID, bool assertOnFail );
|
||||||
|
|
||||||
|
// ideally, the LoadAnim function should be made more generic
|
||||||
|
bool LoadAnim(const char* pFileName, uint32 animName, uint32 referenceChecksum, bool async_load, bool use_pip);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_default_permanent;
|
||||||
|
uint32 m_reference_checksum; // used for anims, bit of a patch
|
||||||
|
Lst::HashTable<Ass::CAsset>* mp_asset_table;
|
||||||
|
CAsset* mp_assetlist_head;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Private Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Declarations **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Public Prototypes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Inline Functions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
} // namespace Ass
|
||||||
|
|
||||||
|
#endif // __GEL_ASSMAN_H
|
||||||
|
|
111
Code/Gel/AssMan/NodeArrayAsset.cpp
Normal file
111
Code/Gel/AssMan/NodeArrayAsset.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// NodeArrayAsset.cpp
|
||||||
|
//
|
||||||
|
// Asset depended code for loading, unloading and reloading a node array
|
||||||
|
//
|
||||||
|
// Dave
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <gel/assman/nodearrayasset.h>
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
#include <gfx/nx.h>
|
||||||
|
#include <gel/scripting/symboltable.h>
|
||||||
|
#include <gel/scripting/script.h>
|
||||||
|
#include <sk/scripting/gs_file.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CNodeArrayAsset::Load( const char* p_file, bool async_load, bool use_pip, void* pExtraData , Script::CStruct *pStruct)
|
||||||
|
{
|
||||||
|
SkateScript::LoadQB( p_file, Script::ASSERT_IF_DUPLICATE_SYMBOLS);
|
||||||
|
m_qb_checksum = Script::GenerateCRC( p_file );
|
||||||
|
|
||||||
|
char nodearrayname[128];
|
||||||
|
|
||||||
|
// Skip back to the backslash.
|
||||||
|
const char *p = &p_file[strlen( p_file ) - 1];
|
||||||
|
while( *p != '\\' && *p != '/') p--;
|
||||||
|
p++;
|
||||||
|
|
||||||
|
strcpy( nodearrayname, p ); // nodearrayname is now "name.qb"
|
||||||
|
sprintf( &nodearrayname[strlen( nodearrayname ) - 3], "_nodearray" ); // nodearrayname is now "name_nodearray"
|
||||||
|
void *p_data = Script::GetArray( nodearrayname );
|
||||||
|
|
||||||
|
// Set the array as the data returned when queried,
|
||||||
|
SetData( p_data );
|
||||||
|
|
||||||
|
Dbg_MsgAssert( p_data, ( "Could not find nodearray %s in %s", nodearrayname, p_file ));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
int CNodeArrayAsset::Unload()
|
||||||
|
{
|
||||||
|
// Unload the asset.
|
||||||
|
SkateScript::UnloadQB( m_qb_checksum );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CNodeArrayAsset::Reload( const char* p_file )
|
||||||
|
{
|
||||||
|
Dbg_Message( "Reloading %s", p_file );
|
||||||
|
|
||||||
|
Unload();
|
||||||
|
|
||||||
|
return( Load( p_file, false, 0, NULL, NULL ) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CNodeArrayAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
const char* CNodeArrayAsset::Name()
|
||||||
|
{
|
||||||
|
// Printable name, for debugging.
|
||||||
|
return "Node Array";
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
EAssetType CNodeArrayAsset::GetType()
|
||||||
|
{
|
||||||
|
// type is hard wired into asset class
|
||||||
|
return ASSET_NODEARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
}
|
36
Code/Gel/AssMan/NodeArrayAsset.h
Normal file
36
Code/Gel/AssMan/NodeArrayAsset.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// animasset.h - interface between asset manager, and the actual animation
|
||||||
|
// provides a common interface to the
|
||||||
|
#ifndef __GEL_NODEARRAYASSET_H__
|
||||||
|
#define __GEL_NODEARRAYASSET_H__
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
class CNodeArrayAsset : public CAsset
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int Load( const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct ); // create or load the asset
|
||||||
|
virtual int Unload(); // Unload the asset
|
||||||
|
virtual int Reload( const char *p_file);
|
||||||
|
virtual bool LoadFinished(); // Check to make sure asset is actually there
|
||||||
|
virtual const char * Name(); // printable name, for debugging
|
||||||
|
virtual EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
uint32 m_qb_checksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace Ass
|
||||||
|
|
||||||
|
#endif // #ifndef __GEL_ASSET_H__
|
||||||
|
|
168
Code/Gel/AssMan/animasset.cpp
Normal file
168
Code/Gel/AssMan/animasset.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// AnimAsset.cpp
|
||||||
|
//
|
||||||
|
// Asset depended code for loading, unloading and reloading an animation
|
||||||
|
//
|
||||||
|
// Mick
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <gel/assman/animasset.h>
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
|
||||||
|
#include <gfx/bonedanim.h>
|
||||||
|
#include <gfx/nx.h>
|
||||||
|
|
||||||
|
#include <gel/scripting/symboltable.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAnimAsset::Load(const char* p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct) // create or load the asset
|
||||||
|
{
|
||||||
|
int errorCode = -1;
|
||||||
|
|
||||||
|
Mem::PushMemProfile((char*)p_file);
|
||||||
|
|
||||||
|
Gfx::CBonedAnimFrameData* pSeq = new Gfx::CBonedAnimFrameData;
|
||||||
|
|
||||||
|
char fullName[256];
|
||||||
|
|
||||||
|
// add extension to create name of platform-specific SKA file
|
||||||
|
sprintf( fullName, "%s.%s", p_file, Nx::CEngine::sGetPlatformExtension() );
|
||||||
|
|
||||||
|
// Load the data
|
||||||
|
if ( !pSeq->Load(fullName, true, async_load, use_pip) )
|
||||||
|
{
|
||||||
|
if ( Script::GetInteger( CRCD(0x25dc7904,"AssertOnMissingAssets") ) )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( 0,( "Anim %s doesn't exist.", fullName ) );
|
||||||
|
}
|
||||||
|
delete pSeq;
|
||||||
|
pSeq = NULL;
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get this far, then it's successful
|
||||||
|
errorCode = 0;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
// Add it to the list:
|
||||||
|
SetData( (void*)pSeq );
|
||||||
|
Mem::PopMemProfile(/*(char*)p_file*/);
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CAnimAsset::Load(uint32* p_data, int data_size) // create or load the asset
|
||||||
|
{
|
||||||
|
int errorCode = -1;
|
||||||
|
|
||||||
|
char pDebugAssetString[256];
|
||||||
|
sprintf( pDebugAssetString, "anim from data stream" );
|
||||||
|
|
||||||
|
Mem::PushMemProfile((char*)pDebugAssetString);
|
||||||
|
|
||||||
|
Gfx::CBonedAnimFrameData* pSeq = new Gfx::CBonedAnimFrameData;
|
||||||
|
|
||||||
|
// Load the data
|
||||||
|
if ( !pSeq->Load(p_data, data_size, true ) )
|
||||||
|
{
|
||||||
|
if ( Script::GetInteger( CRCD(0x25dc7904,"AssertOnMissingAssets") ) )
|
||||||
|
{
|
||||||
|
Dbg_Assert( 0 );
|
||||||
|
}
|
||||||
|
delete pSeq;
|
||||||
|
pSeq = NULL;
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get this far, then it's successful
|
||||||
|
errorCode = 0;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
// Add it to the list:
|
||||||
|
SetData( (void*)pSeq );
|
||||||
|
Mem::PopMemProfile(/*(char*)p_file*/);
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAnimAsset::Unload()
|
||||||
|
{
|
||||||
|
// Unload the asset
|
||||||
|
|
||||||
|
if (GetData())
|
||||||
|
{
|
||||||
|
delete (Gfx::CBonedAnimFrameData*) GetData();
|
||||||
|
|
||||||
|
SetData(NULL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CAnimAsset::Reload(const char* p_file)
|
||||||
|
{
|
||||||
|
Dbg_Message( "Reloading %s", p_file );
|
||||||
|
|
||||||
|
Unload();
|
||||||
|
|
||||||
|
return ( Load(p_file, false, 0, NULL, NULL ) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CAnimAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
Gfx::CBonedAnimFrameData * p_anim = (Gfx::CBonedAnimFrameData*) GetData();
|
||||||
|
Dbg_MsgAssert(p_anim, ("LoadFinished(): Data pointer NULL (load probably was never started)"));
|
||||||
|
|
||||||
|
return p_anim->LoadFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
const char* CAnimAsset::Name()
|
||||||
|
{
|
||||||
|
// printable name, for debugging
|
||||||
|
return "Animation";
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
EAssetType CAnimAsset::GetType()
|
||||||
|
{
|
||||||
|
// type is hard wired into asset class
|
||||||
|
return ASSET_ANIM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
}
|
40
Code/Gel/AssMan/animasset.h
Normal file
40
Code/Gel/AssMan/animasset.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// animasset.h - interface between asset manager, and the actual animation
|
||||||
|
// provides a common interface to the
|
||||||
|
#ifndef __GEL_ANIMASSET_H__
|
||||||
|
#define __GEL_ANIMASSET_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CAnimAsset : public CAsset
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct); // create or load the asset
|
||||||
|
virtual int Load(uint32* p_data, int data_size); // create or load the asset
|
||||||
|
virtual int Unload(); // Unload the asset
|
||||||
|
virtual int Reload(const char *p_file);
|
||||||
|
virtual bool LoadFinished(); // Check to make sure asset is actually there
|
||||||
|
virtual const char * Name(); // printable name, for debugging
|
||||||
|
virtual EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace Ass
|
||||||
|
|
||||||
|
#endif // #ifndef __GEL_ASSET_H__
|
||||||
|
|
113
Code/Gel/AssMan/asset.cpp
Normal file
113
Code/Gel/AssMan/asset.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Asset.cpp
|
||||||
|
//
|
||||||
|
// Mick
|
||||||
|
//
|
||||||
|
// Base class of all assets
|
||||||
|
// provides basic interface to them
|
||||||
|
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
// when destroying an asset, we also unload it
|
||||||
|
// this should only be done via the asset manager
|
||||||
|
|
||||||
|
CAsset::CAsset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CAsset::~CAsset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlink for the doubly linked list
|
||||||
|
void CAsset::Unlink()
|
||||||
|
{
|
||||||
|
mp_next->mp_prev = mp_prev;
|
||||||
|
mp_prev->mp_next = mp_next;
|
||||||
|
mp_prev = this;
|
||||||
|
mp_next = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CAsset::Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData , Script::CStruct *pParams)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("CAsset::Load() should not be called"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CAsset::Load(uint32* p_data, int data_size)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("CAsset::Load() from data buffer should not be called"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CAsset::Reload(const char *p_file)
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("CAsset::Reload() should not be called"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CAsset::Unload()
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("CAsset::Unload() should not be called"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(0,("CAsset::LoadFinished() should not be called"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char * CAsset::Name() // printable name, for debugging
|
||||||
|
{
|
||||||
|
return "Unnamed Asset";
|
||||||
|
}
|
||||||
|
|
||||||
|
void * CAsset::GetData() // return a pointer to the asset's data
|
||||||
|
{
|
||||||
|
return mp_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAsset::SetData(void *p_data)
|
||||||
|
{
|
||||||
|
mp_data = p_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
|
||||||
|
void CAsset::SetID(uint32 id)
|
||||||
|
{
|
||||||
|
m_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 CAsset::GetID()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAsset::SetGroup(uint32 group)
|
||||||
|
{
|
||||||
|
m_group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 CAsset::GetGroup()
|
||||||
|
{
|
||||||
|
return m_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EAssetType CAsset::GetType() // type is hard wired into asset class
|
||||||
|
{
|
||||||
|
return ASSET_UNKNOWN; // for now return 0, not sure if this should return the EAssetType
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
102
Code/Gel/AssMan/asset.h
Normal file
102
Code/Gel/AssMan/asset.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// asset.h - base class for managed assets
|
||||||
|
|
||||||
|
#ifndef __GEL_ASSET_H__
|
||||||
|
#define __GEL_ASSET_H__
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
#include <core/string/cstring.h>
|
||||||
|
|
||||||
|
namespace Script
|
||||||
|
{
|
||||||
|
class CStruct;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
class CAsset : public Spt::Class
|
||||||
|
{
|
||||||
|
friend class CAssMan;
|
||||||
|
friend class CRefAsset;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CAsset(); // constructor is private, so only CAssMan can create them
|
||||||
|
virtual ~CAsset(); //
|
||||||
|
|
||||||
|
virtual int Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pParams); // create or load the asset
|
||||||
|
virtual int Load(uint32* p_data, int data_size);
|
||||||
|
virtual int Unload(); // Unload the asset
|
||||||
|
virtual int Reload(const char *p_file);
|
||||||
|
virtual bool LoadFinished(); // Check to make sure asset is actually there
|
||||||
|
|
||||||
|
|
||||||
|
void Unlink(); // Unlink the asset
|
||||||
|
|
||||||
|
// Some acessor functions for memory usage metrics
|
||||||
|
virtual const char* Name(); // printable name, for debugging
|
||||||
|
|
||||||
|
// acessors for seting the low level id stuff
|
||||||
|
// maybe this should just be derived from CObject?
|
||||||
|
void SetID(uint32 id); // Unique asset ID
|
||||||
|
uint32 GetID();
|
||||||
|
virtual void SetGroup(uint32 group); // Unique group ID
|
||||||
|
virtual uint32 GetGroup();
|
||||||
|
|
||||||
|
virtual EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
virtual void SetData(void *p_data); // return a pointer to the asset….
|
||||||
|
virtual void * GetData(); // return a pointer to the asset….
|
||||||
|
virtual void SetPermanent(bool perm);
|
||||||
|
|
||||||
|
void SetText(const char *p_text);
|
||||||
|
const char * GetText();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 m_id;
|
||||||
|
uint32 m_group;
|
||||||
|
|
||||||
|
char m_permanent; // should it stay in memory after a cleanup
|
||||||
|
char m_dead; // asset is dead, remove it
|
||||||
|
|
||||||
|
void * mp_data; // pointer to the asset data
|
||||||
|
|
||||||
|
// Str::String m_text;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CRefAsset * mp_ref_asset; // pointer to first CRefAsset that points to this
|
||||||
|
|
||||||
|
// The assets are also stored in a simple doubly linked list with a head node
|
||||||
|
// this is to simplify the
|
||||||
|
CAsset * mp_prev;
|
||||||
|
CAsset * mp_next;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Inline member functions
|
||||||
|
|
||||||
|
|
||||||
|
inline void CAsset::SetText(const char *p_text)
|
||||||
|
{
|
||||||
|
// m_text = p_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char * CAsset::GetText()
|
||||||
|
{
|
||||||
|
// return m_text.getString();
|
||||||
|
return "names removed";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CAsset::SetPermanent(bool perm) {m_permanent = perm;}
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace Ass
|
||||||
|
|
||||||
|
#endif // #ifndef __GEL_ASSET_H__
|
||||||
|
|
24
Code/Gel/AssMan/assettypes.h
Normal file
24
Code/Gel/AssMan/assettypes.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// asset types for the asset manager
|
||||||
|
|
||||||
|
#ifndef __GEL_ASSETTYPES_H
|
||||||
|
#define __GEL_ASSETTYPES_H
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
enum EAssetType {
|
||||||
|
ASSET_UNKNOWN, // unknown, needs to be determined by inspection
|
||||||
|
ASSET_BINARY, // binary file
|
||||||
|
ASSET_SCENE, // world_geometry
|
||||||
|
ASSET_TEXTURES, // Texture file
|
||||||
|
ASSET_COLLISION, // collision file
|
||||||
|
ASSET_ANIM, // animation
|
||||||
|
ASSET_SKELETON, // skeleton
|
||||||
|
ASSET_SKIN, // skin
|
||||||
|
ASSET_CUTSCENE, // cutscene
|
||||||
|
ASSET_NODEARRAY, // model node array
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ass
|
||||||
|
|
||||||
|
#endif
|
118
Code/Gel/AssMan/cutsceneasset.cpp
Normal file
118
Code/Gel/AssMan/cutsceneasset.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
//****************************************************************************
|
||||||
|
//* MODULE: Ass
|
||||||
|
//* FILENAME: cutsceneasset.cpp
|
||||||
|
//* OWNER: Gary Jesdanun
|
||||||
|
//* CREATION DATE: 01/13/2003
|
||||||
|
//****************************************************************************
|
||||||
|
|
||||||
|
#include <gel/assman/cutsceneasset.h>
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
#include <gfx/nx.h>
|
||||||
|
#include <sk/objects/cutscenedetails.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CCutsceneAsset::Load( const char* p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct ) // create or load the asset
|
||||||
|
{
|
||||||
|
Mem::PushMemProfile( (char*)p_file );
|
||||||
|
|
||||||
|
Obj::CCutsceneData* p_cutsceneData = new Obj::CCutsceneData;
|
||||||
|
|
||||||
|
// get the platform-specific CUT file name
|
||||||
|
char platFileName[256];
|
||||||
|
sprintf( platFileName, "%s.%s", p_file, Nx::CEngine::sGetPlatformExtension() );
|
||||||
|
|
||||||
|
// load the data
|
||||||
|
if ( !p_cutsceneData->Load( platFileName, true, async_load ) )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( 0, ( "Cutscene %s doesn't exist.", platFileName ) );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add it to the list:
|
||||||
|
SetData( (void*)p_cutsceneData );
|
||||||
|
|
||||||
|
Mem::PopMemProfile(/*(char*)p_file*/);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CCutsceneAsset::Unload()
|
||||||
|
{
|
||||||
|
// Unload the asset
|
||||||
|
Obj::CCutsceneData* pData = (Obj::CCutsceneData*)GetData();
|
||||||
|
if ( pData )
|
||||||
|
{
|
||||||
|
delete pData;
|
||||||
|
SetData(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CCutsceneAsset::Reload(const char* p_file)
|
||||||
|
{
|
||||||
|
Dbg_Message( "Reloading %s...", p_file );
|
||||||
|
|
||||||
|
Unload();
|
||||||
|
|
||||||
|
return ( Load( p_file, false, 0, NULL, NULL ) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CCutsceneAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
Obj::CCutsceneData* p_cutsceneData = (Obj::CCutsceneData*)GetData();
|
||||||
|
Dbg_MsgAssert( p_cutsceneData, ( "LoadFinished(): Data pointer NULL (load probably was never started)" ) );
|
||||||
|
return p_cutsceneData->LoadFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
const char* CCutsceneAsset::Name()
|
||||||
|
{
|
||||||
|
// printable name, for debugging
|
||||||
|
return "Cutscene";
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
EAssetType CCutsceneAsset::GetType()
|
||||||
|
{
|
||||||
|
// type is hard wired into asset class
|
||||||
|
return ASSET_CUTSCENE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
}
|
46
Code/Gel/AssMan/cutsceneasset.h
Normal file
46
Code/Gel/AssMan/cutsceneasset.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//****************************************************************************
|
||||||
|
//* MODULE: Ass
|
||||||
|
//* FILENAME: cutsceneasset.h
|
||||||
|
//* OWNER: Gary Jesdanun
|
||||||
|
//* CREATION DATE: 01/13/2003
|
||||||
|
//****************************************************************************
|
||||||
|
|
||||||
|
// interface between asset manager, and the actual cutscene
|
||||||
|
|
||||||
|
#ifndef __GEL_CUTSCENEASSET_H__
|
||||||
|
#define __GEL_CUTSCENEASSET_H__
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
class CCutsceneAsset : public CAsset
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct); // create or load the asset
|
||||||
|
virtual int Unload(); // unload the asset
|
||||||
|
virtual int Reload(const char *p_file);
|
||||||
|
virtual bool LoadFinished(); // check to make sure asset is actually there
|
||||||
|
virtual const char * Name(); // printable name, for debugging
|
||||||
|
virtual EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
156
Code/Gel/AssMan/refasset.cpp
Normal file
156
Code/Gel/AssMan/refasset.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// RefAsset.cpp
|
||||||
|
//
|
||||||
|
// Mick
|
||||||
|
//
|
||||||
|
// Type of asset that just refers to another asset
|
||||||
|
// so you can have multiple indicies to reference an asset
|
||||||
|
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
#include <gel/assman/refasset.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
CRefAsset::CRefAsset(CAsset *p_asset)
|
||||||
|
{
|
||||||
|
|
||||||
|
mp_asset = p_asset;
|
||||||
|
mp_sibling = NULL;
|
||||||
|
if (p_asset->mp_ref_asset == NULL)
|
||||||
|
{
|
||||||
|
// this is the first reference, so just stick it in mp_ref_asset
|
||||||
|
p_asset->mp_ref_asset = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// it's a new asset, so insert it as the head
|
||||||
|
// of siblings that refer to this
|
||||||
|
CRefAsset *p_other_ref = p_asset->mp_ref_asset;
|
||||||
|
p_asset->mp_ref_asset = this;
|
||||||
|
mp_sibling = p_other_ref;
|
||||||
|
}
|
||||||
|
mp_data = NULL; // Ref Assets explicitly have no data
|
||||||
|
m_permanent = p_asset->m_permanent; // inherit the permanence flag
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CRefAsset::~CRefAsset()
|
||||||
|
{
|
||||||
|
|
||||||
|
// unhook the references
|
||||||
|
// from the assman table, the asset it refers to, and other assets
|
||||||
|
|
||||||
|
if (mp_asset)
|
||||||
|
{
|
||||||
|
CRefAsset * p_prev = mp_asset->mp_ref_asset;
|
||||||
|
if (p_prev == this)
|
||||||
|
{
|
||||||
|
mp_asset->mp_ref_asset = mp_sibling;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (p_prev && p_prev->mp_sibling != this)
|
||||||
|
{
|
||||||
|
p_prev = p_prev->mp_sibling;
|
||||||
|
}
|
||||||
|
Dbg_MsgAssert(p_prev,("Reference not listed in its parent asset"));
|
||||||
|
p_prev->mp_sibling = mp_sibling;
|
||||||
|
}
|
||||||
|
mp_asset = NULL;
|
||||||
|
mp_sibling = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Dbg_MsgAssert(mp_asset == NULL,("Destroying ref with non-null asset"));
|
||||||
|
Dbg_MsgAssert(mp_sibling == NULL,("Destroying ref with non-null sibling"));
|
||||||
|
Dbg_MsgAssert(mp_data == NULL,("Ref Asset has data!"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// all other functions simply call the appropiate function on the referenced asset
|
||||||
|
// (might want to make these inline later)
|
||||||
|
|
||||||
|
int CRefAsset::Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData) // create or load the asset
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(!async_load, ("Async load not supported on CRefAsset"));
|
||||||
|
|
||||||
|
// return mp_asset->Load(p_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CRefAsset::Unload() // Unload the asset
|
||||||
|
{
|
||||||
|
// return mp_asset->Unload();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int CRefAsset::Reload(const char *p_file)
|
||||||
|
{
|
||||||
|
// printf("Reloading dereferenced asset with %s\n", p_file);
|
||||||
|
|
||||||
|
return mp_asset->Reload(p_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CRefAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(GetData(), ("LoadFinished(): Data pointer NULL (load probably was never started)"));
|
||||||
|
|
||||||
|
return mp_asset->LoadFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char* CRefAsset::Name() // printable name, for debugging
|
||||||
|
{
|
||||||
|
return mp_asset->Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CRefAsset::SetGroup(uint32 group) // Unique group ID
|
||||||
|
{
|
||||||
|
// mp_asset->SetGroup(group);
|
||||||
|
m_group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32 CRefAsset::GetGroup()
|
||||||
|
{
|
||||||
|
// return mp_asset->GetGroup();
|
||||||
|
return m_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EAssetType CRefAsset::GetType() // type is hard wired into asset class
|
||||||
|
{
|
||||||
|
return mp_asset->GetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CRefAsset::SetData(void *p_data) // return a pointer to the asset….
|
||||||
|
{
|
||||||
|
mp_asset->SetData(p_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void * CRefAsset::GetData() // return a pointer to the asset….
|
||||||
|
{
|
||||||
|
return mp_asset->GetData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CRefAsset::SetPermanent(bool perm)
|
||||||
|
{
|
||||||
|
m_permanent = perm;
|
||||||
|
mp_asset->SetPermanent(perm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
53
Code/Gel/AssMan/refasset.h
Normal file
53
Code/Gel/AssMan/refasset.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
// asset.h - base class for managed assets
|
||||||
|
|
||||||
|
#ifndef __GEL_REFASSET_H__
|
||||||
|
#define __GEL_REFASSET_H__
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CRefAsset : public CAsset
|
||||||
|
{
|
||||||
|
friend class CAssMan;
|
||||||
|
protected:
|
||||||
|
CRefAsset(CAsset *p_asset);
|
||||||
|
~CRefAsset();
|
||||||
|
|
||||||
|
int Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData); // create or load the asset
|
||||||
|
int Unload(); // Unload the asset
|
||||||
|
int Reload(const char *p_file);
|
||||||
|
bool LoadFinished(); // Check to make sure asset is actually there
|
||||||
|
int RamUsage();
|
||||||
|
int VramUsage();
|
||||||
|
int SramUsage();
|
||||||
|
const char* Name(); // printable name, for debugging
|
||||||
|
void SetGroup(uint32 group); // Unique group ID
|
||||||
|
uint32 GetGroup();
|
||||||
|
EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
void SetData(void *p_data); // return a pointer to the asset….
|
||||||
|
void * GetData(); // return a pointer to the asset….
|
||||||
|
void SetPermanent(bool perm);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CAsset * mp_asset; // pointer to the actual asset
|
||||||
|
CRefAsset * mp_sibling; // pointer to other CRefAsset that references mp_asset
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// Inline member functions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace Ass
|
||||||
|
|
||||||
|
#endif // #ifndef __GEL_REFASSET_H__
|
||||||
|
|
137
Code/Gel/AssMan/skeletonasset.cpp
Normal file
137
Code/Gel/AssMan/skeletonasset.cpp
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
//****************************************************************************
|
||||||
|
//* MODULE: Ass
|
||||||
|
//* FILENAME: skeletonasset.cpp
|
||||||
|
//* OWNER: Gary Jesdanun
|
||||||
|
//* CREATION DATE: ??/??/????
|
||||||
|
//****************************************************************************
|
||||||
|
|
||||||
|
#include <gel/assman/skeletonasset.h>
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
|
||||||
|
#include <gfx/nx.h>
|
||||||
|
#include <gfx/skeleton.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CSkeletonAsset::Load( const char *p_file, bool async_load, bool use_pip, void* pExtraData , Script::CStruct *pStruct) // create or load the asset
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( !async_load, ( "Async load not supported on CSkeletonAsset" ) );
|
||||||
|
|
||||||
|
// Load the data, add it to the list:
|
||||||
|
Gfx::CSkeletonData* pSkeletonData = new Gfx::CSkeletonData;
|
||||||
|
|
||||||
|
char fullName[256];
|
||||||
|
|
||||||
|
// add extension to create name of platform-specific SKE file
|
||||||
|
sprintf( fullName, "%s.%s", p_file, Nx::CEngine::sGetPlatformExtension() );
|
||||||
|
|
||||||
|
if ( !pSkeletonData->Load( fullName, true ) )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( 0,( "File %s doesn't exist.", fullName ));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SetData( (void*)pSkeletonData );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CSkeletonAsset::Load( uint32* p_data, int data_size )
|
||||||
|
{
|
||||||
|
char pDebugAssetString[256];
|
||||||
|
sprintf( pDebugAssetString, "skeleton from data stream" );
|
||||||
|
|
||||||
|
Mem::PushMemProfile((char*)pDebugAssetString);
|
||||||
|
|
||||||
|
// Load the data, add it to the list:
|
||||||
|
Gfx::CSkeletonData* pSkeletonData = new Gfx::CSkeletonData;
|
||||||
|
|
||||||
|
if ( !pSkeletonData->Load( p_data, data_size, true ) )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( 0,( "Couldn't create skeleton from data stream." ));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetData((void*)pSkeletonData);
|
||||||
|
|
||||||
|
Mem::PopMemProfile(/*"skeleton from data stream"*/);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CSkeletonAsset::Unload() // Unload the asset
|
||||||
|
{
|
||||||
|
Gfx::CSkeletonData* pData = (Gfx::CSkeletonData*)GetData();
|
||||||
|
if ( pData )
|
||||||
|
{
|
||||||
|
delete pData;
|
||||||
|
SetData(NULL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CSkeletonAsset::Reload( const char *p_file )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CSkeletonAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( GetData(), ( "LoadFinished(): Data pointer NULL (load probably was never started)" ) );
|
||||||
|
|
||||||
|
// Since we don't support async, this is always true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
const char * CSkeletonAsset::Name() // printable name, for debugging
|
||||||
|
{
|
||||||
|
return "Skeleton";
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
EAssetType CSkeletonAsset::GetType() // type is hard wired into asset class
|
||||||
|
{
|
||||||
|
return ASSET_SKELETON; // for now return 0, not sure if this should return the EAssetType
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
}
|
47
Code/Gel/AssMan/skeletonasset.h
Normal file
47
Code/Gel/AssMan/skeletonasset.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
//****************************************************************************
|
||||||
|
//* MODULE: Ass
|
||||||
|
//* FILENAME: skeletonasset.h
|
||||||
|
//* OWNER: Gary Jesdanun
|
||||||
|
//* CREATION DATE: ??/??/????
|
||||||
|
//****************************************************************************
|
||||||
|
|
||||||
|
// interface between asset manager, and the actual skeleton data
|
||||||
|
// provides a common interface to the skeleton data
|
||||||
|
|
||||||
|
#ifndef __GEL_SKELETONASSET_H__
|
||||||
|
#define __GEL_SKELETONASSET_H__
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
#include <core/support.h>
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
class CSkeletonAsset : public CAsset
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct); // create or load the asset
|
||||||
|
virtual int Load(uint32* p_data, int data_size); // create or load the asset from data stream
|
||||||
|
virtual int Unload(); // unload the asset
|
||||||
|
virtual int Reload(const char *p_file);
|
||||||
|
virtual bool LoadFinished(); // check to make sure asset is actually there
|
||||||
|
virtual const char * Name(); // printable name, for debugging
|
||||||
|
virtual EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
161
Code/Gel/AssMan/skinasset.cpp
Normal file
161
Code/Gel/AssMan/skinasset.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// SkinAsset.cpp
|
||||||
|
//
|
||||||
|
// Asset depended code for loading, unloading and reloading a skin
|
||||||
|
//
|
||||||
|
// Mick
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <gel/assman/skinasset.h>
|
||||||
|
|
||||||
|
#include <core/string/stringutils.h>
|
||||||
|
|
||||||
|
#include <gel/assman/assettypes.h>
|
||||||
|
|
||||||
|
#include <gfx/nx.h>
|
||||||
|
#include <gfx/nxmesh.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
int CSkinAsset::Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct) // create or load the asset
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(!async_load, ("Async load not supported on CSkinAsset"));
|
||||||
|
|
||||||
|
Mem::PushMemProfile((char*)p_file);
|
||||||
|
|
||||||
|
SSkinAssetLoadContext theContext;
|
||||||
|
theContext.forceTexDictLookup = false;
|
||||||
|
theContext.doShadowVolume = false;
|
||||||
|
theContext.texDictOffset = 0;
|
||||||
|
|
||||||
|
// GJ: kludge to prevent tex dict offset clashes
|
||||||
|
// in bail board asset... i will remove this
|
||||||
|
// after i figure out why the tex dict offsets
|
||||||
|
// are clashing in the first place...
|
||||||
|
// if ( strstr(p_file,"board_default") )
|
||||||
|
// {
|
||||||
|
// texDictOffset = -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if ( pExtraData )
|
||||||
|
{
|
||||||
|
theContext = *(SSkinAssetLoadContext*)pExtraData;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nx::CMesh* pMesh = Nx::CEngine::sLoadMesh( p_file, theContext.texDictOffset, theContext.forceTexDictLookup, theContext.doShadowVolume );
|
||||||
|
if ( !pMesh )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( 0,( "mesh %s doesn't exist.", p_file ));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetData((void*)pMesh);
|
||||||
|
|
||||||
|
// make sure the filename is in lower-case
|
||||||
|
char msg[128];
|
||||||
|
strcpy( msg, p_file );
|
||||||
|
Str::LowerCase( msg );
|
||||||
|
|
||||||
|
// only MDL files should load their collision data
|
||||||
|
if ( strstr( msg, ".mdl" ) )
|
||||||
|
{
|
||||||
|
// Might be overrided by having a "nocollision=1" as a parameter
|
||||||
|
int no_collision = 0;
|
||||||
|
if (pStruct)
|
||||||
|
{
|
||||||
|
pStruct->GetInteger(CRCD(0xbf29bc0,"nocollision"),&no_collision);
|
||||||
|
}
|
||||||
|
if (!no_collision)
|
||||||
|
{
|
||||||
|
pMesh->LoadCollision(p_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Model node arrays are now loaded via the NodeArrayComponent.
|
||||||
|
// pMesh->LoadModelNodeArray(p_file);
|
||||||
|
|
||||||
|
Mem::PopMemProfile(/*"Skin"*/);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSkinAsset::Load(uint32* p_data, int data_size) // create or load the asset
|
||||||
|
{
|
||||||
|
char pDebugAssetString[256];
|
||||||
|
sprintf( pDebugAssetString, "skin from data stream" );
|
||||||
|
|
||||||
|
Mem::PushMemProfile((char*)pDebugAssetString);
|
||||||
|
|
||||||
|
// GJ: for now, we need to access 3 pointers for the MDL, TEX, and CAS
|
||||||
|
// data... eventually, i'd like to store each of the 3 files
|
||||||
|
// separately in the asset manager, in which case we wouldn't
|
||||||
|
// have to do this clumsy hack of sending 3 pointers wrapped up
|
||||||
|
// in a struct...
|
||||||
|
SCutsceneModelDataInfo* p_cutscene_data = (SCutsceneModelDataInfo*)p_data;
|
||||||
|
|
||||||
|
Nx::CMesh* pMesh = Nx::CEngine::sLoadMesh( p_cutscene_data->modelChecksum,
|
||||||
|
p_cutscene_data->pModelData,
|
||||||
|
p_cutscene_data->modelDataSize,
|
||||||
|
p_cutscene_data->pCASData,
|
||||||
|
p_cutscene_data->texDictChecksum,
|
||||||
|
p_cutscene_data->pTextureData,
|
||||||
|
p_cutscene_data->textureDataSize,
|
||||||
|
p_cutscene_data->texDictOffset,
|
||||||
|
p_cutscene_data->isSkin,
|
||||||
|
p_cutscene_data->doShadowVolume );
|
||||||
|
if ( !pMesh )
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert( 0,( "Couldn't create mesh from data stream." ));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetData((void*)pMesh);
|
||||||
|
|
||||||
|
// for now, we're going to assume that data loaded in through
|
||||||
|
// a data stream will not have collision or a node array,
|
||||||
|
// since we're only using this for cutscene assets right
|
||||||
|
// now... this can be changed very easily...
|
||||||
|
|
||||||
|
Mem::PopMemProfile(/*"skin from data stream"*/);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSkinAsset::Unload() // Unload the asset
|
||||||
|
{
|
||||||
|
if (GetData())
|
||||||
|
{
|
||||||
|
Nx::CEngine::sUnloadMesh( (Nx::CMesh*) GetData() );
|
||||||
|
|
||||||
|
SetData(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSkinAsset::Reload(const char *p_file)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSkinAsset::LoadFinished()
|
||||||
|
{
|
||||||
|
Dbg_MsgAssert(GetData(), ("LoadFinished(): Data pointer NULL (load probably was never started)"));
|
||||||
|
|
||||||
|
// Since we don't support async, this is always true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * CSkinAsset::Name() // printable name, for debugging
|
||||||
|
{
|
||||||
|
return "Skin";
|
||||||
|
}
|
||||||
|
|
||||||
|
EAssetType CSkinAsset::GetType() // type is hard wired into asset class
|
||||||
|
{
|
||||||
|
return ASSET_SKIN; // for now return 0, not sure if this should return the EAssetType
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
59
Code/Gel/AssMan/skinasset.h
Normal file
59
Code/Gel/AssMan/skinasset.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// skinasset.h - interface between asset manager, and the actual skin
|
||||||
|
// provides a common interface to the asset manager
|
||||||
|
#ifndef __GEL_SKINASSET_H__
|
||||||
|
#define __GEL_SKINASSET_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gel/assman/asset.h>
|
||||||
|
|
||||||
|
namespace Ass
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SCutsceneModelDataInfo
|
||||||
|
{
|
||||||
|
uint32 modelChecksum;
|
||||||
|
uint32* pModelData;
|
||||||
|
int modelDataSize;
|
||||||
|
uint32* pTextureData;
|
||||||
|
int textureDataSize;
|
||||||
|
uint8* pCASData;
|
||||||
|
uint32 texDictChecksum;
|
||||||
|
int texDictOffset;
|
||||||
|
bool isSkin;
|
||||||
|
bool doShadowVolume;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SSkinAssetLoadContext
|
||||||
|
{
|
||||||
|
int forceTexDictLookup;
|
||||||
|
bool doShadowVolume;
|
||||||
|
int texDictOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CSkinAsset : public CAsset
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int Load(const char *p_file, bool async_load, bool use_pip, void* pExtraData, Script::CStruct *pStruct); // create or load the asset
|
||||||
|
virtual int Load(uint32* p_data, int data_size); // create or load the asset
|
||||||
|
virtual int Unload(); // Unload the asset
|
||||||
|
virtual int Reload(const char *p_file);
|
||||||
|
virtual bool LoadFinished(); // Check to make sure asset is actually there
|
||||||
|
virtual const char * Name(); // printable name, for debugging
|
||||||
|
virtual EAssetType GetType(); // type is hard wired into asset class
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // end namespace Ass
|
||||||
|
|
||||||
|
#endif // #ifndef __GEL_SKINASSET_H__
|
||||||
|
|
482
Code/Gel/Collision/BatchTriColl.cpp
Normal file
482
Code/Gel/Collision/BatchTriColl.cpp
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment. **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 1999 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: PS2 **
|
||||||
|
** **
|
||||||
|
** Module: Nx **
|
||||||
|
** **
|
||||||
|
** File name: gel\collision\BatchTriColl.cpp **
|
||||||
|
** **
|
||||||
|
** Created by: 04/12/02 - grj **
|
||||||
|
** **
|
||||||
|
** Description: **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <core/defines.h>
|
||||||
|
|
||||||
|
#include <gel/collision/BatchTriColl.h>
|
||||||
|
#include <gel/collision/collision.h>
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
#include <libdma.h>
|
||||||
|
#include <devvu0.h>
|
||||||
|
#include <gfx/ngps/nx/interrupts.h>
|
||||||
|
#include <gfx/ngps/nx/resource.h>
|
||||||
|
#endif //__PLAT_NGPS__
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** DBG Information **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Nx
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef BATCH_TRI_COLLISION
|
||||||
|
|
||||||
|
CollData * CBatchTriColl::sp_coll_data;
|
||||||
|
|
||||||
|
volatile bool CBatchTriCollMan::s_processing = false;
|
||||||
|
volatile bool CBatchTriCollMan::s_result_processing = false;
|
||||||
|
volatile int CBatchTriCollMan::s_nested = 0;
|
||||||
|
volatile bool CBatchTriCollMan::s_found_collision = false;
|
||||||
|
CBatchTriColl CBatchTriCollMan::s_tri_collision_array[MAX_BATCH_COLLISIONS][2];
|
||||||
|
int CBatchTriCollMan::s_current_array = 0;
|
||||||
|
int CBatchTriCollMan::s_array_size = 0;
|
||||||
|
int CBatchTriCollMan::s_next_idx_to_batch = 0;
|
||||||
|
int CBatchTriCollMan::s_num_collisions = 0;
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
int CBatchTriCollMan::s_collision_handler_id = -1;
|
||||||
|
bool CBatchTriCollMan::s_use_vu0_micro = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
bool vu0RayTriangleCollision(const Mth::Vector *rayStart, const Mth::Vector *rayDir,
|
||||||
|
Mth::Vector *v0, Mth::Vector *v1, Mth::Vector *v2, float *t)
|
||||||
|
{
|
||||||
|
register bool result;
|
||||||
|
|
||||||
|
asm __volatile__(
|
||||||
|
"
|
||||||
|
.set noreorder
|
||||||
|
lqc2 vf06,0x0(%4) # v0
|
||||||
|
lqc2 vf08,0x0(%6) # v2
|
||||||
|
lqc2 vf07,0x0(%5) # v1
|
||||||
|
lqc2 vf04,0x0(%2) # rayStart
|
||||||
|
lqc2 vf05,0x0(%3) # rayDir
|
||||||
|
|
||||||
|
vcallms RayTriangleCollision # call microsubroutine
|
||||||
|
vnop # interlocking instruction, waits for vu0 completion
|
||||||
|
|
||||||
|
cfc2 %0,$vi02 # get boolean result from vu0
|
||||||
|
#li %0,1 # store 1 for return value
|
||||||
|
|
||||||
|
beq %0, $0, vu0RayTriDone # skip copy of t if not needed
|
||||||
|
nop
|
||||||
|
|
||||||
|
qmfc2 $8, $vf17 # move t to $8
|
||||||
|
sw $8, 0(%1) # and write out
|
||||||
|
|
||||||
|
vu0RayTriDone:
|
||||||
|
|
||||||
|
.set reorder
|
||||||
|
": "=r" (result), "+r" (t) : "r" (rayStart), "r" (rayDir), "r" (v0), "r" (v1) , "r" (v2) : "$8", "$9" );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif // __PLAT_NGPS__
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CBatchTriCollMan::sInit(CollData *p_coll_data)
|
||||||
|
{
|
||||||
|
// Check for nesting; abort if true
|
||||||
|
if (s_processing)
|
||||||
|
{
|
||||||
|
s_nested++;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dbg_Assert(s_processing == false);
|
||||||
|
|
||||||
|
s_array_size = 0;
|
||||||
|
s_next_idx_to_batch = 0;
|
||||||
|
s_found_collision = false;
|
||||||
|
|
||||||
|
CBatchTriColl::sp_coll_data = p_coll_data;
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
// install interrupt handler for render completion
|
||||||
|
if (s_collision_handler_id == -1)
|
||||||
|
{
|
||||||
|
s_collision_handler_id = AddIntcHandler(INTC_VU0, s_collision_done, 0);
|
||||||
|
EnableIntc(INTC_VU0);
|
||||||
|
sceDevVu0PutTBit(1); // Use T-bit interrupt
|
||||||
|
}
|
||||||
|
#endif // __PLAT_NGPS__
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CBatchTriCollMan::sFinish()
|
||||||
|
{
|
||||||
|
if (s_nested)
|
||||||
|
{
|
||||||
|
s_nested--;
|
||||||
|
Dbg_Assert(s_nested >= 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, don't wait for collision to finish, since we
|
||||||
|
// are trying to avoid a stall here. But this will probably
|
||||||
|
// cause deadlock situations once it is on the VU0.
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CBatchTriCollMan::sAddTriCollision(const Mth::Line &test_line, const Mth::Vector &test_line_dir,
|
||||||
|
CCollObj *p_collision_obj, FaceIndex face_index)
|
||||||
|
{
|
||||||
|
Dbg_Assert(s_nested == 0);
|
||||||
|
|
||||||
|
CBatchTriColl *p_tri_collision;
|
||||||
|
p_tri_collision = &(s_tri_collision_array[s_array_size++][s_current_array]);
|
||||||
|
|
||||||
|
p_tri_collision->m_test_line = test_line;
|
||||||
|
p_tri_collision->m_test_line_dir = test_line_dir;
|
||||||
|
p_tri_collision->mp_collision_obj = p_collision_obj;
|
||||||
|
p_tri_collision->m_face_index = face_index;
|
||||||
|
|
||||||
|
//Dbg_Assert(s_array_size <= MAX_BATCH_COLLISIONS);
|
||||||
|
if (s_array_size == MAX_BATCH_COLLISIONS)
|
||||||
|
{
|
||||||
|
// sWaitTriCollisions(); // make sure were done working
|
||||||
|
sStartNewTriCollisions();
|
||||||
|
|
||||||
|
//s_switch_buffers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CBatchTriCollMan::sRemoveTriCollision(CBatchTriColl *p_tri_collision)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CBatchTriCollMan::sStartNewTriCollisions()
|
||||||
|
{
|
||||||
|
Dbg_Assert(s_nested == 0);
|
||||||
|
|
||||||
|
sWaitTriCollisions(); // make sure were done working
|
||||||
|
Dbg_Assert(!s_processing);
|
||||||
|
|
||||||
|
// Check if we have anything to do
|
||||||
|
if (s_next_idx_to_batch >= s_array_size)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_processing = true;
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
if(s_use_vu0_micro)
|
||||||
|
{
|
||||||
|
uint128 *p_vu0_mem = (uint128*)0x11004000; // VU0 data memory
|
||||||
|
|
||||||
|
// Write out sizes first
|
||||||
|
uint32 *p_vu0_word_mem = (uint32 *) (p_vu0_mem++);
|
||||||
|
*(p_vu0_word_mem++) = s_next_idx_to_batch;
|
||||||
|
*(p_vu0_word_mem++) = s_array_size;
|
||||||
|
|
||||||
|
for (int i = s_next_idx_to_batch; i < s_array_size; i++)
|
||||||
|
{
|
||||||
|
const CBatchTriColl &tri_coll = s_tri_collision_array[i][s_current_array];
|
||||||
|
|
||||||
|
Mth::Vector *v0, *v1, *v2;
|
||||||
|
if (tri_coll.mp_collision_obj->mp_coll_tri_data->m_use_face_small)
|
||||||
|
{
|
||||||
|
CCollObjTriData::SFaceSmall *face = &(tri_coll.mp_collision_obj->mp_coll_tri_data->mp_face_small[tri_coll.m_face_index]);
|
||||||
|
|
||||||
|
v0 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[0]];
|
||||||
|
v1 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[1]];
|
||||||
|
v2 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[2]];
|
||||||
|
} else {
|
||||||
|
CCollObjTriData::SFace *face = &(tri_coll.mp_collision_obj->mp_coll_tri_data->mp_faces[tri_coll.m_face_index]);
|
||||||
|
|
||||||
|
v0 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[0]];
|
||||||
|
v1 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[1]];
|
||||||
|
v2 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[2]];
|
||||||
|
}
|
||||||
|
|
||||||
|
*(p_vu0_mem++) = *((uint128*) &(tri_coll.m_test_line.m_start));
|
||||||
|
*(p_vu0_mem++) = *((uint128*) &(tri_coll.m_test_line_dir));
|
||||||
|
*(p_vu0_mem++) = *((uint128*) v0);
|
||||||
|
*(p_vu0_mem++) = *((uint128*) v1);
|
||||||
|
*(p_vu0_mem++) = *((uint128*) v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//FlushCache(WRITEBACK_DCACHE);
|
||||||
|
|
||||||
|
//sceDevVu0PutTBit(1); // Use T-bit interrupt
|
||||||
|
|
||||||
|
// Switch the buffers before we make the call (in case it finishes immediately)
|
||||||
|
s_switch_buffers();
|
||||||
|
|
||||||
|
asm __volatile__(
|
||||||
|
"
|
||||||
|
.set noreorder
|
||||||
|
sync.l
|
||||||
|
vcallms BatchRayTriangleCollision # call microsubroutine
|
||||||
|
|
||||||
|
.set reorder
|
||||||
|
");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // __PLAT_NGPS__
|
||||||
|
{
|
||||||
|
// Just do it manually now
|
||||||
|
for (int i = s_next_idx_to_batch; i < s_array_size; i++)
|
||||||
|
{
|
||||||
|
const CBatchTriColl &tri_coll = s_tri_collision_array[i][s_current_array];
|
||||||
|
|
||||||
|
Mth::Vector *v0, *v1, *v2;
|
||||||
|
if (tri_coll.mp_collision_obj->mp_coll_tri_data->m_use_face_small)
|
||||||
|
{
|
||||||
|
CCollObjTriData::SFaceSmall *face = &(tri_coll.mp_collision_obj->mp_coll_tri_data->mp_face_small[tri_coll.m_face_index]);
|
||||||
|
|
||||||
|
v0 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[0]];
|
||||||
|
v1 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[1]];
|
||||||
|
v2 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[2]];
|
||||||
|
} else {
|
||||||
|
CCollObjTriData::SFace *face = &(tri_coll.mp_collision_obj->mp_coll_tri_data->mp_faces[tri_coll.m_face_index]);
|
||||||
|
|
||||||
|
v0 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[0]];
|
||||||
|
v1 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[1]];
|
||||||
|
v2 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[2]];
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance;
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
if (vu0RayTriangleCollision(&tri_coll.m_test_line.m_start, &tri_coll.m_test_line_dir, v0, v1, v2, &distance))
|
||||||
|
#else
|
||||||
|
if (CCollObj::sRayTriangleCollision(&tri_coll.m_test_line.m_start, &tri_coll.m_test_line_dir,
|
||||||
|
v0, v1, v2, &distance))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
SCollSurface collisionSurface;
|
||||||
|
|
||||||
|
/* We've got one */
|
||||||
|
collisionSurface.point = (*v0);
|
||||||
|
collisionSurface.index = tri_coll.m_face_index;
|
||||||
|
|
||||||
|
// Find normal
|
||||||
|
Mth::Vector vTmp1(*v1 - *v0);
|
||||||
|
Mth::Vector vTmp2(*v2 - *v0);
|
||||||
|
collisionSurface.normal = Mth::CrossProduct(vTmp1, vTmp2);
|
||||||
|
collisionSurface.normal.Normalize();
|
||||||
|
|
||||||
|
if (CCollObj::s_found_collision(&tri_coll.m_test_line, tri_coll.mp_collision_obj, &collisionSurface, distance, CBatchTriColl::sp_coll_data))
|
||||||
|
{
|
||||||
|
s_found_collision = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_processing = false; // Just for manual version
|
||||||
|
|
||||||
|
s_switch_buffers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
int CBatchTriCollMan::s_collision_done(int arg)
|
||||||
|
{
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
// We should check to see if this is the T-bit first (instead of the debug D bit)
|
||||||
|
uint32 stat;
|
||||||
|
asm( "cfc2 %0, $vi29" :"=r"( stat ) : );
|
||||||
|
if ( !(stat & 0x4) )
|
||||||
|
{
|
||||||
|
ExitHandler();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save floats
|
||||||
|
//unsigned int floatBuffer[32];
|
||||||
|
//saveFloatRegs(floatBuffer);
|
||||||
|
|
||||||
|
asm __volatile__(
|
||||||
|
"
|
||||||
|
.set noreorder
|
||||||
|
cfc2 %0,$vi01 # get number of collisions result from vu0
|
||||||
|
|
||||||
|
.set reorder
|
||||||
|
": "=r" (s_num_collisions) );
|
||||||
|
|
||||||
|
s_processing = false; // Tell that we are done
|
||||||
|
|
||||||
|
if (s_num_collisions > 0)
|
||||||
|
{
|
||||||
|
s_result_processing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore floats
|
||||||
|
//restoreFloatRegs(floatBuffer);
|
||||||
|
|
||||||
|
ExitHandler();
|
||||||
|
#endif // __PLAT_NGPS__
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CBatchTriCollMan::s_process_results()
|
||||||
|
{
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
SCollOutput *p_output = (SCollOutput*)0x11004010; // VU0 data memory
|
||||||
|
int previous_array = s_current_array ^ 1;
|
||||||
|
for (int i = 0; i < s_num_collisions; i++)
|
||||||
|
{
|
||||||
|
const CBatchTriColl &tri_coll = s_tri_collision_array[p_output->index][previous_array];
|
||||||
|
|
||||||
|
Mth::Vector *v0, *v1, *v2;
|
||||||
|
if (tri_coll.mp_collision_obj->mp_coll_tri_data->m_use_face_small)
|
||||||
|
{
|
||||||
|
CCollObjTriData::SFaceSmall *face = &(tri_coll.mp_collision_obj->mp_coll_tri_data->mp_face_small[tri_coll.m_face_index]);
|
||||||
|
|
||||||
|
v0 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[0]];
|
||||||
|
v1 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[1]];
|
||||||
|
v2 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[2]];
|
||||||
|
} else {
|
||||||
|
CCollObjTriData::SFace *face = &(tri_coll.mp_collision_obj->mp_coll_tri_data->mp_faces[tri_coll.m_face_index]);
|
||||||
|
|
||||||
|
v0 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[0]];
|
||||||
|
v1 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[1]];
|
||||||
|
v2 = &tri_coll.mp_collision_obj->mp_coll_tri_data->mp_vert_pos[face->m_vertex_index[2]];
|
||||||
|
}
|
||||||
|
|
||||||
|
SCollSurface collisionSurface;
|
||||||
|
|
||||||
|
/* We've got one */
|
||||||
|
collisionSurface.point = (*v0);
|
||||||
|
collisionSurface.index = tri_coll.m_face_index;
|
||||||
|
|
||||||
|
// Find normal
|
||||||
|
Mth::Vector vTmp1(*v1 - *v0);
|
||||||
|
Mth::Vector vTmp2(*v2 - *v0);
|
||||||
|
collisionSurface.normal = Mth::CrossProduct(vTmp1, vTmp2);
|
||||||
|
collisionSurface.normal.Normalize();
|
||||||
|
|
||||||
|
if (CCollObj::s_found_collision(&tri_coll.m_test_line, tri_coll.mp_collision_obj, &collisionSurface, p_output->distance, CBatchTriColl::sp_coll_data))
|
||||||
|
{
|
||||||
|
s_found_collision = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_output++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_result_processing = false;
|
||||||
|
#else
|
||||||
|
Dbg_Assert(s_result_processing);
|
||||||
|
#endif // __PLAT_NGPS__
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CBatchTriCollMan::sWaitTriCollisions()
|
||||||
|
{
|
||||||
|
// Wait for collision to finish
|
||||||
|
while (s_processing)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (s_result_processing)
|
||||||
|
{
|
||||||
|
s_process_results();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_found_collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
bool CBatchTriCollMan::sUseVU0Micro()
|
||||||
|
{
|
||||||
|
// Make sure we're not in the middle of something
|
||||||
|
Dbg_Assert(!s_processing);
|
||||||
|
Dbg_Assert(!s_result_processing);
|
||||||
|
|
||||||
|
return s_use_vu0_micro = NxPs2::CSystemResources::sRequestResource(NxPs2::CSystemResources::vVU0_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
void CBatchTriCollMan::sDisableVU0Micro()
|
||||||
|
{
|
||||||
|
// Make sure we're not in the middle of something
|
||||||
|
Dbg_Assert(!s_processing);
|
||||||
|
Dbg_Assert(!s_result_processing);
|
||||||
|
|
||||||
|
if (s_use_vu0_micro)
|
||||||
|
{
|
||||||
|
NxPs2::CSystemResources::sFreeResource(NxPs2::CSystemResources::vVU0_MEMORY);
|
||||||
|
s_use_vu0_micro = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // __PLAT_NGPS__
|
||||||
|
|
||||||
|
#endif // BATCH_TRI_COLLISION
|
||||||
|
|
||||||
|
} // namespace Nx
|
||||||
|
|
163
Code/Gel/Collision/BatchTriColl.h
Normal file
163
Code/Gel/Collision/BatchTriColl.h
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
** **
|
||||||
|
** Neversoft Entertainment **
|
||||||
|
** **
|
||||||
|
** Copyright (C) 2002 - All Rights Reserved **
|
||||||
|
** **
|
||||||
|
******************************************************************************
|
||||||
|
** **
|
||||||
|
** Project: PS2 **
|
||||||
|
** **
|
||||||
|
** Module: Nx **
|
||||||
|
** **
|
||||||
|
** File name: BatchTriColl.h **
|
||||||
|
** **
|
||||||
|
** Created: 04/12/2002 - grj **
|
||||||
|
** **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __GEL_BATCHTRICOLL_H
|
||||||
|
#define __GEL_BATCHTRICOLL_H
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Includes **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __CORE_DEFINES_H
|
||||||
|
#include <core/defines.h>
|
||||||
|
#endif
|
||||||
|
#include <core/math.h>
|
||||||
|
#include <core/math/geometry.h>
|
||||||
|
|
||||||
|
#include <gel/collision/collenums.h>
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Defines **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
//#define BATCH_TRI_COLLISION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Nx
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef BATCH_TRI_COLLISION
|
||||||
|
|
||||||
|
class CCollObj;
|
||||||
|
class CollData;
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
** Class Definitions **
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
class CBatchTriColl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mth::Line m_test_line;
|
||||||
|
Mth::Vector m_test_line_dir;
|
||||||
|
CCollObj * mp_collision_obj;
|
||||||
|
float m_distance;
|
||||||
|
FaceIndex m_face_index;
|
||||||
|
|
||||||
|
static CollData * sp_coll_data; // We should only have one at a time
|
||||||
|
};
|
||||||
|
|
||||||
|
// Results from collision
|
||||||
|
struct SCollOutput
|
||||||
|
{
|
||||||
|
float distance;
|
||||||
|
int pad1;
|
||||||
|
int pad2;
|
||||||
|
int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CBatchTriCollMan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool sInit(CollData *p_coll_data);
|
||||||
|
static void sFinish();
|
||||||
|
|
||||||
|
static void sAddTriCollision(const Mth::Line &test_line, const Mth::Vector &test_line_dir,
|
||||||
|
CCollObj *p_collision_obj, FaceIndex face_index);
|
||||||
|
static bool sRemoveTriCollision(CBatchTriColl *p_tri_collsion);
|
||||||
|
|
||||||
|
static void sStartNewTriCollisions();
|
||||||
|
static volatile bool sIsTriCollisionDone();
|
||||||
|
static volatile bool sIsNested();
|
||||||
|
static bool sWaitTriCollisions();
|
||||||
|
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
static bool sUseVU0Micro();
|
||||||
|
static void sDisableVU0Micro();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MAX_BATCH_COLLISIONS = 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Collision callback
|
||||||
|
static int s_collision_done(int);
|
||||||
|
static void s_process_results();
|
||||||
|
|
||||||
|
static void s_switch_buffers();
|
||||||
|
|
||||||
|
static volatile bool s_processing;
|
||||||
|
static volatile bool s_result_processing;
|
||||||
|
static volatile int s_nested; // Indicates nesting level, so normal collision must be used
|
||||||
|
static volatile bool s_found_collision;
|
||||||
|
|
||||||
|
static CBatchTriColl s_tri_collision_array[MAX_BATCH_COLLISIONS][2]; // Double buffered
|
||||||
|
static int s_current_array;
|
||||||
|
static int s_array_size;
|
||||||
|
static int s_next_idx_to_batch;
|
||||||
|
|
||||||
|
static int s_num_collisions;
|
||||||
|
static SCollOutput s_collision_results[MAX_BATCH_COLLISIONS];
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef __PLAT_NGPS__
|
||||||
|
static int s_collision_handler_id;// for interrupt callback
|
||||||
|
static bool s_use_vu0_micro;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline volatile bool CBatchTriCollMan::sIsTriCollisionDone()
|
||||||
|
{
|
||||||
|
return !s_processing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline volatile bool CBatchTriCollMan::sIsNested()
|
||||||
|
{
|
||||||
|
return s_nested > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************/
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/******************************************************************/
|
||||||
|
|
||||||
|
inline void CBatchTriCollMan::s_switch_buffers()
|
||||||
|
{
|
||||||
|
s_array_size = 0;
|
||||||
|
s_next_idx_to_batch = 0;
|
||||||
|
s_current_array = s_current_array ^ 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BATCH_TRI_COLLISION
|
||||||
|
|
||||||
|
} // namespace Nx
|
||||||
|
|
||||||
|
#endif // __GEL_BATCHTRICOLL_H
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user