KEYFRAME.CPP 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*
  2. ** Command & Conquer Red Alert(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. /* $Header: /CounterStrike/KEYFRAME.CPP 1 3/03/97 10:25a Joe_bostic $ */
  19. /***********************************************************************************************
  20. *** 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 ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : KEYFRAME.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * Programmer : David Dettmer *
  29. * *
  30. * Start Date : 06/25/95 *
  31. * *
  32. * Last Update : June 25, 1995 [JLB] *
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * Get_Build_Frame_Count -- Fetches the number of frames in data block. *
  37. * Get_Build_Frame_Width -- Fetches the width of the shape image. *
  38. * Get_Build_Frame_Height -- Fetches the height of the shape image. *
  39. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  40. #include "function.h"
  41. #define SUBFRAMEOFFS 7 // 3 1/2 frame offsets loaded (2 offsets/frame)
  42. #define Apply_Delta(buffer, delta) Apply_XOR_Delta((char*)(buffer), (char*)(delta))
  43. typedef struct {
  44. unsigned short frames;
  45. unsigned short x;
  46. unsigned short y;
  47. unsigned short width;
  48. unsigned short height;
  49. unsigned short largest_frame_size;
  50. short flags;
  51. } KeyFrameHeaderType;
  52. #ifdef WIN32
  53. #define INITIAL_BIG_SHAPE_BUFFER_SIZE 20000000
  54. #define UNCOMPRESS_MAGIC_NUMBER 56789
  55. unsigned BigShapeBufferLength = INITIAL_BIG_SHAPE_BUFFER_SIZE;
  56. extern "C"{
  57. char * BigShapeBufferStart = NULL;
  58. BOOL UseBigShapeBuffer = FALSE;
  59. }
  60. char * BigShapeBufferPtr = NULL;
  61. int TotalBigShapes=0;
  62. BOOL ReallocShapeBufferFlag = FALSE;
  63. char ** KeyFrameSlots [1000];
  64. int TotalSlotsUsed=0;
  65. typedef struct tShapeHeaderType{
  66. unsigned draw_flags;
  67. char * shape_data;
  68. } ShapeHeaderType;
  69. static int Length;
  70. void * Get_Shape_Header_Data(void * ptr)
  71. {
  72. if (UseBigShapeBuffer) {
  73. return((void *)(((ShapeHeaderType *)ptr)->shape_data+(long)BigShapeBufferStart));
  74. } else {
  75. return (ptr);
  76. }
  77. }
  78. int Get_Last_Frame_Length(void)
  79. {
  80. return(Length);
  81. }
  82. void Reallocate_Big_Shape_Buffer(void)
  83. {
  84. if (ReallocShapeBufferFlag) {
  85. BigShapeBufferLength += 2000000; //Extra 2 Mb of uncompressed shape space
  86. BigShapeBufferPtr -= (unsigned)BigShapeBufferStart;
  87. BigShapeBufferStart = (char*)Resize_Alloc(BigShapeBufferStart, BigShapeBufferLength);
  88. BigShapeBufferPtr += (unsigned)BigShapeBufferStart;
  89. ReallocShapeBufferFlag = FALSE;
  90. }
  91. }
  92. void Check_Use_Compressed_Shapes (void)
  93. {
  94. MEMORYSTATUS mem_info;
  95. mem_info.dwLength=sizeof(mem_info);
  96. GlobalMemoryStatus(&mem_info);
  97. UseBigShapeBuffer = (mem_info.dwTotalPhys > 12*1024*1024) ? TRUE : FALSE;
  98. }
  99. #endif
  100. unsigned long Build_Frame(void const * dataptr, unsigned short framenumber, void * buffptr)
  101. {
  102. #ifdef FIXIT_SCORE_CRASH
  103. char * ptr;
  104. unsigned long offcurr, offdiff;
  105. #else
  106. char * ptr, * lockptr;
  107. unsigned long offcurr, off16, offdiff;
  108. #endif
  109. unsigned long offset[SUBFRAMEOFFS];
  110. KeyFrameHeaderType * keyfr;
  111. unsigned short buffsize, currframe, subframe;
  112. unsigned long length = 0;
  113. char frameflags;
  114. //
  115. // valid pointer??
  116. //
  117. if ( !dataptr || !buffptr ) {
  118. return(0);
  119. }
  120. //
  121. // look at header then check that frame to build is not greater
  122. // than total frames
  123. //
  124. keyfr = (KeyFrameHeaderType *) dataptr;
  125. if ( framenumber >= keyfr->frames ) {
  126. return(0);
  127. }
  128. // calc buff size
  129. buffsize = keyfr->width * keyfr->height;
  130. // get offset into data
  131. ptr = (char *)dataptr + (((unsigned long)framenumber << 3) + sizeof(KeyFrameHeaderType));
  132. Mem_Copy( ptr, &offset[0], 12L );
  133. frameflags = (char)(offset[0] >> 24);
  134. if ( (frameflags & KF_KEYFRAME) ) {
  135. ptr = (char *)Add_Long_To_Pointer( dataptr, (offset[0] & 0x00FFFFFFL) );
  136. if (keyfr->flags & 1 ) {
  137. ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
  138. }
  139. length = LCW_Uncompress( ptr, buffptr, buffsize );
  140. } else { // key delta or delta
  141. if ( (frameflags & KF_DELTA) ) {
  142. currframe = (unsigned short)offset[1];
  143. ptr = (char *)Add_Long_To_Pointer( dataptr, (((unsigned long)currframe << 3) + sizeof(KeyFrameHeaderType)) );
  144. Mem_Copy( ptr, &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
  145. }
  146. // key frame
  147. offcurr = offset[1] & 0x00FFFFFFL;
  148. // key delta
  149. offdiff = (offset[0] & 0x00FFFFFFL) - offcurr;
  150. ptr = (char *)Add_Long_To_Pointer( dataptr, offcurr );
  151. if (keyfr->flags & 1 ) {
  152. ptr = (char *)Add_Long_To_Pointer( ptr, 768L );
  153. }
  154. #ifndef FIXIT_SCORE_CRASH
  155. off16 = (unsigned long)lockptr & 0x00003FFFL;
  156. #endif
  157. length = LCW_Uncompress( ptr, buffptr, buffsize );
  158. if (length > buffsize) {
  159. return(0);
  160. }
  161. #ifndef FIXIT_SCORE_CRASH
  162. if ( ((offset[2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
  163. ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
  164. off16 = (unsigned long)ptr & 0x00003FFFL;
  165. offcurr += offdiff;
  166. offdiff = 0;
  167. }
  168. #endif
  169. #ifdef NEVER
  170. // check for LCW'd rsd
  171. if ( ((offset[1] >> 24) & KF_LCW) ) {
  172. length = LCW_Uncompress( ptr, buffptr, buffsize );
  173. } else {
  174. length = buffsize;
  175. Apply_XOR_Delta( buffptr, Add_Long_To_Pointer( ptr, offdiff ) );
  176. }
  177. #else
  178. length = buffsize;
  179. Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
  180. #endif
  181. if ( (frameflags & KF_DELTA) ) {
  182. // adjust to delta after the keydelta
  183. currframe++;
  184. subframe = 2;
  185. while (currframe <= framenumber) {
  186. offdiff = (offset[subframe] & 0x00FFFFFFL) - offcurr;
  187. #ifndef FIXIT_SCORE_CRASH
  188. if ( ((offset[subframe+2] & 0x00FFFFFFL) - offcurr) >= (0x00010000L - off16) ) {
  189. ptr = (char *)Add_Long_To_Pointer( ptr, offdiff );
  190. off16 = (unsigned long)lockptr & 0x00003FFFL;
  191. offcurr += offdiff;
  192. offdiff = 0;
  193. }
  194. #endif
  195. #ifdef NEVER
  196. // check for LCW'd rsd
  197. if ( ((offset[1] >> 24) & KF_LCW) ) {
  198. length = LCW_Uncompress( ptr, buffptr, buffsize );
  199. } else {
  200. length = buffsize;
  201. Apply_XOR_Delta( buffptr, Add_Long_To_Pointer( ptr, offdiff ) );
  202. }
  203. #else
  204. length = buffsize;
  205. Apply_Delta(buffptr, Add_Long_To_Pointer(ptr, offdiff));
  206. #endif
  207. currframe++;
  208. subframe += 2;
  209. if ( subframe >= (SUBFRAMEOFFS - 1) &&
  210. currframe <= framenumber ) {
  211. Mem_Copy( Add_Long_To_Pointer( dataptr,
  212. (((unsigned long)currframe << 3) +
  213. sizeof(KeyFrameHeaderType)) ),
  214. &offset[0], (long)(SUBFRAMEOFFS * sizeof(unsigned long)) );
  215. subframe = 0;
  216. }
  217. }
  218. }
  219. }
  220. return(length);
  221. }
  222. /***********************************************************************************************
  223. * Get_Build_Frame_Count -- Fetches the number of frames in data block. *
  224. * *
  225. * Use this routine to determine the number of shapes within the data block. *
  226. * *
  227. * INPUT: dataptr -- Pointer to the keyframe shape data block. *
  228. * *
  229. * OUTPUT: Returns with the number of shapes in the data block. *
  230. * *
  231. * WARNINGS: none *
  232. * *
  233. * HISTORY: *
  234. * 06/25/1995 JLB : Commented. *
  235. *=============================================================================================*/
  236. unsigned short Get_Build_Frame_Count(void const * dataptr)
  237. {
  238. if (dataptr) {
  239. return(((KeyFrameHeaderType const *)dataptr)->frames);
  240. }
  241. return(0);
  242. }
  243. unsigned short Get_Build_Frame_X(void const * dataptr)
  244. {
  245. if (dataptr) {
  246. return(((KeyFrameHeaderType const *)dataptr)->x);
  247. }
  248. return(0);
  249. }
  250. unsigned short Get_Build_Frame_Y(void const * dataptr)
  251. {
  252. if (dataptr) {
  253. return(((KeyFrameHeaderType const *)dataptr)->y);
  254. }
  255. return(0);
  256. }
  257. /***********************************************************************************************
  258. * Get_Build_Frame_Width -- Fetches the width of the shape image. *
  259. * *
  260. * Use this routine to fetch the width of the shapes within the keyframe shape data block. *
  261. * All shapes within the block have the same width. *
  262. * *
  263. * INPUT: dataptr -- Pointer to the keyframe shape data block. *
  264. * *
  265. * OUTPUT: Returns with the width of the shapes in the block -- expressed in pixels. *
  266. * *
  267. * WARNINGS: none *
  268. * *
  269. * HISTORY: *
  270. * 06/25/1995 JLB : Commented *
  271. *=============================================================================================*/
  272. unsigned short Get_Build_Frame_Width(void const * dataptr)
  273. {
  274. if (dataptr) {
  275. return(((KeyFrameHeaderType const *)dataptr)->width);
  276. }
  277. return(0);
  278. }
  279. /***********************************************************************************************
  280. * Get_Build_Frame_Height -- Fetches the height of the shape image. *
  281. * *
  282. * Use this routine to fetch the height of the shapes within the keyframe shape data block. *
  283. * All shapes within the block have the same height. *
  284. * *
  285. * INPUT: dataptr -- Pointer to the keyframe shape data block. *
  286. * *
  287. * OUTPUT: Returns with the height of the shapes in the block -- expressed in pixels. *
  288. * *
  289. * WARNINGS: none *
  290. * *
  291. * HISTORY: *
  292. * 06/25/1995 JLB : Commented *
  293. *=============================================================================================*/
  294. unsigned short Get_Build_Frame_Height(void const * dataptr)
  295. {
  296. if (dataptr) {
  297. return(((KeyFrameHeaderType const *)dataptr)->height);
  298. }
  299. return(0);
  300. }
  301. bool Get_Build_Frame_Palette(void const * dataptr, void * palette)
  302. {
  303. if (dataptr && (((KeyFrameHeaderType const *)dataptr)->flags & 1)) {
  304. char const * ptr = (char const *)Add_Long_To_Pointer( dataptr,
  305. ( (( (long)sizeof(unsigned long) << 1) *
  306. ((KeyFrameHeaderType *) dataptr)->frames ) +
  307. 16 + sizeof(KeyFrameHeaderType) ) );
  308. memcpy(palette, ptr, 768L);
  309. return(true);
  310. }
  311. return(false);
  312. }