Added czech translation by fri
[drnoksnes] / gfx.cpp
diff --git a/gfx.cpp b/gfx.cpp
index 61d1e38..3a92def 100644 (file)
--- a/gfx.cpp
+++ b/gfx.cpp
@@ -38,6 +38,9 @@
  * 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 "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,109 +107,6 @@ 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 ()
 {
     register uint32 PixelOdd = 1;
@@ -227,7 +119,7 @@ bool8_32 S9xGraphicsInit ()
 
     for (uint8 bitshift = 0; bitshift < 4; bitshift++)
     {
-       for (register char i = 0; i < 16; i++)
+       for (register int i = 0; i < 16; i++)
        {
            register uint32 h = 0;
            register uint32 l = 0;
@@ -315,43 +207,29 @@ 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)
-    {
-       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 ();
+       IPPU.DirectColourMapsNeedRebuild = TRUE;
+       if (Settings.SixteenBit) {
+               DrawTilePtr = DrawTile16;
+               DrawClippedTilePtr = DrawClippedTile16;
+               DrawLargePixelPtr = DrawLargePixel16;
+               DrawHiResTilePtr= DrawHiResTile16;
+               DrawHiResClippedTilePtr = DrawHiResClippedTile16;
+       } else {
+               DrawTilePtr = DrawTile;
+               DrawClippedTilePtr = DrawClippedTile;
+               DrawLargePixelPtr = DrawLargePixel;
+               DrawHiResTilePtr = DrawTile;
+               DrawHiResClippedTilePtr = DrawClippedTile;
+       }
+    S9xFixColourBrightness();
 
     if (Settings.SixteenBit)
     {
@@ -547,42 +425,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 +499,51 @@ void RenderLine (uint8 C)
 
 void S9xEndScreenRefresh()
 {
-    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.HDMAStarted = FALSE;
+
+       if (IPPU.RenderThisFrame) {
+               FLUSH_REDRAW ();
+
+               IPPU.RenderedFramesCount++;
+
+               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 ();
 
-           PPU.CGDATA[0] = saved;
-       }
-            GFX.Pitch = GFX.Pitch2 = GFX.RealPitch;
-            GFX.PPL = GFX.PPLx2 >> 1;
+                       IPPU.ColorsChanged = FALSE;
+                   S9xSetPalette();
+                       PPU.CGDATA[0] = saved;
+               }
+
+               if (Settings.DisplayFrameRate) {
+                       S9xDisplayFrameRate();
+               }
 
-       if (Settings.DisplayFrameRate)
-           S9xDisplayFrameRate ();
-       if (GFX.InfoString)
-           S9xDisplayString (GFX.InfoString);
+               if (GFX.InfoString) {
+                       S9xDisplayString(GFX.InfoString);
+               }
 
-       S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight,
-                        Settings.SixteenBit);
+               S9xDeinitUpdate(
+                       IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight,
+                       Settings.SixteenBit);
     }
+
 #ifndef RC_OPTIMIZED
-    S9xApplyCheats ();
+       S9xApplyCheats ();
 #endif
 
-
 #ifdef DEBUGGER
     if (CPU.Flags & FRAME_ADVANCE_FLAG)
     {
@@ -695,7 +561,6 @@ void S9xEndScreenRefresh()
     }
 #endif
 
-/* 
     if (CPU.SRAMModified)
     {
                if (!CPU.AutoSaveTimer)
@@ -712,13 +577,21 @@ 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)
@@ -865,8 +738,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;
@@ -955,26 +826,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)
                    {
@@ -985,15 +856,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);
                    }
                }
            }
@@ -1100,9 +971,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;
@@ -1141,13 +1012,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
@@ -1157,13 +1028,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);
                            }
                        }
                    }
@@ -1177,13 +1048,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
@@ -1193,20 +1064,20 @@ 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);
            }
        }
     }
@@ -1339,7 +1210,7 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
            uint32 TotalCount = 0;
            uint32 MaxCount = 8;
 
-           uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
+           uint32 s = Left * GFX_PIX_SIZE + Y * GFX.PPL;
            bool8_32 left_hand_edge = (Left == 0);
            Width = Right - Left;
 
@@ -1446,19 +1317,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)
@@ -1467,26 +1338,26 @@ 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;
            }
        }
@@ -1497,9 +1368,6 @@ 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;
@@ -1606,8 +1474,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;
+           uint32 s = (Left>>1) * GFX_PIX_SIZE + Y * GFX.PPL;
+           uint32 HPos = (HOffset + Left * GFX_PIX_SIZE) & 0x3ff;
 
            uint32 Quot = HPos >> 3;
            uint32 Count = 0;
@@ -1626,7 +1494,8 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
                Count = 8 - Offset;
                if (Count > Width)
                    Count = Width;
-               s -= (Offset>>1);
+               if (s) // XXX: Workaround for underflow (Secret of MANA)
+                       s -= (Offset>>1);
                Tile = READ_2BYTES (t);
                GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
 
@@ -1636,13 +1505,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
@@ -1651,7 +1520,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)
@@ -1660,20 +1529,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);
                    }
                }
 
@@ -1700,13 +1569,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
@@ -1715,7 +1584,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)
@@ -1724,20 +1593,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);
                    }
                }
 
@@ -1760,13 +1629,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
@@ -1775,7 +1644,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)
@@ -1784,20 +1653,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);
                    }
                }
            }
@@ -1807,8 +1676,6 @@ void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2)
 
 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];
@@ -1955,7 +1822,7 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                            continue;
                    }
 
-                   uint32 s = Left * GFX.PixSize + Y * GFX.PPL;
+                   uint32 s = Left * GFX_PIX_SIZE + Y * GFX.PPL;
                    uint32 HPos = (HOffset + Left) & OffsetMask;
 
                    uint32 Quot = HPos >> 3;
@@ -1985,14 +1852,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
                        {
@@ -2000,7 +1867,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)
@@ -2009,20 +1876,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);
                            }
                        }
 
@@ -2043,14 +1910,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];
@@ -2064,13 +1931,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
@@ -2080,19 +1947,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)
@@ -2122,14 +1989,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)
@@ -2139,14 +2006,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
@@ -2154,7 +2021,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);
                            }
                        }
                    }
@@ -2162,55 +2029,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; \
-       int BB = l->MatrixB * yy + (CentreX << 8); \
-       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]) \
@@ -2220,14 +2086,13 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                        if (Right <= Left) \
                                continue; \
            } \
-           TYPE *p = (TYPE *) Screen + Left; \
-           uint8 *d = Depth + Left; \
+           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; \
            } \
@@ -2235,130 +2100,176 @@ 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); \
-                   uint32 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); \
-                               uint32 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; \
-                                       uint32 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) \
     }
 
+#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 DrawBGMode7Background (uint8 *Screen, int bg)
 {
-    RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask))
+    RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & bmask))
 }
 
 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)
 {
     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)
 {
     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)
 {
     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)
 {
     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) \
@@ -2989,7 +2900,7 @@ 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;
@@ -3037,32 +2948,35 @@ void DisplayChar (uint8 *Screen, uint8 c)
 #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);
+       uint8 *Screen = GFX.Screen + 2 +
+               (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch;
+       char string[12];
+    int len;
+    const unsigned int char_width = Settings.SixteenBit ? 
+                               (font_width - 1) * sizeof (uint16) : 
+                               (font_width - 1);
+
+       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)
 {
     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;
@@ -3132,78 +3046,46 @@ 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;
+
+               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
+                       if (Settings.SixteenBit) {
+                               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;
+                                       }
                                }
-                               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)
+                   } 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) {
                                                *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)
-                                       *q = *(q + 1) = *p;
                                }
                    }
-#endif
-                   IPPU.DoubleWidthPixels = TRUE;
+
+                       IPPU.DoubleWidthPixels = TRUE;
                }
-    }
+       }
 #endif //RC_OPTIMIZED (DONT DO ABOVE)
 
     uint32 black = BLACK | (BLACK << 16);
@@ -3242,11 +3124,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,
@@ -3254,7 +3134,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++)
                                        {
@@ -3268,7 +3148,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);
                                                        }
@@ -3290,7 +3170,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
@@ -3307,7 +3187,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;
 
@@ -3318,7 +3198,6 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                        }
                                }
 #endif
-//#undef RC_OPTIMIZED
 
                    }
                    else
@@ -3350,17 +3229,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);
                                        }
@@ -3385,7 +3264,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);
                            }
                        }
@@ -3403,7 +3282,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;
 
@@ -3454,7 +3333,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;
@@ -3483,7 +3362,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;
@@ -3513,7 +3392,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;
@@ -3541,7 +3420,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;
@@ -3574,7 +3453,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;
@@ -3617,7 +3496,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;
@@ -3635,7 +3514,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;
 
@@ -3674,17 +3553,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++)
@@ -3694,7 +3573,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);
                                                }
@@ -3704,7 +3583,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)
@@ -3713,7 +3592,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;
 
@@ -3728,24 +3607,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
@@ -3816,7 +3695,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                        // 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,
+                               memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch), back,
                                        IPPU.RenderedScreenWidth>>1);
                    }
                }
@@ -3829,7 +3708,7 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                        // 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,
+                       ZeroMemory (GFX.Screen + y * GFX.Pitch,
                                    IPPU.RenderedScreenWidth);
                    }
                }
@@ -3855,18 +3734,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)
                    {
@@ -4004,9 +3884,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);
            }
        }
     }
@@ -4072,4 +3952,6 @@ bool8_32 S9xSetRenderPixelFormat (int format)
     }
     return (FALSE);
 }
+
 #endif
+