From 56f58caf4d4e15aad8399a39a5ad426e2a8d5bf2 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 2 Oct 2012 09:28:57 +0000 Subject: [PATCH] snesgfx-preliminary work on bg tilemap entry viewer. --- .../Nintendo/SNES/SNESGraphicsDecoder.cs | 28 +++++++- .../SNESTools/SNESGraphicsDebugger.cs | 69 +++++++++++++++++-- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs index 968c26137a..53aac5b2c1 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/SNESGraphicsDecoder.cs @@ -41,11 +41,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES public enum ScreenSize { - AAAA_32x32 = 0, ABAB_64x32 = 1, AABB_32x64 = 2, ABCD_64x64 = 3 + AAAA_32x32 = 0, ABAB_64x32 = 1, AABB_32x64 = 2, ABCD_64x64 = 3, + Hacky_1x1 = 4, } public static Dimensions SizeInTilesForBGSize(ScreenSize size) { + if (size == ScreenSize.Hacky_1x1) return new Dimensions(1, 1); var ret = SizeInBlocksForBGSize(size); ret.Width *= 32; ret.Height *= 32; @@ -389,6 +391,30 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES } } + /// + /// returns a tilemap which might be resized into 8x8 physical tiles if the 16x16 logical tilesize is specified + /// + //TileEntry[] AdaptTilemap(TileEntry[] map8x8, int tilesWide, int tilesTall, int tilesize) + //{ + // if (tilesize == 8) return map8x8; + // int numTiles = tilesWide * tilesTall; + // var ret = new TileEntry[numTiles * 4]; + // for(int y=0;y /// decodes a BG. youll still need to paletteize and colorize it. /// someone else has to take care of calculating the starting color from the mode and layer number. diff --git a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs index 0351aa3550..a317fd2ff8 100644 --- a/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs +++ b/BizHawk.MultiClient/SNESTools/SNESGraphicsDebugger.cs @@ -643,24 +643,56 @@ namespace BizHawk.MultiClient } } + class TileViewerBGState + { + public SNESGraphicsDecoder.TileEntry entry; + public int bgnum; + } + TileViewerBGState currTileViewerBGState; int currViewingTile = -1; int currViewingTileBpp = -1; void RenderTileView(bool force=false) { + //TODO - blech - handle invalid some other way with a dedicated black-setter bool valid = currViewingTile != -1; + valid |= (currTileViewerBGState != null); if (!valid && !force) return; - int bpp = currViewingTileBpp; + if (currTileViewerBGState != null) + { + //view a BG tile (no mode7 support yet) - itd be nice if we could generalize this code a bit + //TODO - choose correct palette (commonize that code) + int paletteStart = 0; + var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bgs = currTileViewerBGState; + var oneTileEntry = new SNESGraphicsDecoder.TileEntry[] { bgs.entry }; + if (valid) + { + gd.DecodeBG((int*)bmpdata.Scan0, bmpdata.Stride / 4, oneTileEntry, si.BG[bgs.bgnum].TiledataAddr, SNESGraphicsDecoder.ScreenSize.Hacky_1x1, si.BG[bgs.bgnum].Bpp, 8, paletteStart); + gd.Paletteize((int*)bmpdata.Scan0, 0, 0, 64); + gd.Colorize((int*)bmpdata.Scan0, 0, 64); + } - var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - if(valid) gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, currViewingTile, 1); - bmp.UnlockBits(bmpdata); - viewerTile.SetBitmap(bmp); + bmp.UnlockBits(bmpdata); + viewerTile.SetBitmap(bmp); + } + else + { + //view a tileset tile + int bpp = currViewingTileBpp; + + var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var bmpdata = bmp.LockBits(new Rectangle(0, 0, 8, 8), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + if (valid) gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, currViewingTile, 1); + bmp.UnlockBits(bmpdata); + viewerTile.SetBitmap(bmp); + } } void UpdateViewerMouseover(Point loc) { + currTileViewerBGState = null; currViewingTile = -1; currViewingTileBpp = -1; int tx = loc.X / 8; @@ -673,6 +705,31 @@ namespace BizHawk.MultiClient if (currViewingTile < 0 || currViewingTile >= (8192 / currViewingTileBpp)) currViewingTile = -1; break; + case eDisplayType.BG1: + case eDisplayType.BG2: + case eDisplayType.BG3: + case eDisplayType.BG4: + { + var bg = si.BG[(int)CurrDisplaySelection]; + var map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize); + if (bg.TileSize == 16) { tx /= 2; ty /= 2; } //worry about this later. need to pass a different flag into `currViewingTile` + + int tloc = ty * bg.ScreenSizeInTiles.Width + tx; + if (tloc > map.Length) break; + + currTileViewerBGState = new TileViewerBGState(); + currTileViewerBGState.bgnum = (int)CurrDisplaySelection; + currTileViewerBGState.entry = map[tloc]; + + //public void DecodeBG(int* screen, int stride, TileEntry[] map, int tiledataBaseAddr, ScreenSize size, int bpp, int tilesize, int paletteStart) + + + //var map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize); + //int paletteStart = 0; + //gd.DecodeBG(pixelptr, stride / 4, map, bg.TiledataAddr, bg.ScreenSize, bg.Bpp, bg.TileSize, paletteStart); + //gd.Paletteize(pixelptr, 0, 0, numPixels); + } + break; } RenderTileView(true);