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;
135 for (
auto y :
xrange(startY, endY)) {
136 ranges::fill(workFrame->getLineDirect(y).subspan(startX,
size_t(endX - startX)),
138 workFrame->setLineWidth(y, lineWidth);
143 int fromX,
int fromY,
int toX,
int toY,
144 int displayX,
int displayY,
int displayYA,
int displayYB)
146 static int const screenW = SCREEN_WIDTH * 8;
147 static int const screenH = SCREEN_HEIGHT;
152 fromY -= lineRenderTop;
153 toY -= lineRenderTop;
175 if ((toX > fromX) && (toY > fromY)) {
180 int displayWidth = toX - fromX;
181 int displayHeight = toY - fromY;
185 displayY, displayYA, displayYB,
186 displayWidth, displayHeight,
191 displayWidth, displayHeight,
196 displayWidth, displayHeight,
203 int fromX,
int fromY,
int displayX,
204 int displayY,
int displayYA,
int displayYB,
205 int displayWidth,
int displayHeight,
bool drawSprites)
207 while (displayHeight--) {
208 auto dst = workFrame->getLineDirect(fromY).subspan(fromX, displayWidth);
210 displayYA, displayYB, drawSprites);
211 workFrame->setLineWidth(fromY, 320);
220 int fromX,
int fromY,
int displayX,
int displayY,
int displayYA,
221 int displayWidth,
int displayHeight,
bool drawSprites)
223 while (displayHeight--) {
224 auto dst = workFrame->getLineDirect(fromY).subspan(fromX, displayWidth);
225 p2Converter.
convertLine(dst, displayX, displayY, displayYA, drawSprites);
226 workFrame->setLineWidth(fromY, 640);
234 int fromX,
int fromY,
int displayX,
int displayY,
int displayYA,
235 int displayWidth,
int displayHeight,
bool drawSprites)
238 unsigned x = displayX + scrollX;
252 unsigned scrollYBase = scrollY & ~rollMask & 0x1FFF;
254 while (displayHeight--) {
260 unsigned y = scrollYBase + ((displayYA + scrollY) & rollMask);
261 auto dst = workFrame->getLineDirect(fromY).subspan(fromX, displayWidth);
262 bitmapConverter.
convertLine(dst, x, y, cursorY, drawSprites);
265 displayYA += lineStep;
277 std::array<int, 32> intensity;
278 for (
auto [i, r] :
enumerate(intensity)) {
279 r = narrow_cast<int>(255.0f * renderSettings.
transformComponent(narrow<float>(i) * (1.0f / 31.0f)));
281 for (
auto [grb, col] :
enumerate(palette32768)) {
283 intensity[(grb >> 5) & 31],
284 intensity[(grb >> 10) & 31],
285 intensity[(grb >> 0) & 31]));
289 for (
auto r :
xrange(32)) {
290 for (
auto b :
xrange(32)) {
294 palette32768[(
g << 10) + (r << 5) + b] =
Pixel(
302 std::array<int, 8> mapRG = {0, 4, 9, 13, 18, 22, 27, 31};
303 std::array<int, 4> mapB = {0, 11, 21, 31};
305 for (
auto r :
xrange(8)) {
306 for (
auto b :
xrange(4)) {
307 auto idx256 = (
g << 5) | (r << 2) | b;
308 auto idx32768 = (mapRG[
g] << 10) | (mapRG[r] << 5) | mapB[b];
309 palette256_32768[idx256] = narrow<int16_t>(idx32768);
310 palette256[idx256] = palette32768[idx32768];
319 byte r,
byte g,
byte b,
bool ys)
321 auto idx32768 = ((
g & 31) << 10) | ((r & 31) << 5) | ((b & 31) << 0);
322 palette64_32768[index & 63] = narrow<int16_t>(idx32768);
324 : palette32768[idx32768];
330 for (
auto i :
xrange(64)) {
346 return postProcessor->isRecording();
352 &renderSettings.getBrightnessSetting(),
353 &renderSettings.getContrastSetting(),
354 &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:
constexpr void fill(ForwardRange &&range, const T &value)
A period, either horizontal or vertical, starts with a synchronisation pulse followed by a blank peri...
constexpr auto xrange(T e)