示例#1
0
        public void DrawTiles()
        {
            ushort tileBaseAddress    = DisFuncs.GetTileBaseAddress(_state.TileBase);
            ushort tileMapBaseAddress = DisFuncs.GetTileMapBaseAddress(_state.TileMap);

            for (int tileY = 0; tileY < 18; ++tileY)
            {
                for (int tileX = 0; tileX < 20; ++tileX)
                {
                    int tileOffset;
                    if (_state.NoTileMap)
                    {
                        tileOffset = 16 * tileY + tileX;
                    }
                    else
                    {
                        tileOffset = DisFuncs.GetTileOffset(_disDef, _memory, tileMapBaseAddress,
                                                            _state.TileBase, tileX, tileY);
                    }
                    byte[] tileData = DisFuncs.GetTileData(_disDef, _memory, tileBaseAddress, tileOffset, false);

                    DrawFuncs.DrawTile(_pixelLookupTable,
                                       _disDef, _debugInternalTargets[(int)DebugTargets.Tiles],
                                       _tempPixelBuffer,
                                       _disDef.ScreenPixelCountX, tileData,
                                       8 * tileX, 8 * tileY,
                                       256, 256);
                }
            }
        }
示例#2
0
        internal void HandleMemoryChange(MMR mappedRegister, byte value)
        {
            switch (mappedRegister)
            {
            case MMR.LCDC:
                // We set all the LCDC bits
                for (int i = 0; i < 8; ++i)
                {
                    _state.LCDCBits[i] = (value & (1 << i)) != 0;
                }
                break;

            case MMR.STAT:
                _state.STAT = value;
                break;

            case MMR.SCY:
                _state.SCY = value;
                break;

            case MMR.SCX:
                _state.SCX = value;
                break;

            case MMR.LY:
                _state.CurrentLine = 0;
                break;

            case MMR.LYC:
                _state.LYC = value;
                break;

            case MMR.DMA:
                LoadSprites();
                break;

            case MMR.BGP:
                DisFuncs.SetupTilePallete(_disDef, _memory);
                break;

            case MMR.OBP0:
                DisFuncs.SetupSpritePalletes(_disDef, _memory, MMR.OBP0);
                break;

            case MMR.OBP1:
                DisFuncs.SetupSpritePalletes(_disDef, _memory, MMR.OBP1);
                break;

            case MMR.WY:
                _state.WY = value;
                break;

            case MMR.WX:
                _state.WX = value;
                break;

            default:
                throw new InvalidProgramException("All cases should be handled...");
            }
        }
示例#3
0
        internal void DrawSprite(uint[] spriteData, int spriteCode, int pX, int pY)
        {
            DrawFuncs.DrawTransparency(_disDef, spriteData, 8, 0, 0, 8, 16);

            if (_state.LCDCBits[2])
            {
                spriteCode = spriteCode & 0xFE; // We remove the last bit
            }

            // We draw the top part
            byte[] pixels = DisFuncs.GetTileData(_disDef, _memory, 0x8000, spriteCode, _state.LCDCBits[2]);
            DrawFuncs.DrawTile(_pixelLookupTable,
                               _disDef, spriteData, _tempPixelBuffer,
                               8, pixels, pX, pY,
                               _disDef.ScreenPixelCountX, _disDef.ScreenPixelCountY);
        }
示例#4
0
        DrawTile(short[] pixelLookupTable,
                 DisplayDefinition disDef, uint[] bitmapData, uint[] pixelBuffer,
                 int stride, byte[] tileData,
                 int pX, int pY, int maxPx, int maxPy)
        {
            // We iterate for the actual bytes
            for (int j = 0; j < tileData.Length; j += 2)
            {
                int pixelY = pY + (j / 2);
                if (pixelY < 0)
                {
                    continue;
                }
                if (pixelY >= maxPy)
                {
                    break;
                }                            // We can continue no further

                int index = pixelY * stride; // Only add every 2 bytes
                DisFuncs.GetPixelsFromTileBytes(pixelLookupTable,
                                                ref pixelBuffer,
                                                disDef.TilePallete,
                                                disDef.PixelPerTileX,
                                                tileData[j], tileData[j + 1]);
                for (int i = 0; i < 8; i++)
                {
                    int pixelX = pX + i;
                    if (pixelX < 0)
                    {
                        continue;
                    }
                    if (pixelX >= maxPx)
                    {
                        break;
                    }
                    int pIndex = index + pixelX;
                    bitmapData[pIndex] = pixelBuffer[i];
                }
            }
        }
示例#5
0
        public void DrawFrame(int rowBegin, int rowEnd)
        {
            if (!_state.Enabled)
            {
                return;
            }
            if (rowBegin > 143)
            {
                return;
            }

            #region BACKGROUND

            bool drawBackground = _state.LCDCBits[0];
            // We copy the information from the background tile to the effective screen
            for (int y = rowBegin; y < rowEnd; y++)
            {
                // We obtain the correct row
                int bY = (y + _state.SCY) % _disDef.FramePixelCountY;
                DisFuncs.GetRowPixels(ref _tempFrameLineBuffer,
                                      _pixelLookupTable,
                                      _disDef, _memory,
                                      _tempPixelBuffer,
                                      bY, _state.LCDCBits[3], _state.LCDCBits[4]);

                if (_updateDebugTargets[(int)DebugTargets.Background])
                {
                    // TODO(Cristian): Draw the whole debug target
                    DrawFuncs.DrawLine(_disDef, _debugInternalTargets[(int)DebugTargets.Background],
                                       _disDef.FramePixelCountX,
                                       _tempFrameLineBuffer,
                                       0, bY,
                                       0, _disDef.FramePixelCountX);
                }

                if (drawBackground)
                {
                    DrawFuncs.DrawLine(_disDef, _screenInternalBuffer,
                                       _disDef.ScreenPixelCountX,
                                       _tempFrameLineBuffer,
                                       0, y,
                                       _state.SCX, _disDef.FramePixelCountX,
                                       false, true);
                }
            }

            #endregion

            #region WINDOW

            int rWX = _state.WX - 7; // The window pos is (WX - 7, WY)

            // TODO(Cristian): If BG display is off, it actually prints white
            bool drawWindow = _state.LCDCBits[5];
            for (int row = rowBegin; row < rowEnd; row++)
            {
                if ((row >= _state.CurrentWY) && (row < 144))
                {
                    // The offset indexes represent that the window is drawn from it's beggining
                    // at (WX, WY)
                    DisFuncs.GetRowPixels(ref _tempFrameLineBuffer,
                                          _pixelLookupTable,
                                          _disDef, _memory, _tempPixelBuffer,
                                          row - _state.CurrentWY,
                                          _state.LCDCBits[6], _state.LCDCBits[4]);

                    // Independent target
                    if (_updateDebugTargets[(int)DebugTargets.Window])
                    {
                        DrawFuncs.DrawLine(_disDef, _debugInternalTargets[(int)DebugTargets.Window],
                                           _disDef.ScreenPixelCountX,
                                           _tempFrameLineBuffer,
                                           rWX, row,
                                           0, _disDef.ScreenPixelCountX - rWX);
                    }

                    // Screen target
                    if (drawWindow)
                    {
                        DrawFuncs.DrawLine(_disDef, _screenInternalBuffer,
                                           _disDef.ScreenPixelCountX,
                                           _tempFrameLineBuffer,
                                           rWX, row,
                                           0, _disDef.ScreenPixelCountX - rWX);
                    }
                }
            }

            #endregion

            #region SPRITES

            bool drawSprites = _state.LCDCBits[1];
            for (int row = rowBegin; row < rowEnd; row++)
            {
                if (_updateDebugTargets[(int)DebugTargets.SpriteLayer])
                {
                    // Independent target
                    uint[] pixels = new uint[_disDef.ScreenPixelCountX];
                    DisFuncs.GetSpriteRowPixels(_pixelLookupTable,
                                                _disDef, _memory, _spriteOAMs, pixels,
                                                _tempPixelBuffer,
                                                row, _state.LCDCBits[2],
                                                true);
                    DrawFuncs.DrawLine(_disDef, _debugInternalTargets[(int)DebugTargets.SpriteLayer],
                                       _disDef.ScreenPixelCountX,
                                       pixels,
                                       0, row,
                                       0, _disDef.ScreenPixelCountX);
                }

                // Screen Target
                if (drawSprites)
                {
                    DisFuncs.GetPixelRowFromBitmap(ref _tempFrameLineBuffer,
                                                   _disDef, _screenInternalBuffer,
                                                   row, _disDef.ScreenPixelCountX);
                    DisFuncs.GetSpriteRowPixels(_pixelLookupTable,
                                                _disDef, _memory, _spriteOAMs,
                                                _tempFrameLineBuffer, _tempPixelBuffer,
                                                row, _state.LCDCBits[2]);
                    DrawFuncs.DrawLine(_disDef, _screenInternalBuffer, _disDef.ScreenPixelCountX,
                                       _tempFrameLineBuffer,
                                       0, row,
                                       0, _disDef.ScreenPixelCountX);
                }
            }

            #endregion
        }