Genesis VDP display. But not as slick as http://www.youtube.com/watch?v=Tsr-XtuKuSw

This commit is contained in:
goyuken 2014-02-19 22:26:33 +00:00
parent 223116252b
commit c14e4239c4
12 changed files with 591 additions and 13 deletions

View File

@ -537,6 +537,12 @@
<Compile Include="tools\Genesis\GenGameGenie.Designer.cs">
<DependentUpon>GenGameGenie.cs</DependentUpon>
</Compile>
<Compile Include="tools\Genesis\VDPViewer.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="tools\Genesis\VDPViewer.Designer.cs">
<DependentUpon>VDPViewer.cs</DependentUpon>
</Compile>
<Compile Include="tools\HexEditor\HexColor.cs">
<SubType>Form</SubType>
</Compile>
@ -1045,6 +1051,9 @@
<EmbeddedResource Include="tools\Genesis\GenGameGenie.resx">
<DependentUpon>GenGameGenie.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="tools\Genesis\VDPViewer.resx">
<DependentUpon>VDPViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="tools\HexEditor\HexColor.resx">
<DependentUpon>HexColor.cs</DependentUpon>
</EmbeddedResource>

View File

@ -223,6 +223,7 @@
this.PCESubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.PCEBGViewerMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.PCEtileViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.codeDataLoggerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator25 = new System.Windows.Forms.ToolStripSeparator();
this.PCEAlwaysPerformSpriteLimitMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.PCEAlwaysEqualizeVolumesMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -343,7 +344,7 @@
this.ClearSRAMContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ShowMenuContextMenuSeparator = new System.Windows.Forms.ToolStripSeparator();
this.ShowMenuContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.codeDataLoggerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.vDPViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.MainformMenu.SuspendLayout();
this.MainStatusBar.SuspendLayout();
this.MainFormContextMenu.SuspendLayout();
@ -2017,6 +2018,13 @@
this.PCEtileViewerToolStripMenuItem.Text = "&Tile Viewer";
this.PCEtileViewerToolStripMenuItem.Click += new System.EventHandler(this.PCEtileViewerToolStripMenuItem_Click);
//
// codeDataLoggerToolStripMenuItem
//
this.codeDataLoggerToolStripMenuItem.Name = "codeDataLoggerToolStripMenuItem";
this.codeDataLoggerToolStripMenuItem.Size = new System.Drawing.Size(240, 22);
this.codeDataLoggerToolStripMenuItem.Text = "Code-Data Logger";
this.codeDataLoggerToolStripMenuItem.Click += new System.EventHandler(this.codeDataLoggerToolStripMenuItem_Click);
//
// toolStripSeparator25
//
this.toolStripSeparator25.Name = "toolStripSeparator25";
@ -2455,14 +2463,15 @@
// DGBsettingsToolStripMenuItem
//
this.DGBsettingsToolStripMenuItem.Name = "DGBsettingsToolStripMenuItem";
this.DGBsettingsToolStripMenuItem.Size = new System.Drawing.Size(125, 22);
this.DGBsettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.DGBsettingsToolStripMenuItem.Text = "Settings...";
this.DGBsettingsToolStripMenuItem.Click += new System.EventHandler(this.DGBsettingsToolStripMenuItem_Click);
//
// GenesisSubMenu
//
this.GenesisSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.GenesisSettingsToolStripMenuItem});
this.GenesisSettingsToolStripMenuItem,
this.vDPViewerToolStripMenuItem});
this.GenesisSubMenu.Name = "GenesisSubMenu";
this.GenesisSubMenu.Size = new System.Drawing.Size(56, 17);
this.GenesisSubMenu.Text = "&Genesis";
@ -2470,8 +2479,8 @@
// GenesisSettingsToolStripMenuItem
//
this.GenesisSettingsToolStripMenuItem.Name = "GenesisSettingsToolStripMenuItem";
this.GenesisSettingsToolStripMenuItem.Size = new System.Drawing.Size(125, 22);
this.GenesisSettingsToolStripMenuItem.Text = "Settings...";
this.GenesisSettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.GenesisSettingsToolStripMenuItem.Text = "&Settings...";
this.GenesisSettingsToolStripMenuItem.Click += new System.EventHandler(this.GenesisSettingsToolStripMenuItem_Click);
//
// HelpSubMenu
@ -2995,12 +3004,12 @@
this.ShowMenuContextMenuItem.Text = "Show Menu";
this.ShowMenuContextMenuItem.Click += new System.EventHandler(this.ShowMenuContextMenuItem_Click);
//
// codeDataLoggerToolStripMenuItem
// vDPViewerToolStripMenuItem
//
this.codeDataLoggerToolStripMenuItem.Name = "codeDataLoggerToolStripMenuItem";
this.codeDataLoggerToolStripMenuItem.Size = new System.Drawing.Size(240, 22);
this.codeDataLoggerToolStripMenuItem.Text = "Code-Data Logger";
this.codeDataLoggerToolStripMenuItem.Click += new System.EventHandler(this.codeDataLoggerToolStripMenuItem_Click);
this.vDPViewerToolStripMenuItem.Name = "vDPViewerToolStripMenuItem";
this.vDPViewerToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.vDPViewerToolStripMenuItem.Text = "&VDP Viewer";
this.vDPViewerToolStripMenuItem.Click += new System.EventHandler(this.vDPViewerToolStripMenuItem_Click);
//
// MainForm
//
@ -3358,6 +3367,7 @@
private System.Windows.Forms.ToolStripMenuItem PCEtileViewerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSVDPViewerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem codeDataLoggerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem vDPViewerToolStripMenuItem;
}
}

