Esempio n. 1
0
        /// <summary>
        /// Reads a texture with the specified characteristics from a binary stream.
        /// </summary>
        internal void LoadTextureData(EndianBinaryReader input, GcGame game, GcTextureFormat format, int totalLevelSize, int width, int height, int levelCount)
        {
            if (!SupportedTextureFormats.Contains(format))
            {
                throw new InvalidTplFileException("Unsupported texture format.");
            }

            int remainingSize = totalLevelSize;

            this.format = format;
            this.width  = width;
            this.height = height;

            for (int level = 0; level < levelCount; level++)
            {
                byte[] levelData = new byte[CalculateSizeOfLevel(level)];

                // Try to read as many bytes as we can into the level data buffer,
                // but we may not be able to due to bugs in F-Zero GX / SMB2.
                int sizeToRead = Math.Min(levelData.Length, remainingSize);
                input.Read(levelData, 0, sizeToRead);
                remainingSize -= sizeToRead;

                encodedLevelData.Add(levelData);
            }

            if (TplVersionDetails.VerifyCorrectSize(game) && SizeOfTextureData(game) != totalLevelSize)
            {
                throw new InvalidTplFileException("Texture size doesn't match expected size.");
            }
        }
Esempio n. 2
0
        /// Gets the size of the texture when written to a binary stream.
        internal int SizeOfTextureData(GcGame game)
        {
            int size = 0;

            for (int level = 0; level < LevelCount; level++)
            {
                // Hack: CMPR sizes are not calculated correctly as explained in the doc., replicate the bug
                if (TplVersionDetails.HasCmprSizeBug(game) && format == GcTextureFormat.CMPR)
                {
                    int levelWidth = width >> level, levelHeight = height >> level;
                    int w     = PaddingUtils.Align(levelWidth, 4);  // Align to 4 (should really be 8)
                    int h     = PaddingUtils.Align(levelHeight, 4); // Align to 4 (should really be 8)
                    int sz    = (w * h * 4) / 8;                    // CMPR is 4 bits per pixel
                    int szpad = PaddingUtils.Align(sz, 32);         // Align to 32 (this should normally not be needed)
                    size += szpad;
                }
                else
                {
                    size += CalculateSizeOfLevel(level);
                }
            }
            return(size);
        }