예제 #1
0
 public unsafe void Begin()
 {
     if (_CanRender)
     {
         _IsRendering  = true;
         lastLineState = RenderLineState.RenderClipping;
         if (highResSnap)
         {
             log        = new StreamWriter(snapfile + "log.txt");
             takingSnap = true;
         }
     }
 }
예제 #2
0
 public void BlankPixel(int X, int Y)
 {
     if (_CanRender & _IsRendering)
     {
         //Check if we should cut this line
         if (Y >= _FirstLinesTCut & Y < (_ScanLines + _FirstLinesTCut))
         {
             if (lastLineState != oppu.rstate)
             {
                 lastLineState = oppu.rstate;
                 lastTileNo    = -1;
             }
             if (hasHiResPack)
             {
                 RenderTile(X, Y);
             }
         }
     }
 }
예제 #3
0
        public void DrawPixel(int X, int Y, int Color)
        {
            if (_CanRender & _IsRendering)
            {
                //Check if we should cut this line
                if (Y >= _FirstLinesTCut & Y < (_ScanLines + _FirstLinesTCut))
                {
                    if (lastLineState != oppu.rstate)
                    {
                        lastLineState = oppu.rstate;
                        lastTileNo    = -1;
                    }

                    if (oppu.rstate == RenderLineState.ClearScanline || oppu.rstate == RenderLineState.RenderClipping || !hasHiResPack)
                    {
                        DrawBasicPixel(X, Y, Color);
                    }
                    else
                    {
                        RenderTile(X, Y);
                    }
                }
            }
        }
예제 #4
0
        public void RunPPU()
        {
            ScanCycle++;
            TileCycle++;
            if (ScanCycle == 341)
            {
                ScanCycle       = 0;
                TileCycle       = 8;
                SpritesRendered = false;
                ScanLine++;
                //Render the actual data to be displayed on the screen
                if (ScanLine >= ScanlineOfEndOfVblank & ScanLine <= 239 + ScanlineOfEndOfVblank)
                {
                    rstate = RenderLineState.ClearScanline;
                    //Clean up the line from before

                    /*fixed (byte* pSrc = piorityBuff)
                     * {
                     *  byte* ps = pSrc;
                     *  for (int i = 0; i < 256; i += 8)
                     *  {
                     *((UInt64*)(ps + i)) = 0;
                     *  }
                     * }*/
                    //Draw background color
                    byte B = MEM_PPU[0x3F00];
                    if (B >= 63)
                    {
                        B = 63;
                    }
                    for (int i = 0; i < 256; i++)
                    {
                        VIDEO.DrawPixel(i, ScanLine - ScanlineOfEndOfVblank, PALETTE[B]);
                        piorityBuff[i] = 0;
                    }
                    //Tick mapper timer (scanline timer)
                    if (BackgroundVisibility | SpriteVisibility)
                    {
                        MEM_CPU.MAPPER.TickScanlineTimer();
                    }
                }
                //do nothing for 1 scanline
                if (ScanLine == ScanlinesPerFrame)
                {
                    //Handle the speed
                    if (!NoLimiter)
                    {
                        double currentTime = Timer.GetCurrentTime();
                        _currentFrameTime = currentTime - _lastFrameTime;
                        if ((_currentFrameTime < FramePeriod))
                        {
                            while (true)
                            {
                                if ((Timer.GetCurrentTime() - _lastFrameTime) >= FramePeriod)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    _lastFrameTime = Timer.GetCurrentTime();
                    ScanLine       = -1;
                    FPS++;
                    //Odd frame ? only in ntsc
                    if (TV == TVFORMAT.NTSC)
                    {
                        OddFrame = !OddFrame;
                        if (!OddFrame & BackgroundVisibility)
                        {
                            if (BBackgroundVisibility)
                            {
                                ScanCycle += 1;
                            }
                        }
                        BBackgroundVisibility = BackgroundVisibility;
                    }
                    //render into screen
                    VIDEO.RenderFrame();
                }
            }
            else if (ScanLine >= ScanlineOfEndOfVblank & ScanLine <= 239 + ScanlineOfEndOfVblank)
            {
                if (ScanCycle < 256)    //Render on the screen
                {
                    if (TileCycle >= 8) //Render BG tile each 8 cycles
                    {
                        if (BackgroundVisibility)
                        {
                            if (rstate != RenderLineState.RenderBackground)
                            {
                                rstate = RenderLineState.RenderBackground;
                                hflip  = true;
                                vflip  = false;
                            }
                            RenderNextBackgroundTile();
                        }
                        TileCycle -= 8;
                    }
                }
                else if (!SpritesRendered)
                {
                    if (SpriteVisibility)
                    {
                        rstate = RenderLineState.RenderSprite;
                        RenderSprites();
                    }
                    if (BackgroundClipping)
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            VIDEO.DrawPixel(i, ScanLine - ScanlineOfEndOfVblank, 0);
                        }
                    }
                    //Update Hscroll
                    if (SpriteVisibility | BackgroundVisibility)
                    {
                        VRAM_ADDRESS     = (ushort)((VRAM_ADDRESS & 0x7BE0) | (VRAM_TEMP & 0x041F));
                        nameTableAddress = (VRAM_ADDRESS & 0x0800) +
                                           (VRAM_TEMP & 0x0400) + 0x2000;
                        HScroll = (((VRAM_TEMP & 0x001F) << 3) | TileX);
                    }
                    SpritesRendered = true;
                }
            }
            //Start of vblank
            if (ScanLine == 0 & ScanCycle == 339)
            {
                if (ExecuteNMIOnVBlank)
                {
                    CPU.NMIRequest = true;
                }
                VBlank = true;
            }
            //End of vblank
            else if (ScanLine == ScanlineOfEndOfVblank)
            {
                if (ScanCycle == 305)
                {
                    //Update Vscroll
                    if (SpriteVisibility | BackgroundVisibility)
                    {
                        VRAM_ADDRESS = VRAM_TEMP;
                        VScroll      = (((VRAM_TEMP & 0x03E0) >> 2) | ((VRAM_TEMP & 0x7000) >> 12));
                        if (VScroll >= 240)
                        {
                            VScroll -= 256;
                        }
                    }
                }
                if (ScanCycle == 339)
                {
                    VIDEO.Begin();
                    //Clear flags
                    Sprite0Hit    = false;
                    VBlank        = false;
                    SpriteCrossed = 0;
                }
            }
        }