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