OSDN Git Service

Merge pull request #1115 from Hourier/feature/Divide-Mind-Power-Getter
[hengbandforosx/hengbandosx.git] / src / main / x11-gamma-builder.cpp
1 /*!
2  * @file x11-gamma-builder.cpp
3  * @brief X11環境 (の中でもmaid-x11を必要とする特殊な環境)でガンマ値を調整する
4  * @date 2020/05/16
5  * @author Hourier
6  * @details
7  * Important note about "colors"
8  *
9  * The "TERM_*" color definitions list the "composition" of each
10  * "Angband color" in terms of "quarters" of each of the three color
11  * components (Red, Green, Blue), for example, TERM_UMBER is defined
12  * as 2/4 Red, 1/4 Green, 0/4 Blue.
13  *
14  * The following info is from "Torbjorn Lindgren" (see "main-xaw.c").
15  *
16  * These values are NOT gamma-corrected.  On most machines (with the
17  * Macintosh being an important exception), you must "gamma-correct"
18  * the given values, that is, "correct for the intrinsic non-linearity
19  * of the phosphor", by converting the given intensity levels based
20  * on the "gamma" of the target screen, which is usually 1.7 (or 1.5).
21  *
22  * The actual formula for conversion is unknown to me at this time,
23  * but you can use the table below for the most common gamma values.
24  *
25  * So, on most machines, simply convert the values based on the "gamma"
26  * of the target screen, which is usually in the range 1.5 to 1.7, and
27  * usually is closest to 1.7.  The converted value for each of the five
28  * different "quarter" values is given below:
29  *
30  *  Given     Gamma 1.0       Gamma 1.5       Gamma 1.7     Hex 1.7
31  *  -----       ----            ----            ----          ---
32  *   0/4        0.00            0.00            0.00          #00
33  *   1/4        0.25            0.27            0.28          #47
34  *   2/4        0.50            0.55            0.56          #8f
35  *   3/4        0.75            0.82            0.84          #d7
36  *   4/4        1.00            1.00            1.00          #ff
37  *
38  * Note that some machines (i.e. most IBM machines) are limited to a
39  * hard-coded set of colors, and so the information above is useless.
40  *
41  * Also, some machines are limited to a pre-determined set of colors,
42  * for example, the IBM can only display 16 colors, and only 14 of
43  * those colors resemble colors used by Angband, and then only when
44  * you ignore the fact that "Slate" and "cyan" are not really matches,
45  * so on the IBM, we use "orange" for both "Umber", and "Light Umber"
46  * in addition to the obvious "Orange", since by combining all of the
47  * "indeterminate" colors into a single color, the rest of the colors
48  * are left with "meaningful" values.
49  */
50
51 #include "system/angband.h"
52 #include "main/x11-gamma-builder.h"
53
54 /* Table of gamma values */
55 byte gamma_table[256];
56
57 /* Table of ln(x/256) * 256 for x going from 0 -> 255 */
58 static s16b gamma_helper[256] =
59 {
60 0,-1420,-1242,-1138,-1065,-1007,-961,-921,-887,-857,-830,-806,-783,-762,-744,-726,
61 -710,-694,-679,-666,-652,-640,-628,-617,-606,-596,-586,-576,-567,-577,-549,-541,
62 -532,-525,-517,-509,-502,-495,-488,-482,-475,-469,-463,-457,-451,-455,-439,-434,
63 -429,-423,-418,-413,-408,-403,-398,-394,-389,-385,-380,-376,-371,-367,-363,-359,
64 -355,-351,-347,-343,-339,-336,-332,-328,-325,-321,-318,-314,-311,-308,-304,-301,
65 -298,-295,-291,-288,-285,-282,-279,-276,-273,-271,-268,-265,-262,-259,-257,-254,
66 -251,-248,-246,-243,-241,-238,-236,-233,-231,-228,-226,-223,-221,-219,-216,-214,
67 -212,-209,-207,-205,-203,-200,-198,-196,-194,-192,-190,-188,-186,-184,-182,-180,
68 -178,-176,-174,-172,-170,-168,-166,-164,-162,-160,-158,-156,-155,-153,-151,-149,
69 -147,-146,-144,-142,-140,-139,-137,-135,-134,-132,-130,-128,-127,-125,-124,-122,
70 -120,-119,-117,-116,-114,-112,-111,-109,-108,-106,-105,-103,-102,-100,-99,-97,
71 -96,-95,-93,-92,-90,-89,-87,-86,-85,-83,-82,-80,-79,-78,-76,-75,
72 -74,-72,-71,-70,-68,-67,-66,-65,-63,-62,-61,-59,-58,-57,-56,-54,
73 -53,-52,-51,-50,-48,-47,-46,-45,-44,-42,-41,-40,-39,-38,-37,-35,
74 -34,-33,-32,-31,-30,-29,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,
75 -17,-16,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1
76 };
77
78 /*
79  * Build the gamma table so that floating point isn't needed.
80  *
81  * Note gamma goes from 0->256.  The old value of 100 is now 128.
82  */
83 void build_gamma_table(int gamma)
84 {
85         gamma_table[0] = 0;
86         gamma_table[255] = 255;
87         for (int i = 1; i < 255; i++)
88         {
89                 /*
90                  * Initialise the Taylor series
91                  *
92                  * value and diff have been scaled by 256
93                  */
94                 int n = 1;
95                 long value = 256 * 256;
96                 long diff = ((long)gamma_helper[i]) * (gamma - 256);
97
98                 while (diff)
99                 {
100                         value += diff;
101                         n++;
102
103
104                         /*
105                          * Use the following identiy to calculate the gamma table.
106                          * exp(x) = 1 + x + x^2/2 + x^3/(2*3) + x^4/(2*3*4) +...
107                          *
108                          * n is the current term number.
109                          *
110                          * The gamma_helper array contains a table of
111                          * ln(x/256) * 256
112                          * This is used because a^b = exp(b*ln(a))
113                          *
114                          * In this case:
115                          * a is i / 256
116                          * b is gamma.
117                          *
118                          * Note that everything is scaled by 256 for accuracy,
119                          * plus another factor of 256 for the final result to
120                          * be from 0-255.  Thus gamma_helper[] * gamma must be
121                          * divided by 256*256 each itteration, to get back to
122                          * the original power series.
123                          */
124                         diff = (((diff / 256) * gamma_helper[i]) * (gamma - 256)) / (256 * n);
125                 }
126
127                 /*
128                  * Store the value in the table so that the
129                  * floating point pow function isn't needed .
130                  */
131                 gamma_table[i] = ((long)(value / 256) * i) / 256;
132         }
133 }