unsafe float GetSpriteBB_RightX( int size, int tileX, int tileY, FastBitmap fastBmp )
 {
     for( int x = size - 1; x >= 0; x-- ) {
         for( int y = 0; y < size; y++ ) {
             int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
             if( (row[x] & alphaTest) != 0 )
                 return (float)(x + 1) / size;
         }
     }
     return 0;
 }
 unsafe float GetSpriteBB_TopY( int size, int tileX, int tileY, FastBitmap fastBmp )
 {
     for( int y = 0; y < size; y++ ) {
         int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
         for( int x = 0; x < size; x++ ) {
             if( (row[x] & alphaTest) != 0 )
                 return 1 - (float)y / size;
         }
     }
     return 0;
 }
 unsafe float GetSpriteBB_LeftX( int size, int tileX, int tileY, FastBitmap fastBmp )
 {
     for( int x = 0; x < size; x++ ) {
         for( int y = 0; y < size; y++ ) {
             int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
             if( (byte)(row[x] >> 24) != 0 )
                 return (float)x / size;
         }
     }
     return 1;
 }
 unsafe float GetSpriteBB_BottomY( int size, int tileX, int tileY, FastBitmap fastBmp )
 {
     for( int y = size - 1; y >= 0; y-- ) {
         int* row = fastBmp.GetRowPtr( tileY * size + y ) + (tileX * size);
         for( int x = 0; x < size; x++ ) {
             if( (row[x] & alphaTest) != 0 )
                 return 1 - (float)(y + 1) / size;
         }
     }
     return 1;
 }
        internal void RecalculateBB( int block, FastBitmap fastBmp )
        {
            int elemSize = fastBmp.Width / 16;
            int texId = GetTextureLoc( (byte)block, TileSide.Top );
            float topY = GetSpriteBB_TopY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
            float bottomY = GetSpriteBB_BottomY( elemSize, texId & 0x0F, texId >> 4, fastBmp );
            float leftX = GetSpriteBB_LeftX( elemSize, texId & 0x0F, texId >> 4, fastBmp );
            float rightX = GetSpriteBB_RightX( elemSize, texId & 0x0F, texId >> 4, fastBmp );

            MinBB[block] = Utils.RotateY( leftX - 0.5f, bottomY, 0, 45f * Utils.Deg2Rad )
                + new Vector3( 0.5f, 0, 0.5f );
            MaxBB[block] = Utils.RotateY( rightX - 0.5f, topY, 0, 45f * Utils.Deg2Rad )
                + new Vector3( 0.5f, 0, 0.5f );
        }
        internal void RecalculateBB( int block, FastBitmap fastBmp )
        {
            int elemSize = fastBmp.Width / 16;
            int texId = GetTextureLoc( (byte)block, Side.Top );
            int texX = texId & 0x0F, texY = texId >> 4;

            float topY = GetSpriteBB_TopY( elemSize, texX, texY, fastBmp );
            float bottomY = GetSpriteBB_BottomY( elemSize, texX, texY, fastBmp );
            float leftX = GetSpriteBB_LeftX( elemSize, texX, texY, fastBmp );
            float rightX = GetSpriteBB_RightX( elemSize, texX, texY, fastBmp );

            MinBB[block] = Utils.RotateY( leftX - 0.5f, bottomY, 0, angle ) + centre;
            MaxBB[block] = Utils.RotateY( rightX - 0.5f, topY, 0, angle ) + centre;
        }
Пример #7
0
        /// <summary> Reads a bitmap from the stream (converting it to 32 bits per pixel if necessary),
        /// and updates the native texture for it. </summary>
        public void UpdateTexture(ref int texId, byte[] data, bool setSkinType)
        {
            MemoryStream stream = new MemoryStream(data);

            Graphics.DeleteTexture(ref texId);

            using (Bitmap bmp = Platform.ReadBmp(stream)) {
                if (setSkinType)
                {
                    DefaultPlayerSkinType = Utils.GetSkinType(bmp);
                }

                if (!FastBitmap.CheckFormat(bmp.PixelFormat))
                {
                    using (Bitmap bmp32 = Drawer2D.ConvertTo32Bpp(bmp))
                        texId = Graphics.CreateTexture(bmp32);
                }
                else
                {
                    texId = Graphics.CreateTexture(bmp);
                }
            }
        }
