snesgfxdebugger-fix a bunch of bugs and half-baked things. no new features.

This commit is contained in:
zeromus 2012-12-02 02:51:30 +00:00
parent 10585b69e4
commit 8834d3dd5c
4 changed files with 397 additions and 252 deletions

View File

@ -78,8 +78,30 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
}
}
public enum BGMode
{
Unavailable, Text, Mode7, Mode7Ext, Mode7DC
}
/// <summary>
/// this class is not 'smart' - it wont recompute values for you. it's meant to be read only (we should find some way to protect write access to make that clear)
/// </summary>
public class BGInfo
{
public BGInfo(int num)
{
}
/// <summary>
/// what type of BG is it?
/// </summary>
public BGMode BGMode;
/// <summary>
/// is this BGMode a mode7 type (mode7, mode7ext, mode7DC)
/// </summary>
public bool BGModeIsMode7Type { get { return BGMode == SNESGraphicsDecoder.BGMode.Mode7 || BGMode == SNESGraphicsDecoder.BGMode.Mode7DC || BGMode == SNESGraphicsDecoder.BGMode.Mode7Ext; } }
/// <summary>
/// Is the layer even enabled?
/// </summary>
@ -103,12 +125,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
/// <summary>
/// the address of the screen data
/// </summary>
public int ScreenAddr { get { return SCADDR << 9; } }
public int ScreenAddr;
/// <summary>
/// the address of the tile data
/// </summary>
public int TiledataAddr { get { return TDADDR << 13; } }
public int TiledataAddr;
/// <summary>
/// Screen size (shape, really.)
@ -148,7 +170,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
/// <summary>
/// The size of the layer, in tiles
/// </summary>
public Dimensions ScreenSizeInTiles { get { return SizeInTilesForBGSize(ScreenSize); } }
public Dimensions ScreenSizeInTiles
{
get
{
if (BGMode == SNESGraphicsDecoder.BGMode.Text)
return SizeInTilesForBGSize(ScreenSize);
else return new Dimensions(128, 128);
}
}
/// <summary>
/// The size of the layer, in pixels. This has factored in the selection of 8x8 or 16x16 tiles
@ -170,7 +200,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public class BGInfos
{
BGInfo[] bgs = new BGInfo[4] { new BGInfo(), new BGInfo(), new BGInfo(), new BGInfo() };
BGInfo[] bgs = new BGInfo[4] { new BGInfo(1), new BGInfo(2), new BGInfo(3), new BGInfo(4) };
public BGInfo BG1 { get { return bgs[0]; } }
public BGInfo BG2 { get { return bgs[1]; } }
public BGInfo BG3 { get { return bgs[2]; } }
@ -296,8 +326,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
si.BG.BG3.Bpp = ModeBpps[si.Mode.MODE, 2];
si.BG.BG4.Bpp = ModeBpps[si.Mode.MODE, 3];
if (si.Mode.MODE == 7 && si.SETINI_Mode7ExtBG)
si.BG.BG2.Bpp = 7;
//initial setting of mode type (derived from bpp table.. mode7 bg types will be fixed up later)
for(int i=1;i<=4;i++)
si.BG[i].BGMode = si.BG[i].Bpp == 0 ? BGMode.Unavailable : BGMode.Text;
si.BG.BG1.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG1_TILESIZE);
si.BG.BG2.TILESIZE = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.BG2_TILESIZE);
@ -331,7 +362,33 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
si.BG.BG4.MathEnabled = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.CGADSUB_BG4) == 1;
for (int i = 1; i <= 4; i++)
{
si.BG[i].Mode = si.Mode.MODE;
si.BG[i].TiledataAddr = si.BG[i].TDADDR << 13;
si.BG[i].ScreenAddr = si.BG[i].SCADDR << 9;
}
//fixup irregular things for mode 7
if (si.Mode.MODE == 7)
{
si.BG.BG1.TiledataAddr = 0;
si.BG.BG1.ScreenAddr = 0;
if (si.CGWSEL_DirectColor)
{
si.BG.BG1.BGMode = BGMode.Mode7DC;
}
else
si.BG.BG1.BGMode = BGMode.Mode7;
if (si.SETINI_Mode7ExtBG)
{
si.BG.BG2.BGMode = BGMode.Mode7Ext;
si.BG.BG2.Bpp = 7;
si.BG.BG2.TiledataAddr = 0;
si.BG.BG2.ScreenAddr = 0;
}
}
//determine which colors each BG could use
switch (si.Mode.MODE)
@ -452,7 +509,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public enum TileEntryFlags : byte
{
Priority = 1, Horz = 2, Vert = 4,
None = 0, Priority = 1, Horz = 2, Vert = 4,
}
/// <summary>
@ -563,6 +620,23 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
}
}
public TileEntry[] FetchMode7Tilemap()
{
TileEntry[] buf = new TileEntry[128*128];
for (int ty = 0, tidx = 0; ty < 128; ty++)
{
for (int tx = 0; tx < 128; tx++, tidx++)
{
int tileEntry = vram[tidx * 2];
buf[tidx].address = tidx * 2;
buf[tidx].tilenum = (ushort)tileEntry;
//palette and flags are ok defaulting to 0
}
}
return buf;
}
/// <summary>
/// fetches a tilemap. this is simple; apparently only the screen size (shape) is a factor (not the tile size)
/// </summary>
@ -732,17 +806,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
/// <summary>
/// renders the mode7 tiles to a screen with the predefined size.
/// </summary>
public void RenderMode7TilesToScreen(int* screen, int stride, bool ext, bool directColor)
public void RenderMode7TilesToScreen(int* screen, int stride, bool ext, bool directColor, int tilesWide = 16, int startTile = 0, int numTiles = 256)
{
int numTiles = 256;
int tilesWide = 16;
int[] tilebuf = _tileCache[ext?17:7];
for (int i = 0; i < numTiles; i++)
{
int tnum = startTile + i;
//TODO - mask by possible number of tiles? only in OBJ rendering mode?
int ty = i / tilesWide;
int tx = i % tilesWide;
int dstOfs = (ty * 8) * stride + tx * 8;
int srcOfs = i * 64;
int srcOfs = tnum * 64;
for (int y = 0, p = 0; y < 8; y++)
{
for (int x = 0; x < 8; x++, p++)
@ -758,6 +833,38 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
Colorize(screen, 0, numPixels);
}
/// <summary>
/// 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
/// </summary>
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;
int[] tilebuf = _tileCache[bpp];
for (int i = 0; i < numTiles; i++)
{
int tnum = startTile + i;
//TODO - mask by possible number of tiles? only in OBJ rendering mode?
int ty = i / tilesWide;
int tx = i % tilesWide;
int dstOfs = (ty * 8) * stride + tx * 8;
int srcOfs = tnum * 64;
for (int y = 0, p = 0; y < 8; y++)
for (int x = 0; x < 8; x++, p++)
{
screen[dstOfs + y * stride + x] = tilebuf[srcOfs + p];
}
}
int numPixels = numTiles * 8 * 8;
Paletteize(screen, 0, startcolor, numPixels);
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] };
@ -794,36 +901,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
}
}
/// <summary>
/// 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
/// </summary>
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;
int[] tilebuf = _tileCache[bpp];
for (int i = 0; i < numTiles; i++)
{
int tnum = startTile + i;
//TODO - mask by possible number of tiles? only in OBJ rendering mode?
int ty = i / tilesWide;
int tx = i % tilesWide;
int dstOfs = (ty * 8) * stride + tx * 8;
int srcOfs = tnum * 64;
for (int y = 0,p=0; y < 8; y++)
for (int x = 0; x < 8; x++,p++)
{
screen[dstOfs+y*stride+x] = tilebuf[srcOfs + p];
}
}
int numPixels = numTiles * 8 * 8;
Paletteize(screen, 0, startcolor, numPixels);
Colorize(screen, 0, numPixels);
}
public int Colorize(int rgb555)
{
return colortable[491520 + rgb555];

View File

@ -43,18 +43,8 @@
this.panel1 = new System.Windows.Forms.Panel();
this.groupFreeze = new System.Windows.Forms.GroupBox();
this.pnGroupFreeze = new System.Windows.Forms.Panel();
this.labelMemory = new System.Windows.Forms.Label();
this.check2x = new System.Windows.Forms.CheckBox();
this.groupBox8 = new System.Windows.Forms.GroupBox();
this.radioButton6 = new System.Windows.Forms.RadioButton();
this.radioButton1 = new System.Windows.Forms.RadioButton();
this.radioButton10 = new System.Windows.Forms.RadioButton();
this.radioButton15 = new System.Windows.Forms.RadioButton();
this.radioButton5 = new System.Windows.Forms.RadioButton();
this.radioButton14 = new System.Windows.Forms.RadioButton();
this.radioButton4 = new System.Windows.Forms.RadioButton();
this.radioButton3 = new System.Windows.Forms.RadioButton();
this.radioButton13 = new System.Windows.Forms.RadioButton();
this.radioButton2 = new System.Windows.Forms.RadioButton();
this.comboDisplayType = new System.Windows.Forms.ComboBox();
this.label47 = new System.Windows.Forms.Label();
this.pnBackdropColor = new System.Windows.Forms.Panel();
@ -71,6 +61,17 @@
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label26 = new System.Windows.Forms.Label();
this.txtOBSELT1OfsBits = new System.Windows.Forms.TextBox();
this.groupBox8 = new System.Windows.Forms.GroupBox();
this.radioButton6 = new System.Windows.Forms.RadioButton();
this.radioButton1 = new System.Windows.Forms.RadioButton();
this.radioButton10 = new System.Windows.Forms.RadioButton();
this.radioButton15 = new System.Windows.Forms.RadioButton();
this.radioButton5 = new System.Windows.Forms.RadioButton();
this.radioButton14 = new System.Windows.Forms.RadioButton();
this.radioButton4 = new System.Windows.Forms.RadioButton();
this.radioButton3 = new System.Windows.Forms.RadioButton();
this.radioButton13 = new System.Windows.Forms.RadioButton();
this.radioButton2 = new System.Windows.Forms.RadioButton();
this.label41 = new System.Windows.Forms.Label();
this.txtOBSELT1OfsDescr = new System.Windows.Forms.TextBox();
this.checkEN1_OBJ = new System.Windows.Forms.CheckBox();
@ -159,6 +160,7 @@
this.label4 = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.txtBG1MapSizeBytes = new System.Windows.Forms.TextBox();
this.txtBGPaletteInfo = new System.Windows.Forms.TextBox();
this.rbBG4 = new System.Windows.Forms.RadioButton();
this.rbBG3 = new System.Windows.Forms.RadioButton();
@ -219,18 +221,17 @@
this.viewerTile = new BizHawk.MultiClient.SNESGraphicsViewer();
this.viewerMapEntryTile = new BizHawk.MultiClient.SNESGraphicsViewer();
this.viewer = new BizHawk.MultiClient.SNESGraphicsViewer();
this.labelMemory = new System.Windows.Forms.Label();
this.menuStrip1.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.panel1.SuspendLayout();
this.groupFreeze.SuspendLayout();
this.pnGroupFreeze.SuspendLayout();
this.groupBox8.SuspendLayout();
this.groupBox3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudScanline)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.sliderScanline)).BeginInit();
this.groupBox6.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox8.SuspendLayout();
this.groupBox1.SuspendLayout();
this.groupBox5.SuspendLayout();
this.tabctrlDetails.SuspendLayout();
@ -372,6 +373,15 @@
this.pnGroupFreeze.Size = new System.Drawing.Size(208, 94);
this.pnGroupFreeze.TabIndex = 0;
//
// labelMemory
//
this.labelMemory.AutoSize = true;
this.labelMemory.Location = new System.Drawing.Point(3, 2);
this.labelMemory.Name = "labelMemory";
this.labelMemory.Size = new System.Drawing.Size(176, 13);
this.labelMemory.TabIndex = 1;
this.labelMemory.Text = "Right-click an item to display it here.";
//
// check2x
//
this.check2x.Appearance = System.Windows.Forms.Appearance.Button;
@ -386,145 +396,6 @@
this.check2x.UseVisualStyleBackColor = true;
this.check2x.CheckedChanged += new System.EventHandler(this.check2x_CheckedChanged);
//
// groupBox8
//
this.groupBox8.Controls.Add(this.radioButton6);
this.groupBox8.Controls.Add(this.radioButton1);
this.groupBox8.Controls.Add(this.radioButton10);
this.groupBox8.Controls.Add(this.radioButton15);
this.groupBox8.Controls.Add(this.radioButton5);
this.groupBox8.Controls.Add(this.radioButton14);
this.groupBox8.Controls.Add(this.radioButton4);
this.groupBox8.Controls.Add(this.radioButton3);
this.groupBox8.Controls.Add(this.radioButton13);
this.groupBox8.Controls.Add(this.radioButton2);
this.groupBox8.Location = new System.Drawing.Point(273, 247);
this.groupBox8.Name = "groupBox8";
this.groupBox8.Size = new System.Drawing.Size(15, 22);
this.groupBox8.TabIndex = 54;
this.groupBox8.TabStop = false;
this.groupBox8.Text = "groupBox8";
//
// radioButton6
//
this.radioButton6.AutoSize = true;
this.radioButton6.Enabled = false;
this.radioButton6.Location = new System.Drawing.Point(77, 115);
this.radioButton6.Name = "radioButton6";
this.radioButton6.Size = new System.Drawing.Size(73, 17);
this.radioButton6.TabIndex = 49;
this.radioButton6.TabStop = true;
this.radioButton6.Text = "Mode7Ext";
this.radioButton6.UseVisualStyleBackColor = true;
//
// radioButton1
//
this.radioButton1.AutoSize = true;
this.radioButton1.Enabled = false;
this.radioButton1.Location = new System.Drawing.Point(27, 51);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(46, 17);
this.radioButton1.TabIndex = 19;
this.radioButton1.TabStop = true;
this.radioButton1.Text = "BG1";
this.radioButton1.UseVisualStyleBackColor = true;
//
// radioButton10
//
this.radioButton10.AutoSize = true;
this.radioButton10.Enabled = false;
this.radioButton10.Location = new System.Drawing.Point(77, 67);
this.radioButton10.Name = "radioButton10";
this.radioButton10.Size = new System.Drawing.Size(49, 17);
this.radioButton10.TabIndex = 28;
this.radioButton10.TabStop = true;
this.radioButton10.Text = "4bpp";
this.radioButton10.UseVisualStyleBackColor = true;
//
// radioButton15
//
this.radioButton15.AutoSize = true;
this.radioButton15.Enabled = false;
this.radioButton15.Location = new System.Drawing.Point(77, 99);
this.radioButton15.Name = "radioButton15";
this.radioButton15.Size = new System.Drawing.Size(58, 17);
this.radioButton15.TabIndex = 33;
this.radioButton15.TabStop = true;
this.radioButton15.Text = "Mode7";
this.radioButton15.UseVisualStyleBackColor = true;
//
// radioButton5
//
this.radioButton5.AutoSize = true;
this.radioButton5.Enabled = false;
this.radioButton5.Location = new System.Drawing.Point(77, 51);
this.radioButton5.Name = "radioButton5";
this.radioButton5.Size = new System.Drawing.Size(49, 17);
this.radioButton5.TabIndex = 23;
this.radioButton5.TabStop = true;
this.radioButton5.Text = "2bpp";
this.radioButton5.UseVisualStyleBackColor = true;
//
// radioButton14
//
this.radioButton14.AutoSize = true;
this.radioButton14.Enabled = false;
this.radioButton14.Location = new System.Drawing.Point(27, 116);
this.radioButton14.Name = "radioButton14";
this.radioButton14.Size = new System.Drawing.Size(45, 17);
this.radioButton14.TabIndex = 32;
this.radioButton14.TabStop = true;
this.radioButton14.Text = "OBJ";
this.radioButton14.UseVisualStyleBackColor = true;
//
// radioButton4
//
this.radioButton4.AutoSize = true;
this.radioButton4.Enabled = false;
this.radioButton4.Location = new System.Drawing.Point(27, 99);
this.radioButton4.Name = "radioButton4";
this.radioButton4.Size = new System.Drawing.Size(46, 17);
this.radioButton4.TabIndex = 22;
this.radioButton4.TabStop = true;
this.radioButton4.Text = "BG4";
this.radioButton4.UseVisualStyleBackColor = true;
//
// radioButton3
//
this.radioButton3.AutoSize = true;
this.radioButton3.Enabled = false;
this.radioButton3.Location = new System.Drawing.Point(27, 83);
this.radioButton3.Name = "radioButton3";
this.radioButton3.Size = new System.Drawing.Size(46, 17);
this.radioButton3.TabIndex = 21;
this.radioButton3.TabStop = true;
this.radioButton3.Text = "BG3";
this.radioButton3.UseVisualStyleBackColor = true;
//
// radioButton13
//
this.radioButton13.AutoSize = true;
this.radioButton13.Enabled = false;
this.radioButton13.Location = new System.Drawing.Point(77, 83);
this.radioButton13.Name = "radioButton13";
this.radioButton13.Size = new System.Drawing.Size(49, 17);
this.radioButton13.TabIndex = 31;
this.radioButton13.TabStop = true;
this.radioButton13.Text = "8bpp";
this.radioButton13.UseVisualStyleBackColor = true;
//
// radioButton2
//
this.radioButton2.AutoSize = true;
this.radioButton2.Enabled = false;
this.radioButton2.Location = new System.Drawing.Point(27, 67);
this.radioButton2.Name = "radioButton2";
this.radioButton2.Size = new System.Drawing.Size(46, 17);
this.radioButton2.TabIndex = 20;
this.radioButton2.TabStop = true;
this.radioButton2.Text = "BG2";
this.radioButton2.UseVisualStyleBackColor = true;
//
// comboDisplayType
//
this.comboDisplayType.DisplayMember = "descr";
@ -568,6 +439,7 @@
this.comboPalette.Name = "comboPalette";
this.comboPalette.Size = new System.Drawing.Size(70, 21);
this.comboPalette.TabIndex = 52;
this.toolTip1.SetToolTip(this.comboPalette, resources.GetString("comboPalette.ToolTip"));
this.comboPalette.ValueMember = "type";
this.comboPalette.SelectedIndexChanged += new System.EventHandler(this.comboPalette_SelectedIndexChanged);
//
@ -789,6 +661,145 @@
this.txtOBSELT1OfsBits.TabIndex = 55;
this.txtOBSELT1OfsBits.Text = "00";
//
// groupBox8
//
this.groupBox8.Controls.Add(this.radioButton6);
this.groupBox8.Controls.Add(this.radioButton1);
this.groupBox8.Controls.Add(this.radioButton10);
this.groupBox8.Controls.Add(this.radioButton15);
this.groupBox8.Controls.Add(this.radioButton5);
this.groupBox8.Controls.Add(this.radioButton14);
this.groupBox8.Controls.Add(this.radioButton4);
this.groupBox8.Controls.Add(this.radioButton3);
this.groupBox8.Controls.Add(this.radioButton13);
this.groupBox8.Controls.Add(this.radioButton2);
this.groupBox8.Location = new System.Drawing.Point(273, 247);
this.groupBox8.Name = "groupBox8";
this.groupBox8.Size = new System.Drawing.Size(15, 22);
this.groupBox8.TabIndex = 54;
this.groupBox8.TabStop = false;
this.groupBox8.Text = "groupBox8";
//
// radioButton6
//
this.radioButton6.AutoSize = true;
this.radioButton6.Enabled = false;
this.radioButton6.Location = new System.Drawing.Point(77, 115);
this.radioButton6.Name = "radioButton6";
this.radioButton6.Size = new System.Drawing.Size(73, 17);
this.radioButton6.TabIndex = 49;
this.radioButton6.TabStop = true;
this.radioButton6.Text = "Mode7Ext";
this.radioButton6.UseVisualStyleBackColor = true;
//
// radioButton1
//
this.radioButton1.AutoSize = true;
this.radioButton1.Enabled = false;
this.radioButton1.Location = new System.Drawing.Point(27, 51);
this.radioButton1.Name = "radioButton1";
this.radioButton1.Size = new System.Drawing.Size(46, 17);
this.radioButton1.TabIndex = 19;
this.radioButton1.TabStop = true;
this.radioButton1.Text = "BG1";
this.radioButton1.UseVisualStyleBackColor = true;
//
// radioButton10
//
this.radioButton10.AutoSize = true;
this.radioButton10.Enabled = false;
this.radioButton10.Location = new System.Drawing.Point(77, 67);
this.radioButton10.Name = "radioButton10";
this.radioButton10.Size = new System.Drawing.Size(49, 17);
this.radioButton10.TabIndex = 28;
this.radioButton10.TabStop = true;
this.radioButton10.Text = "4bpp";
this.radioButton10.UseVisualStyleBackColor = true;
//
// radioButton15
//
this.radioButton15.AutoSize = true;
this.radioButton15.Enabled = false;
this.radioButton15.Location = new System.Drawing.Point(77, 99);
this.radioButton15.Name = "radioButton15";
this.radioButton15.Size = new System.Drawing.Size(58, 17);
this.radioButton15.TabIndex = 33;
this.radioButton15.TabStop = true;
this.radioButton15.Text = "Mode7";
this.radioButton15.UseVisualStyleBackColor = true;
//
// radioButton5
//
this.radioButton5.AutoSize = true;
this.radioButton5.Enabled = false;
this.radioButton5.Location = new System.Drawing.Point(77, 51);
this.radioButton5.Name = "radioButton5";
this.radioButton5.Size = new System.Drawing.Size(49, 17);
this.radioButton5.TabIndex = 23;
this.radioButton5.TabStop = true;
this.radioButton5.Text = "2bpp";
this.radioButton5.UseVisualStyleBackColor = true;
//
// radioButton14
//
this.radioButton14.AutoSize = true;
this.radioButton14.Enabled = false;
this.radioButton14.Location = new System.Drawing.Point(27, 116);
this.radioButton14.Name = "radioButton14";
this.radioButton14.Size = new System.Drawing.Size(45, 17);
this.radioButton14.TabIndex = 32;
this.radioButton14.TabStop = true;
this.radioButton14.Text = "OBJ";
this.radioButton14.UseVisualStyleBackColor = true;
//
// radioButton4
//
this.radioButton4.AutoSize = true;
this.radioButton4.Enabled = false;
this.radioButton4.Location = new System.Drawing.Point(27, 99);
this.radioButton4.Name = "radioButton4";
this.radioButton4.Size = new System.Drawing.Size(46, 17);
this.radioButton4.TabIndex = 22;
this.radioButton4.TabStop = true;
this.radioButton4.Text = "BG4";
this.radioButton4.UseVisualStyleBackColor = true;
//
// radioButton3
//
this.radioButton3.AutoSize = true;
this.radioButton3.Enabled = false;
this.radioButton3.Location = new System.Drawing.Point(27, 83);
this.radioButton3.Name = "radioButton3";
this.radioButton3.Size = new System.Drawing.Size(46, 17);
this.radioButton3.TabIndex = 21;
this.radioButton3.TabStop = true;
this.radioButton3.Text = "BG3";
this.radioButton3.UseVisualStyleBackColor = true;
//
// radioButton13
//
this.radioButton13.AutoSize = true;
this.radioButton13.Enabled = false;
this.radioButton13.Location = new System.Drawing.Point(77, 83);
this.radioButton13.Name = "radioButton13";
this.radioButton13.Size = new System.Drawing.Size(49, 17);
this.radioButton13.TabIndex = 31;
this.radioButton13.TabStop = true;
this.radioButton13.Text = "8bpp";
this.radioButton13.UseVisualStyleBackColor = true;
//
// radioButton2
//
this.radioButton2.AutoSize = true;
this.radioButton2.Enabled = false;
this.radioButton2.Location = new System.Drawing.Point(27, 67);
this.radioButton2.Name = "radioButton2";
this.radioButton2.Size = new System.Drawing.Size(46, 17);
this.radioButton2.TabIndex = 20;
this.radioButton2.TabStop = true;
this.radioButton2.Text = "BG2";
this.radioButton2.UseVisualStyleBackColor = true;
//
// label41
//
this.label41.AutoSize = true;
@ -1649,6 +1660,7 @@
//
// groupBox1
//
this.groupBox1.Controls.Add(this.txtBG1MapSizeBytes);
this.groupBox1.Controls.Add(this.txtBGPaletteInfo);
this.groupBox1.Controls.Add(this.rbBG4);
this.groupBox1.Controls.Add(this.rbBG3);
@ -1681,6 +1693,16 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "BG";
//
// txtBG1MapSizeBytes
//
this.txtBG1MapSizeBytes.Location = new System.Drawing.Point(34, 112);
this.txtBG1MapSizeBytes.Multiline = true;
this.txtBG1MapSizeBytes.Name = "txtBG1MapSizeBytes";
this.txtBG1MapSizeBytes.ReadOnly = true;
this.txtBG1MapSizeBytes.Size = new System.Drawing.Size(33, 17);
this.txtBG1MapSizeBytes.TabIndex = 40;
this.txtBG1MapSizeBytes.Text = "(32K)";
//
// txtBGPaletteInfo
//
this.txtBGPaletteInfo.Location = new System.Drawing.Point(5, 181);
@ -1893,7 +1915,7 @@
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(124, 95);
this.label3.Location = new System.Drawing.Point(134, 96);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(32, 13);
this.label3.TabIndex = 7;
@ -1916,9 +1938,9 @@
this.txtBG1SizeInTiles.Multiline = true;
this.txtBG1SizeInTiles.Name = "txtBG1SizeInTiles";
this.txtBG1SizeInTiles.ReadOnly = true;
this.txtBG1SizeInTiles.Size = new System.Drawing.Size(48, 17);
this.txtBG1SizeInTiles.Size = new System.Drawing.Size(59, 17);
this.txtBG1SizeInTiles.TabIndex = 6;
this.txtBG1SizeInTiles.Text = "64x64";
this.txtBG1SizeInTiles.Text = "128x128 (32K)";
//
// label2
//
@ -2196,9 +2218,9 @@
this.txtMapEntryTileAddr.Multiline = true;
this.txtMapEntryTileAddr.Name = "txtMapEntryTileAddr";
this.txtMapEntryTileAddr.ReadOnly = true;
this.txtMapEntryTileAddr.Size = new System.Drawing.Size(42, 18);
this.txtMapEntryTileAddr.Size = new System.Drawing.Size(45, 18);
this.txtMapEntryTileAddr.TabIndex = 57;
this.txtMapEntryTileAddr.Text = "@FFFF";
this.txtMapEntryTileAddr.Text = "@0D00";
//
// txtMapEntryPrio
//
@ -2306,15 +2328,6 @@
this.viewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.viewer_MouseMove);
this.viewer.MouseUp += new System.Windows.Forms.MouseEventHandler(this.viewer_MouseUp);
//
// labelMemory
//
this.labelMemory.AutoSize = true;
this.labelMemory.Location = new System.Drawing.Point(3, 2);
this.labelMemory.Name = "labelMemory";
this.labelMemory.Size = new System.Drawing.Size(176, 13);
this.labelMemory.TabIndex = 1;
this.labelMemory.Text = "Right-click an item to display it here.";
//
// SNESGraphicsDebugger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -2337,8 +2350,6 @@
this.groupFreeze.ResumeLayout(false);
this.pnGroupFreeze.ResumeLayout(false);
this.pnGroupFreeze.PerformLayout();
this.groupBox8.ResumeLayout(false);
this.groupBox8.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudScanline)).EndInit();
@ -2347,6 +2358,8 @@
this.groupBox6.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox8.ResumeLayout(false);
this.groupBox8.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox5.ResumeLayout(false);
@ -2414,7 +2427,6 @@
private System.Windows.Forms.TextBox txtBG1SizeInPixels;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtBG1SCAddrBits;
private System.Windows.Forms.TextBox txtBG1SizeInTiles;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtBG1SizeBits;
private System.Windows.Forms.Label label19;
@ -2554,5 +2566,7 @@
private System.Windows.Forms.RadioButton radioButton2;
private System.Windows.Forms.Panel pnGroupFreeze;
private System.Windows.Forms.Label labelMemory;
private System.Windows.Forms.TextBox txtBG1MapSizeBytes;
private System.Windows.Forms.TextBox txtBG1SizeInTiles;
}
}

