31 void PixelRenderer::draw(
32 int startX,
int startY,
int endX,
int endY, DrawType drawType,
bool atEnd)
34 if (drawType == DRAW_BORDER) {
35 rasterizer->drawBorder(startX, startY, endX, endY);
37 assert(drawType == DRAW_DISPLAY);
42 int displayY = startY - zero;
48 displayY = (displayY & 7) | (textModeCounter * 8);
49 if (atEnd && (drawType == DRAW_DISPLAY)) {
50 int low = std::max(0, (startY - zero)) / 8;
51 int high = std::max(0, (endY - zero)) / 8;
52 textModeCounter += (high - low);
57 int displayWidth = (endX - (startX & ~1)) / 2;
58 int displayHeight = endY - startY;
60 assert(0 <= displayX);
61 assert(displayX + displayWidth <= 512);
63 rasterizer->drawDisplay(
66 displayWidth, displayHeight
70 rasterizer->drawSprites(
72 displayX / 2, displayY,
73 (displayWidth + 1) / 2, displayHeight);
78 void PixelRenderer::subdivide(
79 int startX,
int startY,
int endX,
int endY,
int clipL,
int clipR,
84 bool atEnd = (startY != endY) || (endX >= clipR);
86 draw(startX, startY, (atEnd ? clipR : endX),
87 startY + 1, drawType, atEnd);
89 if (startY == endY)
return;
93 bool drawLast =
false;
96 }
else if (endX > clipL) {
101 draw(clipL, startY, clipR, endY, drawType,
true);
107 if (drawLast) draw(clipL, endY, endX, endY + 1, drawType,
false);
111 : vdp(vdp_), vram(vdp.getVRAM())
112 , eventDistributor(vdp.getReactor().getEventDistributor())
113 , realTime(vdp.getMotherBoard().getRealTime())
114 , renderSettings(display.getRenderSettings())
115 , videoSourceSetting(vdp.getMotherBoard().getVideoSource())
116 , spriteChecker(vdp.getSpriteChecker())
117 , rasterizer(display.getVideoSystem().createRasterizer(vdp))
125 finishFrameDuration = 0;
126 frameSkipCounter = 999;
127 prevRenderFrame =
false;
141 return rasterizer->getPostProcessor();
158 displayEnabled = enabled;
163 if (!rasterizer->isActive()) {
164 frameSkipCounter = 999;
166 prevRenderFrame =
false;
169 prevRenderFrame = renderFrame;
174 if (frameSkipCounter <
178 }
else if (frameSkipCounter >=
180 frameSkipCounter = 0;
184 if (rasterizer->isRecording()) {
188 unsigned(finishFrameDuration), time);
191 frameSkipCounter = 0;
195 if (!renderFrame)
return;
197 rasterizer->frameStart(time);
210 bool skipEvent = !renderFrame;
217 rasterizer->frameEnd();
219 auto current = time2 - time1;
220 const double ALPHA = 0.2;
221 finishFrameDuration = finishFrameDuration * (1 - ALPHA) +
233 std::make_shared<FinishFrameEvent>(
234 rasterizer->getPostProcessor()->getVideoSource(),
242 if (displayEnabled) sync(time);
248 if (displayEnabled) sync(time);
254 if (displayEnabled) sync(time);
260 if (displayEnabled) sync(time);
266 if (displayEnabled) sync(time);
267 rasterizer->setTransparency(enabled);
273 if (displayEnabled) sync(time);
274 rasterizer->setSuperimposeVideoFrame(videoSource);
280 if (displayEnabled) sync(time);
288 rasterizer->setBackgroundColor(color);
295 if (displayEnabled) sync(time);
301 if (displayEnabled) sync(time);
317 if (displayEnabled) {
324 if (index == (bgColor & 3) || (index == (bgColor >> 2))) {
333 rasterizer->setPalette(index, grb);
339 if (displayEnabled) sync(time);
345 if (displayEnabled) sync(time);
360 rasterizer->setDisplayMode(mode);
366 if (displayEnabled) sync(time);
372 if (displayEnabled) sync(time);
378 if (displayEnabled) sync(time);
384 if (displayEnabled) sync(time);
387 static inline bool overlap(
395 if (displayY0 <= displayY1) {
396 if (vramLine1 > displayY0) {
397 if (vramLine0 <= displayY1)
return true;
400 if (vramLine1 > displayY0)
return true;
401 if (vramLine0 <= displayY1)
return true;
413 if (!displayEnabled)
return false;
422 int displayY0 = (nextY + deltaY) & 255;
423 int displayY1 = (limitY + deltaY) & 255;
429 int vramQuarter = (offset & 0x1800) >> 11;
431 for (
int i = 0; i < 4; i++) {
432 if ( (i & mask) == vramQuarter
433 && overlap(displayY0, displayY1, i * 64, (i + 1) * 64) ) {
443 int vramQuarter = (offset & 0x1800) >> 11;
445 for (
int i = 0; i < 4; i++) {
446 if ( (i & mask) == vramQuarter
447 && overlap(displayY0, displayY1, i * 64, (i + 1) * 64) ) {
457 int vramLine = ((offset & 0x3FF) / 32) * 8;
458 if (overlap(displayY0, displayY1, vramLine, vramLine + 8)) {
474 return (offset & 0x18000) == visiblePage
475 || (offset & 0x18000) == (visiblePage & 0x10000);
477 return (offset & 0x18000) == visiblePage;
495 if (renderFrame && displayEnabled && checkSync(offset, time)) {
512 if (!renderFrame)
return;
565 if (limitX == nextX && limitY == nextY)
return;
567 if (displayEnabled) {
585 subdivide(nextX, nextY, limitX, limitY,
586 0, displayL, DRAW_BORDER );
588 subdivide(nextX, nextY, limitX, limitY,
589 displayL, borderR, DRAW_DISPLAY );
591 subdivide(nextX, nextY, limitX, limitY,
594 subdivide(nextX, nextY, limitX, limitY,
602 void PixelRenderer::update(
const Setting& setting)
607 frameSkipCounter = 999;