From 6e06ed95f0d5023759891cd37bd45bd943ebaa33 Mon Sep 17 00:00:00 2001
From: Adrian Conlon <98398945+AdrianConlon@users.noreply.github.com>
Date: Mon, 14 Oct 2024 21:38:51 +0100
Subject: [PATCH] Partial fix of a GB background optimisation problem.

---
 LR35902/inc/Display.h               |  9 ++++-
 LR35902/src/CharacterDefinition.cpp |  2 +-
 LR35902/src/Display.cpp             | 52 ++++++++++++++++++++---------
 3 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/LR35902/inc/Display.h b/LR35902/inc/Display.h
index f1fba5b..14994a9 100644
--- a/LR35902/inc/Display.h
+++ b/LR35902/inc/Display.h
@@ -53,7 +53,14 @@ namespace EightBit {
 			void renderBackground() noexcept;
 			void renderBackground(
 				int bgArea, int bgCharacters,
-				tile_offset_t offsetType, 
+				tile_offset_t offsetType,
+				int offsetX, int offsetY,
+				const std::array<int, 4>& palette) noexcept;
+
+			void renderBackgroundTile(
+				int definitionOffset,
+				int row, int column,
+				int bgCharacters, tile_offset_t offsetType,
 				int offsetX, int offsetY,
 				const std::array<int, 4>& palette) noexcept;
 
diff --git a/LR35902/src/CharacterDefinition.cpp b/LR35902/src/CharacterDefinition.cpp
index c932d26..c60b019 100644
--- a/LR35902/src/CharacterDefinition.cpp
+++ b/LR35902/src/CharacterDefinition.cpp
@@ -10,7 +10,7 @@ EightBit::GameBoy::CharacterDefinition::CharacterDefinition(Ram& vram, const uin
 
 std::array<int, 8> EightBit::GameBoy::CharacterDefinition::get(int row) const noexcept {
 
-	std::array<int, 8> returned;
+	std::array<int, 8> returned {};
 
 	const auto planeAddress = m_address + row * 2;
 	
diff --git a/LR35902/src/Display.cpp b/LR35902/src/Display.cpp
index 7a35045..72e6460 100644
--- a/LR35902/src/Display.cpp
+++ b/LR35902/src/Display.cpp
@@ -14,6 +14,7 @@ EightBit::GameBoy::Display::Display(const AbstractColourPalette* colours, Bus& b
   m_colours(colours) {
 }
 
+#pragma optimize ("t", off)
 void EightBit::GameBoy::Display::renderCurrentScanline() noexcept {
 	m_scanLine = m_bus.IO().peek(IoRegisters::LY);
 	if (m_scanLine < RasterHeight) {
@@ -25,6 +26,7 @@ void EightBit::GameBoy::Display::renderCurrentScanline() noexcept {
 			renderObjects();
 	}
 }
+#pragma optimize ("t", on)
 
 std::array<int, 4> EightBit::GameBoy::Display::createPalette(const int address) noexcept {
 	const auto raw = m_bus.IO().peek(address);
@@ -81,6 +83,7 @@ void EightBit::GameBoy::Display::renderObjects() noexcept {
 	}
 }
 
+#pragma optimize ("t", off)
 void EightBit::GameBoy::Display::renderBackground() noexcept {
 
 	const auto palette = createPalette(IoRegisters::BGP);
@@ -101,34 +104,34 @@ void EightBit::GameBoy::Display::renderBackground() noexcept {
 	const auto offsetType = bgCharacters == 0 ? tile_offset_t::Unsigned : tile_offset_t::Signed;
 	renderBackground(bgArea, bgCharacters, offsetType, offsetX - scrollX, offsetY - scrollY, palette);
 }
+#pragma optimize ("t", on)
 
 void EightBit::GameBoy::Display::renderBackground(
-		int bgArea, int bgCharacters, tile_offset_t offsetType,
-		int offsetX, int offsetY,
-		const std::array<int, 4>& palette) noexcept {
+	int bgArea, int bgCharacters, tile_offset_t offsetType,
+	int offsetX, int offsetY,
+	const std::array<int, 4>& palette) noexcept {
 
 	const int row = (m_scanLine - offsetY) / 8;
-	auto address = bgArea + row * BufferCharacterWidth;
+	const auto address = bgArea + (row * BufferCharacterWidth);
 
 	for (int column = 0; column < BufferCharacterWidth; ++column) {
-
-		const auto character = m_vram.peek(address++);
-
+		const auto character = m_vram.peek(address + column);
 		const auto definitionOffset = offsetType == tile_offset_t::Signed ? 16 * (int8_t)character : 16 * character;
-		const auto definition = CharacterDefinition(m_vram, bgCharacters + definitionOffset);
 		renderBackgroundTile(
-			column * 8 + offsetX, row * 8 + offsetY,
-			palette,
-			definition);
+			definitionOffset,
+			row, column,
+			bgCharacters, offsetType,
+			offsetX, offsetY,
+			palette);
 	}
 }
 
 void EightBit::GameBoy::Display::renderSpriteTile(
-		const int height,
-		const int drawX, const int drawY,
-		const bool flipX, const bool flipY,
-		const std::array<int, 4>& palette,
-		const CharacterDefinition& definition) noexcept {
+	const int height,
+	const int drawX, const int drawY,
+	const bool flipX, const bool flipY,
+	const std::array<int, 4>& palette,
+	const CharacterDefinition& definition) noexcept {
 	renderTile(
 		height,
 		drawX, drawY,
@@ -137,6 +140,23 @@ void EightBit::GameBoy::Display::renderSpriteTile(
 		definition);
 }
 
+void EightBit::GameBoy::Display::renderBackgroundTile(
+	int definitionOffset,
+		int row, int column,
+		int bgCharacters, tile_offset_t offsetType,
+		int offsetX, int offsetY,
+		const std::array<int, 4>& palette) noexcept {
+
+	const auto definition = CharacterDefinition(m_vram, bgCharacters + definitionOffset);
+	const auto drawX = (column * 8) + offsetX;
+	const auto drawY = (row * 8) + offsetY;
+
+	renderBackgroundTile(
+		drawX, drawY,
+		palette,
+		definition);
+}
+
 void EightBit::GameBoy::Display::renderBackgroundTile(
 		const int drawX, const int drawY,
 		const std::array<int, 4>& palette,