2
0

pointerremap.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWSaveLoad *
  23. * *
  24. * $Archive:: /Commando/Code/wwsaveload/pointerremap.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 5/09/01 11:36a $*
  29. * *
  30. * $Revision:: 9 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "pointerremap.h"
  36. #include "refcount.h"
  37. #include "wwdebug.h"
  38. const int POINTER_TABLES_GROWTH_STEP = 4096;
  39. PointerRemapClass::PointerRemapClass(void)
  40. {
  41. PointerPairTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
  42. PointerRequestTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
  43. RefCountRequestTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
  44. }
  45. PointerRemapClass::~PointerRemapClass(void)
  46. {
  47. }
  48. void PointerRemapClass::Reset(void)
  49. {
  50. PointerPairTable.Delete_All();
  51. PointerRequestTable.Delete_All();
  52. RefCountRequestTable.Delete_All();
  53. }
  54. void PointerRemapClass::Process(void)
  55. {
  56. if ( PointerPairTable.Count() > 0 ) {
  57. qsort(&PointerPairTable[0], PointerPairTable.Count(), sizeof(PointerPairTable[0]), ptr_pair_compare_function);
  58. }
  59. if ( PointerRequestTable.Count() > 0 ) {
  60. WWASSERT( PointerPairTable.Count() > 0 );
  61. qsort(&PointerRequestTable[0],PointerRequestTable.Count(), sizeof(PointerRequestTable[0]), ptr_request_compare_function);
  62. Process_Request_Table(PointerRequestTable,false);
  63. }
  64. // remap the ref-counted pointers
  65. if ( RefCountRequestTable.Count() > 0 ) {
  66. WWASSERT( PointerPairTable.Count() > 0 );
  67. qsort(&RefCountRequestTable[0],RefCountRequestTable.Count(), sizeof(RefCountRequestTable[0]), ptr_request_compare_function);
  68. Process_Request_Table(RefCountRequestTable,true);
  69. }
  70. }
  71. void PointerRemapClass::Process_Request_Table(DynamicVectorClass<PtrRemapStruct> & request_table,bool refcount)
  72. {
  73. // Remap the pointers
  74. int pointer_index = 0;
  75. int pair_index = 0;
  76. for (pointer_index = 0; pointer_index < request_table.Count(); pointer_index++) {
  77. void * pointer_to_remap = *(request_table[pointer_index].PointerToRemap);
  78. int pre_search_index = pair_index;
  79. // Find the pair which contains the pointer we are looking for as its "old" pointer
  80. while ( (pair_index < PointerPairTable.Count()) &&
  81. (PointerPairTable[pair_index].OldPointer < pointer_to_remap) )
  82. {
  83. pair_index++;
  84. }
  85. if ((pair_index < PointerPairTable.Count()) && (PointerPairTable[pair_index].OldPointer == pointer_to_remap)) {
  86. // we found the match, plug in the new pointer and add a ref if needed.
  87. *request_table[pointer_index].PointerToRemap = PointerPairTable[pair_index].NewPointer;
  88. if (refcount) {
  89. RefCountClass * refptr = (RefCountClass *)(*request_table[pointer_index].PointerToRemap);
  90. refptr->Add_Ref();
  91. }
  92. } else {
  93. // Failed to re-map the pointer.
  94. // warn the user, set pointer to NULL, reset index to the pre_search_index.
  95. // If this happens, things could be going very wrong. (find out why its happening!)
  96. pair_index = pre_search_index;
  97. *request_table[pointer_index].PointerToRemap = NULL;
  98. #ifdef WWDEBUG
  99. const char * file = request_table[pointer_index].File;
  100. int line = request_table[pointer_index].Line;
  101. 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));
  102. WWASSERT( 0 );
  103. #endif
  104. }
  105. }
  106. }
  107. void PointerRemapClass::Register_Pointer (void *old_pointer, void *new_pointer)
  108. {
  109. PointerPairTable.Add(PtrPairStruct(old_pointer,new_pointer));
  110. }
  111. #ifdef WWDEBUG
  112. void PointerRemapClass::Request_Pointer_Remap(void **pointer_to_convert,const char * file,int line)
  113. {
  114. PtrRemapStruct remap;
  115. remap.PointerToRemap = pointer_to_convert;
  116. remap.File = file;
  117. remap.Line = line;
  118. PointerRequestTable.Add(remap);
  119. }
  120. void PointerRemapClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file, int line)
  121. {
  122. PtrRemapStruct remap;
  123. remap.PointerToRemap = (void**)pointer_to_convert;
  124. remap.File = file;
  125. remap.Line = line;
  126. RefCountRequestTable.Add(remap);
  127. }
  128. #else
  129. void PointerRemapClass::Request_Pointer_Remap (void **pointer_to_convert)
  130. {
  131. PtrRemapStruct remap;
  132. remap.PointerToRemap = pointer_to_convert;
  133. PointerRequestTable.Add(remap);
  134. }
  135. void PointerRemapClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert)
  136. {
  137. PtrRemapStruct remap;
  138. remap.PointerToRemap = (void**)pointer_to_convert;
  139. RefCountRequestTable.Add(remap);
  140. }
  141. #endif
  142. /*
  143. ** sort compare function for pointer pair structures
  144. ** sorts by the old pointer value
  145. */
  146. int __cdecl PointerRemapClass::ptr_pair_compare_function(void const * ptr1, void const * ptr2)
  147. {
  148. void * old1 = ((PointerRemapClass::PtrPairStruct const *)ptr1)->OldPointer;
  149. void * old2 = ((PointerRemapClass::PtrPairStruct const *)ptr2)->OldPointer;
  150. if (old1 == old2) {
  151. return(0);
  152. }
  153. if (old1 < old2) {
  154. return(-1);
  155. }
  156. return(1);
  157. }
  158. /*
  159. ** sort compare function for pointer remap structures
  160. ** sorts by the old pointer value
  161. */
  162. int __cdecl PointerRemapClass::ptr_request_compare_function(void const * ptr1, void const * ptr2)
  163. {
  164. PtrRemapStruct * remap1 = (PtrRemapStruct *)ptr1;
  165. PtrRemapStruct * remap2 = (PtrRemapStruct *)ptr2;
  166. void * old1 = *(remap1->PointerToRemap);
  167. void * old2 = *(remap2->PointerToRemap);
  168. if (old1 == old2) {
  169. return(0);
  170. }
  171. if (old1 < old2) {
  172. return(-1);
  173. }
  174. return(1);
  175. }