diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index 261812fc91..322e54ade7 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -62,6 +62,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo public int[] GetVideoBuffer() { + //why is it faster to continually reallocate? i have no idea. int[] pixels = new int[256 * 240]; int i = 0; for (int y = 0; y < 240; y++) diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs index 185c03850d..077cc3db5e 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.cs @@ -100,11 +100,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo void runppu(int x) { //pputime+=x; - //if(cputodo<200) return; //DON'T LIKE THIS.... - ppur.status.cycle = (ppur.status.cycle + x) % - ppur.status.end_cycle; + ppur.status.cycle += x; + if (ppur.status.cycle > ppur.status.end_cycle) + ppur.status.cycle -= ppur.status.end_cycle; + nes.RunCpu(x); //pputime -= cputodo<<2; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs index dc2e8b05e2..27ca5b934f 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.regs.cs @@ -31,6 +31,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo public Bit intense_blue; //Intensify blues (and darken other colors) public Bit intense_red; //Intensify reds (and darken other colors) + public int intensity_lsl_8; //an optimization.. + public bool PPUON { get { return show_bg || show_obj; } } public byte Value @@ -49,6 +51,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo intense_green = (value >> 5) & 1; intense_blue = (value >> 6) & 1; intense_red = (value >> 7) & 1; + intensity_lsl_8 = ((value >> 5) & 7)<<8; } } } @@ -120,17 +123,44 @@ namespace BizHawk.Emulation.Consoles.Nintendo //other regs that need savestating public int fh;//3 (horz scroll) - //other regs that don't need saving - public int par;//8 (sort of a hack, just stored in here, but not managed by this system) - //cached state data. these are always reset at the beginning of a frame and don't need saving //but just to be safe, we're gonna save it public PPUSTATUS status = new PPUSTATUS(); + //public int ComputeIndex() + //{ + // return fv | (v << 3) | (h << 4) | (vt << 5) | (ht << 10) | (fh << 15); + //} + //public void DecodeIndex(int index) + //{ + // fv = index & 7; + // v = (index >> 3) & 1; + // h = (index >> 4) & 1; + // vt = (index >> 5) & 0x1F; + // ht = (index >> 10) & 0x1F; + // fh = (index >> 15) & 7; + //} + + //const int tbl_size = 1 << 18; + //int[] tbl_increment_hsc = new int[tbl_size]; + //int[] tbl_increment_vs = new int[tbl_size]; + //public void BuildTables() + //{ + // for (int i = 0; i < tbl_size; i++) + // { + // DecodeIndex(i); + // increment_hsc(); + // tbl_increment_hsc[i] = ComputeIndex(); + // DecodeIndex(i); + // increment_vs(); + // tbl_increment_vs[i] = ComputeIndex(); + // } + //} + public void reset() { fv = v = h = vt = ht = 0; - fh = par = 0; + fh = 0; _fv = _v = _h = _vt = _ht = 0; status.cycle = 0; status.end_cycle = 341; @@ -202,7 +232,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo } //address line 3 relates to the pattern table fetch occuring (the PPU always makes them in pairs). - public int get_ptread() + public int get_ptread(int par) { int s = ppu.reg_2000.bg_pattern_hi; return (s << 0xC) | (par << 0x4) | fv; diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs index 87bd387ca3..05d88226c0 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/PPU.run.cs @@ -50,8 +50,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo } runppu(1); - ppur.par = bgdata.nt; - addr = ppur.get_ptread(); + addr = ppur.get_ptread(bgdata.nt); bgdata.pt_0 = ppubus_read(addr); runppu(kFetchTime); addr |= 8; @@ -70,15 +69,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo //TODO - check flashing sirens in werewolf short PaletteAdjustPixel(int pixel) { - //tack on the deemph bits - pixel |= (reg_2001.intense_red<<8)|(reg_2001.intense_green<<9)|(reg_2001.intense_blue<<10); - return (short)pixel; + //tack on the deemph bits. THESE MAY BE ORDERED WRONG. PLEASE CHECK IN THE PALETTE CODE + return (short)(pixel| reg_2001.intensity_lsl_8); } const int kLineTime = 341; public unsafe void FrameAdvance() { - BGDataRecord[] bgdata = new BGDataRecord[34]; //one at the end is junk, it can never be rendered + BGDataRecord *bgdata = stackalloc BGDataRecord[34]; //one at the end is junk, it can never be rendered //262 scanlines if (ppudead != 0) @@ -117,8 +115,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo //if(PPUON) // ppur.install_latches(); - TempOAM[,] oams = new TempOAM[2,64]; //[7] turned to [8] for faster indexing - int[] oamcounts = new int[2]; + TempOAM* oams = stackalloc TempOAM[128]; + int* oamcounts = stackalloc int[2]; int oamslot=0; int oamcount=0; @@ -185,7 +183,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo bool havepixel = false; for (int s = 0; s < oamcount; s++) { - fixed (TempOAM* oam = &oams[renderslot, s]) + TempOAM *oam = &oams[(renderslot<<6)+s]; { int x = oam->oam[3]; if (rasterpos >= x && rasterpos < x + 8) @@ -232,6 +230,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo } //c# fixed oam ptr + }//oamcount loop xbuf[target] = PaletteAdjustPixel(pixelcolor); @@ -248,8 +247,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo int spriteHeight = reg_2000.obj_size_16 ? 16 : 8; for (int i = 0; i < 64; i++) - fixed (TempOAM* oam = &oams[scanslot, i]) - oam->present = 0; + oams[(scanslot<<6)+i].present = 0; for (int i = 0; i < 64; i++) { @@ -267,7 +265,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo } //just copy some bytes into the internal sprite buffer - fixed (TempOAM* oam = &oams[scanslot, oamcount]) + TempOAM* oam = &oams[(scanslot << 6) + oamcount]; { for (int j = 0; j < 4; j++) oam->oam[j] = OAM[spr + j]; @@ -276,7 +274,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo //note that we stuff the oam index into [6]. //i need to turn this into a struct so we can have fewer magic numbers - oams[scanslot, oamcount].index = (byte)i; + oams[(scanslot<<6)+oamcount].index = (byte)i; oamcount++; } } @@ -315,7 +313,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo //this could be handy for the debugging tools also bool realSprite = (s < 8); - fixed (TempOAM* oam = &oams[scanslot, s]) + TempOAM* oam = &oams[(scanslot << 6) + s]; + //fixed (TempOAM* oam = &oams[scanslot, s]) { int line = yp - oam->oam[0]; if ((oam->oam[2] & 0x80) != 0) //vflip diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs index e571aaf7b2..f3c3450036 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/Palettes.cs @@ -18,6 +18,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo public static void ApplyDeemphasis(ref int r, ref int g, ref int b, int deemph_bits) { + //DEEMPH BITS MAY BE ORDERED WRONG. PLEASE CHECK if (deemph_bits == 0) return; int d = deemph_bits-1; r = (int)(r * rtmul[d]); diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 54594a6fa1..c987edb81a 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading; using System.Drawing; using System.Drawing.Imaging; @@ -31,7 +32,10 @@ namespace BizHawk.MultiClient bool runloop_frameProgress; DateTime FrameAdvanceTimestamp = DateTime.MinValue; public bool EmulatorPaused; + int runloop_fps; bool runloop_frameadvance; + DateTime runloop_second; + Throttle throttle = new Throttle(); int rewindCredits; @@ -135,8 +139,8 @@ namespace BizHawk.MultiClient LoadRamSearch(); if (Global.Config.AutoLoadHexEditor) LoadHexEditor(); - if (Global.Config.AutoLoadNESPPU && Global.Emulator is NES) - LoadNESPPU(); + //if (Global.Config.AutoLoadNESPPU && Global.Emulator is NES) + // LoadNESPPU(); if (Global.Config.MainWndx >= 0 && Global.Config.MainWndy >= 0 && Global.Config.SaveWindowPosition) this.Location = new Point(Global.Config.MainWndx, Global.Config.MainWndy); @@ -704,6 +708,14 @@ namespace BizHawk.MultiClient bool genSound = false; if (runFrame) { + runloop_fps++; + if ((DateTime.Now - runloop_second).TotalSeconds > 1) + { + runloop_second = DateTime.Now; + Global.RenderPanel.FPS = runloop_fps; + runloop_fps = 0; + } + if(!suppressCaptureRewind && Global.Config.RewindEnabled) CaptureRewindState(); if (!runloop_frameadvance) genSound = true; else if (!Global.Config.MuteFrameAdvance) diff --git a/BizHawk.MultiClient/RenderPanel.cs b/BizHawk.MultiClient/RenderPanel.cs index ef5818fbb7..34152ea4c4 100644 --- a/BizHawk.MultiClient/RenderPanel.cs +++ b/BizHawk.MultiClient/RenderPanel.cs @@ -109,12 +109,14 @@ namespace BizHawk.MultiClient void Render(IVideoProvider video); bool Resized { get; set; } void AddMessage(string msg); + decimal FPS { get; set; } } public class SysdrawingRenderPanel : IRenderer { public bool Resized { get; set; } public void Dispose() { } + public decimal FPS { get; set; } public void Render(IVideoProvider video) { Color BackgroundColor = Color.FromArgb(video.BackgroundColor); @@ -144,6 +146,7 @@ namespace BizHawk.MultiClient { public Color BackgroundColor { get; set; } public bool Resized { get; set; } + public decimal FPS { get; set; } private Direct3D d3d; private Device Device; @@ -262,6 +265,9 @@ namespace BizHawk.MultiClient string input = MakeInputDisplay(); MessageFont.DrawString(null, input, 1, 16, new Color4(Color.White)); } + + if (Global.Config.DisplayFPS) + MessageFont.DrawString(null, FPS.ToString(), 0, 0, new Color4(Color.White)); } private string MakeFrameCounter()