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 Event::create<FinishFrameEvent>(
132 rasterizer->getPostProcessor()->getVideoSource(),
138void V9990PixelRenderer::sync(EmuTime::param time,
bool force)
140 if (!drawFrame)
return;
148void V9990PixelRenderer::renderUntil(EmuTime::param time)
154 auto [toX, toY] = [&] {
171 return std::pair{0, 0};
175 if ((toX == lastX) && (toY == lastY))
return;
182 if (displayEnabled) {
184 subdivide(lastX, lastY, toX, toY, 0, left, DRAW_BORDER);
190 subdivide(lastX, lastY, toX, toY, left, right, DRAW_DISPLAY);
192 subdivide(lastX, lastY, toX, toY, right, rightEdge, DRAW_BORDER);
195 subdivide(lastX, lastY, toX, toY, 0, rightEdge, DRAW_BORDER);
202void V9990PixelRenderer::subdivide(
int fromX,
int fromY,
int toX,
int toY,
203 int clipL,
int clipR, DrawType drawType)
208 bool atEnd = (fromY != toY) || (toX >= clipR);
209 draw(fromX, fromY, (atEnd ? clipR : toX), fromY + 1,
212 if (fromY == toY)
return;
216 bool drawLast =
false;
219 }
else if (toX > clipL) {
224 draw(clipL, fromY, clipR, toY, drawType);
228 if (drawLast) draw(clipL, toY, toX, toY + 1, drawType);
231void V9990PixelRenderer::draw(
int fromX,
int fromY,
int toX,
int toY,
234 if (type == DRAW_BORDER) {
235 rasterizer->drawBorder(fromX, fromY, toX, toY);
238 assert(type == DRAW_DISPLAY);
242 int displayYA = fromY - verticalOffsetA;
243 int displayYB = fromY - verticalOffsetB;
245 rasterizer->drawDisplay(fromX, fromY, toX, toY,
247 displayY, displayYA, displayYB);
254 displayEnabled = enabled;
260 rasterizer->setDisplayMode(mode);
266 if (displayEnabled) {
272 rasterizer->setPalette(index, r,
g, b, ys);
277 rasterizer->setSuperimpose(enabled);
282 rasterizer->setColorMode(mode);
292 if (displayEnabled) sync(time);
297 if (displayEnabled) sync(time);
301 if (displayEnabled) {
305 verticalOffsetA = lastY;
311 if (displayEnabled) {
315 verticalOffsetB = lastY;
321 assert(&
setting ==
one_of(&renderSettings.getMinFrameSkipSetting(),
322 &renderSettings.getMaxFrameSkipSetting()));
325 frameSkipCounter = 999;
void distributeEvent(Event &&event)
Schedule the given event for delivery.
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
Abstract base class for post processors.
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
Deinterlacing [on, off].
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: