diff --git a/src/gb.rs b/src/gb.rs
index c6b0cd4314a14174c92811292ae04195e259fa2d..437c5ecebade820779474da41c22b5a562a6eff8 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -58,7 +58,7 @@ impl GameBoyMode {
         }
     }
 
-    pub fn from_u8(value: u8) -> GameBoyMode {
+    pub fn from_u8(value: u8) -> Self {
         match value {
             1 => GameBoyMode::Dmg,
             2 => GameBoyMode::Cgb,
@@ -67,7 +67,7 @@ impl GameBoyMode {
         }
     }
 
-    pub fn from_string(value: &str) -> GameBoyMode {
+    pub fn from_string(value: &str) -> Self {
         match value {
             "dmg" => GameBoyMode::Dmg,
             "cgb" => GameBoyMode::Cgb,
@@ -75,6 +75,18 @@ impl GameBoyMode {
             _ => panic!("Invalid mode value: {}", value),
         }
     }
+
+    pub fn is_dmg(&self) -> bool {
+        *self == GameBoyMode::Dmg
+    }
+
+    pub fn is_cgb(&self) -> bool {
+        *self == GameBoyMode::Cgb
+    }
+
+    pub fn is_sgb(&self) -> bool {
+        *self == GameBoyMode::Sgb
+    }
 }
 
 impl Display for GameBoyMode {
@@ -98,7 +110,7 @@ impl GameBoySpeed {
         }
     }
 
-    pub fn switch(&self) -> GameBoySpeed {
+    pub fn switch(&self) -> Self {
         match self {
             GameBoySpeed::Normal => GameBoySpeed::Double,
             GameBoySpeed::Double => GameBoySpeed::Normal,
@@ -112,7 +124,7 @@ impl GameBoySpeed {
         }
     }
 
-    pub fn from_u8(value: u8) -> GameBoySpeed {
+    pub fn from_u8(value: u8) -> Self {
         match value {
             0 => GameBoySpeed::Normal,
             1 => GameBoySpeed::Double,
diff --git a/src/ppu.rs b/src/ppu.rs
index 4461a53877817a5d106b8ae9cdb90e659b72ec64..690da47c5f3554bc31057dcf02c0e4ecddf060a9 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -1063,38 +1063,60 @@ impl Ppu {
     }
 
     fn render_line(&mut self) {
+        if self.gb_mode == GameBoyMode::Dmg {
+            self.render_line_dmg();
+        } else {
+            self.render_line_cgb();
+        }
+    }
+
+    fn render_line_dmg(&mut self) {
         if self.first_frame {
             return;
         }
-        let switch_bg_window =
-            (self.gb_mode == GameBoyMode::Cgb && !self.dmg_compat) || self.switch_bg;
+        if self.switch_bg {
+            self.render_map_dmg(self.bg_map, self.scx, self.scy, 0, 0, self.ly);
+        }
+        if self.switch_bg && self.switch_window {
+            self.render_map_dmg(self.window_map, 0, 0, self.wx, self.wy, self.window_counter);
+        }
+        if self.switch_obj {
+            self.render_objects();
+        }
+    }
 
+    fn render_line_cgb(&mut self) {
+        if self.first_frame {
+            return;
+        }
+        let switch_bg_window = (self.gb_mode.is_cgb() && !self.dmg_compat) || self.switch_bg;
         if switch_bg_window {
-            if self.gb_mode == GameBoyMode::Dmg {
-                self.render_map_dmg(self.bg_map, self.scx, self.scy, 0, 0, self.ly);
-            } else {
-                self.render_map(self.bg_map, self.scx, self.scy, 0, 0, self.ly);
-            }
+            self.render_map(self.bg_map, self.scx, self.scy, 0, 0, self.ly);
         }
         if switch_bg_window && self.switch_window {
-            if self.gb_mode == GameBoyMode::Dmg {
-                self.render_map_dmg(self.window_map, 0, 0, self.wx, self.wy, self.window_counter);
-            } else {
-                self.render_map(self.window_map, 0, 0, self.wx, self.wy, self.window_counter);
-            }
+            self.render_map(self.window_map, 0, 0, self.wx, self.wy, self.window_counter);
         }
         if self.switch_obj {
             self.render_objects();
         }
     }
 
-    fn render_map_dmg(&mut self, map: bool, scx: u8, scy: u8, wx: u8, wy: u8, ld: u8) {
+    fn render_map(&mut self, map: bool, scx: u8, scy: u8, wx: u8, wy: u8, ld: u8) {
         // in case the target window Y position has not yet been reached
         // then there's nothing to be done, returns control flow immediately
         if self.ly < wy {
             return;
         }
 
+        // selects the correct background attributes map based on the bg map flag
+        // because the attributes are separated according to the map they represent
+        // this is only relevant for CGB mode
+        let bg_map_attrs = if map {
+            self.bg_map_attrs_1
+        } else {
+            self.bg_map_attrs_0
+        };
+
         // obtains the base address of the background map using the bg map flag
         // that control which background map is going to be used
         let map_offset: usize = if map { 0x1c00 } else { 0x1800 };
@@ -1121,6 +1143,35 @@ impl Ppu {
             tile_index += 256;
         }
 
+        // obtains the reference to the attributes of the new tile in
+        // drawing for meta processing (CGB only)
+        let mut tile_attr = if self.dmg_compat {
+            &DEFAULT_TILE_ATTR
+        } else {
+            &bg_map_attrs[row_offset + line_offset]
+        };
+
+        // retrieves the proper palette for the current tile in drawing
+        // taking into consideration if we're running in CGB mode or not
+        let mut palette = if self.gb_mode == GameBoyMode::Cgb {
+            if self.dmg_compat {
+                &self.palette_bg
+            } else {
+                &self.palettes_color_bg[tile_attr.palette as usize]
+            }
+        } else {
+            &self.palette_bg
+        };
+
+        // obtains the values of both X and Y flips for the current tile
+        // they will be applied by the get tile pixel method
+        let mut xflip = tile_attr.xflip;
+        let mut yflip = tile_attr.yflip;
+
+        // increments the tile index value by the required offset for the VRAM
+        // bank in which the tile is stored, this is only required for CGB mode
+        tile_index += tile_attr.vram_bank as usize * TILE_COUNT_DMG;
+
         // obtains the reference to the tile that is going to be drawn
         let mut tile = &self.tiles[tile_index];
 
@@ -1149,8 +1200,8 @@ impl Ppu {
         for _ in initial_index..DISPLAY_WIDTH {
             // obtains the current pixel data from the tile and
             // re-maps it according to the current palette
-            let pixel = tile.get(x, y);
-            let color = &self.palette_bg[pixel as usize];
+            let pixel = tile.get_flipped(x, y, xflip, yflip);
+            let color = &palette[pixel as usize];
 
             // updates the pixel in the color buffer, which stores
             // the raw pixel color information (unmapped)
@@ -1182,6 +1233,17 @@ impl Ppu {
                     tile_index += 256;
                 }
 
+                // in case the current mode is CGB and the DMG compatibility
+                // flag is not set then a series of tile values must be
+                // updated according to the tile attributes field
+                if self.gb_mode == GameBoyMode::Cgb && !self.dmg_compat {
+                    tile_attr = &bg_map_attrs[row_offset + line_offset];
+                    palette = &self.palettes_color_bg[tile_attr.palette as usize];
+                    xflip = tile_attr.xflip;
+                    yflip = tile_attr.yflip;
+                    tile_index += tile_attr.vram_bank as usize * TILE_COUNT_DMG;
+                }
+
                 // obtains the reference to the new tile in drawing
                 tile = &self.tiles[tile_index];
             }
@@ -1196,22 +1258,13 @@ impl Ppu {
         }
     }
 
-    fn render_map(&mut self, map: bool, scx: u8, scy: u8, wx: u8, wy: u8, ld: u8) {
+    fn render_map_dmg(&mut self, map: bool, scx: u8, scy: u8, wx: u8, wy: u8, ld: u8) {
         // in case the target window Y position has not yet been reached
         // then there's nothing to be done, returns control flow immediately
         if self.ly < wy {
             return;
         }
 
-        // selects the correct background attributes map based on the bg map flag
-        // because the attributes are separated according to the map they represent
-        // this is only relevant for CGB mode
-        let bg_map_attrs = if map {
-            self.bg_map_attrs_1
-        } else {
-            self.bg_map_attrs_0
-        };
-
         // obtains the base address of the background map using the bg map flag
         // that control which background map is going to be used
         let map_offset: usize = if map { 0x1c00 } else { 0x1800 };
@@ -1238,35 +1291,6 @@ impl Ppu {
             tile_index += 256;
         }
 
-        // obtains the reference to the attributes of the new tile in
-        // drawing for meta processing (CGB only)
-        let mut tile_attr = if self.dmg_compat {
-            &DEFAULT_TILE_ATTR
-        } else {
-            &bg_map_attrs[row_offset + line_offset]
-        };
-
-        // retrieves the proper palette for the current tile in drawing
-        // taking into consideration if we're running in CGB mode or not
-        let mut palette = if self.gb_mode == GameBoyMode::Cgb {
-            if self.dmg_compat {
-                &self.palette_bg
-            } else {
-                &self.palettes_color_bg[tile_attr.palette as usize]
-            }
-        } else {
-            &self.palette_bg
-        };
-
-        // obtains the values of both X and Y flips for the current tile
-        // they will be applied by the get tile pixel method
-        let mut xflip = tile_attr.xflip;
-        let mut yflip = tile_attr.yflip;
-
-        // increments the tile index value by the required offset for the VRAM
-        // bank in which the tile is stored, this is only required for CGB mode
-        tile_index += tile_attr.vram_bank as usize * TILE_COUNT_DMG;
-
         // obtains the reference to the tile that is going to be drawn
         let mut tile = &self.tiles[tile_index];
 
@@ -1295,8 +1319,8 @@ impl Ppu {
         for _ in initial_index..DISPLAY_WIDTH {
             // obtains the current pixel data from the tile and
             // re-maps it according to the current palette
-            let pixel = tile.get_flipped(x, y, xflip, yflip);
-            let color = &palette[pixel as usize];
+            let pixel = tile.get(x, y);
+            let color = &self.palette_bg[pixel as usize];
 
             // updates the pixel in the color buffer, which stores
             // the raw pixel color information (unmapped)
@@ -1328,17 +1352,6 @@ impl Ppu {
                     tile_index += 256;
                 }
 
-                // in case the current mode is CGB and the DMG compatibility
-                // flag is not set then a series of tile values must be
-                // updated according to the tile attributes field
-                if self.gb_mode == GameBoyMode::Cgb && !self.dmg_compat {
-                    tile_attr = &bg_map_attrs[row_offset + line_offset];
-                    palette = &self.palettes_color_bg[tile_attr.palette as usize];
-                    xflip = tile_attr.xflip;
-                    yflip = tile_attr.yflip;
-                    tile_index += tile_attr.vram_bank as usize * TILE_COUNT_DMG;
-                }
-
                 // obtains the reference to the new tile in drawing
                 tile = &self.tiles[tile_index];
             }