Skip to content
Snippets Groups Projects
Verified Commit d870fd4f authored by João Magalhães's avatar João Magalhães :rocket:
Browse files

chore: better endian handling in frame buffer

parent a58c525d
No related branches found
No related tags found
No related merge requests found
Pipeline #3195 failed
...@@ -6,7 +6,7 @@ use boytacean::{ ...@@ -6,7 +6,7 @@ use boytacean::{
debugln, debugln,
gb::{AudioProvider, GameBoy}, gb::{AudioProvider, GameBoy},
pad::PadKey, pad::PadKey,
ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_XRGB8888_SIZE, XRGB8888_SIZE}, ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_SIZE, XRGB8888_SIZE},
rom::Cartridge, rom::Cartridge,
}; };
use consts::{ use consts::{
...@@ -28,7 +28,7 @@ use std::{ ...@@ -28,7 +28,7 @@ use std::{
static mut EMULATOR: Option<GameBoy> = None; static mut EMULATOR: Option<GameBoy> = None;
static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None; static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None;
static mut FRAME_BUFFER: [u8; FRAME_BUFFER_XRGB8888_SIZE] = [0x00; FRAME_BUFFER_XRGB8888_SIZE]; static mut FRAME_BUFFER: [u32; FRAME_BUFFER_SIZE] = [0x00; FRAME_BUFFER_SIZE];
static mut PENDING_CYCLES: u32 = 0_u32; static mut PENDING_CYCLES: u32 = 0_u32;
...@@ -249,11 +249,11 @@ pub extern "C" fn retro_run() { ...@@ -249,11 +249,11 @@ pub extern "C" fn retro_run() {
// in case a new frame is available in the emulator // in case a new frame is available in the emulator
// then the frame must be pushed into display // then the frame must be pushed into display
if emulator.ppu_frame() != last_frame { if emulator.ppu_frame() != last_frame {
let frame_buffer = emulator.frame_buffer_xrgb8888(); let frame_buffer = emulator.frame_buffer_xrgb8888_u32();
unsafe { unsafe {
FRAME_BUFFER.copy_from_slice(&frame_buffer); FRAME_BUFFER.copy_from_slice(&frame_buffer);
video_refresh_cb( video_refresh_cb(
FRAME_BUFFER.as_ptr(), FRAME_BUFFER.as_ptr() as *const u8,
DISPLAY_WIDTH as u32, DISPLAY_WIDTH as u32,
DISPLAY_HEIGHT as u32, DISPLAY_HEIGHT as u32,
DISPLAY_WIDTH * XRGB8888_SIZE, DISPLAY_WIDTH * XRGB8888_SIZE,
......
...@@ -966,14 +966,26 @@ impl GameBoy { ...@@ -966,14 +966,26 @@ impl GameBoy {
self.ppu().frame_buffer_xrgb8888() self.ppu().frame_buffer_xrgb8888()
} }
pub fn frame_buffer_xrgb8888_u32(&mut self) -> [u32; FRAME_BUFFER_SIZE] {
self.ppu().frame_buffer_xrgb8888_u32()
}
pub fn frame_buffer_rgb1555(&mut self) -> [u8; FRAME_BUFFER_RGB1555_SIZE] { pub fn frame_buffer_rgb1555(&mut self) -> [u8; FRAME_BUFFER_RGB1555_SIZE] {
self.ppu().frame_buffer_rgb1555() self.ppu().frame_buffer_rgb1555()
} }
pub fn frame_buffer_rgb1555_u16(&mut self) -> [u16; FRAME_BUFFER_SIZE] {
self.ppu().frame_buffer_rgb1555_u16()
}
pub fn frame_buffer_rgb565(&mut self) -> [u8; FRAME_BUFFER_RGB565_SIZE] { pub fn frame_buffer_rgb565(&mut self) -> [u8; FRAME_BUFFER_RGB565_SIZE] {
self.ppu().frame_buffer_rgb565() self.ppu().frame_buffer_rgb565()
} }
pub fn frame_buffer_rgb565_u16(&mut self) -> [u16; FRAME_BUFFER_SIZE] {
self.ppu().frame_buffer_rgb565_u16()
}
pub fn audio_buffer(&mut self) -> &VecDeque<u8> { pub fn audio_buffer(&mut self) -> &VecDeque<u8> {
self.apu().audio_buffer() self.apu().audio_buffer()
} }
......
...@@ -939,6 +939,19 @@ impl Ppu { ...@@ -939,6 +939,19 @@ impl Ppu {
buffer buffer
} }
pub fn frame_buffer_xrgb8888_u32(&self) -> [u32; FRAME_BUFFER_SIZE] {
let mut buffer = [0u32; FRAME_BUFFER_SIZE];
for index in 0..DISPLAY_SIZE {
let (r, g, b) = (
self.frame_buffer[index * RGB_SIZE],
self.frame_buffer[index * RGB_SIZE + 1],
self.frame_buffer[index * RGB_SIZE + 2],
);
buffer[index] = ((r as u32) << 16) | ((g as u32) << 8) | b as u32;
}
buffer
}
pub fn frame_buffer_rgb1555(&self) -> [u8; FRAME_BUFFER_RGB1555_SIZE] { pub fn frame_buffer_rgb1555(&self) -> [u8; FRAME_BUFFER_RGB1555_SIZE] {
let mut buffer = [0u8; FRAME_BUFFER_RGB1555_SIZE]; let mut buffer = [0u8; FRAME_BUFFER_RGB1555_SIZE];
for index in 0..DISPLAY_SIZE { for index in 0..DISPLAY_SIZE {
...@@ -954,6 +967,19 @@ impl Ppu { ...@@ -954,6 +967,19 @@ impl Ppu {
buffer buffer
} }
pub fn frame_buffer_rgb1555_u16(&self) -> [u16; FRAME_BUFFER_SIZE] {
let mut buffer = [0u16; FRAME_BUFFER_SIZE];
for index in 0..DISPLAY_SIZE {
let (r, g, b) = (
self.frame_buffer[index * RGB_SIZE],
self.frame_buffer[index * RGB_SIZE + 1],
self.frame_buffer[index * RGB_SIZE + 2],
);
buffer[index] = Self::rgb888_to_rgb1555_u16(r, g, b);
}
buffer
}
pub fn frame_buffer_rgb565(&self) -> [u8; FRAME_BUFFER_RGB565_SIZE] { pub fn frame_buffer_rgb565(&self) -> [u8; FRAME_BUFFER_RGB565_SIZE] {
let mut buffer = [0u8; FRAME_BUFFER_RGB565_SIZE]; let mut buffer = [0u8; FRAME_BUFFER_RGB565_SIZE];
for index in 0..DISPLAY_SIZE { for index in 0..DISPLAY_SIZE {
...@@ -969,6 +995,19 @@ impl Ppu { ...@@ -969,6 +995,19 @@ impl Ppu {
buffer buffer
} }
pub fn frame_buffer_rgb565_u16(&self) -> [u16; FRAME_BUFFER_SIZE] {
let mut buffer = [0u16; FRAME_BUFFER_SIZE];
for index in 0..DISPLAY_SIZE {
let (r, g, b) = (
self.frame_buffer[index * RGB_SIZE],
self.frame_buffer[index * RGB_SIZE + 1],
self.frame_buffer[index * RGB_SIZE + 2],
);
buffer[index] = Self::rgb888_to_rgb565_u16(r, g, b);
}
buffer
}
pub fn vram(&self) -> &[u8; VRAM_SIZE] { pub fn vram(&self) -> &[u8; VRAM_SIZE] {
&self.vram &self.vram
} }
...@@ -1784,22 +1823,28 @@ impl Ppu { ...@@ -1784,22 +1823,28 @@ impl Ppu {
} }
fn rgb888_to_rgb1555(first: u8, second: u8, third: u8) -> PixelRgb1555 { fn rgb888_to_rgb1555(first: u8, second: u8, third: u8) -> PixelRgb1555 {
let pixel = Self::rgb888_to_rgb1555_u16(first, second, third);
[pixel as u8, (pixel >> 8) as u8]
}
fn rgb888_to_rgb1555_u16(first: u8, second: u8, third: u8) -> u16 {
let r = (first as u16 >> 3) & 0x1f; let r = (first as u16 >> 3) & 0x1f;
let g = (second as u16 >> 3) & 0x1f; let g = (second as u16 >> 3) & 0x1f;
let b = (third as u16 >> 3) & 0x1f; let b = (third as u16 >> 3) & 0x1f;
let a = 1; let a = 1;
(a << 15) | (r << 10) | (g << 5) | b
}
let pixel = (a << 15) | (r << 10) | (g << 5) | b; fn rgb888_to_rgb565(first: u8, second: u8, third: u8) -> PixelRgb565 {
let pixel = Self::rgb888_to_rgb565_u16(first, second, third);
[pixel as u8, (pixel >> 8) as u8] [pixel as u8, (pixel >> 8) as u8]
} }
fn rgb888_to_rgb565(first: u8, second: u8, third: u8) -> PixelRgb565 { fn rgb888_to_rgb565_u16(first: u8, second: u8, third: u8) -> u16 {
let r = (first as u16 >> 3) & 0x1f; let r = (first as u16 >> 3) & 0x1f;
let g = (second as u16 >> 2) & 0x3f; let g = (second as u16 >> 2) & 0x3f;
let b = (third as u16 >> 3) & 0x1f; let b = (third as u16 >> 3) & 0x1f;
(r << 11) | (g << 5) | b
let pixel = (r << 11) | (g << 5) | b;
[pixel as u8, (pixel >> 8) as u8]
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment