added configure script
[drnoksnes] / gfx.cpp
diff --git a/gfx.cpp b/gfx.cpp
index 85334ef..ce2421b 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
@@ -112,109 +105,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;
@@ -315,14 +205,8 @@ 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;
@@ -549,8 +433,10 @@ void S9xBuildDirectColourMaps ()
 
 void S9xStartScreenRefresh ()
 {
-    if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0)
-       GFX.InfoString = NULL;
+       if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) {
+               free(GFX.InfoString);
+               GFX.InfoString = NULL;
+       }
 
     if (IPPU.RenderThisFrame)
     {
@@ -571,9 +457,6 @@ void S9xStartScreenRefresh ()
        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;
@@ -713,10 +596,19 @@ 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)
@@ -962,7 +854,7 @@ void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
                            if (W > Width)
                                W = Width;
                            (*DrawClippedTilePtr) (Tile, O, Offset, W,
-                                                  TileLine, LineCount, &GFX);
+                                                  TileLine, LineCount);
                            
                            if (W >= Width)
                                continue;
@@ -986,12 +878,12 @@ void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0)
                    for (int X = 0; X < Middle; X++, O += 8 * GFX.PixSize,
                         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);
                    }
                }
            }
@@ -1139,13 +1031,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 +1047,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 +1067,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,20 +1083,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);
            }
        }
     }
@@ -1449,14 +1341,14 @@ void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                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,20 +1357,20 @@ 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);
                    }
                }
 
@@ -1624,7 +1516,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];
 
@@ -1634,13 +1527,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 +1542,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 +1551,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 +1591,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 +1606,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 +1615,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 +1651,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 +1666,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 +1675,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);
                    }
                }
            }
@@ -1990,7 +1883,7 @@ void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
                        if (BG.TileSize == 8)
                        {
                            (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign,
-                                                  Lines, &GFX);
+                                                  Lines);
                        }
                        else
                        {
@@ -1998,7 +1891,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 +1900,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);
                            }
                        }
 
@@ -2062,13 +1955,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 +1971,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 +2013,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 +2030,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 +2045,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 +2053,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 +2113,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 +2124,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); \
-                   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) \
     }
 
+#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) \
@@ -3172,10 +3109,6 @@ void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW())
                                                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
@@ -4070,4 +4003,6 @@ bool8_32 S9xSetRenderPixelFormat (int format)
     }
     return (FALSE);
 }
+
 #endif
+