Пример #8
0
        protected void DrawBitmapTextImpl(FastBitmap dst, ref DrawTextArgs args, int x, int y)
        {
            bool underline = args.Font.Style == FontStyle.Underline;

            if (args.UseShadow)
            {
                int offset = ShadowOffset(args.Font.Size);
                DrawPart(dst, ref args, x + offset, y + offset, true);
#if !LAUNCHER
                if (underline)
                {
                    DrawUnderline(dst, x + offset, 0, ref args, true);
                }
#endif
            }

            DrawPart(dst, ref args, x, y, false);
#if !LAUNCHER
            if (underline)
            {
                DrawUnderline(dst, x, -2, ref args, false);
            }
#endif
        }
Пример #9
0
        protected void DrawBitmapTextImpl(FastBitmap dst, ref DrawTextArgs args, int x, int y)
        {
            bool ul     = args.Font.Style == FontStyle.Underline;
            int  offset = Utils.Floor(args.Font.Size) / 8;

            if (args.UseShadow)
            {
                DrawCore(dst, ref args, x + offset, y + offset, true);
                                #if !LAUNCHER
                if (ul)
                {
                    DrawUnderline(dst, ref args, x + offset, y + offset, true);
                }
                                #endif
            }

            DrawCore(dst, ref args, x, y, false);
                        #if !LAUNCHER
            if (ul)
            {
                DrawUnderline(dst, ref args, x, y, false);
            }
                        #endif
        }
 public void RecalculateSpriteBB( FastBitmap fastBmp )
 {
     for( int i = 0; i < 256; i++ ) {
         if( IsSprite[i] ) RecalculateBB( i, fastBmp );
     }
 }
        void DrawRun(FastBitmap dst, int x, int y, int xMul,
                     int runCount, byte *coords, int point, FastColour col)
        {
            if (runCount == 0)
            {
                return;
            }
            int srcY = (coords[0] >> 4) * boxSize;
            int textHeight = AdjTextSize(point), cellHeight = CellSize(textHeight);
            int padding = (cellHeight - textHeight) / 2;
            int startX  = x;

            ushort *dstWidths = stackalloc ushort[runCount];

            for (int i = 0; i < runCount; i++)
            {
                dstWidths[i] = (ushort)PtToPx(point, widths[coords[i]]);
            }

            for (int yy = 0; yy < textHeight; yy++)
            {
                int  fontY   = srcY + yy * boxSize / textHeight;
                int *fontRow = fontPixels.GetRowPtr(fontY);
                int  dstY    = y + (yy + padding);
                if (dstY >= dst.Height)
                {
                    return;
                }

                int *dstRow  = dst.GetRowPtr(dstY);
                int  xOffset = xMul * ((textHeight - 1 - yy) / italicSize);
                for (int i = 0; i < runCount; i++)
                {
                    int srcX = (coords[i] & 0x0F) * boxSize;
                    int srcWidth = widths[coords[i]], dstWidth = dstWidths[i];

                    for (int xx = 0; xx < dstWidth; xx++)
                    {
                        int fontX = srcX + xx * srcWidth / dstWidth;
                        int src   = fontRow[fontX];
                        if ((byte)(src >> 24) == 0)
                        {
                            continue;
                        }
                        int dstX = x + xx + xOffset;
                        if (dstX >= dst.Width)
                        {
                            break;
                        }

                        int pixel = src & ~0xFFFFFF;
                        pixel       |= ((src & 0xFF) * col.B / 255);
                        pixel       |= (((src >> 8) & 0xFF) * col.G / 255) << 8;
                        pixel       |= (((src >> 16) & 0xFF) * col.R / 255) << 16;
                        dstRow[dstX] = pixel;
                    }
                    x += PtToPx(point, srcWidth + 1);
                }
                x = startX;
            }
        }
