workaround a problem with the harmattan gcc
[drnoksnes] / gfx.cpp
diff --git a/gfx.cpp b/gfx.cpp
index 85334ef..45e5dce 100644 (file)
--- a/gfx.cpp
+++ b/gfx.cpp
  * Super NES and Super Nintendo Entertainment System are trademarks of
  * Nintendo Co., Limited and its subsidiary companies.
  */
+
+#include <stdarg.h>
+
 #include "snes9x.h"
 
 #include "memmap.h"
 #include "ppu.h"
 #include "cpuexec.h"
-#include "display.h"
 #include "gfx.h"
 #include "apu.h"
 #include "cheats.h"
-#include <stdint.h>
-//#include "asmmemfuncs.h"
+#include "tile.h"
+#include "misc.h"
 
-//misc.s
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern void memcpy16(unsigned short *dest, unsigned short *src, int count);
-extern void memcpy16bswap(unsigned short *dest, void *src, int count);
-extern void memcpy32(uint32_t *dest, uint32_t *src, int count);
-extern void memset32(uint32_t *dest, int c, int count);
-#ifdef __cplusplus
-}
-#endif
+#define USE_CRAZY_OPTS
 
 #define M7 19
 #define M8 19
 
-void ComputeClipWindows ();
-static void S9xDisplayFrameRate ();
-static void S9xDisplayString (const char *string);
+#define GFX_PIX_SIZE 1
+
+void ComputeClipWindows();
+static void S9xDisplayFrameRate();
+static void S9xDisplayString(const char *string);
 
 extern uint8 BitShifts[8][4];
 extern uint8 TileShifts[8][4];
@@ -112,110 +106,7 @@ extern uint8  Mode7Depths [2];
 
 #define BLACK BUILD_PIXEL(0,0,0)
 
-void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine,
-              uint32 LineCount, struct SGFX * gfx);
-void DrawClippedTile (uint32 Tile, uint32 Offset,
-                     uint32 StartPixel, uint32 Width,
-                     uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                uint32 LineCount, struct SGFX * gfx);
-void DrawClippedTilex2 (uint32 Tile, uint32 Offset,
-                       uint32 StartPixel, uint32 Width,
-                       uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-void DrawTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-              uint32 LineCount, struct SGFX * gfx);
-void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset,
-                         uint32 StartPixel, uint32 Width,
-                         uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-void DrawLargePixel (uint32 Tile, uint32 Offset,
-                    uint32 StartPixel, uint32 Pixels,
-                    uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                uint32 LineCount, struct SGFX * gfx);
-void DrawClippedTile16 (uint32 Tile, uint32 Offset,
-                       uint32 StartPixel, uint32 Width,
-                       uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                  uint32 LineCount, struct SGFX * gfx);
-void DrawClippedTile16x2 (uint32 Tile, uint32 Offset,
-                         uint32 StartPixel, uint32 Width,
-                         uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-void DrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                    uint32 LineCount, struct SGFX * gfx);
-void DrawClippedTile16x2x2 (uint32 Tile, uint32 Offset,
-                           uint32 StartPixel, uint32 Width,
-                           uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-void DrawLargePixel16 (uint32 Tile, uint32 Offset,
-                      uint32 StartPixel, uint32 Pixels,
-                      uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine,
-                   uint32 LineCount, struct SGFX * gfx);
-
-void DrawClippedTile16Add (uint32 Tile, uint32 Offset,
-                          uint32 StartPixel, uint32 Width,
-                          uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                      uint32 LineCount, struct SGFX * gfx);
-
-void DrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset,
-                             uint32 StartPixel, uint32 Width,
-                             uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                           uint32 LineCount, struct SGFX * gfx);
-
-void DrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset,
-                                  uint32 StartPixel, uint32 Width,
-                                  uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine,
-                   uint32 LineCount, struct SGFX * gfx);
-
-void DrawClippedTile16Sub (uint32 Tile, uint32 Offset,
-                          uint32 StartPixel, uint32 Width,
-                          uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                      uint32 LineCount, struct SGFX * gfx);
-
-void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset,
-                             uint32 StartPixel, uint32 Width,
-                             uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine,
-                           uint32 LineCount, struct SGFX * gfx);
-
-void DrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset,
-                                  uint32 StartPixel, uint32 Width,
-                                  uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawLargePixel16Add (uint32 Tile, uint32 Offset,
-                         uint32 StartPixel, uint32 Pixels,
-                         uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset,
-                            uint32 StartPixel, uint32 Pixels,
-                            uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawLargePixel16Sub (uint32 Tile, uint32 Offset,
-                         uint32 StartPixel, uint32 Pixels,
-                         uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset,
-                            uint32 StartPixel, uint32 Pixels,
-                            uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawHiResClippedTile16 (uint32 Tile, uint32 Offset,
-                       uint32 StartPixel, uint32 Width,
-                       uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-void DrawHiResTile16 (uint32 Tile, uint32 Offset,
-                       uint32 StartLine, uint32 LineCount, struct SGFX * gfx);
-
-bool8_32 S9xGraphicsInit ()
+bool8 S9xGraphicsInit ()
 {
     register uint32 PixelOdd = 1;
     register uint32 PixelEven = 2;
@@ -315,46 +206,20 @@ bool8_32 S9xGraphicsInit ()
        PixelOdd <<= 2;
     }
 
-    GFX.RealPitch = GFX.Pitch2 = GFX.Pitch;
-    GFX.ZPitch = GFX.Pitch;
-    if (Settings.SixteenBit)
-       GFX.ZPitch >>= 1;
-    GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
-    GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer;
-    //GFX.InfoStringTimeout = 0;
-    //GFX.InfoString = NULL;
+    GFX.InfoStringTimeout = 0;
+    GFX.InfoString = NULL;
 
     PPU.BG_Forced = 0;
     IPPU.OBJChanged = TRUE;
-    if (Settings.Transparency)
-       Settings.SixteenBit = TRUE;
 
-    IPPU.DirectColourMapsNeedRebuild = TRUE;
-    GFX.PixSize = 1;
-    if (Settings.SixteenBit)
-    {
+       IPPU.DirectColourMapsNeedRebuild = TRUE;
        DrawTilePtr = DrawTile16;
        DrawClippedTilePtr = DrawClippedTile16;
        DrawLargePixelPtr = DrawLargePixel16;
        DrawHiResTilePtr= DrawHiResTile16;
        DrawHiResClippedTilePtr = DrawHiResClippedTile16;
-       GFX.PPL = GFX.Pitch >> 1;
-       GFX.PPLx2 = GFX.Pitch;
-    }
-    else
-    {
-       DrawTilePtr = DrawTile;
-       DrawClippedTilePtr = DrawClippedTile;
-       DrawLargePixelPtr = DrawLargePixel;
-       DrawHiResTilePtr = DrawTile;
-       DrawHiResClippedTilePtr = DrawClippedTile;
-       GFX.PPL = GFX.Pitch;
-       GFX.PPLx2 = GFX.Pitch * 2;
-    }
-    S9xFixColourBrightness ();
+    S9xFixColourBrightness();
 
-    if (Settings.SixteenBit)
-    {
        if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000)))
            return (FALSE);
 
@@ -501,15 +366,8 @@ bool8_32 S9xGraphicsInit ()
                }
            }
        }
-    }
-    else
-    {
-       GFX.X2 = NULL;
-       GFX.ZERO_OR_X2 = NULL;
-       GFX.ZERO = NULL;
-    }
 
-    return (TRUE);
+    return TRUE;
 }
 
 void S9xGraphicsDeinit (void)
@@ -547,42 +405,30 @@ void S9xBuildDirectColourMaps ()
     IPPU.DirectColourMapsNeedRebuild = FALSE;
 }
 
