]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/xonotic/slider_decibels.qc
Fix auxiliary crosshairs
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / slider_decibels.qc
1 #include "../../warpzonelib/mathlib.qh"
2
3 #ifndef SLIDER_DECIBELS_H
4 #define SLIDER_DECIBELS_H
5 #include "slider.qc"
6 CLASS(XonoticDecibelsSlider, XonoticSlider)
7         METHOD(XonoticDecibelsSlider, loadCvars, void(entity))
8         METHOD(XonoticDecibelsSlider, saveCvars, void(entity))
9         METHOD(XonoticDecibelsSlider, valueToText, string(entity, float))
10 ENDCLASS(XonoticDecibelsSlider)
11 entity makeXonoticDecibelsSlider(float, float, float, string);
12 #endif
13
14 #ifdef IMPLEMENTATION
15
16 float toDecibelOfSquare(float f, float mi)
17 {
18         float A = log(10) / 20; // note: about 0.115; inverse: about 8.686
19         if(mi != 0)
20         {
21                 // linear scale part
22                 float t = 1 / A + mi;
23                 float y = exp(1 + A * mi);
24                 if(f <= y)
25                         return mi + (t - mi) * (f / y);
26         }
27         return log(f) / A;
28 }
29
30 float fromDecibelOfSquare(float f, float mi)
31 {
32         float A = log(10) / 20; // note: about 0.115; inverse: about 8.686
33         if(mi != 0)
34         {
35                 // linear scale part
36                 float t = 1 / A + mi;
37                 float y = exp(1 + A * mi);
38                 if(f <= t)
39                         return y * ((f - mi) / (t - mi));
40         }
41         return exp(A * f);
42 }
43
44 entity makeXonoticDecibelsSlider(float theValueMin, float theValueMax, float theValueStep, string theCvar)
45 {
46         entity me;
47         me = NEW(XonoticDecibelsSlider);
48         me.configureXonoticSlider(me, theValueMin, theValueMax, theValueStep, theCvar);
49         return me;
50 }
51 void XonoticDecibelsSlider_loadCvars(entity me)
52 {
53         float v;
54
55         if (!me.cvarName)
56                 return;
57
58         v = cvar(me.cvarName);
59
60         // snapping
61         if(v > fromDecibelOfSquare(me.valueMax - 0.5 * me.valueStep, me.valueMin))
62                 Slider_setValue(me, me.valueMax);
63         else
64                 Slider_setValue(me, me.valueStep * floor(0.5 + toDecibelOfSquare(v, me.valueMin) / me.valueStep) );
65 }
66 void XonoticDecibelsSlider_saveCvars(entity me)
67 {
68         if (!me.cvarName)
69                 return;
70
71         if(me.value > me.valueMax - 0.5 * me.valueStep)
72                 cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.valueMax, me.valueMin)));
73         else
74                 cvar_set(me.cvarName, ftos(fromDecibelOfSquare(me.value, me.valueMin)));
75 }
76
77 float autocvar_menu_snd_sliderscale;
78 string XonoticDecibelsSlider_valueToText(entity me, float v)
79 {
80         if(v > me.valueMax - 0.5 * me.valueStep)
81                 return CTX(_("VOL^MAX"));
82         else if(v <= me.valueMin)
83                 return CTX(_("VOL^OFF"));
84         else if(autocvar_menu_snd_sliderscale == 3) // fake percent scale
85                 return sprintf("%d %%", (v - me.valueMin) / (me.valueMax - me.valueMin) * 100);
86         else if(autocvar_menu_snd_sliderscale == 2) // 0..10 scale
87                 return sprintf("%.1f", (v - me.valueMin) / (me.valueMax - me.valueMin) * 10);
88         else if(autocvar_menu_snd_sliderscale == 1) // real percent scale
89                 return sprintf("%.2f %%", fromDecibelOfSquare(v, me.valueMin) * 100);
90         else // decibel scale
91                 return sprintf(_("%s dB"), ftos_decimals(toDecibelOfSquare(fromDecibelOfSquare(v, me.valueMin), 0), me.valueDigits));
92 }
93
94 void _TEST_XonoticDecibelsSlider()
95 {
96         float i;
97         for(i = -400; i < 0; ++i)
98         {
99                 float db = i * 0.1;
100                 float v = fromDecibelOfSquare(db, -40);
101                 float dbv = toDecibelOfSquare(v, -40);
102                 float d = dbv - db;
103                 printf("%f -> %f -> %f (diff: %f)\n", db, v, dbv, d);
104                 TEST_Check(fabs(d) > 0.02);
105         }
106         TEST_OK();
107 }
108
109 #endif