ft2_palette.c (11229B)
1 #include <stdint.h> 2 #include <stdbool.h> 3 #include <math.h> 4 #include "ft2_palette.h" 5 #include "ft2_gui.h" 6 #include "ft2_config.h" 7 #include "ft2_video.h" 8 #include "ft2_palette.h" 9 #include "ft2_tables.h" 10 11 uint8_t cfg_ColorNum = 0; // globalized 12 13 static uint8_t cfg_Red, cfg_Green, cfg_Blue, cfg_Contrast; 14 15 static const uint8_t FTC_EditOrder[6] = { PAL_PATTEXT, PAL_BLCKMRK, PAL_BLCKTXT, PAL_MOUSEPT, PAL_DESKTOP, PAL_BUTTONS }; 16 static const uint8_t scaleOrder[3] = { 8, 4, 9 }; 17 18 static uint8_t palContrast[12][2] = // palette desktop/button contrasts 19 { 20 {59, 55}, {59, 53}, {56, 59}, {68, 55}, {57, 59}, {48, 55}, 21 {66, 62}, {68, 57}, {58, 42}, {57, 55}, {62, 57}, {52, 57} 22 }; 23 24 void setCustomPalColor(uint32_t color) 25 { 26 video.palette[PAL_CUSTOM] = (PAL_CUSTOM << 24) | color; 27 } 28 29 void setPal16(pal16 *p, bool redrawScreen) 30 { 31 #define LOOP_PIN_COL_SUB 96 32 #define TEXT_MARK_COLOR 0x0078D7 33 #define BOX_SELECT_COLOR 0x7F7F7F 34 35 int16_t r, g, b; 36 37 // set main palette w/ 18-bit -> 24-bit conversion 38 for (int32_t i = 0; i < 16; i++) 39 { 40 r = P6_TO_P8(p[i].r); // 0..63 -> 0..255 41 g = P6_TO_P8(p[i].g); 42 b = P6_TO_P8(p[i].b); 43 44 video.palette[i] = (i << 24) | RGB32(r, g, b); 45 } 46 47 // set custom FT2 clone palette entries 48 49 video.palette[PAL_TEXTMRK] = (PAL_TEXTMRK << 24) | TEXT_MARK_COLOR; 50 video.palette[PAL_BOXSLCT] = (PAL_BOXSLCT << 24) | BOX_SELECT_COLOR; 51 52 r = RGB32_R(video.palette[PAL_PATTEXT]); 53 g = RGB32_G(video.palette[PAL_PATTEXT]); 54 b = RGB32_B(video.palette[PAL_PATTEXT]); 55 56 r = MAX(r - LOOP_PIN_COL_SUB, 0); 57 g = MAX(g - LOOP_PIN_COL_SUB, 0); 58 b = MAX(b - LOOP_PIN_COL_SUB, 0); 59 60 video.palette[PAL_LOOPPIN] = (PAL_LOOPPIN << 24) | RGB32(r, g, b); 61 62 // update framebuffer pixels with new palette 63 if (redrawScreen && video.frameBuffer != NULL) 64 { 65 for (int32_t i = 0; i < SCREEN_W*SCREEN_H; i++) 66 video.frameBuffer[i] = video.palette[(video.frameBuffer[i] >> 24) & 15]; // ARGB alpha channel = palette index 67 } 68 } 69 70 static void showColorErrorMsg(void) 71 { 72 okBox(0, "System message", "Default colors cannot be modified.", NULL); 73 } 74 75 static void showMouseColorErrorMsg(void) 76 { 77 okBox(0, "System message", "Mouse color can only be changed when \"Software mouse\" is enabled.", NULL); 78 } 79 80 static double palPow(double dX, double dY) 81 { 82 if (dY == 1.0) 83 return dX; 84 85 dY *= log(fabs(dX)); 86 dY = CLAMP(dY, -86.0, 86.0); 87 88 return exp(dY); 89 } 90 91 uint8_t palMax(int32_t c) 92 { 93 return (uint8_t)CLAMP(c, 0, 63); 94 } 95 96 static void drawCurrentPaletteColor(void) 97 { 98 const uint8_t palIndex = FTC_EditOrder[cfg_ColorNum]; 99 100 const uint8_t r = P6_TO_P8(cfg_Red); 101 const uint8_t g = P6_TO_P8(cfg_Green); 102 const uint8_t b = P6_TO_P8(cfg_Blue); 103 104 textOutShadow(516, 3, PAL_FORGRND, PAL_DSKTOP2, "Palette:"); 105 hexOutBg(573, 3, PAL_FORGRND, PAL_DESKTOP, RGB32(r, g, b) & 0xFFFFFF, 6); 106 clearRect(616, 2, 12, 10); 107 fillRect(617, 3, 10, 8, palIndex); 108 } 109 110 static void updatePaletteEditor(void) 111 { 112 const uint8_t colorNum = FTC_EditOrder[cfg_ColorNum]; 113 114 cfg_Red = palTable[config.cfg_StdPalNum][colorNum].r; 115 cfg_Green = palTable[config.cfg_StdPalNum][colorNum].g; 116 cfg_Blue = palTable[config.cfg_StdPalNum][colorNum].b; 117 118 if (cfg_ColorNum == 4 || cfg_ColorNum == 5) 119 cfg_Contrast = palContrast[config.cfg_StdPalNum][cfg_ColorNum-4]; 120 else 121 cfg_Contrast = 0; 122 123 setScrollBarPos(SB_PAL_R, cfg_Red, false); 124 setScrollBarPos(SB_PAL_G, cfg_Green, false); 125 setScrollBarPos(SB_PAL_B, cfg_Blue, false); 126 setScrollBarPos(SB_PAL_CONTRAST, cfg_Contrast, false); 127 128 drawCurrentPaletteColor(); 129 } 130 131 static void paletteDragMoved(void) 132 { 133 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 134 { 135 updatePaletteEditor(); // resets colors/contrast vars 136 showColorErrorMsg(); 137 return; 138 } 139 140 if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 141 { 142 updatePaletteEditor(); // resets colors/contrast vars 143 showMouseColorErrorMsg(); 144 return; 145 } 146 147 const uint8_t colorNum = FTC_EditOrder[cfg_ColorNum]; 148 const uint8_t p = (uint8_t)config.cfg_StdPalNum; 149 150 palTable[p][colorNum].r = cfg_Red; 151 palTable[p][colorNum].g = cfg_Green; 152 palTable[p][colorNum].b = cfg_Blue; 153 154 if (cfg_ColorNum == 4 || cfg_ColorNum == 5) 155 { 156 double dRed = cfg_Red; 157 double dGreen = cfg_Green; 158 double dBlue = cfg_Blue; 159 160 int32_t contrast = cfg_Contrast; 161 if (contrast < 1) 162 contrast = 1; 163 164 const double dContrast = contrast * (1.0 / 40.0); 165 166 for (int32_t i = 0; i < 3; i++) 167 { 168 const int32_t k = scaleOrder[i] + (cfg_ColorNum - 4) * 2; 169 170 double dMul = palPow((i + 1) * (1.0 / 2.0), dContrast); 171 172 palTable[p][k].r = palMax((int32_t)((dRed * dMul) + 0.5)); 173 palTable[p][k].g = palMax((int32_t)((dGreen * dMul) + 0.5)); 174 palTable[p][k].b = palMax((int32_t)((dBlue * dMul) + 0.5)); 175 } 176 177 palContrast[p][cfg_ColorNum-4] = cfg_Contrast; 178 } 179 else 180 { 181 cfg_Contrast = 0; 182 183 setScrollBarPos(SB_PAL_R, cfg_Red, false); 184 setScrollBarPos(SB_PAL_G, cfg_Green, false); 185 setScrollBarPos(SB_PAL_B, cfg_Blue, false); 186 } 187 188 setScrollBarPos(SB_PAL_CONTRAST, cfg_Contrast, false); 189 190 setPal16(palTable[config.cfg_StdPalNum], true); 191 drawCurrentPaletteColor(); 192 } 193 194 void sbPalRPos(uint32_t pos) 195 { 196 if (cfg_Red != (uint8_t)pos) 197 { 198 cfg_Red = (uint8_t)pos; 199 paletteDragMoved(); 200 } 201 } 202 203 void sbPalGPos(uint32_t pos) 204 { 205 if (cfg_Green != (uint8_t)pos) 206 { 207 cfg_Green = (uint8_t)pos; 208 paletteDragMoved(); 209 } 210 } 211 212 void sbPalBPos(uint32_t pos) 213 { 214 if (cfg_Blue != (uint8_t)pos) 215 { 216 cfg_Blue = (uint8_t)pos; 217 paletteDragMoved(); 218 } 219 } 220 221 void sbPalContrastPos(uint32_t pos) 222 { 223 if (cfg_Contrast != (uint8_t)pos) 224 { 225 cfg_Contrast = (uint8_t)pos; 226 paletteDragMoved(); 227 } 228 } 229 230 void configPalRDown(void) 231 { 232 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 233 showColorErrorMsg(); 234 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 235 showMouseColorErrorMsg(); 236 else 237 scrollBarScrollLeft(SB_PAL_R, 1); 238 } 239 240 void configPalRUp(void) 241 { 242 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 243 showColorErrorMsg(); 244 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 245 showMouseColorErrorMsg(); 246 else 247 scrollBarScrollRight(SB_PAL_R, 1); 248 } 249 250 void configPalGDown(void) 251 { 252 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 253 showColorErrorMsg(); 254 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 255 showMouseColorErrorMsg(); 256 else 257 scrollBarScrollLeft(SB_PAL_G, 1); 258 } 259 260 void configPalGUp(void) 261 { 262 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 263 showColorErrorMsg(); 264 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 265 showMouseColorErrorMsg(); 266 else 267 scrollBarScrollRight(SB_PAL_G, 1); 268 } 269 270 void configPalBDown(void) 271 { 272 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 273 showColorErrorMsg(); 274 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 275 showMouseColorErrorMsg(); 276 else 277 scrollBarScrollLeft(SB_PAL_B, 1); 278 } 279 280 void configPalBUp(void) 281 { 282 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 283 showColorErrorMsg(); 284 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 285 showMouseColorErrorMsg(); 286 else 287 scrollBarScrollRight(SB_PAL_B, 1); 288 } 289 290 void configPalContDown(void) 291 { 292 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 293 showColorErrorMsg(); 294 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 295 showMouseColorErrorMsg(); 296 else 297 scrollBarScrollLeft(SB_PAL_CONTRAST, 1); 298 } 299 300 void configPalContUp(void) 301 { 302 if (config.cfg_StdPalNum != PAL_USER_DEFINED) 303 showColorErrorMsg(); 304 else if ((config.specialFlags2 & HARDWARE_MOUSE) && cfg_ColorNum == 3) 305 showMouseColorErrorMsg(); 306 else 307 scrollBarScrollRight(SB_PAL_CONTRAST, 1); 308 } 309 310 void showPaletteEditor(void) 311 { 312 charOutShadow(503, 17, PAL_FORGRND, PAL_DSKTOP2, 'R'); 313 charOutShadow(503, 31, PAL_FORGRND, PAL_DSKTOP2, 'G'); 314 charOutShadow(503, 45, PAL_FORGRND, PAL_DSKTOP2, 'B'); 315 316 showScrollBar(SB_PAL_R); 317 showScrollBar(SB_PAL_G); 318 showScrollBar(SB_PAL_B); 319 showPushButton(PB_CONFIG_PAL_R_DOWN); 320 showPushButton(PB_CONFIG_PAL_R_UP); 321 showPushButton(PB_CONFIG_PAL_G_DOWN); 322 showPushButton(PB_CONFIG_PAL_G_UP); 323 showPushButton(PB_CONFIG_PAL_B_DOWN); 324 showPushButton(PB_CONFIG_PAL_B_UP); 325 326 showRadioButtonGroup(RB_GROUP_CONFIG_PAL_ENTRIES); 327 328 textOutShadow(516, 59, PAL_FORGRND, PAL_DSKTOP2, "Contrast:"); 329 showScrollBar(SB_PAL_CONTRAST); 330 showPushButton(PB_CONFIG_PAL_CONT_DOWN); 331 showPushButton(PB_CONFIG_PAL_CONT_UP); 332 333 updatePaletteEditor(); 334 } 335 336 void rbConfigPalPatternText(void) 337 { 338 cfg_ColorNum = 0; 339 checkRadioButton(RB_CONFIG_PAL_PATTERNTEXT); 340 updatePaletteEditor(); 341 } 342 343 void rbConfigPalBlockMark(void) 344 { 345 cfg_ColorNum = 1; 346 checkRadioButton(RB_CONFIG_PAL_BLOCKMARK); 347 updatePaletteEditor(); 348 } 349 350 void rbConfigPalTextOnBlock(void) 351 { 352 cfg_ColorNum = 2; 353 checkRadioButton(RB_CONFIG_PAL_TEXTONBLOCK); 354 updatePaletteEditor(); 355 } 356 357 void rbConfigPalMouse(void) 358 { 359 cfg_ColorNum = 3; 360 checkRadioButton(RB_CONFIG_PAL_MOUSE); 361 updatePaletteEditor(); 362 } 363 364 void rbConfigPalDesktop(void) 365 { 366 cfg_ColorNum = 4; 367 checkRadioButton(RB_CONFIG_PAL_DESKTOP); 368 updatePaletteEditor(); 369 } 370 371 void rbConfigPalButttons(void) 372 { 373 cfg_ColorNum = 5; 374 checkRadioButton(RB_CONFIG_PAL_BUTTONS); 375 updatePaletteEditor(); 376 } 377 378 void rbConfigPalArctic(void) 379 { 380 config.cfg_StdPalNum = PAL_ARCTIC; 381 updatePaletteEditor(); 382 setPal16(palTable[config.cfg_StdPalNum], true); 383 checkRadioButton(RB_CONFIG_PAL_ARCTIC); 384 } 385 386 void rbConfigPalLitheDark(void) 387 { 388 config.cfg_StdPalNum = PAL_LITHE_DARK; 389 updatePaletteEditor(); 390 setPal16(palTable[config.cfg_StdPalNum], true); 391 checkRadioButton(RB_CONFIG_PAL_LITHE_DARK); 392 } 393 394 void rbConfigPalAuroraBorealis(void) 395 { 396 config.cfg_StdPalNum = PAL_AURORA_BOREALIS; 397 updatePaletteEditor(); 398 setPal16(palTable[config.cfg_StdPalNum], true); 399 checkRadioButton(RB_CONFIG_PAL_AURORA_BOREALIS); 400 } 401 402 void rbConfigPalRose(void) 403 { 404 config.cfg_StdPalNum = PAL_ROSE; 405 updatePaletteEditor(); 406 setPal16(palTable[config.cfg_StdPalNum], true); 407 checkRadioButton(RB_CONFIG_PAL_ROSE); 408 } 409 410 void rbConfigPalBlues(void) 411 { 412 config.cfg_StdPalNum = PAL_BLUES; 413 updatePaletteEditor(); 414 setPal16(palTable[config.cfg_StdPalNum], true); 415 checkRadioButton(RB_CONFIG_PAL_BLUES); 416 } 417 418 void rbConfigPalDarkMode(void) 419 { 420 config.cfg_StdPalNum = PAL_DARK_MODE; 421 updatePaletteEditor(); 422 setPal16(palTable[config.cfg_StdPalNum], true); 423 checkRadioButton(RB_CONFIG_PAL_DARK_MODE); 424 } 425 426 void rbConfigPalGold(void) 427 { 428 config.cfg_StdPalNum = PAL_GOLD; 429 updatePaletteEditor(); 430 setPal16(palTable[config.cfg_StdPalNum], true); 431 checkRadioButton(RB_CONFIG_PAL_GOLD); 432 } 433 434 void rbConfigPalViolent(void) 435 { 436 config.cfg_StdPalNum = PAL_VIOLENT; 437 updatePaletteEditor(); 438 setPal16(palTable[config.cfg_StdPalNum], true); 439 checkRadioButton(RB_CONFIG_PAL_VIOLENT); 440 } 441 442 void rbConfigPalHeavyMetal(void) 443 { 444 config.cfg_StdPalNum = PAL_HEAVY_METAL; 445 updatePaletteEditor(); 446 setPal16(palTable[config.cfg_StdPalNum], true); 447 checkRadioButton(RB_CONFIG_PAL_HEAVY_METAL); 448 } 449 450 void rbConfigPalWhyColors(void) 451 { 452 config.cfg_StdPalNum = PAL_WHY_COLORS; 453 updatePaletteEditor(); 454 setPal16(palTable[config.cfg_StdPalNum], true); 455 checkRadioButton(RB_CONFIG_PAL_WHY_COLORS); 456 } 457 458 void rbConfigPalJungle(void) 459 { 460 config.cfg_StdPalNum = PAL_JUNGLE; 461 updatePaletteEditor(); 462 setPal16(palTable[config.cfg_StdPalNum], true); 463 checkRadioButton(RB_CONFIG_PAL_JUNGLE); 464 } 465 466 void rbConfigPalUserDefined(void) 467 { 468 config.cfg_StdPalNum = PAL_USER_DEFINED; 469 updatePaletteEditor(); 470 setPal16(palTable[config.cfg_StdPalNum], true); 471 checkRadioButton(RB_CONFIG_PAL_USER_DEFINED); 472 }