X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fmenu%2Fxonotic%2Fslider_decibels.c;h=0ea9d161f1e166f358ea53867522eab681ed136e;hp=ba7cffc22f049b99564ca11fb7582225716b90db;hb=23ae96654035b8cda3da563f346b4507d04d73e8;hpb=715202f719f244160bfc0b004013fa6e1bcc5668 diff --git a/qcsrc/menu/xonotic/slider_decibels.c b/qcsrc/menu/xonotic/slider_decibels.c index ba7cffc22..0ea9d161f 100644 --- a/qcsrc/menu/xonotic/slider_decibels.c +++ b/qcsrc/menu/xonotic/slider_decibels.c @@ -9,6 +9,34 @@ entity makeXonoticDecibelsSlider(float, float, float, string); #ifdef IMPLEMENTATION +float toDecibelOfSquare(float f, float mi) +{ + float A = log(10) / 20; // note: about 0.115; inverse: about 8.686 + if(mi != 0) + { + // linear scale part + float t = 1 / A + mi; + float y = exp(1 + A * mi); + if(f <= y) + return mi + (t - mi) * (f / y); + } + return log(f) / A; +} + +float fromDecibelOfSquare(float f, float mi) +{ + float A = log(10) / 20; // note: about 0.115; inverse: about 8.686 + if(mi != 0) + { + // linear scale part + float t = 1 / A + mi; + float y = exp(1 + A * mi); + if(f <= t) + return y * ((f - mi) / (t - mi)); + } + return exp(A * f); +} + entity makeXonoticDecibelsSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar) { entity me; @@ -16,7 +44,7 @@ entity makeXonoticDecibelsSlider(float theValueMin, float theValueMax, float the me.configureXonoticSlider(me, theValueMin, theValueMax, theValueStep, theCvar); return me; } -void loadCvarsXonoticDecibelsSlider(entity me) +void XonoticDecibelsSlider_loadCvars(entity me) { float v; @@ -24,33 +52,54 @@ void loadCvarsXonoticDecibelsSlider(entity me) return; v = cvar(me.cvarName); - if(v >= 0.98) - setValueSlider( me, 0 ); - else if(v < 0.0005) - setValueSlider( me, -1000000 ); + + // snapping + if(v > fromDecibelOfSquare(me.valueMax - 0.5 * me.valueStep, me.valueMin)) + Slider_setValue(me, me.valueMax); else - setValueSlider( me, 0.1 * floor(0.5 + 10.0 * log10(cvar(me.cvarName)) * 10) ); + Slider_setValue(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v, me.valueMin) / me.valueStep) ); } -void saveCvarsXonoticDecibelsSlider(entity me) +void XonoticDecibelsSlider_saveCvars(entity me) { if not(me.cvarName) return; - if(me.value >= -0.1) - cvar_set(me.cvarName, "1"); - if(me.value < -33) - cvar_set(me.cvarName, "0"); + if(me.value > me.valueMax - 0.5 * me.valueStep) + cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.valueMax, me.valueMin))); else - cvar_set(me.cvarName, ftos(pow(10, me.value / 10))); + cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.value, me.valueMin))); +} + +float autocvar_menu_snd_sliderscale; +string XonoticDecibelsSlider_valueToText(entity me, float v) +{ + if(v > me.valueMax - 0.5 * me.valueStep) + return CTX(_("VOL^MAX")); + else if(v <= me.valueMin) + return CTX(_("VOL^OFF")); + else if(autocvar_menu_snd_sliderscale == 3) // fake percent scale + return sprintf(_("%d %%"), (v - me.valueMin) / (me.valueMax - me.valueMin) * 100); + else if(autocvar_menu_snd_sliderscale == 2) // 0..10 scale + return sprintf(_("%.1f"), (v - me.valueMin) / (me.valueMax - me.valueMin) * 10); + else if(autocvar_menu_snd_sliderscale == 1) // real percent scale + return sprintf(_("%.2f %%"), fromDecibelOfSquare(v, me.valueMin) * 100); + else // decibel scale + return sprintf(_("%s dB"), ftos_decimals(toDecibelOfSquare(fromDecibelOfSquare(v, me.valueMin), 0), me.valueDigits)); } -string valueToTextXonoticDecibelsSlider(entity me, float v) +void _TEST_XonoticDecibelsSlider() { - if(v < -33) - return "OFF"; - else if(v >= -0.1) - return "MAX"; - return strcat(valueToTextSlider(me, v), " dB"); + float i; + for(i = -400; i < 0; ++i) + { + float db = i * 0.1; + float v = fromDecibelOfSquare(db, -40); + float dbv = toDecibelOfSquare(v, -40); + float d = dbv - db; + print(sprintf("%f -> %f -> %f (diff: %f)\n", db, v, dbv, d)); + TEST_Check(fabs(d) > 0.02); + } + TEST_OK(); } #endif