Skip to content

Commit

Permalink
Render double-width-res tiles from Background Mode 5 as half-width ti…
Browse files Browse the repository at this point in the history
…les. 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...
  • Loading branch information
Nebuleon committed Jan 1, 2013
1 parent 73f8077 commit 3cd20e2
Show file tree
Hide file tree
Showing 4 changed files with 230 additions and 14 deletions.
138 changes: 124 additions & 14 deletions source/gfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -820,7 +857,6 @@ void S9xEndScreenRefresh ()
}
#endif


if (CPU.SRAMModified)
{
S9xAutoSaveSRAM ();
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -1254,6 +1299,69 @@ if(Settings.BGLayering) {
DrawTilePtr = DrawTile;
DrawClippedTilePtr = DrawClippedTile;
}
#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
}
}
Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions source/ppu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions source/ppu.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ struct InternalPPU {
bool8 Interlace;
bool8 InterlaceSprites;
bool8 DoubleWidthPixels;
bool8 HalfWidthPixels;
int RenderedScreenHeight;
int RenderedScreenWidth;
uint32 Red [256];
Expand Down
104 changes: 104 additions & 0 deletions source/tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down

0 comments on commit 3cd20e2

Please sign in to comment.