PALETTE.CPP (15277B)
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 A S S O C I A T E S ** 18 *************************************************************************** 19 * * 20 * Project Name : WWLIB * 21 * * 22 * File Name : PALETTE.C * 23 * * 24 * Programmer : BILL STOKES * 25 * * 26 * Start Date : 6/20/91 * 27 * * 28 * Last Update : August 2, 1994 [SKB] * 29 * * 30 *-------------------------------------------------------------------------* 31 * Note: This module contains dependencies upon the video system, * 32 * specifically Get_Video_Mode(). * 33 *-------------------------------------------------------------------------* 34 * Functions: * 35 * Set_Palette -- sets the current palette * 36 * Set_Palette_Color -- Set a color number in a palette to the data. * 37 * Fade_Palette_To -- Fades the current palette into another * 38 * Determine_Bump_Rate -- determines desired bump rate for fading * 39 * Bump_Palette -- increments the palette one step, for fading * 40 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 41 /* 42 ********************************* Includes ********************************** 43 */ 44 //#include <mem.h> 45 46 #include "palette.h" 47 #include "timer.h" 48 #include "wwstd.h" 49 50 51 /* 52 ********************************* Constants ********************************* 53 */ 54 55 /* 56 ********************************** Globals ********************************** 57 */ 58 extern "C" extern unsigned char CurrentPalette[]; /* in pal.asm */ 59 60 /* 61 ******************************** Prototypes ********************************* 62 */ 63 64 PRIVATE void __cdecl Determine_Bump_Rate(void *palette, int delay, short *ticks, short *rate); 65 PRIVATE BOOL __cdecl Bump_Palette(void *palette1, unsigned int step); 66 67 /* 68 ******************************** Code ********************************* 69 */ 70 71 /*************************************************************************** 72 * Set_Palette -- sets the current palette * 73 * * 74 * INPUT: * 75 * void *palette - palette to set * 76 * * 77 * OUTPUT: * 78 * none * 79 * * 80 * WARNINGS: * 81 * * 82 * HISTORY: * 83 * 04/25/1994 SKB : Created. * 84 * 04/27/1994 BR : Converted to 32-bit * 85 *=========================================================================*/ 86 void __cdecl Set_Palette(void *palette) 87 { 88 89 #if(IBM) 90 Set_Palette_Range(palette); 91 #else 92 Copy_Palette(palette,CurrentPalette); 93 LoadRGB4(&Main_Screen->ViewPort,palette,32L); 94 LoadRGB4(AltVPort,palette,32L); 95 #endif 96 97 } /* end of Set_Palette */ 98 99 100 /*************************************************************************** 101 * Set_Palette_Color -- Set a color number in a palette to the data. * 102 * * 103 * * 104 * INPUT: * 105 * void *palette - palette to set color in * 106 * int color - which color index to set * 107 * void *data - RGB data for color * 108 * * 109 * OUTPUT: * 110 * none * 111 * * 112 * WARNINGS: * 113 * * 114 * HISTORY: * 115 * 04/25/1994 SKB : Created. * 116 * 04/27/1994 BR : Converted to 32-bit * 117 *=========================================================================*/ 118 void __cdecl Set_Palette_Color(void *palette, int color, void *data) 119 { 120 /* 121 ---------------------- Return if 'palette' is NULL ----------------------- 122 */ 123 if (!palette) return; 124 125 /* 126 ------------------- Change the color & set the palette ------------------- 127 */ 128 #if(IBM) 129 memcpy(&((unsigned char *)palette)[color * RGB_BYTES], data, RGB_BYTES); 130 Set_Palette_Range(palette); 131 #else 132 palette[color] = *(unsigned short*)data; 133 Set_Palette(palette); 134 #endif 135 136 } /* end of Set_Palette */ 137 138 139 /*************************************************************************** 140 * Fade_Palette_To -- Fades the current palette into another * 141 * * 142 * This will allow the palette to fade from current palette into the * 143 * palette that was passed in. This can be used to fade in and fade out. * 144 * * 145 * INPUT: * 146 * char *palette1 - this is the palette to fade to. * 147 * unsigned int delay - fade with this timer count down * 148 * void *callback - user-defined callback function * 149 * * 150 * OUTPUT: none * 151 * * 152 * WARNINGS: none * 153 * * 154 * HISTORY: * 155 * 06/20/1991 BS : Created. * 156 *=========================================================================*/ 157 void Fade_Palette_To(void *palette1, unsigned int delay, void (*callback)() ) 158 { 159 BOOL changed; // Flag that palette has changed this tick. 160 short jump; // Gun values to jump per palette set. 161 unsigned long timer; // Tick count timer used for timing. 162 short ticksper; // The ticks (fixed point) per bit jump. 163 int tickaccum; 164 165 166 extern void (*cb_ptr)(void); // callback function pointer 167 168 // (void *)cb_ptr = callback; 169 cb_ptr = callback; 170 171 /* 172 ---------------------- Return if 'palette1' is NULL ---------------------- 173 */ 174 if (!palette1) 175 return; 176 177 /* 178 --------------------------- Get the bump rate ---------------------------- 179 */ 180 Determine_Bump_Rate(palette1, delay, &ticksper, &jump); 181 182 tickaccum = 0; // init accumulated elapsed time 183 timer = TickCount.Time(); // timer = current time 184 do { 185 changed = FALSE; 186 187 tickaccum += ticksper; // tickaccum = time of next change * 256 188 timer += (tickaccum >> 8); // timer = time of next change (rounded) 189 tickaccum &= 0x0FF; // shave off high byte, keep roundoff bits 190 191 changed = Bump_Palette(palette1, jump); // increment palette 192 193 /* 194 .................. Wait for time increment to elapse .................. 195 */ 196 if (changed) { 197 while (TickCount.Time() < (int)timer) { 198 /* 199 ................. Update callback while waiting ................. 200 */ 201 if (callback) { 202 #if LIB_EXTERNS_RESOLVED 203 Sound_Callback(); // should be removed! 204 #endif 205 (*cb_ptr)(); 206 } 207 } 208 } 209 210 #if LIB_EXTERNS_RESOLVED 211 Sound_Callback(); // should be removed! 212 #endif 213 if (callback) { 214 (*cb_ptr)(); 215 } 216 } while (changed); 217 218 } /* end of Fade_Palette_To */ 219 220 221 /*************************************************************************** 222 * Determine_Bump_Rate -- determines desired bump rate for fading * 223 * * 224 * INPUT: * 225 * unsigned char *palette - palette to fade to * 226 * int delay - desired time delay in 60ths of a second * 227 * short *ticks - output: loop ticks per color jump * 228 * short *rate - output: color gun increment rate * 229 * * 230 * OUTPUT: * 231 * none * 232 * * 233 * WARNINGS: * 234 * * 235 * HISTORY: * 236 * 04/27/1994 BR : Converted to 32-bit * 237 * 08/02/1994 SKB : Made private * 238 *=========================================================================*/ 239 PRIVATE void __cdecl Determine_Bump_Rate(void *palette, int delay, short *ticks, 240 short *rate) 241 { 242 int gun1; // Palette 1 gun value. 243 int gun2; // Palette 2 gun value. 244 int diff; // Maximum color gun difference. 245 int tp; // Temporary tick accumulator. 246 int index; // Color gun working index. 247 long t; // Working tick intermediate value. 248 int adiff; // Absolute difference between guns. 249 250 /* 251 ------------------------ Find max gun difference ------------------------- 252 */ 253 diff = 0; 254 for (index = 0; index < PALETTE_BYTES; index++) { 255 gun1 = ((unsigned char *)palette)[index]; 256 gun2 = CurrentPalette[index]; 257 adiff = ABS(gun1-gun2); 258 diff = MAX(diff, adiff); 259 } 260 261 /*------------------------------------------------------------------------ 262 ticks = (total time delay ) / (max gun diff) 263 The value is computed based on (delay * 256), for fixed-point math; 264 the lower bits represent the leftover from the division; 'ticks' is 265 returned still shifted, so the low bits can be used to accumulate the 266 time more accurately; the caller must shift the accumulated value down 267 8 bits to determine the actual elapsed time! 268 ------------------------------------------------------------------------*/ 269 t = ((long)delay) << 8; 270 if (diff) { 271 t /= diff; 272 t = MIN((long)t, (long)0x7FFF); 273 } 274 *ticks = (short)t; 275 276 /*------------------------------------------------------------------------ 277 Adjust the color gun rate value if the time to fade is faster than can 278 reasonably be performed given the palette change, ie if (ticks>>8)==0, 279 and thus less than 1/60 of a second 280 ------------------------------------------------------------------------*/ 281 tp = *ticks; 282 *rate = 1; 283 while (*rate <= diff && *ticks < 256) { 284 *ticks += tp; 285 *rate += 1; 286 } 287 288 } /* end of Determine_Bump_Rate */ 289 290 291 /*************************************************************************** 292 * Bump_Palette -- increments the palette one step, for fading * 293 * * 294 * INPUT: * 295 * palette1 - palette to fade towards * 296 * step - max step amount, determined by Determine_Bump_Rate * 297 * * 298 * OUTPUT: * 299 * FALSE = no change, TRUE = changed * 300 * * 301 * WARNINGS: * 302 * * 303 * HISTORY: * 304 * 04/27/1994 BR : Created. * 305 * 08/02/1994 SKB : Made private * 306 *=========================================================================*/ 307 #if(IBM) 308 PRIVATE BOOL __cdecl Bump_Palette(void *palette1, unsigned int step) 309 { 310 BOOL changed=FALSE; // Flag that palette has changed this tick. 311 int index; // Index to DAC register gun. 312 int gun1,gun2; // Palette 1 gun value. 313 unsigned char palette[PALETTE_BYTES]; // copy of current palette 314 315 /* 316 ---------------------- Return if 'palette1' is NULL ---------------------- 317 */ 318 if (!palette1) 319 return (FALSE); 320 321 322 /* 323 ------------------------ Copy the current palette ------------------------ 324 */ 325 memcpy(palette, CurrentPalette, 768); 326 327 /* 328 ----------------------- Loop through palette bytes ----------------------- 329 */ 330 for (index = 0; index < PALETTE_BYTES; index++) { 331 gun1 = ((unsigned char *)palette1)[index]; 332 gun2 = palette[index]; 333 334 /* 335 ............. If the colors match, go on to the next one .............. 336 */ 337 if (gun1 == gun2) continue; 338 339 changed = TRUE; 340 341 /* 342 .................. Increment current palette's color .................. 343 */ 344 if (gun2 < gun1) { 345 gun2 += step; 346 gun2 = MIN(gun2, gun1); // make sure we didn't overshoot it 347 } 348 /* 349 .................. Decrement current palette's color .................. 350 */ 351 else { 352 gun2 -= step; 353 gun2 = MAX(gun2, gun1); // make sure we didn't overshoot it 354 } 355 356 palette[index] = (unsigned char)gun2; 357 } 358 359 /* 360 ----------------- Set current palette to the new palette ----------------- 361 */ 362 if (changed) { 363 Set_Palette(&palette[0]); 364 } 365 366 return (changed); 367 368 } /* end of Bump_Palette */ 369 370 #else 371 372 /* This is already implemented in asm on the Amiga */ 373 374 #endif 375 376 void (*cb_ptr)(void); // callback function pointer 377 378 /**************************** End of palette.cpp ***************************/ 379 380 381