From: havoc Date: Fri, 7 Mar 2003 09:34:15 +0000 (+0000) Subject: menu.c - changed M_DrawSlider to take a value and a min/max range, now prints the... X-Git-Tag: xonotic-v0.1.0preview~6732 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=d6fb6e3d3eb443499060b44c10bd6647c90e00d6 menu.c - changed M_DrawSlider to take a value and a min/max range, now prints the current value of the cvar as well menu.c, menu.h, gl_draw.c - added new color control options menu (the gl_draw.c change is merely adding a "ditherpattern" texture) menu.c - added "Delay refresh (faster)" to options menu (gl_delayfinish cvar) menu.c - added "Game Speed" to options menu (slowmo cvar) vid_wgl.c, vid_glx.c, vid_null.c, vid_shared.c, vid.h, palette.c, palette.h, host.c - gamma system redesigned (VID_SetGamma now takes ramps, VID_GetGamma added, other cruft removed), moved VID_UpdateGamma to vid_shared.c, gamma is now turned off when darkplaces is minimized in X11 (unmapped), and when it's window is not active in Windows as well vid_wgl.c - trailing whitespace fixed vid_shared.c - added v_color_enable, v_color_black_[rgb], v_color_grey_[rgb], and v_color_white_[rgb] cvars as another way to adjust color settings gl_draw.c - added support for v_color_* cvars, removed support for darkening screen (not possible to do in color) vid_glx.c - got rid of unfinished X11 colormap based gamma code (using XF86 VidMode extension instead) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2813 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_draw.c b/gl_draw.c index 8e7ea4eb..d203b6f7 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -197,6 +197,14 @@ static rtexture_t *draw_generatecrosshair(int num) return R_LoadTexture2D(drawtexturepool, va("crosshair%i", num), 16, 16, &data[0][0], TEXTYPE_RGBA, TEXF_ALPHA | TEXF_PRECACHE, NULL); } +static rtexture_t *draw_generateditherpattern(void) +{ + qbyte data[16]; + memset(data, 255, sizeof(data)); + data[0] = data[1] = data[2] = data[12] = data[13] = data[14] = 0; + return R_LoadTexture2D(drawtexturepool, "ditherpattern", 2, 2, data, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_PRECACHE, NULL); +} + /* ================ Draw_CachePic @@ -258,6 +266,8 @@ cachepic_t *Draw_CachePic (char *path) pic->tex = draw_generatecrosshair(3); if (pic->tex == NULL && !strcmp(path, "gfx/crosshair5.tga")) pic->tex = draw_generatecrosshair(4); + if (pic->tex == NULL && !strcmp(path, "gfx/colorcontrol/ditherpattern.tga")) + pic->tex = draw_generateditherpattern(); if (pic->tex == NULL) { Con_Printf ("Draw_CachePic: failed to load %s\n", path); @@ -371,7 +381,7 @@ int quadelements[768]; void R_DrawQueue(void) { int pos, num, chartexnum, overbright, texnum, additive, batch; - float x, y, w, h, s, t, u, v, cr, cg, cb, ca, *av, *at; + float x, y, w, h, s, t, u, v, *av, *at, c[4]; cachepic_t *pic; drawqueue_t *dq; char *str, *currentpic; @@ -429,10 +439,10 @@ void R_DrawQueue(void) m.depthdisable = true; R_Mesh_MainState(&m); - cr = (float) ((color >> 24) & 0xFF) * (1.0f / 255.0f) * r_colorscale; - cg = (float) ((color >> 16) & 0xFF) * (1.0f / 255.0f) * r_colorscale; - cb = (float) ((color >> 8) & 0xFF) * (1.0f / 255.0f) * r_colorscale; - ca = (float) ( color & 0xFF) * (1.0f / 255.0f); + c[0] = (float) ((color >> 24) & 0xFF) * (1.0f / 255.0f) * r_colorscale; + c[1] = (float) ((color >> 16) & 0xFF) * (1.0f / 255.0f) * r_colorscale; + c[2] = (float) ((color >> 8) & 0xFF) * (1.0f / 255.0f) * r_colorscale; + c[3] = (float) ( color & 0xFF) * (1.0f / 255.0f); x = dq->x; y = dq->y; w = dq->scalex; @@ -469,7 +479,7 @@ void R_DrawQueue(void) varray_vertex[ 4] = x+w;varray_vertex[ 5] = y ;varray_vertex[ 6] = 10; varray_vertex[ 8] = x+w;varray_vertex[ 9] = y+h;varray_vertex[10] = 10; varray_vertex[12] = x ;varray_vertex[13] = y+h;varray_vertex[14] = 10; - GL_Color(cr, cg, cb, ca); + GL_Color(c[0], c[1], c[2], c[3]); R_Mesh_Draw(4, 2, quadelements); break; case DRAWQUEUE_STRING: @@ -483,7 +493,7 @@ void R_DrawQueue(void) batchcount = 0; at = varray_texcoord[0]; av = varray_vertex; - GL_Color(cr, cg, cb, ca); + GL_Color(c[0], c[1], c[2], c[3]); while ((num = *str++) && x < vid.conwidth) { if (num != ' ') @@ -531,7 +541,7 @@ void R_DrawQueue(void) } } - if (!v_hwgamma.integer) + if (!vid_usinghwgamma) { // we use one big triangle for all the screen blends varray_texcoord[0][0] = 0;varray_texcoord[0][1] = 0; @@ -543,36 +553,41 @@ void R_DrawQueue(void) // all the blends ignore depth memset(&m, 0, sizeof(m)); m.depthdisable = true; - t = v_contrast.value * (float) (1 << v_overbrightbits.integer); - if (t >= 1.01f) + if (v_color_enable.integer) + { + c[0] = v_color_white_r.value; + c[1] = v_color_white_g.value; + c[2] = v_color_white_b.value; + } + else + c[0] = c[1] = c[2] = v_contrast.value; + VectorScale(c, (float) (1 << v_overbrightbits.integer), c); + if (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f) { m.blendfunc1 = GL_DST_COLOR; m.blendfunc2 = GL_ONE; R_Mesh_State(&m); - while (t >= 1.01f) + while (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f) { - cr = t - 1.0f; - if (cr > 1.0f) - cr = 1.0f; - GL_Color(cr, cr, cr, 1); + GL_Color(bound(0, c[0] - 1, 1), bound(0, c[1] - 1, 1), bound(0, c[2] - 1, 1), 1); R_Mesh_Draw(3, 1, polygonelements); - t *= 0.5; + VectorScale(c, 0.5, c); } } - else if (t <= 0.99f) + if (v_color_enable.integer) { - m.blendfunc1 = GL_ZERO; - m.blendfunc2 = GL_SRC_COLOR; - R_Mesh_State(&m); - GL_Color(t, t, t, 1); - R_Mesh_Draw(3, 1, polygonelements); + c[0] = v_color_black_r.value; + c[1] = v_color_black_g.value; + c[2] = v_color_black_b.value; } - if (v_brightness.value >= 0.01f) + else + c[0] = c[1] = c[2] = v_brightness.value; + if (c[0] >= 0.01f || c[1] >= 0.01f || c[2] >= 0.01f) { m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ONE; R_Mesh_State(&m); - GL_Color(v_brightness.value, v_brightness.value, v_brightness.value, 1); + GL_Color(c[0], c[1], c[2], 1); R_Mesh_Draw(3, 1, polygonelements); } } diff --git a/host.c b/host.c index 7c0957cc..3ac0f7e0 100644 --- a/host.c +++ b/host.c @@ -898,7 +898,6 @@ void Host_Init (void) if (cls.state != ca_dedicated) { - Gamma_Init(); Palette_Init(); VID_Shared_Init(); VID_Init(); diff --git a/menu.c b/menu.c index 23fbafcd..bcc5117e 100644 --- a/menu.c +++ b/menu.c @@ -38,6 +38,7 @@ void M_Menu_Main_f (void); void M_Menu_Net_f (void); void M_Menu_Options_f (void); void M_Menu_Options_Effects_f (void); + void M_Menu_Options_ColorControl_f (void); void M_Menu_Keys_f (void); void M_Menu_Video_f (void); void M_Menu_Help_f (void); @@ -57,6 +58,7 @@ void M_Main_Draw (void); void M_Net_Draw (void); void M_Options_Draw (void); void M_Options_Effects_Draw (void); + void M_Options_ColorControl_Draw (void); void M_Keys_Draw (void); void M_Video_Draw (void); void M_Help_Draw (void); @@ -76,6 +78,7 @@ void M_Main_Key (int key); void M_Net_Key (int key); void M_Options_Key (int key); void M_Options_Effects_Key (int key); + void M_Options_ColorControl_Key (int key); void M_Keys_Key (int key); void M_Video_Key (int key); void M_Help_Key (int key); @@ -305,9 +308,9 @@ void M_ToggleMenu_f (void) int demo_cursor; void M_Demo_Draw (void) { - int i; + int i; - for (i=0; i < NumberOfNehahraDemos; i++) + for (i = 0;i < NumberOfNehahraDemos;i++) M_Print (16, 16 + 8*i, NehahraDemos[i].desc); // line cursor @@ -317,9 +320,9 @@ void M_Demo_Draw (void) void M_Menu_Demos_f (void) { - key_dest = key_menu; - m_state = m_demo; - m_entersound = true; + key_dest = key_menu; + m_state = m_demo; + m_entersound = true; } void M_Demo_Key (int k) @@ -1247,19 +1250,19 @@ again: #define SLIDER_RANGE 10 -void M_DrawSlider (int x, int y, float range) +void M_DrawSlider (int x, int y, float num, float rangemin, float rangemax) { - int i; - - if (range < 0) - range = 0; - if (range > 1) - range = 1; + char text[16]; + int i; + float range; + range = bound(0, (num - rangemin) / (rangemax - rangemin), 1); M_DrawCharacter (x-8, y, 128); - for (i=0 ; i 200) { Cvar_SetValueQuick (&cl_forwardspeed, 200); @@ -1353,22 +1352,22 @@ void M_Menu_Options_AdjustSliders (int dir) Cvar_SetValueQuick (&cl_backspeed, 400); } break; - case 22: // lookspring + case 21: // lookspring Cvar_SetValueQuick (&lookspring, !lookspring.integer); break; - case 23: // lookstrafe + case 22: // lookstrafe Cvar_SetValueQuick (&lookstrafe, !lookstrafe.integer); break; - case 24: // mouse speed + case 23: // mouse speed Cvar_SetValueQuick (&sensitivity, bound(1, sensitivity.value + dir * 0.5, 50)); break; - case 25: // mouse look + case 24: // mouse look Cvar_SetValueQuick (&freelook, !freelook.integer); break; - case 26: // invert mouse + case 25: // invert mouse Cvar_SetValueQuick (&m_pitch, -m_pitch.value); break; - case 27: // windowed mouse + case 26: // windowed mouse Cvar_SetValueQuick (&vid_mouse, !vid_mouse.integer); break; } @@ -1389,26 +1388,25 @@ void M_Options_Draw (void) M_Print(16, y, " Reset to defaults");y += 8; M_Print(16, y, " Video Options");y += 8; M_Print(16, y, " Effects Options");y += 8; - M_Print(16, y, " 2D Resolution");M_DrawSlider(220, y, scr_2dresolution.value);y += 8; - M_Print(16, y, " Screen size");M_DrawSlider(220, y, (scr_viewsize.value - 30) /(120 - 30));y += 8; + M_Print(16, y, " Color Control Options");y += 8; + M_Print(16, y, " 2D Resolution");M_DrawSlider(220, y, scr_2dresolution.value, 0, 1);y += 8; + M_Print(16, y, " Screen size");M_DrawSlider(220, y, scr_viewsize.value, 30, 120);y += 8; M_Print(16, y, " Sky");M_DrawCheckbox(220, y, r_sky.integer);y += 8; - M_Print(16, y, " Overbright Bits");M_DrawSlider(220, y, (v_overbrightbits.value) / 4);y += 8; + M_Print(16, y, " Overbright Bits");M_DrawSlider(220, y, v_overbrightbits.value, 0, 4);y += 8; M_Print(16, y, " Texture Combine");M_DrawCheckbox(220, y, gl_combine.integer);y += 8; M_Print(16, y, " Dithering");M_DrawCheckbox(220, y, gl_dither.integer);y += 8; - M_ItemPrint(16, y, "Hardware Gamma Control", hardwaregammasupported);M_DrawCheckbox(220, y, v_hwgamma.integer);y += 8; - M_ItemPrint(16, y, " Gamma", v_hwgamma.integer);M_DrawSlider(220, y, (v_gamma.value - 1) / 4);y += 8; - M_Print(16, y, " Contrast");M_DrawSlider(220, y, (v_contrast.value - 0.5) / (5 - 0.5));y += 8; - M_Print(16, y, " Brightness");M_DrawSlider(220, y, v_brightness.value / 0.8);y += 8; - M_ItemPrint(16, y, " CD Music Volume", cdaudioinitialized);M_DrawSlider(220, y, bgmvolume.value);y += 8; - M_ItemPrint(16, y, " Sound Volume", snd_initialized);M_DrawSlider(220, y, volume.value);y += 8; - M_Print(16, y, " Crosshair");M_DrawSlider(220, y, crosshair.value / 5);y += 8; - M_Print(16, y, " Crosshair Size");M_DrawSlider(220, y, (crosshair_size.value - 1) / 4);y += 8; + M_Print(16, y, "Delay refresh (faster)");M_DrawCheckbox(220, y, gl_delayfinish.integer);y += 8; + M_ItemPrint(16, y, " Game Speed", sv.active);M_DrawSlider(220, y, slowmo.value, 0, 5);y += 8; + M_ItemPrint(16, y, " CD Music Volume", cdaudioinitialized);M_DrawSlider(220, y, bgmvolume.value, 0, 1);y += 8; + M_ItemPrint(16, y, " Sound Volume", snd_initialized);M_DrawSlider(220, y, volume.value, 0, 1);y += 8; + M_Print(16, y, " Crosshair");M_DrawSlider(220, y, crosshair.value, 0, 5);y += 8; + M_Print(16, y, " Crosshair Size");M_DrawSlider(220, y, crosshair_size.value, 1, 5);y += 8; M_Print(16, y, " Static Crosshair");M_DrawCheckbox(220, y, crosshair_static.integer);y += 8; M_Print(16, y, " Show Framerate");M_DrawCheckbox(220, y, showfps.integer);y += 8; M_Print(16, y, " Always Run");M_DrawCheckbox(220, y, cl_forwardspeed.value > 200);y += 8; M_Print(16, y, " Lookspring");M_DrawCheckbox(220, y, lookspring.integer);y += 8; M_Print(16, y, " Lookstrafe");M_DrawCheckbox(220, y, lookstrafe.integer);y += 8; - M_Print(16, y, " Mouse Speed");M_DrawSlider(220, y, (sensitivity.value - 1)/50);y += 8; + M_Print(16, y, " Mouse Speed");M_DrawSlider(220, y, sensitivity.value, 1, 50);y += 8; M_Print(16, y, " Mouse Look");M_DrawCheckbox(220, y, freelook.integer);y += 8; M_Print(16, y, " Invert Mouse");M_DrawCheckbox(220, y, m_pitch.value < 0);y += 8; M_Print(16, y, " Use Mouse");M_DrawCheckbox(220, y, vid_mouse.integer);y += 8; @@ -1446,6 +1444,9 @@ void M_Options_Key (int k) case 4: M_Menu_Options_Effects_f (); break; + case 5: + M_Menu_Options_ColorControl_f (); + break; default: M_Menu_Options_AdjustSliders (1); break; @@ -1572,7 +1573,7 @@ void M_Options_Effects_Draw (void) M_DrawPic((320-p->width)/2, 4, "gfx/p_option.lmp"); y = 32; - M_Print(16, y, " Lights Per Model");M_DrawSlider(220, y, r_modellights.value / 8);y += 8; + M_Print(16, y, " Lights Per Model");M_DrawSlider(220, y, r_modellights.value, 0, 8);y += 8; M_Print(16, y, " Fast Dynamic Lighting");M_DrawCheckbox(220, y, !r_dlightmap.integer);y += 8; M_Print(16, y, " Coronas");M_DrawCheckbox(220, y, r_coronas.integer);y += 8; M_Print(16, y, " Use Only Coronas");M_DrawCheckbox(220, y, gl_flashblend.integer);y += 8; @@ -1586,8 +1587,8 @@ void M_Options_Effects_Draw (void) M_Print(16, y, " Sparks");M_DrawCheckbox(220, y, cl_particles_sparks.integer);y += 8; M_Print(16, y, " Bubbles");M_DrawCheckbox(220, y, cl_particles_bubbles.integer);y += 8; M_Print(16, y, " Blood");M_DrawCheckbox(220, y, cl_particles_blood.integer);y += 8; - M_Print(16, y, " Blood Size");M_DrawSlider(220, y, (cl_particles_blood_size.value - 2) / 18);y += 8; - M_Print(16, y, " Blood Opacity");M_DrawSlider(220, y, (cl_particles_blood_alpha.value - 0.2) / 0.8);y += 8; + M_Print(16, y, " Blood Size");M_DrawSlider(220, y, cl_particles_blood_size.value, 2, 20);y += 8; + M_Print(16, y, " Blood Opacity");M_DrawSlider(220, y, cl_particles_blood_alpha.value, 0.2, 1);y += 8; // cursor M_DrawCharacter(200, 32 + options_effects_cursor*8, 12+((int)(realtime*4)&1)); @@ -1630,6 +1631,240 @@ void M_Options_Effects_Key (int k) } } + + + + +#define OPTIONS_COLORCONTROL_ITEMS 18 + +int options_colorcontrol_cursor; + +// intensity value to match up to 50% dither to 'correct' quake +cvar_t menu_options_colorcontrol_correctionvalue = {0, "menu_options_colorcontrol_correctionvalue", "0.25"}; + +void M_Menu_Options_ColorControl_f (void) +{ + key_dest = key_menu; + m_state = m_options_colorcontrol; + m_entersound = true; +} + + +void M_Menu_Options_ColorControl_AdjustSliders (int dir) +{ + float f; + S_LocalSound ("misc/menu3.wav"); + + switch (options_colorcontrol_cursor) + { + case 1: + Cvar_SetValueQuick (&v_hwgamma, !v_hwgamma.integer); + break; + case 2: + Cvar_SetValueQuick (&v_color_enable, 0); + Cvar_SetValueQuick (&v_gamma, bound(1, v_gamma.value + dir * 0.125, 5)); + break; + case 3: + Cvar_SetValueQuick (&v_color_enable, 0); + Cvar_SetValueQuick (&v_contrast, bound(1, v_contrast.value + dir * 0.125, 5)); + break; + case 4: + Cvar_SetValueQuick (&v_color_enable, 0); + Cvar_SetValueQuick (&v_brightness, bound(0, v_brightness.value + dir * 0.05, 0.8)); + break; + case 5: + Cvar_SetValueQuick (&v_color_enable, !v_color_enable.integer); + break; + case 6: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_black_r, bound(0, v_color_black_r.value + dir * 0.0125, 0.8)); + break; + case 7: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_black_g, bound(0, v_color_black_g.value + dir * 0.0125, 0.8)); + break; + case 8: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_black_b, bound(0, v_color_black_b.value + dir * 0.0125, 0.8)); + break; + case 9: + Cvar_SetValueQuick (&v_color_enable, 1); + f = bound(0, (v_color_black_r.value + v_color_black_g.value + v_color_black_b.value) / 3 + dir * 0.0125, 0.8); + Cvar_SetValueQuick (&v_color_black_r, f); + Cvar_SetValueQuick (&v_color_black_g, f); + Cvar_SetValueQuick (&v_color_black_b, f); + break; + case 10: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_grey_r, bound(0, v_color_grey_r.value + dir * 0.0125, 0.95)); + break; + case 11: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_grey_g, bound(0, v_color_grey_g.value + dir * 0.0125, 0.95)); + break; + case 12: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_grey_b, bound(0, v_color_grey_b.value + dir * 0.0125, 0.95)); + break; + case 13: + Cvar_SetValueQuick (&v_color_enable, 1); + f = bound(0, (v_color_grey_r.value + v_color_grey_g.value + v_color_grey_b.value) / 3 + dir * 0.0125, 0.95); + Cvar_SetValueQuick (&v_color_grey_r, f); + Cvar_SetValueQuick (&v_color_grey_g, f); + Cvar_SetValueQuick (&v_color_grey_b, f); + break; + case 14: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_white_r, bound(1, v_color_white_r.value + dir * 0.125, 5)); + break; + case 15: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_white_g, bound(1, v_color_white_g.value + dir * 0.125, 5)); + break; + case 16: + Cvar_SetValueQuick (&v_color_enable, 1); + Cvar_SetValueQuick (&v_color_white_b, bound(1, v_color_white_b.value + dir * 0.125, 5)); + break; + case 17: + Cvar_SetValueQuick (&v_color_enable, 1); + f = bound(1, (v_color_white_r.value + v_color_white_g.value + v_color_white_b.value) / 3 + dir * 0.125, 5); + Cvar_SetValueQuick (&v_color_white_r, f); + Cvar_SetValueQuick (&v_color_white_g, f); + Cvar_SetValueQuick (&v_color_white_b, f); + break; + } +} + +void M_Options_ColorControl_Draw (void) +{ + float x, y, c, s, t, u, v; + cachepic_t *p; + + M_DrawPic(16, 4, "gfx/qplaque.lmp"); + p = Draw_CachePic("gfx/p_option.lmp"); + M_DrawPic((320-p->width)/2, 4, "gfx/p_option.lmp"); + + y = 32; + M_Print(16, y, " Reset to defaults");y += 8; + M_ItemPrint(16, y, "Hardware Gamma Control", vid_hardwaregammasupported);M_DrawCheckbox(220, y, v_hwgamma.integer);y += 8; + M_ItemPrint(16, y, " Gamma", !v_color_enable.integer && vid_hardwaregammasupported && v_hwgamma.integer);M_DrawSlider(220, y, v_gamma.value, 1, 5);y += 8; + M_ItemPrint(16, y, " Contrast", !v_color_enable.integer);M_DrawSlider(220, y, v_contrast.value, 1, 5);y += 8; + M_ItemPrint(16, y, " Brightness", !v_color_enable.integer);M_DrawSlider(220, y, v_brightness.value, 0, 0.8);y += 8; + M_Print(16, y, " Color Level Controls");M_DrawCheckbox(220, y, v_color_enable.integer);y += 8; + M_ItemPrint(16, y, " Black: Red ", v_color_enable.integer);M_DrawSlider(220, y, v_color_black_r.value, 0, 0.8);y += 8; + M_ItemPrint(16, y, " Black: Green", v_color_enable.integer);M_DrawSlider(220, y, v_color_black_g.value, 0, 0.8);y += 8; + M_ItemPrint(16, y, " Black: Blue ", v_color_enable.integer);M_DrawSlider(220, y, v_color_black_b.value, 0, 0.8);y += 8; + M_ItemPrint(16, y, " Black: Grey ", v_color_enable.integer);M_DrawSlider(220, y, (v_color_black_r.value + v_color_black_g.value + v_color_black_b.value) / 3, 0, 0.8);y += 8; + M_ItemPrint(16, y, " Grey: Red ", v_color_enable.integer && vid_hardwaregammasupported && v_hwgamma.integer);M_DrawSlider(220, y, v_color_grey_r.value, 0, 0.95);y += 8; + M_ItemPrint(16, y, " Grey: Green", v_color_enable.integer && vid_hardwaregammasupported && v_hwgamma.integer);M_DrawSlider(220, y, v_color_grey_g.value, 0, 0.95);y += 8; + M_ItemPrint(16, y, " Grey: Blue ", v_color_enable.integer && vid_hardwaregammasupported && v_hwgamma.integer);M_DrawSlider(220, y, v_color_grey_b.value, 0, 0.95);y += 8; + M_ItemPrint(16, y, " Grey: Grey ", v_color_enable.integer && vid_hardwaregammasupported && v_hwgamma.integer);M_DrawSlider(220, y, (v_color_grey_r.value + v_color_grey_g.value + v_color_grey_b.value) / 3, 0, 0.95);y += 8; + M_ItemPrint(16, y, " White: Red ", v_color_enable.integer);M_DrawSlider(220, y, v_color_white_r.value, 1, 5);y += 8; + M_ItemPrint(16, y, " White: Green", v_color_enable.integer);M_DrawSlider(220, y, v_color_white_g.value, 1, 5);y += 8; + M_ItemPrint(16, y, " White: Blue ", v_color_enable.integer);M_DrawSlider(220, y, v_color_white_b.value, 1, 5);y += 8; + M_ItemPrint(16, y, " White: Grey ", v_color_enable.integer);M_DrawSlider(220, y, (v_color_white_r.value + v_color_white_g.value + v_color_white_b.value) / 3, 1, 5);y += 8; + + y += 4; + DrawQ_Fill(menu_x, menu_y + y, 320, 4 + 64 + 8 + 64 + 4, 0, 0, 0, 1, 0);y += 4; + s = (float) 312 / 2 * vid.realwidth / vid.conwidth; + t = (float) 4 / 2 * vid.realheight / vid.conheight; + DrawQ_SuperPic(menu_x + 4, menu_y + y, "gfx/colorcontrol/ditherpattern.tga", 312, 4, 0,0, 1,0,0,1, s,0, 1,0,0,1, 0,t, 1,0,0,1, s,t, 1,0,0,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 1,0,0,1, 0,1, 0,0,0,1, 1,1, 1,0,0,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, "gfx/colorcontrol/ditherpattern.tga", 312, 4, 0,0, 0,1,0,1, s,0, 0,1,0,1, 0,t, 0,1,0,1, s,t, 0,1,0,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 0,1,0,1, 0,1, 0,0,0,1, 1,1, 0,1,0,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, "gfx/colorcontrol/ditherpattern.tga", 312, 4, 0,0, 0,0,1,1, s,0, 0,0,1,1, 0,t, 0,0,1,1, s,t, 0,0,1,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 0,0,1,1, 0,1, 0,0,0,1, 1,1, 0,0,1,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, "gfx/colorcontrol/ditherpattern.tga", 312, 4, 0,0, 1,1,1,1, s,0, 1,1,1,1, 0,t, 1,1,1,1, s,t, 1,1,1,1, 0);y += 4; + DrawQ_SuperPic(menu_x + 4, menu_y + y, NULL , 312, 4, 0,0, 0,0,0,1, 1,0, 1,1,1,1, 0,1, 0,0,0,1, 1,1, 1,1,1,1, 0);y += 4; + + c = menu_options_colorcontrol_correctionvalue.value; // intensity value that should be matched up to a 50% dither to 'correct' quake + s = (float) 48 / 2 * vid.realwidth / vid.conwidth; + t = (float) 48 / 2 * vid.realheight / vid.conheight; + u = s * 0.5; + v = t * 0.5; + y += 8; + x = 4; + DrawQ_Fill(menu_x + x, menu_y + y, 64, 48, c, 0, 0, 1, 0); + DrawQ_SuperPic(menu_x + x + 16, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 1,0,0,1, s,0, 1,0,0,1, 0,t, 1,0,0,1, s,t, 1,0,0,1, 0); + DrawQ_SuperPic(menu_x + x + 32, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 1,0,0,1, u,0, 1,0,0,1, 0,v, 1,0,0,1, u,v, 1,0,0,1, 0); + x += 80; + DrawQ_Fill(menu_x + x, menu_y + y, 64, 48, 0, c, 0, 1, 0); + DrawQ_SuperPic(menu_x + x + 16, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 0,1,0,1, s,0, 0,1,0,1, 0,t, 0,1,0,1, s,t, 0,1,0,1, 0); + DrawQ_SuperPic(menu_x + x + 32, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 0,1,0,1, u,0, 0,1,0,1, 0,v, 0,1,0,1, u,v, 0,1,0,1, 0); + x += 80; + DrawQ_Fill(menu_x + x, menu_y + y, 64, 48, 0, 0, c, 1, 0); + DrawQ_SuperPic(menu_x + x + 16, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 0,0,1,1, s,0, 0,0,1,1, 0,t, 0,0,1,1, s,t, 0,0,1,1, 0); + DrawQ_SuperPic(menu_x + x + 32, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 0,0,1,1, u,0, 0,0,1,1, 0,v, 0,0,1,1, u,v, 0,0,1,1, 0); + x += 80; + DrawQ_Fill(menu_x + x, menu_y + y, 64, 48, c, c, c, 1, 0); + DrawQ_SuperPic(menu_x + x + 16, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 1,1,1,1, s,0, 1,1,1,1, 0,t, 1,1,1,1, s,t, 1,1,1,1, 0); + DrawQ_SuperPic(menu_x + x + 32, menu_y + y + 16, "gfx/colorcontrol/ditherpattern.tga", 16, 16, 0,0, 1,1,1,1, u,0, 1,1,1,1, 0,v, 1,1,1,1, u,v, 1,1,1,1, 0); + + // cursor + M_DrawCharacter(200, 32 + options_colorcontrol_cursor*8, 12+((int)(realtime*4)&1)); +} + + +void M_Options_ColorControl_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_ENTER: + m_entersound = true; + switch (options_colorcontrol_cursor) + { + case 0: + Cvar_SetValueQuick(&v_hwgamma, 1); + Cvar_SetValueQuick(&v_gamma, 1); + Cvar_SetValueQuick(&v_contrast, 1); + Cvar_SetValueQuick(&v_brightness, 0); + Cvar_SetValueQuick(&v_color_enable, 0); + Cvar_SetValueQuick(&v_color_black_r, 0); + Cvar_SetValueQuick(&v_color_black_g, 0); + Cvar_SetValueQuick(&v_color_black_b, 0); + Cvar_SetValueQuick(&v_color_grey_r, 0); + Cvar_SetValueQuick(&v_color_grey_g, 0); + Cvar_SetValueQuick(&v_color_grey_b, 0); + Cvar_SetValueQuick(&v_color_white_r, 1); + Cvar_SetValueQuick(&v_color_white_g, 1); + Cvar_SetValueQuick(&v_color_white_b, 1); + Cbuf_AddText ("exec default.cfg\n"); + break; + default: + M_Menu_Options_ColorControl_AdjustSliders (1); + break; + } + return; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + options_colorcontrol_cursor--; + if (options_colorcontrol_cursor < 0) + options_colorcontrol_cursor = OPTIONS_COLORCONTROL_ITEMS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + options_colorcontrol_cursor++; + if (options_colorcontrol_cursor >= OPTIONS_COLORCONTROL_ITEMS) + options_colorcontrol_cursor = 0; + break; + + case K_LEFTARROW: + M_Menu_Options_ColorControl_AdjustSliders (-1); + break; + + case K_RIGHTARROW: + M_Menu_Options_ColorControl_AdjustSliders (1); + break; + } +} + + //============================================================================= /* KEYS MENU */ @@ -3308,6 +3543,8 @@ void M_Init (void) Cmd_AddCommand ("menu_setup", M_Menu_Setup_f); Cmd_AddCommand ("menu_options", M_Menu_Options_f); Cmd_AddCommand ("menu_options_effects", M_Menu_Options_Effects_f); + Cmd_AddCommand ("menu_options_colorcontrol", M_Menu_Options_ColorControl_f); + Cvar_RegisterVariable (&menu_options_colorcontrol_correctionvalue); Cmd_AddCommand ("menu_keys", M_Menu_Keys_f); Cmd_AddCommand ("menu_video", M_Menu_Video_f); Cmd_AddCommand ("help", M_Menu_Help_f); @@ -3407,6 +3644,10 @@ void M_Draw (void) M_Options_Effects_Draw (); break; + case m_options_colorcontrol: + M_Options_ColorControl_Draw (); + break; + case m_keys: M_Keys_Draw (); break; @@ -3497,6 +3738,10 @@ void M_Keydown (int key) M_Options_Effects_Key (key); return; + case m_options_colorcontrol: + M_Options_ColorControl_Key (key); + return; + case m_keys: M_Keys_Key (key); return; diff --git a/menu.h b/menu.h index 75b68d18..2031fb17 100644 --- a/menu.h +++ b/menu.h @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -47,7 +47,8 @@ enum m_state_e { m_gameoptions, m_search, m_slist, - m_options_effects + m_options_effects, + m_options_colorcontrol }; extern int m_activenet; diff --git a/palette.c b/palette.c index e6bf563c..b08118b8 100644 --- a/palette.c +++ b/palette.c @@ -13,12 +13,6 @@ unsigned int palette_font[256]; qbyte host_basepal[768]; -cvar_t v_gamma = {CVAR_SAVE, "v_gamma", "1"}; -cvar_t v_contrast = {CVAR_SAVE, "v_contrast", "1"}; -cvar_t v_brightness = {CVAR_SAVE, "v_brightness", "0"}; -cvar_t v_overbrightbits = {CVAR_SAVE, "v_overbrightbits", "0"}; -cvar_t v_hwgamma = {0, "v_hwgamma", "1"}; - void Palette_Setup8to24(void) { int i; @@ -171,62 +165,6 @@ void BuildGammaTable16(float prescale, float gamma, float scale, float base, uns } } -qboolean hardwaregammasupported = false; -void VID_UpdateGamma(qboolean force) -{ - static float cachegamma = -1, cachebrightness = -1, cachecontrast = -1; - static int cacheoverbrightbits = -1, cachehwgamma = -1; - - // LordHavoc: don't mess with gamma tables if running dedicated - if (cls.state == ca_dedicated) - return; - - if (!force - && v_gamma.value == cachegamma - && v_contrast.value == cachecontrast - && v_brightness.value == cachebrightness - && v_overbrightbits.integer == cacheoverbrightbits - && v_hwgamma.value == cachehwgamma) - return; - - if (v_gamma.value < 0.1) - Cvar_SetValue("v_gamma", 0.1); - if (v_gamma.value > 5.0) - Cvar_SetValue("v_gamma", 5.0); - - if (v_contrast.value < 0.5) - Cvar_SetValue("v_contrast", 0.5); - if (v_contrast.value > 5.0) - Cvar_SetValue("v_contrast", 5.0); - - if (v_brightness.value < 0) - Cvar_SetValue("v_brightness", 0); - if (v_brightness.value > 0.8) - Cvar_SetValue("v_brightness", 0.8); - - cachegamma = v_gamma.value; - cachecontrast = v_contrast.value; - cachebrightness = v_brightness.value; - cacheoverbrightbits = v_overbrightbits.integer; - - hardwaregammasupported = VID_SetGamma((float) (1 << cacheoverbrightbits), cachegamma, cachecontrast, cachebrightness); - if (!hardwaregammasupported) - { - Con_Printf("Hardware gamma not supported.\n"); - Cvar_SetValue("v_hwgamma", 0); - } - cachehwgamma = v_hwgamma.integer; -} - -void Gamma_Init(void) -{ - Cvar_RegisterVariable(&v_gamma); - Cvar_RegisterVariable(&v_brightness); - Cvar_RegisterVariable(&v_contrast); - Cvar_RegisterVariable(&v_hwgamma); - Cvar_RegisterVariable(&v_overbrightbits); -} - void Palette_Init(void) { int i; diff --git a/palette.h b/palette.h index a0e97a97..2824717a 100644 --- a/palette.h +++ b/palette.h @@ -2,12 +2,6 @@ #ifndef PALLETE_H #define PALLETE_H -extern cvar_t v_gamma; -extern cvar_t v_contrast; -extern cvar_t v_brightness; -extern cvar_t v_overbrightbits; -extern cvar_t v_hwgamma; - extern unsigned int palette_complete[256]; extern unsigned int palette_nofullbrights[256]; extern unsigned int palette_onlyfullbrights[256]; @@ -18,15 +12,10 @@ extern unsigned int palette_shirtaswhite[256]; extern unsigned int palette_alpha[256]; extern unsigned int palette_font[256]; -extern qboolean hardwaregammasupported; - -void VID_UpdateGamma(qboolean force); - // used by hardware gamma functions in vid_* files void BuildGammaTable8(float prescale, float gamma, float scale, float base, qbyte *out); void BuildGammaTable16(float prescale, float gamma, float scale, float base, unsigned short *out); -void Gamma_Init(void); void Palette_Init(void); #endif diff --git a/vid.h b/vid.h index fffadd1e..8ea82bbc 100644 --- a/vid.h +++ b/vid.h @@ -43,6 +43,9 @@ extern void (*vid_menukeyfn)(int key); extern int vid_hidden; extern int vid_activewindow; +extern int vid_allowhwgamma; +extern int vid_hardwaregammasupported; +extern int vid_usinghwgamma; extern cvar_t vid_fullscreen; extern cvar_t vid_width; @@ -51,6 +54,22 @@ extern cvar_t vid_bitsperpixel; extern cvar_t vid_mouse; extern cvar_t vid_stencil; +extern cvar_t v_gamma; +extern cvar_t v_contrast; +extern cvar_t v_brightness; +extern cvar_t v_color_enable; +extern cvar_t v_color_black_r; +extern cvar_t v_color_black_g; +extern cvar_t v_color_black_b; +extern cvar_t v_color_grey_r; +extern cvar_t v_color_grey_g; +extern cvar_t v_color_grey_b; +extern cvar_t v_color_white_r; +extern cvar_t v_color_white_g; +extern cvar_t v_color_white_b; +extern cvar_t v_overbrightbits; +extern cvar_t v_hwgamma; + extern int gl_stencil; // brand of graphics chip @@ -99,7 +118,13 @@ int VID_SetMode (int modenum); // sets hardware gamma correction, returns false if the device does not // support gamma control -int VID_SetGamma (float prescale, float gamma, float scale, float base); +int VID_SetGamma (unsigned short *ramps); +// gets hardware gamma correction, returns false if the device does not +// support gamma control +int VID_GetGamma (unsigned short *ramps); + +void VID_UpdateGamma(qboolean force); +void VID_RestoreSystemGamma(void); void VID_GetWindowSize (int *x, int *y, int *width, int *height); diff --git a/vid_glx.c b/vid_glx.c index fc4cdcb7..14c09ca4 100644 --- a/vid_glx.c +++ b/vid_glx.c @@ -71,7 +71,7 @@ static dllfunction_t videosyncfuncs[] = }; static Display *vidx11_display = NULL; -static int scrnum; +static int vidx11_screen; static Window win; static GLXContext ctx = NULL; @@ -381,7 +381,7 @@ static void HandleEvents(void) case 5: Key_Event(K_MWHEELDOWN, true); break; - default: + default: Con_Printf("HandleEvents: ButtonPress gave value %d, 1-5 expected\n", event.xbutton.button); break; } @@ -406,7 +406,7 @@ static void HandleEvents(void) case 5: Key_Event(K_MWHEELDOWN, false); break; - default: + default: Con_Printf("HandleEvents: ButtonRelease gave value %d, 1-5 expected\n", event.xbutton.button); break; } @@ -435,22 +435,31 @@ static void HandleEvents(void) case MapNotify: // window restored vid_hidden = false; + vid_allowhwgamma = true; break; case UnmapNotify: // window iconified/rolledup/whatever vid_hidden = true; + vid_allowhwgamma = false; + VID_RestoreSystemGamma(); break; case FocusIn: // window is now the input focus + vid_allowhwgamma = true; break; case FocusOut: // window is no longer the input focus + vid_allowhwgamma = false; + VID_RestoreSystemGamma(); break; case EnterNotify: // mouse entered window + vid_allowhwgamma = true; break; case LeaveNotify: // mouse left window + vid_allowhwgamma = false; + VID_RestoreSystemGamma(); break; } } @@ -490,7 +499,6 @@ static void IN_ActivateMouse( void ) } } - void VID_Shutdown(void) { if (!ctx || !vidx11_display) @@ -500,11 +508,12 @@ void VID_Shutdown(void) usingmouse = false; if (vidx11_display) { + VID_RestoreSystemGamma(); uninstall_grabs(); // FIXME: glXDestroyContext here? if (vidmode_active) - XF86VidModeSwitchToMode(vidx11_display, scrnum, vidmodes[0]); + XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, vidmodes[0]); if (win) XDestroyWindow(vidx11_display, win); XCloseDisplay(vidx11_display); @@ -520,6 +529,7 @@ void VID_Shutdown(void) void signal_handler(int sig) { printf("Received signal %d, exiting...\n", sig); + VID_RestoreSystemGamma(); Sys_Quit(); exit(0); } @@ -583,80 +593,14 @@ void VID_Finish (void) } } -// LordHavoc: ported from SDL 1.2.2, this was far more difficult to port from -// SDL than to simply use the XFree gamma ramp extension, but that affects the -// whole screen even when the game window is inactive, this only affects the -// screen while the window is active, very desirable behavior :) -int VID_SetGamma(float prescale, float gamma, float scale, float base) +int VID_SetGamma(unsigned short *ramps) { -// LordHavoc: FIXME: finish this code, we need to allocate colors before we can store them -#if 1 - return FALSE; -#else - int i, ncolors, c; - unsigned int Rmask, Gmask, Bmask, Rloss, Gloss, Bloss, Rshift, Gshift, Bshift, mask; - XColor xcmap[256]; - unsigned short ramp[256]; - - if (COM_CheckParm("-nogamma")) - return FALSE; - - if (vidx11_visual->class != DirectColor) - { - Con_Printf("X11 Visual class is %d, can only do gamma on %d\n", vidx11_visual->class, DirectColor); - return FALSE; - } - - Rmask = vidx11_visual->red_mask; - Gmask = vidx11_visual->green_mask; - Bmask = vidx11_visual->blue_mask; - - Rshift = 0; - Rloss = 8; - if ((mask = Rmask)) - { - for (;!(mask & 1);mask >>= 1) - ++Rshift; - for (;(mask & 1);mask >>= 1) - --Rloss; - } - Gshift = 0; - Gloss = 8; - if ((mask = Gmask)) - { - for (;!(mask & 1);mask >>= 1) - ++Gshift; - for (;(mask & 1);mask >>= 1) - --Gloss; - } - Bshift = 0; - Bloss = 8; - if ((mask = Bmask)) - { - for (;!(mask & 1);mask >>= 1) - ++Bshift; - for (;(mask & 1);mask >>= 1) - --Bloss; - } - - BuildGammaTable16(prescale, gamma, scale, base, ramp); + return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512); +} - // convert gamma ramp to palette (yes this seems odd) - ncolors = vidx11_visual->map_entries; - for (i = 0;i < ncolors;i++) - { - c = (256 * i / ncolors); - xcmap[i].pixel = ((c >> Rloss) << Rshift) | ((c >> Gloss) << Gshift) | ((c >> Bloss) << Bshift); - xcmap[i].red = ramp[c]; - xcmap[i].green = ramp[c]; - xcmap[i].blue = ramp[c]; - xcmap[i].flags = (DoRed|DoGreen|DoBlue); - } - XStoreColors(vidx11_display, vidx11_colormap, xcmap, ncolors); - XSync(vidx11_display, false); - // FIXME: should this check for BadAccess/BadColor/BadValue errors produced by XStoreColors before setting this true? - return TRUE; -#endif +int VID_GetGamma(unsigned short *ramps) +{ + return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, 256, ramps, ramps + 256, ramps + 512); } void VID_Init(void) @@ -668,7 +612,7 @@ void VID_Init(void) mouse_avail = false; } -void VID_BuildGLXAttrib(int *attrib, int stencil, int gamma) +void VID_BuildGLXAttrib(int *attrib, int stencil) { *attrib++ = GLX_RGBA; *attrib++ = GLX_RED_SIZE;*attrib++ = 1; @@ -682,10 +626,6 @@ void VID_BuildGLXAttrib(int *attrib, int stencil, int gamma) *attrib++ = GLX_STENCIL_SIZE;*attrib++ = 8; *attrib++ = GLX_ALPHA_SIZE;*attrib++ = 1; } - if (gamma) - { - *attrib++ = GLX_X_VISUAL_TYPE;*attrib++ = GLX_DIRECT_COLOR; - }; *attrib++ = None; } @@ -716,8 +656,8 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int stencil) return false; } - scrnum = DefaultScreen(vidx11_display); - root = RootWindow(vidx11_display, scrnum); + vidx11_screen = DefaultScreen(vidx11_display); + root = RootWindow(vidx11_display, vidx11_screen); // Get video mode list MajorVersion = MinorVersion = 0; @@ -739,35 +679,22 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int stencil) return false; } - visinfo = NULL; -// LordHavoc: FIXME: finish this code, we need to allocate colors before we can store them -#if 0 - if (!COM_CheckParm("-nogamma")) - { - VID_BuildGLXAttrib(attrib, stencil, true); - visinfo = qglXChooseVisual(vidx11_display, scrnum, attrib); - } -#endif + VID_BuildGLXAttrib(attrib, stencil); + visinfo = qglXChooseVisual(vidx11_display, vidx11_screen, attrib); if (!visinfo) { - VID_BuildGLXAttrib(attrib, stencil, false); - visinfo = qglXChooseVisual(vidx11_display, scrnum, attrib); - if (!visinfo) - { - Con_Printf("Couldn't get an RGB, Double-buffered, Depth visual\n"); - return false; - } + Con_Printf("Couldn't get an RGB, Double-buffered, Depth visual\n"); + return false; } if (vidmode_ext) { int best_fit, best_dist, dist, x, y; - XF86VidModeGetAllModeLines(vidx11_display, scrnum, &num_vidmodes, &vidmodes); - // Are we going fullscreen? If so, let's change video mode if (fullscreen) { + XF86VidModeGetAllModeLines(vidx11_display, vidx11_screen, &num_vidmodes, &vidmodes); best_dist = 9999999; best_fit = -1; @@ -795,11 +722,11 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int stencil) height = vidmodes[best_fit]->vdisplay; // change to the mode - XF86VidModeSwitchToMode(vidx11_display, scrnum, vidmodes[best_fit]); + XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, vidmodes[best_fit]); vidmode_active = true; // Move the viewport to top left - XF86VidModeSetViewPort(vidx11_display, scrnum, 0, 0); + XF86VidModeSetViewPort(vidx11_display, vidx11_screen, 0, 0); } else fullscreen = 0; @@ -841,7 +768,7 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int stencil) XWarpPointer(vidx11_display, None, win, 0, 0, 0, 0, 0, 0); XFlush(vidx11_display); // Move the viewport to top left - XF86VidModeSetViewPort(vidx11_display, scrnum, 0, 0); + XF86VidModeSetViewPort(vidx11_display, vidx11_screen, 0, 0); } //XSync(vidx11_display, False); @@ -866,13 +793,14 @@ int VID_InitMode(int fullscreen, int width, int height, int bpp, int stencil) gl_version = qglGetString(GL_VERSION); gl_extensions = qglGetString(GL_EXTENSIONS); gl_platform = "GLX"; - gl_platformextensions = qglXQueryExtensionsString(vidx11_display, scrnum); + gl_platformextensions = qglXQueryExtensionsString(vidx11_display, vidx11_screen); GL_CheckExtension("GLX_ARB_get_proc_address", getprocaddressfuncs, "-nogetprocaddress", false); gl_videosyncavailable = GL_CheckExtension("GLX_SGI_video_sync", videosyncfuncs, "-novideosync", false); usingmouse = false; vid_hidden = false; + vid_allowhwgamma = true; GL_Init(); return true; } diff --git a/vid_null.c b/vid_null.c index 2b232f56..77ed527a 100644 --- a/vid_null.c +++ b/vid_null.c @@ -58,7 +58,12 @@ void VID_Finish (void) { } -int VID_SetGamma(float prescale, float gamma, float scale, float base) +int VID_SetGamma(unsigned short *ramps) +{ + return FALSE; +} + +int VID_GetGamma(unsigned short *ramps) { return FALSE; } diff --git a/vid_shared.c b/vid_shared.c index 2260f240..37f2444b 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -32,6 +32,16 @@ int vid_hidden = true; // LordHavoc: if window is not the active window, don't hog as much CPU time, // let go of the mouse, turn off sound, and restore system gamma ramps... int vid_activewindow = true; +// LordHavoc: whether to allow use of hwgamma (disabled when window is inactive) +int vid_allowhwgamma = false; + +// we don't know until we try it! +int vid_hardwaregammasupported = true; +// whether hardware gamma ramps are currently in effect +int vid_usinghwgamma = false; + +unsigned short vid_gammaramps[768]; +unsigned short vid_systemgammaramps[768]; cvar_t vid_fullscreen = {CVAR_SAVE, "vid_fullscreen", "1"}; cvar_t vid_width = {CVAR_SAVE, "vid_width", "640"}; @@ -47,6 +57,22 @@ cvar_t in_pitch_max = {0, "in_pitch_max", "80"}; cvar_t m_filter = {CVAR_SAVE, "m_filter","0"}; +cvar_t v_gamma = {CVAR_SAVE, "v_gamma", "1"}; +cvar_t v_contrast = {CVAR_SAVE, "v_contrast", "1"}; +cvar_t v_brightness = {CVAR_SAVE, "v_brightness", "0"}; +cvar_t v_color_enable = {CVAR_SAVE, "v_color_enable", "0"}; +cvar_t v_color_black_r = {CVAR_SAVE, "v_color_black_r", "0"}; +cvar_t v_color_black_g = {CVAR_SAVE, "v_color_black_g", "0"}; +cvar_t v_color_black_b = {CVAR_SAVE, "v_color_black_b", "0"}; +cvar_t v_color_grey_r = {CVAR_SAVE, "v_color_grey_r", "0.5"}; +cvar_t v_color_grey_g = {CVAR_SAVE, "v_color_grey_g", "0.5"}; +cvar_t v_color_grey_b = {CVAR_SAVE, "v_color_grey_b", "0.5"}; +cvar_t v_color_white_r = {CVAR_SAVE, "v_color_white_r", "1"}; +cvar_t v_color_white_g = {CVAR_SAVE, "v_color_white_g", "1"}; +cvar_t v_color_white_b = {CVAR_SAVE, "v_color_white_b", "1"}; +cvar_t v_overbrightbits = {CVAR_SAVE, "v_overbrightbits", "0"}; +cvar_t v_hwgamma = {0, "v_hwgamma", "1"}; + // brand of graphics chip const char *gl_vendor; // graphics chip model and other information @@ -449,8 +475,114 @@ void IN_Mouse(usercmd_t *cmd, float mx, float my) } } +static float cachegamma, cachebrightness, cachecontrast, cacheblack[3], cachegrey[3], cachewhite[3]; +static int cacheoverbrightbits = -1, cachecolorenable, cachehwgamma; +#define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f); +void VID_UpdateGamma(qboolean force) +{ + cvar_t *c; + float f; + + // LordHavoc: don't mess with gamma tables if running dedicated + if (cls.state == ca_dedicated) + return; + + if (!force + && vid_usinghwgamma == (vid_allowhwgamma && v_hwgamma.integer) + && v_overbrightbits.integer == cacheoverbrightbits + && v_gamma.value == cachegamma + && v_contrast.value == cachecontrast + && v_brightness.value == cachebrightness + && cachecolorenable == v_color_enable.integer + && cacheblack[0] == v_color_black_r.value + && cacheblack[1] == v_color_black_g.value + && cacheblack[2] == v_color_black_b.value + && cachegrey[0] == v_color_grey_r.value + && cachegrey[1] == v_color_grey_g.value + && cachegrey[2] == v_color_grey_b.value + && cachewhite[0] == v_color_white_r.value + && cachewhite[1] == v_color_white_g.value + && cachewhite[2] == v_color_white_b.value) + return; + + if (vid_allowhwgamma && v_hwgamma.integer) + { + if (!vid_usinghwgamma) + { + vid_usinghwgamma = true; + vid_hardwaregammasupported = VID_GetGamma(vid_systemgammaramps); + } + + BOUNDCVAR(v_gamma, 0.1, 5);cachegamma = v_gamma.value; + BOUNDCVAR(v_contrast, 1, 5);cachecontrast = v_contrast.value; + BOUNDCVAR(v_brightness, 0, 0.8);cachebrightness = v_brightness.value; + BOUNDCVAR(v_color_black_r, 0, 0.8);cacheblack[0] = v_color_black_r.value; + BOUNDCVAR(v_color_black_g, 0, 0.8);cacheblack[1] = v_color_black_g.value; + BOUNDCVAR(v_color_black_b, 0, 0.8);cacheblack[2] = v_color_black_b.value; + BOUNDCVAR(v_color_grey_r, 0, 0.95);cachegrey[0] = v_color_grey_r.value; + BOUNDCVAR(v_color_grey_g, 0, 0.95);cachegrey[1] = v_color_grey_g.value; + BOUNDCVAR(v_color_grey_b, 0, 0.95);cachegrey[2] = v_color_grey_b.value; + BOUNDCVAR(v_color_white_r, 1, 5);cachewhite[0] = v_color_white_r.value; + BOUNDCVAR(v_color_white_g, 1, 5);cachewhite[1] = v_color_white_g.value; + BOUNDCVAR(v_color_white_b, 1, 5);cachewhite[2] = v_color_white_b.value; + cachecolorenable = v_color_enable.integer; + cacheoverbrightbits = v_overbrightbits.integer; + cachehwgamma = v_hwgamma.integer; + + if (cachecolorenable) + { + BuildGammaTable16((float) (1 << cacheoverbrightbits), invpow(0.5, 1 - cachegrey[0]), cachewhite[0], cacheblack[0], vid_gammaramps); + BuildGammaTable16((float) (1 << cacheoverbrightbits), invpow(0.5, 1 - cachegrey[1]), cachewhite[1], cacheblack[1], vid_gammaramps + 256); + BuildGammaTable16((float) (1 << cacheoverbrightbits), invpow(0.5, 1 - cachegrey[2]), cachewhite[2], cacheblack[2], vid_gammaramps + 512); + } + else + { + BuildGammaTable16((float) (1 << cacheoverbrightbits), cachegamma, cachecontrast, cachebrightness, vid_gammaramps); + BuildGammaTable16((float) (1 << cacheoverbrightbits), cachegamma, cachecontrast, cachebrightness, vid_gammaramps + 256); + BuildGammaTable16((float) (1 << cacheoverbrightbits), cachegamma, cachecontrast, cachebrightness, vid_gammaramps + 512); + } + + vid_hardwaregammasupported = VID_SetGamma(vid_gammaramps); + } + else + { + if (vid_usinghwgamma) + { + vid_usinghwgamma = false; + vid_hardwaregammasupported = VID_SetGamma(vid_systemgammaramps); + } + } +} + +void VID_RestoreSystemGamma(void) +{ + if (vid_usinghwgamma) + { + vid_usinghwgamma = false; + VID_SetGamma(vid_systemgammaramps); + } +} + void VID_Shared_Init(void) { + Cvar_RegisterVariable(&v_gamma); + Cvar_RegisterVariable(&v_brightness); + Cvar_RegisterVariable(&v_contrast); + + Cvar_RegisterVariable(&v_color_enable); + Cvar_RegisterVariable(&v_color_black_r); + Cvar_RegisterVariable(&v_color_black_g); + Cvar_RegisterVariable(&v_color_black_b); + Cvar_RegisterVariable(&v_color_grey_r); + Cvar_RegisterVariable(&v_color_grey_g); + Cvar_RegisterVariable(&v_color_grey_b); + Cvar_RegisterVariable(&v_color_white_r); + Cvar_RegisterVariable(&v_color_white_g); + Cvar_RegisterVariable(&v_color_white_b); + + Cvar_RegisterVariable(&v_hwgamma); + Cvar_RegisterVariable(&v_overbrightbits); + Cvar_RegisterVariable(&vid_fullscreen); Cvar_RegisterVariable(&vid_width); Cvar_RegisterVariable(&vid_height); diff --git a/vid_wgl.c b/vid_wgl.c index 97a889f8..36787132 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -62,10 +62,6 @@ static dllfunction_t wglswapintervalfuncs[] = {NULL, NULL} }; -void VID_RestoreGameGamma(void); -void VID_GetSystemGamma(void); -void VID_RestoreSystemGamma(void); - qboolean scr_skipupdate; static DEVMODE gdevmode; @@ -427,7 +423,6 @@ void ClearAllStates (void) IN_ClearStates (); } -void VID_RestoreGameGamma(void); extern qboolean host_loopactive; void AppActivate(BOOL fActive, BOOL minimize) @@ -461,6 +456,7 @@ void AppActivate(BOOL fActive, BOOL minimize) if (fActive) { + vid_allowhwgamma = true; if (vid_isfullscreen) { if (vid_wassuspended) @@ -473,12 +469,11 @@ void AppActivate(BOOL fActive, BOOL minimize) // LordHavoc: from dabb, fix for alt-tab bug in NVidia drivers MoveWindow(mainwindow,0,0,gdevmode.dmPelsWidth,gdevmode.dmPelsHeight,false); } - if (host_loopactive) - VID_RestoreGameGamma(); } if (!fActive) { + vid_allowhwgamma = false; vid_usingmouse = false; IN_DeactivateMouse (); IN_ShowMouse (); @@ -607,52 +602,22 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return lRet; } - -//static int grabsysgamma = true; -WORD systemgammaramps[3][256], currentgammaramps[3][256]; - -int VID_SetGamma(float prescale, float gamma, float scale, float base) +int VID_SetGamma(unsigned short *ramps) { - int i; - HDC hdc; - hdc = GetDC (NULL); - - BuildGammaTable16(prescale, gamma, scale, base, ¤tgammaramps[0][0]); - for (i = 0;i < 256;i++) - currentgammaramps[1][i] = currentgammaramps[2][i] = currentgammaramps[0][i]; - - i = SetDeviceGammaRamp(hdc, ¤tgammaramps[0][0]); - + HDC hdc = GetDC (NULL); + int i = SetDeviceGammaRamp(hdc, ramps); ReleaseDC (NULL, hdc); return i; // return success or failure } -void VID_RestoreGameGamma(void) -{ - VID_UpdateGamma(true); -} - -void VID_GetSystemGamma(void) +int VID_GetGamma(unsigned short *ramps) { - HDC hdc; - hdc = GetDC (NULL); - - GetDeviceGammaRamp(hdc, &systemgammaramps[0][0]); - - ReleaseDC (NULL, hdc); -} - -void VID_RestoreSystemGamma(void) -{ - HDC hdc; - hdc = GetDC (NULL); - - SetDeviceGammaRamp(hdc, &systemgammaramps[0][0]); - + HDC hdc = GetDC (NULL); + int i = GetDeviceGammaRamp(hdc, ramps); ReleaseDC (NULL, hdc); + return i; // return success or failure } - static HINSTANCE gldll; int GL_OpenLibrary(const char *name) @@ -775,8 +740,6 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int stencil) memset(&gdevmode, 0, sizeof(gdevmode)); - VID_GetSystemGamma(); - vid_isfullscreen = false; if (fullscreen) { @@ -884,7 +847,7 @@ int VID_InitMode (int fullscreen, int width, int height, int bpp, int stencil) // fix the leftover Alt from any Alt-Tab or the like that switched us away ClearAllStates (); - + hdc = GetDC(mainwindow); if ((pixelformat = ChoosePixelFormat(hdc, &pfd)) == 0) @@ -971,6 +934,8 @@ void VID_Shutdown (void) HGLRC hRC = 0; HDC hDC = 0; + VID_RestoreSystemGamma(); + vid_initialized = false; IN_Shutdown(); if (qwglGetCurrentContext) @@ -989,7 +954,6 @@ void VID_Shutdown (void) ChangeDisplaySettings (NULL, 0); vid_isfullscreen = false; AppActivate(false, false); - VID_RestoreSystemGamma(); if (mainwindow) DestroyWindow(mainwindow); mainwindow = 0; @@ -1132,7 +1096,7 @@ qboolean IN_InitDInput (void) if (!hInstDI) { hInstDI = LoadLibrary("dinput.dll"); - + if (hInstDI == NULL) { Con_SafePrintf ("Couldn't load dinput.dll\n"); @@ -1209,7 +1173,7 @@ IN_StartupMouse */ void IN_StartupMouse (void) { - if (COM_CheckParm ("-nomouse") || COM_CheckParm("-safe")) + if (COM_CheckParm ("-nomouse") || COM_CheckParm("-safe")) return; mouseinitialized = true; @@ -1234,16 +1198,16 @@ void IN_StartupMouse (void) if (mouseparmsvalid) { - if ( COM_CheckParm ("-noforcemspd") ) + if ( COM_CheckParm ("-noforcemspd") ) newmouseparms[2] = originalmouseparms[2]; - if ( COM_CheckParm ("-noforcemaccel") ) + if ( COM_CheckParm ("-noforcemaccel") ) { newmouseparms[0] = originalmouseparms[0]; newmouseparms[1] = originalmouseparms[1]; } - if ( COM_CheckParm ("-noforcemparms") ) + if ( COM_CheckParm ("-noforcemparms") ) { newmouseparms[0] = originalmouseparms[0]; newmouseparms[1] = originalmouseparms[1]; @@ -1286,8 +1250,8 @@ void IN_MouseEvent (int mstate) { Key_Event (K_MOUSE1 + i, false); } - } - + } + mouse_oldbuttonstate = mstate; } } @@ -1459,25 +1423,25 @@ void IN_ClearStates (void) } -/* -=============== -IN_StartupJoystick +/* +=============== +IN_StartupJoystick =============== -*/ -void IN_StartupJoystick (void) +*/ +void IN_StartupJoystick (void) { int numdevs; JOYCAPS jc; MMRESULT mmr; mmr = 0; - + // assume no joystick - joy_avail = false; + joy_avail = false; // abort startup if user requests no joystick - if (COM_CheckParm ("-nojoy") || COM_CheckParm("-safe")) - return; - + if (COM_CheckParm ("-nojoy") || COM_CheckParm("-safe")) + return; + // verify joystick driver is present if ((numdevs = joyGetNumDevs ()) == 0) { @@ -1494,7 +1458,7 @@ void IN_StartupJoystick (void) if ((mmr = joyGetPosEx (joy_id, &ji)) == JOYERR_NOERROR) break; - } + } // abort startup if we didn't find a valid joystick if (mmr != JOYERR_NOERROR) @@ -1508,7 +1472,7 @@ void IN_StartupJoystick (void) memset (&jc, 0, sizeof(jc)); if ((mmr = joyGetDevCaps (joy_id, &jc, sizeof(jc))) != JOYERR_NOERROR) { - Con_Printf ("\njoystick not found -- invalid joystick capabilities (%x)\n\n", mmr); + Con_Printf ("\njoystick not found -- invalid joystick capabilities (%x)\n\n", mmr); return; } @@ -1522,10 +1486,10 @@ void IN_StartupJoystick (void) // mark the joystick as available and advanced initialization not completed // this is needed as cvars are not available during initialization - joy_avail = true; + joy_avail = true; joy_advancedinit = false; - Con_Printf ("\njoystick detected\n\n"); + Con_Printf ("\njoystick detected\n\n"); } @@ -1697,11 +1661,11 @@ void IN_Commands (void) } -/* -=============== +/* +=============== IN_ReadJoystick -=============== -*/ +=============== +*/ qboolean IN_ReadJoystick (void) { @@ -1752,7 +1716,7 @@ void IN_JoyMove (usercmd_t *cmd) // verify joystick is available and that the user wants to use it if (!joy_avail || !in_joystick.integer) { - return; + return; } // collect the joystick data, if possible @@ -1792,7 +1756,7 @@ void IN_JoyMove (usercmd_t *cmd) } } - // convert range from -32768..32767 to -1..1 + // convert range from -32768..32767 to -1..1 fAxisValue /= 32768.0; switch (dwAxisMap[i]) @@ -1802,7 +1766,7 @@ void IN_JoyMove (usercmd_t *cmd) { // user wants forward control to become look control if (fabs(fAxisValue) > joy_pitchthreshold.value) - { + { // if mouse invert is on, invert the joystick pitch value // only absolute control support here (joy_advanced is false) if (m_pitch.value < 0.0)