Exemplo n.º 1
0
        public static SpriteInfo      GetSpriteInfo(GMFileContent content, uint id, Dictionary <uint, uint> toil = null)
        {
            if (id >= content.Sprites->Count)
            {
                throw new ArgumentOutOfRangeException(nameof(id));
            }

            var se = (SpriteEntry *)GMFile.PtrFromOffset(content, (&content.Sprites->Offsets)[id]);

            var ret = new SpriteInfo();

            ret.Name     = StringFromOffset(content, se->Name);
            ret.Size     = se->Size;
            ret.Bounding = se->Bounding;
            ret.BBoxMode = se->BBoxMode;
            ret.Origin   = se->Origin;
            ret.Version  = 1;

            ret.SeparateColMasks = se->SeparateColMasks.IsTrue();

            var tex = &se->Textures;

            if (tex->Count == ~(uint)0)
            {
                var se2 = (SpriteEntry2 *)GMFile.PtrFromOffset(content, (&content.Sprites->Offsets)[id]);
                tex              = &se2->Textures;
                ret.Version      = 2;
                ret.UnknownFloat = se2->funk;
            }
            if (tex->Count == ~(uint)0)
            {
                Console.Error.WriteLine($"Warning: texture count of sprite {id} ({((ulong)se-(ulong)content.RawData.BPtr).ToString(SR.HEX_FM8)}) is -1.");
                return(ret);
            }

            ret.TextureIndices = new uint[tex->Count];

            for (uint i = 0; i < tex->Count; i++)
            {
                if (toil == null)
                {
                    for (uint j = 0; j < content.TexturePages->Count; j++)
                    {
                        if ((&tex->Offsets)[i] == (&content.TexturePages->Offsets)[j])
                        {
                            ret.TextureIndices[i] = j;
                            break;
                        }
                    }
                }
                else
                {
                    ret.TextureIndices[i] = toil[(&tex->Offsets)[i]];
                }
            }

            SpriteCollisionMask *masks =
                (SpriteCollisionMask *)((ulong)&tex->Offsets + sizeof(uint) * tex->Count);

            // TODO: store this in a different way. this is wasteful as f**k.
            uint amt = ret.SeparateColMasks ? masks->MaskCount : 1;

            //Console.WriteLine("amt="+amt.ToString(SR.HEX_FM8) + " at " + ((ulong)&masks->MaskCount - (ulong)content.RawData.BPtr).ToString(SR.HEX_FM8));

            if (amt < 0x100) // guesstimate
            {
                ret.CollisionMasks = new bool[amt][, ];
                byte *maskData = &masks->MaskData;

                uint w = (uint)(ret.Size.X & 0x7FFFFFFF);
                uint h = (uint)(ret.Size.Y & 0x7FFFFFFF);

                uint wPad = (((w & 7) == 0) ? w : (w - (w & 7) + 8)) / 8;

                for (uint i = 0; i < amt; i++)
                {
                    bool[,] stuff = new bool[wPad * 8, h];

                    for (uint y = 0; y < h; y++)
                    {
                        for (uint x = 0; x < wPad * 8; x++)
                        {
                            uint rown = y * wPad;

                            uint byten = x >> 3;
                            byte bitn  = (byte)(x & 7);

                            byte *curptr  = maskData + rown + byten;
                            byte  curbyte = *curptr;
                            byte  curbit  = (byte)(curbyte & (byte)(1 << bitn));

                            stuff[x, y] = curbit != 0;
                        }
                    }

                    ret.CollisionMasks[i] = stuff;
                    maskData += wPad * h;
                }
            }
            else
            {
                Console.Error.WriteLine($"Warning: collision mask of sprite {id} ({((ulong)se - (ulong)content.RawData.BPtr).ToString(SR.HEX_FM8)}) is bogus ({amt.ToString(SR.HEX_FM8)}), ignoring...");
            }

            return(ret);
        }
Exemplo n.º 2
0
        public static SpriteInfo      GetSpriteInfo(GMFileContent content, uint id)
        {
            if (id >= content.Sprites->Count)
            {
                throw new ArgumentOutOfRangeException(nameof(id));
            }

            var se = (SpriteEntry *)GMFile.PtrFromOffset(content, (&content.Sprites->Offsets)[id]);

            var ret = new SpriteInfo();

            ret.Name     = StringFromOffset(content, se->Name);
            ret.Size     = se->Size;
            ret.Bounding = se->Bounding;
            ret.BBoxMode = se->BBoxMode;
            ret.Origin   = se->Origin;

            ret.SeparateColMasks = se->SeparateColMasks.IsTrue();

            ret.TextureIndices = new uint[se->Textures.Count];

            for (uint i = 0; i < se->Textures.Count; i++)
            {
                for (uint j = 0; j < content.TexturePages->Count; j++)
                {
                    if ((&se->Textures.Offsets)[i] == (&content.TexturePages->Offsets)[j])
                    {
                        ret.TextureIndices[i] = j;
                        break;
                    }
                }
            }

            SpriteCollisionMask *masks =
                (SpriteCollisionMask *)&se->Textures + sizeof(uint) * se->Textures.Count;

            uint amt = ret.SeparateColMasks ? masks->MaskCount : 1;

            //Console.WriteLine("amt="+amt.ToString(SR.HEX_FM8) + " at " + ((ulong)&masks->MaskCount - (ulong)content.RawData.BPtr).ToString(SR.HEX_FM8));

            if (amt < 0x100) // guesstimate
            {
                ret.CollisionMasks = new bool[amt][, ];
                byte *maskData = &masks->MaskData;

                uint w = (uint)(ret.Size.X & 0x7FFFFFFF);
                uint h = (uint)(ret.Size.Y & 0x7FFFFFFF);

                uint wPad = ((w & 7) == 0) ? w : (w - (w & 7) + 8);

                for (uint i = 0; i < amt; i++)
                {
                    bool[,] stuff = new bool[w, h];

                    for (uint y = 0; y < h; y++)
                    {
                        for (uint x = 0; x < w; x++)
                        {
                            uint rown = y * wPad;

                            uint byten = x >> 3;
                            byte bitn  = (byte)(x & 7);

                            byte *curptr  = maskData + rown + byten;
                            byte  curbyte = *curptr;
                            byte  curbit  = (byte)(curbyte & (byte)(1 << bitn));

                            stuff[x, y] = curbit != 0;
                        }
                    }

                    ret.CollisionMasks[i] = stuff;
                    maskData += wPad * h;
                }
            }
            else
            {
                Console.WriteLine($"Warning: collision mask of sprite {id} ({((ulong)se - (ulong)content.RawData.BPtr).ToString(SR.HEX_FM8)}) is bogus ({amt.ToString(SR.HEX_FM8)}), ignoring...");
            }

            return(ret);
        }