snes-add scanline render callbacks and add scanline selector to graphics debugger
This commit is contained in:
parent
6f28003f48
commit
03cb238ae3
|
@ -2,7 +2,7 @@
|
|||
|
||||
//TODO
|
||||
//libsnes needs to be modified to support multiple instances - THIS IS NECESSARY - or else loading one game and then another breaks things
|
||||
//rename snes.dll so nobody thinks it's a stock snes.dll (we'll be editing it substantially at some point)
|
||||
// edit - this is a lot of work
|
||||
//wrap dll code around some kind of library-accessing interface so that it doesnt malfunction if the dll is unavailable
|
||||
|
||||
using System;
|
||||
|
@ -17,27 +17,27 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
{
|
||||
public unsafe static class LibsnesDll
|
||||
{
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern string snes_library_id();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int snes_library_revision_major();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int snes_library_revision_minor();
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_init();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_power();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_reset();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_run();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_term();
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_unload_cartridge();
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_load_cartridge_normal(
|
||||
[MarshalAs(UnmanagedType.LPStr)]
|
||||
string rom_xml,
|
||||
|
@ -53,49 +53,53 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
public delegate ushort snes_input_state_t(int port, int device, int index, int id);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void snes_audio_sample_t(ushort left, ushort right);
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void snes_scanlineStart_t(int line);
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_set_video_refresh(snes_video_refresh_t video_refresh);
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_set_input_poll(snes_input_poll_t input_poll);
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_set_input_state(snes_input_state_t input_state);
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_set_audio_sample(snes_audio_sample_t audio_sample);
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_set_scanlineStart(snes_scanlineStart_t scanlineStart);
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static extern bool snes_check_cartridge(
|
||||
[MarshalAs(UnmanagedType.LPArray)] byte[] rom_data,
|
||||
int rom_size);
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static extern SNES_REGION snes_get_region();
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int snes_get_memory_size(SNES_MEMORY id);
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr snes_get_memory_data(SNES_MEMORY id);
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int snes_serialize_size();
|
||||
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool snes_serialize(IntPtr data, int size);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool snes_unserialize(IntPtr data, int size);
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void snes_set_layer_enable(int layer, int priority,
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
bool enable
|
||||
);
|
||||
|
||||
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
[DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int snes_peek_logical_register(SNES_REG reg);
|
||||
|
||||
public enum SNES_REG : int
|
||||
|
@ -180,7 +184,43 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
}
|
||||
}
|
||||
|
||||
public class ScanlineHookManager
|
||||
{
|
||||
public void Register(object tag, Action<int> callback)
|
||||
{
|
||||
var rr = new RegistrationRecord();
|
||||
rr.tag = tag;
|
||||
rr.callback = callback;
|
||||
|
||||
Unregister(tag);
|
||||
records.Add(rr);
|
||||
OnHooksChanged();
|
||||
}
|
||||
|
||||
public int HookCount { get { return records.Count; } }
|
||||
|
||||
public virtual void OnHooksChanged() { }
|
||||
|
||||
public void Unregister(object tag)
|
||||
{
|
||||
records.RemoveAll((r) => r.tag == tag);
|
||||
}
|
||||
|
||||
public void HandleScanline(int scanline)
|
||||
{
|
||||
foreach (var rr in records) rr.callback(scanline);
|
||||
}
|
||||
|
||||
List<RegistrationRecord> records = new List<RegistrationRecord>();
|
||||
|
||||
class RegistrationRecord
|
||||
{
|
||||
public object tag;
|
||||
public int scanline;
|
||||
public Action<int> callback;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe class LibsnesCore : IEmulator, IVideoProvider, ISoundProvider
|
||||
{
|
||||
bool disposed = false;
|
||||
|
@ -195,6 +235,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_poll(null);
|
||||
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(null);
|
||||
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(null);
|
||||
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_scanlineStart(null);
|
||||
|
||||
LibsnesDll.snes_unload_cartridge();
|
||||
LibsnesDll.snes_term();
|
||||
|
@ -205,11 +246,36 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
//that will be necessary to get it saving to disk
|
||||
byte[] disposedSaveRam;
|
||||
|
||||
|
||||
//we can only have one active snes core at a time, due to libsnes being so static.
|
||||
//so we'll track the current one here and detach the previous one whenever a new one is booted up.
|
||||
static LibsnesCore CurrLibsnesCore;
|
||||
|
||||
public class MyScanlineHookManager : ScanlineHookManager
|
||||
{
|
||||
public MyScanlineHookManager(LibsnesCore core)
|
||||
{
|
||||
this.core = core;
|
||||
}
|
||||
LibsnesCore core;
|
||||
|
||||
public override void OnHooksChanged()
|
||||
{
|
||||
core.OnScanlineHooksChanged();
|
||||
}
|
||||
}
|
||||
public MyScanlineHookManager ScanlineHookManager;
|
||||
void OnScanlineHooksChanged()
|
||||
{
|
||||
if (disposed) return;
|
||||
if (ScanlineHookManager.HookCount == 0) LibsnesDll.snes_set_scanlineStart(null);
|
||||
else LibsnesDll.snes_set_scanlineStart(scanlineStart_cb);
|
||||
}
|
||||
|
||||
void snes_scanlineStart(int line)
|
||||
{
|
||||
ScanlineHookManager.HandleScanline(line);
|
||||
}
|
||||
|
||||
public LibsnesCore(byte[] romData)
|
||||
{
|
||||
//attach this core as the current
|
||||
|
@ -217,6 +283,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
CurrLibsnesCore.Dispose();
|
||||
CurrLibsnesCore = this;
|
||||
|
||||
ScanlineHookManager = new MyScanlineHookManager(this);
|
||||
|
||||
LibsnesDll.snes_init();
|
||||
|
||||
vidcb = new LibsnesDll.snes_video_refresh_t(snes_video_refresh);
|
||||
|
@ -231,6 +299,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
soundcb = new LibsnesDll.snes_audio_sample_t(snes_audio_sample);
|
||||
BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(soundcb);
|
||||
|
||||
scanlineStart_cb = new LibsnesDll.snes_scanlineStart_t(snes_scanlineStart);
|
||||
|
||||
// start up audio resampler
|
||||
InitAudio();
|
||||
|
||||
|
@ -253,6 +323,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
LibsnesDll.snes_input_poll_t pollcb;
|
||||
LibsnesDll.snes_input_state_t inputcb;
|
||||
LibsnesDll.snes_audio_sample_t soundcb;
|
||||
LibsnesDll.snes_scanlineStart_t scanlineStart_cb;
|
||||
|
||||
ushort snes_input_state(int port, int device, int index, int id)
|
||||
{
|
||||
|
|
|
@ -245,6 +245,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
{
|
||||
int tileEntry = vram[tidx * 2];
|
||||
int src = tileEntry * 64;
|
||||
if (tileEntry != 0)
|
||||
{
|
||||
int zzz = 9;
|
||||
}
|
||||
for (int py = 0, pix=src; py < 8; py++)
|
||||
{
|
||||
for (int px = 0; px < 8; px++, pix++)
|
||||
|
|
|
@ -2210,7 +2210,11 @@ namespace BizHawk.MultiClient
|
|||
NESNameTableViewer1.UpdateValues();
|
||||
NESPPU1.UpdateValues();
|
||||
PCEBGViewer1.UpdateValues();
|
||||
SNESGraphicsDebugger1.UpdateValues();
|
||||
}
|
||||
|
||||
public void UpdateToolsLoadstate()
|
||||
{
|
||||
SNESGraphicsDebugger1.UpdateToolsLoadstate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2222,6 +2226,7 @@ namespace BizHawk.MultiClient
|
|||
//frame of execution in its list view.
|
||||
LuaConsole1.LuaImp.FrameRegisterAfter();
|
||||
TAStudio1.UpdateValues();
|
||||
SNESGraphicsDebugger1.UpdateToolsAfter();
|
||||
}
|
||||
|
||||
private unsafe Image MakeScreenshotImage()
|
||||
|
@ -2376,6 +2381,7 @@ namespace BizHawk.MultiClient
|
|||
Global.OSD.ClearGUIText();
|
||||
UpdateToolsBefore();
|
||||
UpdateToolsAfter();
|
||||
UpdateToolsLoadstate();
|
||||
Global.OSD.AddMessage("Loaded state: " + name);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
this.saveWindowPositionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.groupBox4 = new System.Windows.Forms.GroupBox();
|
||||
this.radioButton15 = new System.Windows.Forms.RadioButton();
|
||||
this.radioButton14 = new System.Windows.Forms.RadioButton();
|
||||
this.groupBox5 = new System.Windows.Forms.GroupBox();
|
||||
this.tabctrlDetails = new System.Windows.Forms.TabControl();
|
||||
|
@ -111,9 +112,11 @@
|
|||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.label17 = new System.Windows.Forms.Label();
|
||||
this.label18 = new System.Windows.Forms.Label();
|
||||
this.nudScanline = new System.Windows.Forms.NumericUpDown();
|
||||
this.sliderScanline = new System.Windows.Forms.TrackBar();
|
||||
this.label19 = new System.Windows.Forms.Label();
|
||||
this.paletteViewer = new BizHawk.MultiClient.SNESGraphicsViewer();
|
||||
this.viewer = new BizHawk.MultiClient.SNESGraphicsViewer();
|
||||
this.radioButton15 = new System.Windows.Forms.RadioButton();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
|
@ -122,6 +125,8 @@
|
|||
this.groupBox5.SuspendLayout();
|
||||
this.tabctrlDetails.SuspendLayout();
|
||||
this.tpPalette.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudScanline)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.sliderScanline)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
|
@ -136,6 +141,7 @@
|
|||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.rbBG4);
|
||||
this.groupBox1.Controls.Add(this.label18);
|
||||
this.groupBox1.Controls.Add(this.rbBG3);
|
||||
this.groupBox1.Controls.Add(this.rbBG2);
|
||||
this.groupBox1.Controls.Add(this.rbBG1);
|
||||
|
@ -876,6 +882,18 @@
|
|||
this.groupBox4.TabIndex = 35;
|
||||
this.groupBox4.TabStop = false;
|
||||
//
|
||||
// radioButton15
|
||||
//
|
||||
this.radioButton15.AutoSize = true;
|
||||
this.radioButton15.Enabled = false;
|
||||
this.radioButton15.Location = new System.Drawing.Point(169, 83);
|
||||
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;
|
||||
//
|
||||
// radioButton14
|
||||
//
|
||||
this.radioButton14.AutoSize = true;
|
||||
|
@ -891,7 +909,7 @@
|
|||
// groupBox5
|
||||
//
|
||||
this.groupBox5.Controls.Add(this.paletteViewer);
|
||||
this.groupBox5.Location = new System.Drawing.Point(6, 378);
|
||||
this.groupBox5.Location = new System.Drawing.Point(6, 387);
|
||||
this.groupBox5.Name = "groupBox5";
|
||||
this.groupBox5.Size = new System.Drawing.Size(319, 328);
|
||||
this.groupBox5.TabIndex = 36;
|
||||
|
@ -905,7 +923,7 @@
|
|||
this.tabctrlDetails.Location = new System.Drawing.Point(6, 238);
|
||||
this.tabctrlDetails.Name = "tabctrlDetails";
|
||||
this.tabctrlDetails.SelectedIndex = 0;
|
||||
this.tabctrlDetails.Size = new System.Drawing.Size(319, 134);
|
||||
this.tabctrlDetails.Size = new System.Drawing.Size(282, 143);
|
||||
this.tabctrlDetails.TabIndex = 0;
|
||||
//
|
||||
// tpPalette
|
||||
|
@ -922,7 +940,7 @@
|
|||
this.tpPalette.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpPalette.Name = "tpPalette";
|
||||
this.tpPalette.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tpPalette.Size = new System.Drawing.Size(311, 108);
|
||||
this.tpPalette.Size = new System.Drawing.Size(274, 117);
|
||||
this.tpPalette.TabIndex = 0;
|
||||
this.tpPalette.Text = "Palette";
|
||||
this.tpPalette.UseVisualStyleBackColor = true;
|
||||
|
@ -1020,7 +1038,7 @@
|
|||
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage2.Size = new System.Drawing.Size(311, 108);
|
||||
this.tabPage2.Size = new System.Drawing.Size(274, 117);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "tabPage2";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
|
@ -1038,11 +1056,47 @@
|
|||
// label18
|
||||
//
|
||||
this.label18.AutoSize = true;
|
||||
this.label18.Location = new System.Drawing.Point(233, 162);
|
||||
this.label18.Location = new System.Drawing.Point(161, 170);
|
||||
this.label18.Name = "label18";
|
||||
this.label18.Size = new System.Drawing.Size(70, 26);
|
||||
this.label18.Size = new System.Drawing.Size(56, 26);
|
||||
this.label18.TabIndex = 38;
|
||||
this.label18.Text = "Todo: BG pal\r\ninfo";
|
||||
this.label18.Text = "Todo: BG \r\npal info";
|
||||
//
|
||||
// nudScanline
|
||||
//
|
||||
this.nudScanline.Location = new System.Drawing.Point(242, 159);
|
||||
this.nudScanline.Maximum = new decimal(new int[] {
|
||||
224,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudScanline.Name = "nudScanline";
|
||||
this.nudScanline.Size = new System.Drawing.Size(77, 20);
|
||||
this.nudScanline.TabIndex = 39;
|
||||
this.nudScanline.ValueChanged += new System.EventHandler(this.nudScanline_ValueChanged);
|
||||
//
|
||||
// sliderScanline
|
||||
//
|
||||
this.sliderScanline.AutoSize = false;
|
||||
this.sliderScanline.Location = new System.Drawing.Point(294, 180);
|
||||
this.sliderScanline.Maximum = 224;
|
||||
this.sliderScanline.Name = "sliderScanline";
|
||||
this.sliderScanline.Orientation = System.Windows.Forms.Orientation.Vertical;
|
||||
this.sliderScanline.Size = new System.Drawing.Size(30, 210);
|
||||
this.sliderScanline.TabIndex = 40;
|
||||
this.sliderScanline.Text = "label14";
|
||||
this.sliderScanline.TickFrequency = 16;
|
||||
this.sliderScanline.Value = 224;
|
||||
this.sliderScanline.ValueChanged += new System.EventHandler(this.sliderScanline_ValueChanged);
|
||||
//
|
||||
// label19
|
||||
//
|
||||
this.label19.AutoSize = true;
|
||||
this.label19.Location = new System.Drawing.Point(242, 182);
|
||||
this.label19.Name = "label19";
|
||||
this.label19.Size = new System.Drawing.Size(48, 13);
|
||||
this.label19.TabIndex = 41;
|
||||
this.label19.Text = "Scanline";
|
||||
//
|
||||
// paletteViewer
|
||||
//
|
||||
|
@ -1065,24 +1119,14 @@
|
|||
this.viewer.TabIndex = 17;
|
||||
this.viewer.TabStop = false;
|
||||
//
|
||||
// radioButton15
|
||||
//
|
||||
this.radioButton15.AutoSize = true;
|
||||
this.radioButton15.Enabled = false;
|
||||
this.radioButton15.Location = new System.Drawing.Point(169, 83);
|
||||
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;
|
||||
//
|
||||
// SNESGraphicsDebugger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(905, 727);
|
||||
this.Controls.Add(this.label18);
|
||||
this.Controls.Add(this.label19);
|
||||
this.Controls.Add(this.sliderScanline);
|
||||
this.Controls.Add(this.nudScanline);
|
||||
this.Controls.Add(this.label17);
|
||||
this.Controls.Add(this.tabctrlDetails);
|
||||
this.Controls.Add(this.groupBox5);
|
||||
|
@ -1108,6 +1152,8 @@
|
|||
this.tabctrlDetails.ResumeLayout(false);
|
||||
this.tpPalette.ResumeLayout(false);
|
||||
this.tpPalette.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudScanline)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.sliderScanline)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -1201,5 +1247,8 @@
|
|||
private System.Windows.Forms.Label lblDetailsOBJOrBG;
|
||||
private System.Windows.Forms.TextBox txtPaletteDetailsIndexHex;
|
||||
private System.Windows.Forms.RadioButton radioButton15;
|
||||
private System.Windows.Forms.NumericUpDown nudScanline;
|
||||
private System.Windows.Forms.TrackBar sliderScanline;
|
||||
private System.Windows.Forms.Label label19;
|
||||
}
|
||||
}
|
|
@ -27,6 +27,15 @@ namespace BizHawk.MultiClient
|
|||
tabctrlDetails.SelectedIndex = 1;
|
||||
}
|
||||
|
||||
LibsnesCore currentSnesCore;
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
if (currentSnesCore != null)
|
||||
currentSnesCore.ScanlineHookManager.Unregister(this);
|
||||
currentSnesCore = null;
|
||||
}
|
||||
|
||||
string FormatBpp(int bpp)
|
||||
{
|
||||
if (bpp == 0) return "---";
|
||||
|
@ -47,11 +56,57 @@ namespace BizHawk.MultiClient
|
|||
else return string.Format("@{0} ({1}K)", address.ToHexString(4), address / 1024);
|
||||
}
|
||||
|
||||
public void UpdateValues()
|
||||
public void UpdateToolsAfter()
|
||||
{
|
||||
SyncCore();
|
||||
}
|
||||
|
||||
public void UpdateToolsLoadstate()
|
||||
{
|
||||
SyncCore();
|
||||
UpdateValues();
|
||||
}
|
||||
|
||||
private void nudScanline_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (suppression) return;
|
||||
SyncCore();
|
||||
suppression = true;
|
||||
sliderScanline.Value = 224 - (int)nudScanline.Value;
|
||||
suppression = false;
|
||||
}
|
||||
|
||||
private void sliderScanline_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (suppression) return;
|
||||
SyncCore();
|
||||
suppression = true;
|
||||
nudScanline.Value = 224 - sliderScanline.Value;
|
||||
suppression = false;
|
||||
}
|
||||
|
||||
void SyncCore()
|
||||
{
|
||||
LibsnesCore core = Global.Emulator as LibsnesCore;
|
||||
if (currentSnesCore != core && currentSnesCore != null)
|
||||
currentSnesCore.ScanlineHookManager.Unregister(this);
|
||||
|
||||
currentSnesCore = core;
|
||||
|
||||
if(currentSnesCore != null)
|
||||
currentSnesCore.ScanlineHookManager.Register(this, ScanlineHook);
|
||||
}
|
||||
|
||||
void ScanlineHook(int line)
|
||||
{
|
||||
int target = (int)nudScanline.Value;
|
||||
if (target == line) UpdateValues();
|
||||
}
|
||||
|
||||
void UpdateValues()
|
||||
{
|
||||
if (!this.IsHandleCreated || this.IsDisposed) return;
|
||||
var snes = Global.Emulator as LibsnesCore;
|
||||
if (snes == null) return;
|
||||
if (currentSnesCore == null) return;
|
||||
|
||||
var gd = new SNESGraphicsDecoder();
|
||||
var si = gd.ScanScreenInfo();
|
||||
|
@ -315,6 +370,5 @@ namespace BizHawk.MultiClient
|
|||
//cd.ShowDialog(this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ void PPU::scanline() {
|
|||
regs.range_over = false;
|
||||
}
|
||||
|
||||
interface->scanlineStart(line);
|
||||
|
||||
if(line == 1) {
|
||||
//mosaic reset
|
||||
for(int bg = BG1; bg <= BG4; bg++) regs.bg_y[bg] = 1;
|
||||
|
|
|
@ -7,6 +7,9 @@ struct Interface {
|
|||
virtual void message(const string &text);
|
||||
virtual time_t currentTime();
|
||||
virtual time_t randomSeed();
|
||||
|
||||
//zero 27-sep-2012
|
||||
virtual void scanlineStart(int line) = 0;
|
||||
};
|
||||
|
||||
extern Interface *interface;
|
||||
|
|
|
@ -40,6 +40,13 @@ struct Interface : public SNES::Interface {
|
|||
if(paudio_sample) return paudio_sample(left, right);
|
||||
}
|
||||
|
||||
//zero 27-sep-2012
|
||||
snes_scanlineStart_t pScanlineStart;
|
||||
void scanlineStart(int line)
|
||||
{
|
||||
if(pScanlineStart) pScanlineStart((int)line);
|
||||
}
|
||||
|
||||
int16_t inputPoll(bool port, SNES::Input::Device device, unsigned index, unsigned id) {
|
||||
if(pinput_state) return pinput_state(port?1:0, (unsigned)device, index, id);
|
||||
return 0;
|
||||
|
@ -249,6 +256,11 @@ void snes_cheat_set(unsigned index, bool enable, const char *code) {
|
|||
SNES::cheat.synchronize();
|
||||
}
|
||||
|
||||
//zero 21-sep-2012
|
||||
void snes_set_scanlineStart(snes_scanlineStart_t cb)
|
||||
{
|
||||
interface.pScanlineStart = cb;
|
||||
}
|
||||
|
||||
//zero 03-sep-2012
|
||||
bool snes_check_cartridge(const uint8_t *rom_data, unsigned rom_size)
|
||||
|
|
|
@ -131,6 +131,8 @@ unsigned snes_get_memory_size(unsigned id);
|
|||
//zeromus additions
|
||||
bool snes_check_cartridge(const uint8_t *rom_data, unsigned rom_size);
|
||||
void snes_set_layer_enable(int layer, int priority, bool enable);
|
||||
typedef void (*snes_scanlineStart_t)(int);
|
||||
void snes_set_scanlineStart(snes_scanlineStart_t);
|
||||
|
||||
//$2105
|
||||
#define SNES_REG_BG_MODE 0
|
||||
|
|
Loading…
Reference in New Issue