OXYGENHUB
◆ main openmsx / src / video / PixelRenderer.hh
6.0 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef PIXELRENDERER_HH
2
#define PIXELRENDERER_HH
3
4
#include "RenderSettings.hh"
5
#include "Renderer.hh"
6
7
#include "Observer.hh"
8
9
#include <cstdint>
10
#include <memory>
11
12
namespace openmsx {
13
14
class EventDistributor;
15
class RealTime;
16
class SpeedManager;
17
class ThrottleManager;
18
class Display;
19
class Rasterizer;
20
class VDP;
21
class VDPVRAM;
22
class SpriteChecker;
23
class DisplayMode;
24
class Setting;
25
class VideoSourceSetting;
26
27
/** Generic implementation of a pixel-based Renderer.
28
  * Uses a Rasterizer to plot actual pixels for a specific video system.
29
  */
30
class PixelRenderer final : public Renderer, private Observer<Setting>
31
{
32
public:
33
	PixelRenderer(VDP& vdp, Display& display);
34
	~PixelRenderer() override;
35
36
	// Renderer interface:
37
	[[nodiscard]] PostProcessor* getPostProcessor() const override;
38
	[[nodiscard]] const RawFrame* getWorkingFrame(EmuTime time) override;
39
	[[nodiscard]] const RawFrame* getLastFrame() const override;
40
	void reInit() override;
41
	void frameStart(EmuTime time) override;
42
	void frameEnd(EmuTime time) override;
43
	void updateHorizontalScrollLow(uint8_t scroll, EmuTime time) override;
44
	void updateHorizontalScrollHigh(uint8_t scroll, EmuTime time) override;
45
	void updateBorderMask(bool masked, EmuTime time) override;
46
	void updateMultiPage(bool multiPage, EmuTime time) override;
47
	void updateTransparency(bool enabled, EmuTime time) override;
48
	void updateSuperimposing(const RawFrame* videoSource, EmuTime time) override;
49
	void updateForegroundColor(uint8_t color, EmuTime time) override;
50
	void updateBackgroundColor(uint8_t color, EmuTime time) override;
51
	void updateBlinkForegroundColor(uint8_t color, EmuTime time) override;
52
	void updateBlinkBackgroundColor(uint8_t color, EmuTime time) override;
53
	void updateBlinkState(bool enabled, EmuTime time) override;
54
	void updatePalette(unsigned index, int grb, EmuTime time) override;
55
	void updateVerticalScroll(int scroll, EmuTime time) override;
56
	void updateHorizontalAdjust(int adjust, EmuTime time) override;
57
	void updateLineZero(EmuTime time) override;
58
	void updateDisplayEnabled(bool enabled, EmuTime time) override;
59
	void updateDisplayMode(DisplayMode mode, EmuTime time) override;
60
	void updateNameBase(unsigned addr, EmuTime time) override;
61
	void updatePatternBase(unsigned addr, EmuTime time) override;
62
	void updateColorBase(unsigned addr, EmuTime time) override;
63
	void updateSpritesEnabled(bool enabled, EmuTime time) override;
64
	void updateVRAM(unsigned offset, EmuTime time) override;
65
	void updateWindow(bool enabled, EmuTime time) override;
66
67
private:
68
	/** Indicates whether the area to be drawn is border or display. */
69
	enum DrawType : uint8_t { DRAW_BORDER, DRAW_DISPLAY };
70
71
	// Observer<Setting> interface:
72
	void update(const Setting& setting) noexcept override;
73
74
	/** Call the right draw method in the subclass,
75
	  * depending on passed drawType.
76
	  */
77
	void draw(
78
		int startX, int startY, int endX, int endY, DrawType drawType,
79
		bool atEnd);
80
81
	/** Subdivide an area specified by two scan positions into a series of
82
	  * rectangles.
83
	  * Clips the rectangles to { (x,y) | clipL <= x < clipR }.
84
	  * @param drawType
85
	  *   If DRAW_BORDER, draw rectangles using drawBorder;
86
	  *   if DRAW_DISPLAY, draw rectangles using drawDisplay.
87
	  */
88
	void subdivide(
89
		int startX, int startY, int endX, int endY,
90
		int clipL, int clipR, DrawType drawType);
91
92
	[[nodiscard]] bool checkSync(unsigned offset, EmuTime time) const;
93
94
	/** Update renderer state to specified moment in time.
95
	  * @param time Moment in emulated time to update to.
96
	  * @param force When screen accuracy is used,
97
	  *     rendering is only performed if this parameter is true.
98
	  */
99
	void sync(EmuTime time, bool force = false);
100
101
	/** Render lines until specified moment in time.
102
	  * Unlike sync(), this method does not sync with VDPVRAM.
103
	  * The VRAM should be to be up to date and remain unchanged
104
	  * from the current time to the specified time.
105
	  * @param time Moment in emulated time to render lines until.
106
	  */
107
	void renderUntil(EmuTime time);
108
109
private:
110
	/** The VDP of which the video output is being rendered.
111
	  */
112
	VDP& vdp;
113
114
	/** The VRAM whose contents are rendered.
115
	  */
116
	VDPVRAM& vram;
117
118
	EventDistributor& eventDistributor;
119
	RealTime& realTime;
120
	SpeedManager& speedManager;
121
	ThrottleManager& throttleManager;
122
	RenderSettings& renderSettings;
123
	VideoSourceSetting& videoSourceSetting;
124
125
	/** The sprite checker whose sprites are rendered.
126
	  */
127
	SpriteChecker& spriteChecker;
128
129
	const std::unique_ptr<Rasterizer> rasterizer;
130
131
	float finishFrameDuration = 0.0f;
132
	float frameSkipCounter = 999.0f; // force drawing of frame
133
134
	/** Number of the next position within a line to render.
135
	  * Expressed in VDP clock ticks since start of line.
136
	  */
137
	int nextX;
138
139
	/** Number of the next line to render.
140
	  * Expressed in number of lines since start of frame.
141
	  */
142
	int nextY;
143
144
	// internal VDP counter, actually belongs in VDP
145
	int textModeCounter;
146
147
	/** Vertical scroll (R#23) as used for drawing. The V99x8 fetches
148
	  * bitmap VRAM in bursts of 8 pixels (one row address per burst, see
149
	  * doc/internal/vdp-vram-timing), so a mid-line R#23 change only
150
	  * reaches the screen at a later 8-pixel group boundary.
151
	  */
152
	int renderScroll = 0;
153
	int pendingScroll = 0;
154
	int pendingScrollTicks = -1; // -1: nothing pending
155
	void applyPendingScroll(EmuTime time);
156
157
	/** Accuracy setting for current frame.
158
	  */
159
	RenderSettings::Accuracy accuracy;
160
161
	/** Is display enabled?
162
	  * Enabled means the current line is in the display area and
163
	  * forced blanking is off.
164
	  */
165
	bool displayEnabled;
166
167
	/** Should current frame be draw or can it be skipped.
168
	  */
169
	bool renderFrame;
170
	bool prevRenderFrame = false;
171
172
	/** Should a rendered frame be painted to the window?
173
	  * When renderFrame is false, paintFrame must be false as well.
174
	  * But when recording, renderFrame will be true for every frame,
175
	  * while paintFrame may not.
176
	  */
177
	bool paintFrame;
178
179
	/** Timestamp (us, like Timer::getTime()) at which we last painted a frame.
180
	  * Used to force a minimal paint rate when throttle is off.
181
	  */
182
	uint64_t lastPaintTime = 0;
183
};
184
185
} // namespace openmsx
186
187
#endif