Пример #12
0
        void DrawCore(FastBitmap dst, ref DrawTextArgs args, int x, int y, bool shadow)
        {
            PackedCol col = Cols['f'];

            if (shadow)
            {
                col = BlackTextShadows ? PackedCol.Black : PackedCol.Scale(col, 0.25f);
            }

            string text = args.Text;
            int    point = Utils.Floor(args.Font.Size), count = 0;

            byte *     coords    = stackalloc byte[256];
            PackedCol *cols      = stackalloc PackedCol[256];
            ushort *   dstWidths = stackalloc ushort[256];

            for (int i = 0; i < text.Length; i++)
            {
                char c = text[i];
                if (c == '&' && ValidColCode(text, i + 1))
                {
                    col = GetCol(text[i + 1]);
                    if (shadow)
                    {
                        col = BlackTextShadows ? PackedCol.Black : PackedCol.Scale(col, 0.25f);
                    }
                    i++; continue;                     // Skip over the colour code.
                }

                byte cur = Utils.UnicodeToCP437(c);
                coords[count]    = cur;
                cols[count]      = col;
                dstWidths[count] = (ushort)Width(point, cur);
                count++;
            }

            int dstHeight = point, startX = x;
            // adjust coords to make drawn text match GDI fonts
            int xPadding = Utils.CeilDiv(point, 8);
            int yPadding = (AdjHeight(dstHeight) - dstHeight) / 2;

            for (int yy = 0; yy < dstHeight; yy++)
            {
                int dstY = y + (yy + yPadding);
                if (dstY >= dst.Height)
                {
                    return;
                }

                int  fontY  = 0 + yy * boxSize / dstHeight;
                int *dstRow = dst.GetRowPtr(dstY);

                for (int i = 0; i < count; i++)
                {
                    int  srcX    = (coords[i] & 0x0F) * boxSize;
                    int  srcY    = (coords[i] >> 4) * boxSize;
                    int *fontRow = fontPixels.GetRowPtr(fontY + srcY);

                    int srcWidth = widths[coords[i]], dstWidth = dstWidths[i];
                    col = cols[i];

                    for (int xx = 0; xx < dstWidth; xx++)
                    {
                        int fontX = srcX + xx * srcWidth / dstWidth;
                        int src   = fontRow[fontX];
                        if ((byte)(src >> 24) == 0)
                        {
                            continue;
                        }

                        int dstX = x + xx;
                        if (dstX >= dst.Width)
                        {
                            break;
                        }

                        int pixel = src & ~0xFFFFFF;
                        pixel       |= ((src & 0xFF) * col.B / 255);
                        pixel       |= (((src >> 8) & 0xFF) * col.G / 255) << 8;
                        pixel       |= (((src >> 16) & 0xFF) * col.R / 255) << 16;
                        dstRow[dstX] = pixel;
                    }
                    x += dstWidth + xPadding;
                }
                x = startX;
            }
        }
		public static void CopyRow( int srcY, int dstY, FastBitmap src, FastBitmap dst, int width ) {
			int* srcRow = src.GetRowPtr( srcY ), dstRow = dst.GetRowPtr( dstY);
			for( int x = 0; x < width; x++ )
				dstRow[x] = srcRow[x];
		}
Пример #14
0
 /// <summary> Updates the underlying atlas bitmap </summary>
 public void UpdateState()
 {
     using (FastBitmap fastBmp = new FastBitmap(AtlasBitmap, true, true))
         BlockInfo.RecalculateSpriteBB(fastBmp);
 }
Пример #15
0
		void HandleCpeDefineBlock() {
			byte block = reader.ReadUInt8();
			BlockInfo info = game.BlockInfo;
			info.ResetBlockInfo( block );
			
			info.Name[block] = reader.ReadAsciiString();
			info.CollideType[block] = (BlockCollideType)reader.ReadUInt8();
			if( info.CollideType[block] != BlockCollideType.Solid ) {
				info.IsTransparent[block] = true;
				info.IsOpaque[block] = false;
			}
			
			info.SpeedMultiplier[block] = (float)Math.Pow( 2, (reader.ReadUInt8() - 128) / 64f );
			info.SetTop( reader.ReadUInt8(), (Block)block );
			info.SetSide( reader.ReadUInt8(), (Block)block );
			info.SetBottom( reader.ReadUInt8(), (Block)block );
			info.BlocksLight[block] = reader.ReadUInt8() == 0;
			reader.ReadUInt8(); // walk sound, but we ignore this.
			info.FullBright[block] = reader.ReadUInt8() != 0;
			
			byte shape = reader.ReadUInt8();
			if( shape == 2 ) {
				info.Height[block] = 0.5f;
			} else if( shape == 3 ) { // TODO: upside down slab not properly supported
				info.Height[block] = 0.5f;
			} else if( shape == 4 ) {
				info.IsSprite[block] = true;
			}
			if( info.IsOpaque[block] )
				info.IsOpaque[block] = shape == 0;
			if( shape != 1 )
				info.IsTransparent[block] = true;
			
			byte blockDraw = reader.ReadUInt8();
			if( blockDraw == 1 ) {
				info.IsTransparent[block] = true;
			} else if( blockDraw == 2 ) {
				info.IsTransparent[block] = true;
				info.CullWithNeighbours[block] = false;
			} else if( blockDraw == 3 ) {
				info.IsTranslucent[block] = true;
			}
			if( info.IsOpaque[block] )
				info.IsOpaque[block] = blockDraw == 0;
			
			byte fogDensity = reader.ReadUInt8();
			info.FogDensity[block] = fogDensity == 0 ? 0 : (fogDensity + 1) / 128f;
			info.FogColour[block] = new FastColour(
				reader.ReadUInt8(), reader.ReadUInt8(), reader.ReadUInt8() );
			info.SetupCullingCache();
			
			// Update sprite BoundingBox if necessary
			if( info.IsSprite[block] ) {
				using( FastBitmap fastBmp =
				      new FastBitmap( game.TerrainAtlas.AtlasBitmap, true ) ) {
					info.RecalculateBB( block, fastBmp );
				}
			}
		}
