Exemplo n.º 1
0
        GetScanLineOAMs(DisplayDefinition disDef, OAM[] spriteOAMs, int row, bool LCDCBit2)
        {
            int spriteSize = disDef.BytesPerTileShort / 2;

            if (LCDCBit2)
            {
                spriteSize = disDef.BytesPerTileLong / 2;
            }

            // Then we select the 10 that correspond
            int scanLineSize    = 0;
            int maxScanLineSize = 10;

            foreach (OAM oam in spriteOAMs)
            {
                int y = oam.Y - 16;
                if ((y <= row) && (row < (y + spriteSize)))
                {
                    scanLineOAMs[scanLineSize++] = oam;
                    if (scanLineSize == maxScanLineSize)
                    {
                        break;
                    }
                }
            }

            return(scanLineSize);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets a row of pixels from the tilemap
        /// </summary>
        /// <param name="row">The row number to retreive [0, frameHeight)</param>
        /// <param name="LCDBit3">
        /// Whether the LCDC Register (0xFF40) Bit 3 is enabled.
        /// Determines what tilemap (where the tile indexes are) is used:
        /// 0: 0x9800 - 0x9BFF
        /// 1: 0x9C00 - 0x9FFF
        /// </param>
        /// <param name="LCDBit4">
        /// Whether the LCDC Register (0xFF40) Bit 3 is enabled.
        /// Determines the base address for the actual tiles and the
        /// accessing method (interpretation of the byte tile index retreived from the tilemap).
        /// 0: 0x8800 - 0x97FF | signed access
        /// 1: 0x8000 - 0x8FFF | unsigned access
        /// </param>
        /// <returns>An array with the pixels to show for that row (color already calculated)</returns>
        internal static void GetRowPixels(ref uint[] frameLineBuffer,
                 short[] pixelLookupTable,
                 DisplayDefinition disDef, Memory memory,
                 uint[] pixelBuffer, 
                 int row, bool LCDBit3, bool LCDBit4)
        {
            // We determine the y tile
              int tileY = row / disDef.PixelPerTileY;
              int tileRemainder = row % disDef.PixelPerTileY;

              ushort tileMapBaseAddress = GetTileMapBaseAddress(LCDBit3);
              ushort tileBaseAddress = GetTileBaseAddress(LCDBit4);

              for (int tileX = 0; tileX < disDef.FrameTileCountX; tileX++)
              {
            // We obtain the correct tile index
            int tileOffset = GetTileOffset(disDef, memory, tileMapBaseAddress, LCDBit4, tileX, tileY);

            // We obtain both pixels
            int currentTileBaseAddress = tileBaseAddress + disDef.BytesPerTileShort * tileOffset;
            byte top = memory.LowLevelRead((ushort)(currentTileBaseAddress + 2 * tileRemainder));
            byte bottom = memory.LowLevelRead((ushort)(currentTileBaseAddress + 2 * tileRemainder + 1));

            GetPixelsFromTileBytes(pixelLookupTable,
                               ref pixelBuffer,
                               disDef.TilePallete,
                               disDef.PixelPerTileX,
                               top, bottom);
            int currentTileIndex = tileX * disDef.PixelPerTileX;
            for (int i = 0; i < disDef.PixelPerTileX; i++)
            {
              frameLineBuffer[currentTileIndex + i] = pixelBuffer[i];
            }
              }
        }
Exemplo n.º 3
0
        GetRowPixels(ref uint[] frameLineBuffer,
                     short[] pixelLookupTable,
                     DisplayDefinition disDef, Memory memory,
                     uint[] pixelBuffer,
                     int row, bool LCDBit3, bool LCDBit4)
        {
            // We determine the y tile
            int tileY         = row / disDef.PixelPerTileY;
            int tileRemainder = row % disDef.PixelPerTileY;

            ushort tileMapBaseAddress = GetTileMapBaseAddress(LCDBit3);
            ushort tileBaseAddress    = GetTileBaseAddress(LCDBit4);

            for (int tileX = 0; tileX < disDef.FrameTileCountX; tileX++)
            {
                // We obtain the correct tile index
                int tileOffset = GetTileOffset(disDef, memory, tileMapBaseAddress, LCDBit4, tileX, tileY);

                // We obtain both pixels
                int  currentTileBaseAddress = tileBaseAddress + disDef.BytesPerTileShort * tileOffset;
                byte top    = memory.LowLevelRead((ushort)(currentTileBaseAddress + 2 * tileRemainder));
                byte bottom = memory.LowLevelRead((ushort)(currentTileBaseAddress + 2 * tileRemainder + 1));

                GetPixelsFromTileBytes(pixelLookupTable,
                                       ref pixelBuffer,
                                       disDef.TilePallete,
                                       disDef.PixelPerTileX,
                                       top, bottom);
                int currentTileIndex = tileX * disDef.PixelPerTileX;
                for (int i = 0; i < disDef.PixelPerTileX; i++)
                {
                    frameLineBuffer[currentTileIndex + i] = pixelBuffer[i];
                }
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Draw a tile into a bitmap. 
        /// IMPORTANT: presently it requires that the bitmap be the whole background (256x256 pixels)
        /// </summary>
        /// <param name="bmd">The bitmap data where to output the pixels</param>
        /// <param name="tileData">The 16 bytes that conform the 8x8 pixels</param>
        /// <param name="pX">x coord of the pixel where to start drawing the tile</param>
        /// <param name="pY">y coord of the pixel where to start drawing the tile</param>
        internal static void 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];
            }
              }
        }
Exemplo n.º 5
0
 SetupSpritePalletes(DisplayDefinition disDef, Memory memory, MMR pallete)
 {
     if (pallete == MMR.OBP0)
     {
         byte obp0 = memory.LowLevelRead((ushort)MMR.OBP0);
         disDef.SpritePallete0[0] = 0x00000000; // Sprite colors are trasparent
         for (int color = 1; color < 4; ++color)
         {
             int down  = (obp0 >> (2 * color)) & 1;
             int up    = (obp0 >> (2 * color + 1)) & 1;
             int index = (up << 1) | down;
             disDef.SpritePallete0[color] = disDef.SpriteColors[index];
         }
     }
     else if (pallete == MMR.OBP1)
     {
         byte obp1 = memory.LowLevelRead((ushort)MMR.OBP1);
         disDef.SpritePallete1[1] = 0x00000000; // Sprite colors are trasparent
         for (int color = 1; color < 4; ++color)
         {
             int down  = (obp1 >> (2 * color)) & 1;
             int up    = (obp1 >> (2 * color + 1)) & 1;
             int index = (up << 1) | down;
             disDef.SpritePallete1[color] = disDef.SpriteColors[index];
         }
     }
     else
     {
         throw new InvalidProgramException("Invalid pallete register given");
     }
 }
Exemplo n.º 6
0
        GetTileOffset(DisplayDefinition disDef, Memory memory,
                      ushort tileMapBaseAddress, bool LCDBit4,
                      int tileX, int tileY)
        {
            int tileOffset;

            if (LCDBit4)
            {
                tileOffset = memory.LowLevelRead((ushort)(tileMapBaseAddress +
                                                          (disDef.FrameTileCountX * tileY) +
                                                          tileX));
            }
            else
            {
                unchecked
                {
                    byte t = memory.LowLevelRead((ushort)(tileMapBaseAddress +
                                                          (disDef.FrameTileCountX * tileY) +
                                                          tileX));
                    sbyte tR = (sbyte)t;
                    tileOffset = tR;
                }
            }

            return(tileOffset);
        }
Exemplo n.º 7
0
        GetTileData(DisplayDefinition disDef, Memory memory,
                    int tileX, int tileY,
                    bool LCDCBit2, bool LCDBit3, bool LCDBit4,
                    bool wrap)
        {
            if (wrap)
            {
                tileX %= disDef.FrameTileCountX;
                tileY %= disDef.ScreenTileCountY;
            }
            else
            {
                if (tileX >= disDef.FrameTileCountX)
                {
                    tileX = disDef.FrameTileCountX - 1;
                }
                if (tileY >= disDef.ScreenTileCountY)
                {
                    tileY = disDef.ScreenTileCountY - 1;
                }
            }

            ushort tileMapBaseAddress = GetTileMapBaseAddress(LCDBit3);
            ushort tileBaseAddress    = GetTileBaseAddress(LCDBit4);
            int    tileOffset         = GetTileOffset(disDef, memory, tileMapBaseAddress, LCDBit4, tileX, tileY);

            // We obtain the correct tile index
            byte[] result = GetTileData(disDef, memory, tileBaseAddress, tileOffset, LCDCBit2);
            return(result);
        }
Exemplo n.º 8
0
 internal static void GetPixelRowFromBitmap(ref uint[] frameLineBuffer, 
                   DisplayDefinition disDef, uint[] bitmapData, int row, int stride)
 {
     int index = row * stride;
       for (int x = 0; x < stride; ++x)
       {
     frameLineBuffer[x] = bitmapData[index++];
       }
 }
Exemplo n.º 9
0
        GetPixelRowFromBitmap(ref uint[] frameLineBuffer,
                              DisplayDefinition disDef, uint[] bitmapData, int row, int stride)
        {
            int index = row * stride;

            for (int x = 0; x < stride; ++x)
            {
                frameLineBuffer[x] = bitmapData[index++];
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Display constructor.
        /// </summary>
        /// <param name="interruptController">A reference to the interrupt controller.</param>
        /// <param name="Memory">A reference to the memory.</param>
        public Display(InterruptController interruptController, Memory memory)
        {
            _interruptController = interruptController;
            _memory = memory;
            _disDef = new DisplayDefinition();
            _state  = new State();
            GeneratePixelLookupTable();

            Reset();
        }
Exemplo n.º 11
0
        SetupTilePallete(DisplayDefinition disDef, Memory memory)
        {
            // We extract the BGP (BG Pallete Data)
            byte bgp = memory.LowLevelRead((ushort)MMR.BGP);

            for (int color = 0; color < 4; ++color)
            {
                int down  = (bgp >> (2 * color)) & 1;
                int up    = (bgp >> (2 * color + 1)) & 1;
                int index = (up << 1) | down;
                disDef.TilePallete[color] = disDef.TileColors[index];
            }
        }
Exemplo n.º 12
0
        GetTileData(DisplayDefinition disDef, Memory memory,
                    int tileBaseAddress, int tileOffset,
                    bool LCDCBit2,
                    bool flipX = false, bool flipY = false)
        {
            int tileLength   = 16;
            int spriteLength = disDef.BytesPerTileShort;

            if (LCDCBit2)
            {
                spriteLength = disDef.BytesPerTileLong;
            }

            // We obtain the tile memory
            byte[] data = memory.LowLevelArrayRead(
                (ushort)(tileBaseAddress + (tileLength * tileOffset)),
                spriteLength);

            if (flipX)
            {
                for (int i = 0; i < spriteLength; ++i)
                {
                    byte d = data[i];
                    byte r = (byte)((flipLookup[d & 0x0F] << 4) | flipLookup[d >> 4]);
                    data[i] = r;
                }
            }

            if (flipY)
            {
                // NOTE(Cristian): We have to flip them in pairs, because
                //                 otherwise the colors change!
                for (int i = 0; i < spriteLength / 4; ++i)
                {
                    byte d0 = data[2 * i];
                    byte d1 = data[2 * i + 1];

                    int index = (spriteLength - 1) - 2 * i;
                    data[2 * i]     = data[index - 1];
                    data[2 * i + 1] = data[index];

                    data[index - 1] = d0;
                    data[index]     = d1;
                }
            }

            return(data);
        }
Exemplo n.º 13
0
        DrawTransparency(DisplayDefinition disDef, uint[] bitmapData, int stride,
                         int minX, int minY, int maxX, int maxY)
        {
            uint[] colors     = { 0xF0F0F0F0, 0xF0CDCDCD };
            int    squareSize = 5;

            for (int y = minY; y < maxY; y++)
            {
                int rowIndex = y * stride;
                for (int x = minX; x < maxX; x++)
                {
                    int sX         = x / squareSize;
                    int sY         = y / squareSize;
                    int colorIndex = (sX + (sY % 2)) % 2;
                    int pIndex     = rowIndex + x;
                    bitmapData[pIndex] = colors[colorIndex];
                }
            }
        }
Exemplo n.º 14
0
 DrawRectangle(DisplayDefinition disDef, uint[] bitmapData, int stride,
               int rX, int rY, int rWidth, int rHeight,
               uint color, bool fill = false)
 {
     for (int y = 0; y < rHeight; y++)
     {
         for (int x = 0; x < rWidth; x++)
         {
             int pX = (rX + x) % disDef.FramePixelCountX;
             int pY = (rY + y) % disDef.FramePixelCountY;
             if (fill ||
                 x == 0 || x == (rWidth - 1) ||
                 y == 0 || y == (rHeight - 1))
             {
                 int index = pY * stride + pX;
                 bitmapData[index] = color;
             }
         }
     }
 }
Exemplo n.º 15
0
 internal static void DrawRectangle(DisplayDefinition disDef, uint[] bitmapData, int stride,
           int rX, int rY, int rWidth, int rHeight,
           uint color, bool fill = false)
 {
     for (int y = 0; y < rHeight; y++)
       {
     for (int x = 0; x < rWidth; x++)
     {
       int pX = (rX + x) % disDef.FramePixelCountX;
       int pY = (rY + y) % disDef.FramePixelCountY;
       if (fill ||
      x == 0 || x == (rWidth - 1) ||
      y == 0 || y == (rHeight - 1))
       {
     int index = pY * stride + pX;
     bitmapData[index] = color;
       }
     }
       }
 }
Exemplo n.º 16
0
        DrawLine(DisplayDefinition disDef, uint[] bitmapData, int stride,
                 uint[] rowPixels,
                 int targetX, int targetY,
                 int rowStart, int rowSpan,
                 bool CopyZeroPixels = false,
                 bool wrap           = false)
        {
            // We obtain the data
            int baseIndex = targetY * stride + targetX;

            // NOTE(Cristian): rowMax is included
            for (int i = 0; i < stride; i++)
            {
                // NOTE(Cristian): Sometimes the window is 7 pixels to the left (in the case of the windows)
                //                 We must draw on those cases
                if (targetX < 0)
                {
                    targetX++;
                    continue;
                }

                int rowIndex = rowStart + i;
                if (rowIndex >= rowSpan)
                {
                    if (wrap)
                    {
                        rowIndex %= rowSpan;
                    }
                    else
                    {
                        break;
                    }
                }
                uint pixel = rowPixels[rowIndex];
                if (!CopyZeroPixels && pixel == 0)
                {
                    continue;
                }
                bitmapData[baseIndex + i] = rowPixels[rowIndex];
            }
        }
Exemplo n.º 17
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];
                }
            }
        }
Exemplo n.º 18
0
        internal static void DrawLine(DisplayDefinition disDef, uint[] bitmapData, int stride,
             uint[] rowPixels,
             int targetX, int targetY, 
             int rowStart, int rowSpan,
             bool CopyZeroPixels = false,
             bool wrap = false)
        {
            // We obtain the data
              int baseIndex = targetY * stride + targetX;
              // NOTE(Cristian): rowMax is included
              for (int i = 0; i < stride; i++)
              {
            // NOTE(Cristian): Sometimes the window is 7 pixels to the left (in the case of the windows)
            //                 We must draw on those cases
            if (targetX < 0)
            {
              targetX++;
              continue;
            }

            int rowIndex = rowStart + i;
            if (rowIndex >= rowSpan)
            {
              if(wrap)
              {
            rowIndex %= rowSpan;
              }
              else
              {
            break;
              }
            }
            uint pixel = rowPixels[rowIndex];
            if (!CopyZeroPixels && pixel == 0) { continue; }
            bitmapData[baseIndex + i] = rowPixels[rowIndex];
              }
        }
Exemplo n.º 19
0
        GetSpriteRowPixels(short[] pixelLookupTable,
                           DisplayDefinition disDef, Memory memory, OAM[] spriteOAMs,
                           uint[] targetPixels, uint[] pixelBuffer,
                           int row, bool LCDCBit2,
                           bool ignoreBackgroundPriority = false)
        {
            int scanLineSize = GetScanLineOAMs(disDef, spriteOAMs, row, LCDCBit2);

            // We obtain the pixels we want from it
            for (int oamIndex = scanLineSize - 1; oamIndex >= 0; --oamIndex)
            {
                OAM oam = scanLineOAMs[oamIndex];

                bool   flipX      = Utils.UtilFuncs.TestBit(oam.Flags, 5) != 0;
                bool   flipY      = Utils.UtilFuncs.TestBit(oam.Flags, 6) != 0;
                byte[] tilePixels = GetTileData(disDef, memory, 0x8000, oam.SpriteCode,
                                                LCDCBit2, flipX, flipY);

                int x = oam.X - 8;
                int y = row - (oam.Y - 16);

                uint[] spritePallete = (Utils.UtilFuncs.TestBit(oam.Flags, 4) == 0) ?
                                       disDef.SpritePallete0 : disDef.SpritePallete1;

                GetPixelsFromTileBytes(pixelLookupTable,
                                       ref pixelBuffer,
                                       spritePallete,
                                       disDef.PixelPerTileX,
                                       tilePixels[2 * y], tilePixels[2 * y + 1]);
                bool backgroundPriority = (Utils.UtilFuncs.TestBit(oam.Flags, 7) != 0);
                if (ignoreBackgroundPriority)
                {
                    backgroundPriority = false;
                }
                for (int i = 0; i < 8; ++i)
                {
                    int pX = x + i;
                    if (pX < 0)
                    {
                        continue;
                    }
                    if (pX >= disDef.ScreenPixelCountX)
                    {
                        break;
                    }
                    uint color = pixelBuffer[i];
                    if (color == 0)
                    {
                        continue;
                    }                   // transparent pixel

                    // NOTE(Cristian): If the BG priority bit is set, the sprite is hidden
                    //                 on every color except tile color 0
                    if (backgroundPriority)
                    {
                        if (targetPixels[pX] != disDef.TileColors[0])
                        {
                            continue;
                        }
                    }
                    targetPixels[pX] = color;
                }
            }
        }
Exemplo n.º 20
0
        internal static void SetupSpritePalletes(DisplayDefinition disDef, Memory memory, MMR pallete)
        {
            if (pallete == MMR.OBP0)
              {

            byte obp0 = memory.LowLevelRead((ushort)MMR.OBP0);
            disDef.SpritePallete0[0] = 0x00000000; // Sprite colors are trasparent
            for (int color = 1; color < 4; ++color)
            {
              int down = (obp0 >> (2 * color)) & 1;
              int up = (obp0 >> (2 * color + 1)) & 1;
              int index = (up << 1) | down;
              disDef.SpritePallete0[color] = disDef.SpriteColors[index];
            }
              }
              else if (pallete == MMR.OBP1)
              {
            byte obp1 = memory.LowLevelRead((ushort)MMR.OBP1);
            disDef.SpritePallete1[1] = 0x00000000; // Sprite colors are trasparent
            for (int color = 1; color < 4; ++color)
            {
              int down = (obp1 >> (2 * color)) & 1;
              int up = (obp1 >> (2 * color + 1)) & 1;
              int index = (up << 1) | down;
              disDef.SpritePallete1[color] = disDef.SpriteColors[index];
            }
              }
              else
              {
            throw new InvalidProgramException("Invalid pallete register given");
              }
        }
Exemplo n.º 21
0
        internal static void SetupTilePallete(DisplayDefinition disDef, Memory memory)
        {
            // We extract the BGP (BG Pallete Data)
              byte bgp = memory.LowLevelRead((ushort)MMR.BGP);

              for (int color = 0; color < 4; ++color)
              {
            int down = (bgp >> (2 * color)) & 1;
            int up = (bgp >> (2 * color + 1)) & 1;
            int index = (up << 1) | down;
            disDef.TilePallete[color] = disDef.TileColors[index];
              }
        }
Exemplo n.º 22
0
        internal static byte[] GetTileData(DisplayDefinition disDef, Memory memory,
                int tileBaseAddress, int tileOffset,
                bool LCDCBit2,
                bool flipX = false, bool flipY = false)
        {
            int tileLength = 16;
              int spriteLength = disDef.BytesPerTileShort;
              if (LCDCBit2) { spriteLength = disDef.BytesPerTileLong; }

              // We obtain the tile memory
              byte[] data = memory.LowLevelArrayRead(
            (ushort)(tileBaseAddress + (tileLength * tileOffset)),
            spriteLength);

              if (flipX)
              {
            for (int i = 0; i < spriteLength; ++i)
            {
              byte d = data[i];
              byte r = (byte)((flipLookup[d & 0x0F] << 4) | flipLookup[d >> 4]);
              data[i] = r;
            }
              }

              if (flipY)
              {
            // NOTE(Cristian): We have to flip them in pairs, because
            //                 otherwise the colors change!
            for (int i = 0; i < spriteLength / 4; ++i)
            {
              byte d0 = data[2 * i];
              byte d1 = data[2 * i + 1];

              int index = (spriteLength - 1) - 2 * i;
              data[2 * i] = data[index - 1];
              data[2 * i + 1] = data[index];

              data[index - 1] = d0;
              data[index] = d1;
            }
              }

              return data;
        }
Exemplo n.º 23
0
        internal static int GetTileOffset(DisplayDefinition disDef, Memory memory,
                  ushort tileMapBaseAddress, bool LCDBit4,
                  int tileX, int tileY)
        {
            int tileOffset;
              if (LCDBit4)
              {
            tileOffset = memory.LowLevelRead((ushort)(tileMapBaseAddress +
                                                 (disDef.FrameTileCountX * tileY) +
                                                 tileX));
              }
              else
              {
            unchecked
            {
              byte t = memory.LowLevelRead((ushort)(tileMapBaseAddress +
                                                (disDef.FrameTileCountX * tileY) +
                                                tileX));
              sbyte tR = (sbyte)t;
              tileOffset = tR;
            }
              }

              return tileOffset;
        }
Exemplo n.º 24
0
        /// <summary>
        /// Display constructor.
        /// </summary>
        /// <param name="interruptController">A reference to the interrupt controller.</param>
        /// <param name="Memory">A reference to the memory.</param>
        public Display(InterruptController interruptController, Memory memory)
        {
            _interruptController = interruptController;
              _memory = memory;
              _disDef = new DisplayDefinition();
              _state = new State();
              GeneratePixelLookupTable();

              Reset();
        }
Exemplo n.º 25
0
        /// <summary>
        /// Retreives a the contents on a tile depending on the coordinates and the accessing methods.
        /// </summary>
        /// <param name="tileX">The x coord for the tile</param>
        /// <param name="tileY">The y coord for the tile</param>
        /// <param name="LCDBit3">
        /// Whether the LCDC Register (0xFF40) Bit 3 is enabled.
        /// Determines what tilemap (where the tile indexes are) is used:
        /// 0: 0x9800 - 0x9BFF
        /// 1: 0x9C00 - 0x9FFF
        /// </param>
        /// <param name="LCDBit4">
        /// Whether the LCDC Register (0xFF40) Bit 3 is enabled.
        /// Determines the base address for the actual tiles and the
        /// accessing method (interpretation of the byte tile index retreived from the tilemap).
        /// 0: 0x8800 - 0x97FF | signed access
        /// 1: 0x8000 - 0x8FFF | unsigned access
        /// </param>
        /// <param name="wrap">Whether the x, y tile coordinates should wrap or be clipped</param>
        /// <returns>A byte[] with the 16 bytes that create a tile</returns>
        internal static byte[] GetTileData(DisplayDefinition disDef, Memory memory,
                int tileX, int tileY,
                bool LCDCBit2, bool LCDBit3, bool LCDBit4,
                bool wrap)
        {
            if (wrap)
              {
            tileX %= disDef.FrameTileCountX;
            tileY %= disDef.ScreenTileCountY;
              }
              else
              {
            if (tileX >= disDef.FrameTileCountX) { tileX = disDef.FrameTileCountX - 1; }
            if (tileY >= disDef.ScreenTileCountY) { tileY = disDef.ScreenTileCountY - 1; }
              }

              ushort tileMapBaseAddress = GetTileMapBaseAddress(LCDBit3);
              ushort tileBaseAddress = GetTileBaseAddress(LCDBit4);
              int tileOffset = GetTileOffset(disDef, memory, tileMapBaseAddress, LCDBit4, tileX, tileY);

              // We obtain the correct tile index
              byte[] result = GetTileData(disDef, memory, tileBaseAddress, tileOffset, LCDCBit2);
              return result;
        }
