Exemplo n.º 1
0
        // Reads the hashes and related strings
        private void ReadBuildHashes(BinaryReader reader)
        {
            var buildHashes = new Dictionary <int, SpriteBaseName>();
            var numHashes   = reader.ReadInt32();

            Utilities.LogToDump($"\n<Hashtable {numHashes}>", Logger);
            for (var i = 0; i < numHashes; i++)
            {
                var hash = reader.ReadInt32();
                var str  = reader.ReadPString();
                Utilities.LogToDump($"  {hash} -> \"{str}\"", Logger);
                buildHashes[hash] = new SpriteBaseName(str);
            }

            BuildHashes = buildHashes;
        }
Exemplo n.º 2
0
        private void PackBuild(TexturePacker texture)
        {
            BuildData         = new Build();
            BuildData.Version = 10; // magic number
            SetSymbolsAndFrames(texture.SpriteAtlas);
            BuildData.Name = scml.GetElementsByTagName("entity")[0].Attributes["name"].Value;
            var histogram = texture.GetHistogram();
            var hashTable = new Dictionary <SpriteBaseName, int>();

            BuildData.Symbols = new List <Symbol>();
            var            symbolIndex = -1;
            SpriteBaseName lastName    = null;

            foreach (var sprite in texture.SpriteAtlas)
            {
                // Only add each unique symbol once
                if (lastName != sprite.BaseName)
                {
                    var symbol = new Symbol();
                    // The hash table caches a KleiHash translation of all sprites.
                    // It may be unnecessary but the original had it, and I don't know if the performance impact is
                    // small enough to remove it.
                    if (!hashTable.ContainsKey(sprite.BaseName))
                    {
                        hashTable[sprite.BaseName] = sprite.BaseName.KleiHashed;
                    }

                    symbol.Hash  = hashTable[sprite.BaseName];
                    symbol.Path  = symbol.Hash;
                    symbol.Color = 0; // no Klei files use color other than 0 so fair assumption is it can be 0
                    // only check in decompile for flag checks flag = 8 for a layered anim (which we won't do)
                    // so should be safe to leave flags = 0
                    // have seen some Klei files in which flags = 1 for some symbols but can't determine what that does
                    symbol.Flags      = 0;
                    symbol.FrameCount = histogram[sprite.BaseName];
                    symbol.Frames     = new List <Frame>();
                    BuildData.Symbols.Add(symbol);

                    symbolIndex++;
                    lastName = sprite.BaseName;
                }

                var frame = new Frame();
                frame.SourceFrameNum = sprite.SpriteName.Index;
                // duration is always 1 because the frames for a symbol always are numbered incrementing by 1
                // (or at least that's why I think it's always 1 in the examples I looked at)
                frame.Duration = 1;
                // this value as read from the file is unused by Klei code and all example files have it set to 0 for all symbols
                frame.BuildImageIndex = 0;

                frame.X1 = (float)sprite.X / texture.SpriteSheet.Width;
                frame.X2 = (float)(sprite.X + sprite.Width) / texture.SpriteSheet.Width;
                frame.Y1 = (float)sprite.Y / texture.SpriteSheet.Height;
                frame.Y2 = (float)(sprite.Y + sprite.Height) / texture.SpriteSheet.Height;

                // do not set frame.time since it was a calculated property and not actually used in kbild
                frame.PivotWidth  = sprite.Width * 2;
                frame.PivotHeight = sprite.Height * 2;

                // Find the appropriate pivot from the scml
                var key = $"{sprite.BaseName}_{frame.SourceFrameNum}";
                if (!projectSprites.ContainsKey(sprite.SpriteName))
                {
                    continue;
                }
                var scmlnode = projectSprites[sprite.SpriteName];
                frame.PivotX = -(float.Parse(scmlnode.Attributes["pivot_x"].Value) - 0.5f) * frame.PivotWidth;
                frame.PivotY = (float.Parse(scmlnode.Attributes["pivot_y"].Value) - 0.5f) * frame.PivotHeight;
                BuildData.Symbols[symbolIndex].Frames.Add(frame);
            }

            // Finally, flip the key/values to get the build hash table
            BuildHashes = new Dictionary <int, SpriteBaseName>();
            foreach (var entry in hashTable)
            {
                BuildHashes[entry.Value] = entry.Key;
            }

            BuildBuildTable(texture.SpriteSheet.Width, texture.SpriteSheet.Height);
        }