CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

HEAP.CPP (29605B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header:   F:\projects\c&c\vcs\code\heap.cpv   2.18   16 Oct 1995 16:49:56   JOE_BOSTIC  $ */
     17 /*********************************************************************************************** 
     18  ***             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               *** 
     19  *********************************************************************************************** 
     20  *                                                                                             * 
     21  *                 Project Name : Command & Conquer                                            * 
     22  *                                                                                             * 
     23  *                    File Name : HEAP.CPP                                                     * 
     24  *                                                                                             * 
     25  *                   Programmer : Joe L. Bostic                                                * 
     26  *                                                                                             * 
     27  *                   Start Date : 02/18/95                                                     * 
     28  *                                                                                             * 
     29  *                  Last Update : May 22, 1995 [JLB]                                           * 
     30  *                                                                                             * 
     31  *---------------------------------------------------------------------------------------------* 
     32  * Functions:                                                                                  * 
     33  *   FixedIHeapClass::Free -- Frees an object in the heap.                                     * 
     34  *   FixedHeapClass::FixedHeapClass -- Normal constructor for heap management class.           * 
     35  *   FixedHeapClass::~FixedHeapClass -- Destructor for the heap manager class.                 * 
     36  *   FixedHeapClass::Set_Heap -- Assigns a memory block for this heap manager.                 * 
     37  *   FixedHeapClass::Allocate -- Allocate a sub-block from the heap.                           * 
     38  *   FixedHeapClass::Free -- Frees a sub-block in the heap.                                    * 
     39  *   FixedHeapClass::ID -- Converts a pointer to a sub-block index number.                     * 
     40  *   FixedHeapClass::Clear -- Clears (and frees) the heap manager memory.                      * 
     41  *   TFixedIHeapClass::Save -- Saves all active objects                                        *
     42  *   TFixedIHeapClass::Load -- Loads all active objects                                        *
     43  *   TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save   *
     44  *   TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading       *
     45  *   FixedHeapClass::Free_All -- Frees all objects in the fixed heap.                          * 
     46  *   FixedIHeapClass::Free_All -- Frees all objects out of the indexed heap.                   * 
     47  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     48 
     49 
     50 #include	"function.h"
     51 #include	"heap.h"
     52 //#include	<mem.h>
     53 #include	<stdio.h>
     54 #include	<stddef.h>
     55 #include	<conio.h>
     56 #include	<string.h>
     57 
     58 
     59 /*********************************************************************************************** 
     60  * FixedHeapClass::FixedHeapClass -- Normal constructor for heap management class.             * 
     61  *                                                                                             * 
     62  *    This is the normal constructor used for the heap manager class. This initializes         * 
     63  *    the class but doesn't yet assign actual heap memory to this manager. That is handled     * 
     64  *    by the Set_Heap() function.                                                              * 
     65  *                                                                                             * 
     66  * INPUT:   size  -- The size of the individual sub-blocks in this heap. This value is         * 
     67  *                   typically the size of some class or structure.                            * 
     68  *                                                                                             * 
     69  * OUTPUT:  none                                                                               * 
     70  *                                                                                             * 
     71  * WARNINGS:   The heap must first be assigned a block of memory to manage before it can       * 
     72  *             be used.                                                                        * 
     73  *                                                                                             * 
     74  * HISTORY:                                                                                    * 
     75  *   02/21/1995 JLB : Created.                                                                 * 
     76  *=============================================================================================*/
     77 FixedHeapClass::FixedHeapClass(int size)
     78 {
     79 	Size = size;
     80 	Buffer = 0;
     81 	IsAllocated = false;
     82 	TotalCount = 0;
     83 	ActiveCount = 0;
     84 }	
     85 
     86 
     87 /*********************************************************************************************** 
     88  * FixedHeapClass::~FixedHeapClass -- Destructor for the heap manager class.                   * 
     89  *                                                                                             * 
     90  *    This is the default constructor for the heap manager class. It handles freeing the       * 
     91  *    memory assigned to this heap.                                                            * 
     92  *                                                                                             * 
     93  * INPUT:   none                                                                               * 
     94  *                                                                                             * 
     95  * OUTPUT:  none                                                                               * 
     96  *                                                                                             * 
     97  * WARNINGS:   none                                                                            * 
     98  *                                                                                             * 
     99  * HISTORY:                                                                                    * 
    100  *   02/21/1995 JLB : Created.                                                                 * 
    101  *=============================================================================================*/
    102 FixedHeapClass::~FixedHeapClass(void)
    103 {
    104 	FixedHeapClass::Clear();
    105 }	
    106 
    107 
    108 /*********************************************************************************************** 
    109  * FixedHeapClass::Set_Heap -- Assigns a memory block for this heap manager.                   * 
    110  *                                                                                             * 
    111  *    This routine is used to assign a memory heap to this object. A memory heap so assigned   * 
    112  *    will start with all sub-blocks unallocated. After this routine is called, normal         * 
    113  *    allocation and freeing may occur. This routine will allocate necessary memory if the     * 
    114  *    buffer parameter is NULL.                                                                * 
    115  *                                                                                             * 
    116  * INPUT:   count    -- The number of objects that this heap should manage.                    * 
    117  *                                                                                             * 
    118  *          buffer   -- Pointer to pre-allocated buffer that this manager will use. If this    * 
    119  *                      parameter is NULL, then memory will be automatically allocated.        * 
    120  *                                                                                             * 
    121  * OUTPUT:  bool; Was the heap successfully initialized?                                       * 
    122  *                                                                                             * 
    123  * WARNINGS:   none                                                                            * 
    124  *                                                                                             * 
    125  * HISTORY:                                                                                    * 
    126  *   02/21/1995 JLB : Created.                                                                 * 
    127  *=============================================================================================*/
    128 int FixedHeapClass::Set_Heap(int count, void * buffer)
    129 {
    130 	/*
    131 	**	Clear out the old heap data.
    132 	*/
    133 	Clear();
    134 
    135 	/*
    136 	**	If there is no size to the objects in the heap, then this block memory
    137 	**	handler can NEVER function. Return with a failure condition.
    138 	*/
    139 	if (!Size) return(false);
    140 
    141 	/*
    142 	**	If there is no count specified, then this indicates that the heap should
    143 	**	be disabled.
    144 	*/
    145 	if (!count) return(true);
    146 
    147 	/*
    148 	**	Initialize the free boolean vector and the buffer for the actual
    149 	**	allocation objects.
    150 	*/
    151 	if (FreeFlag.Resize(count)) {
    152 		if (!buffer) {
    153 			buffer = new char[count * Size];
    154 			if (!buffer) {
    155 				FreeFlag.Clear();
    156 				return(false);
    157 			}
    158 			IsAllocated = true;
    159 		}
    160 		Buffer = buffer;
    161 		TotalCount = count;
    162 
    163 		memset((unsigned char *)Buffer, 0x00, count * Size);  // Added. Needed to identify bad states in saved games. ST - 10/3/2019 11:49AM		
    164 
    165 		return(true);
    166 	}
    167 	return(false);
    168 }	
    169 
    170 
    171 /*********************************************************************************************** 
    172  * FixedHeapClass::Allocate -- Allocate a sub-block from the heap.                             * 
    173  *                                                                                             * 
    174  *    Finds the first available sub-block in the heap and returns a pointer to it. The sub-    * 
    175  *    block is marked as allocated by this routine. If there are no more sub-blocks            * 
    176  *    available, then this routine will return NULL.                                           * 
    177  *                                                                                             * 
    178  * INPUT:   none                                                                               * 
    179  *                                                                                             * 
    180  * OUTPUT:  Returns with a pointer to the newly allocated sub-block.                           * 
    181  *                                                                                             * 
    182  * WARNINGS:   none                                                                            * 
    183  *                                                                                             * 
    184  * HISTORY:                                                                                    * 
    185  *   02/21/1995 JLB : Created.                                                                 * 
    186  *=============================================================================================*/
    187 void * FixedHeapClass::Allocate(void)
    188 {
    189 	if (ActiveCount < TotalCount) {
    190 		int index = FreeFlag.First_False();
    191 
    192 		if (index != -1) {
    193 			ActiveCount++;
    194 			FreeFlag[index] = true;
    195 			return((*this)[index]);
    196 		}
    197 	}
    198 	return(0);
    199 }	
    200 
    201 
    202 /*********************************************************************************************** 
    203  * FixedHeapClass::Free -- Frees a sub-block in the heap.                                      * 
    204  *                                                                                             * 
    205  *    Use this routine to free a previously allocated sub-block in the heap.                   * 
    206  *                                                                                             * 
    207  * INPUT:   pointer  -- A pointer to the sub-block to free. This is the same pointer that      * 
    208  *                      was returned from the Allocate() function.                             * 
    209  *                                                                                             * 
    210  * OUTPUT:  bool; Was the deallocation successful? Failure could indicate a pointer that       * 
    211  *                doesn't refer to this heap or a null pointer.                                * 
    212  *                                                                                             * 
    213  * WARNINGS:   none                                                                            * 
    214  *                                                                                             * 
    215  * HISTORY:                                                                                    * 
    216  *   02/21/1995 JLB : Created.                                                                 * 
    217  *=============================================================================================*/
    218 int FixedHeapClass::Free(void * pointer)
    219 {
    220 	if (pointer && ActiveCount) {
    221 		int index = ID(pointer);
    222 
    223 		if (index < TotalCount) {
    224 			if (FreeFlag[index]) {
    225 				ActiveCount--;
    226 				FreeFlag[index] = false;
    227 
    228 				return(true);	 
    229 			}
    230 		}
    231 	}
    232 	return(false);
    233 }	
    234 
    235 
    236 /*********************************************************************************************** 
    237  * FixedHeapClass::ID -- Converts a pointer to a sub-block index number.                       * 
    238  *                                                                                             * 
    239  *    Use this routine to convert a pointer (returned by Allocate) into the sub-block          * 
    240  *    index number. This index number can be used as a form of identifier for the block.       * 
    241  *                                                                                             * 
    242  * INPUT:   pointer  -- A pointer to the sub-block to conver into an ID number.                * 
    243  *                                                                                             * 
    244  * OUTPUT:  Returns with the index (ID) number for the sub-block specified. This number will   * 
    245  *          range between 0 and the sub-block max -1. If -1 is returned, then the pointer      * 
    246  *          was invalid.                                                                       * 
    247  *                                                                                             * 
    248  * WARNINGS:   none                                                                            * 
    249  *                                                                                             * 
    250  * HISTORY:                                                                                    * 
    251  *   02/21/1995 JLB : Created.                                                                 * 
    252  *=============================================================================================*/
    253 int FixedHeapClass::ID(void const * pointer)
    254 {
    255 	if (pointer && Size) {
    256 		return((int)(((char *)pointer - (char *)Buffer) / Size));
    257 	}
    258 	return(-1);
    259 }	
    260 
    261 
    262 /*********************************************************************************************** 
    263  * FixedHeapClass::Clear -- Clears (and frees) the heap manager memory.                        * 
    264  *                                                                                             * 
    265  *    This routine is used to bring the heap manager back into a non-functioning state. All    * 
    266  *    memory allocated by this manager is freeed. Any previous pointers to allocated blocks    * 
    267  *    from this heap are now invalid.                                                          * 
    268  *                                                                                             * 
    269  * INPUT:   none                                                                               * 
    270  *                                                                                             * 
    271  * OUTPUT:  none                                                                               * 
    272  *                                                                                             * 
    273  * WARNINGS:   none                                                                            * 
    274  *                                                                                             * 
    275  * HISTORY:                                                                                    * 
    276  *   02/21/1995 JLB : Created.                                                                 * 
    277  *=============================================================================================*/
    278 void FixedHeapClass::Clear(void)
    279 {
    280 	/*
    281 	**	Free the old buffer (if present).
    282 	*/
    283 	if (Buffer && IsAllocated) {
    284 		delete[] Buffer;
    285 	}
    286 	Buffer = 0;
    287 	IsAllocated = false;
    288 	ActiveCount = 0;
    289 	TotalCount = 0;
    290 	FreeFlag.Clear();
    291 }	
    292 
    293 
    294 /*********************************************************************************************** 
    295  * FixedHeapClass::Free_All -- Frees all objects in the fixed heap.                            * 
    296  *                                                                                             * 
    297  *    This routine will free all previously allocated objects out of the heap. Use this        * 
    298  *    routine to ensure that the heap is empty.                                                * 
    299  *                                                                                             * 
    300  * INPUT:   none                                                                               * 
    301  *                                                                                             * 
    302  * OUTPUT:  Was the heap successfully cleared of all objects?                                  * 
    303  *                                                                                             * 
    304  * WARNINGS:   none                                                                            * 
    305  *                                                                                             * 
    306  * HISTORY:                                                                                    * 
    307  *   05/22/1995 JLB : Created.                                                                 * 
    308  *=============================================================================================*/
    309 int FixedHeapClass::Free_All(void)
    310 {
    311 	ActiveCount = 0;
    312 	FreeFlag.Reset();
    313 	return(true);
    314 }	
    315 
    316 
    317 /////////////////////////////////////////////////////////////////////
    318 
    319 
    320 /*********************************************************************************************** 
    321  * FixedIHeapClass::Free_All -- Frees all objects out of the indexed heap.                     * 
    322  *                                                                                             * 
    323  *    Use this routine to free all previously allocated objects in the heap. This routine will * 
    324  *    also clear out the allocated object vector as well.                                      * 
    325  *                                                                                             * 
    326  * INPUT:   none                                                                               * 
    327  *                                                                                             * 
    328  * OUTPUT:  Was the heap successfully cleared of objects?                                      * 
    329  *                                                                                             * 
    330  * WARNINGS:   none                                                                            * 
    331  *                                                                                             * 
    332  * HISTORY:                                                                                    * 
    333  *   05/22/1995 JLB : Created.                                                                 * 
    334  *=============================================================================================*/
    335 int FixedIHeapClass::Free_All(void)
    336 {
    337 	ActivePointers.Delete_All();
    338 	return(FixedHeapClass::Free_All());
    339 }
    340 
    341 
    342 void FixedIHeapClass::Clear(void)
    343 {
    344 	FixedHeapClass::Clear();
    345 	ActivePointers.Clear();
    346 }	
    347 
    348 
    349 int FixedIHeapClass::Set_Heap(int count, void * buffer)
    350 {
    351 	Clear();
    352 	if (FixedHeapClass::Set_Heap(count, buffer)) {
    353 		ActivePointers.Resize(count);
    354 		return(true);
    355 	}
    356 	return(false);
    357 }	
    358 
    359 
    360 void * FixedIHeapClass::Allocate(void)
    361 {
    362 	void * ptr = FixedHeapClass::Allocate();
    363 	if (ptr)	{
    364 		ActivePointers.Add(ptr);
    365 		memset (ptr, 0, Size);
    366 	}
    367 	return(ptr);
    368 }	
    369 
    370 
    371 /*********************************************************************************************** 
    372  * FixedIHeapClass::Free -- Frees an object in the heap.                                       * 
    373  *                                                                                             * 
    374  *    This routine is used to free an object in the heap. Freeing is accomplished by marking   * 
    375  *    the object's memory as free to be reallocated. The object is also removed from the       * 
    376  *    allocated object pointer vector.                                                         * 
    377  *                                                                                             * 
    378  * INPUT:   pointer  -- Pointer to the object that is to be removed from the heap.             * 
    379  *                                                                                             * 
    380  * OUTPUT:  none                                                                               * 
    381  *                                                                                             * 
    382  * WARNINGS:   none                                                                            * 
    383  *                                                                                             * 
    384  * HISTORY:                                                                                    * 
    385  *   02/21/1995 JLB : Created.                                                                 * 
    386  *=============================================================================================*/
    387 int FixedIHeapClass::Free(void * pointer)
    388 {
    389 	if (FixedHeapClass::Free(pointer)) {
    390 		ActivePointers.Delete(pointer);
    391 	}
    392 	return(false);
    393 }	
    394 
    395 #if (0)
    396 /*********************************************************************************************** 
    397  * TFixedIHeapClass::Save -- Saves all active objects                                          *
    398  *                                                                                             * 
    399  * INPUT:   file      file to write to                                                         *
    400  *                                                                                             * 
    401  * OUTPUT:  true = OK, false = error                                                           *
    402  *                                                                                             * 
    403  * WARNINGS:   none                                                                            * 
    404  *                                                                                             * 
    405  * HISTORY:                                                                                    * 
    406  *   03/15/1995 BRR : Created.                                                                 *
    407  *=============================================================================================*/
    408 template<class T>
    409 int TFixedIHeapClass<T>::Save(FileClass &file)
    410 {
    411 	int i;				// loop counter
    412 	int idx;				// object index
    413 
    414 	/*
    415 	** Save the number of instances of this class
    416 	*/
    417 	if (file.Write(&ActiveCount, sizeof(ActiveCount)) != sizeof(ActiveCount)) {
    418 		return(false);
    419 	}
    420 
    421 	/*
    422 	** Save each instance of this class
    423 	*/
    424 	for (i = 0; i < ActiveCount; i++) {
    425 		/*
    426 		** Save the array index of the object, so it can be loaded back into the
    427 		** same array location (so TARGET translations will work)
    428 		*/
    429 		idx = ID(Ptr(i));
    430 		if (file.Write(&idx, sizeof(idx)) != sizeof(idx)) {
    431 			return(false);
    432 		}
    433 
    434 		/*
    435 		** Save the object itself
    436 		*/
    437 		if (!Ptr(i)->Save(file)) {
    438 			return(false);
    439 		}
    440 	}
    441 
    442 	return(true);
    443 }	
    444 
    445 
    446 /*********************************************************************************************** 
    447  * TFixedIHeapClass::Load -- Loads all active objects                                          *
    448  *                                                                                             * 
    449  * INPUT:   file      file to read from                                                        *
    450  *                                                                                             * 
    451  * OUTPUT:  true = OK, false = error                                                           *
    452  *                                                                                             * 
    453  * WARNINGS:   none                                                                            * 
    454  *                                                                                             * 
    455  * HISTORY:                                                                                    * 
    456  *   03/15/1995 BRR : Created.                                                                 *
    457  *=============================================================================================*/
    458 template<class T>
    459 int TFixedIHeapClass<T>::Load(FileClass &file)
    460 {
    461 	int i;			// loop counter
    462 	int idx;			// object index
    463 	T *ptr;			// object pointer
    464 	int a_count;
    465 
    466 	/*
    467 	** Read the number of instances of this class
    468 	*/
    469 	if (file.Read(&a_count, sizeof(a_count)) != sizeof(a_count)) {
    470 		return(false);
    471 	}
    472 
    473 	/*
    474 	** Error if more objects than we can hold
    475 	*/
    476 	if (a_count > TotalCount) {
    477 		return(false);
    478 	}
    479 
    480 	/*
    481 	** Read each class instance
    482 	*/
    483 	for (i = 0; i < a_count; i++) {
    484 		/*
    485 		** Read the object's array index
    486 		*/
    487 		if (file.Read (&idx, sizeof(idx)) != sizeof(idx)) {
    488 			return(false);
    489 		}
    490 
    491 		/*
    492 		** Get a pointer to the object, activate that object
    493 		*/
    494 		ptr = (T *)(*this)[idx];
    495 		FreeFlag[idx] = true;
    496 		ActiveCount++;
    497 		ActivePointers.Add(ptr);
    498 
    499 		/*
    500 		** Load the object
    501 		*/
    502 		if (!ptr->Load(file)) {
    503 			return(false);
    504 		}
    505 	}
    506 
    507 	return(true);
    508 }	
    509 
    510 
    511 /*********************************************************************************************** 
    512  * TFixedIHeapClass::Code_Pointers -- codes pointers for every object, to prepare for save     *
    513  *                                                                                             * 
    514  * INPUT:   file      file to read from                                                        *
    515  *                                                                                             * 
    516  * OUTPUT:  true = OK, false = error                                                           *
    517  *                                                                                             * 
    518  * WARNINGS:   none                                                                            * 
    519  *                                                                                             * 
    520  * HISTORY:                                                                                    * 
    521  *   03/15/1995 BRR : Created.                                                                 *
    522  *=============================================================================================*/
    523 template<class T>
    524 void TFixedIHeapClass<T>::Code_Pointers(void)
    525 {
    526 	int i;
    527 
    528 	for (i = 0; i < ActiveCount; i++) {
    529 		Ptr(i)->Code_Pointers();
    530 	}
    531 }
    532 
    533 
    534 /*********************************************************************************************** 
    535  * TFixedIHeapClass::Decode_Pointers -- Decodes all object pointers, for after loading         *
    536  *                                                                                             * 
    537  * INPUT:   file      file to read from                                                        *
    538  *                                                                                             * 
    539  * OUTPUT:  true = OK, false = error                                                           *
    540  *                                                                                             * 
    541  * WARNINGS:   none                                                                            * 
    542  *                                                                                             * 
    543  * HISTORY:                                                                                    * 
    544  *   03/15/1995 BRR : Created.                                                                 *
    545  *=============================================================================================*/
    546 template<class T>
    547 void TFixedIHeapClass<T>::Decode_Pointers(void)
    548 {
    549 	int i;
    550 
    551 	for (i = 0; i < ActiveCount; i++) {
    552 		Ptr(i)->Decode_Pointers();
    553 	}
    554 }
    555 
    556 #endif