(Dr Mario Fixes) Second tile selection bank is indexed in a signed manner.

Signed-off-by: Adrian Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2020-10-28 14:02:42 +00:00
parent 5631d2b367
commit 808251d0f6
5 changed files with 27 additions and 20 deletions

View File

@ -35,6 +35,10 @@ namespace EightBit {
void loadObjectAttributes();
private:
enum class tile_offset_t {
Signed, Unsigned,
};
std::array<uint32_t, PixelCount> m_pixels = { 0 };
Bus& m_bus;
Ram& m_oam;
@ -49,6 +53,7 @@ namespace EightBit {
void renderBackground();
void renderBackground(
int bgArea, int bgCharacters,
tile_offset_t offsetType,
int offsetX, int offsetY,
const std::array<int, 4>& palette);

View File

@ -88,14 +88,14 @@ namespace EightBit {
};
enum LcdcControl {
DisplayBackground = Chip::Bit0,
ObjectEnable = Chip::Bit1,
ObjectBlockCompositionSelection = Chip::Bit2,
BackgroundCodeAreaSelection = Chip::Bit3,
BackgroundCharacterDataSelection = Chip::Bit4,
WindowEnable = Chip::Bit5,
WindowCodeAreaSelection = Chip::Bit6,
LcdEnable = Chip::Bit7
LCD_EN = Chip::Bit7, // 0: Stop completely (no picture on screen), 1 : operation
WIN_MAP = Chip::Bit6, // 0 : $9800 - $9BFF, 1 : $9C00 - $9FFF
WIN_EN = Chip::Bit5, // 0 : off, 1 : on
TILE_SEL = Chip::Bit4, // 0 : $8800 - $97FF, 1 : $8000 - $8FFF < -Same area as OBJ
BG_MAP = Chip::Bit3, // 0 : $9800 - $9BFF, 1 : $9C00 - $9FFF
OBJ_SIZE = Chip::Bit2, // 0 : 8 * 8, 1 : 8 * 16 (width * height)
OBJ_EN = Chip::Bit1, // 0 : off, 1 : on
BG_EN = Chip::Bit0, // 0 : off, 1 : on
};
enum LcdStatusMode {

View File

@ -22,10 +22,10 @@ void EightBit::GameBoy::Display::render() {
m_scanLine = m_bus.IO().peek(IoRegisters::LY);
if (m_scanLine < RasterHeight) {
m_control = m_bus.IO().peek(IoRegisters::LCDC);
if (m_control & IoRegisters::LcdEnable) {
if (m_control & IoRegisters::DisplayBackground)
if (m_control & IoRegisters::LCD_EN) {
if (m_control & IoRegisters::BG_EN)
renderBackground();
if (m_control & IoRegisters::ObjectEnable)
if (m_control & IoRegisters::OBJ_EN)
renderObjects();
}
}
@ -49,7 +49,7 @@ void EightBit::GameBoy::Display::loadObjectAttributes() {
void EightBit::GameBoy::Display::renderObjects() {
const auto objBlockHeight = (m_control & IoRegisters::ObjectBlockCompositionSelection) ? 16 : 8;
const auto objBlockHeight = (m_control & IoRegisters::OBJ_SIZE) ? 16 : 8;
const std::array<std::array<int, 4>, 2> palettes = {
createPalette(IoRegisters::OBP0),
@ -90,9 +90,9 @@ void EightBit::GameBoy::Display::renderBackground() {
const auto palette = createPalette(IoRegisters::BGP);
const auto window = !!(m_control & IoRegisters::WindowEnable);
const auto bgArea = (m_control & IoRegisters::BackgroundCodeAreaSelection) ? 0x1c00 : 0x1800;
const auto bgCharacters = (m_control & IoRegisters::BackgroundCharacterDataSelection) ? 0 : 0x800;
const auto window = !!(m_control & IoRegisters::WIN_EN);
const auto bgArea = (m_control & IoRegisters::BG_MAP) ? 0x1c00 : 0x1800;
const auto bgCharacters = (m_control & IoRegisters::TILE_SEL) ? 0 : 0x1000;
const auto wx = m_bus.IO().peek(IoRegisters::WX);
const auto wy = m_bus.IO().peek(IoRegisters::WY);
@ -103,11 +103,12 @@ void EightBit::GameBoy::Display::renderBackground() {
const auto scrollX = m_bus.IO().peek(IoRegisters::SCX);
const auto scrollY = m_bus.IO().peek(IoRegisters::SCY);
renderBackground(bgArea, bgCharacters, offsetX - scrollX, offsetY - scrollY, palette);
const auto offsetType = bgCharacters == 0 ? tile_offset_t::Unsigned : tile_offset_t::Signed;
renderBackground(bgArea, bgCharacters, offsetType, offsetX - scrollX, offsetY - scrollY, palette);
}
void EightBit::GameBoy::Display::renderBackground(
int bgArea, int bgCharacters,
int bgArea, int bgCharacters, tile_offset_t offsetType,
int offsetX, int offsetY,
const std::array<int, 4>& palette) {
@ -118,7 +119,8 @@ void EightBit::GameBoy::Display::renderBackground(
const auto character = m_vram.peek(address++);
auto definition = CharacterDefinition(m_vram, bgCharacters + 16 * character);
const auto definitionOffset = offsetType == tile_offset_t::Signed ? 16 * (int8_t)character : 16 * character;
auto definition = CharacterDefinition(m_vram, bgCharacters + definitionOffset);
renderTile(
8,
column * 8 + offsetX, row * 8 + offsetY,

View File

@ -192,7 +192,7 @@ EightBit::MemoryMapping EightBit::GameBoy::Bus::mapping(uint16_t address) {
}
void EightBit::GameBoy::Bus::runRasterLines() {
m_enabledLCD = !!(IO().peek(IoRegisters::LCDC) & IoRegisters::LcdEnable);
m_enabledLCD = !!(IO().peek(IoRegisters::LCDC) & IoRegisters::LCD_EN);
IO().resetLY();
runRasterLines(Display::RasterHeight);
}

View File

@ -11,7 +11,7 @@ EightBit::GameBoy::IoRegisters::IoRegisters(Bus& bus)
void EightBit::GameBoy::IoRegisters::reset() {
poke(NR52, 0xf1);
poke(LCDC, DisplayBackground | BackgroundCharacterDataSelection | LcdEnable);
poke(LCDC, BG_EN | BG_MAP | LCD_EN);
m_divCounter = 0xabcc;
m_timerCounter = 0;
}