View File

@ -4,6 +4,7 @@
//TODO - maybe draw a label (in lieu of above, also) showing what scale the content is at: 2x or 1x or 1/2x
//TODO - add eDisplayType for BG1-Tiles, BG2-Tiles, etc. which show the tiles available to a BG. more concise than viewing all tiles and illustrating the relevant accessible areas
// . could this apply to the palette too?
//TODO - show the priority list for the current mode. make the priority list have checkboxes, and use that to control whether that item displays (does bsnes have that granularity? maybe)
//http://stackoverflow.com/questions/1101149/displaying-thumbnail-icons-128x128-pixels-or-larger-in-a-grid-in-listview
@ -57,9 +58,9 @@ namespace BizHawk.MultiClient
comboDisplayType.SelectedIndex = 0;
var paletteTypeItems = new List<PaletteTypeItem>();
paletteTypeItems.Add(new PaletteTypeItem("BizHawk Palette", SnesColors.ColorType.BizHawk));
paletteTypeItems.Add(new PaletteTypeItem("bsnes Palette", SnesColors.ColorType.BSNES));
paletteTypeItems.Add(new PaletteTypeItem("Snes9X Palette", SnesColors.ColorType.Snes9x));
paletteTypeItems.Add(new PaletteTypeItem("BizHawk", SnesColors.ColorType.BizHawk));
paletteTypeItems.Add(new PaletteTypeItem("bsnes", SnesColors.ColorType.BSNES));
paletteTypeItems.Add(new PaletteTypeItem("Snes9X", SnesColors.ColorType.Snes9x));
suppression = true;
comboPalette.DataSource = paletteTypeItems;
comboPalette.SelectedIndex = 0;
@ -87,13 +88,6 @@ namespace BizHawk.MultiClient
else return bpp.ToString();
}
string FormatScreenSizeInTiles(SNESGraphicsDecoder.ScreenSize screensize)
{
var dims = SNESGraphicsDecoder.SizeInTilesForBGSize(screensize);
int size = dims.Width * dims.Height * 2 / 1024;
return string.Format("{0} ({1}K)", dims, size);
}
string FormatVramAddress(int address)
{
int excess = address & 1023;
@ -179,6 +173,8 @@ namespace BizHawk.MultiClient
SNESGraphicsDecoder gd = new SNESGraphicsDecoder(SnesColors.ColorType.BizHawk);
SNESGraphicsDecoder.ScreenInfo si;
SNESGraphicsDecoder.TileEntry[] map;
SNESGraphicsDecoder.BGMode viewBgMode;
void RegenerateData()
{
@ -234,13 +230,15 @@ namespace BizHawk.MultiClient
txtBG1TSizeDescr.Text = string.Format("{0}x{0}", bg.TileSize);
txtBG1Bpp.Text = FormatBpp(bg.Bpp);
txtBG1SizeBits.Text = bg.SCSIZE.ToString();
txtBG1SizeInTiles.Text = FormatScreenSizeInTiles(bg.ScreenSize);
txtBG1SizeInTiles.Text = bg.ScreenSizeInTiles.ToString();
int size = bg.ScreenSizeInTiles.Width * bg.ScreenSizeInTiles.Height * 2 / 1024;
txtBG1MapSizeBytes.Text = string.Format("({0}K)", size);
txtBG1SCAddrBits.Text = bg.SCADDR.ToString();
txtBG1SCAddrDescr.Text = FormatVramAddress(bg.SCADDR << 9);
txtBG1SCAddrDescr.Text = FormatVramAddress(bg.ScreenAddr);
txtBG1Colors.Text = (1 << bg.Bpp).ToString();
if (bg.Bpp == 8 && si.CGWSEL_DirectColor) txtBG1Colors.Text = "(Direct Color)";
txtBG1TDAddrBits.Text = bg.TDADDR.ToString();
txtBG1TDAddrDescr.Text = FormatVramAddress(bg.TDADDR << 13);
txtBG1TDAddrDescr.Text = FormatVramAddress(bg.TiledataAddr);
if (bg.Bpp != 0)
{
@ -249,9 +247,7 @@ namespace BizHawk.MultiClient
}
else txtBGPaletteInfo.Text = "";
var sizeInPixels = SNESGraphicsDecoder.SizeInTilesForBGSize(bg.ScreenSize);
sizeInPixels.Width *= si.BG[bgnum].TileSize;
sizeInPixels.Height *= si.BG[bgnum].TileSize;
var sizeInPixels = bg.ScreenSizeInPixels;
txtBG1SizeInPixels.Text = string.Format("{0}x{1}", sizeInPixels.Width, sizeInPixels.Height);
checkTMOBJ.Checked = si.OBJ_MainEnabled;
@ -290,7 +286,6 @@ namespace BizHawk.MultiClient
RenderPalette();
RenderTileView();
UpdateColorDetails();
UpdateMapEntryDetails();
}
eDisplayType CurrDisplaySelection { get { return (comboDisplayType.SelectedValue as eDisplayType?).Value; } }
@ -377,12 +372,16 @@ namespace BizHawk.MultiClient
var si = gd.ScanScreenInfo();
var bg = si.BG[bgnum];
map = new SNESGraphicsDecoder.TileEntry[0];
viewBgMode = bg.BGMode;
bool handled = false;
if (bg.Enabled)
{
//TODO - directColor in normal BG renderer
bool DirectColor = si.CGWSEL_DirectColor && bg.Bpp == 8; //any exceptions?
int numPixels = 0;
//TODO - could use BGMode property on BG... too much chaos to deal with it now
if (si.Mode.MODE == 7)
{
bool mode7 = bgnum == 1;
@ -395,6 +394,9 @@ namespace BizHawk.MultiClient
numPixels = 128 * 128 * 8 * 8;
if (DirectColor) gd.DirectColorify(pixelptr, numPixels);
else gd.Paletteize(pixelptr, 0, 0, numPixels);
//get a fake map, since mode7 doesnt really have a map
map = gd.FetchMode7Tilemap();
}
}
else
@ -406,7 +408,7 @@ namespace BizHawk.MultiClient
numPixels = dims.Width * dims.Height;
System.Diagnostics.Debug.Assert(stride / 4 == dims.Width);
var map = gd.FetchTilemap(bg.ScreenAddr, bg.ScreenSize);
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);
@ -689,6 +691,11 @@ namespace BizHawk.MultiClient
int baseTileNum = tiledataBaseAddr / tileSizeBytes;
int tileNum = baseTileNum + currMapEntryState.entry.tilenum;
int addr = tileNum * tileSizeBytes;
//mode7 takes up 128 bytes per tile because its interleaved with the screen data
if (bg.BGModeIsMode7Type)
addr *= 2;
addr &= 0xFFFF;
txtMapEntryTileAddr.Text = "@" + addr.ToHexString(4);
}
@ -860,26 +867,33 @@ namespace BizHawk.MultiClient
public Point Location;
}
MapEntryState currMapEntryState;
int currViewingTile = -1;
int currViewingTileBpp = -1;
int currViewingSprite = -1;
void RenderTileView(bool force=false)
{
//TODO - blech - handle invalid some other way with a dedicated black-setter
bool valid = currViewingTile != -1;
valid |= (currMapEntryState != null);
if (!valid && !force) return;
class TileDataState
{
public eDisplayType Type;
public int Bpp;
public int Tile;
}
TileDataState tileDataState;
void RenderTileView()
{
if (currMapEntryState != 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)
//view a BG tile
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 = currMapEntryState;
var oneTileEntry = new SNESGraphicsDecoder.TileEntry[] { bgs.entry };
if (valid)
if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, currMapEntryState.entry.tilenum, 1);
else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7Ext)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, currMapEntryState.entry.tilenum, 1);
else if (viewBgMode == SNESGraphicsDecoder.BGMode.Mode7DC)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, currMapEntryState.entry.tilenum, 1);
else
{
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);
@ -889,24 +903,48 @@ namespace BizHawk.MultiClient
bmp.UnlockBits(bmpdata);
viewerMapEntryTile.SetBitmap(bmp);
}
else
else if (tileDataState != null)
{
//view a tileset tile
int bpp = currViewingTileBpp;
int bpp = tileDataState.Bpp;
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);
if (tileDataState.Type == eDisplayType.TilesMode7)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, false, 1, tileDataState.Tile, 1);
else if (tileDataState.Type == eDisplayType.TilesMode7Ext)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, true, false, 1, tileDataState.Tile, 1);
else if (tileDataState.Type == eDisplayType.TilesMode7DC)
gd.RenderMode7TilesToScreen((int*)bmpdata.Scan0, bmpdata.Stride / 4, false, true, 1, tileDataState.Tile, 1);
else gd.RenderTilesToScreen((int*)bmpdata.Scan0, 1, 1, bmpdata.Stride / 4, bpp, currPaletteSelection.start, tileDataState.Tile, 1);
bmp.UnlockBits(bmpdata);
viewerTile.SetBitmap(bmp);
}
else
{
var bmp = new Bitmap(8, 8, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
viewerTile.SetBitmap(bmp);
}
}
void HandleTileViewMouseOver(int pxacross, int pxtall, int bpp, int tx, int ty)
{
int tilestride = pxacross / 8;
int tilesTall = pxtall / 8;
if (tx < 0 || ty < 0 || tx >= tilestride || ty >= tilesTall)
return;
tileDataState = new TileDataState();
tileDataState.Bpp = bpp;
tileDataState.Type = CurrDisplaySelection;
tileDataState.Tile = ty * tilestride + tx;
tabctrlDetails.SelectedTab = tpTile;
}
void UpdateViewerMouseover(Point loc)
{
currMapEntryState = null;
currViewingTile = -1;
currViewingTileBpp = -1;
tileDataState = null;
int tx = loc.X / 8;
int ty = loc.Y / 8;
switch (CurrDisplaySelection)
@ -915,12 +953,19 @@ namespace BizHawk.MultiClient
//currViewingSprite = tx + ty * 16;
RenderView();
break;
case eDisplayType.Tiles2bpp:
HandleTileViewMouseOver(512, 512, 2, tx, ty);
break;
case eDisplayType.Tiles4bpp:
currViewingTileBpp = 4;
currViewingTile = ty * 64 + tx;
if (currViewingTile < 0 || currViewingTile >= (8192 / currViewingTileBpp))
currViewingTile = -1;
tabctrlDetails.SelectedTab = tpTile;
HandleTileViewMouseOver(512, 256, 4, tx, ty);
break;
case eDisplayType.Tiles8bpp:
HandleTileViewMouseOver(256, 256, 8, tx, ty);
break;
case eDisplayType.TilesMode7:
case eDisplayType.TilesMode7Ext:
case eDisplayType.TilesMode7DC:
HandleTileViewMouseOver(128, 128, 8, tx, ty);
break;
case eDisplayType.BG1:
case eDisplayType.BG2:
@ -928,7 +973,7 @@ namespace BizHawk.MultiClient
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;
@ -952,7 +997,8 @@ namespace BizHawk.MultiClient
break;
}
RenderTileView(true);
RenderTileView();
UpdateMapEntryDetails();
}
private void viewer_MouseEnter(object sender, EventArgs e)

View File

@ -123,6 +123,14 @@
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>126, 17</value>
</metadata>
<data name="comboPalette.ToolTip" xml:space="preserve">
<value>Colors can be converted from the snes 555 format to PC standard 888 in several ways.
Snes9x really didnt make any effort to make sense;
bsnes seemed to make an effort but didnt make sense to us;
and bizhawk of course makes sense to us.
The different palettes are provided here so that you can achieve uniformity with
old data while using bizhawk to rip art. The differences are slight.</value>
</data>
<data name="checkScanlineControl.ToolTip" xml:space="preserve">
<value>Enable the scanline controls.
Leaving this disabled will be fine for most users and