22 std::unique_ptr<PostProcessor> postProcessor_)
23 : vdp(vdp_), vram(vdp.getVRAM())
26 , renderSettings(display.getRenderSettings())
27 , postProcessor(
std::move(postProcessor_))
28 , bitmapConverter(vdp, palette64, palette64_32768, palette256, palette256_32768, palette32768)
29 , p1Converter(vdp, palette64)
30 , p2Converter(vdp, palette64)
51 return postProcessor.get();
56 return postProcessor->needRender() &&
79 (horTiming.
display - SCREEN_WIDTH * 8) / 2;
84 (verTiming.
display - SCREEN_HEIGHT) / 2;
89 workFrame = postProcessor->rotateFrames(std::move(workFrame), time);
109 int fromX,
int fromY,
int limitX,
int limitY)
115 int startY = std::max(fromY - lineRenderTop, 0);
116 int endY = std::min(limitY - lineRenderTop, 240);
117 if (startY >= endY)
return;
121 for (
auto y :
xrange(startY, endY)) {
122 workFrame->setBlank(y, bgColor);
127 static int const screenW = SCREEN_WIDTH * 8;
128 int startX = std::max(0,
V9990::UCtoX(fromX - colZero, displayMode));
131 ? screenW : std::min(screenW, limitX - colZero), displayMode);
132 if (startX >= endX)
return;
136 for (
auto y :
xrange(startY, endY)) {
137 memset(workFrame->getLineDirect(y).subspan(startX,
size_t(endX - startX)),
139 workFrame->setLineWidth(y, lineWidth);
144 int fromX,
int fromY,
int toX,
int toY,
145 int displayX,
int displayY,
int displayYA,
int displayYB)
147 static int const screenW = SCREEN_WIDTH * 8;
148 static int const screenH = SCREEN_HEIGHT;
153 fromY -= lineRenderTop;
154 toY -= lineRenderTop;
176 if ((toX > fromX) && (toY > fromY)) {
181 int displayWidth = toX - fromX;
182 int displayHeight = toY - fromY;
186 displayY, displayYA, displayYB,
187 displayWidth, displayHeight,
192 displayWidth, displayHeight,
197 displayWidth, displayHeight,
204 int fromX,
int fromY,
int displayX,
205 int displayY,
int displayYA,
int displayYB,
206 int displayWidth,
int displayHeight,
bool drawSprites)
208 while (displayHeight--) {
209 auto dst = workFrame->getLineDirect(fromY).subspan(fromX, displayWidth);
211 displayYA, displayYB, drawSprites);
212 workFrame->setLineWidth(fromY, 320);
221 int fromX,
int fromY,
int displayX,
int displayY,
int displayYA,
222 int displayWidth,
int displayHeight,
bool drawSprites)
224 while (displayHeight--) {
225 auto dst = workFrame->getLineDirect(fromY).subspan(fromX, displayWidth);
226 p2Converter.
convertLine(dst, displayX, displayY, displayYA, drawSprites);
227 workFrame->setLineWidth(fromY, 640);
235 int fromX,
int fromY,
int displayX,
int displayY,
int displayYA,
236 int displayWidth,
int displayHeight,
bool drawSprites)
239 unsigned x = displayX + scrollX;
253 unsigned scrollYBase = scrollY & ~rollMask & 0x1FFF;
255 while (displayHeight--) {
261 unsigned y = scrollYBase + ((displayYA + scrollY) & rollMask);
262 auto dst = workFrame->getLineDirect(fromY).subspan(fromX, displayWidth);
263 bitmapConverter.
convertLine(dst, x, y, cursorY, drawSprites);
266 displayYA += lineStep;
278 std::array<int, 32> intensity;
279 for (
auto [i, r] :
enumerate(intensity)) {
280 r = narrow_cast<int>(255.0f * renderSettings.
transformComponent(narrow<float>(i) * (1.0f / 31.0f)));
282 for (
auto [grb, col] :
enumerate(palette32768)) {
284 intensity[(grb >> 5) & 31],
285 intensity[(grb >> 10) & 31],
286 intensity[(grb >> 0) & 31]));
290 for (
auto r :
xrange(32)) {
291 for (
auto b :
xrange(32)) {
295 palette32768[(
g << 10) + (r << 5) + b] =
Pixel(
303 std::array<int, 8> mapRG = {0, 4, 9, 13, 18, 22, 27, 31};
304 std::array<int, 4> mapB = {0, 11, 21, 31};
306 for (
auto r :
xrange(8)) {
307 for (
auto b :
xrange(4)) {
308 auto idx256 = (
g << 5) | (r << 2) | b;
309 auto idx32768 = (mapRG[
g] << 10) | (mapRG[r] << 5) | mapB[b];
310 palette256_32768[idx256] = narrow<int16_t>(idx32768);
311 palette256[idx256] = palette32768[idx32768];
320 byte r,
byte g,
byte b,
bool ys)
322 auto idx32768 = ((
g & 31) << 10) | ((r & 31) << 5) | ((b & 31) << 0);
323 palette64_32768[index & 63] = narrow<int16_t>(idx32768);
325 : palette32768[idx32768];
331 for (
auto i :
xrange(64)) {
347 return postProcessor->isRecording();
353 &renderSettings.getBrightnessSetting(),
354 &renderSettings.getContrastSetting(),
355 &renderSettings.getColorMatrixSetting())) {
Represents the output window/screen of openMSX.
@ ODD
Interlacing is on and this is an odd frame.
@ EVEN
Interlacing is on and this is an even frame.
@ NONINTERLACED
Interlacing is off for this frame.
MSXMotherBoard & getMotherBoard() const
Get the mother board this device belongs to.
bool isFastForwarding() const
A frame buffer where pixels can be written to.
uint32_t mapRGB255(gl::ivec3 rgb) const
Same as mapRGB, but RGB components are in range [0..255].
Pixel getKeyColor() const
Returns the color key for this output surface.
uint32_t mapRGB(gl::vec3 rgb) const
Returns the pixel value for the given RGB color.
A post processor builds the frame that is displayed from the MSX frame, while applying effects such a...
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
float transformComponent(float c) const
Apply brightness, contrast and gamma transformation on the input color component.
gl::vec3 transformRGB(gl::vec3 rgb) const
Apply brightness, contrast and gamma transformation on the input color.
bool isColorMatrixIdentity() const
Returns true iff the current color matrix is the identity matrix.
FloatSetting & getContrastSetting()
Contrast video setting.
FloatSetting & getBrightnessSetting()
Brightness video setting.
FloatSetting & getGammaSetting()
The amount of gamma correction.
bool getDisableSprites() const
StringSetting & getColorMatrixSetting()
Color matrix setting.
void detach(Observer< T > &observer)
void attach(Observer< T > &observer)
void convertLine(std::span< Pixel > dst, unsigned x, unsigned y, int cursorY, bool drawCursors) const
Convert a line of VRAM into host pixels.
void setColorMode(V9990ColorMode colorMode_, V9990DisplayMode display)
Set a different rendering mode.
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)
void convertLine(std::span< Pixel > buf, unsigned displayX, unsigned displayY, unsigned displayYA, unsigned displayYB, bool drawSprites)
void convertLine(std::span< Pixel > buf, unsigned displayX, unsigned displayY, unsigned displayYA, bool drawSprites)
void setPalette(int index, byte r, byte g, byte b, bool ys) override
Set RGB values for a palette entry.
void setDisplayMode(V9990DisplayMode displayMode) override
The display mode determines the screens geometry and how V9990 pixels are mapped to pixels on screen.
void drawBorder(int fromX, int fromY, int limitX, int limitY) override
Render a rectangle of border pixels on the host screen.
void drawP1Mode(int fromX, int fromY, int displayX, int displayY, int displayYA, int displayYB, int displayWidth, int displayHeight, bool drawSprites)
void preCalcPalettes()
Fill the palettes.
PostProcessor * getPostProcessor() const override
See V9990::getPostProcessor().
bool isActive() override
Will the output of this Rasterizer be displayed? There is no point in producing a frame that will not...
void setColorMode(V9990ColorMode colorMode) override
The color mode determines how the V9990 VRAM data gets converted to pixel colors.
void frameStart() override
Indicates the start of a new frame.
void update(const Setting &setting) noexcept override
void drawBxMode(int fromX, int fromY, int displayX, int displayY, int displayYA, int displayWidth, int displayHeight, bool drawSprites)
void drawP2Mode(int fromX, int fromY, int displayX, int displayY, int displayYA, int displayWidth, int displayHeight, bool drawSprites)
void setSuperimpose(bool enabled) override
Is superimpose enabled?
bool isRecording() const override
Is video recording active?
~V9990SDLRasterizer() override
void drawDisplay(int fromX, int fromY, int toX, int toY, int displayX, int displayY, int displayYA, int displayYB) override
Render a rectangle of display pixels on the host screen.
void frameEnd(EmuTime::param time) override
Indicates the end of the current frame.
V9990SDLRasterizer(V9990 &vdp, Display &display, OutputSurface &screen, std::unique_ptr< PostProcessor > postProcessor)
void reset() override
Resynchronize with VDP - flush caches etc.
Implementation of the Yamaha V9990 VDP as used in the GFX9000 cartridge by Sunrise.
unsigned getCursorYOffset() const
In overscan mode the cursor position is still specified with 'normal' (non-overscan) y-coordinates.
bool isSuperimposing() const
Should this frame be superimposed? This is a combination of bit 5 (YSE) in R#8 and the presence of an...
byte getBackDropColor() const
Return the current back drop color.
bool isInterlaced() const
Get interlace status.
unsigned getLineWidth() const
Return the display width.
bool isEvenOddEnabled() const
Get even/odd page alternation status.
V9990DisplayMode getDisplayMode() const
Return the current display mode.
bool spritesEnabled() const
Are sprites (cursors) enabled?
GetPaletteResult getPalette(int index) const
static int UCtoX(int ticks, V9990DisplayMode mode)
Convert UC ticks to V9990 pixel position on a line.
unsigned getScrollAX() const
Returns the X scroll offset for screen A of P1 and other modes.
unsigned getScrollAY() const
Returns the Y scroll offset for screen A of P1 and other modes.
unsigned getRollMask(unsigned maxMask) const
Returns the vertical roll mask.
const V9990DisplayPeriod & getVerticalTiming() const
Get vertical display timings.
V9990ColorMode getColorMode() const
Return the current color mode.
const V9990DisplayPeriod & getHorizontalTiming() const
Get horizontal display timings.
bool isOverScan() const
Returns true iff in overscan mode.
bool getEvenOdd() const
Is the even or odd field being displayed?
constexpr auto enumerate(Iterable &&iterable)
Heavily inspired by Nathan Reed's blog post: Python-Like enumerate() In C++17 http://reedbeta....
This file implemented 3 utility functions:
A period, either horizontal or vertical, starts with a synchronisation pulse followed by a blank peri...
constexpr auto xrange(T e)