void draw(int tile) { int offset = tile * 16; if (!(offset >= offsetStart && offset < offsetEnd)) { return; } int x = ((offset - offsetStart) / 16) % Width; int y = ((offset - offsetStart) / 16) / Width; int bank = 0; if (offset >= 0x1800) { offset -= 0x1800; bank = 1; } byte[] data = new byte[16]; Array.Copy(graphicsState.VramBuffer[bank], offset, data, 0, 16); Bitmap subImage = GbGraphics.TileToBitmap(data); Graphics g = Graphics.FromImage(image); g.DrawImage(subImage, x * 8, y * 8); QueueDraw(); }
public Bitmap GetTileImage(int index) { if (tileImagesCache[index] != null) { return(tileImagesCache[index]); } Bitmap image = new Bitmap(16, 16); Graphics g = Graphics.FromImage(image); for (int y = 0; y < 2; y++) { for (int x = 0; x < 2; x++) { int tileIndex = GetSubTileIndex(index, x, y); int flags = GetSubTileFlags(index, x, y); int tileOffset = 0x1000 + ((sbyte)tileIndex) * 16; byte[] src = new byte[16]; Array.Copy(graphicsState.VramBuffer[1], tileOffset, src, 0, 16); Bitmap subImage = GbGraphics.TileToBitmap(src, GraphicsState.GetBackgroundPalettes()[flags & 7], flags); g.DrawImageUnscaled(subImage, x * 8, y * 8); } } g.Dispose(); // if (fullCachedImageData == null) // fullCachedImageData = fullCachedImage.LockBits( // new Rectangle(0, 0, fullCachedImage.Width, fullCachedImage.Height), // ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // GbGraphics.QuickDraw(fullCachedImageData, image, (index%16)*16, (index/16)*16); g = Graphics.FromImage(fullCachedImage); g.DrawImageUnscaled(image, (index % 16) * 16, (index / 16) * 16); g.Dispose(); tileImagesCache[index] = image; return(image); }
public ObjectAnimationFrame(ObjectAnimation anim, Data animData) { _animation = anim; _animData = animData; Color[][] palettes = anim.GetPalettes(); try { // Note: this "index" is more like index*2, since it's added directly to the offset // without being multiplied first int oamIndex = (byte)_animData.NextData.GetIntValue(0); // Get entry in oam table for this object Data oamPtr = Project.GetData(_animation.OamTableName, oamIndex); _oamData = Project.GetData(oamPtr.GetValue(0)); // Load sprite images int _numSprites = _oamData.GetIntValue(0); Data data = _oamData.NextData; for (int i = 0; i < _numSprites; i++) { int y = (sbyte)data.GetIntValue(0) - 16; data = data.NextData; int x = (sbyte)data.GetIntValue(0) - 8; data = data.NextData; int tileIndex = data.GetIntValue(0) + _animation.TileIndexBase; data = data.NextData; byte flags = (byte)(data.GetIntValue(0) | _animation.OamFlagsBase); data = data.NextData; ObjectGfxHeaderData gfxHeader = _animation.ObjectGfxHeaderData; int origTileIndex = tileIndex; while (tileIndex >= 0x20) { if (gfxHeader.ShouldHaveNext) { gfxHeader = gfxHeader.NextGfxHeader; tileIndex -= 0x20; } else { throw new InvalidAnimationException("Tileindex out of range (" + tileIndex + ")"); } } int tileOffset = (tileIndex & 0xfe) * 16; Stream gfxStream = gfxHeader.GfxStream; if (gfxStream.Length - tileOffset < 0x20) { throw new InvalidAnimationException("Sprite not defined in gfx data"); } gfxStream.Seek(tileOffset, SeekOrigin.Begin); byte[] gfxData = new byte[0x20]; gfxStream.Read(gfxData, 0, 0x20); Bitmap bitmap = GbGraphics.TileToBitmap(gfxData, palettes[flags & 7], flags); bitmaps.Add(new Tuple <Bitmap, int, int>(bitmap, x, y)); } } catch (InvalidLookupException e) { bitmaps = null; throw new InvalidAnimationException(e); } catch (FormatException e) { bitmaps = null; throw new InvalidAnimationException(e); } }