-void S9xStartScreenRefresh ()
+void S9xStartScreenRefresh()
 {
-    if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0)
-       GFX.InfoString = NULL;
-
-    if (IPPU.RenderThisFrame)
-    {
-#ifndef _SNESPPC
-       if (!S9xInitUpdate ())
-       {
-           IPPU.RenderThisFrame = FALSE;
-           return;
+       if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) {
+               free(GFX.InfoString);
+               GFX.InfoString = NULL;
        }
-#endif
-       IPPU.RenderedFramesCount++;
-       IPPU.PreviousLine = IPPU.CurrentLine = 0;
-       IPPU.MaxBrightness = PPU.Brightness;
-       IPPU.LatchedBlanking = PPU.ForcedBlanking;
-       IPPU.LatchedInterlace = (Memory.FillRAM[0x2133] & 1);
-       IPPU.RenderedScreenWidth = 256;
-       IPPU.RenderedScreenHeight = PPU.ScreenHeight;
-       IPPU.DoubleWidthPixels = FALSE;
-       GFX.Pitch2 = GFX.Pitch = GFX.RealPitch;
-       GFX.PPL = GFX.PPLx2 >> 1;
-       GFX.ZPitch = GFX.RealPitch;
-       if (Settings.SixteenBit)
-                   GFX.ZPitch >>= 1;
-       PPU.RecomputeClipWindows = TRUE;
-       GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer;
-       GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1;
-    }
-    if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0)
-    {
-       IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount;
-       IPPU.RenderedFramesCount = 0;
-       IPPU.FrameCount = 0;
+
+       IPPU.FrameCount++;
+
+       if (IPPU.RenderThisFrame) {
+               if (!S9xInitUpdate()) {
+                       IPPU.RenderThisFrame = FALSE;
+                       return;
+               }
+
+               IPPU.PreviousLine = IPPU.CurrentLine = 0;
+               IPPU.MaxBrightness = PPU.Brightness;
+               IPPU.LatchedBlanking = PPU.ForcedBlanking;
+               IPPU.LatchedInterlace = (Memory.FillRAM[0x2133] & 1);
+               IPPU.RenderedScreenWidth = 256;
+               IPPU.RenderedScreenHeight = PPU.ScreenHeight;
+               IPPU.DoubleWidthPixels = FALSE;
+
+               PPU.RecomputeClipWindows = TRUE;
     }
 }
 
@@ -633,51 +479,32 @@ void RenderLine (uint8 C)
 
 void S9xEndScreenRefresh()
 {
-    IPPU.HDMAStarted = FALSE;
+       IPPU.HDMAStarted = FALSE;
 
-//RC
-    if (IPPU.RenderThisFrame)
-    {
-       FLUSH_REDRAW ();
-       if (IPPU.ColorsChanged)
-       {
-           uint32 saved = PPU.CGDATA[0];
-           if (!Settings.SixteenBit)
-           {
-                       // Hack for Super Mario World - to get its sky blue
-                       // (It uses Fixed colour addition on the backdrop colour)
-                       if (!(Memory.FillRAM [0x2131] & 0x80) &&
-                               (Memory.FillRAM[0x2131] & 0x20) &&
-                               (PPU.FixedColourRed || PPU.FixedColourGreen ||
-                                PPU.FixedColourBlue))
-                       {
-                               PPU.CGDATA[0] = PPU.FixedColourRed |
-                                               (PPU.FixedColourGreen << 5) |
-                                               (PPU.FixedColourBlue << 10);
-                       }
-           }
-           IPPU.ColorsChanged = FALSE;
-               
-           S9xSetPalette ();
+       if (IPPU.RenderThisFrame) {
+               FLUSH_REDRAW ();
 
-           PPU.CGDATA[0] = saved;
-       }
-            GFX.Pitch = GFX.Pitch2 = GFX.RealPitch;
-            GFX.PPL = GFX.PPLx2 >> 1;
+               IPPU.RenderedFramesCount++;
+
+               if (IPPU.ColorsChanged) {
+                       IPPU.ColorsChanged = FALSE;
+               }
 
-       if (Settings.DisplayFrameRate)
-           S9xDisplayFrameRate ();
-       if (GFX.InfoString)
-           S9xDisplayString (GFX.InfoString);
+               if (Settings.DisplayFrameRate) {
+                       S9xDisplayFrameRate();
+               }
 
-       S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight,
-                        Settings.SixteenBit);
+               if (GFX.InfoString) {
+                       S9xDisplayString(GFX.InfoString);
+               }
+
+               S9xDeinitUpdate(IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight);
     }
+
 #ifndef RC_OPTIMIZED
-    S9xApplyCheats ();
+       S9xApplyCheats ();
 #endif
 
-
 #ifdef DEBUGGER
     if (CPU.Flags & FRAME_ADVANCE_FLAG)
     {
@@ -713,13 +540,22 @@ void S9xEndScreenRefresh()
     }
 }
 
-void S9xSetInfoString (const char *string)
+void S9xSetInfoString (const char * fmt, ...)
 {
-    GFX.InfoString = string;
-    GFX.InfoStringTimeout = 120;
+       va_list ap;
+       va_start(ap, fmt);
+
+       if (vasprintf(&GFX.InfoString, fmt, ap) > 0) {
+               GFX.InfoStringTimeout = 120;
+       } else {
+               GFX.InfoString = 0;
+               GFX.InfoStringTimeout = 0;
+       }
+
+    va_end(ap);
 }
 
-INLINE void SelectTileRenderer (bool8_32 normal)
+static inline void SelectTileRenderer (bool normal)
 {
     if (normal)
     {
@@ -845,7 +681,7 @@ void S9xSetupOBJ ()
     IPPU.OBJChanged = FALSE;
 }
 
-void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
+static void DrawOBJS (bool OnMain = FALSE, uint8 D = 0)
 {
        uint32 O;
     uint32 BaseTile, Tile;
@@ -863,8 +699,6 @@ void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
        BG.NameSelect = PPU.OBJNameSelect;
     BG.DirectColourMode = FALSE;
 
-    GFX.PixSize = 1;
-
     GFX.Z1 = D + 2;
 
     int I = 0;
@@ -953,26 +787,26 @@ void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
                    {
                        Tile += ((Left - PPU.OBJ[S].HPos) >> 3) * TileInc;
                        Middle -= (Left - PPU.OBJ[S].HPos) >> 3;
-                       O += Left * GFX.PixSize;
+                       O += Left * GFX_PIX_SIZE;
                        if ((Offset = (Left - PPU.OBJ[S].HPos) & 7))
                        {
-                           O -= Offset * GFX.PixSize;
+                           O -= Offset * GFX_PIX_SIZE;
                            int W = 8 - Offset;
                            int Width = Right - Left;
                            if (W > Width)
                                W = Width;
                            (*DrawClippedTilePtr) (Tile, O, Offset, W,
-                                                  TileLine, LineCount, &GFX);
+                                                  TileLine, LineCount);
                            
                            if (W >= Width)
                                continue;
                            Tile += TileInc;
                            Middle--;
-                           O += 8 * GFX.PixSize;
+                           O += 8 * GFX_PIX_SIZE;
                        }
                    }
                    else
-                       O += PPU.OBJ[S].HPos * GFX.PixSize;
+                       O += PPU.OBJ[S].HPos * GFX_PIX_SIZE;
 
                    if (PPU.OBJ[S].HPos + Size >= Right)
                    {
@@ -983,15 +817,15 @@ void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
                    else
                        Offset = 0;
 
-                   for (int X = 0; X < Middle; X++, O += 8 * GFX.PixSize,
+                   for (int X = 0; X < Middle; X++, O += 8 * GFX_PIX_SIZE,
                         Tile += TileInc)
                    {
-                       (*DrawTilePtr) (Tile, O, TileLine, LineCount, &GFX);
+                       (*DrawTilePtr) (Tile, O, TileLine, LineCount);
                    }
                    if (Offset)
                    {
                        (*DrawClippedTilePtr) (Tile, O, 0, Offset,
-                                              TileLine, LineCount, &GFX);
+                                              TileLine, LineCount);
                    }
                }
            }
@@ -999,7 +833,7 @@ void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
     }
 }
 
-void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
+static void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
 {
     CHECK_SOUND();
 
@@ -1098,9 +932,9 @@ void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                HPos = HOffset + Left;
                PixWidth = PPU.Mosaic - r;
            }
