From 7ff342f9074405a19945df8442929110ae685d56 Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 23 Nov 2012 23:44:45 +0000 Subject: [PATCH] snesgfxdebugger-preliminary sprite visualizing --- .../Nintendo/SNES/SNESGraphicsDecoder.cs | 87 +++++++++++++++++-- .../SNESTools/SNESGraphicsDebugger.cs | 22 ++++- 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs index 1153bf2764..e48bc27055 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs @@ -171,6 +171,45 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES public int MODE; } + public class OAMInfo + { + public int Index { private set; get; } + public int X { private set; get; } + public int Y { private set; get; } + public int Tile { private set; get; } + public int Table { private set; get; } + public int Palette { private set; get; } + public int Priority { private set; get; } + public bool VFlip { private set; get; } + public bool HFlip { private set; get; } + public int Size { private set; get; } + + public OAMInfo(SNESGraphicsDecoder dec, int num) + { + Index = num; + + int lowaddr = num*4; + X = dec.oam[lowaddr++]; + Y = dec.oam[lowaddr++]; + Tile = dec.oam[lowaddr++]; + Table = dec.oam[lowaddr] & 1; + Palette = (dec.oam[lowaddr]>>1) & 7; + Priority = (dec.oam[lowaddr] >> 4) & 3; + HFlip = ((dec.oam[lowaddr] >> 6) & 1)==1; + VFlip = ((dec.oam[lowaddr] >> 7) & 1) == 1; + + int highaddr = num / 4; + int shift = (num % 4) * 2; + int high = dec.oam[512+highaddr]; + high >>= shift; + int x = high & 1; + high >>= 1; + Size = high & 1; + X |= (x << 9); + X = (X << 23) >> 23; + } + } + public class ScreenInfo { public BGInfos BG = new BGInfos(); @@ -344,15 +383,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES colortable = SnesColors.GetLUT(SnesColors.ColorType.Bizhawk); } - byte* vram; + public byte* vram, oam; public ushort* cgram, vram16; public SNESGraphicsDecoder() { IntPtr block = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.VRAM); - vram = (byte*)block.ToPointer(); - vram16 = (ushort*)vram; + vram = (byte*)block; + vram16 = (ushort*)block; block = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.CGRAM); - cgram = (ushort*)block.ToPointer(); + cgram = (ushort*)block; + block = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.OAM); + oam = (byte*)block; } public struct TileEntry @@ -669,12 +710,48 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES Colorize(screen, 0, numPixels); } + public void RenderSpriteToScreen(int* screen, int stride, int destx, int desty, ScreenInfo si, int spritenum) + { + var dims = new[] { SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, 0], SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size, 1] }; + var oam = new OAMInfo(this, spritenum); + var dim = dims[oam.Size]; + + int[] tilebuf = _tileCache[4]; + + int baseaddr; + if (oam.Table == 0) + baseaddr = si.OBJTable0Addr; + else + baseaddr = si.OBJTable1Addr; + + int bcol = oam.Tile & 0xF; + int brow = (oam.Tile >> 4) & 0xF; + for(int y=0;y> 3)) & 0xF; + int row = (brow + (y >> 3)) & 0xF; + int sx = x & 0x7; + int sy = y & 0x7; + + int addr = baseaddr*2 + (row * 16 + col) * 64; + addr += sy * 8 + sx; + + int dofs = stride*dy+dx; + screen[dofs] = tilebuf[addr]; + Paletteize(screen, dofs, oam.Palette * 16 + 128, 1); + Colorize(screen, dofs, 1); + } + } + /// /// renders the tiles to a screen of the crudely specified size. /// we might need 16x16 unscrambling and some other perks here eventually. /// provide a start color to use as the basis for the palette /// - public void RenderTilesToScreen(int* screen, int tilesWide, int tilesTall, int stride, int bpp, int startcolor, int startTile = 0, int numTiles = -1, bool descramble16=false) + public void RenderTilesToScreen(int* screen, int tilesWide, int tilesTall, int stride, int bpp, int startcolor, int startTile = 0, int numTiles = -1, bool descramble16 = false) { if(numTiles == -1) numTiles = 8192 / bpp; diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs index dc4b42f360..ca7650e777 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs @@ -36,7 +36,8 @@ namespace BizHawk.MultiClient displayTypeItems.Add(new DisplayTypeItem("BG2",eDisplayType.BG2)); displayTypeItems.Add(new DisplayTypeItem("BG3",eDisplayType.BG3)); displayTypeItems.Add(new DisplayTypeItem("BG4",eDisplayType.BG4)); - displayTypeItems.Add(new DisplayTypeItem("OBJ",eDisplayType.OBJ0)); + displayTypeItems.Add(new DisplayTypeItem("OBJ Tiles",eDisplayType.OBJ0)); + displayTypeItems.Add(new DisplayTypeItem("Sprites", eDisplayType.Sprites)); displayTypeItems.Add(new DisplayTypeItem("2bpp tiles",eDisplayType.Tiles2bpp)); displayTypeItems.Add(new DisplayTypeItem("4bpp tiles",eDisplayType.Tiles4bpp)); displayTypeItems.Add(new DisplayTypeItem("8bpp tiles",eDisplayType.Tiles8bpp)); @@ -240,6 +241,23 @@ namespace BizHawk.MultiClient }; var selection = CurrDisplaySelection; + if (selection == eDisplayType.Sprites) + { + var dims = new[] { SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size,0], SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size,1] }; + int largestWidth = Math.Max(dims[0].Width, dims[1].Width); + int largestHeight = Math.Max(dims[0].Height, dims[1].Height); + int width = largestWidth * 16; + int height = largestHeight * 8; + allocate(width, height); + for (int i = 0; i < 128; i++) + { + int tx = i % 16; + int ty = i / 16; + int x = tx * largestWidth; + int y = ty * largestHeight; + gd.RenderSpriteToScreen(pixelptr, stride / 4, x,y, si, i); + } + } if (selection == eDisplayType.OBJ0 || selection == eDisplayType.OBJ1) { allocate(128, 256); @@ -336,7 +354,7 @@ namespace BizHawk.MultiClient enum eDisplayType { - BG1=1, BG2=2, BG3=3, BG4=4, OBJ0, OBJ1, Tiles2bpp, Tiles4bpp, Tiles8bpp, TilesMode7, TilesMode7Ext, TilesMode7DC + BG1=1, BG2=2, BG3=3, BG4=4, Sprites, OBJ0, OBJ1, Tiles2bpp, Tiles4bpp, Tiles8bpp, TilesMode7, TilesMode7Ext, TilesMode7DC } static bool IsDisplayTypeBG(eDisplayType type) { return type == eDisplayType.BG1 || type == eDisplayType.BG2 || type == eDisplayType.BG3 || type == eDisplayType.BG4; } static bool IsDisplayTypeOBJ(eDisplayType type) { return type == eDisplayType.OBJ0 || type == eDisplayType.OBJ1; }