INTERPAL.CPP 16 KB

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