OXYGENHUB
◆ main openmsx / src / video / RenderSettings.hh
9.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef RENDERSETTINGS_HH
2
#define RENDERSETTINGS_HH
3
4
#include "BooleanSetting.hh"
5
#include "EnumSetting.hh"
6
#include "FloatSetting.hh"
7
#include "IntegerSetting.hh"
8
#include "StringSetting.hh"
9
10
#include "Observer.hh"
11
#include "gl_mat.hh"
12
#include "narrow.hh"
13
14
#include <cstdint>
15
16
namespace openmsx {
17
18
class CommandController;
19
class Interpreter;
20
21
/** Class containing all settings for renderers.
22
  * Keeping the settings here makes sure they are preserved when the user
23
  * switches to another renderer.
24
  */
25
class RenderSettings final : private Observer<Setting>
26
{
27
public:
28
	/** Enumeration of Renderers known to openMSX.
29
	  * This is the full list, the list of available renderers may be smaller.
30
	  */
31
	enum class RendererID : uint8_t { UNINITIALIZED, DUMMY, SDLGL_PP };
32
	using RendererSetting = EnumSetting<RendererID>;
33
34
	/** Render accuracy: granularity of the rendered area.
35
	  */
36
	enum class Accuracy : uint8_t { SCREEN, LINE, PIXEL };
37
38
	/** Scaler algorithm
39
	  */
40
	enum class ScaleAlgorithm : uint8_t {
41
		SIMPLE, SCALE, HQ, RGBTRIPLET, TV,
42
		NO
43
	};
44
45
	enum class DisplayDeform : uint8_t {
46
		NORMAL, _3D
47
	};
48
49
	explicit RenderSettings(CommandController& commandController);
50
	~RenderSettings();
51
52
	/** Accuracy [screen, line, pixel]. */
53
	[[nodiscard]] EnumSetting<Accuracy>& getAccuracySetting() { return accuracySetting; }
54
	[[nodiscard]] Accuracy getAccuracy() const { return accuracySetting.getEnum(); }
55
56
	/** Deinterlacing [on, off]. */
57
	[[nodiscard]] BooleanSetting& getDeinterlaceSetting() { return deinterlaceSetting; }
58
	[[nodiscard]] bool getDeinterlace() const { return deinterlaceSetting.getBoolean(); }
59
60
	/** Deflicker [on, off]. */
61
	[[nodiscard]] BooleanSetting& getDeflickerSetting() { return deflickerSetting; }
62
	[[nodiscard]] bool getDeflicker() const { return deflickerSetting.getBoolean(); }
63
64
	/** The current max frameskip. */
65
	[[nodiscard]] IntegerSetting& getMaxFrameSkipSetting() { return maxFrameSkipSetting; }
66
	[[nodiscard]] int getMaxFrameSkip() const { return maxFrameSkipSetting.getInt(); }
67
68
	/** The current min frameskip. */
69
	[[nodiscard]] IntegerSetting& getMinFrameSkipSetting() { return minFrameSkipSetting; }
70
	[[nodiscard]] int getMinFrameSkip() const { return minFrameSkipSetting.getInt(); }
71
72
	/** Full screen [on, off]. */
73
	[[nodiscard]] BooleanSetting& getFullScreenSetting() { return fullScreenSetting; }
74
	[[nodiscard]] bool getFullScreen() const { return fullScreenSetting.getBoolean(); }
75
76
	/** The amount of gamma correction. */
77
	[[nodiscard]] FloatSetting& getGammaSetting() { return gammaSetting; }
78
	[[nodiscard]] float getGamma() const { return gammaSetting.getFloat(); }
79
80
	/** Brightness video setting. */
81
	[[nodiscard]] FloatSetting& getBrightnessSetting() { return brightnessSetting; }
82
	[[nodiscard]] float getBrightness() const { return brightnessSetting.getFloat(); }
83
84
	/** Contrast video setting. */
85
	[[nodiscard]] FloatSetting& getContrastSetting() { return contrastSetting; }
86
	[[nodiscard]] float getContrast() const { return contrastSetting.getFloat(); }
87
88
	/** Color matrix setting. */
89
	[[nodiscard]] StringSetting& getColorMatrixSetting() { return colorMatrixSetting; }
90
	/** Returns true iff the current color matrix is the identity matrix. */
91
	[[nodiscard]] bool isColorMatrixIdentity() const { return cmIdentity; }
92
93
	/** The amount of glow [0..100]. */
94
	[[nodiscard]] IntegerSetting& getGlowSetting() { return glowSetting; }
95
	[[nodiscard]] int getGlow() const { return glowSetting.getInt(); }
96
97
	/** The amount of noise to add to the frame. */
98
	[[nodiscard]] FloatSetting& getNoiseSetting() { return noiseSetting; }
99
	[[nodiscard]] float getNoise() const { return noiseSetting.getFloat(); }
100
101
	/** The amount of horizontal blur [0..256]. */
102
	[[nodiscard]] IntegerSetting& getBlurSetting() { return horizontalBlurSetting; }
103
	[[nodiscard]] int getBlurFactor() const {
104
		return (horizontalBlurSetting.getInt()) * 256 / 100;
105
	}
106
107
	/** The alpha value [0..255] of the gap between scanlines. */
108
	[[nodiscard]] IntegerSetting& getScanlineSetting() { return scanlineAlphaSetting; }
109
	[[nodiscard]] int getScanlineFactor() const {
110
		return 255 - ((scanlineAlphaSetting.getInt() * 255) / 100);
111
	}
112
	/** The amount of space [0..1] between scanlines. */
113
	[[nodiscard]] float getScanlineGap() const {
114
		return narrow<float>(scanlineAlphaSetting.getInt()) * 0.01f;
115
	}
116
117
	/** The current renderer. */
118
	[[nodiscard]] RendererSetting& getRendererSetting() { return rendererSetting; }
119
	[[nodiscard]] RendererID getRenderer() const {
120
		auto r = rendererSetting.getEnum();
121
		return r == RendererID::UNINITIALIZED ? RendererID::DUMMY : r;
122
	}
123
124
	/** The current scaling algorithm. */
125
	[[nodiscard]] auto& getScaleAlgorithmSetting() { return scaleAlgorithmSetting; }
126
	[[nodiscard]] ScaleAlgorithm getScaleAlgorithm() const {
127
		return scaleAlgorithmSetting.getEnum();
128
	}
129
130
	/** The current scaling factor. */
131
	[[nodiscard]] IntegerSetting& getScaleFactorSetting() { return scaleFactorSetting; }
132
	[[nodiscard]] int getScaleFactor() const { return scaleFactorSetting.getInt(); }
133
134
	/** Limit number of sprites per line?
135
	  * If true, limit number of sprites per line as real VDP does.
136
	  * If false, display all sprites.
137
	  * For accurate emulation, this setting should be on.
138
	  * Turning it off can improve games with a lot of flashing sprites,
139
	  * such as Aleste. */
140
	[[nodiscard]] BooleanSetting& getLimitSpritesSetting() { return limitSpritesSetting; }
141
142
	/** Disable sprite rendering? */
143
	[[nodiscard]] BooleanSetting& getDisableSpritesSetting() { return disableSpritesSetting; }
144
	[[nodiscard]] bool getDisableSprites() const { return disableSpritesSetting.getBoolean(); }
145
146
	/** CmdTiming [real, broken].
147
	  * This setting is intended for debugging only, not for users. */
148
	[[nodiscard]] EnumSetting<bool>& getCmdTimingSetting() { return cmdTimingSetting; }
149
150
	/** TooFastAccess [real, ignored].
151
	  * Indicates whether too fast VDP VRAM access should be correctly
152
	  * emulated (= some accesses are dropped) or ignored (= all accesses
153
	  * are correctly executed). */
154
	[[nodiscard]] EnumSetting<bool>& getTooFastAccessSetting() { return tooFastAccessSetting; }
155
156
	/** Display deformation (normal, 3d). */
157
	[[nodiscard]] auto& getDisplayDeformSetting() { return displayDeformSetting; }
158
	[[nodiscard]] DisplayDeform getDisplayDeform() const { return displayDeformSetting.getEnum(); }
159
160
	/** VSync [on, off]. */
161
	[[nodiscard]] BooleanSetting& getVSyncSetting() { return vSyncSetting; }
162
163
	[[nodiscard]] BooleanSetting& getFullStretchSetting() { return fullStretchSetting; }
164
	[[nodiscard]] bool getFullStretch() const { return fullStretchSetting.getBoolean(); }
165
166
	/** Amount of horizontal stretch.
167
	  * This number represents the amount of MSX pixels (normal width) that
168
	  * will be stretched to the complete width of the host window. */
169
	[[nodiscard]] FloatSetting& getHorizontalStretchSetting() {
170
		return horizontalStretchSetting;
171
	}
172
	[[nodiscard]] float getHorizontalStretch() const {
173
		return horizontalStretchSetting.getFloat();
174
	}
175
176
	/** The amount of time until the pointer is hidden in the openMSX
177
	  * window. negative means: no hiding, 0 means immediately. */
178
	[[nodiscard]] FloatSetting& getPointerHideDelaySetting() {
179
		return pointerHideDelaySetting;
180
	}
181
	[[nodiscard]] float getPointerHideDelay() const {
182
		return pointerHideDelaySetting.getFloat();
183
	}
184
185
	/** Is black frame interleaving enabled? */
186
	[[nodiscard]] bool getInterleaveBlackFrame() const {
187
		return interleaveBlackFrameSetting.getBoolean();
188
	}
189
190
	/** Apply brightness, contrast and gamma transformation on the input
191
	  * color component. The component is expected to be in the range
192
	  * [0.0 .. 1.0] but it's not an error if it lays outside of this range.
193
	  * The return value is guaranteed to lay inside this range.
194
	  * This method skips the cross-influence of color components on each
195
	  * other that is controlled by the "color_matrix" setting.
196
	  */
197
	[[nodiscard]] float transformComponent(float c) const;
198
199
	/** Apply brightness, contrast and gamma transformation on the input
200
	  * color. The R, G and B component are expected to be in the range
201
	  * [0.0 .. 1.0] but it's not an error if a component lays outside of
202
	  * this range. After transformation it's guaranteed all components
203
	  * lay inside this range.
204
	  */
205
	[[nodiscard]] gl::vec3 transformRGB(gl::vec3 rgb) const;
206
207
private:
208
	[[nodiscard]] static EnumSetting<ScaleAlgorithm>::Map getScalerMap();
209
	[[nodiscard]] static EnumSetting<RendererID>::Map getRendererMap();
210
211
	// Observer:
212
	void update(const Setting& setting) noexcept override;
213
214
	/** Sets the "brightness" and "contrast" fields according to the setting
215
	  * values.
216
	  */
217
	void updateBrightnessAndContrast();
218
219
	void parseColorMatrix(Interpreter& interp, const TclObject& value);
220
221
private:
222
	EnumSetting<Accuracy> accuracySetting;
223
	BooleanSetting deinterlaceSetting;
224
	BooleanSetting deflickerSetting;
225
	IntegerSetting maxFrameSkipSetting;
226
	IntegerSetting minFrameSkipSetting;
227
	BooleanSetting fullScreenSetting;
228
	FloatSetting gammaSetting;
229
	FloatSetting brightnessSetting;
230
	FloatSetting contrastSetting;
231
	StringSetting colorMatrixSetting;
232
	IntegerSetting glowSetting;
233
	FloatSetting noiseSetting;
234
	RendererSetting rendererSetting;
235
	IntegerSetting horizontalBlurSetting;
236
	EnumSetting<ScaleAlgorithm> scaleAlgorithmSetting;
237
	IntegerSetting scaleFactorSetting;
238
	IntegerSetting scanlineAlphaSetting;
239
	BooleanSetting limitSpritesSetting;
240
	BooleanSetting disableSpritesSetting;
241
	EnumSetting<bool> cmdTimingSetting;
242
	EnumSetting<bool> tooFastAccessSetting;
243
	EnumSetting<DisplayDeform> displayDeformSetting;
244
	BooleanSetting vSyncSetting;
245
	BooleanSetting fullStretchSetting;
246
	FloatSetting horizontalStretchSetting;
247
	FloatSetting pointerHideDelaySetting;
248
	BooleanSetting interleaveBlackFrameSetting;
249
250
	float brightness;
251
	float contrast;
252
253
	/** Parsed color matrix, kept in sync with colorMatrix setting. */
254
	gl::mat3 colorMatrix;
255
	/** True iff color matrix is identity matrix. */
256
	bool cmIdentity;
257
};
258
259
} // namespace openmsx
260
261
#endif