Ticket #2376: FPSsettingsshow.patch

File FPSsettingsshow.patch, 16.0 KB (added by Jeremiah Payne, 10 years ago)

Added an option in the settings

  • binaries/data/mods/public/gui/options/options.js

     
    1 /**
    2  * This array holds the data to populate the general section with.
    3  * Data is in the form [Title, Tooltip, {ActionType:Action}, InputType].
    4  */
    5 var options = {
    6     "generalSetting":
    7     [
    8         ["Windowed Mode", "Start 0 A.D. in windowed mode", {"config":"windowed"}, "boolean"],
    9         ["Background Pause", "Pause single player games when window loses focus", {"config":"pauseonfocusloss"}, "boolean"],
    10     ],
    11     "graphicsSetting":
    12     [
    13         ["Prefer GLSL", "Use OpenGL 2.0 shaders (recommended)", {"renderer":"PreferGLSL"}, "boolean"],
    14         ["Shadows", "Enable shadows", {"renderer":"Shadows"}, "boolean"],
    15         ["Particles", "Enable particles", {"renderer":"Particles"}, "boolean"],
    16         ["Show Sky", "Render Sky", {"renderer":"ShowSky"}, "boolean"],
    17         ["Unit Silhouettes", "Show outlines of units behind buildings", {"renderer":"Silhouettes"}, "boolean"],
    18         ["Shadow Flitering", "Smooth shadows", {"renderer":"ShadowPCF"}, "boolean"],
    19         ["HQ Waviness", "Use real normals for ocean-wave rendering, instead of applying them as a flat texture", {"renderer":"WaterNormal"}, "boolean"],
    20         ["Real Water Depth", "Use actual water depth in rendering calculations", {"renderer":"WaterRealDepth"}, "boolean"],
    21         ["Water Reflections", "Allow water to reflect a mirror image", {"renderer":"WaterReflection"}, "boolean"],
    22         ["Water Refraction", "Use a real water refraction map and not transparency", {"renderer":"WaterRefraction"}, "boolean"],
    23         ["Shore Foam", "Show foam on water near shore depending on water waviness", {"renderer":"WaterFoam"}, "boolean"],
    24         ["Shore Waves", "Show breaking waves on water near shore (Requires HQ Waviness)", {"renderer":"WaterCoastalWaves"}, "boolean"],
    25         ["Water Shadows", "Cast shadows on water", {"renderer":"WaterShadow"}, "boolean"],
    26     ],
    27     "soundSetting":
    28     [
    29         ["Master Gain", "Master audio gain", {"config":"sound.mastergain", "function":"Engine.SetMasterGain(Number(this.caption));"}, "number"],
    30         ["Music Gain", "In game music gain", {"config":"sound.musicgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
    31         ["Ambient Gain", "In game ambient sound gain", {"config":"sound.ambientgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
    32         ["Action Gain", "In game unit action sound gain", {"config":"sound.actiongain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
    33         ["UI Gain", "UI sound gain", {"config":"sound.uigain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
    34     ],
    35     "lobbySetting":
    36     [
    37         ["Chat Backlog", "Number of backlogged messages to load when joining the lobby", {"config":"lobby.history"}, "number"],
    38         ["Chat Timestamp", "Show time that messages are posted in the lobby chat", {"config":"lobby.chattimestamp"}, "boolean"],
    39     ],
    40 };
    41 
    42 function init()
    43 {
    44     // WARNING: We assume a strict formatting of the XML and do minimal checking.
    45     for each (var prefix in Object.keys(options))
    46     {
    47         var lastSize;
    48         for (var i = 0; i < options[prefix].length; i++)
    49         {
    50             var body = Engine.GetGUIObjectByName(prefix + "[" + i + "]");
    51             var label = Engine.GetGUIObjectByName(prefix + "Label[" + i + "]");
    52             // Setup control.
    53             setupControl(options[prefix][i], i, prefix);
    54             // Setup label.
    55             label.caption = options[prefix][i][0];
    56             label.tooltip = options[prefix][i][1];
    57             // Move each element to the correct place.
    58             if (i > 0)
    59             {
    60                 var newSize = new GUISize();
    61                 newSize.left = lastSize.left;
    62                 newSize.rright = lastSize.rright;
    63                 newSize.top = lastSize.bottom;
    64                 newSize.bottom = newSize.top + 25;
    65                 body.size = newSize;
    66                 lastSize = newSize;
    67             }
    68             else
    69             {
    70                 lastSize = body.size;
    71             }
    72             // Show element.
    73             body.hidden = false;
    74         }
    75     }
    76 }
    77 
    78 /**
    79  * Setup the apropriate control for a given option.
    80  *
    81  * @param option Structure containing the data to setup an option.
    82  * @param prefix Prefix to use when accessing control, for example "generalSetting" when the tickbox name is generalSettingTickbox[i].
    83  */
    84 function setupControl(option, i, prefix)
    85 {
    86     switch (option[3])
    87     {
    88         case "boolean":
    89             var control = Engine.GetGUIObjectByName(prefix + "Tickbox[" + i + "]");
    90             var checked;
    91             var onPress = function(){};
    92             // Different option action load and save differently, so this switch is needed.
    93             for each (var action in Object.keys(option[2]))
    94             {
    95                 switch (action)
    96                 {
    97                     case "config":
    98                         // Load initial value if not yet loaded.
    99                         if (!checked || typeof checked != boolean)
    100                             checked = Engine.ConfigDB_GetValue("user", option[2][action]) === "true" ? true : false;
    101                         // Hacky macro to create the callback.
    102                         var callback = function(key)
    103                         {
    104                             return function()
    105                             {
    106                                 Engine.ConfigDB_CreateValue("user", key, String(this.checked));
    107                             };
    108                         }(option[2][action]);
    109                         // Merge the new callback with any existing callbacks.
    110                         onPress = mergeFunctions(callback, onPress);
    111                         break;
    112                     case "renderer":
    113                         // Load initial value if not yet loaded.
    114                         if (!checked || typeof checked != boolean)
    115                             checked = eval("Engine.Renderer_Get" + option[2][action] + "Enabled()");
    116                         // Hacky macro to create the callback.
    117                         var callback = function(key)
    118                         {
    119                             return function()
    120                             {
    121                                 eval("Engine.Renderer_Set" + key + "Enabled(" + this.checked + ")");
    122                             };
    123                         }(option[2][action]);
    124                         // Merge the new callback with any existing callbacks.
    125                         onPress = mergeFunctions(callback, onPress);
    126                         break;
    127                     case "function":
    128                         // This allows for doing low-level actions, like hiding/showing UI elements.
    129                         onPress = mergeFunctions(eval("function(){" + option[2][action] + "}"), onPress);
    130                         break;
    131                     default:
    132                         warn("Unknown option source type '" + action + "'");
    133                 }
    134             }
    135             // Load final data to the control element.
    136             control.checked = checked;
    137             control.onPress = onPress;
    138             break;
    139         case "number":
    140             // TODO: Slider
    141         case "string":
    142             var control = Engine.GetGUIObjectByName(prefix + "Input[" + i + "]");
    143             var caption;
    144             var onPress = function(){};
    145             for each (var action in Object.keys(option[2]))
    146             {
    147                 switch (action)
    148                 {
    149                     case "config":
    150                         // Load initial value if not yet loaded.
    151                         if (!checked || typeof checked != boolean)
    152                             caption = Engine.ConfigDB_GetValue("user", option[2][action]);;
    153                         // Hacky macro to create the callback.
    154                         var callback = function(key)
    155                         {
    156                             return function()
    157                             {
    158                                 Engine.ConfigDB_CreateValue("user", key, String(this.caption));
    159                             };
    160                         }(option[2][action]);
    161                         // Merge the new callback with any existing callbacks.
    162                         onPress = mergeFunctions(callback, onPress);
    163                         break;
    164                     case "function":
    165                         // This allows for doing low-level actions, like hiding/showing UI elements.
    166                         onPress = mergeFunctions(function(){eval(option[2][action])}, onPress);
    167                         break;
    168                     default:
    169                         warn("Unknown option source type '" + action + "'");
    170                 }
    171             }
    172             control.caption = caption;
    173             control.onPress = onPress;
    174             break;
    175         default:
    176             warn("Unknown option type '" + options[3] + "', assuming string. Valid types are 'number', 'string', or 'bool'.");
    177             var control = Engine.GetGUIObjectByName(prefix + "Input[" + i + "]");
    178             break;
    179     }
    180     control.hidden = false;
    181     control.tooltip = option[1];
    182     return control;
    183 }
    184 
    185 /**
    186  * Merge two functions which don't expect arguments.
    187  *
    188  * @return Merged function.
    189  */
    190 function mergeFunctions(function1, function2)
    191 {
    192     return function()
    193     {
    194         function1.apply(this);
    195         function2.apply(this);
    196     };
    197 }
     1/**
     2 * This array holds the data to populate the general section with.
     3 * Data is in the form [Title, Tooltip, {ActionType:Action}, InputType].
     4 */
     5var options = {
     6    "generalSetting":
     7    [
     8        ["Windowed Mode", "Start 0 A.D. in windowed mode", {"config":"windowed"}, "boolean"],
     9        ["Background Pause", "Pause single player games when window loses focus", {"config":"pauseonfocusloss"}, "boolean"],
     10        ["Show FPS", "Show FPS in the top right corner", {"config":"pauseonfocusloss"}, "boolean"],
     11    ],
     12    "graphicsSetting":
     13    [
     14        ["Prefer GLSL", "Use OpenGL 2.0 shaders (recommended)", {"renderer":"PreferGLSL"}, "boolean"],
     15        ["Shadows", "Enable shadows", {"renderer":"Shadows"}, "boolean"],
     16        ["Particles", "Enable particles", {"renderer":"Particles"}, "boolean"],
     17        ["Show Sky", "Render Sky", {"renderer":"ShowSky"}, "boolean"],
     18        ["Unit Silhouettes", "Show outlines of units behind buildings", {"renderer":"Silhouettes"}, "boolean"],
     19        ["Shadow Flitering", "Smooth shadows", {"renderer":"ShadowPCF"}, "boolean"],
     20        ["HQ Waviness", "Use real normals for ocean-wave rendering, instead of applying them as a flat texture", {"renderer":"WaterNormal"}, "boolean"],
     21        ["Real Water Depth", "Use actual water depth in rendering calculations", {"renderer":"WaterRealDepth"}, "boolean"],
     22        ["Water Reflections", "Allow water to reflect a mirror image", {"renderer":"WaterReflection"}, "boolean"],
     23        ["Water Refraction", "Use a real water refraction map and not transparency", {"renderer":"WaterRefraction"}, "boolean"],
     24        ["Shore Foam", "Show foam on water near shore depending on water waviness", {"renderer":"WaterFoam"}, "boolean"],
     25        ["Shore Waves", "Show breaking waves on water near shore (Requires HQ Waviness)", {"renderer":"WaterCoastalWaves"}, "boolean"],
     26        ["Water Shadows", "Cast shadows on water", {"renderer":"WaterShadow"}, "boolean"],
     27    ],
     28    "soundSetting":
     29    [
     30        ["Master Gain", "Master audio gain", {"config":"sound.mastergain", "function":"Engine.SetMasterGain(Number(this.caption));"}, "number"],
     31        ["Music Gain", "In game music gain", {"config":"sound.musicgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
     32        ["Ambient Gain", "In game ambient sound gain", {"config":"sound.ambientgain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
     33        ["Action Gain", "In game unit action sound gain", {"config":"sound.actiongain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
     34        ["UI Gain", "UI sound gain", {"config":"sound.uigain", "function":"Engine.SetMusicGain(Number(this.caption));"}, "number"],
     35    ],
     36    "lobbySetting":
     37    [
     38        ["Chat Backlog", "Number of backlogged messages to load when joining the lobby", {"config":"lobby.history"}, "number"],
     39        ["Chat Timestamp", "Show time that messages are posted in the lobby chat", {"config":"lobby.chattimestamp"}, "boolean"],
     40    ],
     41};
     42
     43function init()
     44{
     45    // WARNING: We assume a strict formatting of the XML and do minimal checking.
     46    for each (var prefix in Object.keys(options))
     47    {
     48        var lastSize;
     49        for (var i = 0; i < options[prefix].length; i++)
     50        {
     51            var body = Engine.GetGUIObjectByName(prefix + "[" + i + "]");
     52            var label = Engine.GetGUIObjectByName(prefix + "Label[" + i + "]");
     53            // Setup control.
     54            setupControl(options[prefix][i], i, prefix);
     55            // Setup label.
     56            label.caption = options[prefix][i][0];
     57            label.tooltip = options[prefix][i][1];
     58            // Move each element to the correct place.
     59            if (i > 0)
     60            {
     61                var newSize = new GUISize();
     62                newSize.left = lastSize.left;
     63                newSize.rright = lastSize.rright;
     64                newSize.top = lastSize.bottom;
     65                newSize.bottom = newSize.top + 25;
     66                body.size = newSize;
     67                lastSize = newSize;
     68            }
     69            else
     70            {
     71                lastSize = body.size;
     72            }
     73            // Show element.
     74            body.hidden = false;
     75        }
     76    }
     77}
     78
     79/**
     80 * Setup the apropriate control for a given option.
     81 *
     82 * @param option Structure containing the data to setup an option.
     83 * @param prefix Prefix to use when accessing control, for example "generalSetting" when the tickbox name is generalSettingTickbox[i].
     84 */
     85function setupControl(option, i, prefix)
     86{
     87    switch (option[3])
     88    {
     89        case "boolean":
     90            var control = Engine.GetGUIObjectByName(prefix + "Tickbox[" + i + "]");
     91            var checked;
     92            var onPress = function(){};
     93            // Different option action load and save differently, so this switch is needed.
     94            for each (var action in Object.keys(option[2]))
     95            {
     96                switch (action)
     97                {
     98                    case "config":
     99                        // Load initial value if not yet loaded.
     100                        if (!checked || typeof checked != boolean)
     101                            checked = Engine.ConfigDB_GetValue("user", option[2][action]) === "true" ? true : false;
     102                        // Hacky macro to create the callback.
     103                        var callback = function(key)
     104                        {
     105                            return function()
     106                            {
     107                                Engine.ConfigDB_CreateValue("user", key, String(this.checked));
     108                            };
     109                        }(option[2][action]);
     110                        // Merge the new callback with any existing callbacks.
     111                        onPress = mergeFunctions(callback, onPress);
     112                        break;
     113                    case "renderer":
     114                        // Load initial value if not yet loaded.
     115                        if (!checked || typeof checked != boolean)
     116                            checked = eval("Engine.Renderer_Get" + option[2][action] + "Enabled()");
     117                        // Hacky macro to create the callback.
     118                        var callback = function(key)
     119                        {
     120                            return function()
     121                            {
     122                                eval("Engine.Renderer_Set" + key + "Enabled(" + this.checked + ")");
     123                            };
     124                        }(option[2][action]);
     125                        // Merge the new callback with any existing callbacks.
     126                        onPress = mergeFunctions(callback, onPress);
     127                        break;
     128                    case "function":
     129                        // This allows for doing low-level actions, like hiding/showing UI elements.
     130                        onPress = mergeFunctions(eval("function(){" + option[2][action] + "}"), onPress);
     131                        break;
     132                    default:
     133                        warn("Unknown option source type '" + action + "'");
     134                }
     135            }
     136            // Load final data to the control element.
     137            control.checked = checked;
     138            control.onPress = onPress;
     139            break;
     140        case "number":
     141            // TODO: Slider
     142        case "string":
     143            var control = Engine.GetGUIObjectByName(prefix + "Input[" + i + "]");
     144            var caption;
     145            var onPress = function(){};
     146            for each (var action in Object.keys(option[2]))
     147            {
     148                switch (action)
     149                {
     150                    case "config":
     151                        // Load initial value if not yet loaded.
     152                        if (!checked || typeof checked != boolean)
     153                            caption = Engine.ConfigDB_GetValue("user", option[2][action]);;
     154                        // Hacky macro to create the callback.
     155                        var callback = function(key)
     156                        {
     157                            return function()
     158                            {
     159                                Engine.ConfigDB_CreateValue("user", key, String(this.caption));
     160                            };
     161                        }(option[2][action]);
     162                        // Merge the new callback with any existing callbacks.
     163                        onPress = mergeFunctions(callback, onPress);
     164                        break;
     165                    case "function":
     166                        // This allows for doing low-level actions, like hiding/showing UI elements.
     167                        onPress = mergeFunctions(function(){eval(option[2][action])}, onPress);
     168                        break;
     169                    default:
     170                        warn("Unknown option source type '" + action + "'");
     171                }
     172            }
     173            control.caption = caption;
     174            control.onPress = onPress;
     175            break;
     176        default:
     177            warn("Unknown option type '" + options[3] + "', assuming string. Valid types are 'number', 'string', or 'bool'.");
     178            var control = Engine.GetGUIObjectByName(prefix + "Input[" + i + "]");
     179            break;
     180    }
     181    control.hidden = false;
     182    control.tooltip = option[1];
     183    return control;
     184}
     185
     186/**
     187 * Merge two functions which don't expect arguments.
     188 *
     189 * @return Merged function.
     190 */
     191function mergeFunctions(function1, function2)
     192{
     193    return function()
     194    {
     195        function1.apply(this);
     196        function2.apply(this);
     197    };
     198}