From fcc80b12ad2203dd79b93dc463ebcea687688bfd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 23 Mar 2020 16:32:11 -0700 Subject: [PATCH] Colour Cube Calibration Menu! (called "Advanced Color Settings" because No Fun Allowed...) https://cdn.discordapp.com/attachments/237798387070664724/304343382073933824/aa.png Also, a "Reset all" button for the Monitor toggle menu, a ton of new cvars to match up with the colour cube calibration, and a bunch of variable renames related to colour cube operations. (cherry picked from commit c3840ba01d866d257434b2abdad40ef3b0cb581f) # Conflicts: # src/m_menu.c # src/v_video.c --- src/d_netcmd.c | 25 ++++++- src/m_menu.c | 4 +- src/v_video.c | 181 +++++++++++++++++++++++++++++++++++++++---------- src/v_video.h | 6 +- 4 files changed, 174 insertions(+), 42 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 489590978..03096197a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -856,8 +856,29 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_netdemosyncquality); // FIXME: not to be here.. but needs be done for config loading - CV_RegisterVar(&cv_usegamma); - CV_RegisterVar(&cv_usesaturation); + CV_RegisterVar(&cv_globalgamma); + CV_RegisterVar(&cv_globalsaturation); + + CV_RegisterVar(&cv_rhue); + CV_RegisterVar(&cv_yhue); + CV_RegisterVar(&cv_ghue); + CV_RegisterVar(&cv_chue); + 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_rsaturation); + CV_RegisterVar(&cv_ysaturation); + CV_RegisterVar(&cv_gsaturation); + CV_RegisterVar(&cv_csaturation); + CV_RegisterVar(&cv_bsaturation); + CV_RegisterVar(&cv_msaturation); // m_menu.c //CV_RegisterVar(&cv_compactscoreboard); diff --git a/src/m_menu.c b/src/m_menu.c index 6ac2ef5ab..4bbaa1205 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1252,7 +1252,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 20}, #endif {IT_STRING | IT_CVAR | IT_CV_SLIDER, - NULL, "Gamma", &cv_usegamma, 30}, + NULL, "Gamma", &cv_globalgamma, 30}, {IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 45}, //{IT_STRING | IT_CVAR, NULL, "NiGHTS Draw Dist", &cv_drawdist_nights, 55}, @@ -2675,7 +2675,7 @@ boolean M_Responder(event_t *ev) return true; case KEY_F11: // Gamma Level - CV_AddValue(&cv_usegamma, 1); + CV_AddValue(&cv_globalgamma, 1); return true; // Spymode on F12 handled in game logic diff --git a/src/v_video.c b/src/v_video.c index fddfa07a7..1a7aabc82 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -38,14 +38,39 @@ UINT8 *screens[5]; // screens[3] = fade screen start // screens[4] = fade screen end, postimage tempoarary buffer -static CV_PossibleValue_t gamma_cons_t[] = {{-5, "MIN"}, {5, "MAX"}, {0, NULL}}; -static void CV_usegamma_OnChange(void); +consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_ticrate = {"showfps", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static void CV_palette_OnChange(void); + +static CV_PossibleValue_t gamma_cons_t[] = {{-15, "MIN"}, {5, "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}; static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; -consvar_t cv_usesaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_globalsaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +#define huecoloursteps 4 + +static CV_PossibleValue_t hue_cons_t[] = {{0, "MIN"}, {(huecoloursteps*6)-1, "MAX"}, {0, NULL}}; +consvar_t cv_rhue = {"rhue", "0", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_yhue = {"yhue", "4", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_ghue = {"ghue", "8", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chue = {"chue", "12", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +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_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}; +consvar_t cv_gsaturation = {"gsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_csaturation = {"csaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_bsaturation = {"bsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_msaturation = {"msaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t constextsize_cons_t[] = { {V_NOSCALEPATCH, "Small"}, {V_SMALLSCALEPATCH, "Medium"}, {V_MEDSCALEPATCH, "Large"}, {0, "Huge"}, @@ -125,54 +150,136 @@ static boolean InitCube(void) } } }; + float desatur[3]; // grey + float globalgammamul, globalgammaoffs; + boolean doinggamma; + +#define diffcons(cv) (cv.value != atoi(cv.defaultvalue)) + + doinggamma = diffcons(cv_globalgamma); - if (cv_usegamma.value) - { #define gammascale 8 - float gammamul = (255 - (gammascale*abs(cv_usegamma.value)))/255.0; - float gammaoffs = ((cv_usegamma.value > 0) ? ((gammascale*cv_usegamma.value)/255.0) : 0.0); -#undef gammascale + globalgammamul = (cv_globalgamma.value ? ((255 - (gammascale*abs(cv_globalgamma.value)))/255.0) : 1.0); + globalgammaoffs = ((cv_globalgamma.value > 0) ? ((gammascale*cv_globalgamma.value)/255.0) : 0.0); + desatur[0] = desatur[1] = desatur[2] = globalgammaoffs + (0.33*globalgammamul); - apply = true; - - #define dogamma(i, j, k, l) \ - working[i][j][k][l]*= gammamul;\ - working[i][j][k][l] += gammaoffs - for (q = 0; q < 3; q++) - { - dogamma(0, 0, 0, q); - dogamma(1, 0, 0, q); - dogamma(0, 1, 0, q); - dogamma(1, 1, 0, q); - dogamma(0, 0, 1, q); - dogamma(1, 0, 1, q); - dogamma(0, 1, 1, q); - dogamma(1, 1, 1, q); - } -#undef dogamma - } - - if (cv_usesaturation.value != 10) + if (doinggamma + || diffcons(cv_rhue) + || diffcons(cv_yhue) + || diffcons(cv_ghue) + || diffcons(cv_chue) + || diffcons(cv_bhue) + || diffcons(cv_mhue) + || diffcons(cv_rgamma) + || diffcons(cv_ygamma) + || diffcons(cv_ggamma) + || diffcons(cv_cgamma) + || diffcons(cv_bgamma) + || diffcons(cv_mgamma)) { - float desatur[3] = {0.33, 0.33, 0.33}; // grey - float work = (cv_usesaturation.value/10.0); + float mod, tempgammamul, tempgammaoffs; 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; + +#define dohue(hue, gamma, loc) \ + tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\ + tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\ + mod = ((hue % huecoloursteps)*(tempgammamul)/huecoloursteps);\ + switch (hue/huecoloursteps)\ + {\ + case 0:\ + default:\ + loc[0] = tempgammaoffs+tempgammamul;\ + loc[1] = tempgammaoffs+mod;\ + loc[2] = tempgammaoffs;\ + break;\ + case 1:\ + loc[0] = tempgammaoffs+tempgammamul-mod;\ + loc[1] = tempgammaoffs+tempgammamul;\ + loc[2] = tempgammaoffs;\ + break;\ + case 2:\ + loc[0] = tempgammaoffs;\ + loc[1] = tempgammaoffs+tempgammamul;\ + loc[2] = tempgammaoffs+mod;\ + break;\ + case 3:\ + loc[0] = tempgammaoffs;\ + loc[1] = tempgammaoffs+tempgammamul-mod;\ + loc[2] = tempgammaoffs+tempgammamul;\ + break;\ + case 4:\ + loc[0] = tempgammaoffs+mod;\ + loc[1] = tempgammaoffs;\ + loc[2] = tempgammaoffs+tempgammamul;\ + break;\ + case 5:\ + loc[0] = tempgammaoffs+tempgammamul;\ + loc[1] = tempgammaoffs;\ + loc[2] = tempgammaoffs+tempgammamul-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]); +#undef dohue + } + #define dosaturation(a, e) a = ((1 - work)*e + work*a) +#define docvsat(cv_sat, hue, gamma, r, g, b) \ + if diffcons(cv_sat)\ + {\ + float work, mod, tempgammamul, tempgammaoffs;\ + apply = true;\ + work = (cv_sat.value/10.0);\ + mod = ((hue % huecoloursteps)*(1.0)/huecoloursteps);\ + if (hue & huecoloursteps)\ + mod = 2-mod;\ + else\ + mod += 1;\ + tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\ + tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\ + for (q = 0; q < 3; q++)\ + dosaturation(working[r][g][b][q], (tempgammaoffs+(desatur[q]*mod*tempgammamul)));\ + } + + 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); + +#undef gammascale + + if diffcons(cv_globalsaturation) + { + float work = (cv_globalsaturation.value/10.0); + + apply = true; + for (q = 0; q < 3; q++) { - dosaturation(working[0][0][1][q], desatur[q]); - dosaturation(working[0][1][0][q], desatur[q]); dosaturation(working[1][0][0][q], desatur[q]); + dosaturation(working[0][1][0][q], desatur[q]); + dosaturation(working[0][0][1][q], desatur[q]); dosaturation(working[1][1][0][q], 2*desatur[q]); - dosaturation(working[1][0][1][q], 2*desatur[q]); dosaturation(working[0][1][1][q], 2*desatur[q]); + dosaturation(working[1][0][1][q], 2*desatur[q]); } -#undef dosaturation } +#undef dosaturation + +#undef diffcons + if (!apply) return false; @@ -319,7 +426,7 @@ void V_SetPaletteLump(const char *pal) #endif } -static void CV_usegamma_OnChange(void) +static void CV_palette_OnChange(void) { // reload palette LoadMapPalette(); diff --git a/src/v_video.h b/src/v_video.h index 8b35b920a..0a360bc42 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -27,7 +27,11 @@ extern UINT8 *screens[5]; -extern consvar_t cv_ticrate, cv_usegamma, cv_usesaturation, cv_constextsize; +extern consvar_t cv_ticrate, cv_constextsize,\ +cv_globalgamma, 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_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, cv_msaturation; // Allocates buffer screens, call before R_Init. void V_Init(void);