-           uint32 s = Y * GFX.PPL + Left * GFX.PixSize;
+           uint32 s = Y * GFX.PPL + Left * GFX_PIX_SIZE;
            for (uint32 x = Left; x < Right; x += PixWidth, 
-                s += PixWidth * GFX.PixSize,
+                s += PixWidth * GFX_PIX_SIZE,
                 HPos += PixWidth, PixWidth = PPU.Mosaic)
            {
                uint32 Quot = (HPos & OffsetMask) >> 3;
@@ -1139,13 +973,13 @@ void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            {
                                (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                            else
                            {
                                (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                        }
                        else
@@ -1155,13 +989,13 @@ void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            {
                                (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                            else
                            {
                                (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                        }
                    }
@@ -1175,13 +1009,13 @@ void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            {
                                (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                            else
                            {
                                (*DrawLargePixelPtr) (Tile + (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                        }
                        else
@@ -1191,26 +1025,26 @@ void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            {
                                (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                            else
                            {
                                (*DrawLargePixelPtr) (Tile + (Quot & 1), s,
                                                      HPos & 7, PixWidth,
-                                                     VirtAlign, Lines, &GFX);
+                                                     VirtAlign, Lines);
                            }
                        }
                    }
                }
                else
                    (*DrawLargePixelPtr) (Tile, s, HPos & 7, PixWidth,
-                                         VirtAlign, Lines, &GFX);
+                                         VirtAlign, Lines);
            }
        }
     }
 }
 
-void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
+static void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
 {
     CHECK_SOUND();
 
@@ -1337,8 +1171,8 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
            uint32 TotalCount = 0;
            uint32 MaxCount = 8;
 
-           uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
-           bool8_32 left_hand_edge = (Left == 0);
+           uint32 s = Left * GFX_PIX_SIZE + Y * GFX.PPL;
+           bool left_hand_edge = (Left == 0);
            Width = Right - Left;
 
            if (Left & 7)
@@ -1353,7 +1187,7 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                    // for the tile at the left-hand edge of the screen.
                    VOffset = LineData [Y].BG[bg].VOffset;
                                        HOffset = LineHOffset;
-                   left_hand_edge = FALSE;
+                   left_hand_edge = false;
                }
                else
                {
@@ -1444,19 +1278,19 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                if (Count > MaxCount)
                    Count = MaxCount;
 
-               s -= Offset * GFX.PixSize;
+               s -= Offset * GFX_PIX_SIZE;
                Tile = READ_2BYTES(t);
                GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
 
                if (BG.TileSize == 8)
-                   (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines, &GFX);
+                   (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines);
                else
                {
                    if (!(Tile & (V_FLIP | H_FLIP)))
                    {
                        // Normal, unflipped
                        (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1),
-                                              s, Offset, Count, VirtAlign, Lines, &GFX);
+                                              s, Offset, Count, VirtAlign, Lines);
                    }
                    else
                    if (Tile & H_FLIP)
@@ -1465,39 +1299,36 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                        {
                            // H & V flip
                            (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
-                                                  s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                  s, Offset, Count, VirtAlign, Lines);
                        }
                        else
                        {
                            // H flip only
                            (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
-                                                  s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                  s, Offset, Count, VirtAlign, Lines);
                        }
                    }
                    else
                    {
                        // V flip only
                        (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1),
-                                              s, Offset, Count, VirtAlign, Lines, &GFX);
+                                              s, Offset, Count, VirtAlign, Lines);
                    }
                }
 
                Left += Count;
                TotalCount += Count;
-               s += (Offset + Count) * GFX.PixSize;
+               s += (Offset + Count) * GFX_PIX_SIZE;
                MaxCount = 8;
            }
        }
     }
 }
 
-void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
+static void DrawBackgroundMode5 (uint32 /*BGMODE*/, uint32 bg, uint8 Z1, uint8 Z2)
 {
     CHECK_SOUND();
 
-    GFX.Pitch = GFX.RealPitch;
-    GFX.PPL = GFX.PPLx2 >> 1;
-    GFX.PixSize = 1;
     uint8 depths [2] = {Z1, Z2};
 
     uint32 Tile;
@@ -1604,8 +1435,8 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    continue;
            }
 
-           uint32 s = (Left>>1) * GFX.PixSize + Y * GFX.PPL;
-           uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff;
+           intptr_t s = (Left>>1) * GFX_PIX_SIZE + Y * GFX.PPL;
+           uint32 HPos = (HOffset + Left * GFX_PIX_SIZE) & 0x3ff;
 
            uint32 Quot = HPos >> 3;
            uint32 Count = 0;
@@ -1634,13 +1465,13 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    {
                        // Normal, unflipped
                        (*DrawHiResClippedTilePtr) (Tile + (Quot & 1),
-                                                   s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                   s, Offset, Count, VirtAlign, Lines);
                    }
                    else
                    {
                        // H flip
                        (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1),
-                                                   s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                   s, Offset, Count, VirtAlign, Lines);
                    }
                }
                else
@@ -1649,7 +1480,7 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    {
                        // Normal, unflipped
                        (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1),
-                                                   s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                   s, Offset, Count, VirtAlign, Lines);
                    }
                    else
                    if (Tile & H_FLIP)
@@ -1658,20 +1489,20 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                        {
                            // H & V flip
                            (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
-                                                       s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                       s, Offset, Count, VirtAlign, Lines);
                        }
                        else
                        {
                            // H flip only
                            (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
-                                                       s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                       s, Offset, Count, VirtAlign, Lines);
                        }
                    }
                    else
                    {
                        // V flip only
                        (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1),
-                                                   s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                   s, Offset, Count, VirtAlign, Lines);
                    }
                }
 
@@ -1698,13 +1529,13 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    {
                        // Normal, unflipped
                        (*DrawHiResTilePtr) (Tile + (Quot & 1),
-                                            s, VirtAlign, Lines, &GFX);
+                                            s, VirtAlign, Lines);
                    }
                    else
                    {
                        // H flip
                        (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1),
-                                           s, VirtAlign, Lines, &GFX);
+                                           s, VirtAlign, Lines);
                    }
                }
                else
@@ -1713,7 +1544,7 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    {
                        // Normal, unflipped
                        (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1),
-                                            s, VirtAlign, Lines, &GFX);
+                                            s, VirtAlign, Lines);
                    }
                    else
                    if (Tile & H_FLIP)
@@ -1722,20 +1553,20 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                        {
                            // H & V flip
                            (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1),
-                                                s, VirtAlign, Lines, &GFX);
+                                                s, VirtAlign, Lines);
                        }
                        else
                        {
                            // H flip only
                            (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1),
-                                                s, VirtAlign, Lines, &GFX);
+                                                s, VirtAlign, Lines);
                        }
                    }
                    else
                    {
                        // V flip only
                        (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1),
-                                            s, VirtAlign, Lines, &GFX);
+                                            s, VirtAlign, Lines);
                    }
                }
 
@@ -1758,13 +1589,13 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    {
                        // Normal, unflipped
                        (*DrawHiResClippedTilePtr) (Tile + (Quot & 1),
-                                                   s, 0, Count, VirtAlign, Lines, &GFX);
+                                                   s, 0, Count, VirtAlign, Lines);
                    }
                    else
                    {
                        // H flip
                        (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1),
-                                                   s, 0, Count, VirtAlign, Lines, &GFX);
+                                                   s, 0, Count, VirtAlign, Lines);
                    }
                }
                else
@@ -1773,7 +1604,7 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                    {
                        // Normal, unflipped
                        (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1),
-                                                   s, 0, Count, VirtAlign, Lines, &GFX);
+                                                   s, 0, Count, VirtAlign, Lines);
                    }
                    else
                    if (Tile & H_FLIP)
@@ -1782,20 +1613,20 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                        {
                            // H & V flip
                            (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
-                                                       s, 0, Count, VirtAlign, Lines, &GFX);
+                                                       s, 0, Count, VirtAlign, Lines);
                        }
                        else
                        {
                            // H flip only
                            (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
-                                                       s, 0, Count, VirtAlign, Lines, &GFX);
+                                                       s, 0, Count, VirtAlign, Lines);
                        }
                    }
                    else
                    {
                        // V flip only
                        (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1),
-                                                   s, 0, Count, VirtAlign, Lines, &GFX);
+                                                   s, 0, Count, VirtAlign, Lines);
                    }
                }
            }
@@ -1803,10 +1634,8 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
     }
 }
 
-void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
+static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
 {
-    GFX.PixSize = 1;
-
     BG.TileSize = BGSizes [PPU.BG[bg].BGSize];
     BG.BitShift = BitShifts[BGMode][bg];
     BG.TileShift = TileShifts[BGMode][bg];
@@ -1953,7 +1782,7 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            continue;
                    }
 
-                   uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
+                   intptr_t s = Left * GFX_PIX_SIZE + Y * GFX.PPL;
                    uint32 HPos = (HOffset + Left) & OffsetMask;
 
                    uint32 Quot = HPos >> 3;
@@ -1983,14 +1812,14 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                        Count = 8 - Offset;
                        if (Count > Width)
                            Count = Width;
-                       s -= Offset * GFX.PixSize;
+                   s -= Offset * GFX_PIX_SIZE;
                        Tile = READ_2BYTES(t);
                        GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
 
                        if (BG.TileSize == 8)
                        {
                            (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign,
-                                                  Lines, &GFX);
+                                                  Lines);
                        }
                        else
                        {
@@ -1998,7 +1827,7 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            {
                                        // Normal, unflipped
                                        (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1),
-                                                      s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                      s, Offset, Count, VirtAlign, Lines);
                            }
                            else
                            if (Tile & H_FLIP)
@@ -2007,20 +1836,20 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                                {
                                    // H & V flip
                                    (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
-                                                          s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                          s, Offset, Count, VirtAlign, Lines);
                                }
                                else
                                {
                                    // H flip only
                                    (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
-                                                          s, Offset, Count, VirtAlign, Lines, &GFX);
+                                                          s, Offset, Count, VirtAlign, Lines);
                                }
                            }
                            else
                            {
                                // V flip only
                                (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s, 
-                                                      Offset, Count, VirtAlign, Lines, &GFX);
+                                                      Offset, Count, VirtAlign, Lines);
                            }
                        }
 
@@ -2041,14 +1870,14 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                                t = b1;
                        }
                        Quot++;
