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] = [&] {
173 if ((toX == lastX) && (toY == lastY))
return;
180 if (displayEnabled) {
182 subdivide(lastX, lastY, toX, toY, 0, left, DRAW_BORDER);
188 subdivide(lastX, lastY, toX, toY, left, right, DRAW_DISPLAY);
190 subdivide(lastX, lastY, toX, toY, right, rightEdge, DRAW_BORDER);
193 subdivide(lastX, lastY, toX, toY, 0, rightEdge, DRAW_BORDER);
200void V9990PixelRenderer::subdivide(
int fromX,
int fromY,
int toX,
int toY,
201 int clipL,
int clipR, DrawType drawType)
206 bool atEnd = (fromY != toY) || (toX >= clipR);
207 draw(fromX, fromY, (atEnd ? clipR : toX), fromY + 1,
210 if (fromY == toY)
return;
214 bool drawLast =
false;
217 }
else if (toX > clipL) {
222 draw(clipL, fromY, clipR, toY, drawType);
226 if (drawLast) draw(clipL, toY, toX, toY + 1, drawType);
229void V9990PixelRenderer::draw(
int fromX,
int fromY,
int toX,
int toY,
232 if (type == DRAW_BORDER) {
233 rasterizer->drawBorder(fromX, fromY, toX, toY);
236 assert(type == DRAW_DISPLAY);
240 int displayYA = fromY - verticalOffsetA;
241 int displayYB = fromY - verticalOffsetB;
243 rasterizer->drawDisplay(fromX, fromY, toX, toY,
245 displayY, displayYA, displayYB);
252 displayEnabled = enabled;
258 rasterizer->setDisplayMode(mode);
264 if (displayEnabled) {
270 rasterizer->setPalette(index, r,
g, b, ys);
275 rasterizer->setSuperimpose(enabled);
280 rasterizer->setColorMode(mode);
290 if (displayEnabled) sync(time);
295 if (displayEnabled) sync(time);
299 if (displayEnabled) {
303 verticalOffsetA = lastY;
309 if (displayEnabled) {
313 verticalOffsetB = lastY;
319 assert(&
setting ==
one_of(&renderSettings.getMinFrameSkipSetting(),
320 &renderSettings.getMaxFrameSkipSetting()));
323 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() const
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) const
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
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: