2011-03-03 16:38:34 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Windows.Forms;
|
2011-03-09 03:22:38 +00:00
|
|
|
|
using System.Globalization;
|
2013-10-25 00:57:23 +00:00
|
|
|
|
|
|
|
|
|
using BizHawk.Client.Common;
|
2011-03-05 03:03:47 +00:00
|
|
|
|
using BizHawk.Emulation.Consoles.Nintendo;
|
2011-03-03 16:38:34 +00:00
|
|
|
|
|
|
|
|
|
namespace BizHawk.MultiClient
|
|
|
|
|
{
|
2013-11-02 21:31:04 +00:00
|
|
|
|
public partial class NESPPU : Form, IToolForm
|
2011-03-13 01:09:35 +00:00
|
|
|
|
{
|
|
|
|
|
//TODO:
|
2011-08-29 00:05:32 +00:00
|
|
|
|
//If 8/16 sprite mode, mouse over should put 32x64 version of prite
|
2011-08-28 20:43:25 +00:00
|
|
|
|
//Speedups
|
|
|
|
|
//Smarter refreshing? only refresh when things of changed, perhaps peek at the ppu to when the pattern table has changed, or sprites have moved
|
|
|
|
|
//Maybe 48 individual bitmaps for sprites is faster than the overhead of redrawing all that transparent space
|
2011-03-13 01:09:35 +00:00
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
private Bitmap ZoomBoxDefaultImage = new Bitmap(64, 64);
|
|
|
|
|
private NES _nes;
|
|
|
|
|
private readonly byte[] PPUBus = new byte[0x2000];
|
|
|
|
|
private readonly byte[] PPUBusprev = new byte[0x2000];
|
|
|
|
|
private readonly byte[] PALRAM = new byte[0x20];
|
|
|
|
|
private readonly byte[] PALRAMprev = new byte[0x20];
|
|
|
|
|
private readonly NES.PPU.DebugCallback Callback = new NES.PPU.DebugCallback();
|
|
|
|
|
private bool ForceChange;
|
2011-06-10 07:43:48 +00:00
|
|
|
|
|
2013-11-02 21:31:04 +00:00
|
|
|
|
public bool AskSave() { return true; }
|
|
|
|
|
public bool UpdateBefore { get { return true; } }
|
|
|
|
|
|
2011-03-13 01:09:35 +00:00
|
|
|
|
public NESPPU()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
Closing += (o, e) => SaveConfigSettings();
|
2011-06-10 07:43:48 +00:00
|
|
|
|
Callback.Callback = () => Generate();
|
2011-09-04 16:56:56 +00:00
|
|
|
|
for (int x = 0; x < 0x2000; x++)
|
|
|
|
|
{
|
|
|
|
|
PPUBus[x] = 0;
|
|
|
|
|
PPUBusprev[x] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < 0x20; x++)
|
|
|
|
|
{
|
|
|
|
|
PALRAM[x] = 0;
|
|
|
|
|
PALRAMprev[x] = 0;
|
|
|
|
|
}
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SaveConfigSettings()
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
Global.Config.NESPPUWndx = Location.X;
|
|
|
|
|
Global.Config.NESPPUWndy = Location.Y;
|
2011-08-28 18:49:03 +00:00
|
|
|
|
Global.Config.NESPPURefreshRate = RefreshRate.Value;
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Restart()
|
|
|
|
|
{
|
2013-11-02 21:31:04 +00:00
|
|
|
|
if (Global.Emulator is NES)
|
|
|
|
|
{
|
|
|
|
|
_nes = Global.Emulator as NES;
|
|
|
|
|
Generate(true);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LoadConfigSettings()
|
|
|
|
|
{
|
2011-04-06 23:25:53 +00:00
|
|
|
|
if (Global.Config.NESPPUSaveWindowPosition && Global.Config.NESPPUWndx >= 0 && Global.Config.NESPPUWndy >= 0)
|
2011-03-13 01:09:35 +00:00
|
|
|
|
Location = new Point(Global.Config.NESPPUWndx, Global.Config.NESPPUWndy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private byte GetBit(int address, int bit)
|
|
|
|
|
{
|
2011-09-04 16:29:48 +00:00
|
|
|
|
return (byte)(((PPUBus[address] >> (7 - bit)) & 1));
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
2013-04-15 02:14:14 +00:00
|
|
|
|
|
|
|
|
|
private bool CheckChange()
|
2011-03-13 01:09:35 +00:00
|
|
|
|
{
|
2012-10-10 05:06:14 +00:00
|
|
|
|
bool changed = false;
|
|
|
|
|
for (int x = 0; x < 0x20; x++)
|
2011-08-28 18:49:03 +00:00
|
|
|
|
{
|
2012-10-10 05:06:14 +00:00
|
|
|
|
PALRAMprev[x] = PALRAM[x];
|
2013-04-15 02:14:14 +00:00
|
|
|
|
PALRAM[x] = _nes.ppu.PALRAM[x];
|
2012-10-10 05:06:14 +00:00
|
|
|
|
if (PALRAM[x] != PALRAMprev[x])
|
2011-09-04 16:13:44 +00:00
|
|
|
|
{
|
2012-10-10 05:06:14 +00:00
|
|
|
|
changed = true;
|
2012-08-12 19:42:00 +00:00
|
|
|
|
}
|
2012-10-10 05:06:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int x = 0; x < 0x2000; x++)
|
|
|
|
|
{
|
|
|
|
|
PPUBusprev[x] = PPUBus[x];
|
2013-04-15 02:14:14 +00:00
|
|
|
|
PPUBus[x] = _nes.ppu.ppubus_peek(x);
|
2012-10-10 05:06:14 +00:00
|
|
|
|
if (PPUBus[x] != PPUBusprev[x])
|
2012-08-12 19:42:00 +00:00
|
|
|
|
{
|
2012-10-10 05:06:14 +00:00
|
|
|
|
changed = true;
|
2011-09-04 16:13:44 +00:00
|
|
|
|
}
|
2012-10-10 05:06:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ForceChange) return true;
|
|
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe void Generate(bool now = false)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if (!IsHandleCreated || IsDisposed) return;
|
2012-10-10 05:06:14 +00:00
|
|
|
|
|
2013-10-20 18:02:43 +00:00
|
|
|
|
if (Global.Emulator.Frame % RefreshRate.Value == 0 || now)
|
2012-10-10 05:06:14 +00:00
|
|
|
|
{
|
|
|
|
|
bool Changed = CheckChange();
|
2011-09-04 16:13:44 +00:00
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int b0;
|
|
|
|
|
int b1;
|
2011-08-28 18:49:03 +00:00
|
|
|
|
byte value;
|
|
|
|
|
int cvalue;
|
|
|
|
|
|
2011-09-04 16:56:56 +00:00
|
|
|
|
if (Changed)
|
2011-06-10 07:43:48 +00:00
|
|
|
|
{
|
2012-10-10 05:06:14 +00:00
|
|
|
|
ForceChange = false;
|
|
|
|
|
|
2011-09-04 16:56:56 +00:00
|
|
|
|
//Pattern Viewer
|
|
|
|
|
for (int x = 0; x < 16; x++)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
PaletteView.BgPalettesPrev[x].Value = PaletteView.BgPalettes[x].Value;
|
|
|
|
|
PaletteView.SpritePalettesPrev[x].Value = PaletteView.SpritePalettes[x].Value;
|
|
|
|
|
PaletteView.BgPalettes[x].Value = _nes.LookupColor(_nes.ppu.PALRAM[PaletteView.BgPalettes[x].Address]);
|
|
|
|
|
PaletteView.SpritePalettes[x].Value = _nes.LookupColor(_nes.ppu.PALRAM[PaletteView.SpritePalettes[x].Address]);
|
2011-09-04 16:56:56 +00:00
|
|
|
|
}
|
|
|
|
|
if (PaletteView.HasChanged())
|
2012-08-12 19:42:00 +00:00
|
|
|
|
{
|
2011-09-04 16:56:56 +00:00
|
|
|
|
PaletteView.Refresh();
|
2012-08-12 19:42:00 +00:00
|
|
|
|
}
|
2011-08-28 18:49:03 +00:00
|
|
|
|
|
2011-09-04 16:56:56 +00:00
|
|
|
|
System.Drawing.Imaging.BitmapData bmpdata = PatternView.pattern.LockBits(new Rectangle(new Point(0, 0), PatternView.pattern.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
|
|
|
int* framebuf = (int*)bmpdata.Scan0.ToPointer();
|
|
|
|
|
for (int z = 0; z < 2; z++)
|
2011-06-10 07:43:48 +00:00
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int pal;
|
2011-09-04 16:56:56 +00:00
|
|
|
|
if (z == 0)
|
|
|
|
|
pal = PatternView.Pal0;
|
|
|
|
|
else
|
|
|
|
|
pal = PatternView.Pal1;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++)
|
2011-06-10 07:43:48 +00:00
|
|
|
|
{
|
2011-09-04 16:56:56 +00:00
|
|
|
|
for (int j = 0; j < 16; j++)
|
2011-06-10 07:43:48 +00:00
|
|
|
|
{
|
2011-09-04 16:56:56 +00:00
|
|
|
|
for (int x = 0; x < 8; x++)
|
2011-08-28 18:49:03 +00:00
|
|
|
|
{
|
2011-09-04 16:56:56 +00:00
|
|
|
|
for (int y = 0; y < 8; y++)
|
|
|
|
|
{
|
2012-08-12 19:42:00 +00:00
|
|
|
|
int address = (z << 12) + (i << 8) + (j << 4) + y;
|
|
|
|
|
b0 = (byte)(((PPUBus[address] >> (7 - x)) & 1));
|
|
|
|
|
b1 = (byte)(((PPUBus[address + 8] >> (7 - x)) & 1));
|
2011-09-04 16:56:56 +00:00
|
|
|
|
|
|
|
|
|
value = (byte)(b0 + (b1 << 1));
|
2013-04-15 02:14:14 +00:00
|
|
|
|
cvalue = _nes.LookupColor(_nes.ppu.PALRAM[value + (pal << 2)]);
|
2012-08-11 22:32:52 +00:00
|
|
|
|
int adr = (x + (j << 3)) + (y + (i << 3)) * (bmpdata.Stride >> 2);
|
|
|
|
|
framebuf[adr + (z << 7)] = cvalue;
|
2011-09-04 16:56:56 +00:00
|
|
|
|
}
|
2011-08-28 18:49:03 +00:00
|
|
|
|
}
|
2011-06-10 07:43:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-09-04 16:56:56 +00:00
|
|
|
|
PatternView.pattern.UnlockBits(bmpdata);
|
|
|
|
|
PatternView.Refresh();
|
2011-06-10 07:43:48 +00:00
|
|
|
|
}
|
2011-08-28 16:36:50 +00:00
|
|
|
|
|
2011-08-28 18:49:03 +00:00
|
|
|
|
System.Drawing.Imaging.BitmapData bmpdata2 = SpriteView.sprites.LockBits(new Rectangle(new Point(0, 0), SpriteView.sprites.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
|
|
|
int* framebuf2 = (int*)bmpdata2.Scan0.ToPointer();
|
2011-08-28 21:10:21 +00:00
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int pt_add = _nes.ppu.reg_2000.obj_pattern_hi ? 0x1000 : 0;
|
|
|
|
|
bool is8x16 = _nes.ppu.reg_2000.obj_size_16;
|
2011-08-28 16:36:50 +00:00
|
|
|
|
|
2011-09-04 16:56:56 +00:00
|
|
|
|
|
2011-08-28 18:49:03 +00:00
|
|
|
|
//Sprite Viewer
|
|
|
|
|
for (int n = 0; n < 4; n++)
|
2011-07-16 18:16:21 +00:00
|
|
|
|
{
|
2011-08-28 18:49:03 +00:00
|
|
|
|
for (int r = 0; r < 16; r++)
|
2011-07-16 18:16:21 +00:00
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int BaseAddr = (r << 2) + (n << 6);
|
|
|
|
|
int TileNum = _nes.ppu.OAM[BaseAddr + 1];
|
|
|
|
|
int PatAddr;
|
2011-08-28 21:10:21 +00:00
|
|
|
|
|
|
|
|
|
if (is8x16)
|
|
|
|
|
{
|
|
|
|
|
PatAddr = ((TileNum >> 1) * 0x20);
|
|
|
|
|
PatAddr += (0x1000 * (TileNum & 1));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PatAddr = TileNum * 0x10;
|
|
|
|
|
PatAddr += pt_add;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int Attributes = _nes.ppu.OAM[BaseAddr + 2];
|
|
|
|
|
int Palette = Attributes & 0x03;
|
2012-08-12 00:00:57 +00:00
|
|
|
|
|
2011-08-28 18:49:03 +00:00
|
|
|
|
for (int x = 0; x < 8; x++)
|
2011-08-28 16:36:50 +00:00
|
|
|
|
{
|
2011-08-28 18:49:03 +00:00
|
|
|
|
for (int y = 0; y < 8; y++)
|
|
|
|
|
{
|
2012-08-12 19:42:00 +00:00
|
|
|
|
int address = PatAddr + y;
|
|
|
|
|
b0 = (byte)(((PPUBus[address] >> (7 - x)) & 1));
|
|
|
|
|
b1 = (byte)(((PPUBus[address + 8] >> (7 - x)) & 1));
|
2011-08-28 18:49:03 +00:00
|
|
|
|
value = (byte)(b0 + (b1 << 1));
|
2013-04-15 02:14:14 +00:00
|
|
|
|
cvalue = _nes.LookupColor(_nes.ppu.PALRAM[16 + value + (Palette << 2)]);
|
2011-08-28 18:49:03 +00:00
|
|
|
|
|
2012-08-12 00:00:57 +00:00
|
|
|
|
int adr = (x + (r * 16)) + (y + (n * 24)) * (bmpdata2.Stride >> 2);
|
2011-09-04 16:29:48 +00:00
|
|
|
|
framebuf2[adr] = cvalue;
|
2011-08-28 18:49:03 +00:00
|
|
|
|
}
|
2011-08-28 21:10:21 +00:00
|
|
|
|
if (is8x16)
|
|
|
|
|
{
|
|
|
|
|
PatAddr += 0x10;
|
|
|
|
|
for (int y = 0; y < 8; y++)
|
|
|
|
|
{
|
2012-08-12 19:42:00 +00:00
|
|
|
|
int address = PatAddr + y;
|
|
|
|
|
b0 = (byte)(((PPUBus[address] >> (7 - x)) & 1));
|
|
|
|
|
b1 = (byte)(((PPUBus[address + 8] >> (7 - x)) & 1));
|
2011-08-28 21:10:21 +00:00
|
|
|
|
value = (byte)(b0 + (b1 << 1));
|
2013-04-15 02:14:14 +00:00
|
|
|
|
cvalue = _nes.LookupColor(_nes.ppu.PALRAM[16 + value + (Palette << 2)]);
|
2011-08-28 21:10:21 +00:00
|
|
|
|
|
2012-08-12 00:00:57 +00:00
|
|
|
|
int adr = (x + (r << 4)) + ((y+8) + (n * 24)) * (bmpdata2.Stride >> 2);
|
2011-09-04 16:29:48 +00:00
|
|
|
|
framebuf2[adr] = cvalue;
|
2011-08-28 21:10:21 +00:00
|
|
|
|
}
|
|
|
|
|
PatAddr -= 0x10;
|
|
|
|
|
}
|
2011-08-28 16:36:50 +00:00
|
|
|
|
}
|
2011-08-28 18:49:03 +00:00
|
|
|
|
}
|
2011-07-16 18:16:21 +00:00
|
|
|
|
}
|
2011-08-28 18:49:03 +00:00
|
|
|
|
SpriteView.sprites.UnlockBits(bmpdata2);
|
|
|
|
|
SpriteView.Refresh();
|
2011-07-16 18:16:21 +00:00
|
|
|
|
}
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
public void UpdateValues()
|
2011-06-10 07:43:48 +00:00
|
|
|
|
{
|
2013-11-02 21:31:04 +00:00
|
|
|
|
if (Global.Emulator is NES)
|
|
|
|
|
{
|
|
|
|
|
_nes.ppu.PPUViewCallback = Callback;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
2011-06-10 07:43:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-07 15:54:29 +00:00
|
|
|
|
private void NESPPU_Load(object sender, EventArgs e)
|
2011-03-13 01:09:35 +00:00
|
|
|
|
{
|
|
|
|
|
LoadConfigSettings();
|
2013-10-20 18:02:43 +00:00
|
|
|
|
_nes = Global.Emulator as NES;
|
2011-03-13 01:09:35 +00:00
|
|
|
|
ClearDetails();
|
2011-08-28 18:49:03 +00:00
|
|
|
|
RefreshRate.Value = Global.Config.NESPPURefreshRate;
|
2012-08-12 02:21:53 +00:00
|
|
|
|
Generate(true);
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearDetails()
|
|
|
|
|
{
|
2011-08-28 17:38:33 +00:00
|
|
|
|
DetailsBox.Text = "Details";
|
2011-03-13 01:09:35 +00:00
|
|
|
|
AddressLabel.Text = "";
|
|
|
|
|
ValueLabel.Text = "";
|
2011-08-07 15:54:29 +00:00
|
|
|
|
Value2Label.Text = "";
|
2011-08-28 17:38:33 +00:00
|
|
|
|
Value3Label.Text = "";
|
2011-08-28 17:59:53 +00:00
|
|
|
|
Value4Label.Text = "";
|
|
|
|
|
Value5Label.Text = "";
|
|
|
|
|
ZoomBox.Image = ZoomBoxDefaultImage;
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PaletteView_MouseLeave(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ClearDetails();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PaletteView_MouseEnter(object sender, EventArgs e)
|
|
|
|
|
{
|
2011-08-28 17:38:33 +00:00
|
|
|
|
DetailsBox.Text = "Details - Palettes";
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PaletteView_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
int baseAddr = 0x3F00;
|
|
|
|
|
if (e.Y > 16)
|
|
|
|
|
baseAddr += 16;
|
|
|
|
|
int column = (e.X - PaletteView.Location.X) / 16;
|
|
|
|
|
int addr = column + baseAddr;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
AddressLabel.Text = "Address: 0x" + String.Format("{0:X4}", addr);
|
2011-03-13 01:09:35 +00:00
|
|
|
|
int val;
|
2011-08-28 23:51:45 +00:00
|
|
|
|
int offset = addr & 0x03;
|
2011-08-28 17:38:33 +00:00
|
|
|
|
|
|
|
|
|
Bitmap bmp = new Bitmap(64, 64);
|
|
|
|
|
Graphics g= Graphics.FromImage(bmp);
|
2011-08-28 23:51:45 +00:00
|
|
|
|
|
2011-08-28 17:38:33 +00:00
|
|
|
|
if (baseAddr == 0x3F00)
|
2011-08-28 23:51:45 +00:00
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
val = _nes.ppu.PALRAM[PaletteView.BgPalettes[column].Address];
|
2011-08-28 23:51:45 +00:00
|
|
|
|
ValueLabel.Text = "ID: BG" + (column / 4).ToString();
|
2013-04-15 02:14:14 +00:00
|
|
|
|
g.FillRectangle(new SolidBrush(PaletteView.BgPalettes[column].Color), 0, 0, 64, 64);
|
2011-08-28 23:51:45 +00:00
|
|
|
|
}
|
2011-08-28 17:38:33 +00:00
|
|
|
|
else
|
2011-08-28 23:51:45 +00:00
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
val = _nes.ppu.PALRAM[PaletteView.SpritePalettes[column].Address];
|
2011-08-28 23:51:45 +00:00
|
|
|
|
ValueLabel.Text = "ID: SPR" + (column / 4).ToString();
|
2013-04-15 02:14:14 +00:00
|
|
|
|
g.FillRectangle(new SolidBrush(PaletteView.SpritePalettes[column].Color), 0, 0, 64, 64);
|
2011-08-28 23:51:45 +00:00
|
|
|
|
}
|
2011-08-28 17:38:33 +00:00
|
|
|
|
g.Dispose();
|
2011-08-28 23:51:45 +00:00
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
Value3Label.Text = "Color: 0x" + String.Format("{0:X2}", val);
|
2011-08-28 23:51:45 +00:00
|
|
|
|
Value4Label.Text = "Offset: " + offset.ToString();
|
2011-08-28 17:38:33 +00:00
|
|
|
|
ZoomBox.Image = bmp;
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void autoloadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Global.Config.AutoLoadNESPPU ^= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void saveWindowPositionToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Global.Config.NESPPUSaveWindowPosition ^= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void toolStripDropDownButton1_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
2011-09-11 01:21:10 +00:00
|
|
|
|
autoLoadToolStripMenuItem1.Checked = Global.Config.AutoLoadNESPPU;
|
|
|
|
|
saveWindowPositionToolStripMenuItem1.Checked = Global.Config.NESPPUSaveWindowPosition;
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
2011-03-13 01:49:10 +00:00
|
|
|
|
|
2011-08-07 15:54:29 +00:00
|
|
|
|
private void PatternView_Click(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2011-08-28 17:59:53 +00:00
|
|
|
|
if (e.Button == MouseButtons.Left)
|
2011-08-07 15:54:29 +00:00
|
|
|
|
{
|
2011-08-28 17:59:53 +00:00
|
|
|
|
if (e.X < PatternView.Width / 2)
|
|
|
|
|
{
|
|
|
|
|
PatternView.Pal0++;
|
|
|
|
|
if (PatternView.Pal0 > 7) PatternView.Pal0 = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
PatternView.Pal1++;
|
|
|
|
|
if (PatternView.Pal1 > 7) PatternView.Pal1 = 0;
|
|
|
|
|
}
|
2012-10-10 05:06:14 +00:00
|
|
|
|
UpdatePaletteSelection();
|
2011-08-07 15:54:29 +00:00
|
|
|
|
}
|
2013-04-15 02:14:14 +00:00
|
|
|
|
HandleDefaultImage();
|
2011-08-07 15:54:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-10-10 05:06:14 +00:00
|
|
|
|
private void UpdatePaletteSelection()
|
2011-08-07 15:54:29 +00:00
|
|
|
|
{
|
2012-10-10 05:06:14 +00:00
|
|
|
|
ForceChange = true;
|
2011-08-07 15:54:29 +00:00
|
|
|
|
Table0PaletteLabel.Text = "Palette: " + PatternView.Pal0;
|
|
|
|
|
Table1PaletteLabel.Text = "Palette: " + PatternView.Pal1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PatternView_MouseEnter(object sender, EventArgs e)
|
|
|
|
|
{
|
2011-08-28 17:38:33 +00:00
|
|
|
|
DetailsBox.Text = "Details - Patterns";
|
2011-08-07 15:54:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PatternView_MouseLeave(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ClearDetails();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PatternView_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
int table = 0;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int address;
|
|
|
|
|
int tile;
|
2011-08-07 15:54:29 +00:00
|
|
|
|
if (e.X > PatternView.Width / 2)
|
|
|
|
|
table = 1;
|
|
|
|
|
|
|
|
|
|
if (table == 0)
|
|
|
|
|
{
|
2011-08-29 00:05:32 +00:00
|
|
|
|
tile = (e.X - 1) / 8;
|
|
|
|
|
address = tile * 16;
|
2011-08-07 15:54:29 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tile = (e.X - 128) / 8;
|
2011-08-29 00:05:32 +00:00
|
|
|
|
address = 0x1000 + (tile * 16);
|
|
|
|
|
|
2011-08-07 15:54:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
address += (e.Y / 8) * 256;
|
|
|
|
|
tile += (e.Y / 8) * 16;
|
2011-08-28 23:51:45 +00:00
|
|
|
|
string Usage = "Usage: ";
|
2011-08-07 15:54:29 +00:00
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if ((_nes.ppu.reg_2000.Value & 0x10) << 4 == ((address >> 4) & 0x100))
|
2011-08-28 23:51:45 +00:00
|
|
|
|
Usage = "BG";
|
2013-04-15 02:14:14 +00:00
|
|
|
|
else if (((_nes.ppu.reg_2000.Value & 0x08) << 5) == ((address >> 4) & 0x100))
|
2011-08-28 23:51:45 +00:00
|
|
|
|
Usage = "SPR";
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if ((_nes.ppu.reg_2000.Value & 0x20) > 0)
|
2011-08-28 23:51:45 +00:00
|
|
|
|
Usage += " (SPR16)";
|
|
|
|
|
|
2011-08-07 15:54:29 +00:00
|
|
|
|
AddressLabel.Text = "Address: " + String.Format("{0:X4}", address);
|
|
|
|
|
ValueLabel.Text = "Table " + table.ToString();
|
2011-08-28 23:51:45 +00:00
|
|
|
|
Value3Label.Text = "Tile " + String.Format("{0:X2}", tile);
|
|
|
|
|
Value4Label.Text = Usage;
|
2011-08-28 17:38:33 +00:00
|
|
|
|
|
2011-08-29 00:28:17 +00:00
|
|
|
|
ZoomBox.Image = Section(PatternView.pattern, new Rectangle(new Point((e.X / 8) * 8, (e.Y / 8) * 8), new Size(8, 8)), false);
|
2011-08-28 17:38:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-29 00:28:17 +00:00
|
|
|
|
static public Bitmap Section(Bitmap srcBitmap, Rectangle section, bool Is8x16)
|
2011-08-28 17:38:33 +00:00
|
|
|
|
{
|
|
|
|
|
// Create the new bitmap and associated graphics object
|
|
|
|
|
Bitmap bmp = new Bitmap(64, 64);
|
|
|
|
|
Graphics g = Graphics.FromImage(bmp);
|
|
|
|
|
|
|
|
|
|
// Draw the specified section of the source bitmap to the new one
|
|
|
|
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
|
|
|
|
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
|
2011-08-29 00:28:17 +00:00
|
|
|
|
Rectangle rect;
|
|
|
|
|
if (Is8x16)
|
|
|
|
|
rect = new Rectangle(0, 0, 32, 64);
|
|
|
|
|
else
|
|
|
|
|
rect = new Rectangle(0, 0, 64, 64);
|
|
|
|
|
g.DrawImage(srcBitmap, rect, section, GraphicsUnit.Pixel);
|
2011-08-28 17:38:33 +00:00
|
|
|
|
g.Dispose();
|
|
|
|
|
|
|
|
|
|
// Return the bitmap
|
|
|
|
|
return bmp;
|
2011-08-07 15:54:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void toolStripDropDownButton2_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Table0P0.Checked = false;
|
|
|
|
|
Table0P1.Checked = false;
|
|
|
|
|
Table0P2.Checked = false;
|
|
|
|
|
Table0P3.Checked = false;
|
|
|
|
|
Table0P4.Checked = false;
|
|
|
|
|
Table0P5.Checked = false;
|
|
|
|
|
Table0P6.Checked = false;
|
|
|
|
|
Table0P7.Checked = false;
|
|
|
|
|
Table1P0.Checked = false;
|
|
|
|
|
Table1P1.Checked = false;
|
|
|
|
|
Table1P2.Checked = false;
|
|
|
|
|
Table1P3.Checked = false;
|
|
|
|
|
Table1P4.Checked = false;
|
|
|
|
|
Table1P5.Checked = false;
|
|
|
|
|
Table1P6.Checked = false;
|
|
|
|
|
Table1P7.Checked = false;
|
|
|
|
|
|
|
|
|
|
Table0P0.Checked = false;
|
|
|
|
|
|
|
|
|
|
switch (PatternView.Pal0)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
Table0P0.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
Table0P1.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
Table0P2.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
Table0P3.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
Table0P4.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
Table0P5.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
Table0P6.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
Table0P7.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (PatternView.Pal1)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
Table1P0.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
Table1P1.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
Table1P2.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
Table1P3.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
Table1P4.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
Table1P5.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
Table1P6.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
Table1P7.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Palette_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (sender == Table0P0) PatternView.Pal0 = 0;
|
|
|
|
|
if (sender == Table0P1) PatternView.Pal0 = 1;
|
|
|
|
|
if (sender == Table0P2) PatternView.Pal0 = 2;
|
|
|
|
|
if (sender == Table0P3) PatternView.Pal0 = 3;
|
|
|
|
|
if (sender == Table0P4) PatternView.Pal0 = 4;
|
|
|
|
|
if (sender == Table0P5) PatternView.Pal0 = 5;
|
|
|
|
|
if (sender == Table0P6) PatternView.Pal0 = 6;
|
|
|
|
|
if (sender == Table0P7) PatternView.Pal0 = 7;
|
|
|
|
|
|
|
|
|
|
if (sender == Table1P0) PatternView.Pal1 = 0;
|
|
|
|
|
if (sender == Table1P1) PatternView.Pal1 = 1;
|
|
|
|
|
if (sender == Table1P2) PatternView.Pal1 = 2;
|
|
|
|
|
if (sender == Table1P3) PatternView.Pal1 = 3;
|
|
|
|
|
if (sender == Table1P4) PatternView.Pal1 = 4;
|
|
|
|
|
if (sender == Table1P5) PatternView.Pal1 = 5;
|
|
|
|
|
if (sender == Table1P6) PatternView.Pal1 = 6;
|
|
|
|
|
if (sender == Table1P7) PatternView.Pal1 = 7;
|
|
|
|
|
|
2012-10-10 05:06:14 +00:00
|
|
|
|
UpdatePaletteSelection();
|
2011-08-07 15:54:29 +00:00
|
|
|
|
}
|
2011-06-10 07:43:48 +00:00
|
|
|
|
|
|
|
|
|
private void txtScanline_TextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int temp;
|
2011-06-10 07:43:48 +00:00
|
|
|
|
if (int.TryParse(txtScanline.Text, out temp))
|
|
|
|
|
{
|
|
|
|
|
Callback.Scanline = temp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void NESPPU_FormClosed(object sender, FormClosedEventArgs e)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if (_nes == null) return;
|
|
|
|
|
if (_nes.ppu.PPUViewCallback == Callback)
|
|
|
|
|
_nes.ppu.PPUViewCallback = null;
|
2011-06-10 07:43:48 +00:00
|
|
|
|
}
|
2011-08-28 16:36:50 +00:00
|
|
|
|
|
|
|
|
|
private void SpriteView_MouseEnter(object sender, EventArgs e)
|
|
|
|
|
{
|
2011-08-28 17:38:33 +00:00
|
|
|
|
DetailsBox.Text = "Details - Sprites";
|
2011-08-28 16:36:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SpriteView_MouseLeave(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ClearDetails();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SpriteView_MouseMove(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
bool is8x16 = _nes.ppu.reg_2000.obj_size_16;
|
2011-08-28 16:36:50 +00:00
|
|
|
|
int SpriteNumber = ((e.Y / 24) * 16) + (e.X / 16);
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int X = _nes.ppu.OAM[(SpriteNumber * 4) + 3];
|
|
|
|
|
int Y = _nes.ppu.OAM[SpriteNumber * 4];
|
|
|
|
|
int Color = _nes.ppu.OAM[(SpriteNumber * 4) + 2] & 0x03;
|
|
|
|
|
int Attributes = _nes.ppu.OAM[(SpriteNumber * 4) + 2];
|
2011-08-29 00:19:55 +00:00
|
|
|
|
|
|
|
|
|
string flags = "Flags: ";
|
|
|
|
|
int h = GetBit(Attributes, 6);
|
|
|
|
|
int v = GetBit(Attributes, 7);
|
|
|
|
|
int priority = GetBit(Attributes, 5);
|
|
|
|
|
if (h > 0)
|
|
|
|
|
flags += "H ";
|
|
|
|
|
if (v > 0)
|
|
|
|
|
flags += "V ";
|
|
|
|
|
if (priority > 0)
|
|
|
|
|
flags += "Behind";
|
|
|
|
|
else
|
|
|
|
|
flags += "Front";
|
2011-08-28 20:43:25 +00:00
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
int Tile = _nes.ppu.OAM[SpriteNumber * 1];
|
2011-08-28 16:36:50 +00:00
|
|
|
|
|
|
|
|
|
AddressLabel.Text = "Number: " + String.Format("{0:X2}", SpriteNumber);
|
|
|
|
|
ValueLabel.Text = "X: " + String.Format("{0:X2}", X);
|
|
|
|
|
Value2Label.Text = "Y: " + String.Format("{0:X2}", Y);
|
2011-08-28 17:38:33 +00:00
|
|
|
|
Value3Label.Text = "Tile: " + String.Format("{0:X2}", Tile);
|
2011-08-28 20:43:25 +00:00
|
|
|
|
Value4Label.Text = "Color: " + Color.ToString();
|
2011-08-29 00:19:55 +00:00
|
|
|
|
Value5Label.Text = flags;
|
2011-08-28 17:38:33 +00:00
|
|
|
|
|
2011-08-29 00:28:17 +00:00
|
|
|
|
if (is8x16)
|
|
|
|
|
ZoomBox.Image = Section(SpriteView.sprites, new Rectangle(new Point((e.X / 8) * 8, (e.Y / 24) * 24), new Size(8, 16)), true);
|
|
|
|
|
else
|
|
|
|
|
ZoomBox.Image = Section(SpriteView.sprites, new Rectangle(new Point((e.X / 8) * 8, (e.Y / 8) * 8), new Size(8, 8)), false);
|
2011-08-28 16:36:50 +00:00
|
|
|
|
}
|
2011-08-28 17:59:53 +00:00
|
|
|
|
|
|
|
|
|
private void PaletteView_MouseClick(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
HandleDefaultImage();
|
2011-08-28 17:59:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SpriteView_MouseClick(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
HandleDefaultImage();
|
2011-08-28 17:59:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
private void HandleDefaultImage()
|
2011-08-28 17:59:53 +00:00
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if (ModifierKeys == Keys.Shift)
|
2011-08-28 17:59:53 +00:00
|
|
|
|
{
|
|
|
|
|
ZoomBoxDefaultImage = ZoomBox.Image as Bitmap;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void NESPPU_MouseClick(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ZoomBox.Image = new Bitmap(64, 64);
|
|
|
|
|
}
|
2011-09-15 00:49:25 +00:00
|
|
|
|
|
|
|
|
|
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void savePaletteScreenshotToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PaletteView.Screenshot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void saveImageToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PaletteView.Screenshot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PaletteView.Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void saveImageToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PatternView.Screenshot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void refreshToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PatternView.Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void saveImageToolStripMenuItem2_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SpriteView.Screenshot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void refreshToolStripMenuItem2_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SpriteView.Refresh();
|
|
|
|
|
}
|
2012-03-09 19:22:31 +00:00
|
|
|
|
|
|
|
|
|
private void imageToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SpriteView.ScreenshotToClipboard();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void imageToClipboardToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PatternView.ScreenshotToClipboard();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void imageToClipboardToolStripMenuItem2_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PaletteView.ScreenshotToClipboard();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void savePaletteToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PaletteView.ScreenshotToClipboard();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void copyPatternToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PatternView.ScreenshotToClipboard();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void copySpriteToClipboardToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SpriteView.ScreenshotToClipboard();
|
|
|
|
|
}
|
2012-11-12 22:13:49 +00:00
|
|
|
|
|
|
|
|
|
private void NESPPU_KeyDown(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
2013-04-15 02:14:14 +00:00
|
|
|
|
if (ModifierKeys.HasFlag(Keys.Control) && e.KeyCode == Keys.C)
|
2012-11-12 22:13:49 +00:00
|
|
|
|
{
|
|
|
|
|
// find the control under the mouse
|
2013-04-15 02:14:14 +00:00
|
|
|
|
Point m = Cursor.Position;
|
2012-11-12 22:13:49 +00:00
|
|
|
|
Control top = this;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
Control found;
|
2012-11-12 22:13:49 +00:00
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
found = top.GetChildAtPoint(top.PointToClient(m));
|
|
|
|
|
top = found;
|
|
|
|
|
} while (found != null && found.HasChildren);
|
|
|
|
|
|
|
|
|
|
if (found != null)
|
|
|
|
|
{
|
|
|
|
|
|
2013-04-15 02:14:14 +00:00
|
|
|
|
var meth = found.GetType().GetMethod("ScreenshotToClipboard", Type.EmptyTypes);
|
2012-11-12 22:13:49 +00:00
|
|
|
|
if (meth != null)
|
2013-04-15 02:14:14 +00:00
|
|
|
|
{
|
2012-11-12 22:13:49 +00:00
|
|
|
|
meth.Invoke(found, null);
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
2012-11-12 22:13:49 +00:00
|
|
|
|
else if (found is PictureBox)
|
2013-04-15 02:14:14 +00:00
|
|
|
|
{
|
2012-11-12 22:13:49 +00:00
|
|
|
|
Clipboard.SetImage((found as PictureBox).Image);
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
2012-11-12 22:13:49 +00:00
|
|
|
|
else
|
2013-04-15 02:14:14 +00:00
|
|
|
|
{
|
2012-11-12 22:13:49 +00:00
|
|
|
|
return;
|
2013-04-15 02:14:14 +00:00
|
|
|
|
}
|
2012-11-12 22:13:49 +00:00
|
|
|
|
|
|
|
|
|
toolStripStatusLabel1.Text = found.Text + " copied to clipboard.";
|
|
|
|
|
|
|
|
|
|
messagetimer.Stop();
|
|
|
|
|
messagetimer.Start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void messagetimer_Tick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
messagetimer.Stop();
|
|
|
|
|
toolStripStatusLabel1.Text = "Use CTRL+C to copy the pane under the mouse to the clipboard.";
|
|
|
|
|
}
|
2011-03-13 01:09:35 +00:00
|
|
|
|
}
|
2011-03-03 16:38:34 +00:00
|
|
|
|
}
|