-                       s += 8 * GFX.PixSize;
+                       s += 8 * GFX_PIX_SIZE;
                    }
 
                    // Middle, unclipped tiles
                    Count = Width - Count;
                    int Middle = Count >> 3;
                    Count &= 7;
-                   for (int C = Middle; C > 0; s += 8 * GFX.PixSize, Quot++, C--)
+                   for (int C = Middle; C > 0; s += 8 * GFX_PIX_SIZE, Quot++, C--)
                    {
                        Tile = READ_2BYTES(t);
                        GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
@@ -2062,13 +1891,13 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                                {
                                    // Both horzontal & vertical flip
                                    (*DrawTilePtr) (Tile + t2 + 1 - (Quot & 1), s, 
-                                                   VirtAlign, Lines, &GFX);
+                                                   VirtAlign, Lines);
                                }
                                else
                                {
                                    // Horizontal flip only
                                    (*DrawTilePtr) (Tile + t1 + 1 - (Quot & 1), s, 
-                                                   VirtAlign, Lines, &GFX);
+                                                   VirtAlign, Lines);
                                }
                            }
                            else
@@ -2078,19 +1907,19 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                                {
                                    // Vertical flip only
                                    (*DrawTilePtr) (Tile + t2 + (Quot & 1), s,
-                                                   VirtAlign, Lines, &GFX);
+                                                   VirtAlign, Lines);
                                }
                                else
                                {
                                    // Normal unflipped
                                    (*DrawTilePtr) (Tile + t1 + (Quot & 1), s,
-                                                   VirtAlign, Lines, &GFX);
+                                                   VirtAlign, Lines);
                                }
                            }
                        }
                        else
                        {
-                           (*DrawTilePtr) (Tile, s, VirtAlign, Lines, &GFX);
+                           (*DrawTilePtr) (Tile, s, VirtAlign, Lines);
                        }
 
                        if (BG.TileSize == 8)
@@ -2120,14 +1949,14 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
 
                        if (BG.TileSize == 8)
                            (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign, 
-                                                  Lines, &GFX);
+                                                  Lines);
                        else
                        {
                            if (!(Tile & (V_FLIP | H_FLIP)))
                            {
                                // Normal, unflipped
                                (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0, 
-                                                      Count, VirtAlign, Lines, &GFX);
+                                                      Count, VirtAlign, Lines);
                            }
                            else
                            if (Tile & H_FLIP)
@@ -2137,14 +1966,14 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                                    // H & V flip
                                    (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1),
                                                           s, 0, Count, VirtAlign, 
-                                                          Lines, &GFX);
+                                                          Lines);
                                }
                                else
                                {
                                    // H flip only
                                    (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1),
                                                           s, 0, Count, VirtAlign,
-                                                          Lines, &GFX);
+                                                          Lines);
                                }
                            }
                            else
@@ -2152,7 +1981,7 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                                // V flip only
                                (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1),
                                                       s, 0, Count, VirtAlign, 
-                                                      Lines, &GFX);
+                                                      Lines);
                            }
                        }
                    }
@@ -2160,55 +1989,54 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
     }
 }
 
-#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \
-    CHECK_SOUND(); \
-\
-    uint8 *VRAM1 = Memory.VRAM + 1; \
-    if (GFX.r2130 & 1) \
-    { \
-               if (IPPU.DirectColourMapsNeedRebuild) \
-                       S9xBuildDirectColourMaps (); \
-               GFX.ScreenColors = DirectColourMaps [0]; \
-    } \
-    else \
-               GFX.ScreenColors = IPPU.ScreenColors; \
-\
-    int aa, cc; \
-    int dir; \
-    int startx, endx; \
-    uint32 Left = 0; \
-    uint32 Right = 256; \
-    uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \
-\
-    if (!ClipCount) \
-       ClipCount = 1; \
-\
-    Screen += GFX.StartY * GFX.Pitch; \
-    uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \
-    struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \
-\
-    for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \
-    { \
-       int yy; \
-\
-       int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \
-       int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \
-\
-       int32 CentreX = ((int32) l->CentreX << M7) >> M7; \
-       int32 CentreY = ((int32) l->CentreY << M7) >> M7; \
-\
-       if (PPU.Mode7VFlip) \
-           yy = 261 - (int) Line; \
-       else \
-           yy = Line; \
-\
-       if (PPU.Mode7Repeat == 0) \
-           yy += (VOffset - CentreY) % 1023; \
-       else \
-           yy += VOffset - CentreY; \
-       register int BB = l->MatrixB * yy + (CentreX << 8); \
-       register int DD = l->MatrixD * yy + (CentreY << 8); \
-\
+#define RENDER_BACKGROUND_MODE7_PIXEL_NOREPEAT(FUNC,HFLIP,REPEAT,MASK,PRIOMASK) \
+       const uint8 bmask = MASK; \
+       for (int x = startx; x != endx; \
+               x += (HFLIP ? -1 : 1), AA += aa, CC += cc, p++, d++) \
+       { \
+               int X = ((AA + BB) >> 8) & 0x3ff; \
+               int Y = ((CC + DD) >> 8) & 0x3ff; \
+               uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+               uint8 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
+               uint8 z = Mode7Depths [(b & PRIOMASK) >> 7]; \
+               if (z > *d && b) \
+               { \
+                       *p = (FUNC); \
+                       *d = z; \
+               } \
+       }
+
+#define RENDER_BACKGROUND_MODE7_PIXEL(FUNC,HFLIP,REPEAT,MASK,PRIOMASK,CFILT) \
+       register int AABB = AA + BB; \
+       register int CCDD = CC + DD; \
+       const uint8 bmask = MASK; \
+       for (int x = startx; x != endx; \
+               x += (HFLIP ? -1 : 1), AABB += aa, CCDD += cc, p++, d++) \
+       { \
+               register uint16 X = ((AABB) >> 8) CFILT; \
+               register uint16 Y = ((CCDD) >> 8) CFILT; \
+       \
+               if (((X | Y) & ~0x3ff) == 0) { \
+                       uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
+                       uint8 b = TileData[((Y & 7) << 4) + ((X & 7) << 1)]; \
+                       uint8 z = Mode7Depths [(b & PRIOMASK) >> 7]; \
+                       if (z > *d && b) { \
+                               *p = (FUNC); \
+                               *d = z; \
+                       } \
+               } else if (REPEAT == 3) { \
+                       X = (x + HOffset) & 7; \
+                       Y = (yy + CentreY) & 7; \
+                       uint8 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \
+                       uint8 z = Mode7Depths [(b & PRIOMASK) >> 7]; \
+                       if (z > *d && b) { \
+                               *p = (FUNC); \
+                               *d = z; \
+                       } \
+               } \
+       } \
+
+#define RENDER_BACKGROUND_MODE7_CLIP(TYPE,FUNC,HFLIP,REPEAT,DEZAEMON,MASK,PRIOMASK) \
        for (uint32 clip = 0; clip < ClipCount; clip++) \
        { \
            if (GFX.pCurrentClip->Count [bg]) \
@@ -2221,11 +2049,10 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
            register TYPE *p = (TYPE *) Screen + Left; \
            register uint8 *d = Depth + Left; \
 \
-           if (PPU.Mode7HFlip) \
+           if (HFLIP) \
            { \
                        startx = Right - 1; \
                        endx = Left - 1; \
-                       dir = -1; \
                        aa = -l->MatrixA; \
                        cc = -l->MatrixC; \
            } \
@@ -2233,130 +2060,170 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
            { \
                        startx = Left; \
                        endx = Right; \
-                       dir = 1; \
                        aa = l->MatrixA; \
                        cc = l->MatrixC; \
            } \
            int xx; \
-           if (PPU.Mode7Repeat == 0) \
+           if (!REPEAT) \
                        xx = startx + (HOffset - CentreX) % 1023; \
            else \
                        xx = startx + HOffset - CentreX; \
            int AA = l->MatrixA * xx; \
            int CC = l->MatrixC * xx; \
 \
-           if (!PPU.Mode7Repeat) \
+           if (!REPEAT) \
            { \
-               for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
-               { \
-                   int X = ((AA + BB) >> 8) & 0x3ff; \
-                   int Y = ((CC + DD) >> 8) & 0x3ff; \
-                   uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
-                   uint8 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
-                   GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
-                   if (GFX.Z1 > *d && b) \
-                   { \
-                               *p = (FUNC); \
-                               *d = GFX.Z1; \
-                   } \
-               } \
+                       RENDER_BACKGROUND_MODE7_PIXEL_NOREPEAT(FUNC,HFLIP,REPEAT,MASK,PRIOMASK) \
+           } else if (DEZAEMON) { \
+                       RENDER_BACKGROUND_MODE7_PIXEL(FUNC,HFLIP,REPEAT,MASK,PRIOMASK,& 0x7ff) \
+               } else { \
+                       RENDER_BACKGROUND_MODE7_PIXEL(FUNC,HFLIP,REPEAT,MASK,PRIOMASK,) \
            } \
-           else \
-           { \
-               for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \
-               { \
-                   int X = ((AA + BB) >> 8); \
-                   int Y = ((CC + DD) >> 8); \
+       } \
+
+#ifdef USE_CRAZY_OPTS
+
+#define RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,REPEAT,DEZAEMON) \
+       if (GFX.Mode7PriorityMask) { \
+               RENDER_BACKGROUND_MODE7_CLIP(TYPE,FUNC,HFLIP,REPEAT,DEZAEMON,0x7f,0x80) \
+       } else { \
+               RENDER_BACKGROUND_MODE7_CLIP(TYPE,FUNC,HFLIP,REPEAT,DEZAEMON,0xff,0x00) \
+       }
+
+#define RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_REPEAT_DEZAEMON(TYPE,FUNC,HFLIP) \
+       if (Settings.Dezaemon && PPU.Mode7Repeat) { \
+               switch (PPU.Mode7Repeat) { \
+                       case 1: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,1,1); break; \
+                       case 2: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,2,1); break; \
+                       case 3: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,3,1); break; \
+               } \
+       } else { \
+               switch (PPU.Mode7Repeat) { \
+                       case 0: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,0,0); break; \
+                       case 1: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,1,0); break; \
+                       case 2: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,2,0); break; \
+                       case 3: RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_MASK(TYPE,FUNC,HFLIP,3,0); break; \
+               } \
+       }
+
+#define RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_HFLIP(TYPE,FUNC) \
+       if (PPU.Mode7HFlip) { \
+               RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_REPEAT_DEZAEMON(TYPE,FUNC,1); \
+       } else { \
+               RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_REPEAT_DEZAEMON(TYPE,FUNC,0); \
+       }
+
+#define RENDER_BACKGROUND_MODE7_CLIP_CHOOSE(TYPE,FUNC) \
+       RENDER_BACKGROUND_MODE7_CLIP_CHOOSE_HFLIP(TYPE,FUNC)
+
+#else
+
+#define RENDER_BACKGROUND_MODE7_CLIP_CHOOSE(TYPE,FUNC) \
+       RENDER_BACKGROUND_MODE7_CLIP(TYPE,FUNC,PPU.Mode7HFlip,PPU.Mode7Repeat,Settings.Dezaemon,GFX.Mode7Mask,GFX.Mode7PriorityMask)
+
+#endif
+
+#define RENDER_BACKGROUND_MODE7_LINE(TYPE,FUNC) \
+       for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \
+    { \
+       int yy; \
 \
-                   if (Settings.Dezaemon && PPU.Mode7Repeat == 2) \
-                   { \
-                               X &= 0x7ff; \
-                               Y &= 0x7ff; \
-                   } \
+       int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \
+       int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \
 \
-                   if (((X | Y) & ~0x3ff) == 0) \
-                   { \
-                               uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \
-                               uint8 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \
-                               GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
-                               if (GFX.Z1 > *d && b) \
-                               { \
-                                       *p = (FUNC); \
-                                       *d = GFX.Z1; \
-                               } \
-                   } \
-                   else \
-                   { \
-                               if (PPU.Mode7Repeat == 3) \
-                               { \
-                                       X = (x + HOffset) & 7; \
-                                       Y = (yy + CentreY) & 7; \
-                                       uint8 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \
-                                       GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \
-                                       if (GFX.Z1 > *d && b) \
-                                       { \
-                                               *p = (FUNC); \
-                                               *d = GFX.Z1; \
-                                       } \
-                               } \
-                   } \
-               } \
-           } \
-       } \
+       int32 CentreX = ((int32) l->CentreX << M7) >> M7; \
+       int32 CentreY = ((int32) l->CentreY << M7) >> M7; \
+\
+       if (PPU.Mode7VFlip) \
+           yy = 261 - (int) Line; \
+       else \
+           yy = Line; \
+\
+       if (PPU.Mode7Repeat == 0) \
+           yy += (VOffset - CentreY) % 1023; \
+       else \
+           yy += VOffset - CentreY; \
+       int BB = l->MatrixB * yy + (CentreX << 8); \
+       int DD = l->MatrixD * yy + (CentreY << 8); \
+\
+       RENDER_BACKGROUND_MODE7_CLIP_CHOOSE(TYPE,FUNC) \
     }
 
