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