diff --git a/src/hardware/hw_main.cpp b/src/hardware/hw_main.cpp index 09a1686c0..eb7378bee 100644 --- a/src/hardware/hw_main.cpp +++ b/src/hardware/hw_main.cpp @@ -458,8 +458,8 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col // in palette rendering mode, this is not needed since it properly takes the changes to the palette itself if (!HWR_ShouldUsePaletteRendering()) { - V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue); - V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue); + V_CubeApply(&tint_color); + V_CubeApply(&fade_color); } Surface->PolyColor.rgba = poly_color.rgba; @@ -5958,7 +5958,7 @@ static void HWR_DoPostProcessor(player_t *player) Surf.PolyColor.s.alpha = 0xc0; // match software mode - V_CubeApply(&Surf.PolyColor.s.red, &Surf.PolyColor.s.green, &Surf.PolyColor.s.blue); + V_CubeApply(&Surf.PolyColor); GL_DrawPolygon(&Surf, v, 4, PF_Modulated|PF_Translucent|PF_NoTexture|PF_NoDepthTest); } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9f5fc2c2b..911f382a9 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -417,7 +417,7 @@ static void md2_loadTexture(md2_t *model) size = w*h; while (size--) { - V_CubeApply(&image->s.red, &image->s.green, &image->s.blue); + V_CubeApply(image); image++; } } diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 8ec8e2cd1..1ec40e621 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -818,26 +818,31 @@ static menuitem_t OP_VideoOptionsMenu[] = #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 20}, #endif +#ifdef BACKWARDSCOMPATCORRECTION {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Brightness", &cv_globalgamma, 30}, - - {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Saturation", &cv_globalsaturation , 40}, - - {IT_SUBMENU|IT_STRING, NULL, "Advanced Color Settings...", &OP_ColorOptionsDef, 50}, - - {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 65}, - {IT_STRING | IT_CVAR, NULL, "Weather Draw Distance", &cv_drawdist_precip, 75}, - - {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 95}, - {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 105}, - {IT_STRING | IT_CVAR, NULL, "FPS Cap", &cv_fpscap, 115}, - {IT_STRING | IT_CVAR, NULL, "Drift spark pulse size", &cv_driftsparkpulse, 125}, - {IT_STRING | IT_CVAR, NULL, "VHS effect", &cv_vhseffect, 135}, -#ifdef HWRENDER - {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 145}, + NULL, "Gamma", &cv_globalgamma, 30}, #endif - {IT_SUBMENU|IT_STRING, NULL, "Advanced Video Options...", &OP_ExpOptionsDef, 155}, + + {IT_STRING | IT_CVAR | IT_CV_SLIDER, + NULL, "Brightness", &cv_globalbrightness, 40}, + + {IT_STRING | IT_CVAR | IT_CV_SLIDER, + NULL, "Saturation", &cv_globalsaturation , 50}, + + {IT_SUBMENU|IT_STRING, NULL, "Advanced Color Settings...", &OP_ColorOptionsDef, 60}, + + {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 75}, + {IT_STRING | IT_CVAR, NULL, "Weather Draw Distance", &cv_drawdist_precip, 85}, + + {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 105}, + {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 115}, + {IT_STRING | IT_CVAR, NULL, "FPS Cap", &cv_fpscap, 125}, + {IT_STRING | IT_CVAR, NULL, "Drift spark pulse size", &cv_driftsparkpulse, 135}, + {IT_STRING | IT_CVAR, NULL, "VHS effect", &cv_vhseffect, 145}, +#ifdef HWRENDER + {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 155}, +#endif + {IT_SUBMENU|IT_STRING, NULL, "Advanced Video Options...", &OP_ExpOptionsDef, 165}, }; static const char* OP_VideoTooltips[] = @@ -846,11 +851,12 @@ static const char* OP_VideoTooltips[] = #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) "Enable fullscreen.", #endif - "Gamma (brightness) of the game.", - "Saturation of the game.", + "Increase the gamma of the displayed image.", + "Increase or decrease the brightness of the displayed image.", + "Reduce the saturation of the displayed image.", "Advanced color settings of the game.", - "How far away objects are drawn.", - "How far away weather is drawn.", + "How far objects can be drawn.", + "Affects how far weather visuals can be drawn.", "Show current game framerate and select the style.", "Sync game framerate to refresh rate of monitor.", "Set manual framerate cap.", @@ -869,7 +875,10 @@ enum #if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL) op_video_fullscreen, #endif +#ifdef BACKWARDSCOMPATCORRECTION op_video_gamma, +#endif + op_video_bright, op_video_sat, op_video_color, op_video_dd, @@ -898,37 +907,37 @@ static menuitem_t OP_ColorOptionsMenu[] = {IT_DISABLED, NULL, NULL, NULL, 35}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_rhue, 15}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_rsaturation, 20}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_rgamma, 25}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_rbrightness, 25}, {IT_HEADER, NULL, "Yellow", NULL, 34}, {IT_DISABLED, NULL, NULL, NULL, 73}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_yhue, 40}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_ysaturation, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_ygamma, 50}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_ybrightness, 50}, {IT_HEADER, NULL, "Green", NULL, 59}, {IT_DISABLED, NULL, NULL, NULL, 112}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_ghue, 65}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_gsaturation, 70}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_ggamma, 75}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_gbrightness, 75}, {IT_HEADER, NULL, "Cyan", NULL, 84}, {IT_DISABLED, NULL, NULL, NULL, 255}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_chue, 90}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_csaturation, 95}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_cgamma, 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_cbrightness, 100}, {IT_HEADER, NULL, "Blue", NULL, 109}, {IT_DISABLED, NULL, NULL, NULL, 152}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_bhue, 115}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_bsaturation, 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_bgamma, 125}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_bbrightness, 125}, {IT_HEADER, NULL, "Magenta", NULL, 134}, {IT_DISABLED, NULL, NULL, NULL, 181}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Hue", &cv_mhue, 140}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Saturation", &cv_msaturation, 145}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_mgamma, 150}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness", &cv_mbrightness, 150}, }; static menuitem_t OP_ExpOptionsMenu[] = diff --git a/src/r_draw.cpp b/src/r_draw.cpp index a1bbbbc96..c2b0f9e28 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -113,6 +113,7 @@ CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; struct GenerateBlendTables_State { RGBA_t *LocalPalette; + RGBA_t *gammaCorrectedPalette; }; static void R_GenerateBlendTables_Core(struct GenerateBlendTables_State *state); @@ -126,6 +127,7 @@ static void R_GenerateBlendTables_Thread(void *userdata) R_GenerateBlendTables_Core(state); free(state->LocalPalette); + free(state->gammaCorrectedPalette); free(state); } #endif @@ -154,26 +156,33 @@ void R_InitTranslucencyTables(void) } static colorlookup_t transtab_lut; +static colorlookup_t transtab_lut_corrected; static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt) { INT16 bg, fg; + RGBA_t backrgba, frontrgba, result; if (table == NULL) I_Error("BlendTab_Translucent: input table was NULL!"); for (bg = 0; bg < 0x100; bg++) { + backrgba = pGammaCorrectedPalette[bg]; + for (fg = 0; fg < 0x100; fg++) { - RGBA_t backrgba = V_GetColor(bg); - RGBA_t frontrgba = V_GetColor(fg); - RGBA_t result; + frontrgba = pGammaCorrectedPalette[fg]; +#if 0 // perfect implementation result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF); result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt); - table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue); +#else // performance scrabbler + result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF); + result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt); + table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut_corrected, result.s.red, result.s.green, result.s.blue); // pGammaCorrectedPalette +#endif } } } @@ -224,7 +233,7 @@ static void BlendTab_Modulative(UINT8 *table) RGBA_t frontrgba = V_GetColor(fg); RGBA_t result; result.rgba = ASTBlendPixel(backrgba, frontrgba, AST_MODULATE, 0); - table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue); + table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut_corrected, result.s.red, result.s.green, result.s.blue); } } } @@ -278,11 +287,12 @@ void R_GenerateBlendTables(void) size_t palsize = 256 * sizeof(RGBA_t); state->LocalPalette = static_cast(memcpy(malloc(palsize), pLocalPalette, palsize)); + state->gammaCorrectedPalette = static_cast(memcpy(malloc(palsize), pGammaCorrectedPalette, palsize)); I_spawn_thread("blend-tables", R_GenerateBlendTables_Thread, state); #else - struct GenerateBlendTables_State state = {pLocalPalette}; + struct GenerateBlendTables_State state = {pLocalPalette, pGammaCorrectedPalette}; R_GenerateBlendTables_Core(&state); #endif } @@ -290,6 +300,7 @@ void R_GenerateBlendTables(void) static void R_GenerateBlendTables_Core(struct GenerateBlendTables_State *state) { InitColorLUT(&transtab_lut, state->LocalPalette, false); + InitColorLUT(&transtab_lut_corrected, state->gammaCorrectedPalette, false); // Additive BlendTab_GenerateMaps(blendtab_add, AST_ADD, BlendTab_Translucent); diff --git a/src/screen.c b/src/screen.c index 4a38ef97d..cae7d2479 100644 --- a/src/screen.c +++ b/src/screen.c @@ -215,7 +215,10 @@ void SCR_Startup(void) CV_RegisterVar(&cv_menucaps); CV_RegisterVar(&cv_constextsize); +#ifdef BACKWARDSCOMPATCORRECTION CV_RegisterVar(&cv_globalgamma); +#endif + CV_RegisterVar(&cv_globalbrightness); CV_RegisterVar(&cv_globalsaturation); CV_RegisterVar(&cv_rhue); @@ -225,12 +228,12 @@ void SCR_Startup(void) CV_RegisterVar(&cv_bhue); CV_RegisterVar(&cv_mhue); - CV_RegisterVar(&cv_rgamma); - CV_RegisterVar(&cv_ygamma); - CV_RegisterVar(&cv_ggamma); - CV_RegisterVar(&cv_cgamma); - CV_RegisterVar(&cv_bgamma); - CV_RegisterVar(&cv_mgamma); + CV_RegisterVar(&cv_rbrightness); + CV_RegisterVar(&cv_ybrightness); + CV_RegisterVar(&cv_gbrightness); + CV_RegisterVar(&cv_cbrightness); + CV_RegisterVar(&cv_bbrightness); + CV_RegisterVar(&cv_mbrightness); CV_RegisterVar(&cv_rsaturation); CV_RegisterVar(&cv_ysaturation); diff --git a/src/v_video.c b/src/v_video.c index c26d8c9bd..20c98c154 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -42,8 +42,13 @@ static void CV_palette_OnChange(void); consvar_t cv_palette = {"palette", "", CV_CALL|CV_NOINIT, NULL, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_palettenum = {"palettenum", "0", CV_CALL|CV_NOINIT, CV_Unsigned, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t gamma_cons_t[] = {{-15, "MIN"}, {4, "MAX"}, {0, NULL}}; +#ifdef BACKWARDSCOMPATCORRECTION +static CV_PossibleValue_t gamma_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}}; consvar_t cv_globalgamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +#endif + +static CV_PossibleValue_t brightness_cons_t[] = {{-15, "MIN"}, {5, "MAX"}, {0, NULL}}; +consvar_t cv_globalbrightness = {"brightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_globalsaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -58,12 +63,12 @@ consvar_t cv_chue = {"chue", "12", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnCha consvar_t cv_bhue = {"bhue", "16", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_mhue = {"mhue", "20", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_rgamma = {"rgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_ygamma = {"ygamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_ggamma = {"ggamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cgamma = {"cgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_bgamma = {"bgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_mgamma = {"mgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_rbrightness = {"rbrightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ybrightness = {"ybrightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gbrightness = {"gbrightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cbrightness = {"cbrightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bbrightness = {"bbrightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_mbrightness = {"mbrightness", "0", CV_SAVE|CV_CALL, brightness_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rsaturation = {"rsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_ysaturation = {"ysaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -84,6 +89,7 @@ consvar_t cv_menucaps = {"menucaps", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NUL // local copy of the palette for V_GetColor() RGBA_t *pLocalPalette = NULL; +RGBA_t *pGammaCorrectedPalette = NULL; static size_t currentPaletteSize; @@ -127,100 +133,97 @@ static boolean InitCube(void) }; float desatur[3]; // grey - float globalgammamul, globalgammaoffs; - boolean doinggamma; + float globalbrightnessmul, globalbrightnessoffs; + boolean doingbrightness; if (!loaded_config) return false; #define diffcons(cv) (!fastcmp(cv.string, cv.defaultvalue)) -#define diffconsgamma(cv) (cv.value != 0) +#define diffconsbrightness(cv) (cv.value != 0) + #define diffconssat(cv) (cv.value != 10) -#ifdef BACKWARDSCOMPATCORRECTION - doinggamma = (cv_globalgamma.value < 0); //dont mess up gamma when raising brightness pls -#else - doinggamma = diffcons(cv_globalgamma); -#endif + doingbrightness = diffcons(cv_globalbrightness); -#define gammascale 8 - globalgammamul = (cv_globalgamma.value ? ((255.0f - (gammascale*abs(cv_globalgamma.value))) / 255.0f) : 1.0f); - globalgammaoffs = ((cv_globalgamma.value > 0) ? ((gammascale*cv_globalgamma.value) / 255.0f) : 0.0f); - desatur[0] = desatur[1] = desatur[2] = globalgammaoffs + (0.33f * globalgammamul); +#define brightnessscale 8 + globalbrightnessmul = (cv_globalbrightness.value ? ((255.0f - (brightnessscale*abs(cv_globalbrightness.value))) / 255.0f) : 1.0f); + globalbrightnessoffs = ((cv_globalbrightness.value > 0) ? ((brightnessscale*cv_globalbrightness.value) / 255.0f) : 0.0f); + desatur[0] = desatur[1] = desatur[2] = globalbrightnessoffs + (0.33f * globalbrightnessmul); - if (doinggamma + if (doingbrightness || diffcons(cv_rhue) || diffcons(cv_yhue) || diffcons(cv_ghue) || diffcons(cv_chue) || diffcons(cv_bhue) || diffcons(cv_mhue) - || diffconsgamma(cv_rgamma) - || diffconsgamma(cv_ygamma) - || diffconsgamma(cv_ggamma) - || diffconsgamma(cv_cgamma) - || diffconsgamma(cv_bgamma) - || diffconsgamma(cv_mgamma)) // set the gamma'd/hued positions (saturation is done later) + || diffconsbrightness(cv_rbrightness) + || diffconsbrightness(cv_ybrightness) + || diffconsbrightness(cv_gbrightness) + || diffconsbrightness(cv_cbrightness) + || diffconsbrightness(cv_bbrightness) + || diffconsbrightness(cv_mbrightness)) // set the brightness'd/hued positions (saturation is done later) { - float mod, tempgammamul, tempgammaoffs; + float mod, tempbrightnessmul, tempbrightnessoffs; apply = true; - working[0][0][0][0] = working[0][0][0][1] = working[0][0][0][2] = globalgammaoffs; - working[1][1][1][0] = working[1][1][1][1] = working[1][1][1][2] = globalgammaoffs+globalgammamul; + working[0][0][0][0] = working[0][0][0][1] = working[0][0][0][2] = globalbrightnessoffs; + working[1][1][1][0] = working[1][1][1][1] = working[1][1][1][2] = globalbrightnessoffs+globalbrightnessmul; -#define dohue(hue, gamma, loc) \ - tempgammamul = (gamma ? ((255.0f - (gammascale*abs(gamma)))/255.0f)*globalgammamul : globalgammamul);\ - tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0f) + globalgammaoffs : globalgammaoffs);\ - mod = ((hue % huecoloursteps)*(tempgammamul)/huecoloursteps);\ +#define dohue(hue, brightness, loc) \ + tempbrightnessmul = (brightness ? ((255.0f - (brightnessscale*abs(brightness)))/255.0f)*globalbrightnessmul : globalbrightnessmul);\ + tempbrightnessoffs = ((brightness > 0) ? ((brightnessscale*brightness)/255.0f) + globalbrightnessoffs : globalbrightnessoffs);\ + mod = ((hue % huecoloursteps)*(tempbrightnessmul)/huecoloursteps);\ switch (hue/huecoloursteps)\ {\ case 0:\ default:\ - loc[0] = tempgammaoffs+tempgammamul;\ - loc[1] = tempgammaoffs+mod;\ - loc[2] = tempgammaoffs;\ + loc[0] = tempbrightnessoffs+tempbrightnessmul;\ + loc[1] = tempbrightnessoffs+mod;\ + loc[2] = tempbrightnessoffs;\ break;\ case 1:\ - loc[0] = tempgammaoffs+tempgammamul-mod;\ - loc[1] = tempgammaoffs+tempgammamul;\ - loc[2] = tempgammaoffs;\ + loc[0] = tempbrightnessoffs+tempbrightnessmul-mod;\ + loc[1] = tempbrightnessoffs+tempbrightnessmul;\ + loc[2] = tempbrightnessoffs;\ break;\ case 2:\ - loc[0] = tempgammaoffs;\ - loc[1] = tempgammaoffs+tempgammamul;\ - loc[2] = tempgammaoffs+mod;\ + loc[0] = tempbrightnessoffs;\ + loc[1] = tempbrightnessoffs+tempbrightnessmul;\ + loc[2] = tempbrightnessoffs+mod;\ break;\ case 3:\ - loc[0] = tempgammaoffs;\ - loc[1] = tempgammaoffs+tempgammamul-mod;\ - loc[2] = tempgammaoffs+tempgammamul;\ + loc[0] = tempbrightnessoffs;\ + loc[1] = tempbrightnessoffs+tempbrightnessmul-mod;\ + loc[2] = tempbrightnessoffs+tempbrightnessmul;\ break;\ case 4:\ - loc[0] = tempgammaoffs+mod;\ - loc[1] = tempgammaoffs;\ - loc[2] = tempgammaoffs+tempgammamul;\ + loc[0] = tempbrightnessoffs+mod;\ + loc[1] = tempbrightnessoffs;\ + loc[2] = tempbrightnessoffs+tempbrightnessmul;\ break;\ case 5:\ - loc[0] = tempgammaoffs+tempgammamul;\ - loc[1] = tempgammaoffs;\ - loc[2] = tempgammaoffs+tempgammamul-mod;\ + loc[0] = tempbrightnessoffs+tempbrightnessmul;\ + loc[1] = tempbrightnessoffs;\ + loc[2] = tempbrightnessoffs+tempbrightnessmul-mod;\ break;\ } - dohue(cv_rhue.value, cv_rgamma.value, working[1][0][0]); - dohue(cv_yhue.value, cv_ygamma.value, working[1][1][0]); - dohue(cv_ghue.value, cv_ggamma.value, working[0][1][0]); - dohue(cv_chue.value, cv_cgamma.value, working[0][1][1]); - dohue(cv_bhue.value, cv_bgamma.value, working[0][0][1]); - dohue(cv_mhue.value, cv_mgamma.value, working[1][0][1]); + dohue(cv_rhue.value, cv_rbrightness.value, working[1][0][0]); + dohue(cv_yhue.value, cv_ybrightness.value, working[1][1][0]); + dohue(cv_ghue.value, cv_gbrightness.value, working[0][1][0]); + dohue(cv_chue.value, cv_cbrightness.value, working[0][1][1]); + dohue(cv_bhue.value, cv_bbrightness.value, working[0][0][1]); + dohue(cv_mhue.value, cv_mbrightness.value, working[1][0][1]); #undef dohue } #define dosaturation(a, e) a = ((1 - work)*e + work*a) -#define docvsat(cv_sat, hue, gamma, r, g, b) \ +#define docvsat(cv_sat, hue, brightness, r, g, b) \ if diffconssat(cv_sat)\ {\ - float work, mod, tempgammamul, tempgammaoffs;\ + float work, mod, tempbrightnessmul, tempbrightnessoffs;\ apply = true;\ work = (cv_sat.value/10.0f);\ mod = ((hue % huecoloursteps)*(1.0f)/huecoloursteps);\ @@ -228,20 +231,20 @@ static boolean InitCube(void) mod = 2-mod;\ else\ mod += 1;\ - tempgammamul = (gamma ? ((255.0f - (gammascale*abs(gamma)))/255.0f)*globalgammamul : globalgammamul);\ - tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0f) + globalgammaoffs : globalgammaoffs);\ + tempbrightnessmul = (brightness ? ((255.0f - (brightnessscale*abs(brightness)))/255.0f)*globalbrightnessmul : globalbrightnessmul);\ + tempbrightnessoffs = ((brightness > 0) ? ((brightnessscale*brightness)/255.0f) + globalbrightnessoffs : globalbrightnessoffs);\ for (q = 0; q < 3; q++)\ - dosaturation(working[r][g][b][q], (tempgammaoffs+(desatur[q]*mod*tempgammamul)));\ + dosaturation(working[r][g][b][q], (tempbrightnessoffs+(desatur[q]*mod*tempbrightnessmul)));\ } - docvsat(cv_rsaturation, cv_rhue.value, cv_rgamma.value, 1, 0, 0); - docvsat(cv_ysaturation, cv_yhue.value, cv_ygamma.value, 1, 1, 0); - docvsat(cv_gsaturation, cv_ghue.value, cv_ggamma.value, 0, 1, 0); - docvsat(cv_csaturation, cv_chue.value, cv_cgamma.value, 0, 1, 1); - docvsat(cv_bsaturation, cv_bhue.value, cv_bgamma.value, 0, 0, 1); - docvsat(cv_msaturation, cv_mhue.value, cv_mgamma.value, 1, 0, 1); + docvsat(cv_rsaturation, cv_rhue.value, cv_rbrightness.value, 1, 0, 0); + docvsat(cv_ysaturation, cv_yhue.value, cv_ybrightness.value, 1, 1, 0); + docvsat(cv_gsaturation, cv_ghue.value, cv_gbrightness.value, 0, 1, 0); + docvsat(cv_csaturation, cv_chue.value, cv_cbrightness.value, 0, 1, 1); + docvsat(cv_bsaturation, cv_bhue.value, cv_bbrightness.value, 0, 0, 1); + docvsat(cv_msaturation, cv_mhue.value, cv_mbrightness.value, 1, 0, 1); -#undef gammascale +#undef brightnessscale if diffconssat(cv_globalsaturation) { @@ -264,7 +267,7 @@ static boolean InitCube(void) #undef dosaturation #undef diffcons -#undef diffconsgamma +#undef diffconsbrightness #undef diffconssat if (!apply) @@ -301,24 +304,6 @@ same, I'm not gonna be the one to remove this base modification. toast 20/04/17 ... welp yes i am (27/07/19, see the ifdef around it) */ -const UINT8 correctiontable[256] = - {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, - 17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32, - 33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48, - 49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64, - 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80, - 81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96, - 97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112, - 113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128, - 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, - 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, - 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, - 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, - 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, - 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, - 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255}; - const UINT8 gammatable[5][256] = { {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, @@ -404,6 +389,26 @@ const UINT8 gammatable[5][256] = }; #endif +UINT32 V_GammaCorrect(UINT32 input, double power) +{ + RGBA_t result; + double linear; + + result.rgba = input; + + linear = ((double)result.s.red)/255.0f; + linear = pow(linear, power)*255.0f; + result.s.red = (UINT8)(linear); + linear = ((double)result.s.green)/255.0f; + linear = pow(linear, power)*255.0f; + result.s.green = (UINT8)(linear); + linear = ((double)result.s.blue)/255.0f; + linear = pow(linear, power)*255.0f; + result.s.blue = (UINT8)(linear); + + return result.rgba; +} + // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { @@ -412,7 +417,7 @@ static void LoadPalette(const char *lumpname) lumpnum_t lumpnum; #ifdef BACKWARDSCOMPATCORRECTION - const UINT8 *usegamma = gammatable[min(max(cv_globalgamma.value, 0), 4)]; + const UINT8 *usegamma = gammatable[cv_globalgamma.value]; #endif Cubeapply = InitCube(); @@ -422,25 +427,18 @@ static void LoadPalette(const char *lumpname) palsize = currentPaletteSize / 3; Z_Free(pLocalPalette); + Z_Free(pGammaCorrectedPalette); pLocalPalette = Z_Malloc(sizeof (*pLocalPalette)*palsize, PU_STATIC, NULL); + pGammaCorrectedPalette = Z_Malloc(sizeof (*pGammaCorrectedPalette)*palsize, PU_STATIC, NULL); pal = W_CacheLumpNum(lumpnum, PU_CACHE); for (i = 0; i < palsize; i++) { #ifdef BACKWARDSCOMPATCORRECTION - if (cv_globalgamma.value >= 0 && cv_globalgamma.value <= 4) - { - pLocalPalette[i].s.red = usegamma[*pal++]; - pLocalPalette[i].s.green = usegamma[*pal++]; - pLocalPalette[i].s.blue = usegamma[*pal++]; - } - else - { - pLocalPalette[i].s.red = correctiontable[*pal++]; - pLocalPalette[i].s.green = correctiontable[*pal++]; - pLocalPalette[i].s.blue = correctiontable[*pal++]; - } + pLocalPalette[i].s.red = usegamma[*pal++]; + pLocalPalette[i].s.green = usegamma[*pal++]; + pLocalPalette[i].s.blue = usegamma[*pal++]; #else pLocalPalette[i].s.red = *pal++; pLocalPalette[i].s.green = *pal++; @@ -448,15 +446,17 @@ static void LoadPalette(const char *lumpname) #endif pLocalPalette[i].s.alpha = 0xFF; + pGammaCorrectedPalette[i].rgba = V_GammaDecode(pLocalPalette[i].rgba); + if (!Cubeapply) continue; - // lerp of colour cubing! if you want, make it smoother yourself - V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue); + V_CubeApply(&pGammaCorrectedPalette[i]); + pLocalPalette[i].rgba = V_GammaEncode(pGammaCorrectedPalette[i].rgba); } } -void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue) +void V_CubeApply(RGBA_t *input) { float working[4][3]; float linear; @@ -465,7 +465,7 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue) if (!Cubeapply) return; - linear = (*red/255.0f); + linear = ((*input).s.red/255.0); #define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2) for (q = 0; q < 3; q++) { @@ -474,13 +474,15 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue) working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]); working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]); } - linear = (*green/255.0f); + + linear = ((*input).s.green/255.0); for (q = 0; q < 3; q++) { working[0][q] = dolerp(working[0][q], working[1][q]); working[1][q] = dolerp(working[2][q], working[3][q]); } - linear = (*blue/255.0f); + + linear = ((*input).s.blue/255.0); for (q = 0; q < 3; q++) { working[0][q] = 255*dolerp(working[0][q], working[1][q]); @@ -491,9 +493,9 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue) } #undef dolerp - *red = (UINT8)(working[0][0]); - *green = (UINT8)(working[0][1]); - *blue = (UINT8)(working[0][2]); + (*input).s.red = (UINT8)(working[0][0]); + (*input).s.green = (UINT8)(working[0][1]); + (*input).s.blue = (UINT8)(working[0][2]); } const char *R_GetPalname(UINT16 num) @@ -1328,37 +1330,37 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) // This is now a function since it's otherwise repeated 2 times and honestly looks retarded: static UINT32 V_GetHWConsBackColor(void) { - UINT8 r, g, b; + RGBA_t output; switch (cons_backcolor.value) { - case 0: r = 0xff; g = 0xff; b = 0xff; break; // White - case 1: r = 0x80; g = 0x80; b = 0x80; break; // Black - case 2: r = 0xde; g = 0xb8; b = 0x87; break; // Sepia - case 3: r = 0x40; g = 0x20; b = 0x10; break; // Brown - case 4: r = 0xfa; g = 0x80; b = 0x72; break; // Pink - case 5: r = 0xff; g = 0x69; b = 0xb4; break; // Raspberry - case 6: r = 0xff; g = 0x00; b = 0x00; break; // Red - case 7: r = 0xff; g = 0xd6; b = 0x83; break; // Creamsicle - case 8: r = 0xff; g = 0x80; b = 0x00; break; // Orange - case 9: r = 0xda; g = 0xa5; b = 0x20; break; // Gold - case 10: r = 0x80; g = 0x80; b = 0x00; break; // Yellow - case 11: r = 0x00; g = 0xff; b = 0x00; break; // Emerald - case 12: r = 0x00; g = 0x80; b = 0x00; break; // Green - case 13: r = 0x40; g = 0x80; b = 0xff; break; // Cyan - case 14: r = 0x46; g = 0x82; b = 0xb4; break; // Steel - case 15: r = 0x1e; g = 0x90; b = 0xff; break; // Periwinkle - case 16: r = 0x00; g = 0x00; b = 0xff; break; // Blue - case 17: r = 0xff; g = 0x00; b = 0xff; break; // Purple - case 18: r = 0xee; g = 0x82; b = 0xee; break; // Lavender + case 0: output.s.red = 0xff; output.s.green = 0xff; output.s.blue = 0xff; break; // White + case 1: output.s.red = 0x80; output.s.green = 0x80; output.s.blue = 0x80; break; // Black + case 2: output.s.red = 0xde; output.s.green = 0xb8; output.s.blue = 0x87; break; // Sepia + case 3: output.s.red = 0x40; output.s.green = 0x20; output.s.blue = 0x10; break; // Brown + case 4: output.s.red = 0xfa; output.s.green = 0x80; output.s.blue = 0x72; break; // Pink + case 5: output.s.red = 0xff; output.s.green = 0x69; output.s.blue = 0xb4; break; // Raspberry + case 6: output.s.red = 0xff; output.s.green = 0x00; output.s.blue = 0x00; break; // Red + case 7: output.s.red = 0xff; output.s.green = 0xd6; output.s.blue = 0x83; break; // Creamsicle + case 8: output.s.red = 0xff; output.s.green = 0x80; output.s.blue = 0x00; break; // Orange + case 9: output.s.red = 0xda; output.s.green = 0xa5; output.s.blue = 0x20; break; // Gold + case 10: output.s.red = 0x80; output.s.green = 0x80; output.s.blue = 0x00; break; // Yellow + case 11: output.s.red = 0x00; output.s.green = 0xff; output.s.blue = 0x00; break; // Emerald + case 12: output.s.red = 0x00; output.s.green = 0x80; output.s.blue = 0x00; break; // Green + case 13: output.s.red = 0x40; output.s.green = 0x80; output.s.blue = 0xff; break; // Cyan + case 14: output.s.red = 0x46; output.s.green = 0x82; output.s.blue = 0xb4; break; // Steel + case 15: output.s.red = 0x1e; output.s.green = 0x90; output.s.blue = 0xff; break; // Periwinkle + case 16: output.s.red = 0x00; output.s.green = 0x00; output.s.blue = 0xff; break; // Blue + case 17: output.s.red = 0xff; output.s.green = 0x00; output.s.blue = 0xff; break; // Purple + case 18: output.s.red = 0xee; output.s.green = 0x82; output.s.blue = 0xee; break; // Lavender // Default green - default: r = 0x00; g = 0x80; b = 0x00; break; + default: output.s.red = 0x00; output.s.green = 0x80; output.s.blue = 0x00; break; } if (!HWR_ShouldUsePaletteRendering()) - V_CubeApply(&r, &g, &b); + V_CubeApply(&output); - return (r << 24) | (g << 16) | (b << 8); + return (output.s.red << 24) | (output.s.green << 16) | (output.s.blue << 8); } #endif @@ -3814,12 +3816,14 @@ void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors) UINT8 r, g, b; for (r = 0; r < 0xFF; r++) - for (g = 0; g < 0xFF; g++) - for (b = 0; b < 0xFF; b++) { - i = CLUTINDEX(r, g, b); - if (lut->table[i] == 0xFFFF) - lut->table[i] = NearestPaletteColor(r, g, b, palette); + for (g = 0; g < 0xFF; g++) + { + for (b = 0; b < 0xFF; b++) + { + lut->table[i] = GetColorLUT(lut, r, g, b); + } + } } } } diff --git a/src/v_video.h b/src/v_video.h index 6213dc1bb..7eea1468c 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -40,9 +40,12 @@ extern "C" { // extern consvar_t cv_ticrate, cv_accuratefps, cv_allcaps, cv_constextsize, cv_menucaps, -cv_globalgamma, cv_globalsaturation, +#ifdef BACKWARDSCOMPATCORRECTION +cv_globalgamma, +#endif +cv_globalbrightness, cv_globalsaturation, cv_rhue, cv_yhue, cv_ghue, cv_chue, cv_bhue, cv_mhue, -cv_rgamma, cv_ygamma, cv_ggamma, cv_cgamma, cv_bgamma, cv_mgamma, +cv_rbrightness, cv_ybrightness, cv_gbrightness, cv_cbrightness, cv_bbrightness, cv_mbrightness, cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, cv_msaturation, cv_palette, cv_palettenum; @@ -78,10 +81,15 @@ const char *R_GetPalname(UINT16 num); const char *GetPalette(void); extern RGBA_t *pLocalPalette; +extern RGBA_t *pGammaCorrectedPalette; extern UINT8 hudtrans; -void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue); +UINT32 V_GammaCorrect(UINT32 input, double power); +#define V_GammaDecode(input) V_GammaCorrect(input, 2.2f) +#define V_GammaEncode(input) V_GammaCorrect(input, (1/2.2f)) + +void V_CubeApply(RGBA_t *input); // Retrieve the ARGB value from a palette color index #define V_GetColor(color) (pLocalPalette[color&0xFF])