16 std::span<const Pixel, 16 * 2> palette16_,
17 std::span<const Pixel, 256> palette256_,
18 std::span<const Pixel, 32768> palette32768_)
19 : palette16(palette16_)
20 , palette256(palette256_)
21 , palette32768(palette32768_)
25void BitmapConverter::calcDPalette()
28 unsigned bits =
sizeof(
Pixel) * 8;
29 for (
auto i :
xrange(16)) {
31 for (
auto j :
xrange(16)) {
35 dPalette[16 * i + j] = dp;
45 renderGraphic4(subspan<256>(buf), vramPtr);
49 renderGraphic5(subspan<512>(buf), vramPtr);
67 renderBogus(subspan<256>(buf));
73 std::span<Pixel> buf, std::span<const byte, 128> vramPtr0, std::span<const byte, 128> vramPtr1)
78 renderGraphic6(subspan<512>(buf), vramPtr0, vramPtr1);
82 renderGraphic7(subspan<256>(buf), vramPtr0, vramPtr1);
86 renderYJK(subspan<256>(buf), vramPtr0, vramPtr1);
90 renderYAE(subspan<256>(buf), vramPtr0, vramPtr1);
103 renderBogus(subspan<256>(buf));
108void BitmapConverter::renderGraphic4(
109 std::span<Pixel, 256> buf,
110 std::span<const byte, 128> vramPtr0)
121 if (!dPaletteValid) [[unlikely]] {
125 Pixel* __restrict pixelPtr = buf.data();
126 auto* out = std::bit_cast<DPixel*>(pixelPtr);
127 const auto* in = std::bit_cast<const unsigned*>(vramPtr0.data());
128 for (
auto i :
xrange(256 / 8)) {
130 unsigned data = in[i];
132 out[4 * i + 0] = dPalette[(data >> 24) & 0xFF];
133 out[4 * i + 1] = dPalette[(data >> 16) & 0xFF];
134 out[4 * i + 2] = dPalette[(data >> 8) & 0xFF];
135 out[4 * i + 3] = dPalette[(data >> 0) & 0xFF];
137 out[4 * i + 0] = dPalette[(data >> 0) & 0xFF];
138 out[4 * i + 1] = dPalette[(data >> 8) & 0xFF];
139 out[4 * i + 2] = dPalette[(data >> 16) & 0xFF];
140 out[4 * i + 3] = dPalette[(data >> 24) & 0xFF];
145void BitmapConverter::renderGraphic5(
146 std::span<Pixel, 512> buf,
147 std::span<const byte, 128> vramPtr0)
const
149 Pixel* __restrict pixelPtr = buf.data();
150 for (
auto i :
xrange(128)) {
151 unsigned data = vramPtr0[i];
152 pixelPtr[4 * i + 0] = palette16[ 0 + (data >> 6) ];
153 pixelPtr[4 * i + 1] = palette16[16 + ((data >> 4) & 3)];
154 pixelPtr[4 * i + 2] = palette16[ 0 + ((data >> 2) & 3)];
155 pixelPtr[4 * i + 3] = palette16[16 + ((data >> 0) & 3)];
159void BitmapConverter::renderGraphic6(
160 std::span<Pixel, 512> buf,
161 std::span<const byte, 128> vramPtr0,
162 std::span<const byte, 128> vramPtr1)
164 Pixel* __restrict pixelPtr = buf.data();
173 if (!dPaletteValid) [[unlikely]] {
176 auto* out = std::bit_cast<DPixel*>(pixelPtr);
177 const auto* in0 = std::bit_cast<const unsigned*>(vramPtr0.data());
178 const auto* in1 = std::bit_cast<const unsigned*>(vramPtr1.data());
179 for (
auto i :
xrange(512 / 16)) {
181 unsigned data0 = in0[i];
182 unsigned data1 = in1[i];
184 out[8 * i + 0] = dPalette[(data0 >> 24) & 0xFF];
185 out[8 * i + 1] = dPalette[(data1 >> 24) & 0xFF];
186 out[8 * i + 2] = dPalette[(data0 >> 16) & 0xFF];
187 out[8 * i + 3] = dPalette[(data1 >> 16) & 0xFF];
188 out[8 * i + 4] = dPalette[(data0 >> 8) & 0xFF];
189 out[8 * i + 5] = dPalette[(data1 >> 8) & 0xFF];
190 out[8 * i + 6] = dPalette[(data0 >> 0) & 0xFF];
191 out[8 * i + 7] = dPalette[(data1 >> 0) & 0xFF];
193 out[8 * i + 0] = dPalette[(data0 >> 0) & 0xFF];
194 out[8 * i + 1] = dPalette[(data1 >> 0) & 0xFF];
195 out[8 * i + 2] = dPalette[(data0 >> 8) & 0xFF];
196 out[8 * i + 3] = dPalette[(data1 >> 8) & 0xFF];
197 out[8 * i + 4] = dPalette[(data0 >> 16) & 0xFF];
198 out[8 * i + 5] = dPalette[(data1 >> 16) & 0xFF];
199 out[8 * i + 6] = dPalette[(data0 >> 24) & 0xFF];
200 out[8 * i + 7] = dPalette[(data1 >> 24) & 0xFF];
205void BitmapConverter::renderGraphic7(
206 std::span<Pixel, 256> buf,
207 std::span<const byte, 128> vramPtr0,
208 std::span<const byte, 128> vramPtr1)
const
210 Pixel* __restrict pixelPtr = buf.data();
211 for (
auto i :
xrange(128)) {
212 pixelPtr[2 * i + 0] = palette256[vramPtr0[i]];
213 pixelPtr[2 * i + 1] = palette256[vramPtr1[i]];
217static constexpr std::tuple<int, int, int> yjk2rgb(
int y,
int j,
int k)
224 int r = std::clamp(y + j, 0, 31);
225 int g = std::clamp(y + k, 0, 31);
226 int b = std::clamp((5 * y - 2 * j - k + 2) / 4, 0, 31);
230void BitmapConverter::renderYJK(
231 std::span<Pixel, 256> buf,
232 std::span<const byte, 128> vramPtr0,
233 std::span<const byte, 128> vramPtr1)
const
235 Pixel* __restrict pixelPtr = buf.data();
236 for (
auto i :
xrange(64)) {
237 std::array<unsigned, 4> p = {
243 int j = narrow<int>((p[2] & 7) + ((p[3] & 3) << 3)) - narrow<int>((p[3] & 4) << 3);
244 int k = narrow<int>((p[0] & 7) + ((p[1] & 3) << 3)) - narrow<int>((p[1] & 4) << 3);
246 for (
auto n :
xrange(4)) {
247 int y = narrow<int>(p[n] >> 3);
248 auto [r,
g, b] = yjk2rgb(y, j, k);
249 int col = (r << 10) + (
g << 5) + b;
250 pixelPtr[4 * i + n] = palette32768[col];
255void BitmapConverter::renderYAE(
256 std::span<Pixel, 256> buf,
257 std::span<const byte, 128> vramPtr0,
258 std::span<const byte, 128> vramPtr1)
const
260 Pixel* __restrict pixelPtr = buf.data();
261 for (
auto i :
xrange(64)) {
262 std::array<unsigned, 4> p = {
268 int j = narrow<int>((p[2] & 7) + ((p[3] & 3) << 3)) - narrow<int>((p[3] & 4) << 3);
269 int k = narrow<int>((p[0] & 7) + ((p[1] & 3) << 3)) - narrow<int>((p[1] & 4) << 3);
271 for (
auto n :
xrange(4)) {
275 pix = palette16[p[n] >> 4];
278 int y = narrow<int>(p[n] >> 3);
279 auto [r,
g, b] = yjk2rgb(y, j, k);
280 pix = palette32768[(r << 10) + (
g << 5) + b];
282 pixelPtr[4 * i + n] = pix;
287void BitmapConverter::renderBogus(std::span<Pixel, 256> buf)
const
void convertLinePlanar(std::span< Pixel > buf, std::span< const byte, 128 > vramPtr0, std::span< const byte, 128 > vramPtr1)
Convert a line of V9938 VRAM to 256 or 512 host pixels.
void convertLine(std::span< Pixel > buf, std::span< const byte, 128 > vramPtr)
Convert a line of V9938 VRAM to 256 or 512 host pixels.
BitmapConverter(std::span< const Pixel, 16 *2 > palette16, std::span< const Pixel, 256 > palette256, std::span< const Pixel, 32768 > palette32768)
Create a new bitmap scanline converter.
static constexpr uint8_t GRAPHIC4
static constexpr uint8_t GRAPHIC5
static constexpr uint8_t GRAPHIC7
static constexpr byte YAE
Encoding of YAE flag.
static constexpr uint8_t GRAPHIC6
static constexpr byte YJK
Encoding of YJK flag.
constexpr byte getByte() const
Get the display mode as a byte: YAE YJK M5..M1 combined.
This file implemented 3 utility functions:
constexpr void fill(ForwardRange &&range, const T &value)
constexpr auto xrange(T e)