openMSX
RenderSettings.cc
Go to the documentation of this file.
1#include "RenderSettings.hh"
3#include "CommandException.hh"
4#include "Version.hh"
5#include "stl.hh"
6#include "unreachable.hh"
7#include "build-info.hh"
8#include <algorithm>
9#include <iostream>
10#include <cmath>
11
12using namespace gl;
13
14namespace openmsx {
15
16EnumSetting<RenderSettings::ScaleAlgorithm>::Map RenderSettings::getScalerMap()
17{
18 EnumSetting<ScaleAlgorithm>::Map scalerMap = {
19 {"simple", SCALER_SIMPLE},
20 {"ScaleNx", SCALER_SCALE},
21 {"hq", SCALER_HQ},
22 {"hqlite", SCALER_HQLITE},
23 {"RGBtriplet", SCALER_RGBTRIPLET},
24 {"TV", SCALER_TV}
25 };
26 return scalerMap;
27}
28
29EnumSetting<RenderSettings::RendererID>::Map RenderSettings::getRendererMap()
30{
31 EnumSetting<RendererID>::Map rendererMap = {
32 {"none", DUMMY},// TODO: only register when in CliComm mode
33 {"SDLGL-PP", SDLGL_PP}
34 };
35 return rendererMap;
36}
37
39 : accuracySetting(commandController,
40 "accuracy", "rendering accuracy", ACC_PIXEL,
42 {"screen", ACC_SCREEN},
43 {"line", ACC_LINE},
44 {"pixel", ACC_PIXEL}})
45
46 , deinterlaceSetting(commandController,
47 "deinterlace", "deinterlacing on/off", true)
48
49 , deflickerSetting(commandController,
50 "deflicker", "deflicker on/off", false)
51
52 , maxFrameSkipSetting(commandController,
53 "maxframeskip", "set the max amount of frameskip", 3, 0, 100)
54
55 , minFrameSkipSetting(commandController,
56 "minframeskip", "set the min amount of frameskip", 0, 0, 100)
57
58 , fullScreenSetting(commandController,
59 "fullscreen", "full screen display on/off", false)
60
61 , gammaSetting(commandController, "gamma",
62 "amount of gamma correction: low is dark, high is bright",
63 1.1, 0.1, 5.0)
64
65 , brightnessSetting(commandController, "brightness",
66 "brightness video setting: "
67 "0 is normal, lower is darker, higher is brighter",
68 0.0, -100.0, 100.0)
69 , contrastSetting(commandController, "contrast",
70 "contrast video setting: "
71 "0 is normal, lower is less contrast, higher is more contrast",
72 0.0, -100.0, 100.0)
73
74 , colorMatrixSetting(commandController,
75 "color_matrix",
76 "3x3 matrix to transform MSX RGB to host RGB, see manual for details",
77 "{ 1 0 0 } { 0 1 0 } { 0 0 1 }")
78
79 , glowSetting(commandController,
80 "glow", "amount of afterglow effect: 0 = none, 100 = lots",
81 0, 0, 100)
82
83 , noiseSetting(commandController,
84 "noise", "amount of noise to add to the frame",
85 0.0, 0.0, 100.0)
86
87 , rendererSetting(commandController,
88 "renderer", "rendering back-end used to display the MSX screen",
89 SDLGL_PP, getRendererMap(), Setting::DONT_SAVE)
90
91 , horizontalBlurSetting(commandController,
92 "blur", "amount of horizontal blur effect: 0 = none, 100 = full",
93 50, 0, 100)
94
95 , scaleAlgorithmSetting(
96 commandController, "scale_algorithm", "scale algorithm",
97 SCALER_SIMPLE, getScalerMap())
98
99 , scaleFactorSetting(commandController,
100 "scale_factor", "scale factor",
102
103 , scanlineAlphaSetting(commandController,
104 "scanline", "amount of scanline effect: 0 = none, 100 = full",
105 20, 0, 100)
106
107 , limitSpritesSetting(commandController,
108 "limitsprites", "limit number of sprites per line "
109 "(on for realism, off to reduce sprite flashing)", true)
110
111 , disableSpritesSetting(commandController,
112 "disablesprites", "disable sprite rendering",
113 false, Setting::DONT_SAVE)
114
115 , cmdTimingSetting(commandController,
116 "cmdtiming", "VDP command timing", false,
117 EnumSetting<bool>::Map{{"real", false}, {"broken", true}},
118 Setting::DONT_SAVE)
119
120 , tooFastAccessSetting(commandController,
121 "too_fast_vram_access",
122 "Should too fast VDP VRAM access be correctly emulated.\n"
123 "Possible values are:\n"
124 " real -> too fast accesses are dropped\n"
125 " ignore -> access speed is ignored, all accesses are executed",
126 false,
127 EnumSetting<bool>::Map{{"real", false }, {"ignore", true}},
128 Setting::DONT_SAVE)
129
130 , displayDeformSetting(
131 commandController,
132 "display_deform", "Display deform", DEFORM_NORMAL,
133 EnumSetting<DisplayDeform>::Map{
134 {"normal", DEFORM_NORMAL},
135 {"3d", DEFORM_3D}})
136
137 , vSyncSetting(commandController,
138 "vsync", "Synchronize page flip with the host screen vertical sync:\n"
139 " on -> flip on host vsync: avoids tearing\n"
140 " off -> immediate flip: might be more fluent when host framerate"
141 " (typically 60Hz) differs from MSX framerate (50 or 60Hz).\n",
142 true)
143
144 // Many android devices are relatively low powered. Therefore use
145 // no stretch (value 320) as default for Android because it gives
146 // better performance
147 , horizontalStretchSetting(commandController,
148 "horizontal_stretch",
149 "Amount of horizontal stretch: this many MSX pixels will be "
150 "stretched over the complete width of the output screen.\n"
151 " 320 = no stretch (large borders)\n"
152 " 288 = a bit more than all border pixels\n"
153 " 284 = all border pixels\n"
154 " 280 = a bit less than all border pixels\n"
155 " 272 = realistic\n"
156 " 256 = max stretch (no border visible at all)\n"
157 " good values are 272 or 280\n",
158 PLATFORM_ANDROID ? 320.0 : 280.0, 256.0, 320.0)
159
160 , pointerHideDelaySetting(commandController,
161 "pointer_hide_delay",
162 "number of seconds after which the mouse pointer is hidden in the openMSX "
163 "window; negative = no hiding, 0 = immediately",
164 2.0, -1.0, 60.0)
165
166 , interleaveBlackFrameSetting(commandController,
167 "interleave_black_frame",
168 "Insert a black frame in between each normal MSX frame. "
169 "Useful on (100Hz+) lightboost enabled monitors to reduce "
170 "motion blur and double frame artifacts.",
171 false)
172{
173 brightnessSetting.attach(*this);
174 contrastSetting .attach(*this);
175 updateBrightnessAndContrast();
176
177 auto& interp = commandController.getInterpreter();
178 colorMatrixSetting.setChecker([this, &interp](TclObject& newValue) {
179 try {
180 parseColorMatrix(interp, newValue);
181 } catch (CommandException& e) {
182 throw CommandException(
183 "Invalid color matrix: ", e.getMessage());
184 }
185 });
186 try {
187 parseColorMatrix(interp, colorMatrixSetting.getValue());
188 } catch (MSXException& e) {
189 std::cerr << e.getMessage() << '\n';
190 cmIdentity = true;
191 }
192
193 rendererSetting.setEnum(DUMMY); // always start hidden
194}
195
196RenderSettings::~RenderSettings()
197{
198 brightnessSetting.detach(*this);
199 contrastSetting .detach(*this);
200}
201
202void RenderSettings::update(const Setting& setting) noexcept
203{
204 if (&setting == &brightnessSetting) {
205 updateBrightnessAndContrast();
206 } else if (&setting == &contrastSetting) {
207 updateBrightnessAndContrast();
208 } else {
210 }
211}
212
213void RenderSettings::updateBrightnessAndContrast()
214{
215 float contrastValue = getContrast();
216 contrast = (contrastValue >= 0.0f) ? (1.0f + contrastValue * (1.0f / 25.0f))
217 : (1.0f + contrastValue * (1.0f / 125.0f));
218 brightness = (getBrightness() * (1.0f / 100.0f) - 0.5f) * contrast + 0.5f;
219}
220
221static float conv2(float x, float gamma)
222{
223 return ::powf(std::clamp(x, 0.0f, 1.0f), gamma);
224}
225
226float RenderSettings::transformComponent(float c) const
227{
228 float c2 = c * contrast + brightness;
229 return conv2(c2, 1.0f / getGamma());
230}
231
232vec3 RenderSettings::transformRGB(vec3 rgb) const
233{
234 auto [r, g, b] = colorMatrix * (rgb * contrast + vec3(brightness));
235 float gamma = 1.0f / getGamma();
236 return {conv2(r, gamma),
237 conv2(g, gamma),
238 conv2(b, gamma)};
239}
240
241void RenderSettings::parseColorMatrix(Interpreter& interp, const TclObject& value)
242{
243 if (value.getListLength(interp) != 3) {
244 throw CommandException("must have 3 rows");
245 }
246 bool identity = true;
247 for (auto i : xrange(3)) {
248 TclObject row = value.getListIndex(interp, i);
249 if (row.getListLength(interp) != 3) {
250 throw CommandException("each row must have 3 elements");
251 }
252 for (auto j : xrange(3)) {
253 TclObject element = row.getListIndex(interp, j);
254 float val = element.getFloat(interp);
255 colorMatrix[j][i] = val;
256 identity &= (val == (i == j ? 1.0f : 0.0f));
257 }
258 }
259 cmIdentity = identity;
260}
261
262} // namespace openmsx
BaseSetting * setting
int g
#define MIN_SCALE_FACTOR
Definition build-info.hh:18
#define PLATFORM_ANDROID
Definition build-info.hh:17
#define MAX_SCALE_FACTOR
Definition build-info.hh:19
EnumSettingBase::Map Map
Accuracy
Render accuracy: granularity of the rendered area.
RenderSettings(CommandController &commandController)
unsigned getListLength(Interpreter &interp) const
Definition TclObject.cc:156
TclObject getListIndex(Interpreter &interp, unsigned index) const
Definition TclObject.cc:174
constexpr double e
Definition Math.hh:21
Definition gl_mat.hh:23
vecN< 3, float > vec3
Definition gl_vec.hh:191
This file implemented 3 utility functions:
Definition Autofire.cc:9
#define UNREACHABLE
constexpr auto xrange(T e)
Definition xrange.hh:132