-void DrawBGMode7Background (uint8 *Screen, int bg)
-{
-    RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask))
-}
+#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \
+    CHECK_SOUND(); \
+\
+    uint8 * const VRAM1 = Memory.VRAM + 1; \
+    if (GFX.r2130 & 1) \
+    { \
+               if (IPPU.DirectColourMapsNeedRebuild) \
+                       S9xBuildDirectColourMaps (); \
+               GFX.ScreenColors = DirectColourMaps [0]; \
+    } \
+    else \
+               GFX.ScreenColors = IPPU.ScreenColors; \
+\
+    int aa, cc; \
+    int startx, endx; \
+    uint32 Left = 0; \
+    uint32 Right = 256; \
+    uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \
+\
+    if (!ClipCount) \
+       ClipCount = 1; \
+\
+    Screen += GFX.StartY * GFX.Pitch; \
+    uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \
+    struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \
+    RENDER_BACKGROUND_MODE7_LINE(TYPE,FUNC) \
+\
 
-void DrawBGMode7Background16 (uint8 *Screen, int bg)
+static void DrawBGMode7Background16 (uint8 *Screen, int bg)
 {
-    RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & GFX.Mode7Mask]);
+    RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & bmask]);
 }
 
-void DrawBGMode7Background16Add (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Add (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
-                                           COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_ADD (GFX.ScreenColors [b & bmask],
                                                       p [GFX.Delta]) :
-                                           COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_ADD (GFX.ScreenColors [b & bmask],
                                                       GFX.FixedColour)) :
-                                        GFX.ScreenColors [b & GFX.Mode7Mask]);
+                                        GFX.ScreenColors [b & bmask]);
 }
 
-void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
-                                           COLOR_ADD1_2 (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_ADD1_2 (GFX.ScreenColors [b & bmask],
                                                       p [GFX.Delta]) :
-                                           COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_ADD (GFX.ScreenColors [b & bmask],
                                                       GFX.FixedColour)) :
-                                        GFX.ScreenColors [b & GFX.Mode7Mask]);
+                                        GFX.ScreenColors [b & bmask]);
 }
 
-void DrawBGMode7Background16Sub (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Sub (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
-                                           COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_SUB (GFX.ScreenColors [b & bmask],
                                                       p [GFX.Delta]) :
-                                           COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_SUB (GFX.ScreenColors [b & bmask],
                                                       GFX.FixedColour)) :
-                                        GFX.ScreenColors [b & GFX.Mode7Mask]);
+                                        GFX.ScreenColors [b & bmask]);
 }
 
-void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
-                                           COLOR_SUB1_2 (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_SUB1_2 (GFX.ScreenColors [b & bmask],
                                                       p [GFX.Delta]) :
-                                           COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask],
+                                           COLOR_SUB (GFX.ScreenColors [b & bmask],
                                                       GFX.FixedColour)) :
-                                        GFX.ScreenColors [b & GFX.Mode7Mask]);
+                                        GFX.ScreenColors [b & bmask]);
 }
 
 #define RENDER_BACKGROUND_MODE7_i(TYPE,FUNC,COLORFUNC) \
@@ -2385,12 +2252,12 @@ void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
     Screen += GFX.StartY * GFX.Pitch; \
     uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \
     struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \
-    bool8_32 allowSimpleCase = FALSE; \
+    bool allowSimpleCase = false; \
     if (!l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100) \
         && !LineMatrixData[GFX.EndY].MatrixB && !LineMatrixData[GFX.EndY].MatrixC \
         && (LineMatrixData[GFX.EndY].MatrixA == 0x0100) && (LineMatrixData[GFX.EndY].MatrixD == 0x0100) \
         ) \
-        allowSimpleCase = TRUE;  \
+        allowSimpleCase = true;  \
     \
     for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \
     { \
@@ -2411,7 +2278,7 @@ void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
            yy += (VOffset - CentreY) % 1023; \
        else \
            yy += VOffset - CentreY; \
-        bool8_32 simpleCase = FALSE; \
+        bool simpleCase = false; \
         int BB; \
         int DD; \
         /* Make a special case for the identity matrix, since it's a common case and */ \
@@ -2420,7 +2287,7 @@ void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
         { \
             BB = CentreX << 8; \
             DD = (yy + CentreY) << 8; \
-            simpleCase = TRUE; \
+            simpleCase = true; \
         } \
         else \
         { \
@@ -2735,7 +2602,7 @@ void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg)
         } \
     }
 
-STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
+static inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
 {
     register uint32 x = ((A >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) +
                             ((B >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) +
@@ -2749,12 +2616,12 @@ STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D)
     return x+y;
 }
 
-void DrawBGMode7Background16_i (uint8 *Screen, int bg)
+static void DrawBGMode7Background16_i (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7_i (uint16, theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
 }
 
-void DrawBGMode7Background16Add_i (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Add_i (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
@@ -2765,7 +2632,7 @@ void DrawBGMode7Background16Add_i (uint8 *Screen, int bg)
                                         theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
 }
 
-void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
@@ -2776,7 +2643,7 @@ void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg)
                                         theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
 }
 
-void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
@@ -2787,7 +2654,7 @@ void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg)
                                         theColor, (GFX.ScreenColors[b & GFX.Mode7Mask]));
 }
 
-void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg)
+static void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg)
 {
     RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ?
                                        (*(d + GFX.DepthDelta) != 1 ?
@@ -2832,13 +2699,9 @@ TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \
 HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \
                                 ~TWO_LOW_BITS_MASK ) >> 2);
 
-void RenderScreen (uint8 *Screen, bool8_32 sub, bool8_32 force_no_add, uint8 D)
+static void RenderScreen(uint8 *Screen, bool sub, bool force_no_add, uint8 D)
 {
-    bool8_32 BG0;
-    bool8_32 BG1;
-    bool8_32 BG2;
-    bool8_32 BG3;
-    bool8_32 OB;
+    bool BG0, BG1, BG2, BG3, OB;
 
     GFX.S = Screen;
 
@@ -2987,14 +2850,11 @@ void RenderScreen (uint8 *Screen, bool8_32 sub, bool8_32 force_no_add, uint8 D)
 
 #include "font.h"
 
-void DisplayChar (uint8 *Screen, uint8 c)
+static void DisplayChar(uint8 *Screen, uint8 c)
 {
     int line = (((c & 0x7f) - 32) >> 4) * font_height;
     int offset = (((c & 0x7f) - 32) & 15) * font_width;
-#ifndef _SNESPPC
-    if (Settings.SixteenBit)
-#endif
-    {
+
        int h, w;
        uint16 *s = (uint16 *) Screen;
        for (h = 0; h < font_height; h++, line++,
@@ -3011,56 +2871,36 @@ void DisplayChar (uint8 *Screen, uint8 c)
                    *s = BLACK;
            }
        }
-    }
-#ifndef _SNESPPC
-    else
-    {
-       int h, w;
-       uint8 *s = Screen;
-       for (h = 0; h < font_height; h++, line++,
-            s += GFX.PPL - font_width)
-       {
-           for (w = 0; w < font_width; w++, s++)
-           {
-               uint8 p = font [line][offset + w];
-
-               if (p == '#')
-                   *s = 255;
-               else
-               if (p == '.')
-                   *s = BLACK;
-           }
-       }
-    }
-#endif
 }
 
