INTERPAL.CPP 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  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. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /***********************************************************************************************
  15. *** 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 ***
  16. ***********************************************************************************************
  17. * *
  18. * Project Name : Command & Conquer *
  19. * *
  20. * File Name : INTERPAL.CPP *
  21. * *
  22. * Programmer : Steve Tall *
  23. * *
  24. * Start Date : December 7th 1995 *
  25. * *
  26. *---------------------------------------------------------------------------------------------*
  27. * Overview: *
  28. * This module contains functions to allow use of old 320x200 animations on a 640x400 screen *
  29. * *
  30. * Functions: *
  31. * Read_Interpolation_Palette -- reads an interpolation palette table from disk *
  32. * Write_Interpolation_Palette -- writes an interpolation palette to disk *
  33. * Create_Palette_Interpolation_Table -- build the palette interpolation table *
  34. * Increase_Palette_Luminance -- increase the contrast of a palette *
  35. * Interpolate_2X_Scale -- Stretch a 320x200 graphic buffer into 640x400 *
  36. * *
  37. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  38. #include "function.h"
  39. BOOL InterpolationPaletteChanged = FALSE;
  40. extern "C" {
  41. extern void __cdecl Asm_Interpolate (unsigned char* src_ptr ,
  42. unsigned char* dest_ptr ,
  43. int lines ,
  44. int src_width ,
  45. int dest_width);
  46. extern void __cdecl Asm_Interpolate_Line_Double (unsigned char* src_ptr ,
  47. unsigned char* dest_ptr ,
  48. int lines ,
  49. int src_width ,
  50. int dest_width);
  51. extern void __cdecl Asm_Interpolate_Line_Interpolate (unsigned char* src_ptr ,
  52. unsigned char* dest_ptr ,
  53. int lines ,
  54. int src_width ,
  55. int dest_width);
  56. }
  57. extern "C"{
  58. unsigned char PaletteInterpolationTable[SIZE_OF_PALETTE][SIZE_OF_PALETTE];
  59. unsigned char *InterpolationPalette;
  60. }
  61. /***********************************************************************************************
  62. * Read_Interpolatioin_Palette -- reads an interpolation palette table from disk *
  63. * *
  64. * *
  65. * *
  66. * INPUT: name of palette file *
  67. * *
  68. * OUTPUT: Nothing *
  69. * *
  70. * WARNINGS: None *
  71. * *
  72. * HISTORY: *
  73. * 12/12/95 12:15PM ST : Created *
  74. *=============================================================================================*/
  75. void Read_Interpolation_Palette (char const *palette_file_name)
  76. {
  77. CCFileClass palette_file(palette_file_name);
  78. if (palette_file.Is_Available()){
  79. palette_file.Open(READ);
  80. palette_file.Read(&PaletteInterpolationTable[0][0],256*256);
  81. palette_file.Close();
  82. InterpolationPaletteChanged = FALSE;
  83. }
  84. }
  85. /***********************************************************************************************
  86. * Write_Interpolatioin_Palette -- writes an interpolation palette table to disk *
  87. * *
  88. * *
  89. * *
  90. * INPUT: name of palette file *
  91. * *
  92. * OUTPUT: Nothing *
  93. * *
  94. * WARNINGS: None *
  95. * *
  96. * HISTORY: *
  97. * 12/12/95 12:15PM ST : Created *
  98. *=============================================================================================*/
  99. void Write_Interpolation_Palette (char const *palette_file_name)
  100. {
  101. CCFileClass palette_file(palette_file_name);
  102. if (!palette_file.Is_Available()){
  103. palette_file.Open(WRITE);
  104. palette_file.Write(&PaletteInterpolationTable[0][0],256*256);
  105. palette_file.Close();
  106. }
  107. }
  108. /***************************************************************************
  109. * CREATE_PALETTE_INTERPOLATION_TABLE *
  110. * *
  111. * INPUT: *
  112. * *
  113. * OUTPUT: *
  114. * *
  115. * WARNINGS: *
  116. * *
  117. * HISTORY: *
  118. * 12/06/1995 MG : Created. *
  119. *=========================================================================*/
  120. void Create_Palette_Interpolation_Table( void )
  121. {
  122. //Don't think we need this. ST - 12/20/2018 2:25PM
  123. //Asm_Create_Palette_Interpolation_Table();
  124. #if (0)
  125. int i;
  126. int j;
  127. int p;
  128. unsigned char *first_palette_ptr;
  129. unsigned char *second_palette_ptr;
  130. unsigned char *match_pal_ptr;
  131. int first_r;
  132. int first_g;
  133. int first_b;
  134. int second_r;
  135. int second_g;
  136. int second_b;
  137. int diff_r;
  138. int diff_g;
  139. int diff_b;
  140. int dest_r;
  141. int dest_g;
  142. int dest_b;
  143. int distance;
  144. int closest_distance;
  145. int index_of_closest_color;
  146. //
  147. // Create an interpolation table for the current palette.
  148. //
  149. first_palette_ptr = (unsigned char *) InterpolationPalette;
  150. for ( i = 0; i < SIZE_OF_PALETTE; i ++ ) {
  151. //
  152. // Get the first palette entry's RGB.
  153. //
  154. first_r = *first_palette_ptr;
  155. first_palette_ptr ++;
  156. first_g = *first_palette_ptr;
  157. first_palette_ptr ++;
  158. first_b = *first_palette_ptr;
  159. first_palette_ptr ++;
  160. second_palette_ptr = (unsigned char *) InterpolationPalette;
  161. for ( j = 0; j < SIZE_OF_PALETTE; j ++ ) {
  162. //
  163. // Get the second palette entry's RGB.
  164. //
  165. second_r = *second_palette_ptr;
  166. second_palette_ptr ++;
  167. second_g = *second_palette_ptr;
  168. second_palette_ptr ++;
  169. second_b = *second_palette_ptr;
  170. second_palette_ptr ++;
  171. //
  172. // Now calculate the RGB halfway between the first and second colors.
  173. //
  174. dest_r = ( first_r + second_r ) >> 1;
  175. dest_g = ( first_g + second_g ) >> 1;
  176. dest_b = ( first_b + second_b ) >> 1;
  177. //
  178. // Now find the color in the palette that most closely matches the interpolated color.
  179. //
  180. index_of_closest_color = 0;
  181. // closest_distance = (256 * 256) * 3;
  182. closest_distance = 500000;
  183. match_pal_ptr = (unsigned char *) InterpolationPalette;
  184. for ( p = 0; p < SIZE_OF_PALETTE; p ++ ) {
  185. diff_r = ( ((int) (*match_pal_ptr)) - dest_r );
  186. match_pal_ptr ++;
  187. diff_g = ( ((int) (*match_pal_ptr)) - dest_g );
  188. match_pal_ptr ++;
  189. diff_b = ( ((int) (*match_pal_ptr)) - dest_b );
  190. match_pal_ptr ++;
  191. distance = ( diff_r * diff_r ) + ( diff_g * diff_g ) + ( diff_b * diff_b );
  192. if ( distance < closest_distance ) {
  193. closest_distance = distance;
  194. index_of_closest_color = p;
  195. }
  196. }
  197. PaletteInterpolationTable[ i ][ j ] = (unsigned char) index_of_closest_color;
  198. }
  199. }
  200. #endif
  201. InterpolationPaletteChanged = FALSE;
  202. return;
  203. }
  204. /***********************************************************************************************
  205. * Increase_Palette_Luminance -- increase contrast of colours in a palette *
  206. * *
  207. * *
  208. * *
  209. * INPUT: ptr to palette *
  210. * percentage increase of red *
  211. * percentage increase of green *
  212. * percentage increase of blue *
  213. * cap value for colours *
  214. * *
  215. * *
  216. * OUTPUT: Nothing *
  217. * *
  218. * WARNINGS: None *
  219. * *
  220. * HISTORY: *
  221. * 12/12/95 12:16PM ST : Created *
  222. *=============================================================================================*/
  223. void Increase_Palette_Luminance (unsigned char *palette , int red_percentage , int green_percentage , int blue_percentage ,int cap)
  224. {
  225. unsigned int red;
  226. unsigned int green;
  227. unsigned int blue;
  228. for (int i=0 ; i<SIZE_OF_PALETTE*3 ; i+=3){
  229. red = (unsigned)*(palette+i);
  230. green = (unsigned)*(palette+i+1);
  231. blue = (unsigned)*(palette+i+2);
  232. red += red*red_percentage/100;
  233. green += green*green_percentage/100;
  234. blue += blue*blue_percentage/100;
  235. red = MIN (cap,(int)red);
  236. green = MIN (cap,(int)green);
  237. blue = MIN (cap,(int)blue);
  238. *(palette+i) =(unsigned char)red;
  239. *(palette+i+1) =(unsigned char)green;
  240. *(palette+i+2) =(unsigned char)blue;
  241. }
  242. }
  243. int CopyType =0;
  244. #if( 1 )
  245. /***************************************************************************
  246. * INTERPOLATE_2X_SCALE *
  247. * *
  248. * INPUT: *
  249. * *
  250. * OUTPUT: *
  251. * *
  252. * WARNINGS: *
  253. * *
  254. * HISTORY: *
  255. * 12/06/1995 MG : Created. *
  256. *=========================================================================*/
  257. void Interpolate_2X_Scale( GraphicBufferClass *source, GraphicViewPortClass *dest ,char const *palette_file_name)
  258. {
  259. //Don't think we need this. ST - 12/20/2018 2:25PM
  260. #if (0)
  261. unsigned char *src_ptr;
  262. unsigned char *dest_ptr;
  263. unsigned char *last_dest_ptr;
  264. unsigned char *end_of_source;
  265. int src_width;
  266. int dest_width;
  267. // int width_counter;
  268. BOOL source_locked = FALSE;
  269. BOOL dest_locked = FALSE;
  270. /*
  271. **If a palette table exists on disk then read it in otherwise create it
  272. */
  273. if (InterpolationPaletteChanged){
  274. if (palette_file_name){
  275. Read_Interpolation_Palette(palette_file_name);
  276. }
  277. if (InterpolationPaletteChanged){
  278. Create_Palette_Interpolation_Table();
  279. }
  280. }
  281. /*
  282. ** Write the palette table to disk so we dont have to create it again next time
  283. */
  284. if (palette_file_name){
  285. Write_Interpolation_Palette(palette_file_name);
  286. }
  287. if ( dest == &SeenBuff ) Hide_Mouse();
  288. Wait_Blit();
  289. /*
  290. ** Lock video surfaces if requred
  291. */
  292. if (source->Get_IsDirectDraw()){
  293. if (!source->Lock()){
  294. if (dest == &SeenBuff) Show_Mouse();
  295. return;
  296. }
  297. source_locked = TRUE;
  298. }
  299. if (dest->Get_IsDirectDraw()){
  300. if (!dest->Lock()) {
  301. if (source_locked){
  302. source->Unlock();
  303. }
  304. if (dest == &SeenBuff) Show_Mouse();
  305. return;
  306. }
  307. dest_locked = TRUE;
  308. }
  309. //
  310. // Get pointers to the source and destination buffers.
  311. //
  312. src_ptr = (unsigned char *) source->Get_Offset();
  313. dest_ptr = (unsigned char *) dest->Get_Offset();
  314. end_of_source = src_ptr + ( source->Get_Width() * source->Get_Height() );
  315. //
  316. // Get width of source and dest buffers.
  317. //
  318. src_width = source->Get_Width();
  319. dest_width = 2*(dest->Get_Width() + dest->Get_XAdd() + dest->Get_Pitch());
  320. last_dest_ptr = dest_ptr;
  321. /*
  322. ** Call the appropriate assembly language copy routine
  323. */
  324. #if (1)
  325. switch (CopyType){
  326. case 0:
  327. Asm_Interpolate ( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width);
  328. break;
  329. case 1:
  330. Asm_Interpolate_Line_Double( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width);
  331. break;
  332. case 2:
  333. Asm_Interpolate_Line_Interpolate( src_ptr , dest_ptr , source->Get_Height() , src_width , dest_width);
  334. break;
  335. }
  336. #endif
  337. #if (0)
  338. //
  339. // Copy over the first pixel (upper left).
  340. //
  341. *dest_ptr = *src_ptr;
  342. src_ptr ++;
  343. dest_ptr ++;
  344. //
  345. // Scale copy.
  346. //
  347. width_counter = 0;
  348. while ( src_ptr < end_of_source ) {
  349. //
  350. // Blend this pixel with the one to the left and place this new color in the dest buffer.
  351. //
  352. *dest_ptr = PaletteInterpolationTable[ (*src_ptr) ][ (*( src_ptr - 1 )) ];
  353. dest_ptr ++;
  354. //
  355. // Now place the source pixel into the dest buffer.
  356. //
  357. *dest_ptr = *src_ptr;
  358. src_ptr ++;
  359. dest_ptr ++;
  360. width_counter ++;
  361. if ( width_counter == src_width ) {
  362. width_counter = 0;
  363. last_dest_ptr += dest_width;
  364. dest_ptr = last_dest_ptr;
  365. }
  366. }
  367. #endif
  368. if (source_locked) source->Unlock();
  369. if (dest_locked) dest->Unlock();
  370. if (dest == &SeenBuff) Show_Mouse();
  371. #endif
  372. }
  373. #endif