Emulator: Add function to fetch pixel color from palette
This commit is contained in:
@@ -30,6 +30,11 @@ class Emu final : public ruc::Singleton<Emu> {
|
||||
public:
|
||||
Emu(s) {}
|
||||
|
||||
enum Mode : uint8_t {
|
||||
DMG, // Game Boy
|
||||
CGB, // Game Boy Color
|
||||
};
|
||||
|
||||
void init(uint32_t frequency);
|
||||
|
||||
void update();
|
||||
@@ -43,10 +48,12 @@ public:
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
Mode mode() const { return m_mode; }
|
||||
std::shared_ptr<ProcessingUnit> processingUnit(std::string_view name) const { return m_processing_units.at(name); }
|
||||
MemorySpace memorySpace(std::string_view name) { return m_memory_spaces[name]; }
|
||||
|
||||
private:
|
||||
Mode m_mode { Mode::DMG };
|
||||
uint32_t m_frequency { 0 };
|
||||
double m_timestep { 0 };
|
||||
uint32_t m_cycle { 0 };
|
||||
|
||||
+36
-27
@@ -120,12 +120,9 @@ void PPU::render()
|
||||
bool tile_data_mode = lcd_control & LCDC::BGandWindowTileDataArea;
|
||||
uint32_t tile_data_address = (tile_data_mode) ? 0x8000 : 0x8800;
|
||||
|
||||
// Pallete
|
||||
uint8_t bg_palette = Emu::the().readMemory(0xff47) & 0xff;
|
||||
|
||||
for (uint32_t i = 0; i < tile_map_size; ++i) {
|
||||
uint8_t tile_index = Emu::the().readMemory(bg_tile_map_address + i);
|
||||
drawTile((i % 32) * TILE_WIDTH, (i / 32) * TILE_HEIGHT, tile_data_address + (tile_index * TILE_SIZE), bg_palette);
|
||||
drawTile((i % 32) * TILE_WIDTH, (i / 32) * TILE_HEIGHT, tile_data_address + (tile_index * TILE_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +132,7 @@ void PPU::render()
|
||||
scene.addComponent<Inferno::SpriteComponent>(m_entity, glm::vec4 { 1.0f }, texture);
|
||||
}
|
||||
|
||||
void PPU::drawTile(uint32_t x, uint32_t y, uint32_t tile_address, uint8_t bg_palette)
|
||||
void PPU::drawTile(uint32_t x, uint32_t y, uint32_t tile_address)
|
||||
{
|
||||
uint32_t viewport_x = Emu::the().readMemory(0xff43);
|
||||
uint32_t viewport_y = Emu::the().readMemory(0xff42);
|
||||
@@ -160,28 +157,10 @@ void PPU::drawTile(uint32_t x, uint32_t y, uint32_t tile_address, uint8_t bg_pal
|
||||
}
|
||||
|
||||
uint8_t pixel_index = (pixels_lsb >> (7 - tile_x) | ((pixels_msb >> (7 - tile_x)) << 1)) & 0x3;
|
||||
uint8_t pixel_color = (bg_palette >> (pixel_index * 2)) & 0x3;
|
||||
|
||||
if (pixel_color == 0) {
|
||||
m_screen[index + 0] = 255;
|
||||
m_screen[index + 1] = 255;
|
||||
m_screen[index + 2] = 255;
|
||||
}
|
||||
else if (pixel_color == 1) {
|
||||
m_screen[index + 0] = 168;
|
||||
m_screen[index + 1] = 168;
|
||||
m_screen[index + 2] = 168;
|
||||
}
|
||||
else if (pixel_color == 2) {
|
||||
m_screen[index + 0] = 84;
|
||||
m_screen[index + 1] = 84;
|
||||
m_screen[index + 2] = 84;
|
||||
}
|
||||
else if (pixel_color == 3) {
|
||||
m_screen[index + 0] = 0;
|
||||
m_screen[index + 1] = 0;
|
||||
m_screen[index + 2] = 0;
|
||||
}
|
||||
uint8_t pixel_color = getPixelColor(pixel_index, Palette::BGP);
|
||||
m_screen[index + 0] = pixel_color;
|
||||
m_screen[index + 1] = pixel_color;
|
||||
m_screen[index + 2] = pixel_color;
|
||||
}
|
||||
|
||||
// Move to next line
|
||||
@@ -189,6 +168,36 @@ void PPU::drawTile(uint32_t x, uint32_t y, uint32_t tile_address, uint8_t bg_pal
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PPU::getPixelColor(uint8_t color_index, Palette palette)
|
||||
{
|
||||
VERIFY(color_index < 4, "trying to fetch invalid color index '{}'", color_index);
|
||||
|
||||
switch (Emu::the().mode()) {
|
||||
case Emu::Mode::DMG: {
|
||||
uint8_t palette_data = Emu::the().readMemory(palette) & 0xff;
|
||||
uint8_t palette_value = palette_data >> (color_index * 2) & 0x3;
|
||||
switch (palette_value) {
|
||||
case 0:
|
||||
return 255;
|
||||
case 1:
|
||||
return 168;
|
||||
case 2:
|
||||
return 84;
|
||||
case 3:
|
||||
return 0;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
};
|
||||
}
|
||||
case Emu::Mode::CGB:
|
||||
VERIFY_NOT_REACHED();
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PPU::resetFrame()
|
||||
{
|
||||
m_state = State::OAMSearch;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint> // uint8_t, uint32_t
|
||||
#include <cstdint> // uint8_t, uint16_t, uint32_t
|
||||
|
||||
#include "ruc/meta/core.h"
|
||||
|
||||
@@ -45,10 +45,18 @@ public:
|
||||
VBlank,
|
||||
};
|
||||
|
||||
enum Palette : uint16_t {
|
||||
BGP = 0xff47, // BG and Window palette
|
||||
OBP0 = 0xff48, // OBJ palette 0
|
||||
OBP1 = 0xff49, // OBJ palette 1
|
||||
};
|
||||
|
||||
void update() override;
|
||||
void render();
|
||||
|
||||
void drawTile(uint32_t screen_x, uint32_t screen_y, uint32_t tile_address, uint8_t bg_palette);
|
||||
void drawTile(uint32_t screen_x, uint32_t screen_y, uint32_t tile_address);
|
||||
uint8_t getPixelColor(uint8_t color_index, Palette palette);
|
||||
|
||||
void resetFrame();
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user