diff --git a/frontends/libretro/src/lib.rs b/frontends/libretro/src/lib.rs
index 5f7d582832906815c172fd439c31ab9add8c0284..d71cfaf4c66f85404b27395c8c8514d63ae6b471 100644
--- a/frontends/libretro/src/lib.rs
+++ b/frontends/libretro/src/lib.rs
@@ -6,16 +6,17 @@ use boytacean::{
     debugln,
     gb::{AudioProvider, GameBoy},
     pad::PadKey,
-    ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB155_SIZE, RGB1555_SIZE},
+    ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB565_SIZE, RGB565_SIZE},
     rom::Cartridge,
 };
 use consts::{
-    RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_B, RETRO_DEVICE_ID_JOYPAD_DOWN,
-    RETRO_DEVICE_ID_JOYPAD_L, RETRO_DEVICE_ID_JOYPAD_L2, RETRO_DEVICE_ID_JOYPAD_L3,
-    RETRO_DEVICE_ID_JOYPAD_LEFT, RETRO_DEVICE_ID_JOYPAD_R, RETRO_DEVICE_ID_JOYPAD_R2,
-    RETRO_DEVICE_ID_JOYPAD_R3, RETRO_DEVICE_ID_JOYPAD_RIGHT, RETRO_DEVICE_ID_JOYPAD_SELECT,
-    RETRO_DEVICE_ID_JOYPAD_START, RETRO_DEVICE_ID_JOYPAD_UP, RETRO_DEVICE_ID_JOYPAD_X,
-    RETRO_DEVICE_ID_JOYPAD_Y, RETRO_DEVICE_JOYPAD,
+    REGION_NTSC, RETRO_API_VERSION, RETRO_DEVICE_ID_JOYPAD_A, RETRO_DEVICE_ID_JOYPAD_B,
+    RETRO_DEVICE_ID_JOYPAD_DOWN, RETRO_DEVICE_ID_JOYPAD_L, RETRO_DEVICE_ID_JOYPAD_L2,
+    RETRO_DEVICE_ID_JOYPAD_L3, RETRO_DEVICE_ID_JOYPAD_LEFT, RETRO_DEVICE_ID_JOYPAD_R,
+    RETRO_DEVICE_ID_JOYPAD_R2, RETRO_DEVICE_ID_JOYPAD_R3, RETRO_DEVICE_ID_JOYPAD_RIGHT,
+    RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_DEVICE_ID_JOYPAD_START, RETRO_DEVICE_ID_JOYPAD_UP,
+    RETRO_DEVICE_ID_JOYPAD_X, RETRO_DEVICE_ID_JOYPAD_Y, RETRO_DEVICE_JOYPAD,
+    RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, RETRO_PIXEL_FORMAT_RGB565,
 };
 use std::{
     collections::HashMap,
@@ -25,11 +26,9 @@ use std::{
     slice::from_raw_parts,
 };
 
-use crate::consts::{REGION_NTSC, RETRO_API_VERSION};
-
 static mut EMULATOR: Option<GameBoy> = None;
 static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None;
-static mut FRAME_BUFFER: [u8; FRAME_BUFFER_RGB155_SIZE] = [0x00; FRAME_BUFFER_RGB155_SIZE];
+static mut FRAME_BUFFER: [u8; FRAME_BUFFER_RGB565_SIZE] = [0x00; FRAME_BUFFER_RGB565_SIZE];
 static mut AUDIO_BUFFER: Option<Vec<i16>> = None;
 
 static mut PENDING_CYCLES: u32 = 0_u32;
@@ -198,6 +197,12 @@ pub unsafe extern "C" fn retro_get_system_av_info(info: *mut RetroSystemAvInfo)
     (*info).geometry.aspect_ratio = DISPLAY_WIDTH as f32 / DISPLAY_HEIGHT as f32;
     (*info).timing.fps = GameBoy::VISUAL_FREQ as f64;
     (*info).timing.sample_rate = EMULATOR.as_ref().unwrap().audio_sampling_rate() as f64;
+
+    let environment_cb = unsafe { ENVIRONMENT_CALLBACK.as_ref().unwrap() };
+    environment_cb(
+        RETRO_ENVIRONMENT_SET_PIXEL_FORMAT,
+        &RETRO_PIXEL_FORMAT_RGB565 as *const _ as *const c_void,
+    );
 }
 
 #[no_mangle]
