27 , eventDistributor(vdp.getReactor().getEventDistributor())
28 , realTime(vdp.getMotherBoard().getRealTime())
29 , renderSettings(vdp.getReactor().getDisplay().getRenderSettings())
30 , videoSourceSetting(vdp.getMotherBoard().getVideoSource())
31 , rasterizer(vdp.getReactor().getDisplay().
32 getVideoSystem().createV9990Rasterizer(vdp))
48 return rasterizer->getPostProcessor();
62 if (!rasterizer->isActive()) {
63 frameSkipCounter = 999;
65 prevDrawFrame =
false;
68 prevDrawFrame = drawFrame;
81 if (rasterizer->isRecording()) {
85 unsigned(finishFrameDuration), time);
92 if (!drawFrame)
return;
101 rasterizer->frameStart();
106 bool skipEvent = !drawFrame;
112 rasterizer->frameEnd(time);
114 auto current = narrow_cast<float>(time2 - time1);
115 const float ALPHA = 0.2f;
116 finishFrameDuration = finishFrameDuration * (1 - ALPHA) +
131 rasterizer->getPostProcessor()->getVideoSource(),
137void V9990PixelRenderer::sync(EmuTime::param time,
bool force)
139 if (!drawFrame)
return;
147void V9990PixelRenderer::renderUntil(EmuTime::param time)
153 auto [toX, toY] = [&] {
170 return std::pair{0, 0};
174 if ((toX == lastX) && (toY == lastY))
return;
181 if (displayEnabled) {
183 subdivide(lastX, lastY, toX, toY, 0, left, DRAW_BORDER);
189 subdivide(lastX, lastY, toX, toY, left, right, DRAW_DISPLAY);
191 subdivide(lastX, lastY, toX, toY, right, rightEdge, DRAW_BORDER);
194 subdivide(lastX, lastY, toX, toY, 0, rightEdge, DRAW_BORDER);
201void V9990PixelRenderer::subdivide(
int fromX,
int fromY,
int toX,
int toY,
202 int clipL,
int clipR, DrawType drawType)
207 bool atEnd = (fromY != toY) || (toX >= clipR);
208 draw(fromX, fromY, (atEnd ? clipR : toX), fromY + 1,
211 if (fromY == toY)
return;
215 bool drawLast =
false;
218 }
else if (toX > clipL) {
223 draw(clipL, fromY, clipR, toY, drawType);
227 if (drawLast) draw(clipL, toY, toX, toY + 1, drawType);
230void V9990PixelRenderer::draw(
int fromX,
int fromY,
int toX,
int toY,
233 if (type == DRAW_BORDER) {
234 rasterizer->drawBorder(fromX, fromY, toX, toY);
237 assert(type == DRAW_DISPLAY);
241 int displayYA = fromY - verticalOffsetA;
242 int displayYB = fromY - verticalOffsetB;
244 rasterizer->drawDisplay(fromX, fromY, toX, toY,
246 displayY, displayYA, displayYB);
253 displayEnabled = enabled;
259 rasterizer->setDisplayMode(mode);
265 if (displayEnabled) {
271 rasterizer->setPalette(index, r,
g, b, ys);
276 rasterizer->setSuperimpose(enabled);
281 rasterizer->setColorMode(mode);
291 if (displayEnabled) sync(time);
296 if (displayEnabled) sync(time);
300 if (displayEnabled) {
304 verticalOffsetA = lastY;
310 if (displayEnabled) {
314 verticalOffsetB = lastY;
320 assert(&
setting ==
one_of(&renderSettings.getMinFrameSkipSetting(),
321 &renderSettings.getMaxFrameSkipSetting()));
324 frameSkipCounter = 999;
void distributeEvent(Event &&event)
Schedule the given event for delivery.
This event is send when a device (v99x8, v9990, video9000, laserdisc) reaches the end of a frame.
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
EmuTime::param getCurrentTime()
Convenience method: This is the same as getScheduler().getCurrentTime().
bool isFastForwarding() const
A post processor builds the frame that is displayed from the MSX frame, while applying effects such a...
bool timeLeft(uint64_t us, EmuTime::param time)
Check that there is enough real time left before we reach as certain point in emulated time.
bool getDeinterlace() const
IntegerSetting & getMinFrameSkipSetting()
The current min frameskip.
Accuracy getAccuracy() const
Accuracy [screen, line, pixel].
int getMinFrameSkip() const
int getMaxFrameSkip() const
IntegerSetting & getMaxFrameSkipSetting()
The current max frameskip.
void detach(Observer< T > &observer)
void attach(Observer< T > &observer)
static constexpr int UC_TICKS_PER_LINE
The number of clock ticks per line is independent of the crystal used or the display mode (NTSC/PAL)
static constexpr int getUCTicksPerFrame(bool palTiming)
Get the number of UC ticks in 1 frame.
V9990PixelRenderer(V9990 &vdp)
void updateScrollBX(EmuTime::param time) override
void updatePalette(int index, byte r, byte g, byte b, bool ys, EmuTime::param time) override
Set a palette entry.
void setDisplayMode(V9990DisplayMode mode, EmuTime::param time) override
Set screen mode.
~V9990PixelRenderer() override
void updateScrollAYLow(EmuTime::param time) override
void reset(EmuTime::param time) override
Re-initialise the V9990Renderer's state.
void updateScrollAX(EmuTime::param time) override
Set scroll register.
void updateSuperimposing(bool enabled, EmuTime::param time) override
Change superimpose status.
PostProcessor * getPostProcessor() const override
See V9990::getPostProcessor.
void updateScrollBYLow(EmuTime::param time) override
void frameEnd(EmuTime::param time) override
Signal the end of the current frame.
void updateBackgroundColor(int index, EmuTime::param time) override
Set background color.
void updateDisplayEnabled(bool enabled, EmuTime::param time) override
Informs the renderer of a VDP display enabled change.
void frameStart(EmuTime::param time) override
Signal the start of a new frame.
void setColorMode(V9990ColorMode mode, EmuTime::param time) override
Set color mode.
void sync(EmuTime::param time)
Update VRAM state to specified moment in time.
Implementation of the Yamaha V9990 VDP as used in the GFX9000 cartridge by Sunrise.
bool isPalTiming() const
Is PAL timing active? This setting is fixed at start of frame.
int getUCTicksThisFrame(EmuTime::param time) const
Get the number of elapsed UC ticks in this frame.
V9990VRAM & getVRAM()
Obtain a reference to the V9990's VRAM.
bool isInterlaced() const
Get interlace status.
bool isEvenOddEnabled() const
Get even/odd page alternation status.
V9990DisplayMode getDisplayMode() const
Return the current display mode.
int getLeftBorder() const
Get the number of VDP clock-ticks between the start of the line and the end of the left border.
bool isDisplayEnabled() const
Is the display enabled? Note this is simpler than the V99x8 version.
V9990ColorMode getColorMode() const
Return the current color mode.
int getRightBorder() const
Get the number of VDP clock-ticks between the start of the line and the end of the right border.
bool getEvenOdd() const
Is the even or odd field being displayed?
uint64_t getTime()
Get current (real) time in us.
This file implemented 3 utility functions: