2593 | | warning("unkRoomFunc3(%d,%d,%d,%d,%d): not fully implemented", unk1, unk2, rfact, gfact, bfact); |
2594 | | |
2595 | | // TODO - correctly implement this function (see also patch #588501) |
2596 | | // |
2597 | | // Some "typical" examples of how this function is being invoked in real life: |
2598 | | // |
2599 | | // 1) |
2600 | | // unkRoomFunc3(16, 255, 200, 200, 200) |
2601 | | // |
2602 | | // FOA: Sets up the colors for the boat and submarine shadows in the |
2603 | | // diving scene. Are the shadows too light? Maybe unk1 is used to |
2604 | | // darken the colors? |
2605 | | // |
2606 | | // 2) |
2607 | | // unkRoomFunc3(0, 255, 700, 700, 700) |
2608 | | // |
2609 | | // FOA: Sets up the colors for the subway car headlight when it first |
2610 | | // goes on. This seems to work ok. |
2611 | | // |
2612 | | // 3) |
2613 | | // unkRoomFunc3(160, 191, 300, 300, 300) |
2614 | | // unkRoomFunc3(160, 191, 289, 289, 289) |
2615 | | // ... |
2616 | | // unkRoomFunc3(160, 191, 14, 14, 14) |
2617 | | // unkRoomFunc3(160, 191, 3, 3, 3) |
2618 | | // |
2619 | | // 4) |
2620 | | // FOA: Sets up the colors for the subway car headlight for the later |
2621 | | // half of the trip, where it fades out. This currently doesn't work |
2622 | | // at all. The colors are too dark to be brightened. At first I thought |
2623 | | // unk1 and unk2 were used to tell which color interval to manipulate, |
2624 | | // but as far as I can tell the colors 160-191 aren't used at all to |
2625 | | // draw the light, that can't be it. Apparently unk1 and/or unk2 are |
2626 | | // used to brighten the colors. |
2627 | | // |
2628 | | // 5) |
2629 | | // unkRoomFunc3(16,255,500,500,500) |
| 2595 | // This is a correction of the patch supplied for BUG #588501. |
| 2596 | // It has been tested in four rooms where unkRoomFunc3 is used. |
2631 | | // FOA: Used in the Inner Sanctum after you activated the machine using the |
2632 | | // stone discs (briefly before the Nazis arrive). No idea at all if it is |
2633 | | // right here; also note that palManipulateInit() is called at the same time. |
2634 | | // |
2635 | | // |
2636 | | |
| 2598 | // 1) FOA Room 53: subway departing Knossos for Atlantis. |
| 2599 | // 2) FOA Room 48: subway crashing into the Atlantis entance area |
| 2600 | // 3) FOA Room 82: boat/sub shadows while diving near Thera |
| 2601 | // 4) FOA Room 23: the big machine room inside Atlantis |
| 2602 | // |
| 2603 | // The implementation behaves well in all tests. |
| 2604 | // Pixel comparisons show that the resulting palette entries being |
| 2605 | // derived from the shadow palette generated here occassionally differ |
| 2606 | // slightly from the ones derived in the LEC executable. |
| 2607 | // Not sure yet why, but the differences are VERY minor. |
| 2608 | // |
| 2609 | // Once again, there seems to be no explanation for why this function |
| 2610 | // is called from within Room 23 (the big machine), as it has no shadow |
| 2611 | // effects and thus doesn't result in any visual differences. |
| 2612 | |
2642 | | *table++ = remapPaletteColor(r, g, b, (uint) -1); |
| 2618 | // The following functionality is similar to remapPaletteColor, except |
| 2619 | // 1) we have to work off the original CLUT rather than the current palette, and |
| 2620 | // 2) the target shadow palette entries must be bounded to the upper and lower |
| 2621 | // bounds provided by the opcode. (This becomes significant in Room 48, but |
| 2622 | // is not an issue in all other known case studies.) |
| 2623 | int j; |
| 2624 | int ar, ag, ab; |
| 2625 | uint sum, diff, bestsum, bestitem = 0; |
| 2626 | compareptr = basepal + palstart * 3; |
| 2627 | |
| 2628 | if (r > 255) |
| 2629 | r = 255; |
| 2630 | if (g > 255) |
| 2631 | g = 255; |
| 2632 | if (b > 255) |
| 2633 | b = 255; |
| 2634 | |
| 2635 | bestsum = (uint) - 1; |
| 2636 | |
| 2637 | r &= ~3; |
| 2638 | g &= ~3; |
| 2639 | b &= ~3; |
| 2640 | |
| 2641 | for (j = palstart; j <= palend; j++, compareptr += 3) { |
| 2642 | ar = compareptr[0] & ~3; |
| 2643 | ag = compareptr[1] & ~3; |
| 2644 | ab = compareptr[2] & ~3; |
| 2645 | if (ar == r && ag == g && ab == b) { |
| 2646 | bestitem = j; |
| 2647 | break; |
| 2648 | } |
| 2649 | |
| 2650 | diff = ar - r; |
| 2651 | sum = diff * diff * 3; |
| 2652 | diff = ag - g; |
| 2653 | sum += diff * diff * 6; |
| 2654 | diff = ab - b; |
| 2655 | sum += diff * diff * 2; |
| 2656 | |
| 2657 | if (sum < bestsum) { |
| 2658 | bestsum = sum; |
| 2659 | bestitem = j; |
| 2660 | } |
| 2661 | } |
| 2662 | *table++ = bestitem; |