14 std::span<const Pixel, 16 * 2> palette16_,
15 std::span<const Pixel, 256> palette256_,
16 std::span<const Pixel, 32768> palette32768_)
17 : palette16(palette16_)
18 , palette256(palette256_)
19 , palette32768(palette32768_)
23void BitmapConverter::calcDPalette()
26 unsigned bits =
sizeof(
Pixel) * 8;
27 for (
auto i :
xrange(16)) {
29 for (
auto j :
xrange(16)) {
33 dPalette[16 * i + j] = dp;
43 renderGraphic4(subspan<256>(buf), vramPtr);
47 renderGraphic5(subspan<512>(buf), vramPtr);
65 renderBogus(subspan<256>(buf));
71 std::span<Pixel> buf, std::span<const byte, 128> vramPtr0, std::span<const byte, 128> vramPtr1)
76 renderGraphic6(subspan<512>(buf), vramPtr0, vramPtr1);
80 renderGraphic7(subspan<256>(buf), vramPtr0, vramPtr1);
84 renderYJK(subspan<256>(buf), vramPtr0, vramPtr1);
88 renderYAE(subspan<256>(buf), vramPtr0, vramPtr1);
101 renderBogus(subspan<256>(buf));
106void BitmapConverter::renderGraphic4(
107 std::span<Pixel, 256> buf,
108 std::span<const byte, 128> vramPtr0)
119 if (!dPaletteValid) [[unlikely]] {
123 Pixel* __restrict pixelPtr = buf.data();
124 auto* out =
reinterpret_cast<DPixel*
>(pixelPtr);
125 const auto* in =
reinterpret_cast<const unsigned*
>(vramPtr0.data());
126 for (
auto i :
xrange(256 / 8)) {
128 unsigned data = in[i];
130 out[4 * i + 0] = dPalette[(data >> 24) & 0xFF];
131 out[4 * i + 1] = dPalette[(data >> 16) & 0xFF];
132 out[4 * i + 2] = dPalette[(data >> 8) & 0xFF];
133 out[4 * i + 3] = dPalette[(data >> 0) & 0xFF];
135 out[4 * i + 0] = dPalette[(data >> 0) & 0xFF];
136 out[4 * i + 1] = dPalette[(data >> 8) & 0xFF];
137 out[4 * i + 2] = dPalette[(data >> 16) & 0xFF];
138 out[4 * i + 3] = dPalette[(data >> 24) & 0xFF];
143void BitmapConverter::renderGraphic5(
144 std::span<Pixel, 512> buf,
145 std::span<const byte, 128> vramPtr0)
147 Pixel* __restrict pixelPtr = buf.data();
148 for (
auto i :
xrange(128)) {
149 unsigned data = vramPtr0[i];
150 pixelPtr[4 * i + 0] = palette16[ 0 + (data >> 6) ];
151 pixelPtr[4 * i + 1] = palette16[16 + ((data >> 4) & 3)];
152 pixelPtr[4 * i + 2] = palette16[ 0 + ((data >> 2) & 3)];
153 pixelPtr[4 * i + 3] = palette16[16 + ((data >> 0) & 3)];
157void BitmapConverter::renderGraphic6(
158 std::span<Pixel, 512> buf,
159 std::span<const byte, 128> vramPtr0,
160 std::span<const byte, 128> vramPtr1)
162 Pixel* __restrict pixelPtr = buf.data();
171 if (!dPaletteValid) [[unlikely]] {
174 auto* out =
reinterpret_cast<DPixel*
>(pixelPtr);
175 const auto* in0 =
reinterpret_cast<const unsigned*
>(vramPtr0.data());
176 const auto* in1 =
reinterpret_cast<const unsigned*
>(vramPtr1.data());
177 for (
auto i :
xrange(512 / 16)) {
179 unsigned data0 = in0[i];
180 unsigned data1 = in1[i];
182 out[8 * i + 0] = dPalette[(data0 >> 24) & 0xFF];
183 out[8 * i + 1] = dPalette[(data1 >> 24) & 0xFF];
184 out[8 * i + 2] = dPalette[(data0 >> 16) & 0xFF];
185 out[8 * i + 3] = dPalette[(data1 >> 16) & 0xFF];
186 out[8 * i + 4] = dPalette[(data0 >> 8) & 0xFF];
187 out[8 * i + 5] = dPalette[(data1 >> 8) & 0xFF];
188 out[8 * i + 6] = dPalette[(data0 >> 0) & 0xFF];
189 out[8 * i + 7] = dPalette[(data1 >> 0) & 0xFF];
191 out[8 * i + 0] = dPalette[(data0 >> 0) & 0xFF];
192 out[8 * i + 1] = dPalette[(data1 >> 0) & 0xFF];
193 out[8 * i + 2] = dPalette[(data0 >> 8) & 0xFF];
194 out[8 * i + 3] = dPalette[(data1 >> 8) & 0xFF];
195 out[8 * i + 4] = dPalette[(data0 >> 16) & 0xFF];
196 out[8 * i + 5] = dPalette[(data1 >> 16) & 0xFF];
197 out[8 * i + 6] = dPalette[(data0 >> 24) & 0xFF];
198 out[8 * i + 7] = dPalette[(data1 >> 24) & 0xFF];
203void BitmapConverter::renderGraphic7(
204 std::span<Pixel, 256> buf,
205 std::span<const byte, 128> vramPtr0,
206 std::span<const byte, 128> vramPtr1)
208 Pixel* __restrict pixelPtr = buf.data();
209 for (
auto i :
xrange(128)) {
210 pixelPtr[2 * i + 0] = palette256[vramPtr0[i]];
211 pixelPtr[2 * i + 1] = palette256[vramPtr1[i]];
215static constexpr std::tuple<int, int, int> yjk2rgb(
int y,
int j,
int k)
222 int r = std::clamp(y + j, 0, 31);
223 int g = std::clamp(y + k, 0, 31);
224 int b = std::clamp((5 * y - 2 * j - k + 2) / 4, 0, 31);
228void BitmapConverter::renderYJK(
229 std::span<Pixel, 256> buf,
230 std::span<const byte, 128> vramPtr0,
231 std::span<const byte, 128> vramPtr1)
233 Pixel* __restrict pixelPtr = buf.data();
234 for (
auto i :
xrange(64)) {
235 std::array<unsigned, 4> p = {
241 int j = narrow<int>((p[2] & 7) + ((p[3] & 3) << 3)) - narrow<int>((p[3] & 4) << 3);
242 int k = narrow<int>((p[0] & 7) + ((p[1] & 3) << 3)) - narrow<int>((p[1] & 4) << 3);
244 for (
auto n :
xrange(4)) {
245 int y = narrow<int>(p[n] >> 3);
246 auto [r,
g, b] = yjk2rgb(y, j, k);
247 int col = (r << 10) + (
g << 5) + b;
248 pixelPtr[4 * i + n] = palette32768[col];
253void BitmapConverter::renderYAE(
254 std::span<Pixel, 256> buf,
255 std::span<const byte, 128> vramPtr0,
256 std::span<const byte, 128> vramPtr1)
258 Pixel* __restrict pixelPtr = buf.data();
259 for (
auto i :
xrange(64)) {
260 std::array<unsigned, 4> p = {
266 int j = narrow<int>((p[2] & 7) + ((p[3] & 3) << 3)) - narrow<int>((p[3] & 4) << 3);
267 int k = narrow<int>((p[0] & 7) + ((p[1] & 3) << 3)) - narrow<int>((p[1] & 4) << 3);
269 for (
auto n :
xrange(4)) {
273 pix = palette16[p[n] >> 4];
276 int y = narrow<int>(p[n] >> 3);
277 auto [r,
g, b] = yjk2rgb(y, j, k);
278 pix = palette32768[(r << 10) + (
g << 5) + b];
280 pixelPtr[4 * i + n] = pix;
285void BitmapConverter::renderBogus(std::span<Pixel, 256> buf)
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 byte YAE
Encoding of YAE flag.
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)