From a6dc7abc9b8cc3986eda5a84141da7dc9e4e8f1a Mon Sep 17 00:00:00 2001 From: aliaspider Date: Wed, 29 Oct 2014 05:36:07 +0100 Subject: start moving everything to C --- source/gfx.cpp | 3933 -------------------------------------------------------- 1 file changed, 3933 deletions(-) delete mode 100644 source/gfx.cpp (limited to 'source/gfx.cpp') diff --git a/source/gfx.cpp b/source/gfx.cpp deleted file mode 100644 index 34fb235..0000000 --- a/source/gfx.cpp +++ /dev/null @@ -1,3933 +0,0 @@ -/******************************************************************************* - Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - - (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and - Jerremy Koot (jkoot@snes9x.com) - - (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) - - (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), - funkyass (funkyass@spam.shaw.ca), - Joel Yliluoma (http://iki.fi/bisqwit/) - Kris Bleakley (codeviolation@hotmail.com), - Matthew Kendora, - Nach (n-a-c-h@users.sourceforge.net), - Peter Bortas (peter@bortas.org) and - zones (kasumitokoduck@yahoo.com) - - C4 x86 assembler and some C emulation code - (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), - _Demo_ (_demo_@zsnes.com), and Nach - - C4 C++ code - (c) Copyright 2003 Brad Jorsch - - DSP-1 emulator code - (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, - John Weidman, neviksti (neviksti@hotmail.com), - Kris Bleakley, Andreas Naive - - DSP-2 emulator code - (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and - Lord Nightmare (lord_nightmare@users.sourceforge.net - - OBC1 emulator code - (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and - Kris Bleakley - Ported from x86 assembler to C by sanmaiwashi - - SPC7110 and RTC C++ emulator code - (c) Copyright 2002 Matthew Kendora with research by - zsKnight, John Weidman, and Dark Force - - S-DD1 C emulator code - (c) Copyright 2003 Brad Jorsch with research by - Andreas Naive and John Weidman - - S-RTC C emulator code - (c) Copyright 2001 John Weidman - - ST010 C++ emulator code - (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora - - Super FX x86 assembler emulator code - (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault - - Super FX C emulator code - (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman - - - SH assembler code partly based on x86 assembler code - (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) - - - Specific ports contains the works of other authors. See headers in - individual files. - - Snes9x homepage: http://www.snes9x.com - - Permission to use, copy, modify and distribute Snes9x in both binary and - source form, for non-commercial purposes, is hereby granted without fee, - providing that this license information and copyright notice appear with - all copies and any derived work. - - This software is provided 'as-is', without any express or implied - warranty. In no event shall the authors be held liable for any damages - arising from the use of this software. - - Snes9x is freeware for PERSONAL USE only. Commercial users should - seek permission of the copyright holders first. Commercial use includes - charging money for Snes9x or software derived from Snes9x. - - The copyright holders request that bug fixes and improvements to the code - should be forwarded to them so everyone can benefit from the modifications - in future versions. - - Super NES and Super Nintendo Entertainment System are trademarks of - Nintendo Co., Limited and its subsidiary companies. -*******************************************************************************/ - -#include "snes9x.h" - -#include "memmap.h" -#include "ppu.h" -#include "cpuexec.h" -#include "display.h" -#include "gfx.h" -#include "apu.h" -#include "cheats.h" -#include "screenshot.h" - -#define M7 19 -#define M8 19 - -void output_png(); -void ComputeClipWindows (); -static void S9xDisplayFrameRate (); -static void S9xDisplayString (const char *string); - -extern uint8 BitShifts[8][4]; -extern uint8 TileShifts[8][4]; -extern uint8 PaletteShifts[8][4]; -extern uint8 PaletteMasks[8][4]; -extern uint8 Depths[8][4]; -extern uint8 BGSizes [2]; - -extern NormalTileRenderer DrawTilePtr; -extern ClippedTileRenderer DrawClippedTilePtr; -extern NormalTileRenderer DrawHiResTilePtr; -extern ClippedTileRenderer DrawHiResClippedTilePtr; -extern LargePixelRenderer DrawLargePixelPtr; - -extern struct SBG BG; - -extern struct SLineData LineData[240]; -extern struct SLineMatrixData LineMatrixData [240]; - -extern uint8 Mode7Depths [2]; - -#define CLIP_10_BIT_SIGNED(a) \ - ((a) & ((1 << 10) - 1)) + (((((a) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3) - -#define ON_MAIN(N) \ -(GFX.r212c & (1 << (N)) && \ - !(PPU.BG_Forced & (1 << (N)))) - -#define SUB_OR_ADD(N) \ -(GFX.r2131 & (1 << (N))) - -#define ON_SUB(N) \ -((GFX.r2130 & 0x30) != 0x30 && \ - (GFX.r2130 & 2) && \ - (GFX.r212d & (1 << N)) && \ - !(PPU.BG_Forced & (1 << (N)))) - -#define ANYTHING_ON_SUB \ -((GFX.r2130 & 0x30) != 0x30 && \ - (GFX.r2130 & 2) && \ - (GFX.r212d & 0x1f)) - -#define ADD_OR_SUB_ON_ANYTHING \ -(GFX.r2131 & 0x3f) - -#define FIX_INTERLACE(SCREEN, DO_DEPTH, DEPTH) \ - if (IPPU.DoubleHeightPixels && ((PPU.BGMode != 5 && PPU.BGMode != 6) || !IPPU.Interlace)) \ - for (uint32 y = GFX.StartY; y <= GFX.EndY; y++) \ - { \ - /* memmove converted: Same malloc, non-overlapping addresses [Neb] */ \ - memcpy (SCREEN + (y * 2 + 1) * GFX.Pitch2, \ - SCREEN + y * 2 * GFX.Pitch2, \ - GFX.Pitch2); \ - if(DO_DEPTH){ \ - /* memmove required: Same malloc, potentially overlapping addresses [Neb] */ \ - memmove (DEPTH + (y * 2 + 1) * (GFX.PPLx2>>1), \ - DEPTH + y * GFX.PPL, \ - GFX.PPLx2>>1); \ - } \ - } - - -#define BLACK BUILD_PIXEL(0,0,0) - -void DrawTile16 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawTile16HalfWidth (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16HalfWidth (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawTile16x2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16x2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawTile16x2x2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); -void DrawClippedTile16x2x2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); -void DrawLargePixel16 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); -void DrawLargePixel16HalfWidth (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Add (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Add (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Add1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Add1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16FixedAdd1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16FixedAdd1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Sub (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Sub (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16Sub1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16Sub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawTile16FixedSub1_2 (uint32 Tile, int32 Offset, uint32 StartLine, - uint32 LineCount); - -void DrawClippedTile16FixedSub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Width, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Add (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Add1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Sub (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -void DrawLargePixel16Sub1_2 (uint32 Tile, int32 Offset, - uint32 StartPixel, uint32 Pixels, - uint32 StartLine, uint32 LineCount); - -bool8 S9xGraphicsInit () -{ - register uint32 PixelOdd = 1; - register uint32 PixelEven = 2; - - for (uint8 bitshift = 0; bitshift < 4; bitshift++) - { - for (register int i = 0; i < 16; i++) - { - register uint32 h = 0; - register uint32 l = 0; - -#if defined(LSB_FIRST) - if (i & 8) - h |= PixelOdd; - if (i & 4) - h |= PixelOdd << 8; - if (i & 2) - h |= PixelOdd << 16; - if (i & 1) - h |= PixelOdd << 24; - if (i & 8) - l |= PixelOdd; - if (i & 4) - l |= PixelOdd << 8; - if (i & 2) - l |= PixelOdd << 16; - if (i & 1) - l |= PixelOdd << 24; -#else - if (i & 8) - h |= (PixelOdd << 24); - if (i & 4) - h |= (PixelOdd << 16); - if (i & 2) - h |= (PixelOdd << 8); - if (i & 1) - h |= PixelOdd; - if (i & 8) - l |= (PixelOdd << 24); - if (i & 4) - l |= (PixelOdd << 16); - if (i & 2) - l |= (PixelOdd << 8); - if (i & 1) - l |= PixelOdd; -#endif - - odd_high[bitshift][i] = h; - odd_low[bitshift][i] = l; - h = l = 0; - -#if defined(LSB_FIRST) - if (i & 8) - h |= PixelEven; - if (i & 4) - h |= PixelEven << 8; - if (i & 2) - h |= PixelEven << 16; - if (i & 1) - h |= PixelEven << 24; - if (i & 8) - l |= PixelEven; - if (i & 4) - l |= PixelEven << 8; - if (i & 2) - l |= PixelEven << 16; - if (i & 1) - l |= PixelEven << 24; -#else - if (i & 8) - h |= (PixelEven << 24); - if (i & 4) - h |= (PixelEven << 16); - if (i & 2) - h |= (PixelEven << 8); - if (i & 1) - h |= PixelEven; - if (i & 8) - l |= (PixelEven << 24); - if (i & 4) - l |= (PixelEven << 16); - if (i & 2) - l |= (PixelEven << 8); - if (i & 1) - l |= PixelEven; -#endif - - even_high[bitshift][i] = h; - even_low[bitshift][i] = l; - } - PixelEven <<= 2; - PixelOdd <<= 2; - } - - GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; - GFX.ZPitch = GFX.Pitch; - GFX.ZPitch >>= 1; - GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; - GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; - //GFX.InfoStringTimeout = 0; - //GFX.InfoString = NULL; - - PPU.BG_Forced = 0; - IPPU.OBJChanged = TRUE; - - IPPU.DirectColourMapsNeedRebuild = TRUE; - GFX.PixSize = 1; - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - DrawLargePixelPtr = DrawLargePixel16; - if (Settings.SupportHiRes) - { - DrawHiResTilePtr= DrawTile16; - DrawHiResClippedTilePtr = DrawClippedTile16; - } - else - { - DrawHiResTilePtr= DrawTile16HalfWidth; - DrawHiResClippedTilePtr = DrawClippedTile16HalfWidth; - } - GFX.PPL = GFX.Pitch >> 1; - GFX.PPLx2 = GFX.Pitch; - S9xFixColourBrightness (); - - if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000))) - return (FALSE); - - if (!(GFX.ZERO_OR_X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000)) || - !(GFX.ZERO = (uint16 *) malloc (sizeof (uint16) * 0x10000))) - { - if (GFX.ZERO_OR_X2) - { - free ((char *) GFX.ZERO_OR_X2); - GFX.ZERO_OR_X2 = NULL; - } - if (GFX.X2) - { - free ((char *) GFX.X2); - GFX.X2 = NULL; - } - return (FALSE); - } - uint32 r, g, b; - - // Build a lookup table that multiplies a packed RGB value by 2 with - // saturation. - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r << 1; - if (r2 > MAX_RED) - r2 = MAX_RED; - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g << 1; - if (g2 > MAX_GREEN) - g2 = MAX_GREEN; - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b << 1; - if (b2 > MAX_BLUE) - b2 = MAX_BLUE; - GFX.X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } - ZeroMemory (GFX.ZERO, 0x10000 * sizeof (uint16)); - ZeroMemory (GFX.ZERO_OR_X2, 0x10000 * sizeof (uint16)); - // Build a lookup table that if the top bit of the color value is zero - // then the value is zero, otherwise multiply the value by 2. Used by - // the color subtraction code. - -#if defined(OLD_COLOUR_BLENDING) - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r; - if ((r2 & 0x10) == 0) - r2 = 0; - else - r2 = (r2 << 1) & MAX_RED; - - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g; - if ((g2 & GREEN_HI_BIT) == 0) - g2 = 0; - else - g2 = (g2 << 1) & MAX_GREEN; - - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b; - if ((b2 & 0x10) == 0) - b2 = 0; - else - b2 = (b2 << 1) & MAX_BLUE; - - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } -#else - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r; - if ((r2 & 0x10) == 0) - r2 = 0; - else - r2 = (r2 << 1) & MAX_RED; - - if (r2 == 0) - r2 = 1; - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g; - if ((g2 & GREEN_HI_BIT) == 0) - g2 = 0; - else - g2 = (g2 << 1) & MAX_GREEN; - - if (g2 == 0) - g2 = 1; - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b; - if ((b2 & 0x10) == 0) - b2 = 0; - else - b2 = (b2 << 1) & MAX_BLUE; - - if (b2 == 0) - b2 = 1; - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } -#endif - - // Build a lookup table that if the top bit of the color value is zero - // then the value is zero, otherwise its just the value. - for (r = 0; r <= MAX_RED; r++) - { - uint32 r2 = r; - if ((r2 & 0x10) == 0) - r2 = 0; - else - r2 &= ~0x10; - - for (g = 0; g <= MAX_GREEN; g++) - { - uint32 g2 = g; - if ((g2 & GREEN_HI_BIT) == 0) - g2 = 0; - else - g2 &= ~GREEN_HI_BIT; - for (b = 0; b <= MAX_BLUE; b++) - { - uint32 b2 = b; - if ((b2 & 0x10) == 0) - b2 = 0; - else - b2 &= ~0x10; - - GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); - GFX.ZERO [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); - } - } - } - return (TRUE); -} - -void S9xGraphicsDeinit (void) -{ - // Free any memory allocated in S9xGraphicsInit - if (GFX.X2) - { - free ((char *) GFX.X2); - GFX.X2 = NULL; - } - if (GFX.ZERO_OR_X2) - { - free ((char *) GFX.ZERO_OR_X2); - GFX.ZERO_OR_X2 = NULL; - } - if (GFX.ZERO) - { - free ((char *) GFX.ZERO); - GFX.ZERO = NULL; - } -} - -void S9xBuildDirectColourMaps () -{ - for (uint32 p = 0; p < 8; p++) - { - for (uint32 c = 0; c < 256; c++) - { -// XXX: Brightness - DirectColourMaps [p][c] = BUILD_PIXEL (((c & 7) << 2) | ((p & 1) << 1), - ((c & 0x38) >> 1) | (p & 2), - ((c & 0xc0) >> 3) | (p & 4)); - } - } - IPPU.DirectColourMapsNeedRebuild = FALSE; -} - -void S9xStartScreenRefresh () -{ - if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) - GFX.InfoString = NULL; - - if (IPPU.RenderThisFrame) - { - if (!S9xInitUpdate ()) - { - IPPU.RenderThisFrame = FALSE; - return; - } - - IPPU.RenderedFramesCount++; - IPPU.PreviousLine = IPPU.CurrentLine = 0; - IPPU.MaxBrightness = PPU.Brightness; - IPPU.LatchedBlanking = PPU.ForcedBlanking; - - if(PPU.BGMode == 5 || PPU.BGMode == 6) - IPPU.Interlace = (Memory.FillRAM[0x2133] & 1); - if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace)) - { - IPPU.RenderedScreenWidth = 512; - IPPU.DoubleWidthPixels = TRUE; - IPPU.HalfWidthPixels = FALSE; - - if (IPPU.Interlace) - { - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - IPPU.DoubleHeightPixels = TRUE; - GFX.Pitch2 = GFX.RealPitch; - GFX.Pitch = GFX.RealPitch * 2; - GFX.PPL = GFX.PPLx2 = GFX.RealPitch; - } - else - { - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; - IPPU.DoubleHeightPixels = FALSE; - GFX.PPL = GFX.Pitch >> 1; - GFX.PPLx2 = GFX.PPL << 1; - } - } - else if (!Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace)) - { - IPPU.RenderedScreenWidth = 256; - IPPU.DoubleWidthPixels = FALSE; - // Secret of Mana displays menus with mode 5. - // Make them readable. - IPPU.HalfWidthPixels = TRUE; - } - else - { - IPPU.RenderedScreenWidth = 256; - IPPU.RenderedScreenHeight = PPU.ScreenHeight; - IPPU.DoubleWidthPixels = FALSE; - IPPU.HalfWidthPixels = FALSE; - IPPU.DoubleHeightPixels = FALSE; - { - GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; - GFX.PPL = GFX.PPLx2 >> 1; - GFX.ZPitch = GFX.RealPitch; - 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; - } -} - -void RenderLine (uint8 C) -{ - if (IPPU.RenderThisFrame) - { - LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1; - LineData[C].BG[0].HOffset = PPU.BG[0].HOffset; - LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1; - LineData[C].BG[1].HOffset = PPU.BG[1].HOffset; - - if (PPU.BGMode == 7) - { - struct SLineMatrixData *p = &LineMatrixData [C]; - p->MatrixA = PPU.MatrixA; - p->MatrixB = PPU.MatrixB; - p->MatrixC = PPU.MatrixC; - p->MatrixD = PPU.MatrixD; - p->CentreX = PPU.CentreX; - p->CentreY = PPU.CentreY; - } - else - { - if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 && - PPU.BG[2].HOffset == 0xe000) - { - LineData[C].BG[2].VOffset = 0xe1; - LineData[C].BG[2].HOffset = 0; - } - else - { - LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1; - LineData[C].BG[2].HOffset = PPU.BG[2].HOffset; - LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1; - LineData[C].BG[3].HOffset = PPU.BG[3].HOffset; - } - } - IPPU.CurrentLine = C + 1; - } else { - /* if we're not rendering this frame, we still need to update this */ - // XXX: Check ForceBlank? Or anything else? - if(IPPU.OBJChanged) S9xSetupOBJ(); - PPU.RangeTimeOver |= GFX.OBJLines[C].RTOFlags; - } -} - -void S9xEndScreenRefresh () -{ - IPPU.HDMAStarted = FALSE; - if (IPPU.RenderThisFrame) - { - FLUSH_REDRAW (); - if (IPPU.ColorsChanged) - { - uint32 saved = PPU.CGDATA[0]; - IPPU.ColorsChanged = FALSE; - PPU.CGDATA[0] = saved; - } - - GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; - GFX.PPL = GFX.PPLx2 >> 1; - S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight); - } - - S9xApplyCheats (); - - if (CPU.SRAMModified) - { - S9xAutoSaveSRAM (); - CPU.SRAMModified = FALSE; - } - -} - -void S9xSetInfoString (const char *string) -{ - GFX.InfoString = string; - GFX.InfoStringTimeout = 120; -} - -inline void SelectTileRenderer (bool8 normal) -{ - if (normal) - { - if (IPPU.HalfWidthPixels) - { - DrawTilePtr = DrawTile16HalfWidth; - DrawClippedTilePtr = DrawClippedTile16HalfWidth; - DrawLargePixelPtr = DrawLargePixel16HalfWidth; - } - else - { - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - DrawLargePixelPtr = DrawLargePixel16; - } - } - else - { - switch (GFX.r2131 & 0xC0) - { - case 0x00: - DrawTilePtr = DrawTile16Add; - DrawClippedTilePtr = DrawClippedTile16Add; - DrawLargePixelPtr = DrawLargePixel16Add; - break; - case 0x40: - if (GFX.r2130 & 2) - { - DrawTilePtr = DrawTile16Add1_2; - DrawClippedTilePtr = DrawClippedTile16Add1_2; - } - else - { - // Fixed colour addition - DrawTilePtr = DrawTile16FixedAdd1_2; - DrawClippedTilePtr = DrawClippedTile16FixedAdd1_2; - } - DrawLargePixelPtr = DrawLargePixel16Add1_2; - break; - case 0x80: - DrawTilePtr = DrawTile16Sub; - DrawClippedTilePtr = DrawClippedTile16Sub; - DrawLargePixelPtr = DrawLargePixel16Sub; - break; - case 0xC0: - if (GFX.r2130 & 2) - { - DrawTilePtr = DrawTile16Sub1_2; - DrawClippedTilePtr = DrawClippedTile16Sub1_2; - } - else - { - // Fixed colour substraction - DrawTilePtr = DrawTile16FixedSub1_2; - DrawClippedTilePtr = DrawClippedTile16FixedSub1_2; - } - DrawLargePixelPtr = DrawLargePixel16Sub1_2; - break; - } - } -} - -void S9xSetupOBJ () -{ -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Entering SetupOBJS()\n"); -#endif - int SmallWidth, SmallHeight; - int LargeWidth, LargeHeight; - - switch (PPU.OBJSizeSelect) - { - case 0: - SmallWidth = SmallHeight = 8; - LargeWidth = LargeHeight = 16; - break; - case 1: - SmallWidth = SmallHeight = 8; - LargeWidth = LargeHeight = 32; - break; - case 2: - SmallWidth = SmallHeight = 8; - LargeWidth = LargeHeight = 64; - break; - case 3: - SmallWidth = SmallHeight = 16; - LargeWidth = LargeHeight = 32; - break; - case 4: - SmallWidth = SmallHeight = 16; - LargeWidth = LargeHeight = 64; - break; - default: - case 5: - SmallWidth = SmallHeight = 32; - LargeWidth = LargeHeight = 64; - break; - case 6: - SmallWidth = 16; SmallHeight = 32; - LargeWidth = 32; LargeHeight = 64; - break; - case 7: - SmallWidth = 16; SmallHeight = 32; - LargeWidth = LargeHeight = 32; - break; - } - if(IPPU.InterlaceSprites) - { - SmallHeight>>=1; LargeHeight>>=1; - } -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Sizes are %dx%d and %dx%d\n", SmallWidth, SmallHeight, LargeWidth, LargeHeight); -#endif - - /* OK, we have three cases here. Either there's no priority, priority is - * normal FirstSprite, or priority is FirstSprite+Y. The first two are - * easy, the last is somewhat more ... interesting. So we split them up. */ - - int Height; - uint8 S; - -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Priority rotation=%d, OAMAddr=%d -> ", PPU.OAMPriorityRotation, PPU.OAMAddr*2 | (PPU.OAMFlip&1)); -#endif - if(!PPU.OAMPriorityRotation || !(PPU.OAMFlip&PPU.OAMAddr&1)){ -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "normal FirstSprite = %02x\n", PPU.FirstSprite); -#endif - /* normal case */ - uint8 LineOBJ[SNES_HEIGHT_EXTENDED]; - memset(LineOBJ, 0, sizeof(LineOBJ)); - for(int i=0; i-GFX.OBJWidths[S] && HPos<=256) - { - if(HPos<0){ - GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3; - } else if(HPos+GFX.OBJWidths[S]>=257){ - GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3; - } else { - GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3; - } - for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line=SNES_HEIGHT_EXTENDED) continue; - if(LineOBJ[Y]>=32){ - GFX.OBJLines[Y].RTOFlags|=0x40; -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); -#endif - continue; - } - GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S]; - if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80; - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite=S; - if(PPU.OBJ[S].VFlip){ - // Yes, Width not Height. It so happens that the - // sprites with H=2*W flip as two WxW sprites. - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line^(GFX.OBJWidths[S]-1); - } else { - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Line=line; - } - LineOBJ[Y]++; - } - } - S=(S+1)&0x7F; - } while(S!=FirstSprite); - - for (int Y = 0; Y < SNES_HEIGHT_EXTENDED; Y++) { - if (LineOBJ[Y] < 32) // Add the sentinel - GFX.OBJLines[Y].OBJ[LineOBJ[Y]].Sprite = -1; - } - for(int Y=1; Y-GFX.OBJWidths[S] && HPos<=256) - { - if(HPos<0){ - GFX.OBJVisibleTiles[S]=(GFX.OBJWidths[S]+HPos+7)>>3; - } else if(HPos+GFX.OBJWidths[S]>=257){ - GFX.OBJVisibleTiles[S]=(257-HPos+7)>>3; - } else { - GFX.OBJVisibleTiles[S]=GFX.OBJWidths[S]>>3; - } - for(uint8 line=0, Y=(uint8)(PPU.OBJ[S].VPos&0xff); line=SNES_HEIGHT_EXTENDED) continue; - if (!AnyOBJOnLine[Y]) { - memset(OBJOnLine[Y], 0, 128); - AnyOBJOnLine[Y] = TRUE; - } - if(PPU.OBJ[S].VFlip){ - // Yes, Width not Height. It so happens that the - // sprites with H=2*W flip as two WxW sprites. - OBJOnLine[Y][S]=(line^(GFX.OBJWidths[S]-1)) | 0x80; - } else { - OBJOnLine[Y][S]=line | 0x80; - } - } - } - } - - /* Now go through and pull out those OBJ that are actually visible. */ - int j; - for(int Y=0; Y=32){ - GFX.OBJLines[Y].RTOFlags|=0x40; - #ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "%d: OBJ %02x ranged over\n", Y, S); - #endif - break; - } - GFX.OBJLines[Y].Tiles-=GFX.OBJVisibleTiles[S]; - if(GFX.OBJLines[Y].Tiles<0) GFX.OBJLines[Y].RTOFlags|=0x80; - GFX.OBJLines[Y].OBJ[j].Sprite=S; - GFX.OBJLines[Y].OBJ[j++].Line=OBJOnLine[Y][S]&~0x80; - } - S=(S+1)&0x7F; - } while(S!=FirstSprite); - } - if(j<32) GFX.OBJLines[Y].OBJ[j].Sprite=-1; - } - } - -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) { - fprintf(stderr, "Sprites per line:\n"); - for(int xxx=0; xxx=0; j++){ - fprintf(stderr, " %02x.%d", GFX.OBJLines[xxx].OBJ[j].Sprite, GFX.OBJLines[xxx].OBJ[j].Line); - } - fprintf(stderr, "\n"); - } - - fprintf(stderr, "Exiting SetupObj()\n"); - } -#endif - - IPPU.OBJChanged = FALSE; -} - -static void DrawOBJS (bool8 OnMain = FALSE, uint8 D = 0) -{ -#ifdef ACCUMULATE_JOYPAD -/* - * This call allows NDSSFC to synchronise the DS controller more often. - * If porting a later version of Snes9x into NDSSFC, it is essential to - * preserve it. - */ - NDSSFCAccumulateJoypad (); -#endif -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Entering DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY); -#endif - CHECK_SOUND(); - - BG.BitShift = 4; - BG.TileShift = 5; - BG.TileAddress = PPU.OBJNameBase; - BG.StartPalette = 128; - BG.PaletteShift = 4; - BG.PaletteMask = 7; - BG.Buffer = IPPU.TileCache [TILE_4BIT]; - BG.Buffered = IPPU.TileCached [TILE_4BIT]; - BG.NameSelect = PPU.OBJNameSelect; - BG.DirectColourMode = FALSE; - - GFX.PixSize = 1; - - struct { - uint16 Pos; - bool8 Value; - } Windows[7]; - int clipcount = GFX.pCurrentClip->Count [4]; - if (!clipcount){ - Windows[0].Pos=0; - Windows[0].Value=TRUE; - Windows[1].Pos=256; - Windows[1].Value=FALSE; - Windows[2].Pos=1000; - Windows[2].Value=FALSE; - } else { - Windows[0].Pos=1000; - Windows[0].Value=FALSE; - for(int clip=0, i=1; clipRight[clip][4]<=GFX.pCurrentClip->Left[clip][4]) continue; - int j; - for(j=0; jLeft[clip][4]; j++); - if(jLeft[clip][4]){ - Windows[j].Value = TRUE; - } else { - // memmove required: Overlapping addresses [Neb] - if(jLeft[clip][4]; - Windows[j].Value = TRUE; - i++; - } - for(j=0; jRight[clip][4]; j++); - if(j>=i || Windows[j].Pos!=GFX.pCurrentClip->Right[clip][4]){ - // memmove required: Overlapping addresses [Neb] - if(jRight[clip][4]; - Windows[j].Value = FALSE; - i++; - } - } - } - -#ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - fprintf(stderr, "Windows:\n"); - for(int xxx=0; xxx<6; xxx++){ fprintf(stderr, "%d: %d = %d\n", xxx, Windows[xxx].Pos, Windows[xxx].Value); } -} -#endif - - if (Settings.SupportHiRes) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6) - { - // 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 = 2; - if (IPPU.DoubleHeightPixels) - { - DrawTilePtr = DrawTile16x2x2; - DrawClippedTilePtr = DrawClippedTile16x2x2; - } - else - { - DrawTilePtr = DrawTile16x2; - DrawClippedTilePtr = DrawClippedTile16x2; - } - } - else - { - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - } - } - else // if (!Settings.SupportHiRes) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6) - { - // 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; - } - DrawTilePtr = DrawTile16; - DrawClippedTilePtr = DrawClippedTile16; - } - GFX.Z1 = D + 2; - - for(uint32 Y=GFX.StartY, Offset=Y*GFX.PPL; Y<=GFX.EndY; Y++, Offset+=GFX.PPL){ -#ifdef MK_DEBUG_RTO - bool8 Flag=0; -#endif - int I = 0; -#ifdef MK_DISABLE_TIME_OVER - int tiles=0; -#else - int tiles=GFX.OBJLines[Y].Tiles; -#endif - for (int S = GFX.OBJLines[Y].OBJ[I].Sprite; S >= 0 && I<32; S = GFX.OBJLines[Y].OBJ[++I].Sprite) - { - tiles+=GFX.OBJVisibleTiles[S]; - if(tiles<=0){ -#ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); } - fprintf(stderr, " [%02x]", S); -} -#endif - continue; - } - -#ifdef MK_DEBUG_RTO -if(Settings.BGLayering) { - if(!Flag){ Flag=1; fprintf(stderr, "Line %d:", Y); } - fprintf(stderr, " %02x", S); -} -#endif - - if (OnMain && SUB_OR_ADD(4)) - { - SelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4); - } - - int BaseTile = (((GFX.OBJLines[Y].OBJ[I].Line<<1) + (PPU.OBJ[S].Name&0xf0))&0xf0) | (PPU.OBJ[S].Name&0x100) | (PPU.OBJ[S].Palette << 10); - int TileX = PPU.OBJ[S].Name&0x0f; - int TileLine = (GFX.OBJLines[Y].OBJ[I].Line&7)*8; - int TileInc = 1; - - if (PPU.OBJ[S].HFlip) - { - TileX = (TileX + (GFX.OBJWidths[S] >> 3) - 1) & 0x0f; - BaseTile |= H_FLIP; - TileInc = -1; - } - - GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; - - bool8 WinStat=TRUE; - int WinIdx=0, NextPos=-1000; - int X=PPU.OBJ[S].HPos; if(X==-256) X=256; - for(int t=tiles, O=Offset+X*GFX.PixSize; X<=256 && X=NextPos){ - for(; WinIdx<7 && Windows[WinIdx].Pos<=X; WinIdx++); - if(WinIdx==0) WinStat=FALSE; - else WinStat=Windows[WinIdx-1].Value; - NextPos=(WinIdx<7)?Windows[WinIdx].Pos:1000; - } - - if(X+8X+8) NextPos=X+8; - } - } - } - } -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) if(Flag) fprintf(stderr, "\n"); -#endif - } -#ifdef MK_DEBUG_RTO - if(Settings.BGLayering) fprintf(stderr, "Exiting DrawOBJS() for %d-%d\n", GFX.StartY, GFX.EndY); -#endif -} - -static void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) -{ - CHECK_SOUND(); - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint8 depths [2] = {Z1, Z2}; - - if (BGMode == 0) - BG.StartPalette = bg << 5; - else - BG.StartPalette = 0; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if (PPU.BG[bg].SCSize & 1) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if(((uint8*)SC1-Memory.VRAM)>=0x10000) - SC1-=0x08000; - - - if (PPU.BG[bg].SCSize & 2) - SC2 = SC1 + 1024; - else - SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - - if (PPU.BG[bg].SCSize & 1) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - uint32 Lines; - uint32 OffsetMask; - uint32 OffsetShift; - - if (BG.TileSize == 16) - { - OffsetMask = 0x3ff; - OffsetShift = 4; - } - else - { - OffsetMask = 0x1ff; - OffsetShift = 3; - } - - int m5 = (BGMode == 5 || BGMode == 6) ? 1 : 0; - - for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) - { - uint32 VOffset = LineData [Y].BG[bg].VOffset; - uint32 HOffset = LineData [Y].BG[bg].HOffset; - uint32 MosaicOffset = Y % PPU.Mosaic; - - for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++) - if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || - (HOffset != LineData [Y + Lines].BG[bg].HOffset)) - break; - - uint32 MosaicLine = VOffset + Y - MosaicOffset; - - if (Y + Lines > GFX.EndY) - Lines = GFX.EndY + 1 - Y; - uint32 VirtAlign = (MosaicLine & 7) << 3; - - uint16 *b1; - uint16 *b2; - - uint32 ScreenLine = MosaicLine >> OffsetShift; - uint32 Rem16 = MosaicLine & 15; - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - uint16 *t; - uint32 Left = 0; - uint32 Right = 256 << m5; - - HOffset <<= m5; - - uint32 ClipCount = GFX.pCurrentClip->Count [bg]; - uint32 HPos = HOffset; - uint32 PixWidth = (PPU.Mosaic << m5); - - - if (!ClipCount) - ClipCount = 1; - - for (uint32 clip = 0; clip < ClipCount; clip++) - { - if (GFX.pCurrentClip->Count [bg]) - { - Left = GFX.pCurrentClip->Left [clip][bg] << m5; - Right = GFX.pCurrentClip->Right [clip][bg] << m5; - - uint32 r = Left % (PPU.Mosaic << m5); - HPos = HOffset + Left; - PixWidth = (PPU.Mosaic << m5) - r; - } - uint32 s = Y * GFX.PPL + Left * GFX.PixSize; - for (uint32 x = Left; x < Right; x += PixWidth, - s += (IPPU.HalfWidthPixels ? PixWidth >> 1 : PixWidth) * GFX.PixSize, - HPos += PixWidth, PixWidth = (PPU.Mosaic << m5)) - { - uint32 Quot = (HPos & OffsetMask) >> 3; - - if (x + PixWidth >= Right) - PixWidth = Right - x; - - if (BG.TileSize == 8 && !m5) - { - if (Quot > 31) - t = b2 + (Quot & 0x1f); - else - t = b1 + Quot; - } - else - { - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - } - - Tile = READ_2BYTES (t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - // Draw tile... - if (BG.TileSize != 8) - { - if (Tile & H_FLIP) - { - // Horizontal flip, but what about vertical flip ? - if (Tile & V_FLIP) - { - // Both horzontal & vertical flip - if (Rem16 < 8) - { - (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - else - { - // Horizontal flip only - if (Rem16 > 7) - { - (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - } - else - { - // No horizontal flip, but is there a vertical flip ? - if (Tile & V_FLIP) - { - // Vertical flip only - if (Rem16 < 8) - { - (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - else - { - // Normal unflipped - if (Rem16 > 7) - { - (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - else - { - (*DrawLargePixelPtr) (Tile + (Quot & 1), s, - HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - } - } - else - (*DrawLargePixelPtr) (Tile + (Quot & 1) * m5, s, HPos & 7, PixWidth, - VirtAlign, Lines); - } - } - } -} - -static void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) -{ - CHECK_SOUND(); - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint16 *BPS0; - uint16 *BPS1; - uint16 *BPS2; - uint16 *BPS3; - uint32 Width; - int VOffsetOffset = BGMode == 4 ? 0 : 32; - uint8 depths [2] = {Z1, Z2}; - - BG.StartPalette = 0; - - BPS0 = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1]; - - if (PPU.BG[2].SCSize & 1) - BPS1 = BPS0 + 1024; - else - BPS1 = BPS0; - - if (PPU.BG[2].SCSize & 2) - BPS2 = BPS1 + 1024; - else - BPS2 = BPS0; - - if (PPU.BG[2].SCSize & 1) - BPS3 = BPS2 + 1024; - else - BPS3 = BPS2; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if (PPU.BG[bg].SCSize & 1) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if(((uint8*)SC1-Memory.VRAM)>=0x10000) - SC1-=0x08000; - - - if (PPU.BG[bg].SCSize & 2) - SC2 = SC1 + 1024; - else - SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - - if (PPU.BG[bg].SCSize & 1) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - - static const int Lines = 1; - int OffsetMask; - int OffsetShift; - int OffsetEnableMask = 1 << (bg + 13); - - if (BG.TileSize == 16) - { - OffsetMask = 0x3ff; - OffsetShift = 4; - } - else - { - OffsetMask = 0x1ff; - OffsetShift = 3; - } - - for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y++) - { - uint32 VOff = LineData [Y].BG[2].VOffset - 1; -// uint32 VOff = LineData [Y].BG[2].VOffset; - uint32 HOff = LineData [Y].BG[2].HOffset; - - int VirtAlign; - int ScreenLine = VOff >> 3; - int t1; - int t2; - uint16 *s0; - uint16 *s1; - uint16 *s2; - - if (ScreenLine & 0x20) - s1 = BPS2, s2 = BPS3; - else - s1 = BPS0, s2 = BPS1; - - s1 += (ScreenLine & 0x1f) << 5; - s2 += (ScreenLine & 0x1f) << 5; - - if(BGMode != 4) - { - if((ScreenLine & 0x1f) == 0x1f) - { - if(ScreenLine & 0x20) - VOffsetOffset = BPS0 - BPS2 - 0x1f*32; - else - VOffsetOffset = BPS2 - BPS0 - 0x1f*32; - } - else - { - VOffsetOffset = 32; - } - } - - int clipcount = GFX.pCurrentClip->Count [bg]; - if (!clipcount) - clipcount = 1; - - for (int clip = 0; clip < clipcount; clip++) - { - uint32 Left; - uint32 Right; - - if (!GFX.pCurrentClip->Count [bg]) - { - Left = 0; - Right = 256; - } - else - { - Left = GFX.pCurrentClip->Left [clip][bg]; - Right = GFX.pCurrentClip->Right [clip][bg]; - - if (Right <= Left) - continue; - } - - uint32 VOffset; - uint32 HOffset; - //added: - uint32 LineHOffset=LineData [Y].BG[bg].HOffset; - - uint32 Offset; - uint32 HPos; - uint32 Quot; - uint32 Count; - uint16 *t; - uint32 Quot2; - uint32 VCellOffset; - uint32 HCellOffset; - uint16 *b1; - uint16 *b2; - uint32 TotalCount = 0; - uint32 MaxCount = 8; - - uint32 s = Left * GFX.PixSize + Y * GFX.PPL; - bool8 left_hand_edge = (Left == 0); - Width = Right - Left; - - if (Left & 7) - MaxCount = 8 - (Left & 7); - - while (Left < Right) - { - if (left_hand_edge) - { - // The SNES offset-per-tile background mode has a - // hardware limitation that the offsets cannot be set - // for the tile at the left-hand edge of the screen. - VOffset = LineData [Y].BG[bg].VOffset; - - //MKendora; use temp var to reduce memory accesses - //HOffset = LineData [Y].BG[bg].HOffset; - - HOffset = LineHOffset; - //End MK - - left_hand_edge = FALSE; - } - else - - { - // All subsequent offset tile data is shifted left by one, - // hence the - 1 below. - - Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3; - - if (Quot2 > 31) - s0 = s2 + (Quot2 & 0x1f); - else - s0 = s1 + Quot2; - - HCellOffset = READ_2BYTES (s0); - - if (BGMode == 4) - { - VOffset = LineData [Y].BG[bg].VOffset; - - //MKendora another mem access hack - //HOffset = LineData [Y].BG[bg].HOffset; - HOffset=LineHOffset; - //end MK - - if ((HCellOffset & OffsetEnableMask)) - { - if (HCellOffset & 0x8000) - VOffset = HCellOffset + 1; - else - HOffset = HCellOffset; - } - } - else - { - VCellOffset = READ_2BYTES (s0 + VOffsetOffset); - if ((VCellOffset & OffsetEnableMask)) - VOffset = VCellOffset + 1; - else - VOffset = LineData [Y].BG[bg].VOffset; - - //MKendora Strike Gunner fix - if ((HCellOffset & OffsetEnableMask)) - { - //HOffset= HCellOffset; - - HOffset = (HCellOffset & ~7)|(LineHOffset&7); - //HOffset |= LineData [Y].BG[bg].HOffset&7; - } - else - HOffset=LineHOffset; - //HOffset = LineData [Y].BG[bg].HOffset - - //Settings.StrikeGunnerOffsetHack; - //HOffset &= (~7); - //end MK - } - } - VirtAlign = ((Y + VOffset) & 7) << 3; - ScreenLine = (VOffset + Y) >> OffsetShift; - - if (((VOffset + Y) & 15) > 7) - { - t1 = 16; - t2 = 0; - } - else - { - t1 = 0; - t2 = 16; - } - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - - HPos = (HOffset + Left) & OffsetMask; - - Quot = HPos >> 3; - - if (BG.TileSize == 8) - { - if (Quot > 31) - t = b2 + (Quot & 0x1f); - else - t = b1 + Quot; - } - else - { - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - } - - if (MaxCount + TotalCount > Width) - MaxCount = Width - TotalCount; - - Offset = HPos & 7; - - //Count =1; - Count = 8 - Offset; - if (Count > MaxCount) - Count = MaxCount; - - s -= (IPPU.HalfWidthPixels ? Offset >> 1 : Offset) * GFX.PixSize; - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - (*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); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - - Left += Count; - TotalCount += Count; - s += (IPPU.HalfWidthPixels ? (Offset + Count) >> 1 : (Offset + Count)) * GFX.PixSize; - MaxCount = 8; - } - } - } -} - -static void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) -{ - CHECK_SOUND(); - - if(IPPU.Interlace) - { - GFX.Pitch = GFX.RealPitch; - GFX.PPL = GFX.PPLx2 >> 1; - } - GFX.PixSize = 1; - uint8 depths [2] = {Z1, Z2}; - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint32 Width; - - BG.StartPalette = 0; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if ((PPU.BG[bg].SCSize & 1)) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if((SC1-(unsigned short*)Memory.VRAM)>0x10000) - SC1=(uint16*)&Memory.VRAM[(((uint8*)SC1)-Memory.VRAM)%0x10000]; - - if ((PPU.BG[bg].SCSize & 2)) - SC2 = SC1 + 1024; - else SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - - - if ((PPU.BG[bg].SCSize & 1)) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - - - int Lines; - int VOffsetMask; - int VOffsetShift; - - if (BG.TileSize == 16) - { - VOffsetMask = 0x3ff; - VOffsetShift = 4; - } - else - { - VOffsetMask = 0x1ff; - VOffsetShift = 3; - } - int endy = IPPU.Interlace ? 1 + (GFX.EndY << 1) : GFX.EndY; - - for (int Y = IPPU.Interlace ? GFX.StartY << 1 : GFX.StartY; Y <= endy; Y += Lines) - { - int y = IPPU.Interlace ? (Y >> 1) : Y; - uint32 VOffset = LineData [y].BG[bg].VOffset; - uint32 HOffset = LineData [y].BG[bg].HOffset; - int VirtAlign = (Y + VOffset) & 7; - - for (Lines = 1; Lines < 8 - VirtAlign; Lines++) - if ((VOffset != LineData [y + Lines].BG[bg].VOffset) || - (HOffset != LineData [y + Lines].BG[bg].HOffset)) - break; - - HOffset <<= 1; - if (Y + Lines > endy) - Lines = endy + 1 - Y; - VirtAlign <<= 3; - - int ScreenLine = (VOffset + Y) >> VOffsetShift; - int t1; - int t2; - if (((VOffset + Y) & 15) > 7) - { - t1 = 16; - t2 = 0; - } - else - { - t1 = 0; - t2 = 16; - } - uint16 *b1; - uint16 *b2; - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - - int clipcount = GFX.pCurrentClip->Count [bg]; - if (!clipcount) - clipcount = 1; - for (int clip = 0; clip < clipcount; clip++) - { - int Left; - int Right; - - if (!GFX.pCurrentClip->Count [bg]) - { - Left = 0; - Right = 512; - } - else - { - Left = GFX.pCurrentClip->Left [clip][bg] * 2; - Right = GFX.pCurrentClip->Right [clip][bg] * 2; - - if (Right <= Left) - continue; - } - - uint32 s = (IPPU.HalfWidthPixels ? Left >> 1 : Left) * GFX.PixSize + Y * GFX.PPL; - uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff; - - uint32 Quot = HPos >> 3; - uint32 Count = 0; - - uint16 *t; - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - - Width = Right - Left; - // Left hand edge clipped tile - if (HPos & 7) - { - int Offset = (HPos & 7); - Count = 8 - Offset; - if (Count > Width) - Count = Width; - s -= (IPPU.HalfWidthPixels ? Offset >> 1 : Offset); - Tile = READ_2BYTES (t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - { - if (!(Tile & H_FLIP)) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip - (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - - t += Quot & 1; - if (Quot == 63) - t = b2; - else if (Quot == 127) - t = b1; - Quot++; - s += (IPPU.HalfWidthPixels ? 4 : 8); - } - - // Middle, unclipped tiles - Count = Width - Count; - int Middle = Count >> 3; - Count &= 7; - 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]; - if (BG.TileSize == 8) - { - if (!(Tile & H_FLIP)) - { - // Normal, unflipped - (*DrawHiResTilePtr) (Tile + (Quot & 1), - s, VirtAlign, Lines); - } - else - { - // H flip - (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1), - s, VirtAlign, Lines); - } - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1), - s, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1), - s, VirtAlign, Lines); - } - } - - t += Quot & 1; - if (Quot == 63) - t = b2; - else - if (Quot == 127) - t = b1; - } - - // Right-hand edge clipped tiles - if (Count) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - if (BG.TileSize == 8) - { - if (!(Tile & H_FLIP)) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - else - { - // H flip - (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - } - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), - s, 0, Count, VirtAlign, Lines); - } - } - } - } - } - GFX.Pitch = IPPU.DoubleHeightPixels ? GFX.RealPitch * 2 : GFX.RealPitch; - GFX.PPL = IPPU.DoubleHeightPixels ? GFX.PPLx2 : (GFX.PPLx2 >> 1); - -} - -static void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) -{ -#ifdef ACCUMULATE_JOYPAD -/* - * This call allows NDSSFC to synchronise the DS controller more often. - * If porting a later version of Snes9x into NDSSFC, it is essential to - * preserve it. - */ - NDSSFCAccumulateJoypad (); -#endif - GFX.PixSize = 1; - - BG.TileSize = BGSizes [PPU.BG[bg].BGSize]; - BG.BitShift = BitShifts[BGMode][bg]; - BG.TileShift = TileShifts[BGMode][bg]; - BG.TileAddress = PPU.BG[bg].NameBase << 1; - BG.NameSelect = 0; - BG.Buffer = IPPU.TileCache [Depths [BGMode][bg]]; - BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]]; - BG.PaletteShift = PaletteShifts[BGMode][bg]; - BG.PaletteMask = PaletteMasks[BGMode][bg]; - BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 && - (GFX.r2130 & 1); - - if (PPU.BGMosaic [bg] && PPU.Mosaic > 1) - { - DrawBackgroundMosaic (BGMode, bg, Z1, Z2); - return; - - } - switch (BGMode) - { - case 2: - case 4: // Used by Puzzle Bobble - DrawBackgroundOffset (BGMode, bg, Z1, Z2); - return; - - case 5: - case 6: // XXX: is also offset per tile. -// if (Settings.SupportHiRes) -// { - if (!Settings.SupportHiRes) - SelectTileRenderer(TRUE /* normal */); - DrawBackgroundMode5 (BGMode, bg, Z1, Z2); - return; -// } - break; - } - CHECK_SOUND(); - - uint32 Tile; - uint16 *SC0; - uint16 *SC1; - uint16 *SC2; - uint16 *SC3; - uint32 Width; - uint8 depths [2] = {Z1, Z2}; - - if (BGMode == 0) - BG.StartPalette = bg << 5; - else BG.StartPalette = 0; - - SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; - - if (PPU.BG[bg].SCSize & 1) - SC1 = SC0 + 1024; - else - SC1 = SC0; - - if(SC1>=(unsigned short*)(Memory.VRAM+0x10000)) - SC1=(uint16*)&Memory.VRAM[((uint8*)SC1-&Memory.VRAM[0])%0x10000]; - - if (PPU.BG[bg].SCSize & 2) - SC2 = SC1 + 1024; - else - SC2 = SC0; - - if(((uint8*)SC2-Memory.VRAM)>=0x10000) - SC2-=0x08000; - - if (PPU.BG[bg].SCSize & 1) - SC3 = SC2 + 1024; - else - SC3 = SC2; - - if(((uint8*)SC3-Memory.VRAM)>=0x10000) - SC3-=0x08000; - - - - int Lines; - int OffsetMask; - int OffsetShift; - - if (BG.TileSize == 16) - { - OffsetMask = 0x3ff; - OffsetShift = 4; - } - else - { - OffsetMask = 0x1ff; - OffsetShift = 3; - } - - for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) - { - uint32 VOffset = LineData [Y].BG[bg].VOffset; - uint32 HOffset = LineData [Y].BG[bg].HOffset; - int VirtAlign = (Y + VOffset) & 7; - - for (Lines = 1; Lines < 8 - VirtAlign; Lines++) - if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || - (HOffset != LineData [Y + Lines].BG[bg].HOffset)) - break; - - if (Y + Lines > GFX.EndY) - Lines = GFX.EndY + 1 - Y; - - VirtAlign <<= 3; - - uint32 ScreenLine = (VOffset + Y) >> OffsetShift; - uint32 t1; - uint32 t2; - if (((VOffset + Y) & 15) > 7) - { - t1 = 16; - t2 = 0; - } - else - { - t1 = 0; - t2 = 16; - } - uint16 *b1; - uint16 *b2; - - if (ScreenLine & 0x20) - b1 = SC2, b2 = SC3; - else - b1 = SC0, b2 = SC1; - - b1 += (ScreenLine & 0x1f) << 5; - b2 += (ScreenLine & 0x1f) << 5; - - int clipcount = GFX.pCurrentClip->Count [bg]; - if (!clipcount) - clipcount = 1; - for (int clip = 0; clip < clipcount; clip++) - { - uint32 Left; - uint32 Right; - - if (!GFX.pCurrentClip->Count [bg]) - { - Left = 0; - Right = 256; - } - else - { - Left = GFX.pCurrentClip->Left [clip][bg]; - Right = GFX.pCurrentClip->Right [clip][bg]; - - if (Right <= Left) - continue; - } - - uint32 s = Left * GFX.PixSize + Y * GFX.PPL; - uint32 HPos = (HOffset + Left) & OffsetMask; - - uint32 Quot = HPos >> 3; - uint32 Count = 0; - - uint16 *t; - if (BG.TileSize == 8) - { - if (Quot > 31) - t = b2 + (Quot & 0x1f); - else - t = b1 + Quot; - } - else - { - if (Quot > 63) - t = b2 + ((Quot >> 1) & 0x1f); - else - t = b1 + (Quot >> 1); - } - - Width = Right - Left; - // Left hand edge clipped tile - if (HPos & 7) - { - uint32 Offset = (HPos & 7); - Count = 8 - Offset; - if (Count > Width) - Count = Width; - s -= Offset * GFX.PixSize; - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - { - (*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); - } - else - if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - else - { - // H flip only - (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, Offset, Count, VirtAlign, Lines); - } - } - else - { - // V flip only - (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s, - Offset, Count, VirtAlign, Lines); - } - } - - if (BG.TileSize == 8) - { - t++; - if (Quot == 31) - t = b2; - else if (Quot == 63) - t = b1; - } - else - { - t += Quot & 1; - if (Quot == 63) - t = b2; - else if (Quot == 127) - t = b1; - } - Quot++; - s += (IPPU.HalfWidthPixels ? 4 : 8) * GFX.PixSize; - } - - // Middle, unclipped tiles - Count = Width - Count; - int Middle = Count >> 3; - Count &= 7; - for (int C = Middle; C > 0; s += (IPPU.HalfWidthPixels ? 4 : 8) * GFX.PixSize, Quot++, C--) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize != 8) - { - if (Tile & H_FLIP) - { - // Horizontal flip, but what about vertical flip ? - if (Tile & V_FLIP) - { - // Both horzontal & vertical flip - (*DrawTilePtr) (Tile + t2 + 1 - (Quot & 1), s, - VirtAlign, Lines); - } - else - { - // Horizontal flip only - (*DrawTilePtr) (Tile + t1 + 1 - (Quot & 1), s, - VirtAlign, Lines); - } - } - else - { - // No horizontal flip, but is there a vertical flip ? - if (Tile & V_FLIP) - { - // Vertical flip only - (*DrawTilePtr) (Tile + t2 + (Quot & 1), s, - VirtAlign, Lines); - } - else - { - // Normal unflipped - (*DrawTilePtr) (Tile + t1 + (Quot & 1), s, - VirtAlign, Lines); - } - } - } - else - { - (*DrawTilePtr) (Tile, s, VirtAlign, Lines); - } - - if (BG.TileSize == 8) - { - t++; - if (Quot == 31) - t = b2; - else - if (Quot == 63) - t = b1; - } - else - { - t += Quot & 1; - if (Quot == 63) - t = b2; - else - if (Quot == 127) - t = b1; - } - } - // Right-hand edge clipped tiles - if (Count) - { - Tile = READ_2BYTES(t); - GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; - - if (BG.TileSize == 8) - (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign, - Lines); - else - { - if (!(Tile & (V_FLIP | H_FLIP))) - { - // Normal, unflipped - (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0, - Count, VirtAlign, Lines); - } - else if (Tile & H_FLIP) - { - if (Tile & V_FLIP) - { - // H & V flip - (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, - Lines); - } - else - { - // H flip only - (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), - s, 0, Count, VirtAlign, - Lines); - } - } - else - { - // V flip only - (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), - s, 0, Count, VirtAlign, - Lines); - } - } - } - } - } -} - -#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \ - uint16 *ScreenColors; \ - CHECK_SOUND(); \ -\ - uint8 *VRAM1 = Memory.VRAM + 1; \ - if (GFX.r2130 & 1) \ - { \ - if (IPPU.DirectColourMapsNeedRebuild) \ - S9xBuildDirectColourMaps (); \ - ScreenColors = DirectColourMaps [0]; \ - } \ - else \ - 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 = 255 - (int) Line; \ - else \ - yy = Line; \ -\ - yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \ -\ - int BB = l->MatrixB * yy + (CentreX << 8); \ - int DD = l->MatrixD * yy + (CentreY << 8); \ -\ - for (uint32 clip = 0; clip < ClipCount; clip++) \ - { \ - if (GFX.pCurrentClip->Count [bg]) \ - { \ - Left = GFX.pCurrentClip->Left [clip][bg]; \ - Right = GFX.pCurrentClip->Right [clip][bg]; \ - if (Right <= Left) \ - continue; \ - } \ - TYPE *p = (TYPE *) Screen + Left; \ - uint8 *d = Depth + Left; \ -\ - if (PPU.Mode7HFlip) \ - { \ - startx = Right - 1; \ - endx = Left - 1; \ - dir = -1; \ - aa = -l->MatrixA; \ - cc = -l->MatrixC; \ - } \ - else \ - { \ - startx = Left; \ - endx = Right; \ - dir = 1; \ - aa = l->MatrixA; \ - cc = l->MatrixC; \ - } \ -\ - int xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \ - int AA = l->MatrixA * xx; \ - int CC = l->MatrixC * xx; \ -\ - if (!PPU.Mode7Repeat) \ - { \ - 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 & GFX.Mode7Mask) ) \ - { \ - *p = (FUNC); \ - *d = GFX.Z1; \ - } \ - } \ - } \ - 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); \ -\ - 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 & GFX.Mode7Mask) ) \ - { \ - *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 & GFX.Mode7Mask) ) \ - { \ - *p = (FUNC); \ - *d = GFX.Z1; \ - } \ - } \ - } \ - } \ - } \ - } \ - } - -static void DrawBGMode7Background (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask)) -} - -static void DrawBGMode7Background16 (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7 (uint16, ScreenColors [b & GFX.Mode7Mask]); -} - -static void DrawBGMode7Background16Add (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_ADD (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_ADD (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); -} - -static void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_ADD1_2 (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_ADD (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); -} - -static void DrawBGMode7Background16Sub (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_SUB (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); -} - -static void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB1_2 (ScreenColors [b & GFX.Mode7Mask], - p [GFX.Delta]) : - COLOR_SUB (ScreenColors [b & GFX.Mode7Mask], - GFX.FixedColour)) : - ScreenColors [b & GFX.Mode7Mask]); -} - -#define RENDER_BACKGROUND_MODE7_i(TYPE,FUNC,COLORFUNC) \ - uint16 *ScreenColors; \ - CHECK_SOUND(); \ -\ - uint8 *VRAM1 = Memory.VRAM + 1; \ - if (GFX.r2130 & 1) \ - { \ - if (IPPU.DirectColourMapsNeedRebuild) \ - S9xBuildDirectColourMaps (); \ - ScreenColors = DirectColourMaps [0]; \ - } \ - else \ - 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]; \ - bool8 allowSimpleCase = FALSE; \ - if (!l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100) \ - && !LineMatrixData[GFX.EndY].MatrixB && !LineMatrixData[GFX.EndY].MatrixC \ - && (LineMatrixData[GFX.EndY].MatrixA == 0x0100) && (LineMatrixData[GFX.EndY].MatrixD == 0x0100) \ - ) \ - allowSimpleCase = TRUE; \ - \ - for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ - { \ - int yy; \ - \ - int HOffset = ((int) LineData [Line].BG[0].HOffset << M7) >> M7; \ - int VOffset = ((int) LineData [Line].BG[0].VOffset << M7) >> M7; \ - \ - int CentreX = ((int) l->CentreX << M7) >> M7; \ - int CentreY = ((int) l->CentreY << M7) >> M7; \ - \ - if (PPU.Mode7VFlip) \ - yy = 255 - (int) Line; \ - else \ - yy = Line; \ - \ - \ - yy += CLIP_10_BIT_SIGNED(VOffset - CentreY); \ - bool8 simpleCase = FALSE; \ - int BB; \ - int DD; \ - /* Make a special case for the identity matrix, since it's a common case and */ \ - /* can be done much more quickly without special effects */ \ - if (allowSimpleCase && !l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100)) \ - { \ - BB = CentreX << 8; \ - DD = (yy + CentreY) << 8; \ - simpleCase = TRUE; \ - } \ - else \ - { \ - BB = l->MatrixB * yy + (CentreX << 8); \ - DD = l->MatrixD * yy + (CentreY << 8); \ - } \ - \ - for (uint32 clip = 0; clip < ClipCount; clip++) \ - { \ - if (GFX.pCurrentClip->Count [bg]) \ - { \ - Left = GFX.pCurrentClip->Left [clip][bg]; \ - Right = GFX.pCurrentClip->Right [clip][bg]; \ - if (Right <= Left) \ - continue; \ - } \ - TYPE *p = (TYPE *) Screen + Left; \ - uint8 *d = Depth + Left; \ - \ - if (PPU.Mode7HFlip) \ - { \ - startx = Right - 1; \ - endx = Left - 1; \ - dir = -1; \ - aa = -l->MatrixA; \ - cc = -l->MatrixC; \ - } \ - else \ - { \ - startx = Left; \ - endx = Right; \ - dir = 1; \ - aa = l->MatrixA; \ - cc = l->MatrixC; \ - } \ - int xx; \ - \ - xx = startx + CLIP_10_BIT_SIGNED(HOffset - CentreX); \ - int AA, CC = 0; \ - if (simpleCase) \ - { \ - AA = xx << 8; \ - } \ - else \ - { \ - AA = l->MatrixA * xx; \ - CC = l->MatrixC * xx; \ - } \ - if (simpleCase) \ - { \ - if (!PPU.Mode7Repeat) \ - { \ - int x = startx; \ - do \ - { \ - int X = ((AA + BB) >> 8) & 0x3ff; \ - int Y = (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 & GFX.Mode7Mask) ) \ - { \ - TYPE theColor = COLORFUNC; \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *d = GFX.Z1; \ - } \ - AA += aa, p++, d++; \ - x += dir; \ - } while (x != endx); \ - } \ - else \ - { \ - int x = startx; \ - do { \ - int X = (AA + BB) >> 8; \ - int Y = DD >> 8; \ -\ - 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 & GFX.Mode7Mask) ) \ - { \ - TYPE theColor = COLORFUNC; \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *d = GFX.Z1; \ - } \ - } \ - else if (PPU.Mode7Repeat == 3) \ - { \ - X = (x + HOffset) & 7; \ - Y = (yy + CentreY) & 7; \ - 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 & GFX.Mode7Mask) ) \ - { \ - TYPE theColor = COLORFUNC; \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *d = GFX.Z1; \ - } \ - } \ - AA += aa; p++; d++; \ - x += dir; \ - } while (x != endx); \ - } \ - } \ - else if (!PPU.Mode7Repeat) \ - { \ - /* The bilinear interpolator: get the colors at the four points surrounding */ \ - /* the location of one point in the _sampled_ image, and weight them according */ \ - /* to their (city block) distance. It's very smooth, but blurry with "close up" */ \ - /* points. */ \ - \ - /* 460 (slightly less than 2 source pixels per displayed pixel) is an educated */ \ - /* guess for where bilinear filtering will become a poor method for averaging. */ \ - /* (When reducing the image, the weighting used by a bilinear filter becomes */ \ - /* arbitrary, and a simple mean is a better way to represent the source image.) */ \ - /* You can think of this as a kind of mipmapping. */ \ - if ((aa < 460 && aa > -460) && (cc < 460 && cc > -460)) \ - {\ - for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ - { \ - uint32 xPos = AA + BB; \ - uint32 xPix = xPos >> 8; \ - uint32 yPos = CC + DD; \ - uint32 yPix = yPos >> 8; \ - uint32 X = xPix & 0x3ff; \ - uint32 Y = yPix & 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 & GFX.Mode7Mask) ) \ - { \ - /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ - uint32 X10 = (xPix + dir) & 0x3ff; \ - uint32 Y01 = (yPix + (PPU.Mode7VFlip?-1:1)) & 0x3ff; \ - uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ - uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ - uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 p1 = COLORFUNC; \ - p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \ - b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \ - uint32 p2 = COLORFUNC; \ - p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \ - b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \ - uint32 p4 = COLORFUNC; \ - p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \ - b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \ - uint32 p3 = COLORFUNC; \ - p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \ - /* Xdel, Ydel: position (in 1/32nds) between the points */ \ - uint32 Xdel = (xPos >> 3) & 0x1F; \ - uint32 Ydel = (yPos >> 3) & 0x1F; \ - uint32 XY = (Xdel*Ydel) >> 5; \ - uint32 area1 = 0x20 + XY - Xdel - Ydel; \ - uint32 area2 = Xdel - XY; \ - uint32 area3 = Ydel - XY; \ - uint32 area4 = XY; \ - if(PPU.Mode7HFlip){ \ - uint32 tmp=area1; area1=area2; area2=tmp; \ - tmp=area3; area3=area4; area4=tmp; \ - } \ - if(PPU.Mode7VFlip){ \ - uint32 tmp=area1; area1=area3; area3=tmp; \ - tmp=area2; area2=area4; area4=tmp; \ - } \ - uint32 tempColor = ((area1 * p1) + \ - (area2 * p2) + \ - (area3 * p3) + \ - (area4 * p4)) >> 5; \ - TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *d = GFX.Z1; \ - } \ - } \ - } \ - else \ - /* The oversampling method: get the colors at four corners of a square */ \ - /* in the _displayed_ image, and average them. It's sharp and clean, but */ \ - /* gives the usual huge pixels when the source image gets "close." */ \ - { \ - /* Find the dimensions of the square in the source image whose corners will be examined. */ \ - uint32 aaDelX = aa >> 1; \ - uint32 ccDelX = cc >> 1; \ - uint32 bbDelY = l->MatrixB >> 1; \ - uint32 ddDelY = l->MatrixD >> 1; \ - /* Offset the location within the source image so that the four sampled points */ \ - /* center around where the single point would otherwise have been drawn. */ \ - BB -= (bbDelY >> 1); \ - DD -= (ddDelY >> 1); \ - AA -= (aaDelX >> 1); \ - CC -= (ccDelX >> 1); \ - uint32 BB10 = BB + aaDelX; \ - uint32 BB01 = BB + bbDelY; \ - uint32 BB11 = BB + aaDelX + bbDelY; \ - uint32 DD10 = DD + ccDelX; \ - uint32 DD01 = DD + ddDelY; \ - uint32 DD11 = DD + ccDelX + ddDelY; \ - for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ - { \ - uint32 X = ((AA + BB) >> 8) & 0x3ff; \ - uint32 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 & GFX.Mode7Mask) ) \ - { \ - /* X, Y, X10, Y10, etc. are the coordinates of the four pixels within the */ \ - /* source image that we're going to examine. */ \ - uint32 X10 = ((AA + BB10) >> 8) & 0x3ff; \ - uint32 Y10 = ((CC + DD10) >> 8) & 0x3ff; \ - uint32 X01 = ((AA + BB01) >> 8) & 0x3ff; \ - uint32 Y01 = ((CC + DD01) >> 8) & 0x3ff; \ - uint32 X11 = ((AA + BB11) >> 8) & 0x3ff; \ - uint32 Y11 = ((CC + DD11) >> 8) & 0x3ff; \ - uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y10 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ - uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X01 >> 2) & ~1)] << 7); \ - uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y11 & ~7) << 5) + ((X11 >> 2) & ~1)] << 7); \ - TYPE p1 = COLORFUNC; \ - b = *(TileData10 + ((Y10 & 7) << 4) + ((X10 & 7) << 1)); \ - TYPE p2 = COLORFUNC; \ - b = *(TileData01 + ((Y01 & 7) << 4) + ((X01 & 7) << 1)); \ - TYPE p3 = COLORFUNC; \ - b = *(TileData11 + ((Y11 & 7) << 4) + ((X11 & 7) << 1)); \ - TYPE p4 = COLORFUNC; \ - TYPE theColor = Q_INTERPOLATE(p1, p2, p3, p4); \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *d = GFX.Z1; \ - } \ - } \ - } \ - } \ - else \ - { \ - for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ - { \ - uint32 xPos = AA + BB; \ - uint32 xPix = xPos >> 8; \ - uint32 yPos = CC + DD; \ - uint32 yPix = yPos >> 8; \ - uint32 X = xPix; \ - uint32 Y = yPix; \ - \ -\ - 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 & GFX.Mode7Mask) ) \ - { \ - /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ - uint32 X10 = (xPix + dir) & 0x3ff; \ - uint32 Y01 = (yPix + dir) & 0x3ff; \ - uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ - uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ - uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ - uint32 p1 = COLORFUNC; \ - p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \ - b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \ - uint32 p2 = COLORFUNC; \ - p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \ - b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \ - uint32 p4 = COLORFUNC; \ - p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \ - b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \ - uint32 p3 = COLORFUNC; \ - p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \ - /* Xdel, Ydel: position (in 1/32nds) between the points */ \ - uint32 Xdel = (xPos >> 3) & 0x1F; \ - uint32 Ydel = (yPos >> 3) & 0x1F; \ - uint32 XY = (Xdel*Ydel) >> 5; \ - uint32 area1 = 0x20 + XY - Xdel - Ydel; \ - uint32 area2 = Xdel - XY; \ - uint32 area3 = Ydel - XY; \ - uint32 area4 = XY; \ - uint32 tempColor = ((area1 * p1) + \ - (area2 * p2) + \ - (area3 * p3) + \ - (area4 * p4)) >> 5; \ - TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *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 & GFX.Mode7Mask) ) \ - { \ - TYPE theColor = COLORFUNC; \ - *p = (FUNC) | ALPHA_BITS_MASK; \ - *d = GFX.Z1; \ - } \ - } \ - } \ - } \ - } \ - } \ - } - -STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) -{ - register uint32 x = ((A >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + - ((B >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + - ((C >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + - ((D >> 2) & HIGH_BITS_SHIFTED_TWO_MASK); - register uint32 y = (A & TWO_LOW_BITS_MASK) + - (B & TWO_LOW_BITS_MASK) + - (C & TWO_LOW_BITS_MASK) + - (D & TWO_LOW_BITS_MASK); - y = (y>>2) & TWO_LOW_BITS_MASK; - return x+y; -} - -static void DrawBGMode7Background16_i (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7_i (uint16, theColor, (ScreenColors[b & GFX.Mode7Mask])); -} - -static void DrawBGMode7Background16Add_i (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - (COLOR_ADD (theColor, - p [GFX.Delta])) : - (COLOR_ADD (theColor, - GFX.FixedColour))) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); -} - -static void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_ADD1_2 (theColor, - p [GFX.Delta]) : - COLOR_ADD (theColor, - GFX.FixedColour)) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); -} - -static void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB (theColor, - p [GFX.Delta]) : - COLOR_SUB (theColor, - GFX.FixedColour)) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); -} - -static void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg) -{ - RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? - (*(d + GFX.DepthDelta) != 1 ? - COLOR_SUB1_2 (theColor, - p [GFX.Delta]) : - COLOR_SUB (theColor, - GFX.FixedColour)) : - theColor, (ScreenColors[b & GFX.Mode7Mask])); -} - -#define _BUILD_SETUP(F) \ -GFX.BuildPixel = BuildPixel##F; \ -GFX.BuildPixel2 = BuildPixel2##F; \ -GFX.DecomposePixel = DecomposePixel##F; \ -RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_##F; \ -GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_##F; \ -BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_##F; \ -RED_HI_BIT_MASK = RED_HI_BIT_MASK_##F; \ -GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_##F; \ -BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_##F; \ -MAX_RED = MAX_RED_##F; \ -MAX_GREEN = MAX_GREEN_##F; \ -MAX_BLUE = MAX_BLUE_##F; \ -GREEN_HI_BIT = ((MAX_GREEN_##F + 1) >> 1); \ -SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_##F; \ -RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_##F | \ - GREEN_LOW_BIT_MASK_##F | \ - BLUE_LOW_BIT_MASK_##F); \ -RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_##F | \ - GREEN_HI_BIT_MASK_##F | \ - BLUE_HI_BIT_MASK_##F); \ -RGB_HI_BITS_MASKx2 = ((RED_HI_BIT_MASK_##F | \ - GREEN_HI_BIT_MASK_##F | \ - BLUE_HI_BIT_MASK_##F) << 1); \ -RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK; \ -FIRST_COLOR_MASK = FIRST_COLOR_MASK_##F; \ -SECOND_COLOR_MASK = SECOND_COLOR_MASK_##F; \ -THIRD_COLOR_MASK = THIRD_COLOR_MASK_##F; \ -ALPHA_BITS_MASK = ALPHA_BITS_MASK_##F; \ -FIRST_THIRD_COLOR_MASK = FIRST_COLOR_MASK | THIRD_COLOR_MASK; \ -TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \ -HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \ - ~TWO_LOW_BITS_MASK ) >> 2); - -static void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) -{ - bool8 BG0; - bool8 BG1; - bool8 BG2; - bool8 BG3; - bool8 OB; - - GFX.S = Screen; - - if (!sub) - { - GFX.pCurrentClip = &IPPU.Clip [0]; - BG0 = ON_MAIN (0); - BG1 = ON_MAIN (1); - BG2 = ON_MAIN (2); - BG3 = ON_MAIN (3); - OB = ON_MAIN (4); - } - else - { - GFX.pCurrentClip = &IPPU.Clip [1]; - BG0 = ON_SUB (0); - BG1 = ON_SUB (1); - BG2 = ON_SUB (2); - BG3 = ON_SUB (3); - OB = ON_SUB (4); - } - - sub |= force_no_add; - - switch (PPU.BGMode) { - case 0: - case 1: - if (OB) - { - SelectTileRenderer (sub || !SUB_OR_ADD(4)); - DrawOBJS (!sub, D); - } - if (BG0) - { - SelectTileRenderer (sub || !SUB_OR_ADD(0)); - DrawBackground (PPU.BGMode, 0, D + 10, D + 14); - } - if (BG1) - { - SelectTileRenderer (sub || !SUB_OR_ADD(1)); - DrawBackground (PPU.BGMode, 1, D + 9, D + 13); - } - if (BG2) - { - SelectTileRenderer (sub || !SUB_OR_ADD(2)); - DrawBackground (PPU.BGMode, 2, D + 3, - PPU.BG3Priority ? D + 17 : D + 6); - } - if (BG3 && PPU.BGMode == 0) - { - SelectTileRenderer (sub || !SUB_OR_ADD(3)); - DrawBackground (PPU.BGMode, 3, D + 2, D + 5); - } - break; - case 2: - case 3: - case 4: - case 5: - case 6: - if (OB) - { - SelectTileRenderer (sub || !SUB_OR_ADD(4)); - DrawOBJS (!sub, D); - } - if (BG0) - { - SelectTileRenderer (sub || !SUB_OR_ADD(0)); - DrawBackground (PPU.BGMode, 0, D + 5, D + 13); - } - if (BG1 && PPU.BGMode != 6) - { - SelectTileRenderer (sub || !SUB_OR_ADD(1)); - DrawBackground (PPU.BGMode, 1, D + 2, D + 9); - } - break; - case 7: - if (OB) - { - SelectTileRenderer (sub || !SUB_OR_ADD(4)); - DrawOBJS (!sub, D); - } - if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) - { - int bg; - - if ((Memory.FillRAM [0x2133] & 0x40)&&BG1) - { - GFX.Mode7Mask = 0x7f; - GFX.Mode7PriorityMask = 0x80; - Mode7Depths [0] = (BG0?5:1) + D; - Mode7Depths [1] = 9 + D; - bg = 1; - } - else - { - GFX.Mode7Mask = 0xff; - GFX.Mode7PriorityMask = 0; - Mode7Depths [0] = 5 + D; - Mode7Depths [1] = 5 + D; - bg = 0; - } - if (sub || !SUB_OR_ADD(0)) - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16 (Screen, bg); - else - DrawBGMode7Background16_i (Screen, bg); - } - else - { - if (GFX.r2131 & 0x80) - { - if (GFX.r2131 & 0x40) - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Sub1_2 (Screen, bg); - else - DrawBGMode7Background16Sub1_2_i (Screen, bg); - } - else - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Sub (Screen, bg); - else - DrawBGMode7Background16Sub_i (Screen, bg); - } - } - else - { - if (GFX.r2131 & 0x40) - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Add1_2 (Screen, bg); - else - DrawBGMode7Background16Add1_2_i (Screen, bg); - } - else - { - if (!Settings.Mode7Interpolate) - DrawBGMode7Background16Add (Screen, bg); - else - DrawBGMode7Background16Add_i (Screen, bg); - } - } - } - } - break; - default: - break; - } -} - -#include "font.h" - -void DisplayChar (uint8 *Screen, uint8 c) -{ - int line = (((c & 0x7f) - 32) >> 4) * font_height; - int offset = (((c & 0x7f) - 32) & 15) * font_width; - int h, w; - uint16 *s = (uint16 *) Screen; - for (h = 0; h < font_height; h++, line++, - s += GFX.PPL - font_width) - { - for (w = 0; w < font_width; w++, s++) - { - uint8 p = font [line][offset + w]; - - if (p == '#') - { - /* - if(Memory.Hacked) - *s= BUILD_PIXEL(31,0,0); - else if(Memory.Iffy) - *s= BUILD_PIXEL(31,31,0); - else if(Memory.Iformat==1) - *s= BUILD_PIXEL(0,31,0); - else if(Memory.Iformat==2) - *s= BUILD_PIXEL(0,31,31); - else *s = 0xffff; - */ - *s=Settings.DisplayColor; - } - else - if (p == '.') - *s = BLACK; - } - } -} - -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); - - int i; - for (i = 0; i < len; i++) - { - DisplayChar (Screen, string [i]); - Screen += (font_width - 1) * sizeof (uint16); - } -} - -static void S9xDisplayString (const char *string) -{ - uint8 *Screen = GFX.Screen + 2 + - (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch2; - int len = strlen (string); - int max_chars = IPPU.RenderedScreenWidth / (font_width - 1); - int char_count = 0; - int i; - - for (i = 0; i < len; i++, char_count++) - { - if (char_count >= max_chars || string [i] < 32) - { - Screen -= (font_width - 1) * max_chars * sizeof (uint16); - Screen += font_height * GFX.Pitch; - if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight) - break; - char_count -= max_chars; - } - if (string [i] < 32) - continue; - DisplayChar (Screen, string [i]); - Screen += (font_width - 1) * sizeof (uint16); - } -} - -void S9xUpdateScreen () -{ - int32 x2 = 1; - - GFX.S = GFX.Screen; - GFX.r2131 = Memory.FillRAM [0x2131]; - GFX.r212c = Memory.FillRAM [0x212c]; - GFX.r212d = Memory.FillRAM [0x212d]; - GFX.r2130 = Memory.FillRAM [0x2130]; - -#ifdef JP_FIX - - GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && - (GFX.r212c & 15) != (GFX.r212d & 15) && - (GFX.r2131 == 0x3f); - -#else - - GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && - (GFX.r212c & 15) != (GFX.r212d & 15) && - (GFX.r2131 & 0x3f) == 0; - -#endif - - if (IPPU.OBJChanged) - S9xSetupOBJ (); - - if (PPU.RecomputeClipWindows) - { - ComputeClipWindows (); - PPU.RecomputeClipWindows = FALSE; - } - - GFX.StartY = IPPU.PreviousLine; - if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight) - GFX.EndY = PPU.ScreenHeight - 1; - - // XXX: Check ForceBlank? Or anything else? - PPU.RangeTimeOver |= GFX.OBJLines[GFX.EndY].RTOFlags; - - uint32 starty = GFX.StartY; - uint32 endy = GFX.EndY; - - if (Settings.SupportHiRes && - (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace || IPPU.DoubleHeightPixels)) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6|| IPPU.Interlace) - { - IPPU.RenderedScreenWidth = 512; - x2 = 2; - } - - if (IPPU.DoubleHeightPixels) - { - starty = GFX.StartY * 2; - endy = GFX.EndY * 2 + 1; - } - - if ((PPU.BGMode == 5 || PPU.BGMode == 6) && !IPPU.DoubleWidthPixels) - { - // The game has switched from lo-res to hi-res mode part way down - // the screen. Scale any existing lo-res pixels on screen - for (register uint32 y = 0; y < starty; y++) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; - register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510; - - for (register int x = 255; x >= 0; x--, p--, q -= 2) - *q = *(q + 1) = *p; - } - IPPU.DoubleWidthPixels = TRUE; - IPPU.HalfWidthPixels = FALSE; - } - // BJ: And we have to change the height if Interlace gets set, - // too. - if (IPPU.Interlace && !IPPU.DoubleHeightPixels) - { - starty = GFX.StartY * 2; - endy = GFX.EndY * 2 + 1; - IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; - IPPU.DoubleHeightPixels = TRUE; - GFX.Pitch2 = GFX.RealPitch; - GFX.Pitch = GFX.RealPitch * 2; - GFX.PPL = GFX.PPLx2 = GFX.RealPitch; - - - // The game has switched from non-interlaced to interlaced mode - // part way down the screen. Scale everything. - for (register int32 y = (int32) GFX.StartY - 1; y >= 0; y--) - { - // memmove converted: Same malloc, different addresses, and identical addresses at line 0 [Neb] - // DS2 DMA notes: This code path is unused [Neb] - memcpy (GFX.Screen + y * 2 * GFX.Pitch2, - GFX.Screen + y * GFX.Pitch2, - GFX.Pitch2); - // memmove converted: Same malloc, different addresses [Neb] - memcpy (GFX.Screen + (y * 2 + 1) * GFX.Pitch2, - GFX.Screen + y * GFX.Pitch2, - GFX.Pitch2); - } - } - } - else if (!Settings.SupportHiRes) - { - if (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.Interlace) - { - if (!IPPU.HalfWidthPixels) - { - // The game has switched from lo-res to hi-res mode part way down - // the screen. Hi-res pixels must now be drawn at half width. - IPPU.HalfWidthPixels = TRUE; - } - } - else - { - if (IPPU.HalfWidthPixels) - { - // The game has switched from hi-res to lo-res mode part way down - // the screen. Lo-res pixels must now be drawn at FULL width. - IPPU.HalfWidthPixels = FALSE; - } - } - } - - uint32 black = BLACK | (BLACK << 16); - - if (Settings.Transparency) - { - if (GFX.Pseudo) - { - GFX.r2131 = 0x5f; - GFX.r212c &= (Memory.FillRAM [0x212d] | 0xf0); - GFX.r212d |= (Memory.FillRAM [0x212c] & 0x0f); - GFX.r2130 |= 2; - } - - if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && - (GFX.r2130 & 0x30) != 0x30 && - !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0)) - { - struct ClipData *pClip; - - GFX.FixedColour = BUILD_PIXEL (IPPU.XB [PPU.FixedColourRed], - IPPU.XB [PPU.FixedColourGreen], - IPPU.XB [PPU.FixedColourBlue]); - - // Clear the z-buffer, marking areas 'covered' by the fixed - // colour as depth 1. - pClip = &IPPU.Clip [1]; - - // Clear the z-buffer - if (pClip->Count [5]) - { - // Colour window enabled. - for (uint32 y = starty; y <= endy; y++) - { - ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - - if (IPPU.Clip [0].Count [5]) - { - uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - while (p < q) - *p++ = black; - } - - for (uint32 c = 0; c < pClip->Count [5]; c++) - { - if (pClip->Right [c][5] > pClip->Left [c][5]) - { - memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, - 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); - - if (IPPU.Clip [0].Count [5]) - { - // Blast, have to clear the sub-screen to the fixed-colour - // because there is a colour window in effect clipping - // the main screen that will allow the sub-screen - // 'underneath' to show through. - - uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2); - uint16 *q = p + pClip->Right [c][5] * x2; - p += pClip->Left [c][5] * x2; - - while (p < q) - *p++ = (uint16) GFX.FixedColour; - } - } - } - } - } - else - { - for (uint32 y = starty; y <= endy; y++) - { - ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - memset (GFX.SubZBuffer + y * GFX.ZPitch, 1, IPPU.RenderedScreenWidth); - - if (IPPU.Clip [0].Count [5]) - { - // Blast, have to clear the sub-screen to the fixed-colour - // because there is a colour window in effect clipping - // the main screen that will allow the sub-screen - // 'underneath' to show through. - - uint32 b = GFX.FixedColour | (GFX.FixedColour << 16); - uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - - while (p < q) - *p++ = b; - } - } - } - - if (ANYTHING_ON_SUB) - { - GFX.DB = GFX.SubZBuffer; - RenderScreen (GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH); - } - - if (IPPU.Clip [0].Count [5]) - { - for (uint32 y = starty; y <= endy; y++) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); - register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch; - register uint8 *e = d + IPPU.RenderedScreenWidth; - - while (d < e) - { - if (*d > 1) - *p = *(p + GFX.Delta); - else - *p = BLACK; - d++; - p++; - } - } - } - - GFX.DB = GFX.ZBuffer; - RenderScreen (GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH); - - if (SUB_OR_ADD(5)) - { - uint32 back = IPPU.ScreenColors [0]; - uint32 Left = 0; - uint32 Right = 256; - uint32 Count; - - pClip = &IPPU.Clip [0]; - for (uint32 y = starty; y <= endy; y++) - { - if (!(Count = pClip->Count [5])) - { - Left = 0; - Right = 256 * x2; - Count = 1; - } - - for (uint32 b = 0; b < Count; b++) - { - if (pClip->Count [5]) - { - Left = pClip->Left [b][5] * x2; - Right = pClip->Right [b][5] * x2; - if (Right <= Left) - continue; - } - - if (GFX.r2131 & 0x80) - { - if (GFX.r2131 & 0x40) - { - // Subtract, halving the result. - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); - - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_SUB1_2 (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - else - { - // Subtract - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); - - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_SUB (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - } - else if (GFX.r2131 & 0x40) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_ADD1_2 (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - else if (back != 0) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = COLOR_ADD (back, *(p + GFX.Delta)); - else - *p = back_fixed; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - else - { - if (!pClip->Count [5]) - { - // The backdrop has not been cleared yet - so - // 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 uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; - register uint8 *e = d + Right; - d += Left; - while (d < e) - { - if (*d == 0) - { - if (*s) - { - if (*s != 1) - *p = *(p + GFX.Delta); - else - *p = GFX.FixedColour; - } - else - *p = (uint16) back; - } - d++; - p++; - s++; - } - } - } - } - } - } // --if (SUB_OR_ADD(5)) - else - { - // Subscreen not being added to back - uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); - pClip = &IPPU.Clip [0]; - - if (pClip->Count [5]) - { - for (uint32 y = starty; y <= endy; y++) - { - for (uint32 b = 0; b < pClip->Count [5]; b++) - { - uint32 Left = pClip->Left [b][5] * x2; - uint32 Right = pClip->Right [b][5] * x2; - uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; - uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - uint8 *e = d + Right; - d += Left; - - while (d < e) - { - if (*d == 0) - *p = (int16) back; - d++; - p++; - } - } - } - } - else - { - for (uint32 y = starty; y <= endy; y++) - { - uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); - uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; - uint8 *e = d + 256 * x2; - - while (d < e) - { - if (*d == 0) - *p = (int16) back; - d++; - p++; - } - } - } - } - } //force blanking - else - { - // 16bit and transparency but currently no transparency effects in - // operation. - - uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); - - if (PPU.ForcedBlanking) - back = black; - - if (IPPU.Clip [0].Count[5]) - { - for (uint32 y = starty; y <= endy; y++) - { - uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - - while (p < q) - *p++ = black; - - for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++) - { - if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) - { - uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); - uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2; - p += IPPU.Clip [0].Left [c][5] * x2; - - while (p < q) - *p++ = (uint16) back; - } - } - } - } - else - { - for (uint32 y = starty; y <= endy; y++) - { - uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); - uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); - while (p < q) - *p++ = back; - } - } - - if (!PPU.ForcedBlanking) - { - for (uint32 y = starty; y <= endy; y++) - { - ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, IPPU.RenderedScreenWidth); - } - GFX.DB = GFX.ZBuffer; - RenderScreen (GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH); - } - } - } - else - { - } - - if (Settings.SupportHiRes) - { - if (PPU.BGMode != 5 && PPU.BGMode != 6 && IPPU.DoubleWidthPixels) - { - // Mixure of background modes used on screen - scale width - // of all non-mode 5 and 6 pixels. - for (register uint32 y = starty; y <= endy; y++) - { - register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; - register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510; - for (register int x = 255; x >= 0; x--, p--, q -= 2) - *q = *(q + 1) = *p; - } - } - - // Double the height of the pixels just drawn - FIX_INTERLACE(GFX.Screen, FALSE, GFX.ZBuffer); - } - - IPPU.PreviousLine = IPPU.CurrentLine; -} - - -- cgit v1.2.3