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