aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNebuleon Fumika2013-01-01 03:53:45 -0500
committerNebuleon Fumika2013-01-01 03:53:45 -0500
commit3cd20e203f3b0af8c32921f86547a126d74b34eb (patch)
treeed3ff1d5ba8cd5fd6762b9241c9285659cb8f540
parent73f8077a2af28a6f8b4d2ecafc7af3d06627e6fa (diff)
downloadsnes9x2005-3cd20e203f3b0af8c32921f86547a126d74b34eb.tar.gz
snes9x2005-3cd20e203f3b0af8c32921f86547a126d74b34eb.tar.bz2
snes9x2005-3cd20e203f3b0af8c32921f86547a126d74b34eb.zip
Render double-width-res tiles from Background Mode 5 as half-width tiles. This makes the menu text in Secret of Mana readable.
Sprites in Background Mode 5 are still messed up. At least they're at the right X coordinate, roughly...
-rw-r--r--source/gfx.cpp138
-rw-r--r--source/ppu.cpp1
-rw-r--r--source/ppu.h1
-rw-r--r--source/tile.cpp104
4 files changed, 230 insertions, 14 deletions
diff --git a/source/gfx.cpp b/source/gfx.cpp
index 611ec0a..59ff71a 100644
--- a/source/gfx.cpp
+++ b/source/gfx.cpp
@@ -173,6 +173,11 @@ void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine,
void DrawClippedTile (uint32 Tile, uint32 Offset,
uint32 StartPixel, uint32 Width,
uint32 StartLine, uint32 LineCount);
+void DrawTileHalfWidth (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTileHalfWidth (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine,
uint32 LineCount);
void DrawClippedTilex2 (uint32 Tile, uint32 Offset,
@@ -193,6 +198,11 @@ void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine,
void DrawClippedTile16 (uint32 Tile, uint32 Offset,
uint32 StartPixel, uint32 Width,
uint32 StartLine, uint32 LineCount);
+void DrawTile16HalfWidth (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount);
+void DrawClippedTile16HalfWidth (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount);
void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
uint32 LineCount);
void DrawClippedTile16x2 (uint32 Tile, uint32 Offset,
@@ -392,8 +402,16 @@ bool8 S9xGraphicsInit ()
DrawTilePtr = DrawTile16;
DrawClippedTilePtr = DrawClippedTile16;
DrawLargePixelPtr = DrawLargePixel16;
- DrawHiResTilePtr= DrawTile16;
- DrawHiResClippedTilePtr = DrawClippedTile16;
+ if (Settings.SupportHiRes)
+ {
+ DrawHiResTilePtr= DrawTile16;
+ DrawHiResClippedTilePtr = DrawClippedTile16;
+ }
+ else
+ {
+ DrawHiResTilePtr= DrawTile16HalfWidth;
+ DrawHiResClippedTilePtr = DrawClippedTile16HalfWidth;
+ }
GFX.PPL = GFX.Pitch >> 1;
GFX.PPLx2 = GFX.Pitch;
#ifndef FOREVER_16_BIT
@@ -403,8 +421,16 @@ bool8 S9xGraphicsInit ()
DrawTilePtr = DrawTile;
DrawClippedTilePtr = DrawClippedTile;
DrawLargePixelPtr = DrawLargePixel;
- DrawHiResTilePtr = DrawTile;
- DrawHiResClippedTilePtr = DrawClippedTile;
+ if (Settings.SupportHiRes)
+ {
+ DrawHiResTilePtr= DrawTile;
+ DrawHiResClippedTilePtr = DrawClippedTile;
+ }
+ else
+ {
+ DrawHiResTilePtr= DrawTileHalfWidth;
+ DrawHiResClippedTilePtr = DrawClippedTileHalfWidth;
+ }
GFX.PPL = GFX.Pitch;
GFX.PPLx2 = GFX.Pitch * 2;
}
@@ -635,11 +661,13 @@ void S9xStartScreenRefresh ()
{
IPPU.RenderedScreenWidth = 512;
IPPU.DoubleWidthPixels = TRUE;
+ IPPU.HalfWidthPixels = FALSE;
}
else
{
IPPU.RenderedScreenWidth = 256;
IPPU.DoubleWidthPixels = FALSE;
+ IPPU.HalfWidthPixels = FALSE;
}
if (IPPU.Interlace)
@@ -673,11 +701,20 @@ void S9xStartScreenRefresh ()
GFX.PPLx2 = GFX.PPL << 1;
}
}
+ else if (!Settings.SupportHiRes && (PPU.BGMode == 5))
+ {
+ // Secret of Mana displays menus with mode 5.
+ // Make them readable.
+ IPPU.DoubleWidthPixels = FALSE;
+ IPPU.HalfWidthPixels = TRUE;
+ IPPU.DoubleHeightPixels = FALSE;
+ }
else
{
IPPU.RenderedScreenWidth = 256;
IPPU.RenderedScreenHeight = PPU.ScreenHeight;
IPPU.DoubleWidthPixels = FALSE;
+ IPPU.HalfWidthPixels = FALSE;
IPPU.DoubleHeightPixels = FALSE;
{
GFX.Pitch2 = GFX.Pitch = GFX.RealPitch;
@@ -820,7 +857,6 @@ void S9xEndScreenRefresh ()
}
#endif
-
if (CPU.SRAMModified)
{
S9xAutoSaveSRAM ();
@@ -852,9 +888,18 @@ inline void SelectTileRenderer (bool8 normal)
{
if (normal)
{
- DrawTilePtr = DrawTile16;
- DrawClippedTilePtr = DrawClippedTile16;
- DrawLargePixelPtr = DrawLargePixel16;
+ if (IPPU.HalfWidthPixels)
+ {
+ DrawTilePtr = DrawTile16HalfWidth;
+ DrawClippedTilePtr = DrawClippedTile16HalfWidth;
+ DrawLargePixelPtr = DrawLargePixel16;
+ }
+ else
+ {
+ DrawTilePtr = DrawTile16;
+ DrawClippedTilePtr = DrawClippedTile16;
+ DrawLargePixelPtr = DrawLargePixel16;
+ }
}
else
{
@@ -1257,6 +1302,69 @@ if(Settings.BGLayering) {
#endif
}
}
+ else if (!Settings.SupportHiRes)
+ {
+ if (PPU.BGMode == 5)
+ {
+ // Bah, OnMain is never used except to determine if calling
+ // SelectTileRenderer is necessary. So let's hack it to false here
+ // to stop SelectTileRenderer from being called when it causes
+ // problems.
+ OnMain = FALSE;
+ GFX.PixSize = 1; // half width - maybe? [Neb]
+ if (IPPU.HalfWidthPixels)
+ {
+#ifndef FOREVER_16_BIT
+ if (Settings.SixteenBit)
+ {
+#endif
+ DrawTilePtr = DrawTile16HalfWidth;
+ DrawClippedTilePtr = DrawClippedTile16HalfWidth;
+#ifndef FOREVER_16_BIT
+ }
+ else
+ {
+ DrawTilePtr = DrawTileHalfWidth;
+ DrawClippedTilePtr = DrawClippedTileHalfWidth;
+ }
+#endif
+ }
+ else
+ {
+#ifndef FOREVER_16_BIT
+ if (Settings.SixteenBit)
+ {
+#endif
+ DrawTilePtr = DrawTile16;
+ DrawClippedTilePtr = DrawClippedTile16;
+#ifndef FOREVER_16_BIT
+ }
+ else
+ {
+ DrawTilePtr = DrawTile;
+ DrawClippedTilePtr = DrawClippedTile;
+ }
+#endif
+ }
+ }
+ else
+ {
+#ifndef FOREVER_16_BIT
+ if (Settings.SixteenBit)
+ {
+#endif
+ DrawTilePtr = DrawTile16;
+ DrawClippedTilePtr = DrawClippedTile16;
+#ifndef FOREVER_16_BIT
+ }
+ else
+ {
+ DrawTilePtr = DrawTile;
+ DrawClippedTilePtr = DrawClippedTile;
+ }
+#endif
+ }
+ }
GFX.Z1 = D + 2;
for(uint32 Y=GFX.StartY, Offset=Y*GFX.PPL; Y<=GFX.EndY; Y++, Offset+=GFX.PPL){
@@ -2066,7 +2174,7 @@ static void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8
Count = 8 - Offset;
if (Count > Width)
Count = Width;
- s -= Offset;
+ s -= Offset >> 1;
Tile = READ_2BYTES (t);
GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
@@ -2123,14 +2231,14 @@ static void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8
else if (Quot == 127)
t = b1;
Quot++;
- s += 8;
+ s += (IPPU.HalfWidthPixels ? 4 : 8);
}
// Middle, unclipped tiles
Count = Width - Count;
int Middle = Count >> 3;
Count &= 7;
- for (int C = Middle; C > 0; s += 8, Quot++, C--)
+ for (int C = Middle; C > 0; s += (IPPU.HalfWidthPixels ? 4 : 8), Quot++, C--)
{
Tile = READ_2BYTES(t);
GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13];
@@ -2279,11 +2387,13 @@ static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2)
case 5:
case 6: // XXX: is also offset per tile.
- if (Settings.SupportHiRes)
- {
+// if (Settings.SupportHiRes)
+// {
+ if (!Settings.SupportHiRes)
+ SelectTileRenderer(TRUE /* normal */);
DrawBackgroundMode5 (BGMode, bg, Z1, Z2);
return;
- }
+// }
break;
}
CHECK_SOUND();
diff --git a/source/ppu.cpp b/source/ppu.cpp
index 44dbece..91e16a0 100644
--- a/source/ppu.cpp
+++ b/source/ppu.cpp
@@ -2615,6 +2615,7 @@ static void CommonPPUReset ()
IPPU.Interlace = FALSE;
IPPU.InterlaceSprites = FALSE;
IPPU.DoubleWidthPixels = FALSE;
+ IPPU.HalfWidthPixels = FALSE;
IPPU.DoubleHeightPixels = FALSE;
IPPU.RenderedScreenWidth = SNES_WIDTH;
IPPU.RenderedScreenHeight = SNES_HEIGHT;
diff --git a/source/ppu.h b/source/ppu.h
index 065ad5f..f55421a 100644
--- a/source/ppu.h
+++ b/source/ppu.h
@@ -140,6 +140,7 @@ struct InternalPPU {
bool8 Interlace;
bool8 InterlaceSprites;
bool8 DoubleWidthPixels;
+ bool8 HalfWidthPixels;
int RenderedScreenHeight;
int RenderedScreenWidth;
uint32 Red [256];
diff --git a/source/tile.cpp b/source/tile.cpp
index 008ef33..4fb9de0 100644
--- a/source/tile.cpp
+++ b/source/tile.cpp
@@ -249,6 +249,37 @@ static void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels, uint16 *ScreenC
}
}
}
+static void WRITE_4PIXELS_HALFWIDTH (uint32 Offset, uint8 *Pixels, uint16 *ScreenColors)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+ for (uint8 N = 0; N < 4; N += 2)
+ {
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N]))
+ {
+ Screen [N >> 1] = (uint8) ScreenColors [Pixel];
+ Depth [N >> 1] = GFX.Z2;
+ }
+ }
+}
+
+static void WRITE_4PIXELS_FLIPPED_HALFWIDTH (uint32 Offset, uint8 *Pixels, uint16 *ScreenColors)
+{
+ uint8 Pixel;
+ uint8 *Screen = GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+ for (uint8 N = 0; N < 4; N += 2)
+ {
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[2 - N]))
+ {
+ Screen [N >> 1] = (uint8) ScreenColors [Pixel];
+ Depth [N >> 1] = GFX.Z2;
+ }
+ }
+}
static void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels, uint16 *ScreenColors)
{
@@ -335,6 +366,27 @@ void DrawClippedTile (uint32 Tile, uint32 Offset,
RENDER_CLIPPED_TILE(WRITE_4PIXELS, WRITE_4PIXELS_FLIPPED, 4)
}
+void DrawTileHalfWidth (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS_HALFWIDTH, WRITE_4PIXELS_FLIPPED_HALFWIDTH, 2)
+}
+
+void DrawClippedTileHalfWidth (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS_HALFWIDTH, WRITE_4PIXELS_FLIPPED_HALFWIDTH, 2)
+}
+
void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine,
uint32 LineCount)
{
@@ -423,6 +475,38 @@ static void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels, uint16 *Scree
}
}
+static void WRITE_4PIXELS16_HALFWIDTH (uint32 Offset, uint8 *Pixels, uint16 *ScreenColors)
+{
+ uint8 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+ for (uint8 N = 0; N < 4; N += 2)
+ {
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N]))
+ {
+ Screen [N >> 1] = ScreenColors [Pixel];
+ Depth [N >> 1] = GFX.Z2;
+ }
+ }
+}
+
+static void WRITE_4PIXELS16_FLIPPED_HALFWIDTH (uint32 Offset, uint8 *Pixels, uint16 *ScreenColors)
+{
+ uint8 Pixel;
+ uint16 *Screen = (uint16 *) GFX.S + Offset;
+ uint8 *Depth = GFX.DB + Offset;
+
+ for (uint8 N = 0; N < 4; N += 2)
+ {
+ if (GFX.Z1 > Depth [N] && (Pixel = Pixels[2 - N]))
+ {
+ Screen [N >> 1] = ScreenColors [Pixel];
+ Depth [N >> 1] = GFX.Z2;
+ }
+ }
+}
+
static void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels, uint16 *ScreenColors)
{
uint8 Pixel;
@@ -570,6 +654,26 @@ void DrawClippedTile16 (uint32 Tile, uint32 Offset,
RENDER_CLIPPED_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4)
}
+void DrawTile16HalfWidth (uint32 Tile, uint32 Offset, uint32 StartLine,
+ uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ RENDER_TILE(WRITE_4PIXELS16_HALFWIDTH, WRITE_4PIXELS16_FLIPPED_HALFWIDTH, 2)
+}
+
+void DrawClippedTile16HalfWidth (uint32 Tile, uint32 Offset,
+ uint32 StartPixel, uint32 Width,
+ uint32 StartLine, uint32 LineCount)
+{
+ TILE_PREAMBLE
+ register uint8 *bp;
+
+ TILE_CLIP_PREAMBLE
+ RENDER_CLIPPED_TILE(WRITE_4PIXELS16_HALFWIDTH, WRITE_4PIXELS16_FLIPPED_HALFWIDTH, 2)
+}
+
void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine,
uint32 LineCount)
{