Exemplo n.º 26
0
        internal static void GetSpriteRowPixels(short[] pixelLookupTable,
                       DisplayDefinition disDef, Memory memory, OAM[] spriteOAMs,
                       uint[] targetPixels, uint[] pixelBuffer,
                       int row, bool LCDCBit2,
                       bool ignoreBackgroundPriority = false)
        {
            int scanLineSize = GetScanLineOAMs(disDef, spriteOAMs, row, LCDCBit2);

              // We obtain the pixels we want from it
              for (int oamIndex = scanLineSize - 1; oamIndex >= 0; --oamIndex)
              {
            OAM oam = scanLineOAMs[oamIndex];

            bool flipX = Utils.UtilFuncs.TestBit(oam.Flags, 5) != 0;
            bool flipY = Utils.UtilFuncs.TestBit(oam.Flags, 6) != 0;
            byte[] tilePixels = GetTileData(disDef, memory, 0x8000, oam.SpriteCode,
                                        LCDCBit2, flipX, flipY);

            int x = oam.X - 8;
            int y = row - (oam.Y - 16);

            uint[] spritePallete = (Utils.UtilFuncs.TestBit(oam.Flags, 4) == 0) ?
                                  disDef.SpritePallete0 : disDef.SpritePallete1;

            GetPixelsFromTileBytes(pixelLookupTable,
                               ref pixelBuffer,
                               spritePallete,
                               disDef.PixelPerTileX,
                               tilePixels[2 * y], tilePixels[2 * y + 1]);
            bool backgroundPriority = (Utils.UtilFuncs.TestBit(oam.Flags, 7) != 0);
            if (ignoreBackgroundPriority)
            {
              backgroundPriority = false;
            }
            for (int i = 0; i < 8; ++i)
            {
              int pX = x + i;
              if (pX < 0) { continue; }
              if (pX >= disDef.ScreenPixelCountX) { break; }
              uint color = pixelBuffer[i];
              if (color == 0) { continue; } // transparent pixel

              // NOTE(Cristian): If the BG priority bit is set, the sprite is hidden
              //                 on every color except tile color 0
              if (backgroundPriority)
              {
            if (targetPixels[pX] != disDef.TileColors[0]) { continue; }
              }
              targetPixels[pX] = color;
            }
              }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Gets the OAMs for the a certain row
        /// </summary>
        /// <param name="spriteOAMs"></param>
        /// <param name="row"></param>
        /// <param name="LCDCBit2"></param>
        /// <returns></returns>
        internal static int GetScanLineOAMs(DisplayDefinition disDef, OAM[] spriteOAMs, int row, bool LCDCBit2)
        {
            int spriteSize = disDef.BytesPerTileShort / 2;
              if (LCDCBit2) { spriteSize = disDef.BytesPerTileLong / 2; }

              // Then we select the 10 that correspond
              int scanLineSize = 0;
              int maxScanLineSize = 10;
              foreach (OAM oam in spriteOAMs)
              {
            int y = oam.Y - 16;
            if ((y <= row) && (row < (y + spriteSize)))
            {
              scanLineOAMs[scanLineSize++] = oam;
              if (scanLineSize == maxScanLineSize) { break; }
            }
              }

              return scanLineSize;
        }
Exemplo n.º 28
0
 internal static void DrawTransparency(DisplayDefinition disDef, uint[] bitmapData, int stride,
             int minX, int minY, int maxX, int maxY)
 {
     uint[] colors = { 0xF0F0F0F0, 0xF0CDCDCD };
       int squareSize = 5;
       for (int y = minY; y < maxY; y++)
       {
     int rowIndex = y * stride;
     for (int x = minX; x < maxX; x++)
     {
       int sX = x / squareSize;
       int sY = y / squareSize;
       int colorIndex = (sX + (sY % 2)) % 2;
       int pIndex = rowIndex + x;
       bitmapData[pIndex] = colors[colorIndex];
     }
       }
 }