ChunkFileImage.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 : ChunkView *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/ChunkView/ChunkFileImage.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 9/28/99 9:48a $*
  29. * *
  30. * $Revision:: 2 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "stdafx.h"
  36. #include <assert.h>
  37. #include "ChunkFileImage.h"
  38. #include "rawfile.h"
  39. #include "chunkio.h"
  40. ChunkFileImageClass::ChunkFileImageClass(void) :
  41. RootNode(NULL)
  42. {
  43. }
  44. ChunkFileImageClass::~ChunkFileImageClass(void)
  45. {
  46. Reset();
  47. }
  48. void ChunkFileImageClass::Reset(void)
  49. {
  50. // have to handle the fact that there isn't one root node,
  51. ChunkImageClass * node_to_delete = RootNode;
  52. while (node_to_delete) {
  53. ChunkImageClass * sibling = node_to_delete->Sibling;
  54. delete node_to_delete;
  55. node_to_delete = sibling;
  56. }
  57. }
  58. void ChunkFileImageClass::Load(const char * filename)
  59. {
  60. RawFileClass file(filename);
  61. file.Open();
  62. ChunkLoadClass cload(&file);
  63. cload.Open_Chunk();
  64. RootNode = new ChunkImageClass;
  65. RootNode->Load(cload);
  66. cload.Close_Chunk();
  67. // while we have more top-level chunks, load them and link them
  68. // to the root through its sibling pointer
  69. while (cload.Open_Chunk()) {
  70. ChunkImageClass * root_sibling = new ChunkImageClass;
  71. root_sibling->Load(cload);
  72. RootNode->Add_Sibling(root_sibling);
  73. cload.Close_Chunk();
  74. }
  75. file.Close();
  76. }
  77. ChunkImageClass::ChunkImageClass(void) :
  78. Child(NULL),
  79. Sibling(NULL),
  80. Data(NULL),
  81. ID(0),
  82. Length(0)
  83. {
  84. }
  85. ChunkImageClass::~ChunkImageClass(void)
  86. {
  87. // Delete our children
  88. ChunkImageClass * child = Child;
  89. while (child) {
  90. ChunkImageClass * child_sibling = child->Sibling;
  91. delete child;
  92. child = child_sibling;
  93. }
  94. // Delete our data
  95. if (Data != NULL) {
  96. delete Data;
  97. }
  98. }
  99. void ChunkImageClass::Load(ChunkLoadClass & cload)
  100. {
  101. ID = cload.Cur_Chunk_ID();
  102. Length = cload.Cur_Chunk_Length();
  103. if (cload.Contains_Chunks()) {
  104. while (cload.Open_Chunk()) {
  105. ChunkImageClass * new_child = new ChunkImageClass;
  106. new_child->Load(cload);
  107. Add_Child(new_child);
  108. cload.Close_Chunk();
  109. }
  110. } else {
  111. if (Length > 0) {
  112. Data = new uint8[Length];
  113. cload.Read(Data,Length);
  114. }
  115. }
  116. }
  117. void ChunkImageClass::Add_Child(ChunkImageClass * new_child)
  118. {
  119. assert(new_child != NULL);
  120. assert(new_child->Sibling == NULL);
  121. // need to add to the tail...
  122. if (Child == NULL) {
  123. Child = new_child;
  124. } else {
  125. Child->Add_Sibling(new_child);
  126. }
  127. }
  128. void ChunkImageClass::Add_Sibling(ChunkImageClass * new_sibling)
  129. {
  130. // Need to add to the tail so we display chunks in
  131. // the same order they appear in the file, so we
  132. // search for the tail.
  133. ChunkImageClass * tail = this;
  134. while (tail->Sibling != NULL) {
  135. tail = tail->Sibling;
  136. }
  137. tail->Sibling = new_sibling;
  138. assert(new_sibling->Sibling == NULL);
  139. }
  140. int ChunkImageClass::Get_Child_Count(void) const
  141. {
  142. int count = 0;
  143. ChunkImageClass * child = Child;
  144. while (child != NULL) {
  145. count++;
  146. child = child->Sibling;
  147. }
  148. return count;
  149. }
  150. const ChunkImageClass * ChunkImageClass::Get_Child(int i) const
  151. {
  152. int count = 0;
  153. ChunkImageClass * child = Child;
  154. while (child != NULL && count < i) {
  155. count++;
  156. child = child->Sibling;
  157. }
  158. assert(count == i);
  159. return child;
  160. }
  161. int ChunkImageClass::Get_Sibling_Count(void) const
  162. {
  163. // NOTE: counts 'this' as a sibling.
  164. int count = 0;
  165. const ChunkImageClass * sibling = this;
  166. while (sibling != NULL) {
  167. count++;
  168. sibling = sibling->Sibling;
  169. }
  170. return count;
  171. }
  172. const ChunkImageClass * ChunkImageClass::Get_Sibling(int i) const
  173. {
  174. // NOTE: sibling(0) is 'this' (just makes some other code simpler...)
  175. int count = 0;
  176. const ChunkImageClass * sibling = this;
  177. while (sibling != NULL && count < i) {
  178. count++;
  179. sibling = sibling->Sibling;
  180. }
  181. assert(count == i);
  182. return sibling;
  183. }