Generalise tile rendering code for background and sprites.

Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian.Conlon 2017-09-15 18:23:02 +01:00
parent e40ee1d7a6
commit f4c8496882
2 changed files with 48 additions and 37 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <array>
#include <cstdint> #include <cstdint>
#include "GameBoyBus.h" #include "GameBoyBus.h"
@ -8,6 +9,9 @@
namespace EightBit { namespace EightBit {
namespace GameBoy { namespace GameBoy {
class CharacterDefinition;
class Display { class Display {
public: public:
enum { enum {
@ -42,6 +46,12 @@ namespace EightBit {
void renderObjects(); void renderObjects();
void renderObjects(int objBlockHeight); void renderObjects(int objBlockHeight);
void renderTile(
int drawX, int drawY, int offsetX, int offsetY,
bool flipX, bool flipY, bool allowTransparencies,
const std::array<int, 4>& palette,
const CharacterDefinition& definition);
}; };
} }
} }

View File

@ -61,6 +61,7 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
auto oamAddress = 0xfe00; auto oamAddress = 0xfe00;
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 = ObjectAttribute(m_bus, oamAddress + 4 * i, objBlockHeight);
const auto sprite = current.pattern(); const auto sprite = current.pattern();
const auto definition = CharacterDefinition(m_bus, objDefinitionAddress + 16 * sprite); const auto definition = CharacterDefinition(m_bus, objDefinitionAddress + 16 * sprite);
@ -70,25 +71,11 @@ void EightBit::GameBoy::Display::renderObjects(int objBlockHeight) {
const auto flipX = current.flipX(); const auto flipX = current.flipX();
const auto flipY = current.flipY(); const auto flipY = current.flipY();
for (int cy = 0; cy < 8; ++cy) { renderTile(
spriteX, spriteY, -8, -16,
uint8_t y = spriteY + (flipY ? 7 - cy : cy); flipX, flipY, true,
if (y >= RasterHeight) palette,
break; definition);
for (int cx = 0; cx < 8; ++cx) {
uint8_t x = spriteX + (flipX ? 7 - cx : cx);
if (x >= RasterWidth)
break;
auto outputPixel = y * RasterWidth + x;
auto colour = definition.get()[cy * 8 + cx];
if (colour > 0) // transparency
m_pixels[outputPixel] = m_colours->getColour(palette[colour]);
}
}
} }
} }
@ -137,23 +124,37 @@ void EightBit::GameBoy::Display::renderBackground(
auto definition = definitionPair->second; auto definition = definitionPair->second;
for (int cy = 0; cy < 8; ++cy) { renderTile(
for (int cx = 0; cx < 8; ++cx) { column * 8, row * 8, offsetX - scrollX, offsetY - scrollY,
false, false, false,
uint8_t x = column * 8 + cx + offsetX - scrollX; palette,
if (x >= RasterWidth) definition);
break; }
}
uint8_t y = row * 8 + cy + offsetY - scrollY; }
if (y >= RasterHeight)
break; void EightBit::GameBoy::Display::renderTile(
int drawX, int drawY, int offsetX, int offsetY,
auto outputPixel = y * RasterWidth + x; bool flipX, bool flipY, bool allowTransparencies,
const std::array<int, 4>& palette,
auto colour = palette[definition.get()[cy * 8 + cx]]; const CharacterDefinition& definition) {
m_pixels[outputPixel] = m_colours->getColour(colour);
} for (int cy = 0; cy < 8; ++cy) {
}
for (int cx = 0; cx < 8; ++cx) {
uint8_t y = drawY + cy + offsetY;
if (y >= RasterHeight)
break;
uint8_t x = drawX + cx + offsetX;
if (x >= RasterWidth)
break;
auto outputPixel = y * RasterWidth + x;
auto colour = palette[definition.get()[cy * 8 + cx]];
m_pixels[outputPixel] = m_colours->getColour(colour);
} }
} }
} }