View File

@ -3068,5 +3068,10 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.Tools.Load<PCECDL>();
}
private void vDPViewerToolStripMenuItem_Click(object sender, EventArgs e)
{
GlobalWin.Tools.Load<BizHawk.Client.EmuHawk.tools.Genesis.VDPViewer>();
}
}
}

View File

@ -124,7 +124,7 @@
<data name="DisplayConfigMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADr8AAA6/ATgFUyQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NC
YQUAAAAJcEhZcwAADr4AAA6+AepCscAAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjExR/NC
NwAAAaRJREFUOE+dk0FLAlEUhd9/kgwFMUQMhMEIhJLIhVCRDIRhAznEIEYtlBiQYApBSGQw2xhBlhLE
zCLQTa3bt2nd8tR5pFTaLLxwuJd7vgNv3syIv+Xz+fA9TpSX96s0TZsAp+0862fAM3xpN5DNZpHL5VAo
FFAqlVCpVFCtVsEgxZk7emTIMsOsyGQyGAwGM4lZkU6n4bouVg4aCO1cQDGusXbyiA1rIMWZO3pkyEYi

View File

@ -0,0 +1,188 @@
namespace BizHawk.Client.EmuHawk.tools.Genesis
{
partial class VDPViewer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.groupBox5 = new System.Windows.Forms.GroupBox();
this.bmpViewNTB = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewNTA = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewNTW = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewPal = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewTiles = new BizHawk.Client.EmuHawk.BmpView();
this.label1 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
this.groupBox4.SuspendLayout();
this.groupBox5.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.bmpViewTiles);
this.groupBox1.Location = new System.Drawing.Point(12, 555);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(524, 281);
this.groupBox1.TabIndex = 5;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Tiles";
//
// groupBox2
//
this.groupBox2.Controls.Add(this.bmpViewPal);
this.groupBox2.Location = new System.Drawing.Point(12, 842);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(268, 89);
this.groupBox2.TabIndex = 6;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Palettes";
//
// groupBox3
//
this.groupBox3.Controls.Add(this.bmpViewNTW);
this.groupBox3.Location = new System.Drawing.Point(542, 555);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(524, 281);
this.groupBox3.TabIndex = 7;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Window";
//
// groupBox4
//
this.groupBox4.Controls.Add(this.bmpViewNTA);
this.groupBox4.Location = new System.Drawing.Point(12, 12);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(524, 537);
this.groupBox4.TabIndex = 8;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "BG A";
//
// groupBox5
//
this.groupBox5.Controls.Add(this.bmpViewNTB);
this.groupBox5.Location = new System.Drawing.Point(542, 12);
this.groupBox5.Name = "groupBox5";
this.groupBox5.Size = new System.Drawing.Size(524, 537);
this.groupBox5.TabIndex = 9;
this.groupBox5.TabStop = false;
this.groupBox5.Text = "BG B";
//
// bmpViewNTB
//
this.bmpViewNTB.Location = new System.Drawing.Point(6, 19);
this.bmpViewNTB.Name = "bmpViewNTB";
this.bmpViewNTB.Size = new System.Drawing.Size(75, 23);
this.bmpViewNTB.TabIndex = 2;
this.bmpViewNTB.Text = "bmpView1";
//
// bmpViewNTA
//
this.bmpViewNTA.Location = new System.Drawing.Point(6, 19);
this.bmpViewNTA.Name = "bmpViewNTA";
this.bmpViewNTA.Size = new System.Drawing.Size(75, 23);
this.bmpViewNTA.TabIndex = 1;
this.bmpViewNTA.Text = "bmpView1";
//
// bmpViewNTW
//
this.bmpViewNTW.Location = new System.Drawing.Point(6, 19);
this.bmpViewNTW.Name = "bmpViewNTW";
this.bmpViewNTW.Size = new System.Drawing.Size(75, 23);
this.bmpViewNTW.TabIndex = 3;
this.bmpViewNTW.Text = "bmpView1";
//
// bmpViewPal
//
this.bmpViewPal.Location = new System.Drawing.Point(6, 19);
this.bmpViewPal.Name = "bmpViewPal";
this.bmpViewPal.Size = new System.Drawing.Size(256, 64);
this.bmpViewPal.TabIndex = 4;
this.bmpViewPal.Text = "bmpView1";
this.bmpViewPal.MouseClick += new System.Windows.Forms.MouseEventHandler(this.bmpViewPal_MouseClick);
//
// bmpViewTiles
//
this.bmpViewTiles.Location = new System.Drawing.Point(6, 19);
this.bmpViewTiles.Name = "bmpViewTiles";
this.bmpViewTiles.Size = new System.Drawing.Size(512, 256);
this.bmpViewTiles.TabIndex = 0;
this.bmpViewTiles.Text = "bmpView1";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(743, 842);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(323, 13);
this.label1.TabIndex = 10;
this.label1.Text = "CTRL+C copies the pane under the mouse pointer to the clipboard.";
//
// VDPViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1078, 943);
this.Controls.Add(this.label1);
this.Controls.Add(this.groupBox5);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this.groupBox3);
this.KeyPreview = true;
this.Name = "VDPViewer";
this.Text = "VDPViewer";
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.VDPViewer_KeyDown);
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.groupBox3.ResumeLayout(false);
this.groupBox4.ResumeLayout(false);
this.groupBox5.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private BmpView bmpViewTiles;
private BmpView bmpViewNTA;
private BmpView bmpViewNTB;
private BmpView bmpViewNTW;
private BmpView bmpViewPal;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.GroupBox groupBox5;
private System.Windows.Forms.Label label1;
}
}

