Ticket #8174: cmi-room-saturation.diff

File cmi-room-saturation.diff, 5.5 KB (added by eriktorbjorn, 17 years ago)

Patch against a February 12 CVS snapshot

  • scummvm/scumm/gfx.cpp

    diff -ur ScummVM-cvs20030212/scummvm/scumm/gfx.cpp ScummVM-cvs20030212+hack/scummvm/scumm/gfx.cpp
    old new  
    1919 *
    2020 */
    2121
     22#include <math.h>
     23
    2224#include "stdafx.h"
    2325#include "scumm.h"
    2426#include "actor.h"
     
    28802882        }
    28812883}
    28822884
     2885void Scumm::desaturatePalette(int hueScale, int satScale, int valScale, int startColor, int endColor)
     2886{
     2887        // This is used by CMI when Guybrush walks from the fort towards the
     2888        // swamp. He should gradually fade to gray as he walks into the mist.
     2889
     2890        // FIXME: The result doesn't look quite like the original. There are
     2891        // several possible explanations for this. Maybe CMI isn't scaling
     2892        // the HSV components of the colour after all, or maybe it uses a
     2893        // simplified version of the algorithm.
     2894
     2895        // FIXME: Simplify, and eliminate the floating-point arithmetics?
     2896
     2897        if (startColor <= endColor) {
     2898                byte *cptr, *cur;
     2899                double R, G, B;
     2900                double H, S, V;
     2901                double Rp, Gp, Bp;
     2902                double min, max;
     2903                int j;
     2904
     2905                cptr = getPalettePtr() + startColor * 3;
     2906                cur = _currentPalette + startColor * 3;
     2907
     2908                for (j = startColor; j <= endColor; j++) {
     2909                        R = ((double) *cptr++) / 255.0;
     2910                        G = ((double) *cptr++) / 255.0;
     2911                        B = ((double) *cptr++) / 255.0;
     2912
     2913                        // Convert RGB to HSV
     2914
     2915                        min = MIN(R, MIN(G, B));
     2916                        max = MAX(R, MAX(G, B));
     2917
     2918                        S = (max - min) / max;
     2919                        V = max;
     2920
     2921                        Rp = (max - R) / (max - min);
     2922                        Gp = (max - G) / (max - min);
     2923                        Bp = (max - B) / (max - min);
     2924
     2925                        // The original algorithm says I should test if S is
     2926                        // non-zero, but I don't dare to test for that kind of
     2927                        // equality with floating-point numbers.
     2928
     2929                        if (fabs(S) > 0.00001) {
     2930                                if (R == max && G == min) {
     2931                                        H = 5 + Bp;
     2932                                } else if (R == max && G != min) {
     2933                                        H = 1 - Gp;
     2934                                } else if (G == max && B == min) {
     2935                                        H = Rp + 1;
     2936                                } else if (G == max && B != min) {
     2937                                        H = 3 - Bp;
     2938                                } else if (R == max) {
     2939                                        H = 3 + Gp;
     2940                                } else {
     2941                                        H = 5 - Rp;
     2942                                }
     2943                        } else
     2944                                H = 0.0; // undefined
     2945
     2946                        H *= 60.0;
     2947
     2948                        // Scale HSV
     2949
     2950                        H = (H * hueScale) / 255.0;
     2951                        S = (S * satScale) / 255.0;
     2952                        V = (V * valScale) / 255.0;
     2953
     2954                        // Convert HSV to RGB.
     2955
     2956                        double Hex, primary_color, secondary_color;
     2957                        double a, b, c;
     2958
     2959                        Hex = H / 60.0;
     2960                        primary_color = floor(Hex);
     2961                        secondary_color = Hex - primary_color;
     2962
     2963                        a = (1.0 - S) * V;
     2964                        b = (1.0 - (S * secondary_color)) * V;
     2965                        c = (1.0 - (S * (1.0 - secondary_color))) * V;
     2966
     2967                        switch ((int) Hex) {
     2968                                case 0:
     2969                                case 6:
     2970                                        R = V;
     2971                                        G = c;
     2972                                        B = a;
     2973                                        break;
     2974                                case 1:
     2975                                        R = b;
     2976                                        G = V;
     2977                                        B = a;
     2978                                        break;
     2979                                case 2:
     2980                                        R = a;
     2981                                        G = V;
     2982                                        B = c;
     2983                                        break;
     2984                                case 3:
     2985                                        R = a;
     2986                                        G = b;
     2987                                        B = V;
     2988                                        break;
     2989                                case 4:
     2990                                        R = c;
     2991                                        G = a;
     2992                                        B = V;
     2993                                        break;
     2994                                case 5:
     2995                                        R = V;
     2996                                        G = a;
     2997                                        B = b;
     2998                                        break;
     2999                        }
     3000
     3001                        int red, green, blue;
     3002
     3003                        red = (int) (255.0 * R + 0.5);
     3004                        green = (int) (255.0 * G + 0.5);
     3005                        blue = (int) (255.0 * B + 0.5);
     3006
     3007                        if (red > 255)
     3008                                red = 255;
     3009                        if (green > 255)
     3010                                green = 255;
     3011                        if (blue > 255)
     3012                                blue = 255;
     3013
     3014                        *cur++ = red;
     3015                        *cur++ = green;
     3016                        *cur++ = blue;
     3017                }
     3018                setDirtyColors(startColor, endColor);
     3019        }
     3020}
     3021
    28833022int Scumm::remapPaletteColor(int r, int g, int b, uint threshold)
    28843023{
    28853024        int i;
  • scummvm/scumm/script_v8.cpp

    diff -ur ScummVM-cvs20030212/scummvm/scumm/script_v8.cpp ScummVM-cvs20030212+hack/scummvm/scumm/script_v8.cpp
    old new  
    10181018                c = pop();
    10191019                b = pop();
    10201020                a = pop();
    1021                 // FIXME - this probably has the same format as for darkenPalette:
    1022                 // thre values for R, G, B and a start/end palette range to modify.
    1023                 // Now, how on earth does on modify the saturation of a single color channel?
    1024                 // Change the hue/saturation of a color, no problem, I know how to do that,
    1025                 // but for only a channel alone, I don't even know what that should mean... :-/
     1021                // FIXME - this almost certainly uses the same format as for
     1022                // darkenPalette: three scaling values and a start/end palette
     1023                // range to modify.
     1024                //
     1025                // For now, I have assumed that we should scale H, S and V,
     1026                // but the result doesn't look quite right to me so either my
     1027                // theory isn't quite right, or my implementation isn't, or
     1028                // the original used a simplified version of the algorithm.
    10261029//              warning("o8_roomOps: SO_ROOM_SATURATION(%d, %d, %d, %d, %d)", a, b, c, d, e);
     1030                desaturatePalette(a, b, c, d, e);
    10271031                break;
    10281032        default:
    10291033                error("o8_roomOps: default case 0x%x", subOp);
  • scummvm/scumm/scumm.h

    diff -ur ScummVM-cvs20030212/scummvm/scumm/scumm.h ScummVM-cvs20030212+hack/scummvm/scumm/scumm.h
    old new  
    770770        void setupShadowPalette(int slot, int redScale, int greenScale, int blueScale, int startColor, int endColor);
    771771        void setupShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
    772772        void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
     773        void desaturatePalette(int hueScale, int satScale, int valScale, int startColor, int endColor);
    773774
    774775        void setCursor(int cursor);
    775776        void setCursorImg(uint img, uint room, uint imgindex);