mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
210
Code/wwsaveload/pointerremap.cpp
Normal file
210
Code/wwsaveload/pointerremap.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
** Command & Conquer Renegade(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation, either version 3 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***********************************************************************************************
|
||||
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
||||
***********************************************************************************************
|
||||
* *
|
||||
* Project Name : WWSaveLoad *
|
||||
* *
|
||||
* $Archive:: /Commando/Code/wwsaveload/pointerremap.cpp $*
|
||||
* *
|
||||
* Author:: Greg Hjelstrom *
|
||||
* *
|
||||
* $Modtime:: 5/09/01 11:36a $*
|
||||
* *
|
||||
* $Revision:: 9 $*
|
||||
* *
|
||||
*---------------------------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
#include "pointerremap.h"
|
||||
#include "refcount.h"
|
||||
#include "wwdebug.h"
|
||||
|
||||
|
||||
const int POINTER_TABLES_GROWTH_STEP = 4096;
|
||||
|
||||
|
||||
PointerRemapClass::PointerRemapClass(void)
|
||||
{
|
||||
PointerPairTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
|
||||
PointerRequestTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
|
||||
RefCountRequestTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
|
||||
}
|
||||
|
||||
PointerRemapClass::~PointerRemapClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
void PointerRemapClass::Reset(void)
|
||||
{
|
||||
PointerPairTable.Delete_All();
|
||||
PointerRequestTable.Delete_All();
|
||||
RefCountRequestTable.Delete_All();
|
||||
}
|
||||
|
||||
void PointerRemapClass::Process(void)
|
||||
{
|
||||
if ( PointerPairTable.Count() > 0 ) {
|
||||
qsort(&PointerPairTable[0], PointerPairTable.Count(), sizeof(PointerPairTable[0]), ptr_pair_compare_function);
|
||||
}
|
||||
|
||||
if ( PointerRequestTable.Count() > 0 ) {
|
||||
WWASSERT( PointerPairTable.Count() > 0 );
|
||||
qsort(&PointerRequestTable[0],PointerRequestTable.Count(), sizeof(PointerRequestTable[0]), ptr_request_compare_function);
|
||||
Process_Request_Table(PointerRequestTable,false);
|
||||
}
|
||||
|
||||
// remap the ref-counted pointers
|
||||
if ( RefCountRequestTable.Count() > 0 ) {
|
||||
WWASSERT( PointerPairTable.Count() > 0 );
|
||||
qsort(&RefCountRequestTable[0],RefCountRequestTable.Count(), sizeof(RefCountRequestTable[0]), ptr_request_compare_function);
|
||||
Process_Request_Table(RefCountRequestTable,true);
|
||||
}
|
||||
}
|
||||
|
||||
void PointerRemapClass::Process_Request_Table(DynamicVectorClass<PtrRemapStruct> & request_table,bool refcount)
|
||||
{
|
||||
// Remap the pointers
|
||||
int pointer_index = 0;
|
||||
int pair_index = 0;
|
||||
|
||||
for (pointer_index = 0; pointer_index < request_table.Count(); pointer_index++) {
|
||||
|
||||
void * pointer_to_remap = *(request_table[pointer_index].PointerToRemap);
|
||||
int pre_search_index = pair_index;
|
||||
|
||||
// Find the pair which contains the pointer we are looking for as its "old" pointer
|
||||
while ( (pair_index < PointerPairTable.Count()) &&
|
||||
(PointerPairTable[pair_index].OldPointer < pointer_to_remap) )
|
||||
{
|
||||
pair_index++;
|
||||
}
|
||||
|
||||
if ((pair_index < PointerPairTable.Count()) && (PointerPairTable[pair_index].OldPointer == pointer_to_remap)) {
|
||||
|
||||
// we found the match, plug in the new pointer and add a ref if needed.
|
||||
*request_table[pointer_index].PointerToRemap = PointerPairTable[pair_index].NewPointer;
|
||||
|
||||
if (refcount) {
|
||||
RefCountClass * refptr = (RefCountClass *)(*request_table[pointer_index].PointerToRemap);
|
||||
refptr->Add_Ref();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Failed to re-map the pointer.
|
||||
// warn the user, set pointer to NULL, reset index to the pre_search_index.
|
||||
// If this happens, things could be going very wrong. (find out why its happening!)
|
||||
pair_index = pre_search_index;
|
||||
*request_table[pointer_index].PointerToRemap = NULL;
|
||||
#ifdef WWDEBUG
|
||||
const char * file = request_table[pointer_index].File;
|
||||
int line = request_table[pointer_index].Line;
|
||||
WWDEBUG_SAY(("Warning! Failed to re-map pointer! old_ptr = 0x%X file = %s line = %d\r\n",(unsigned int)pointer_to_remap,file,line));
|
||||
WWASSERT( 0 );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PointerRemapClass::Register_Pointer (void *old_pointer, void *new_pointer)
|
||||
{
|
||||
PointerPairTable.Add(PtrPairStruct(old_pointer,new_pointer));
|
||||
}
|
||||
|
||||
#ifdef WWDEBUG
|
||||
void PointerRemapClass::Request_Pointer_Remap(void **pointer_to_convert,const char * file,int line)
|
||||
{
|
||||
PtrRemapStruct remap;
|
||||
remap.PointerToRemap = pointer_to_convert;
|
||||
remap.File = file;
|
||||
remap.Line = line;
|
||||
PointerRequestTable.Add(remap);
|
||||
}
|
||||
|
||||
void PointerRemapClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file, int line)
|
||||
{
|
||||
PtrRemapStruct remap;
|
||||
remap.PointerToRemap = (void**)pointer_to_convert;
|
||||
remap.File = file;
|
||||
remap.Line = line;
|
||||
RefCountRequestTable.Add(remap);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void PointerRemapClass::Request_Pointer_Remap (void **pointer_to_convert)
|
||||
{
|
||||
PtrRemapStruct remap;
|
||||
remap.PointerToRemap = pointer_to_convert;
|
||||
PointerRequestTable.Add(remap);
|
||||
}
|
||||
|
||||
void PointerRemapClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert)
|
||||
{
|
||||
PtrRemapStruct remap;
|
||||
remap.PointerToRemap = (void**)pointer_to_convert;
|
||||
RefCountRequestTable.Add(remap);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** sort compare function for pointer pair structures
|
||||
** sorts by the old pointer value
|
||||
*/
|
||||
int __cdecl PointerRemapClass::ptr_pair_compare_function(void const * ptr1, void const * ptr2)
|
||||
{
|
||||
void * old1 = ((PointerRemapClass::PtrPairStruct const *)ptr1)->OldPointer;
|
||||
void * old2 = ((PointerRemapClass::PtrPairStruct const *)ptr2)->OldPointer;
|
||||
|
||||
if (old1 == old2) {
|
||||
return(0);
|
||||
}
|
||||
if (old1 < old2) {
|
||||
return(-1);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
** sort compare function for pointer remap structures
|
||||
** sorts by the old pointer value
|
||||
*/
|
||||
int __cdecl PointerRemapClass::ptr_request_compare_function(void const * ptr1, void const * ptr2)
|
||||
{
|
||||
PtrRemapStruct * remap1 = (PtrRemapStruct *)ptr1;
|
||||
PtrRemapStruct * remap2 = (PtrRemapStruct *)ptr2;
|
||||
|
||||
void * old1 = *(remap1->PointerToRemap);
|
||||
void * old2 = *(remap2->PointerToRemap);
|
||||
|
||||
if (old1 == old2) {
|
||||
return(0);
|
||||
}
|
||||
if (old1 < old2) {
|
||||
return(-1);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user