shithub: qk1

Download patch

ref: 5d11846259f00c662e468585b66e62741c7998b8
parent: b8f0cc01c82b238b53ec46d0c6d98aa69a749230
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Fri Oct 11 23:03:16 EDT 2024

implement dynamic v_brightness, v_contrast and v_saturation; add them to the menu

--- /dev/null
+++ b/cmprocess.c
@@ -1,0 +1,33 @@
+#include "quakedef.h"
+#include "colormatrix.h"
+
+void
+cmprocess(s16int cm[4*4], void *in_, void *out_, int n)
+{
+	u32int *in, *out;
+	int i;
+
+	in = in_;
+	out = out_;
+	for(i = 0; i < n; i++, in++){
+		s32int x[4] = {
+			(*in>>0)&0xff,
+			(*in>>8)&0xff,
+			(*in>>16)&0xff,
+			0xff,
+		};
+		s32int y[4] = {
+			(x[0]*cm[4*0+0] + x[1]*cm[4*0+1] + x[2]*cm[4*0+2] + x[3]*cm[4*0+3])/CM(1),
+			(x[0]*cm[4*1+0] + x[1]*cm[4*1+1] + x[2]*cm[4*1+2] + x[3]*cm[4*1+3])/CM(1),
+			(x[0]*cm[4*2+0] + x[1]*cm[4*2+1] + x[2]*cm[4*2+2] + x[3]*cm[4*2+3])/CM(1),
+			0xff,
+		};
+		u8int z[4] = {
+			clamp(y[0], 0, 255),
+			clamp(y[1], 0, 255),
+			clamp(y[2], 0, 255),
+			0xff,
+		};
+		*out++ = z[0]<<0 | z[1]<<8 | z[2]<<16 | z[3]<<24;
+	}
+}
--- /dev/null
+++ b/cmprocess_arm64.s
@@ -1,0 +1,35 @@
+TEXT cmprocess(SB), $0
+	MOV in+8(FP), R1
+	MOV out+16(FP), R2
+	MOVW cnt+24(FP), R3
+
+	WORD $0x4c40a000 // ld1.16b {v0, v1}, [x0]
+	WORD $0x6e3d1fbd // eor.16b v29, v29, v29
+	WORD $0x4f0707fe // movi v30.4s, 0xff, lsl 0
+conv:
+	WORD $0x0ddf803f // ld1 {v31.s}[0], [x1], 4
+	WORD $0x0f0777ff // orr v31.2s, 0xff, lsl 24
+	WORD $0x2f08a7ff // uxtl.8h v31, v31
+	WORD $0x4e0807ff // dup v31.2d, v31.d[0]
+	WORD $0x0e60c3e2 // smull v2.4s, v31.4h, v0.4h
+	WORD $0x4e60c3e3 // smull2 v3.4s, v31.8h, v0.8h
+	WORD $0x0e61c3e4 // smull v4.4s, v31.4h, v1.4h
+	WORD $0x4e61c3e5 // smull2 v5.4s, v31.8h, v1.8h
+	WORD $0x4eb1b842 // addv s2, v2.4s
+	WORD $0x4eb1b863 // addv s3, v3.4s
+	WORD $0x4eb1b884 // addv s4, v4.4s
+	WORD $0x4eb1b8a5 // addv s5, v5.4s
+	WORD $0x4e832842 // trn1.4s v2, v2, v3
+	WORD $0x4e852884 // trn1.4s v4, v4, v5
+	WORD $0x4ec42842 // trn1.2d v2, v2, v4
+	WORD $0x4f340442 // sshr.4s v2, v2, 12
+	WORD $0x4ebd6442 // smax.4s v2, v2, v29
+	WORD $0x4ebe6c42 // smin.4s v2, v2, v30
+	WORD $0x0e612842 // xtn v2.4h, v2.4s
+	WORD $0x0e212842 // xtn v2.8b, v2.8h
+	WORD $0x0d9f8042 // st1.s {v2}[0], [x2], 4
+
+	SUBW $1, R3, R3
+	CBNZW R3, conv
+
+	RETURN
--- /dev/null
+++ b/colormatrix.c
@@ -1,0 +1,121 @@
+#include "quakedef.h"
+#include "colormatrix.h"
+
+cvar_t v_saturation = {"v_saturation", "1", true};
+cvar_t v_contrast = {"v_contrast", "1", true};
+cvar_t v_brightness = {"v_brightness", "1", true};
+
+s16int cm[4*4];
+static s16int cm0[4*4] = {
+	CM(1), CM(0), CM(0), CM(0),
+	CM(0), CM(1), CM(0), CM(0),
+	CM(0), CM(0), CM(1), CM(0),
+	CM(0), CM(0), CM(0), CM(1),
+};
+static bool cmident = true;
+
+static float cmf0[4*4] = {
+	1, 0, 0, 0,
+	0, 1, 0, 0,
+	0, 0, 1, 0,
+	0, 0, 0, 1,
+};
+static float cmbrightness[4*4];
+static float cmcontrast[4*4];
+static float cmsaturation[4*4];
+static float gs[3] = {0.3086, 0.6094, 0.0820};
+
+static void
+mmul(float d[4*4], float a[4*4], float b[4*4])
+{
+	int i, j;
+
+	for(i = 0; i < 4; i++){
+		for(j = 0; j < 4; j++)
+			d[4*i+j] = a[4*i+0]*b[4*0+j] + a[4*i+1]*b[4*1+j] + a[4*i+2]*b[4*2+j] + a[4*i+3]*b[4*3+j];
+	}
+}
+
+static void
+cmcvarcb(cvar_t *var)
+{
+	float r, v, *m, t[4*4], t2[4*4];
+	int i;
+
+	if(var == &v_brightness){
+		v = clamp(var->value, 0.5, 4.5);
+		m = cmbrightness;
+		m[4*0+0] = v;
+		m[4*0+1] = 0;
+		m[4*0+2] = 0;
+		m[4*0+3] = 0;
+		m[4*1+0] = 0;
+		m[4*1+1] = v;
+		m[4*1+2] = 0;
+		m[4*1+3] = 0;
+		m[4*2+0] = 0;
+		m[4*2+1] = 0;
+		m[4*2+2] = v;
+		m[4*2+3] = 0;
+	}else if(var == &v_contrast){
+		v = clamp(var->value, 0.5, 1.5);
+		m = cmcontrast;
+		r = (1.0 - v)/2.0;
+		m[4*0+0] = v;
+		m[4*0+1] = 0;
+		m[4*0+2] = 0;
+		m[4*0+3] = r;
+		m[4*1+0] = 0;
+		m[4*1+1] = v;
+		m[4*1+2] = 0;
+		m[4*1+3] = r;
+		m[4*2+0] = 0;
+		m[4*2+1] = 0;
+		m[4*2+2] = v;
+		m[4*2+3] = r;
+	}else if(var == &v_saturation){
+		v = clamp(var->value, 0, 2);
+		m = cmsaturation;
+		r = 1 - v;
+		m[4*0+0] = r*gs[0] + v;
+		m[4*0+1] = r*gs[1];
+		m[4*0+2] = r*gs[2];
+		m[4*0+3] = 0;
+		m[4*1+0] = r*gs[0];
+		m[4*1+1] = r*gs[1] + v;
+		m[4*1+2] = r*gs[2];
+		m[4*1+3] = 0;
+		m[4*2+0] = r*gs[0];
+		m[4*2+1] = r*gs[1];
+		m[4*2+2] = r*gs[2] + v;
+		m[4*2+3] = 0;
+	}else
+		return;
+	m[4*3+0] = 0;
+	m[4*3+1] = 0;
+	m[4*3+2] = 0;
+	m[4*3+3] = 1;
+	mmul(t, cmbrightness, cmcontrast);
+	mmul(t2, t, cmsaturation);
+	for(i = 0; i < 4*4; i++)
+		cm[i] = CM(t2[i]);
+	cmident = memcmp(cm, cm0, sizeof(cm)) == 0;
+}
+
+void
+cminit(void)
+{
+	memcpy(cm, cm0, sizeof(cm));
+
+	Cvar_RegisterVariable(&v_brightness);
+	v_brightness.cb = cmcvarcb;
+	memcpy(cmbrightness, cmf0, sizeof(cmf0));
+
+	Cvar_RegisterVariable(&v_contrast);
+	v_contrast.cb = cmcvarcb;
+	memcpy(cmcontrast, cmf0, sizeof(cmf0));
+
+	Cvar_RegisterVariable(&v_saturation);
+	v_saturation.cb = cmcvarcb;
+	memcpy(cmsaturation, cmf0, sizeof(cmf0));
+}
--- /dev/null
+++ b/colormatrix.h
@@ -1,0 +1,9 @@
+#define CM(v) ((v)*(1<<12))
+
+extern s16int cm[4*4];
+extern cvar_t v_saturation;
+extern cvar_t v_contrast;
+extern cvar_t v_brightness;
+
+void cmprocess(s16int cm[4*4], void *in, void *out, int n);
+void cminit(void);
--- a/common.c
+++ b/common.c
@@ -9,11 +9,8 @@
 void
 pal3torgbx(byte *in, pixel_t *out, int n, byte *pal, int palsz)
 {
-	int x, n0;
-	pixel_t *out0;
+	int x;
 
-	out0 = out;
-	n0 = n;
 	palsz *= 3;
 	if(in < (byte*)out || in > (byte*)(out+n) || in+n < (byte*)out){
 		while(n-- > 0){
@@ -30,17 +27,11 @@
 			out[n] = 0xff<<24 | pal[x+0]<<16 | pal[x+1]<<8 | pal[x+2];
 		}
 	}
-	PixTransform(out0, n0);
 }
 
 void
 paltorgbx(byte *in, pixel_t *out, int n, pixel_t *pal)
 {
-	pixel_t *out0;
-	int n0;
-
-	out0 = out;
-	n0 = n;
 	if(in < (byte*)out || in > (byte*)(out+n) || in+n < (byte*)out){
 		while(n-- > 0)
 			*out++ = pal[*in++];
@@ -48,7 +39,6 @@
 		while(n-- > 0)
 			out[n] = pal[in[n]];
 	}
-	PixTransform(out0, n0);
 }
 
 void
