summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-05-07 01:33:23 +0300
committerOxore <oxore@protonmail.com>2023-05-07 01:33:23 +0300
commitfcdecd37a2fb59ab534bc02f2b3744e83aff22ec (patch)
tree9cda5aa9ecc4a0114e564247b60ee793eb230c6b
parent9214810f4305efef3667820b37ebd942782279da (diff)
Impl horizontal scroll
-rw-r--r--vdp.cpp41
1 files changed, 32 insertions, 9 deletions
diff --git a/vdp.cpp b/vdp.cpp
index 735ec13..395237f 100644
--- a/vdp.cpp
+++ b/vdp.cpp
@@ -61,6 +61,14 @@
((reg) = ((reg) & ~SCROLLB_ADDR_MASK) \
| (((uint16_t)(v) >> SCROLLB_ADDR_SHIFT) & SCROLLB_ADDR_MASK))
+#define HSCROLL_TABLE_ADDR_MASK (0x3f)
+#define HSCROLL_TABLE_ADDR_SHIFT (10)
+#define HSCROLL_TABLE_ADDR_GET(reg) \
+ ((((uint16_t)(reg)) & (HSCROLL_TABLE_ADDR_MASK)) << HSCROLL_TABLE_ADDR_SHIFT)
+#define HSCROLL_TABLE_ADDR_SET(reg, v) \
+ ((reg) = ((reg) & ~HSCROLL_TABLE_ADDR_MASK) \
+ | (((uint16_t)(v) >> HSCROLL_TABLE_ADDR_SHIFT) & HSCROLL_TABLE_ADDR_MASK))
+
// 0: V32 CELL, 1: V64 CELL, 2: Prohibited, 3: V128 CELL
#define SCROLLSIZE_VCELL_MASK (3)
#define SCROLLSIZE_VCELL_SHIFT (4)
@@ -219,12 +227,18 @@ void VDP::renderScrollBLine(const size_t line_index, const size_t hcell_count)
if (cx * kCellWidthPixels >= kRenderWidth) {
break;
}
- const uint16_t cell_id = GetU16BE(
+ const uint16_t sprite_id = GetU16BE(
_vram + scroll_addr + (cy * hcell_count + cx) * sizeof(uint16_t));
const uint32_t val = GetU32BE(
- _vram + (cell_id * kCellHeightPixels + y) * (kCellWidthPixels / kPixelsPerByte));
+ _vram + (sprite_id * kCellHeightPixels + y) * (kCellWidthPixels / kPixelsPerByte));
+ const size_t hscroll_table_addr_reg =
+ _reg[static_cast<size_t>(RegID::kHScrollTableAddress)];
+ const size_t hscroll_table_addr = HSCROLL_TABLE_ADDR_GET(hscroll_table_addr_reg);
+ const size_t hscroll = GetU16BE(_vram + hscroll_table_addr + sizeof(uint16_t) * 1) & 0x3ff;
for (size_t x = 0; x < kCellWidthPixels; x++) {
- if (cx * kCellWidthPixels + x >= kRenderWidth) {
+ const size_t render_offset_x = (cx * kCellWidthPixels + x + hscroll) %
+ (hcell_count * kCellWidthPixels);
+ if (render_offset_x >= kRenderWidth) {
continue;
}
const size_t color_index = (val >> ((kCellWidthPixels - 1 - x) * 4)) & 0xf;
@@ -240,7 +254,7 @@ void VDP::renderScrollBLine(const size_t line_index, const size_t hcell_count)
const uint16_t cram_color = GetU16BE(_cram + color_index * sizeof(uint16_t));
const uint32_t color = RenderColorFromCRAM(cram_color);
const size_t render_offset =
- ((cy * kCellHeightPixels + y) * kRenderWidth) + cx * kCellWidthPixels + x;
+ ((cy * kCellHeightPixels + y) * kRenderWidth) + render_offset_x;
_rendered_buffer[render_offset] = color;
}
}
@@ -256,12 +270,18 @@ void VDP::renderScrollALine(const size_t line_index, const size_t hcell_count)
if (cx * kCellWidthPixels >= kRenderWidth) {
break;
}
- const uint16_t cell_id = GetU16BE(
+ const uint16_t sprite_id = GetU16BE(
_vram + scroll_addr + (cy * hcell_count + cx) * sizeof(uint16_t));
const uint32_t val = GetU32BE(
- _vram + (cell_id * kCellHeightPixels + y) * (kCellWidthPixels / kPixelsPerByte));
+ _vram + (sprite_id * kCellHeightPixels + y) * (kCellWidthPixels / kPixelsPerByte));
+ const size_t hscroll_table_addr_reg =
+ _reg[static_cast<size_t>(RegID::kHScrollTableAddress)];
+ const size_t hscroll_table_addr = HSCROLL_TABLE_ADDR_GET(hscroll_table_addr_reg);
+ const size_t hscroll = GetU16BE(_vram + hscroll_table_addr + sizeof(uint16_t) * 0) & 0x3ff;
for (size_t x = 0; x < kCellWidthPixels; x++) {
- if (cx * kCellWidthPixels + x >= kRenderWidth) {
+ const size_t render_offset_x = (cx * kCellWidthPixels + x + hscroll) %
+ (hcell_count * kCellWidthPixels);
+ if (render_offset_x >= kRenderWidth) {
continue;
}
const size_t color_index = (val >> ((kCellWidthPixels - 1 - x) * 4)) & 0xf;
@@ -277,7 +297,7 @@ void VDP::renderScrollALine(const size_t line_index, const size_t hcell_count)
const uint16_t cram_color = GetU16BE(_cram + color_index * sizeof(uint16_t));
const uint32_t color = RenderColorFromCRAM(cram_color);
const size_t render_offset =
- ((cy * kCellHeightPixels + y) * kRenderWidth) + cx * kCellWidthPixels + x;
+ ((cy * kCellHeightPixels + y) * kRenderWidth) + render_offset_x;
_rendered_buffer[render_offset] = color;
}
}
@@ -290,7 +310,10 @@ bool VDP::Scanline()
return true;
}
const uint16_t lines_per_screen = _status.pal_mode ? kLinesPerScreenPAL : kLinesPerScreenNTSC;
- memset(_rendered_buffer + kRenderWidth * _lines_counter, 0, kRenderWidth);
+ memset(
+ _rendered_buffer + kRenderWidth * _lines_counter,
+ 0,
+ kRenderWidth * sizeof(*_rendered_buffer));
if (_lines_counter >= (int)kRenderHeight) {
// just render palette
for (size_t i = 0; i < kRenderWidth; i++) {