-static void S9xDisplayFrameRate ()
+static void S9xDisplayFrameRate()
 {
-    uint8 *Screen = GFX.Screen + 2 +
-                   (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch2;
-    char string [10];
-    int len = 5;
-
-    sprintf (string, "%02d/%02d", IPPU.DisplayedRenderedFrameCount,
-            (int) Memory.ROMFramesPerSecond);
+    const unsigned int char_width = (font_width - 1) * sizeof (uint16);
+       uint8 *Screen = GFX.Screen + 2 +
+               (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch;
+       char string[12];
+    int len;
+
+       if (Settings.TurboMode) {
+               len = sprintf(string, "%u",
+                       IPPU.DisplayedRenderedFrameCount);
+       } else {
+               len = sprintf(string, "%2u/%02u",
+                       IPPU.DisplayedRenderedFrameCount,
+                       (unsigned int) Memory.ROMFramesPerSecond);
+       }
 
-    int i;
-#ifdef _SNESPPC
-    Screen += (font_width - 1) * sizeof(uint16);
-#endif
-    for (i = 0; i < len; i++)
-    {
-       DisplayChar (Screen, string [i]);
-       Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) : 
-                 (font_width - 1);
-    }
+       for (int i = 0; i < len; i++) {
+               DisplayChar(Screen, string[i]);
+               Screen += char_width;
+       }
 }
 
-static void S9xDisplayString (const char *string)
+static void S9xDisplayString(const char *string)
 {
+    const unsigned int char_width = (font_width - 1) * sizeof (uint16);
     uint8 *Screen = GFX.Screen + 2 +
-                   (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch2;
+                   (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch;
     int len = strlen (string);
     int max_chars = IPPU.RenderedScreenWidth / (font_width - 1);
     int char_count = 0;
@@ -3070,9 +2910,7 @@ static void S9xDisplayString (const char *string)
     {
        if (char_count >= max_chars || string [i] < 32)
        {
-           Screen -= Settings.SixteenBit ? 
-                       (font_width - 1) * sizeof (uint16) * max_chars :
-                       (font_width - 1) * max_chars;
+           Screen -= char_width * max_chars;
            Screen += font_height * GFX.Pitch;
            if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight)
                break;
@@ -3081,8 +2919,7 @@ static void S9xDisplayString (const char *string)
        if (string [i] < 32)
            continue;
        DisplayChar (Screen, string [i]);
-       Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) : 
-                 (font_width - 1);
+       Screen += char_width;
     }
 }
 
@@ -3130,84 +2967,40 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
     uint32 endy = GFX.EndY;
 
 #ifndef RC_OPTIMIZED
-    if (Settings.SupportHiRes &&
-       (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.LatchedInterlace))
-    {
-               if (PPU.BGMode == 5 || PPU.BGMode == 6)
-               {
+       if (Settings.SupportHiRes &&
+         (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.LatchedInterlace)) {
+               if (PPU.BGMode == 5 || PPU.BGMode == 6) {
                    IPPU.RenderedScreenWidth = 512;
                    x2 = 2;
                }
-               if (IPPU.LatchedInterlace)
-               {
-                   starty = GFX.StartY * 2;
-                   endy = GFX.EndY * 2 + 1;
+
+               if (IPPU.LatchedInterlace) {
+                       starty = GFX.StartY * 2;
+                       endy = GFX.EndY * 2 + 1;
                }
-               if (!IPPU.DoubleWidthPixels)
-               {
-                   // The game has switched from lo-res to hi-res mode part way down
-                   // the screen. Scale any existing lo-res pixels on screen
-#ifndef _SNESPPC
-                       if (Settings.SixteenBit)
-#endif
-                   {
-#if defined (USE_GLIDE) || defined (USE_OPENGL)
-                   if (
-#ifdef USE_GLIDE
-                       (Settings.GlideEnable && GFX.Pitch == 512) ||
-#endif
-#ifdef USE_OPENGL
-                       (Settings.OpenGLEnable && GFX.Pitch == 512) ||
-#endif
-                           0)
-                               {
-                                   // Have to back out of the speed up hack where the low res.
-                                   // SNES image was rendered into a 256x239 sized buffer,
-                                   // ignoring the true, larger size of the buffer.
-                                   
-                                   for (register int32 y = (int32) GFX.StartY - 1; y >= 0; y--)
-                                   {
-                                               register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255;
-                                               register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.RealPitch) + 510;
-                                               for (register int x = 255; x >= 0; x--, p--, q -= 2)
-                                                       *q = *(q + 1) = *p;
-                                   }
-                                   GFX.Pitch = GFX.Pitch2 = GFX.RealPitch;
-                                   GFX.PPL = GFX.Pitch >> 1;
-                                   GFX.PPLx2 = GFX.Pitch;
-                                   GFX.ZPitch = GFX.PPL;
-                               }
-                               else
-#endif
-                                       for (register uint32 y = 0; y < GFX.StartY; y++)
-                                       {
-                                           register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255;
-                                           register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 510;
-                                           for (register int x = 255; x >= 0; x--, p--, q -= 2)
-                                               *q = *(q + 1) = *p;
-                                       }
-                   }
-#ifndef _SNESPPC
-                   else
-                   {
-                               for (register uint32 y = 0; y < GFX.StartY; y++)
-                               {
-                                       register uint8 *p = GFX.Screen + y * GFX.Pitch + 255;
-                                       register uint8 *q = GFX.Screen + y * GFX.Pitch + 510;
-                                       for (register int x = 255; x >= 0; x--, p--, q -= 2)
+
+               if (!IPPU.DoubleWidthPixels) {
+                       // The game has switched from lo-res to hi-res mode part way down
+                       // the screen. Scale any existing lo-res pixels on screen
+                       for (register uint32 y = 0; y < GFX.StartY; y++) {
+                               register uint16 *p =
+                                       (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255;
+                               register uint16 *q =
+                                       (uint16 *) (GFX.Screen + y * GFX.Pitch) + 510;
+                               for (register int x = 255; x >= 0; x--, p--, q -= 2) {
                                        *q = *(q + 1) = *p;
                                }
-                   }
-#endif
-                   IPPU.DoubleWidthPixels = TRUE;
+                       }
+
+                       IPPU.DoubleWidthPixels = TRUE;
                }
-    }
+       }
 #endif //RC_OPTIMIZED (DONT DO ABOVE)
 
     uint32 black = BLACK | (BLACK << 16);
 
        // Are we worrying about transparencies?
-    if (Settings.Transparency && Settings.SixteenBit)
+    if (Settings.Transparency)
     {
                if (GFX.Pseudo)
                {
@@ -3240,11 +3033,9 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                    {
 
                                // Colour window enabled.
-
 #ifdef RC_OPTIMIZED
                                for (uint32 y = starty; y <= endy; y++)
                                {
-
                        ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch,
                                                IPPU.RenderedScreenWidth);
                                        ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch,
@@ -3252,7 +3043,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
 
                        if (IPPU.Clip [0].Count [5])
                                        {
-                                               memset ((GFX.SubScreen + y * GFX.Pitch2), black, IPPU.RenderedScreenWidth);
+                                               memset ((GFX.SubScreen + y * GFX.Pitch), black, IPPU.RenderedScreenWidth);
                                        }
                                        for (uint32 c = 0; c < pClip->Count [5]; c++)
                                        {
@@ -3266,7 +3057,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                                        // because there is a colour window in effect clipping
                                                        // the main screen that will allow the sub-screen
                                                        // 'underneath' to show through.
-                                                       memset ((GFX.SubScreen + y * GFX.Pitch2) + pClip->Left [c][5] * x2,
+                                                       memset ((GFX.SubScreen + y * GFX.Pitch) + pClip->Left [c][5] * x2,
                                                                         GFX.FixedColour,
                                                                         pClip->Right[c][5]*x2 - pClip->Left [c][5] * x2);
                                                        }
@@ -3288,7 +3079,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                        // if there is clipping then clear subscreen to a black color
                                        if (IPPU.Clip [0].Count [5])
                                        {
-                                               memset32 ((uint32_t*)(GFX.SubScreen + y * GFX.Pitch2), black, IPPU.RenderedScreenWidth>>1);
+                                               memset32 ((uint32_t*)(GFX.SubScreen + y * GFX.Pitch), black, IPPU.RenderedScreenWidth>>1);
                                        }
 
                                        // loop through all window clippings
@@ -3305,7 +3096,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                                        // the main screen that will allow the sub-screen
                                                        // 'underneath' to show through.
 
-                                                       register uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2);
+                                                       register uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch);
                                                        register uint16 *q = p + pClip->Right [c][5] * x2;
                                                        p += pClip->Left [c][5] * x2;
 
@@ -3316,7 +3107,6 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                        }
                                }
 #endif
-//#undef RC_OPTIMIZED
 
                    }
                    else
@@ -3348,17 +3138,17 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                // because there is a colour window in effect clipping
                                // the main screen that will allow the sub-screen
                                // 'underneath' to show through.
-                               if (GFX.Pitch2 == (uint32)IPPU.RenderedScreenWidth)
+                               if (GFX.Pitch == (uint32)IPPU.RenderedScreenWidth)
                                {
-                                       memset ((GFX.SubScreen + starty * GFX.Pitch2), 
+                                       memset ((GFX.SubScreen + starty * GFX.Pitch), 
                                                        GFX.FixedColour | (GFX.FixedColour << 16),
-                                                       GFX.Pitch2 * (endy - starty - 1));
+                                                       GFX.Pitch * (endy - starty - 1));
                                }
                                else
                                {
                                        for (uint32 y = starty; y <= endy; y++)
                                        {
-                                               memset ((GFX.SubScreen + y * GFX.Pitch2), 
+                                               memset ((GFX.SubScreen + y * GFX.Pitch), 
                                                                GFX.FixedColour | (GFX.FixedColour << 16),
                                                                IPPU.RenderedScreenWidth);
                                        }
@@ -3383,7 +3173,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                // 'underneath' to show through.
 
 
-                               memset32 ((uint32_t*)(GFX.SubScreen + y * GFX.Pitch2), fixedColour,
+                               memset32 ((uint32_t*)(GFX.SubScreen + y * GFX.Pitch), fixedColour,
                                    IPPU.RenderedScreenWidth>>1);
                            }
                        }
@@ -3401,7 +3191,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                    {
                                        for (uint32 y = starty; y <= endy; y++)
                        {
-                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2);
+                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch);
                                        register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch ;
                                        register uint8 *e = d + SNES_WIDTH;
 
@@ -3452,7 +3242,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                    if (GFX.r2131 & 0x40)
                                    {
                                        // Subtract, halving the result.
-                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + Left;
                                        register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                        register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
                                        register uint8 *e = d + Right;
@@ -3481,7 +3271,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                    else
                                    {
                                        // Subtract
-                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + Left;
                                        register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
                                        register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                        register uint8 *e = d + Right;
@@ -3511,7 +3301,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                else
                                if (GFX.r2131 & 0x40)
                                {
-                                   register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+                                   register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + Left;
                                    register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                    register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
                                    register uint8 *e = d + Right;
@@ -3539,7 +3329,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                else
                                if (back != 0)
                                {
-                                   register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+                                   register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + Left;
                                    register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                    register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
                                    register uint8 *e = d + Right;
@@ -3572,7 +3362,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                        // copy the sub-screen to the main screen
                                        // or fill it with the back-drop colour if the
                                        // sub-screen is clear.
-                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + Left;
                                        register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                        register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left;
                                        register uint8 *e = d + Right;
@@ -3615,7 +3405,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                                {
                                                        uint32 Left = pClip->Left [b][5] * x2;
                                                        uint32 Right = pClip->Right [b][5] * x2;
-                                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left;
+                                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + Left;
                                                        register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                                        register uint8 *e = d + Right;
                                                        d += Left;
@@ -3633,7 +3423,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                {
                                        for (uint32 y = starty; y <= endy; y++)
                                        {
-                                               register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2);
+                                               register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch);
                                                register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch;
                                                register uint8 *e = d + 256 * x2;
 
@@ -3672,17 +3462,17 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                    {
 
 #ifdef RC_OPTIMIZED
-                               if (GFX.Pitch2 == (uint32)IPPU.RenderedScreenWidth)
+                               if (GFX.Pitch == (uint32)IPPU.RenderedScreenWidth)
                                {
-                                       memset (GFX.Screen + starty * GFX.Pitch2, black,
-                                                       GFX.Pitch2 * (endy - starty - 1));
+                                       memset (GFX.Screen + starty * GFX.Pitch, black,
+                                                       GFX.Pitch * (endy - starty - 1));
                                }
                                else
                                {
                                        for (uint32 y = starty; y <= endy; y++)
                                        {
-                                               memset (GFX.Screen + y * GFX.Pitch2, black,
-                                                               GFX.Pitch2);
+                                               memset (GFX.Screen + y * GFX.Pitch, black,
+                                                               GFX.Pitch);
                                        }
                                }
                                for (uint32 y = starty; y <= endy; y++)
@@ -3692,7 +3482,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                                if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5])
                                                {
 
-                                                       memset ((GFX.Screen + y * GFX.Pitch2) + IPPU.Clip [0].Left [c][5] * x2,
+                                                       memset ((GFX.Screen + y * GFX.Pitch) + IPPU.Clip [0].Left [c][5] * x2,
                                                                        back,
                                                                        IPPU.Clip [0].Right [c][5] * x2 - IPPU.Clip [0].Left [c][5] * x2);
                                                }
@@ -3702,7 +3492,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                // loop through all of the lines that are going to be updated as part of this screen update
                                for (uint32 y = starty; y <= endy; y++)
                                {
-                                       memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch2), black,
+                                       memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch), black,
                                                IPPU.RenderedScreenWidth>>1);
 
                                        if (black!=back)
@@ -3711,7 +3501,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                        {
                                                if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5])
                                                {
-                                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); // get pointer to current line in screen buffer
+                                                       register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch); // get pointer to current line in screen buffer
                                                        register uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2; // get pointer to end of line
                                                        p += IPPU.Clip [0].Left [c][5] * x2;
 
@@ -3726,24 +3516,24 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                    else
                    {
 #ifdef RC_OPTIMIZED
-                               if (GFX.Pitch2 == (uint32)IPPU.RenderedScreenWidth)
+                               if (GFX.Pitch == (uint32)IPPU.RenderedScreenWidth)
                                {
-                                       memset (GFX.Screen + starty * GFX.Pitch2, back,
-                                                       GFX.Pitch2 * (endy - starty - 1));
+                                       memset (GFX.Screen + starty * GFX.Pitch, back,
+                                                       GFX.Pitch * (endy - starty - 1));
                                }
                                else
                                {
                                        for (uint32 y = starty; y <= endy; y++)
                                        {
-                                               memset (GFX.Screen + y * GFX.Pitch2, back,
-                                                               GFX.Pitch2);
+                                               memset (GFX.Screen + y * GFX.Pitch, back,
+                                                               GFX.Pitch);
                                        }
                                }
 #else
                                // there is no clipping to worry about so just fill with the back colour
                                for (uint32 y = starty; y <= endy; y++)
                                {
-                                       memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch2), back,
+                                       memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch), back,
                                                IPPU.RenderedScreenWidth>>1);
                                }
 #endif
@@ -3781,57 +3571,39 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
     }
     else // Transparencys are disabled, ahh lovely ... nice and easy.
        {
-#ifndef _SNESPPC
-               if (Settings.SixteenBit)
-#endif
+           // get back colour to be used in clearing the screen
+               register uint32 back;
+               if (!(Memory.FillRAM [0x2131] & 0x80) &&(Memory.FillRAM[0x2131] & 0x20) &&
+                               (PPU.FixedColourRed || PPU.FixedColourGreen || PPU.FixedColourBlue))
                {
-                   // get back colour to be used in clearing the screen
-                       register uint32 back;
-                       if (!(Memory.FillRAM [0x2131] & 0x80) &&(Memory.FillRAM[0x2131] & 0x20) &&
-                                       (PPU.FixedColourRed || PPU.FixedColourGreen || PPU.FixedColourBlue))
-                       {
-                               back = (IPPU.XB[PPU.FixedColourRed]<<11) |
-                                          (IPPU.XB[PPU.FixedColourGreen] << 6) | 
-                                          (IPPU.XB[PPU.FixedColourBlue] << 1) | 1;
-                               back = (back << 16) | back;
-                       }
-                       else
-                       {
-                               back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16);
-                       }
-    
-                   // if Forcedblanking in use then back colour becomes black
-                       if (PPU.ForcedBlanking)
-                               back = black;
-                   else
-                       {
-                               SelectTileRenderer (TRUE);  //selects the tile renderers to be used
-                                                                                       // TRUE means to use the default
-                                                                                       // FALSE means use best renderer based on current
-                                                                                       // graphics register settings
-                       }
-                   
-                       // now clear all graphics lines which are being updated using the back colour
-                       for (register uint32 y = starty; y <= endy; y++)
-                   {
-                               memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch2), back,
-                                       IPPU.RenderedScreenWidth>>1);
-                   }
+                       back = (IPPU.XB[PPU.FixedColourRed]<<11) |
+                                  (IPPU.XB[PPU.FixedColourGreen] << 6) |
+                                  (IPPU.XB[PPU.FixedColourBlue] << 1) | 1;
+                       back = (back << 16) | back;
                }
-#ifndef _SNESPPC
-               else // Settings.SixteenBit == false
+               else
                {
-                   // because we are in 8 bit we can just use 0 to clear the screen
-                       // this means we can use the Zero Memory function
-                       
-                       // Loop through all lines being updated and clear the pixels to 0
-                       for (uint32 y = starty; y <= endy; y++)
-                   {
-                       ZeroMemory (GFX.Screen + y * GFX.Pitch2,
-                                   IPPU.RenderedScreenWidth);
-                   }
+                       back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16);
                }
-#endif
+
+               // if Forcedblanking in use then back colour becomes black
+               if (PPU.ForcedBlanking)
+                       back = black;
+               else
+               {
+                       SelectTileRenderer (TRUE);  //selects the tile renderers to be used
+                                                                               // TRUE means to use the default
+                                                                               // FALSE means use best renderer based on current
+                                                                               // graphics register settings
+               }
+
+               // now clear all graphics lines which are being updated using the back colour
+               for (register uint32 y = starty; y <= endy; y++)
+               {
+                       memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch), back,
+                               IPPU.RenderedScreenWidth>>1);
+               }
+
                if (!PPU.ForcedBlanking)
                {
                        // Loop through all lines being updated and clear the
@@ -3853,18 +3625,19 @@ else \
 
 // Define an inline function to handle which BGs are being displayed
 #define DISPLAY(n) \
-(!(PPU.BG_Forced & n) && \
-(GFX.r212c & n) || \
-((GFX.r212d & n) && subadd))
+       ( \
+               (!(PPU.BG_Forced & n) && (GFX.r212c & n)) || \
+               (((GFX.r212d & n) && subadd)) \
+       )
 
                    uint8 subadd = GFX.r2131 & 0x3f;
 
                        // go through all BGS are check if they need to be displayed
-                   bool8_32 BG0 = DISPLAY(1) && !(Settings.os9x_hack & GFX_IGNORE_BG0);
-                   bool8_32 BG1 = DISPLAY(2) && !(Settings.os9x_hack & GFX_IGNORE_BG1);
-                   bool8_32 BG2 = DISPLAY(4) && !(Settings.os9x_hack & GFX_IGNORE_BG2);
-                   bool8_32 BG3 = DISPLAY(8) && !(Settings.os9x_hack & GFX_IGNORE_BG3);
-                   bool8_32 OB  = DISPLAY(16) && !(Settings.os9x_hack & GFX_IGNORE_OBJ);
+                   bool BG0 = DISPLAY(1) && !(Settings.os9x_hack & GFX_IGNORE_BG0);
+                   bool BG1 = DISPLAY(2) && !(Settings.os9x_hack & GFX_IGNORE_BG1);
+                   bool BG2 = DISPLAY(4) && !(Settings.os9x_hack & GFX_IGNORE_BG2);
+                   bool BG3 = DISPLAY(8) && !(Settings.os9x_hack & GFX_IGNORE_BG3);
+                   bool OB  = DISPLAY(16) && !(Settings.os9x_hack & GFX_IGNORE_OBJ);
 
                    if (PPU.BGMode <= 1)
                    {
@@ -3944,12 +3717,6 @@ else \
                                        bg = 0;
                                    }
 
-#ifndef _SNESPPC
-                                   if (!Settings.SixteenBit)
-                                       DrawBGMode7Background (GFX.Screen, bg);
-                                   else
-#endif
-                                   {
                                        if (!Settings.Mode7Interpolate)
                                        {       
                                            DrawBGMode7Background16 (GFX.Screen, bg);
@@ -3958,7 +3725,6 @@ else \
                                        {       
                                            DrawBGMode7Background16_i (GFX.Screen, bg);
                                        }
-                                 }
                                }
                    }
                }