--- a/hsluv.c
+++ /dev/null
@@ -1,461 +1,0 @@
-/*
- * HSLuv-C: Human-friendly HSL
- * <http://github.com/hsluv/hsluv-c>
- * <http://www.hsluv.org/>
- *
- * Copyright (c) 2015 Alexei Boronine (original idea, JavaScript implementation)
- * Copyright (c) 2015 Roger Tallada (Obj-C implementation)
- * Copyright (c) 2017 Martin Mitas (C implementation, based on Obj-C implementation)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "quakedef.h"
-#include "hsluv.h"
-#ifdef __plan9__
-#define DBL_MAX 1.797693134862315708145e+308
-#define cbrt(x) pow((x), 1.0/3.0)
-#else
-#include <float.h>
-#endif
-
-typedef struct Triplet_tag Triplet;
-struct Triplet_tag {
-    double a;
-    double b;
-    double c;
-};
-
-/* for RGB */
-static const Triplet m[3] = {
-    {  3.24096994190452134377, -1.53738317757009345794, -0.49861076029300328366 },
-    { -0.96924363628087982613,  1.87596750150772066772,  0.04155505740717561247 },
-    {  0.05563007969699360846, -0.20397695888897656435,  1.05697151424287856072 }
-};
-
-/* for XYZ */
-static const Triplet m_inv[3] = {
-    {  0.41239079926595948129,  0.35758433938387796373,  0.18048078840183428751 },
-    {  0.21263900587151035754,  0.71516867876775592746,  0.07219231536073371500 },
-    {  0.01933081871559185069,  0.11919477979462598791,  0.95053215224966058086 }
-};
-
-static const double ref_u = 0.19783000664283680764;
-static const double ref_v = 0.46831999493879100370;
-
-static const double kappa = 903.29629629629629629630;
-static const double epsilon = 0.00885645167903563082;
-
-
-typedef struct Bounds_tag Bounds;
-struct Bounds_tag {
-    double a;
-    double b;
-};
-
-
-static void
-get_bounds(double l, Bounds bounds[6])
-{
-    double tl = l + 16.0;
-    double sub1 = (tl * tl * tl) / 1560896.0;
-    double sub2 = (sub1 > epsilon ? sub1 : (l / kappa));
-    int channel;
-    int t;
-
-    for(channel = 0; channel < 3; channel++) {
-        double m1 = m[channel].a;
-        double m2 = m[channel].b;
-        double m3 = m[channel].c;
-
-        for (t = 0; t < 2; t++) {
-            double top1 = (284517.0 * m1 - 94839.0 * m3) * sub2;
-            double top2 = (838422.0 * m3 + 769860.0 * m2 + 731718.0 * m1) * l * sub2 -  769860.0 * t * l;
-            double bottom = (632260.0 * m3 - 126452.0 * m2) * sub2 + 126452.0 * t;
-
-            bounds[channel * 2 + t].a = top1 / bottom;
-            bounds[channel * 2 + t].b = top2 / bottom;
-        }
-    }
-}
-
-static double
-intersect_line_line(const Bounds* line1, const Bounds* line2)
-{
-    return (line1->b - line2->b) / (line2->a - line1->a);
-}
-
-static double
-dist_from_pole_squared(double x, double y)
-{
-    return x * x + y * y;
-}
-
-static double
-ray_length_until_intersect(double theta, const Bounds* line)
-{
-    return line->b / (sin(theta) - line->a * cos(theta));
-}
-
-static double
-max_safe_chroma_for_l(double l)
-{
-    double min_len_squared = DBL_MAX;
-    Bounds bounds[6];
-    int i;
-
-    get_bounds(l, bounds);
-    for(i = 0; i < 6; i++) {
-        double m1 = bounds[i].a;
-        double b1 = bounds[i].b;
-        /* x where line intersects with perpendicular running though (0, 0) */
-        Bounds line2 = { -1.0 / m1, 0.0 };
-        double x = intersect_line_line(&bounds[i], &line2);
-        double distance = dist_from_pole_squared(x, b1 + x * m1);
-
-        if(distance < min_len_squared)
-            min_len_squared = distance;
-    }
-
-    return sqrt(min_len_squared);
-}
-
-static double
-max_chroma_for_lh(double l, double h)
-{
-    double min_len = DBL_MAX;
-    double hrad = h * 0.01745329251994329577; /* (2 * pi / 360) */
-    Bounds bounds[6];
-    int i;
-
-    get_bounds(l, bounds);
-    for(i = 0; i < 6; i++) {
-        double len = ray_length_until_intersect(hrad, &bounds[i]);
-
-        if(len >= 0  &&  len < min_len)
-            min_len = len;
-    }
-    return min_len;
-}
-
-static double
-dot_product(const Triplet* t1, const Triplet* t2)
-{
-    return (t1->a * t2->a + t1->b * t2->b + t1->c * t2->c);
-}
-
-/* Used for rgb conversions */
-static double
-from_linear(double c)
-{
-    if(c <= 0.0031308)
-        return 12.92 * c;
-    else
-        return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
-}
-
-static double
-to_linear(double c)
-{
-    if (c > 0.04045)
-        return pow((c + 0.055) / 1.055, 2.4);
-    else
-        return c / 12.92;
-}
-
-static void
-xyz2rgb(Triplet* in_out)
-{
-    double r = from_linear(dot_product(&m[0], in_out));
-    double g = from_linear(dot_product(&m[1], in_out));
-    double b = from_linear(dot_product(&m[2], in_out));
-    in_out->a = r;
-    in_out->b = g;
-    in_out->c = b;
-}
-
-static void
-rgb2xyz(Triplet* in_out)
-{
-    Triplet rgbl = { to_linear(in_out->a), to_linear(in_out->b), to_linear(in_out->c) };
-    double x = dot_product(&m_inv[0], &rgbl);
-    double y = dot_product(&m_inv[1], &rgbl);
-    double z = dot_product(&m_inv[2], &rgbl);
-    in_out->a = x;
-    in_out->b = y;
-    in_out->c = z;
-}
-
-/* http://en.wikipedia.org/wiki/CIELUV
- * In these formulas, Yn refers to the reference white point. We are using
- * illuminant D65, so Yn (see refY in Maxima file) equals 1. The formula is
- * simplified accordingly.
- */
-static double
-y2l(double y)
-{
-    if(y <= epsilon)
-        return y * kappa;
-    else
-        return 116.0 * cbrt(y) - 16.0;
-}
-
-static double
-l2y(double l)
-{
-    if(l <= 8.0) {
-        return l / kappa;
-    } else {
-        double x = (l + 16.0) / 116.0;
-        return (x * x * x);
-    }
-}
-
-static void
-xyz2luv(Triplet* in_out)
-{
-    double l = y2l(in_out->b);
-    double var_u = 4.0 * in_out->a;
-    double var_v = 9.0 * in_out->b;
-    double div = (in_out->a + (15.0 * in_out->b) + (3.0 * in_out->c));
-    if (div > 0.00000001) {
-        var_u /= div;
-        var_v /= div;
-    }
-    double u = 13.0 * l * (var_u - ref_u);
-    double v = 13.0 * l * (var_v - ref_v);
-
-    in_out->a = l;
-    if(l < 0.00000001) {
-        in_out->b = 0.0;
-        in_out->c = 0.0;
-    } else {
-        in_out->b = u;
-        in_out->c = v;
-    }
-}
-
-static void
-luv2xyz(Triplet* in_out)
-{
-    if(in_out->a <= 0.00000001) {
-        /* Black will create a divide-by-zero error. */
-        in_out->a = 0.0;
-        in_out->b = 0.0;
-        in_out->c = 0.0;
-        return;
-    }
-
-    double var_u = in_out->b / (13.0 * in_out->a) + ref_u;
-    double var_v = in_out->c / (13.0 * in_out->a) + ref_v;
-    double y = l2y(in_out->a);
-    double x = -(9.0 * y * var_u) / ((var_u - 4.0) * var_v - var_u * var_v);
-    double z = (9.0 * y - (15.0 * var_v * y) - (var_v * x)) / (3.0 * var_v);
-    in_out->a = x;
-    in_out->b = y;
-    in_out->c = z;
-}
-
-static void
-luv2lch(Triplet* in_out)
-{
-    double l = in_out->a;
-    double u = in_out->b;
-    double v = in_out->c;
-    double h;
-    double c = sqrt(u * u + v * v);
-
-    /* Grays: disambiguate hue */
-    if(c < 0.00000001) {
-        h = 0;
-    } else {
-        h = atan2(v, u) * 57.29577951308232087680;  /* (180 / pi) */
-        if(h < 0.0)
-            h += 360.0;
-    }
-
-    in_out->a = l;
-    in_out->b = c;
-    in_out->c = h;
-}
-
-static void
-lch2luv(Triplet* in_out)
-{
-    double hrad = in_out->c * 0.01745329251994329577;  /* (pi / 180.0) */
-    double u = cos(hrad) * in_out->b;
-    double v = sin(hrad) * in_out->b;
-
-    in_out->b = u;
-    in_out->c = v;
-}
-
-static void
-hsluv2lch(Triplet* in_out)
-{
-    double h = in_out->a;
-    double s = in_out->b;
-    double l = in_out->c;
-    double c;
-
-    /* White and black: disambiguate chroma */
-    if(l > 99.9999999 || l < 0.00000001)
-        c = 0.0;
-    else
-        c = max_chroma_for_lh(l, h) / 100.0 * s;
-
-    /* Grays: disambiguate hue */
-    if (s < 0.00000001)
-        h = 0.0;
-
-    in_out->a = l;
-    in_out->b = c;
-    in_out->c = h;
-}
-
-static void
-lch2hsluv(Triplet* in_out)
-{
-    double l = in_out->a;
-    double c = in_out->b;
-    double h = in_out->c;
-    double s;
-
-    /* White and black: disambiguate saturation */
-    if(l > 99.9999999 || l < 0.00000001)
-        s = 0.0;
-    else
-        s = c / max_chroma_for_lh(l, h) * 100.0;
-
-    /* Grays: disambiguate hue */
-    if (c < 0.00000001)
-        h = 0.0;
-
-    in_out->a = h;
-    in_out->b = s;
-    in_out->c = l;
-}
-
-static void
-hpluv2lch(Triplet* in_out)
-{
-    double h = in_out->a;
-    double s = in_out->b;
-    double l = in_out->c;
-    double c;
-
-    /* White and black: disambiguate chroma */
-    if(l > 99.9999999 || l < 0.00000001)
-        c = 0.0;
-    else
-        c = max_safe_chroma_for_l(l) / 100.0 * s;
-
-    /* Grays: disambiguate hue */
-    if (s < 0.00000001)
-        h = 0.0;
-
-    in_out->a = l;
-    in_out->b = c;
-    in_out->c = h;
-}
-
-static void
-lch2hpluv(Triplet* in_out)
-{
-    double l = in_out->a;
-    double c = in_out->b;
-    double h = in_out->c;
-    double s;
-
-    /* White and black: disambiguate saturation */
-    if (l > 99.9999999 || l < 0.00000001)
-        s = 0.0;
-    else
-        s = c / max_safe_chroma_for_l(l) * 100.0;
-
-    /* Grays: disambiguate hue */
-    if (c < 0.00000001)
-        h = 0.0;
-
-    in_out->a = h;
-    in_out->b = s;
-    in_out->c = l;
-}
-
-
-
-void
-hsluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb)
-{
-    Triplet tmp = { h, s, l };
-
-    hsluv2lch(&tmp);
-    lch2luv(&tmp);
-    luv2xyz(&tmp);
-    xyz2rgb(&tmp);
-
-    *pr = tmp.a;
-    *pg = tmp.b;
-    *pb = tmp.c;
-}
-
-void
-hpluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb)
-{
-    Triplet tmp = { h, s, l };
-
-    hpluv2lch(&tmp);
-    lch2luv(&tmp);
-    luv2xyz(&tmp);
-    xyz2rgb(&tmp);
-
-    *pr = tmp.a;
-    *pg = tmp.b;
-    *pb = tmp.c;
-}
-
-void
-rgb2hsluv(double r, double g, double b, double* ph, double* ps, double* pl)
-{
-    Triplet tmp = { r, g, b };
-
-    rgb2xyz(&tmp);
-    xyz2luv(&tmp);
-    luv2lch(&tmp);
-    lch2hsluv(&tmp);
-
-    *ph = tmp.a;
-    *ps = tmp.b;
-    *pl = tmp.c;
-}
-
-void
-rgb2hpluv(double r, double g, double b, double* ph, double* ps, double* pl)
-{
-    Triplet tmp = { r, g, b };
-
-    rgb2xyz(&tmp);
-    xyz2luv(&tmp);
-    luv2lch(&tmp);
-    lch2hpluv(&tmp);
-
-    *ph = tmp.a;
-    *ps = tmp.b;
-    *pl = tmp.c;
-}
--- a/hsluv.h
+++ /dev/null
@@ -1,90 +1,0 @@
-/*
- * HSLuv-C: Human-friendly HSL
- * <http://github.com/hsluv/hsluv-c>
- * <http://www.hsluv.org/>
- *
- * Copyright (c) 2015 Alexei Boronine (original idea, JavaScript implementation)
- * Copyright (c) 2015 Roger Tallada (Obj-C implementation)
- * Copyright (c) 2017 Martin Mitas (C implementation, based on Obj-C implementation)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef HSLUV_H
-#define HSLUV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/**
- * Convert HSLuv to RGB.
- *
- * @param h Hue. Between 0.0 and 360.0.
- * @param s Saturation. Between 0.0 and 100.0.
- * @param l Lightness. Between 0.0 and 100.0.
- * @param[out] pr Red component. Between 0.0 and 1.0.
- * @param[out] pg Green component. Between 0.0 and 1.0.
- * @param[out] pb Blue component. Between 0.0 and 1.0.
- */
-void hsluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb);
-
-/**
- * Convert RGB to HSLuv.
- *
- * @param r Red component. Between 0.0 and 1.0.
- * @param g Green component. Between 0.0 and 1.0.
- * @param b Blue component. Between 0.0 and 1.0.
- * @param[out] ph Hue. Between 0.0 and 360.0.
- * @param[out] ps Saturation. Between 0.0 and 100.0.
- * @param[out] pl Lightness. Between 0.0 and 100.0.
- */
-void rgb2hsluv(double r, double g, double b, double* ph, double* ps, double* pl);
-
-/**
- * Convert HPLuv to RGB.
- *
- * @param h Hue. Between 0.0 and 360.0.
- * @param s Saturation. Between 0.0 and 100.0.
- * @param l Lightness. Between 0.0 and 100.0.
- * @param[out] pr Red component. Between 0.0 and 1.0.
- * @param[out] pg Green component. Between 0.0 and 1.0.
- * @param[out] pb Blue component. Between 0.0 and 1.0.
- */
-void hpluv2rgb(double h, double s, double l, double* pr, double* pg, double* pb);
-
-/**
- * Convert RGB to HPLuv.
- *
- * @param r Red component. Between 0.0 and 1.0.
- * @param g Green component. Between 0.0 and 1.0.
- * @param b Blue component. Between 0.0 and 1.0.
- * @param[out] ph Hue. Between 0.0 and 360.0.
- * @param[out] ps Saturation. Between 0.0 and 100.0.
- * @param[out] pl Lightness. Between 0.0 and 100.0.
- */
-void rgb2hpluv(double r, double g, double b, double* ph, double* ps, double* pl);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* HSLUV_H */
--- a/i_external.c
+++ b/i_external.c
@@ -33,7 +33,6 @@
 		return nil;
 	}
 	n = q->width * q->height;