View File

@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
using System.Drawing.Imaging;
namespace BizHawk.Client.EmuHawk.tools.Genesis
{
public partial class VDPViewer : Form, IToolForm
{
private LibGPGX.VDPView View = new LibGPGX.VDPView();
private GPGX Emu;
int palindex = 0;
public VDPViewer()
{
InitializeComponent();
bmpViewTiles.ChangeBitmapSize(512, 256);
bmpViewPal.ChangeBitmapSize(16, 4);
Restart();
}
unsafe static void DrawTile(int* dest, int pitch, byte* src, int* pal)
{
for (int j = 0; j < 8; j++)
{
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
*dest++ = pal[*src++];
dest += pitch - 8;
}
}
unsafe static void DrawNameTable(LibGPGX.VDPNameTable NT, ushort* vram, byte* tiles, int* pal, BmpView bv)
{
ushort* nametable = vram + NT.Baseaddr / 2;
int tilew = NT.Width;
int tileh = NT.Height;
Size pixsize = new Size(tilew * 8, tileh * 8);
bv.Size = pixsize;
bv.ChangeBitmapSize(pixsize);
var lockdata = bv.bmp.LockBits(new Rectangle(Point.Empty, pixsize), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0;
for (int tiley = 0; tiley < tileh; tiley++)
{
for (int tilex = 0; tilex < tilew; tilex++)
{
ushort bgent = *nametable++;
int palidx = bgent >> 9 & 0x30;
int tileent = bgent & 0x1fff; // h and v flip are stored separately in cache
DrawTile(dest, pitch, tiles + tileent * 64, pal + palidx);
dest += 8;
}
dest -= 8 * tilew;
dest += 8 * pitch;
}
bv.bmp.UnlockBits(lockdata);
bv.Refresh();
}
unsafe void DrawPalettes(int *pal)
{
var lockdata = bmpViewPal.bmp.LockBits(new Rectangle(0, 0, 16, 4), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0;
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 16; i++)
*dest++ = *pal++;
dest += pitch - 16;
}
bmpViewPal.bmp.UnlockBits(lockdata);
bmpViewPal.Refresh();
}
unsafe void DrawTiles()
{
var lockdata = bmpViewTiles.bmp.LockBits(new Rectangle(0, 0, 512, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int pitch = lockdata.Stride / sizeof(int);
int* dest = (int*)lockdata.Scan0;
byte* src = (byte*)View.PatternCache;
int* pal = 0x40 + 0x10 * palindex + (int*)View.ColorCache;
for (int tile = 0; tile < 2048;)
{
DrawTile(dest, pitch, src, pal);
dest += 8;
src += 64;
tile++;
if ((tile & 63) == 0)
dest += 8 * pitch - 512;
}
bmpViewTiles.bmp.UnlockBits(lockdata);
bmpViewTiles.Refresh();
}
public void UpdateValues()
{
if (Emu == null)
return;
Emu.UpdateVDPViewContext(View);
unsafe
{
int* pal = 0x40 + (int*)View.ColorCache;
for (int i = 0; i < 0x40; i++)
pal[i] |= unchecked((int)0xff000000);
DrawPalettes(pal);
DrawTiles();
ushort *VRAMNT = (ushort*)View.VRAM;
byte *tiles = (byte*)View.PatternCache;
DrawNameTable(View.NTA, VRAMNT, tiles, pal, bmpViewNTA);
DrawNameTable(View.NTB, VRAMNT, tiles, pal, bmpViewNTB);
DrawNameTable(View.NTW, VRAMNT, tiles, pal, bmpViewNTW);
}
}
public void Restart()
{
Emu = Global.Emulator as GPGX;
if (Emu == null)
Close();
UpdateValues();
}
public bool AskSave()
{
return true;
}
public bool UpdateBefore
{
get { return true; }
}
private void bmpViewPal_MouseClick(object sender, MouseEventArgs e)
{
int idx = e.Y / 16;
idx = Math.Min(3, Math.Max(idx, 0));
palindex = idx;
DrawTiles();
}
private void VDPViewer_KeyDown(object sender, KeyEventArgs e)
{
if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C)
{
// find the control under the mouse
Point m = Cursor.Position;
Control top = this;
Control found;
do
{
found = top.GetChildAtPoint(top.PointToClient(m));
top = found;
} while (found != null && found.HasChildren);
if (found is BmpView)
{
var bv = found as BmpView;
Clipboard.SetImage(bv.bmp);
}
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -570,6 +570,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
return new List<KeyValuePair<string, int>>();
}
public void UpdateVDPViewContext(LibGPGX.VDPView view)
{
LibGPGX.gpgx_get_vdp_view(view);
}
#endregion
public void Dispose()

View File

@ -232,5 +232,26 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
public cd_read_cb readcallback;
}
[StructLayout(LayoutKind.Sequential)]
public struct VDPNameTable
{
public int Width; // in cells
public int Height; // in cells
public int Baseaddr;
}
[StructLayout(LayoutKind.Sequential)]
public class VDPView
{
public IntPtr VRAM;
public IntPtr PatternCache;
public IntPtr ColorCache;
public VDPNameTable NTA;
public VDPNameTable NTB;
public VDPNameTable NTW;
}
[DllImport("libgenplusgx.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gpgx_get_vdp_view([Out] VDPView view);
}
}

View File

@ -208,6 +208,43 @@ GPGX_EX void gpgx_advance(void)
nsamples = audio_update(soundbuffer);
}
typedef struct
{
uint32 width; // in cells
uint32 height;
uint32 baseaddr;
} nametable_t;
typedef struct
{
uint8 *vram; // 64K vram
uint8 *patterncache; // every pattern, first normal, then hflip, vflip, bothflip
uint32 *colorcache; // 64 colors
nametable_t nta;
nametable_t ntb;
nametable_t ntw;
} vdpview_t;
extern uint8 bg_pattern_cache[];
extern uint32 pixel[];
GPGX_EX void gpgx_get_vdp_view(vdpview_t *view)
{
view->vram = vram;
view->patterncache = bg_pattern_cache;
view->colorcache = pixel + 0x40;
view->nta.width = 1 << (playfield_shift - 1);
view->ntb.width = 1 << (playfield_shift - 1);
view->nta.height = (playfield_row_mask + 1) >> 3;
view->ntb.height = (playfield_row_mask + 1) >> 3;
view->ntw.width = 1 << (5 + (reg[12] & 1));
view->ntw.height = 32;
view->nta.baseaddr = ntab;
view->ntb.baseaddr = ntbb;
view->ntw.baseaddr = ntwb;
}
// internal: computes sram size (no brams)
int saveramsize(void)
{

View File

@ -550,7 +550,7 @@ static const uint32 tms_palette[16] =
#endif
/* Cached and flipped patterns */
static uint8 bg_pattern_cache[0x80000];
uint8 bg_pattern_cache[0x80000];
/* Sprite pattern name offset look-up table (Mode 5) */
static uint8 name_lut[0x400];
@ -562,7 +562,7 @@ static uint32 bp_lut[0x10000];
static uint8 lut[LUT_MAX][LUT_SIZE];
/* Output pixel data look-up tables*/
static PIXEL_OUT_T pixel[0x100];
PIXEL_OUT_T pixel[0x100];
static PIXEL_OUT_T pixel_lut[3][0x200];
static PIXEL_OUT_T pixel_lut_m4[0x40];

Binary file not shown.