26 , eventDistributor(vdp.getReactor().getEventDistributor())
27 , realTime(vdp.getMotherBoard().getRealTime())
28 , renderSettings(vdp.getReactor().getDisplay().getRenderSettings())
29 , videoSourceSetting(vdp.getMotherBoard().getVideoSource())
30 , rasterizer(vdp.getReactor().getDisplay().
31 getVideoSystem().createV9990Rasterizer(vdp))
33 frameSkipCounter = 999;
34 finishFrameDuration = 0;
36 prevDrawFrame =
false;
52 return rasterizer->getPostProcessor();
66 if (!rasterizer->isActive()) {
67 frameSkipCounter = 999;
69 prevDrawFrame =
false;
72 prevDrawFrame = drawFrame;
85 if (rasterizer->isRecording()) {
89 unsigned(finishFrameDuration), time);
96 if (!drawFrame)
return;
105 rasterizer->frameStart();
110 bool skipEvent = !drawFrame;
116 rasterizer->frameEnd(time);
118 auto current = time2 - time1;
119 const float ALPHA = 0.2f;
120 finishFrameDuration = finishFrameDuration * (1 - ALPHA) +
135 Event::create<FinishFrameEvent>(
136 rasterizer->getPostProcessor()->getVideoSource(),
142 void V9990PixelRenderer::sync(EmuTime::param time,
bool force)
144 if (!drawFrame)
return;
152 void V9990PixelRenderer::renderUntil(EmuTime::param time)
158 auto [toX, toY] = [&] {
175 return std::pair{0, 0};
179 if ((toX == lastX) && (toY == lastY))
return;
186 if (displayEnabled) {
188 subdivide(lastX, lastY, toX, toY, 0, left, DRAW_BORDER);
194 subdivide(lastX, lastY, toX, toY, left, right, DRAW_DISPLAY);
196 subdivide(lastX, lastY, toX, toY, right, rightEdge, DRAW_BORDER);
199 subdivide(lastX, lastY, toX, toY, 0, rightEdge, DRAW_BORDER);
206 void V9990PixelRenderer::subdivide(
int fromX,
int fromY,
int toX,
int toY,
207 int clipL,
int clipR, DrawType drawType)
212 bool atEnd = (fromY != toY) || (toX >= clipR);
213 draw(fromX, fromY, (atEnd ? clipR : toX), fromY + 1,
216 if (fromY == toY)
return;
220 bool drawLast =
false;
223 }
else if (toX > clipL) {
228 draw(clipL, fromY, clipR, toY, drawType);
232 if (drawLast) draw(clipL, toY, toX, toY + 1, drawType);
235 void V9990PixelRenderer::draw(
int fromX,
int fromY,
int toX,
int toY,
238 if (type == DRAW_BORDER) {
239 rasterizer->drawBorder(fromX, fromY, toX, toY);
242 assert(type == DRAW_DISPLAY);
246 int displayYA = fromY - verticalOffsetA;
247 int displayYB = fromY - verticalOffsetB;
249 rasterizer->drawDisplay(fromX, fromY, toX, toY,
251 displayY, displayYA, displayYB);
258 displayEnabled = enabled;
264 rasterizer->setDisplayMode(mode);
270 if (displayEnabled) {
276 rasterizer->setPalette(index, r,
g, b, ys);
281 rasterizer->setSuperimpose(enabled);
286 rasterizer->setColorMode(mode);
296 if (displayEnabled) sync(time);
301 if (displayEnabled) sync(time);
305 if (displayEnabled) {
309 verticalOffsetA = lastY;
315 if (displayEnabled) {
319 verticalOffsetB = lastY;
325 assert(&
setting ==
one_of(&renderSettings.getMinFrameSkipSetting(),
326 &renderSettings.getMaxFrameSkipSetting()));
329 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 clockticks 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.
bool isInterlaced() const
Get interlace status.
bool isEvenOddEnabled() const
Get even/odd page alternation status.
V9990DisplayMode getDisplayMode() const
Return the current display mode.
V9990VRAM & getVRAM()
Obtain a reference to the V9990's VRAM.
int getLeftBorder() const
Get the number of VDP clockticks 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 clockticks 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: