OXYGENHUB
◆ main openmsx / src / video / v9990 / V9990PixelRenderer.hh
3.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef V9990PIXELRENDERER_HH
2
#define V9990PIXELRENDERER_HH
3
4
#include "V9990Renderer.hh"
5
6
#include "Observer.hh"
7
#include "RenderSettings.hh"
8
9
#include <cstdint>
10
#include <memory>
11
12
namespace openmsx {
13
14
class V9990;
15
class V9990Rasterizer;
16
class Setting;
17
class EventDistributor;
18
class RealTime;
19
class VideoSourceSetting;
20
21
/** Generic pixel based renderer for the V9990.
22
  * Uses a rasterizer to plot actual pixels for a specific video system
23
  *
24
  * @see PixelRenderer.cc
25
  */
26
class V9990PixelRenderer final : public V9990Renderer
27
                               , private Observer<Setting>
28
{
29
public:
30
	explicit V9990PixelRenderer(V9990& vdp);
31
	~V9990PixelRenderer() override;
32
33
	// V9990Renderer interface:
34
	[[nodiscard]] PostProcessor* getPostProcessor() const override;
35
	void reset(EmuTime time) override;
36
	void frameStart(EmuTime time) override;
37
	void frameEnd(EmuTime time) override;
38
	void updateDisplayEnabled(bool enabled, EmuTime time) override;
39
	void setDisplayMode(V9990DisplayMode mode, EmuTime time) override;
40
	void setColorMode(V9990ColorMode mode, EmuTime time) override;
41
	void updatePalette(int index, uint8_t r, uint8_t g, uint8_t b, bool ys,
42
	                   EmuTime time) override;
43
	void updateSuperimposing(bool enabled, EmuTime time) override;
44
	void updateBackgroundColor(int index, EmuTime time) override;
45
	void updateScrollAX(EmuTime time) override;
46
	void updateScrollBX(EmuTime time) override;
47
	void updateScrollAYLow(EmuTime time) override;
48
	void updateScrollBYLow(EmuTime time) override;
49
50
private:
51
	void sync(EmuTime time, bool force = false);
52
	void renderUntil(EmuTime time) override;
53
54
	/** Type of drawing to do.
55
	  */
56
	enum DrawType : uint8_t {
57
		DRAW_BORDER,
58
		DRAW_DISPLAY
59
	};
60
61
	/**
62
	  */
63
	void draw(int fromX, int fromY, int toX, int toY, DrawType type);
64
65
	/** Subdivide an area specified by two scan positions into a series of
66
	  * rectangles
67
	  */
68
	void subdivide(int fromX, int fromY, int toX, int toY,
69
	               int clipL, int clipR, DrawType drawType);
70
71
	// Observer<Setting>
72
	void update(const Setting& setting) noexcept override;
73
74
private:
75
	/** The V9990 VDP
76
	  */
77
	V9990& vdp;
78
79
	EventDistributor& eventDistributor;
80
	RealTime& realTime;
81
82
	/** Settings shared between all renderers
83
	  */
84
	RenderSettings& renderSettings;
85
	VideoSourceSetting& videoSourceSetting;
86
87
	/** The Rasterizer
88
	  */
89
	const std::unique_ptr<V9990Rasterizer> rasterizer;
90
91
	/** Frameskip
92
	  */
93
	float finishFrameDuration{0.0f};
94
	int frameSkipCounter{999}; // force drawing of frame;
95
96
	/** Accuracy setting for current frame.
97
	 */
98
	RenderSettings::Accuracy accuracy;
99
100
	/** The last sync point's vertical position. In lines, starting
101
	  * from VSYNC
102
	  */
103
	int lastY;
104
105
	/** The last sync point's horizontal position in UC ticks, starting
106
	  * from HSYNC
107
	  */
108
	int lastX;
109
110
	/** Apparently V9990 keeps an internal counter that indicates which line
111
	  * to display. That counter is initialized at the top of the screen and
112
	  * increased after every line. The counter is also reset when the
113
	  * vertical scroll register is written to (even when same value is
114
	  * written). Note: this is different from V99x8 behaviour!
115
	  * TODO we don't actually store the counter but an offset (so that the
116
	  *      V99x8 drawing algorithm can still be used. Code might become
117
	  *      simpler if we do store the counter.
118
	  */
119
	int verticalOffsetA;
120
	int verticalOffsetB;
121
122
	/** Is display enabled?
123
	  * Enabled means the current line is in the display area and
124
	  * forced blanking is off.
125
	  */
126
	bool displayEnabled;
127
128
	/** Should current frame be draw or can it be skipped.
129
	  */
130
	bool drawFrame{false}; // don't draw before frameStart is called
131
	bool prevDrawFrame{false};
132
};
133
134
} // namespace openmsx
135
136
#endif