Пример #16
0
        protected void CheckAsyncResources()
        {
            DownloadedItem item;

            if (game.AsyncDownloader.TryGetItem("terrain", out item))
            {
                if (item.Data != null)
                {
                    Bitmap bmp = (Bitmap)item.Data;
                    game.World.TextureUrl = item.Url;
                    game.Events.RaiseTexturePackChanged();

                    if (!FastBitmap.CheckFormat(bmp.PixelFormat))
                    {
                        Utils.LogDebug("Converting terrain atlas to 32bpp image");
                        game.Drawer2D.ConvertTo32Bpp(ref bmp);
                    }
                    if (!game.ChangeTerrainAtlas(bmp))
                    {
                        bmp.Dispose(); return;
                    }
                    TextureCache.AddToCache(item.Url, bmp);
                    TextureCache.AddETagToCache(item.Url, item.ETag, game.ETags);
                }
                else if (item.ResponseCode == HttpStatusCode.NotModified)
                {
                    Bitmap bmp = TextureCache.GetBitmapFromCache(item.Url);
                    if (bmp == null)                       // Should never happen, but handle anyways.
                    {
                        ExtractDefault();
                    }
                    else if (item.Url != game.World.TextureUrl)
                    {
                        game.Events.RaiseTexturePackChanged();
                        if (!game.ChangeTerrainAtlas(bmp))
                        {
                            bmp.Dispose(); return;
                        }
                    }

                    if (bmp != null)
                    {
                        game.World.TextureUrl = item.Url;
                    }
                }
                else
                {
                    ExtractDefault();
                }
            }

            if (game.AsyncDownloader.TryGetItem("texturePack", out item))
            {
                if (item.Data != null)
                {
                    game.World.TextureUrl = item.Url;

                    TexturePackExtractor extractor = new TexturePackExtractor();
                    extractor.Extract((byte[])item.Data, game);
                    TextureCache.AddToCache(item.Url, (byte[])item.Data);
                    TextureCache.AddETagToCache(item.Url, item.ETag, game.ETags);
                }
                else if (item.ResponseCode == HttpStatusCode.NotModified)
                {
                    byte[] data = TextureCache.GetDataFromCache(item.Url);
                    if (data == null)                        // Should never happen, but handle anyways.
                    {
                        ExtractDefault();
                    }
                    else if (item.Url != game.World.TextureUrl)
                    {
                        TexturePackExtractor extractor = new TexturePackExtractor();
                        extractor.Extract(data, game);
                    }

                    if (data != null)
                    {
                        game.World.TextureUrl = item.Url;
                    }
                }
                else
                {
                    ExtractDefault();
                }
            }
        }
Пример #17
0
        protected void CheckAsyncResources()
        {
            DownloadedItem item;

            if (game.AsyncDownloader.TryGetItem("terrain", out item))
            {
                if (item.Data != null)
                {
                    Bitmap bmp = (Bitmap)item.Data;
                    if (!FastBitmap.CheckFormat(bmp.PixelFormat))
                    {
                        Utils.LogDebug("Converting terrain atlas to 32bpp image");
                        game.Drawer2D.ConvertTo32Bpp(ref bmp);
                    }
                    game.ChangeTerrainAtlas(bmp);
                    TextureCache.AddToCache(item.Url, bmp);
                    game.Map.TextureUrl = item.Url;
                }
                else if (Is304Status(item.WebEx))
                {
                    Bitmap bmp = TextureCache.GetBitmapFromCache(item.Url);
                    if (bmp == null)                      // Should never happen, but handle anyways.
                    {
                        ExtractDefault();
                    }
                    else
                    {
                        game.ChangeTerrainAtlas(bmp);
                    }
                    game.Map.TextureUrl = item.Url;
                }
                else
                {
                    ExtractDefault();
                    game.Map.TextureUrl = null;
                }
            }

            if (game.AsyncDownloader.TryGetItem("texturePack", out item))
            {
                if (item.Data != null)
                {
                    TexturePackExtractor extractor = new TexturePackExtractor();
                    extractor.Extract((byte[])item.Data, game);
                    TextureCache.AddToCache(item.Url, (byte[])item.Data);
                    game.Map.TextureUrl = item.Url;
                }
                else if (Is304Status(item.WebEx))
                {
                    byte[] data = TextureCache.GetDataFromCache(item.Url);
                    if (data == null)                        // Should never happen, but handle anyways.
                    {
                        ExtractDefault();
                    }
                    else
                    {
                        TexturePackExtractor extractor = new TexturePackExtractor();
                        extractor.Extract(data, game);
                    }
                    game.Map.TextureUrl = item.Url;
                }
                else
                {
                    ExtractDefault();
                    game.Map.TextureUrl = null;
                }
            }
        }