-	PixTransform(q->pixels, n);
 	tx = Hunk_Alloc(sizeof(*tx) + n*85/64*sizeof(pixel_t));
 	strncpy(tx->name, name, sizeof(tx->name)-1);
 	tx->name[sizeof(tx->name)-1] = 0;
--- a/i_transform.c
+++ /dev/null
@@ -1,84 +1,0 @@
-#include "quakedef.h"
-#include "hsluv.h"
-
-#define transform() \
-	do { \
-		if(sa != 1.0 || li != 1.0){ \
-			rgb2hsluv(r, g, b, &h, &s, &l); \
-			s *= sa; \
-			if(s > 100.0) \
-				s = 100.0; \
-			l *= li; \
-			if(l > 100.0) \
-				l = 100.0; \
-			hsluv2rgb(h, s, l, &r, &g, &b); \
-		} \
-		if(br != 0){ \
-			r *= br; \
-			g *= br; \
-			b *= br; \
-		} \
-		if(r > 1) r = 1; else if(r < 0) r = 0; \
-		if(g > 1) g = 1; else if(g < 0) g = 0; \
-		if(b > 1) b = 1; else if(b < 0) b = 0; \
-	}while(0)
-
-void
-LightTransform(u8int *p, int n)
-{
-	double h, s, l, r, g, b, sa, li, br;
-	int i;
-
-	sa = v_saturation.value;
-	li = v_lightness.value;
-	br = v_brightness.value;
-	if(sa == 1.0 && li == 1.0 && br == 1.0)
-		return;
-
-	for(i = 0; i < n; i++, p += 3){
-		r = (double)p[0]/255.0;
-		g = (double)p[1]/255.0;
-		b = (double)p[2]/255.0;
-		transform();
-		p[0] = r*255;
-		p[1] = g*255;
-		p[2] = b*255;
-	}
-}
-
-void
-PixTransform(pixel_t *pixels, int n)
-{
-	double h, s, l, r, g, b, sa, li, br;
-	pixel_t p, in, out;
-	int i;
-
-	sa = v_saturation.value;
-	li = v_lightness.value;
-	br = v_brightness.value;
-	if(sa == 1.0 && li == 1.0 && br == 1.0)
-		return;
-
-	in = out = 0;
-	for(i = 0; i < n; i++){
-		p = pixels[i];
-		if(p == 0)
-			continue;
-		if(p == in && i > 0){
-			pixels[i] = out;
-			continue;
-		}
-
-		in = p;
-		r = (double)((p>>16) & 0xff)/255.0;
-		g = (double)((p>> 8) & 0xff)/255.0;
-		b = (double)((p>> 0) & 0xff)/255.0;
-		transform();
-		out =
-			(in & (0xff<<24)) |
-			(pixel_t)(r * 255)<<16 |
-			(pixel_t)(g * 255)<< 8 |
-			(pixel_t)(b * 255)<< 0;
-		pixels[i] = out;
-	}
-}
--- a/i_transform.h
+++ /dev/null
@@ -1,2 +1,0 @@
-void LightTransform(u8int *p, int n);
-void PixTransform(pixel_t *pixels, int n);
--- a/i_wad.c
+++ b/i_wad.c
@@ -160,10 +160,8 @@
 W_ReadPixelsAt(Wad *wad, char *name, int off, int sz, pixel_t *out, int num)
 {
 	int n, palsz, x, fb;
-	pixel_t *out0;
 	byte *t, *pal;
 
-	out0 = out;
 	num = min(num, sz);
 	num = min(num, wad->sz-off);
 	t = wad->in + off;
@@ -192,7 +190,6 @@
 				*out = ((fb && x >= palsz-32*3) ? 0 : 0xff)<<24 | pal[x+0]<<16 | pal[x+1]<<8 | pal[x+2];
 		}
 	}
