public void Convert(
                uint Width,
                uint Height,
                uint LineSize,
                IList <byte> SourceImg,
                int SourceTexPos,
                ref byte[] DestImg,
                Color4UByte[] _)
            {
                var DestTexPos = 0;

                DestImg = new byte[(int)(Width * Height * 8L + 1)];
                for (int i = 0, loopTo = (int)(Height - 1L); i <= loopTo; i++)
                {
                    for (int j = 0, loopTo1 = (int)(Width / 2L - 1L);
                         j <= loopTo1;
                         j++)
                    {
                        BitMath.Split(SourceImg[SourceTexPos],
                                      out var upper4,
                                      out var lower4);

                        byte IAAlpha;
                        if (Conversions.ToBoolean(upper4 & 1))
                        {
                            IAAlpha = 255;
                        }
                        else
                        {
                            IAAlpha = 0;
                        }
                        var upperIntensity =
                            (byte)Math.Round(IoUtil.ShiftR(upper4, 1, 3) * FACTOR);
                        DestImg[DestTexPos]     = upperIntensity;
                        DestImg[DestTexPos + 1] = upperIntensity;
                        DestImg[DestTexPos + 2] = upperIntensity;
                        DestImg[DestTexPos + 3] = IAAlpha;

                        var lowerIntensity =
                            (byte)Math.Round(IoUtil.ShiftR(lower4, 1, 3) * FACTOR);
                        if (Conversions.ToBoolean(lower4 & 1))
                        {
                            IAAlpha = 255;
                        }
                        else
                        {
                            IAAlpha = 0;
                        }
                        DestImg[DestTexPos + 4] = lowerIntensity;
                        DestImg[DestTexPos + 5] = lowerIntensity;
                        DestImg[DestTexPos + 6] = lowerIntensity;
                        DestImg[DestTexPos + 7] = IAAlpha;

                        ++SourceTexPos;
                        DestTexPos += 8;
                    }

                    SourceTexPos = (int)(SourceTexPos + (LineSize * 8L - Width / 2L));
                }
            }
Beispiel #2
0
        public void Update(uint low, uint high)
        {
            this.Low = low & 0x00ffffff;
            for (var i = 0; i < 4; ++i)
            {
                this.CMDParams[i] = (byte)IoUtil.ShiftR(low, (3 - i) * 8, 8);
            }

            this.High = high;
            for (var i = 0; i < 4; ++i)
            {
                this.CMDParams[4 + i] = (byte)IoUtil.ShiftR(high, (3 - i) * 8, 8);
            }

            this.Opcode = this.CMDParams[0];
        }
            public void Convert(
                uint Width,
                uint Height,
                uint LineSize,
                IList <byte> SourceImg,
                int SourceTexPos,
                ref byte[] DestImg,
                Color4UByte[] _)
            {
                var DestTexPos = 0;

                ushort RGBA5551 = 0;

                DestImg = new byte[(int)(Width * Height * 8L + 1)];
                for (var i = 0; i < Height; ++i)
                {
                    for (int j = 0; j < Width; ++j)
                    {
                        RGBA5551            = IoUtil.ReadUInt16(SourceImg, (uint)SourceTexPos);
                        DestImg[DestTexPos] =
                            (byte)Math.Round(IoUtil.ShiftR(RGBA5551, 11, 5) * FACTOR);
                        DestImg[DestTexPos + 1] =
                            (byte)Math.Round(IoUtil.ShiftR(RGBA5551, 6, 5) * FACTOR);
                        DestImg[DestTexPos + 2] =
                            (byte)Math.Round(IoUtil.ShiftR(RGBA5551, 1, 5) * FACTOR);
                        if (Conversions.ToBoolean(RGBA5551 & 1))
                        {
                            DestImg[DestTexPos + 3] = 255;
                        }
                        else
                        {
                            DestImg[DestTexPos + 3] = 0;
                        }
                        SourceTexPos += 2;
                        DestTexPos   += 4;
                    }

                    SourceTexPos = (int)(SourceTexPos + (LineSize * 4L - Width));
                }
            }
        /// <summary>
        ///   Parses a set of animations according to the spec at:
        ///   https://wiki.cloudmodding.com/oot/Animation_Format#C_code
        /// </summary>
        public IList <IAnimation>?GetLinkAnimations(
            IBank HeaderData,
            int LimbCount,
            IBank animationData,
            ListBox animationList)
        {
            animationList.Items.Clear();
            var animations = new List <IAnimation>();

            var trackCount = (uint)(LimbCount * 3);
            var frameSize  = 2 * (3 + trackCount) + 2;

            for (uint i = 0x2310; i <= 0x34F8; i += 4)
            {
                // Verifies the frame count is positive.
                var frameCount = IoUtil.ReadUInt16(HeaderData, i);
                if (frameCount == 0)
                {
                    continue;
                }

                var animationAddress = IoUtil.ReadUInt32(HeaderData, i + 4);
                IoUtil.SplitAddress(animationAddress,
                                    out var animationBank,
                                    out var animationOffset);

                // Should use link_animetion bank.
                var validAnimationBank = animationBank == 7;
                if (!validAnimationBank)
                {
                    continue;
                }

                // Should have zeroes in the expected bytes of the header.
                var hasZeroes = IoUtil.ReadUInt16(HeaderData, i + 2) == 0;
                if (!hasZeroes)
                {
                    continue;
                }

                // Should be within the bounds of the bank.
                var validOffset = animationOffset + frameSize * frameCount <
                                  animationData.Count;
                if (!validOffset)
                {
                    continue;
                }

                // Everything looks good with this animation location!

                // Starts parsing animation from this spot.
                var tracks       = new LinkAnimetionTrack[(int)(trackCount - 1L + 1)];
                var positions    = new Vec3s[frameCount];
                var facialStates = new FacialState[frameCount];

                for (int t = 0, loopTo = (int)(trackCount - 1L);
                     t <= loopTo;
                     t++)
                {
                    tracks[t] = new LinkAnimetionTrack(1, new ushort[frameCount]);
                }

                for (int f = 0, loopTo1 = frameCount - 1; f <= loopTo1; f++)
                {
                    var frameOffset = (uint)(animationOffset + f * frameSize);

                    // TODO: This should be ReadInt16() instead.
                    positions[f] = new Vec3s {
                        X = (short)IoUtil.ReadUInt16(animationData, frameOffset),
                        Y = (short)IoUtil.ReadUInt16(animationData, frameOffset + 2),
                        Z = (short)IoUtil.ReadUInt16(animationData, frameOffset + 4),
                    };
                    for (int t = 0, loopTo2 = (int)(trackCount - 1L);
                         t <= loopTo2;
                         t++)
                    {
                        var trackOffset = (uint)(frameOffset + 2 * (3 + t));
                        tracks[t].Frames[f] = IoUtil.ReadUInt16(animationData, trackOffset);
                    }

                    var facialStateOffset =
                        (int)(frameOffset + 2 * (3 + trackCount));
                    var facialState = animationData[facialStateOffset + 1];
                    var mouthState  = IoUtil.ShiftR(facialState, 4, 4);
                    var eyeState    = IoUtil.ShiftR(facialState, 0, 4);

                    facialStates[f] = new FacialState((EyeState)eyeState,
                                                      (MouthState)mouthState);
                }

                var animation =
                    new LinkAnimetion(frameCount, tracks, positions, facialStates);
                animations.Add(animation);

                animationList.Items.Add("0x" + Conversion.Hex(i));
            }

            return(animations.Count > 0 ? animations : null);
        }