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)); } }
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); }