Пример #18
0
 public static void MovePortion(int srcX, int srcY, int dstX, int dstY, FastBitmap src, FastBitmap dst, int size)
 {
     for (int y = 0; y < size; y++)
     {
         int *srcRow = src.GetRowPtr(srcY + y);
         int *dstRow = dst.GetRowPtr(dstY + y);
         for (int x = 0; x < size; x++)
         {
             dstRow[dstX + x] = srcRow[srcX + x];
         }
     }
 }
Пример #19
0
        public void Reset(Game game)
        {
            // Reset properties
            for (int i = 0; i < IsTransparent.Length; i++)
            {
                IsTransparent[i] = false;
            }
            for (int i = 0; i < IsTranslucent.Length; i++)
            {
                IsTranslucent[i] = false;
            }
            for (int i = 0; i < IsOpaque.Length; i++)
            {
                IsOpaque[i] = false;
            }
            for (int i = 0; i < IsOpaqueY.Length; i++)
            {
                IsOpaqueY[i] = false;
            }
            for (int i = 0; i < IsSprite.Length; i++)
            {
                IsSprite[i] = false;
            }
            for (int i = 0; i < IsLiquid.Length; i++)
            {
                IsLiquid[i] = false;
            }
            for (int i = 0; i < BlocksLight.Length; i++)
            {
                BlocksLight[i] = false;
            }
            for (int i = 0; i < FullBright.Length; i++)
            {
                FullBright[i] = false;
            }
            for (int i = 0; i < Name.Length; i++)
            {
                Name[i] = "Invalid";
            }
            for (int i = 0; i < FogColour.Length; i++)
            {
                FogColour[i] = default(FastColour);
            }
            for (int i = 0; i < FogDensity.Length; i++)
            {
                FogDensity[i] = 0;
            }
            for (int i = 0; i < Collide.Length; i++)
            {
                Collide[i] = CollideType.WalkThrough;
            }
            for (int i = 0; i < SpeedMultiplier.Length; i++)
            {
                SpeedMultiplier[i] = 0;
            }
            for (int i = 0; i < CullWithNeighbours.Length; i++)
            {
                CullWithNeighbours[i] = false;
            }
            for (int i = 0; i < LightOffset.Length; i++)
            {
                LightOffset[i] = 0;
            }
            for (int i = 0; i < DefinedCustomBlocks.Length; i++)
            {
                DefinedCustomBlocks[i] = 0;
            }
            // Reset textures
            texId = 0;
            for (int i = 0; i < textures.Length; i++)
            {
                textures[i] = 0;
            }
            // Reset culling
            for (int i = 0; i < hidden.Length; i++)
            {
                hidden[i] = 0;
            }
            for (int i = 0; i < CanStretch.Length; i++)
            {
                CanStretch[i] = false;
            }
            for (int i = 0; i < IsAir.Length; i++)
            {
                IsAir[i] = false;
            }
            // Reset bounds
            for (int i = 0; i < MinBB.Length; i++)
            {
                MinBB[i] = Vector3.Zero;
            }
            for (int i = 0; i < MaxBB.Length; i++)
            {
                MaxBB[i] = Vector3.One;
            }
            // Reset sounds
            for (int i = 0; i < DigSounds.Length; i++)
            {
                DigSounds[i] = SoundType.None;
            }
            for (int i = 0; i < StepSounds.Length; i++)
            {
                StepSounds[i] = SoundType.None;
            }
            Init();

            // TODO: Make this part of TerrainAtlas2D maybe?
            using (FastBitmap fastBmp = new FastBitmap(game.TerrainAtlas.AtlasBitmap, true, true))
                RecalculateSpriteBB(fastBmp);
        }