@@ -3970,10 +3736,6 @@ else \
        {
            // Mixure of background modes used on screen - scale width
            // of all non-mode 5 and 6 pixels.
-#ifndef _SNESPPC
-               if (Settings.SixteenBit)
-#endif
-           {
                for (register uint32 y = GFX.StartY; y <= GFX.EndY; y++)
                {
                    register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255;
@@ -3981,19 +3743,6 @@ else \
                    for (register int x = 255; x >= 0; x--, p--, q -= 2)
                        *q = *(q + 1) = *p;
                }
-           }
-#ifndef _SNESPPC
-           else
-           {
-               for (register uint32 y = GFX.StartY; y <= GFX.EndY; y++)
-               {
-                   register uint8 *p = GFX.Screen + y * GFX.Pitch + 255;
-                   register uint8 *q = GFX.Screen + y * GFX.Pitch + 510;
-                   for (register int x = 255; x >= 0; x--, p--, q -= 2)
-                       *q = *(q + 1) = *p;
-               }
-           }
-#endif
        }
 
        if (IPPU.LatchedInterlace)
@@ -4002,9 +3751,9 @@ else \
            // pixels.
            for (uint32 y = GFX.StartY; y <= GFX.EndY; y++)
            {
-               memcpy32 ((uint32_t*)(GFX.Screen + (y * 2 + 1) * GFX.Pitch2),
-                        (uint32_t*)(GFX.Screen + y * 2 * GFX.Pitch2),
-                        GFX.Pitch2>>2);
+               memcpy32 ((uint32_t*)(GFX.Screen + (y * 2 + 1) * GFX.Pitch),
+                        (uint32_t*)(GFX.Screen + y * 2 * GFX.Pitch),
+                        GFX.Pitch>>2);
            }
        }
     }
@@ -4036,7 +3785,7 @@ _BUILD_PIXEL(GBR565)
 _BUILD_PIXEL(GBR555)
 _BUILD_PIXEL(RGB5551)
 
-bool8_32 S9xSetRenderPixelFormat (int format)
+bool8 S9xSetRenderPixelFormat (int format)
 {
     extern uint32 current_graphic_format;
 
@@ -4070,4 +3819,6 @@ bool8_32 S9xSetRenderPixelFormat (int format)
     }
     return (FALSE);
 }
+
 #endif
+