-	PixTransform(out0, num);
 	return num;
 err:
 	return -1;
--- a/isnanf.c
+++ b/isnanf.c
@@ -1,7 +1,7 @@
 #include <u.h>
 
 int
-isnanf(float f)
+isNaNf(float f)
 {
 	union {
 		float f;
--- a/mathlib.h
+++ b/mathlib.h
@@ -12,8 +12,6 @@
 #define M_PI		3.14159265358979323846264338327950288
 #endif
 
-int isnanf(float f);
-
 struct mplane_s;
 
 extern vec3_t vec3_origin;
--- a/menu.c
+++ b/menu.c
@@ -1,4 +1,5 @@
 #include "quakedef.h"
+#include "colormatrix.h"
 
 char savs[Nsav][Nsavcm];
 int savcanld[Nsav];
@@ -890,46 +891,41 @@
 	{
 	case 3:	// screen size
 		scr_viewsize.value += dir * 10;
-		if (scr_viewsize.value < 100)
-			scr_viewsize.value = 100;
-		if (scr_viewsize.value > 120)
-			scr_viewsize.value = 120;
-		setcvarv ("viewsize", scr_viewsize.value);
+		scr_viewsize.value = clamp(scr_viewsize.value, 100, 120);
+		setcvarv("viewsize", scr_viewsize.value);
 		break;
-	case 4:	// gamma
-		v_gamma.value -= dir * 0.05;
-		if (v_gamma.value < 0.5)
-			v_gamma.value = 0.5;
-		if (v_gamma.value > 1)
-			v_gamma.value = 1;
-		setcvarv ("gamma", v_gamma.value);
+	case 4:	// brightness
+		v_brightness.value += dir * 0.05;
+		v_brightness.value = clamp(v_brightness.value, 0.5, 4.5);
+		setcvarv("v_brightness", v_brightness.value);
 		break;
-	case 5:	// mouse speed
+	case 5:	// contrast
+		v_contrast.value += dir * 0.05;
+		v_contrast.value = clamp(v_contrast.value, 0.5, 1.5);
+		setcvarv("v_contrast", v_contrast.value);
+		break;
+	case 6:	// saturation
+		v_saturation.value += dir * 0.05;
+		v_saturation.value = clamp(v_saturation.value, 0, 2.0);
+		setcvarv("v_saturation", v_saturation.value);
+		break;
+	case 7:	// mouse speed
 		sensitivity.value += dir * 0.5;
-		if (sensitivity.value < 1)
-			sensitivity.value = 1;
-		if (sensitivity.value > 11)
-			sensitivity.value = 11;
-		setcvarv ("sensitivity", sensitivity.value);
+		sensitivity.value = clamp(sensitivity.value, 1, 11);
+		setcvarv("sensitivity", sensitivity.value);
 		break;
-	case 6:	// music volume
+	case 8:	// music volume
 		bgmvolume.value += dir * 0.1;
-		if (bgmvolume.value < 0)
-			bgmvolume.value = 0;
-		if (bgmvolume.value > 1)
-			bgmvolume.value = 1;
-		setcvarv ("bgmvolume", bgmvolume.value);
+		bgmvolume.value = clamp(bgmvolume.value, 0, 1);
+		setcvarv("bgmvolume", bgmvolume.value);
 		break;
-	case 7:	// sfx volume
+	case 9:	// sfx volume
 		volume.value += dir * 0.1;
-		if (volume.value < 0)
-			volume.value = 0;
-		if (volume.value > 1)
-			volume.value = 1;
-		setcvarv ("volume", volume.value);
+		volume.value = clamp(volume.value, 0, 1);
+		setcvarv("volume", volume.value);
 		break;
 
-	case 8:	// always run
+	case 10:	// always run
 		if (cl_forwardspeed.value > 200)
 		{
 			setcvarv ("cl_forwardspeed", 200);
@@ -942,15 +938,15 @@
 		}
 		break;
 
-	case 9:	// invert mouse
+	case 11:	// invert mouse
 		setcvarv ("m_pitch", -m_pitch.value);
 		break;
 
-	case 10:	// lookspring
+	case 12:	// lookspring
 		setcvarv ("lookspring", !lookspring.value);
 		break;
 
-	case 11:	// lookstrafe
+	case 13:	// lookstrafe
 		setcvarv ("lookstrafe", !lookstrafe.value);
 		break;
 	}
@@ -988,6 +984,7 @@
 static void M_Options_Draw (void)
 {
 	float		r;
+	int y;
 	qpic_t	*p;
 
 	M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") );
@@ -994,41 +991,51 @@
 	p = Draw_CachePic ("gfx/p_option.lmp");
 	M_DrawPic ( (320-p->width)/2, 4, p);
 
-	M_Print (16, 32, "    Customize controls");
-	M_Print (16, 40, "         Go to console");
-	M_Print (16, 48, "     Reset to defaults");
+	y = 32;
+	M_Print (16, y, "    Customize controls"); y += 8;
+	M_Print (16, y, "         Go to console"); y += 8;
+	M_Print (16, y, "     Reset to defaults"); y += 8;
 
-	M_Print (16, 56, "           Screen size");
+	M_Print (16, y, "           Screen size");
 	r = (scr_viewsize.value - 100) / (120 - 100);
-	M_DrawSlider (220, 56, r);
+	M_DrawSlider (220, y, r); y += 8;
 
-	M_Print (16, 64, "            Brightness");
-	r = (1.0 - v_gamma.value) / 0.5;
-	M_DrawSlider (220, 64, r);
+	M_Print (16, y, "            Brightness");
+	r = (v_brightness.value - 0.5) / (4.5 - 0.5);
+	M_DrawSlider (220, y, r); y += 8;
 
-	M_Print (16, 72, "           Mouse Speed");
+	M_Print (16, y, "              Contrast");
+	r = (v_contrast.value - 0.5) / (1.5 - 0.5);
+	M_DrawSlider (220, y, r); y += 8;
+
+	M_Print (16, y, "            Saturation");
+	r = (v_saturation.value - 0.0) / (2 - 0.0);
+	M_DrawSlider (220, y, r); y += 8;
+
+	M_Print (16, y, "           Mouse Speed");
 	r = (sensitivity.value - 1)/10;
-	M_DrawSlider (220, 72, r);
+	M_DrawSlider (220, y, r); y += 8;
 
-	M_Print (16, 80, "       CD Music Volume");
+	M_Print (16, y, "       CD Music Volume");
 	r = bgmvolume.value;
-	M_DrawSlider (220, 80, r);
+	M_DrawSlider (220, y, r); y += 8;
 
-	M_Print (16, 88, "          Sound Volume");
+	M_Print (16, y, "          Sound Volume");
 	r = volume.value;
-	M_DrawSlider (220, 88, r);
+	M_DrawSlider (220, y, r); y += 8;
 
-	M_Print (16, 96,  "            Always Run");
-	M_DrawCheckbox (220, 96, cl_forwardspeed.value > 200);
+	M_Print (16, y,  "            Always Run");
+	M_DrawCheckbox (220, y, cl_forwardspeed.value > 200); y += 8;
 
-	M_Print (16, 104, "          Invert Mouse");
-	M_DrawCheckbox (220, 104, m_pitch.value < 0);
+	M_Print (16, y, "          Invert Mouse");
+	M_DrawCheckbox (220, y, m_pitch.value < 0); y += 8;
 
-	M_Print (16, 112, "            Lookspring");
-	M_DrawCheckbox (220, 112, lookspring.value);
+	M_Print (16, y, "            Lookspring");
+	M_DrawCheckbox (220, y, lookspring.value); y += 8;
 
 	M_Print (16, 120, "            Lookstrafe");
-	M_DrawCheckbox (220, 120, lookstrafe.value);
+	M_DrawCheckbox (220, y, lookstrafe.value); y += 8;
+	USED(y);
 
 	// cursor
 	M_DrawCharacter (200, 32 + options_cursor*8, 12+((int)(realtime*4)&1));
--- a/meson.build
+++ b/meson.build
@@ -31,8 +31,10 @@
 	'cl_parse.c',
 	'cl_tent.c',
 	'cmd.c',
+	'colormatrix.c',
 	'common.c',
 	'console.c',
+	'cmprocess.c',
 	'cvar.c',
 	'd_alpha.c',
 	'd_edge.c',
@@ -49,11 +51,9 @@
 	'fs.c',
 	'host.c',
 	'host_cmd.c',
-	'hsluv.c',
 	'i_external.c',
 	'i_resize.c',
 	'i_tga.c',
-	'i_transform.c',
 	'i_wad.c',
 	'keys.c',
 	'm_random.c',
--- a/mkfile
+++ b/mkfile
@@ -14,6 +14,8 @@
 	cl_parse.$O\
 	cl_tent.$O\
 	cmd.$O\
+	cmprocess`{test -f cmprocess_$objtype.s && echo -n _$objtype}.$O\
+	colormatrix.$O\
 	common.$O\
 	console.$O\
 	cvar.$O\
@@ -32,11 +34,9 @@
 	fs.$O\
 	host.$O\
 	host_cmd.$O\
-	hsluv.$O\
 	i_external.$O\
 	i_resize.$O\
 	i_tga.$O\
-	i_transform.$O\
 	i_wad.$O\
 	in_plan9.$O\
 	isnanf.$O\
@@ -98,6 +98,7 @@
 	bspfile.h\
 	client.h\
 	cmd.h\
+	colormatrix.h\
 	common.h\
 	console.h\
 	cvar.h\
--- a/model_bsp.c
+++ b/model_bsp.c
@@ -266,7 +266,6 @@
 		if((lit = loadhunklmp(s, &litsz)) != nil && litsz >= 4+4+sz*3){
 			if(memcmp(lit, "QLIT", 4) == 0 && lit[4] == 1 && lit[5] == 0 && lit[6] == 0 && lit[7] == 0){
 				mod->lightdata = lit + 8;
-				LightTransform(mod->lightdata, sz);
 				return 0;
 			}else{
 				Con_Printf("%s: invalid/unsupported LIT file\n", s);
@@ -281,7 +280,6 @@
 		mod->lightdata[i*3+1] = in[i];
 		mod->lightdata[i*3+2] = in[i];
 	}
-	LightTransform(mod->lightdata, sz);
 	return 0;
 }
 
--- a/model_bsp30.c
+++ b/model_bsp30.c
@@ -48,7 +48,6 @@
 	}
 
 	memcpy(mod->lightdata = Hunk_Alloc(sz), in, sz);
-	LightTransform(mod->lightdata, sz);
 	return 0;
 }
 
--- a/model_sprite.c
+++ b/model_sprite.c
@@ -36,7 +36,6 @@
 	}else if(mod->ver == SPRITE32_VERSION){
 		for(i = 0; i < size; i++, in += sizeof(pixel_t))
 			pspriteframe->pixels[i] = in[3] == 0 ? 0 : (in[3]<<24 | in[0]<<16 | in[1]<<8 | in[2]);
-		PixTransform(pspriteframe->pixels, size);
 		mod->blend = true;
 	}
 
--- a/plan9/platform.h
+++ b/plan9/platform.h
@@ -15,6 +15,7 @@
 #define sinf sin
 #define sqrtf sqrt
 #define tanf tan
+int isNaNf(float f);
 
 #define __inline__ inline
 
--- a/posix/platform.h
+++ b/posix/platform.h
@@ -39,6 +39,7 @@
 #define getmalloctag(p) (USED(p), 0)
 #define setmalloctag(p, t) do{USED(p); USED(t);}while(0)
 #define setrealloctag(p, t) do{USED(p); USED(t);}while(0)
+#define isNaNf isnan
 
 #define qctz(x) __builtin_ctz(x)
 
--- a/quakedef.h
+++ b/quakedef.h
@@ -141,7 +141,6 @@
 
 #include "i_tga.h"
 #include "i_wad.h"
-#include "i_transform.h"
 #include "draw.h"
 #include "screen.h"
 #include "net.h"
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -42,12 +42,12 @@
 	// bound velocity
 	for (i=0 ; i<3 ; i++)
 	{
-		if (isnanf(ent->v.velocity[i]))
+		if (isNaNf(ent->v.velocity[i]))
 		{
 			Con_Printf ("Got a NaN velocity on %s\n", PR_Str(sv.pr, ent->v.classname));
 			ent->v.velocity[i] = 0;
 		}
-		if (isnanf(ent->v.origin[i]))
+		if (isNaNf(ent->v.origin[i]))
 		{
 			Con_Printf ("Got a NaN origin on %s\n", PR_Str(sv.pr, ent->v.classname));
 			ent->v.origin[i] = 0;
--- a/vid_plan9.c
+++ b/vid_plan9.c
@@ -1,4 +1,5 @@
 #include "quakedef.h"
+#include "colormatrix.h"
 #include <draw.h>
 #include <thread.h>
 
@@ -8,7 +9,7 @@
 
 pixel_t q1pal[256];
 static Image *fbi;
-static u32int *scibuf;
+static s32int *scibuf;
 static int scifactor;
 static Rectangle fbr;
 static pixel_t *vidbuffers[2];
@@ -68,10 +69,10 @@
 
 	freeimage(fbi);
 	if(scifactor != 1){
-		fbi = allocimage(display, Rect(0, 0, vid.width*scifactor, 1), XRGB32, 1, DNofill);
+		fbi = allocimage(display, Rect(0, 0, vid.width*scifactor, 1), screen->chan, 1, DNofill);
 		scibuf = realloc(scibuf, vid.width*scifactor*sizeof(*scibuf));
 	}else{
-		fbi = allocimage(display, Rect(0, 0, vid.width, vid.height), XRGB32, 0, 0);
+		fbi = allocimage(display, Rect(0, 0, vid.width, vid.height), screen->chan, 0, 0);
 		free(scibuf);
 		scibuf = nil;
 	}
@@ -82,7 +83,7 @@
 static void
 loader(void *)
 {
-	u32int *in, *out;
+	s32int *in, *out;
 	int n, x, y, j;
 	Point center;
 	Rectangle r;
@@ -98,14 +99,14 @@
 	for(;;){
 		if((f = recvp(frame)) == nil)
 			break;
+		cmprocess(cm, f, f, vid.width*vid.height);
 		if(scibuf != nil){
-			in = (u32int*)f;
+			in = (s32int*)f;
 
 			r = rectsubpt(
 				rectaddpt(Rect(0, 0, scifactor*vid.width, scifactor), center),
 				Pt(scifactor*vid.width/2, scifactor*vid.height/2)
 			);
-
 			for(y = 0; y < vid.height; y++){
 				for(x = 0, out = scibuf; x < vid.width; x++, in++){
 					for(j = 0; j < scifactor; j++, out++)
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -1,4 +1,5 @@
 #include "quakedef.h"
+#include "colormatrix.h"
 #include <SDL.h>
 
 pixel_t q1pal[256];
@@ -105,6 +106,8 @@
 		return;
 	}
 
+	cmprocess(cm, vidbuffer, vidbuffer, vid.width*vid.height);
+
 	SDL_UpdateTexture(fbi, nil, vidbuffer, vid.width*4);
 	SDL_RenderCopy(rend, fbi, nil, nil);
 	SDL_RenderPresent(rend);
@@ -215,8 +218,8 @@
 	resetfb();
 	IN_Grabm(1);
 
-	v_fullscreen.cb = v_fullscreen_cb;
-	v_sync.cb = v_sync_cb;
 	Cvar_RegisterVariable(&v_fullscreen);
+	v_fullscreen.cb = v_fullscreen_cb;
 	Cvar_RegisterVariable(&v_sync);
+	v_sync.cb = v_sync_cb;
 }
--- a/view.c
+++ b/view.c
@@ -1,4 +1,5 @@
 #include "quakedef.h"
+#include "colormatrix.h"
 
 /*
 
@@ -12,9 +13,6 @@
 cvar_t lcd_x = {"lcd_x","0"};
 
 cvar_t v_scale = {"v_scale", "1", true};
-cvar_t v_saturation = {"v_saturation", "1", true};
-cvar_t v_lightness = {"v_lightness", "1", true};
-cvar_t v_brightness = {"v_brightness", "1", true};
 
 static cvar_t lcd_yaw = {"lcd_yaw","0"};
 
@@ -240,56 +238,7 @@
 static cshift_t cshift_slime = { {0,25,5}, 150 };
 static cshift_t cshift_lava = { {255,80,0}, 150 };
 
-cvar_t v_gamma = {"gamma", "1", true};
-
-static byte gammatable[256];	// palette is sent through this
-
-static void
-BuildGammaTable(float g)
-{
-	int		i, inf;
-
-	if (g == 1.0)
-	{
-		for (i=0 ; i<256 ; i++)
-			gammatable[i] = i;
-		return;
-	}
-
-	for (i=0 ; i<256 ; i++)
-	{
-		inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
-		if (inf < 0)
-			inf = 0;
-		if (inf > 255)
-			inf = 255;
-		gammatable[i] = inf;
-	}
-}
-
 /*
-=================
-V_CheckGamma
-=================
-*/
-static bool
-V_CheckGamma(void)
-{
-	static float oldgammavalue;
-
-	if (v_gamma.value == oldgammavalue)
-		return false;
-	oldgammavalue = v_gamma.value;
-
-	BuildGammaTable (v_gamma.value);
-	vid.recalc_refdef = true;				// force a surface cache flush
-
-	return true;
-}
-
-
-
-/*
 ===============
 V_ParseDamage
 ===============
@@ -461,27 +410,18 @@
 void V_UpdatePalette (void)
 {
 	int		i, j;
-	bool	new;
-	byte	*basepal, *newpal;
-	byte	pal[768];
-	int		r,g,b;
-	bool force;
 
 	V_CalcPowerupCshift ();
 
-	new = false;
-
 	for (i=0 ; i<NUM_CSHIFTS ; i++)
 	{
 		if (cl.cshifts[i].percent != cl.prev_cshifts[i].percent)
 		{
-			new = true;
 			cl.prev_cshifts[i].percent = cl.cshifts[i].percent;
 		}
 		for (j=0 ; j<3 ; j++)
 			if (cl.cshifts[i].destcolor[j] != cl.prev_cshifts[i].destcolor[j])
 			{
-				new = true;
 				cl.prev_cshifts[i].destcolor[j] = cl.cshifts[i].destcolor[j];
 			}
 	}
@@ -495,34 +435,7 @@
 	cl.cshifts[CSHIFT_BONUS].percent -= host_frametime*100;
 	if (cl.cshifts[CSHIFT_BONUS].percent <= 0)
 		cl.cshifts[CSHIFT_BONUS].percent = 0;
-
-	force = V_CheckGamma ();
-	if (!new && !force)
-		return;
-
-	basepal = host_basepal;
-	newpal = pal;
-
-	for (i=0 ; i<256 ; i++)
-	{
-		r = basepal[0];
-		g = basepal[1];
-		b = basepal[2];
-		basepal += 3;
-
-		for (j=0 ; j<NUM_CSHIFTS ; j++)
-		{
-			r += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[0]-r))>>8;
-			g += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[1]-g))>>8;
-			b += (cl.cshifts[j].percent*(cl.cshifts[j].destcolor[2]-b))>>8;
-		}
-
-		newpal[0] = gammatable[r];
-		newpal[1] = gammatable[g];
-		newpal[2] = gammatable[b];
-		newpal += 3;
-	}
-	//setpal(pal); // FIXME(sigrid): 24-bit
+	// FIXME(sigrid): 24-bit
 }
 
 
@@ -965,6 +878,8 @@
 */
 void V_Init (void)
 {
+	cminit();
+
 	Cmd_AddCommand("v_cshift", V_cshift_f);
 	Cmd_AddCommand("bf", V_BonusFlash_f);
 	Cmd_AddCommand("centerview", V_StartPitchDrift);
@@ -972,9 +887,6 @@
 
 	Cvar_RegisterVariable(&v_scale);
 	v_scale.cb = v_scale_cb;
-	Cvar_RegisterVariable(&v_saturation);
-	Cvar_RegisterVariable(&v_lightness);
-	Cvar_RegisterVariable(&v_brightness);
 
 	Cvar_RegisterVariable (&lcd_x);
 	Cvar_RegisterVariable (&lcd_yaw);
@@ -1007,7 +919,4 @@
 	Cvar_RegisterVariable (&v_kicktime);
 	Cvar_RegisterVariable (&v_kickroll);
 	Cvar_RegisterVariable (&v_kickpitch);
-
-	BuildGammaTable (1.0);	// no gamma yet
-	Cvar_RegisterVariable (&v_gamma);
 }
--- a/view.h
+++ b/view.h
@@ -1,13 +1,7 @@
-extern	cvar_t		v_gamma;
-
-extern	byte		ramps[3][256];
 extern float v_blend[4];
 
 extern cvar_t lcd_x;
 extern cvar_t v_scale;
-extern cvar_t v_saturation;
-extern cvar_t v_lightness;
-extern cvar_t v_brightness;
 
 void V_Init (void);
 void V_RenderView (void);