mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-11 17:29:57 +00:00
More preparation for scan line rendering.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
88117398ef
commit
63f7216341
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "GameBoyBus.h"
|
#include "GameBoyBus.h"
|
||||||
#include "AbstractColourPalette.h"
|
#include "AbstractColourPalette.h"
|
||||||
|
#include "ObjectAttribute.h"
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
namespace GameBoy {
|
namespace GameBoy {
|
||||||
@ -29,11 +30,13 @@ namespace EightBit {
|
|||||||
|
|
||||||
void initialise();
|
void initialise();
|
||||||
void render();
|
void render();
|
||||||
|
void loadObjectAttributes();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint32_t> m_pixels;
|
std::vector<uint32_t> m_pixels;
|
||||||
Bus& m_bus;
|
Bus& m_bus;
|
||||||
const AbstractColourPalette* m_colours;
|
const AbstractColourPalette* m_colours;
|
||||||
|
std::array<ObjectAttribute, 40> m_objectAttributes;
|
||||||
|
|
||||||
std::array<int, 4> createPalette(int address);
|
std::array<int, 4> createPalette(int address);
|
||||||
|
|
||||||
|
@ -123,6 +123,7 @@ namespace EightBit {
|
|||||||
Bus();
|
Bus();
|
||||||
|
|
||||||
Signal<int> InterruptGenerated;
|
Signal<int> InterruptGenerated;
|
||||||
|
Signal<int> DisplayStatusModeUpdated;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
@ -209,6 +210,7 @@ namespace EightBit {
|
|||||||
void updateLcdStatusMode(int mode) {
|
void updateLcdStatusMode(int mode) {
|
||||||
const auto current = m_ioPorts.peek(STAT) & ~Processor::Mask2;
|
const auto current = m_ioPorts.peek(STAT) & ~Processor::Mask2;
|
||||||
m_ioPorts.poke(STAT, current | mode);
|
m_ioPorts.poke(STAT, current | mode);
|
||||||
|
DisplayStatusModeUpdated.fire(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableBootRom() { m_disableBootRom = true; }
|
void disableBootRom() { m_disableBootRom = true; }
|
||||||
|
@ -48,6 +48,18 @@ void EightBit::GameBoy::Display::renderObjects() {
|
|||||||
renderObjects(objBlockHeight);
|
renderObjects(objBlockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EightBit::GameBoy::Display::loadObjectAttributes() {
|
||||||
|
|
||||||
|
auto oamAddress = 0xfe00;
|
||||||
|
|
||||||
|
const auto control = m_bus.peekRegister(Bus::LCDC);
|
||||||
|
const auto objBlockHeight = (control & Bus::ObjectBlockCompositionSelection) ? 16 : 8;
|
||||||
|
|
||||||
|
for (int i = 0; i < 40; ++i) {
|
||||||
|
m_objectAttributes[i] = ObjectAttribute(m_bus, oamAddress + 4 * i, objBlockHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
|
void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
|
||||||
|
|
||||||
std::vector<std::array<int, 4>> palettes(2);
|
std::vector<std::array<int, 4>> palettes(2);
|
||||||
@ -59,21 +71,28 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
|
|||||||
|
|
||||||
for (int i = 0; i < 40; ++i) {
|
for (int i = 0; i < 40; ++i) {
|
||||||
|
|
||||||
const auto current = ObjectAttribute(m_bus, oamAddress + 4 * i, objBlockHeight);
|
const auto& current = m_objectAttributes[i];
|
||||||
|
|
||||||
const auto sprite = current.pattern();
|
const auto sprite = current.pattern();
|
||||||
const auto definition = CharacterDefinition(m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight);
|
|
||||||
const auto spriteX = current.positionX();
|
const auto spriteX = current.positionX();
|
||||||
const auto spriteY = current.positionY();
|
const auto spriteY = current.positionY();
|
||||||
const auto& palette = palettes[current.palette()];
|
|
||||||
const auto flipX = current.flipX();
|
|
||||||
const auto flipY = current.flipY();
|
|
||||||
|
|
||||||
renderTile(
|
const auto hidden = (spriteX == 0) && (spriteY == 0);
|
||||||
objBlockHeight,
|
|
||||||
spriteX, spriteY, -8, -16,
|
if (!hidden) {
|
||||||
flipX, flipY, true,
|
|
||||||
palette,
|
const auto definition = CharacterDefinition(m_bus, objDefinitionAddress + 16 * sprite, objBlockHeight);
|
||||||
definition);
|
const auto& palette = palettes[current.palette()];
|
||||||
|
const auto flipX = current.flipX();
|
||||||
|
const auto flipY = current.flipY();
|
||||||
|
|
||||||
|
renderTile(
|
||||||
|
objBlockHeight,
|
||||||
|
spriteX, spriteY, -8, -16,
|
||||||
|
flipX, flipY, true,
|
||||||
|
palette,
|
||||||
|
definition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,14 +373,17 @@ int EightBit::GameBoy::LR35902::runRasterLine(int limit) {
|
|||||||
if ((m_bus.peekRegister(Bus::STAT) & Bit6) && (m_bus.peekRegister(Bus::LYC) == m_bus.peekRegister(Bus::LY)))
|
if ((m_bus.peekRegister(Bus::STAT) & Bit6) && (m_bus.peekRegister(Bus::LYC) == m_bus.peekRegister(Bus::LY)))
|
||||||
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
||||||
|
|
||||||
|
// Mode 2, OAM unavailable
|
||||||
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::SearchingOamRam);
|
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::SearchingOamRam);
|
||||||
if (m_bus.peekRegister(Bus::STAT) & Bit5)
|
if (m_bus.peekRegister(Bus::STAT) & Bit5)
|
||||||
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
||||||
count += run(80); // ~19us
|
count += run(80); // ~19us
|
||||||
|
|
||||||
|
// Mode 3, OAM/VRAM unavailable
|
||||||
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::TransferringDataToLcd);
|
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::TransferringDataToLcd);
|
||||||
count += run(170); // ~41us
|
count += run(170); // ~41us
|
||||||
|
|
||||||
|
// Mode 0
|
||||||
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::HBlank);
|
m_bus.updateLcdStatusMode(Bus::LcdStatusMode::HBlank);
|
||||||
if (m_bus.peekRegister(Bus::STAT) & Bit3)
|
if (m_bus.peekRegister(Bus::STAT) & Bit3)
|
||||||
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
m_bus.triggerInterrupt(Bus::Interrupts::DisplayControlStatus);
|
||||||
@ -392,10 +395,6 @@ int EightBit::GameBoy::LR35902::runRasterLine(int limit) {
|
|||||||
count += run(Bus::CyclesPerLine);
|
count += run(Bus::CyclesPerLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(count > 0);
|
|
||||||
assert(count >= Bus::CyclesPerLine);
|
|
||||||
assert((count - Bus::CyclesPerLine) - 16);
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user