@@ -249,14 +254,14 @@ pub extern "C" fn retro_run() {
         // in case a new frame is available in the emulator
         // then the frame must be pushed into display
         if emulator.ppu_frame() != last_frame {
-            let frame_buffer = emulator.frame_buffer_rgb1555();
+            let frame_buffer = emulator.frame_buffer_rgb565();
             unsafe {
                 FRAME_BUFFER.copy_from_slice(&frame_buffer);
                 video_refresh_cb(
                     FRAME_BUFFER.as_ptr(),
                     DISPLAY_WIDTH as u32,
                     DISPLAY_HEIGHT as u32,
-                    DISPLAY_WIDTH * RGB1555_SIZE,
+                    DISPLAY_WIDTH * RGB565_SIZE,
                 );
             }
 
diff --git a/src/gb.rs b/src/gb.rs
index 6627cdee6680bdc44e18888c2ebb09d7835b4fe9..d6b05e18bd410ae0e0f5e6e911ce30be93bfcfb1 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -16,8 +16,8 @@ use crate::{
     mmu::Mmu,
     pad::{Pad, PadKey},
     ppu::{
-        Ppu, PpuMode, Tile, DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB155_SIZE,
-        FRAME_BUFFER_SIZE,
+        Ppu, PpuMode, Tile, DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB1555_SIZE,
+        FRAME_BUFFER_RGB565_SIZE, FRAME_BUFFER_SIZE,
     },
     rom::{Cartridge, RamSize},
     serial::{NullDevice, Serial, SerialDevice},
@@ -962,10 +962,14 @@ impl GameBoy {
         &(self.ppu().frame_buffer)
     }
 
-    pub fn frame_buffer_rgb1555(&mut self) -> [u8; FRAME_BUFFER_RGB155_SIZE] {
+    pub fn frame_buffer_rgb1555(&mut self) -> [u8; FRAME_BUFFER_RGB1555_SIZE] {
         self.ppu().frame_buffer_rgb1555()
     }
 
+    pub fn frame_buffer_rgb565(&mut self) -> [u8; FRAME_BUFFER_RGB565_SIZE] {
+        self.ppu().frame_buffer_rgb565()
+    }
+
     pub fn audio_buffer(&mut self) -> &VecDeque<u8> {
         self.apu().audio_buffer()
     }
diff --git a/src/ppu.rs b/src/ppu.rs
index 587d93fdd084bca442168fa02134b7e4fdf7ef79..18e768540f656c07911507433246747fd074e862 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -24,6 +24,7 @@ pub const PALETTE_SIZE: usize = 4;
 pub const RGB_SIZE: usize = 3;
 pub const RGBA_SIZE: usize = 4;
 pub const RGB1555_SIZE: usize = 2;
+pub const RGB565_SIZE: usize = 2;
 pub const TILE_WIDTH: usize = 8;
 pub const TILE_HEIGHT: usize = 8;
 pub const TILE_WIDTH_I: usize = 7;
@@ -59,7 +60,10 @@ pub const COLOR_BUFFER_SIZE: usize = DISPLAY_SIZE;
 pub const FRAME_BUFFER_SIZE: usize = DISPLAY_SIZE * RGB_SIZE;
 
 /// The size of the RGB1555 frame buffer in bytes.
-pub const FRAME_BUFFER_RGB155_SIZE: usize = DISPLAY_SIZE * RGB1555_SIZE;
+pub const FRAME_BUFFER_RGB1555_SIZE: usize = DISPLAY_SIZE * RGB1555_SIZE;
+
+/// The size of the RGB565 frame buffer in bytes.
+pub const FRAME_BUFFER_RGB565_SIZE: usize = DISPLAY_SIZE * RGB565_SIZE;
 
 /// The base colors to be used to populate the
 /// custom palettes of the Game Boy.
@@ -85,6 +89,10 @@ pub type PixelAlpha = [u8; RGBA_SIZE];
 /// bit at the beginning.
 pub type PixelRgb1555 = [u8; RGB1555_SIZE];
 
+/// Defines a pixel with 5 bits per channel except for the
+/// green channel which uses 6 bits.
+pub type PixelRgb565 = [u8; RGB565_SIZE];
+
 /// Defines a type that represents a color palette
 /// within the Game Boy context.
 pub type Palette = [Pixel; PALETTE_SIZE];
@@ -907,8 +915,8 @@ impl Ppu {
         }
     }
 
-    pub fn frame_buffer_rgb1555(&self) -> [u8; FRAME_BUFFER_RGB155_SIZE] {
-        let mut buffer = [0u8; FRAME_BUFFER_RGB155_SIZE];
+    pub fn frame_buffer_rgb1555(&self) -> [u8; FRAME_BUFFER_RGB1555_SIZE] {
+        let mut buffer = [0u8; FRAME_BUFFER_RGB1555_SIZE];
         for index in 0..DISPLAY_SIZE {
             let (r, g, b) = (
                 self.frame_buffer[index * 3],
@@ -922,6 +930,21 @@ impl Ppu {
         buffer
     }
 
+    pub fn frame_buffer_rgb565(&self) -> [u8; FRAME_BUFFER_RGB565_SIZE] {
+        let mut buffer = [0u8; FRAME_BUFFER_RGB565_SIZE];
+        for index in 0..DISPLAY_SIZE {
+            let (r, g, b) = (
+                self.frame_buffer[index * 3],
+                self.frame_buffer[index * 3 + 1],
+                self.frame_buffer[index * 3 + 2],
+            );
+            let rgb565 = Self::rgb888_to_rgb565(r, g, b);
+            buffer[index * 2] = rgb565[0];
+            buffer[index * 2 + 1] = rgb565[1];
+        }
+        buffer
+    }
+
     pub fn vram(&self) -> &[u8; VRAM_SIZE] {
         &self.vram
     }
@@ -1745,6 +1768,15 @@ impl Ppu {
         let pixel = (a << 15) | (r << 10) | (g << 5) | b;
         [pixel as u8, (pixel >> 8) as u8]
     }
+
+    fn rgb888_to_rgb565(first: u8, second: u8, third: u8) -> PixelRgb565 {
+        let r = (first as u16 >> 3) & 0x1f;
+        let g = (second as u16 >> 2) & 0x3f;
+        let b = (third as u16 >> 3) & 0x1f;
+
+        let pixel = (r << 11) | (g << 5) | b;
+        [pixel as u8, (pixel >> 8) as u8]
+    }
 }
 
 impl Default for Ppu {