private void LoadYcds() { int cutListCount = (CameraCutList?.Length ?? 0) + 1; var shortName = CutFile.FileEntry?.GetShortNameLower() ?? ""; Ycds = new YcdFile[cutListCount]; if (!string.IsNullOrEmpty(shortName)) { for (int i = 0; i < cutListCount; i++) { var ycdname = shortName + "-" + i.ToString(); var ycdhash = JenkHash.GenHash(ycdname); var ycd = GameFileCache.GetYcd(ycdhash); while ((ycd != null) && (!ycd.Loaded)) { Thread.Sleep(1);//bite me ycd = GameFileCache.GetYcd(ycdhash); } if (ycd != null) { ycd.BuildCutsceneMap(i); } Ycds[i] = ycd; } } }
public void LoadYcd(YcdFile ycd) { Ycd = ycd; fileName = ycd?.Name; if (string.IsNullOrEmpty(fileName)) { fileName = ycd?.RpfFileEntry?.Name; } UpdateFormTitle(); //MainPropertyGrid.SelectedObject = ycd; MainListView.Items.Clear(); if (ycd?.ClipMapEntries != null) { foreach (var cme in ycd.ClipMapEntries) { if (cme != null) { var lvi = MainListView.Items.Add(cme.Clip?.ShortName ?? cme.Hash.ToString()); lvi.Tag = cme.Clip; lvi.Group = MainListView.Groups["Clips"]; } } } if (ycd?.AnimMapEntries != null) { foreach (var ame in ycd.AnimMapEntries) { if (ame != null) { var lvi = MainListView.Items.Add(ame.Hash.ToString()); lvi.Tag = ame.Animation; lvi.Group = MainListView.Groups["Anims"]; } } } }
private void SelectFile(RpfEntry entry, int offset, int length) { SelectedEntry = entry; SelectedOffset = offset; SelectedLength = length; RpfFileEntry rfe = entry as RpfFileEntry; if (rfe == null) { RpfDirectoryEntry rde = entry as RpfDirectoryEntry; if (rde != null) { FileInfoLabel.Text = rde.Path + " (Directory)"; DataTextBox.Text = "[Please select a data file]"; } else { FileInfoLabel.Text = "[Nothing selected]"; DataTextBox.Text = "[Please select a data file]"; } ShowTextures(null); return; } Cursor = Cursors.WaitCursor; string typestr = "Resource"; if (rfe is RpfBinaryFileEntry) { typestr = "Binary"; } byte[] data = rfe.File.ExtractFile(rfe); int datalen = (data != null) ? data.Length : 0; FileInfoLabel.Text = rfe.Path + " (" + typestr + " file) - " + TextUtil.GetBytesReadable(datalen); if (ShowLargeFileContentsCheckBox.Checked || (datalen < 524287)) //512K { DisplayFileContentsText(rfe, data, length, offset); } else { DataTextBox.Text = "[Filesize >512KB. Select the Show large files option to view its contents]"; } bool istexdict = false; if (rfe.NameLower.EndsWith(".ymap")) { YmapFile ymap = new YmapFile(rfe); ymap.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ymap; } else if (rfe.NameLower.EndsWith(".ytyp")) { YtypFile ytyp = new YtypFile(); ytyp.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ytyp; } else if (rfe.NameLower.EndsWith(".ymf")) { YmfFile ymf = new YmfFile(); ymf.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ymf; } else if (rfe.NameLower.EndsWith(".ymt")) { YmtFile ymt = new YmtFile(); ymt.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ymt; } else if (rfe.NameLower.EndsWith(".ybn")) { YbnFile ybn = new YbnFile(); ybn.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ybn; } else if (rfe.NameLower.EndsWith(".fxc")) { FxcFile fxc = new FxcFile(); fxc.Load(data, rfe); DetailsPropertyGrid.SelectedObject = fxc; } else if (rfe.NameLower.EndsWith(".yft")) { YftFile yft = new YftFile(); yft.Load(data, rfe); DetailsPropertyGrid.SelectedObject = yft; if ((yft.Fragment != null) && (yft.Fragment.Drawable != null) && (yft.Fragment.Drawable.ShaderGroup != null) && (yft.Fragment.Drawable.ShaderGroup.TextureDictionary != null)) { ShowTextures(yft.Fragment.Drawable.ShaderGroup.TextureDictionary); istexdict = true; } } else if (rfe.NameLower.EndsWith(".ydr")) { YdrFile ydr = new YdrFile(); ydr.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ydr; if ((ydr.Drawable != null) && (ydr.Drawable.ShaderGroup != null) && (ydr.Drawable.ShaderGroup.TextureDictionary != null)) { ShowTextures(ydr.Drawable.ShaderGroup.TextureDictionary); istexdict = true; } } else if (rfe.NameLower.EndsWith(".ydd")) { YddFile ydd = new YddFile(); ydd.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ydd; //todo: show embedded texdicts in ydd's? is this possible? } else if (rfe.NameLower.EndsWith(".ytd")) { YtdFile ytd = new YtdFile(); ytd.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ytd; ShowTextures(ytd.TextureDict); istexdict = true; } else if (rfe.NameLower.EndsWith(".ycd")) { YcdFile ycd = new YcdFile(); ycd.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ycd; } else if (rfe.NameLower.EndsWith(".ynd")) { YndFile ynd = new YndFile(); ynd.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ynd; } else if (rfe.NameLower.EndsWith(".ynv")) { YnvFile ynv = new YnvFile(); ynv.Load(data, rfe); DetailsPropertyGrid.SelectedObject = ynv; } else if (rfe.NameLower.EndsWith("_cache_y.dat")) { CacheDatFile cdf = new CacheDatFile(); cdf.Load(data, rfe); DetailsPropertyGrid.SelectedObject = cdf; } else if (rfe.NameLower.EndsWith(".rel")) { RelFile rel = new RelFile(rfe); rel.Load(data, rfe); DetailsPropertyGrid.SelectedObject = rel; } else if (rfe.NameLower.EndsWith(".gxt2")) { Gxt2File gxt2 = new Gxt2File(); gxt2.Load(data, rfe); DetailsPropertyGrid.SelectedObject = gxt2; } else if (rfe.NameLower.EndsWith(".pso")) { JPsoFile pso = new JPsoFile(); pso.Load(data, rfe); DetailsPropertyGrid.SelectedObject = pso; } else { DetailsPropertyGrid.SelectedObject = null; } if (!istexdict) { ShowTextures(null); } Cursor = Cursors.Default; }
public byte[] BuildYcd() { YcdFile ycd = new YcdFile(); ycd.ClipDictionary = new ClipDictionary(); var clipmap = new List <ClipMapEntry>(); var animmap = new List <AnimationMapEntry>(); foreach (var onim in OnimFiles) { var anim = new Animation(); anim.Hash = JenkHash.GenHash(onim.Name.ToLowerInvariant()); anim.Frames = (ushort)onim.Frames; anim.SequenceFrameLimit = (ushort)onim.SequenceFrameLimit; anim.Duration = onim.Duration; JenkIndex.Ensure(onim.Name.ToLowerInvariant());//just to make it nicer to debug really bool isUV = false; bool hasRootMotion = false; var boneIds = new List <AnimationBoneId>(); var seqs = new List <Sequence>(); var aseqs = new List <List <AnimSequence> >(); foreach (var oseq in onim.SequenceList) { var boneid = new AnimationBoneId(); boneid.BoneId = (ushort)oseq.BoneID; //TODO: bone ID mapping boneid.Unk0 = 0; //what to use here? switch (oseq.Track) { case "BonePosition": boneid.Track = 0; break; case "BoneRotation": boneid.Track = 1; break; case "ModelPosition": boneid.Track = 5; hasRootMotion = true; break; case "ModelRotation": boneid.Track = 6; hasRootMotion = true; break; case "UV0": boneid.Track = 17; isUV = true; break; case "UV1": boneid.Track = 18; isUV = true; break; case "LightColor": boneid.Track = 0; //what should this be? break; case "LightRange": boneid.Track = 0; //what should this be? break; case "LightIntensity1": boneid.Track = 0; //what should this be? break; case "LightIntensity2": boneid.Track = 0; //what should this be? break; case "LightDirection": boneid.Track = 0; //what should this be? break; case "Type21": boneid.Track = 0; //what should this be? break; case "CameraPosition": boneid.Track = 7; break; case "CameraRotation": boneid.Track = 8; break; case "CameraFOV": boneid.Track = 0; //what should this be? break; case "CameraDof": boneid.Track = 0; //what should this be? break; case "CameraMatrixRotateFactor": boneid.Track = 0; //what should this be? break; case "CameraControl": boneid.Track = 0; //what should this be? break; case "ActionFlags": //not sure what this is for? just ignore it for now continue; default: break; } boneIds.Add(boneid); for (int i = 0; i < oseq.FramesData.Count; i++) { var framesData = oseq.FramesData[i]; if (i > 0) { } Sequence seq = null; List <AnimSequence> aseqlist = null; while (i >= seqs.Count) { seq = new Sequence(); seqs.Add(seq); aseqlist = new List <AnimSequence>(); aseqs.Add(aseqlist); } seq = seqs[i]; aseqlist = aseqs[i]; var chanlist = new List <AnimChannel>(); if (framesData.IsStatic) { var vals = (framesData.Channels.Count > 0) ? framesData.Channels[0].Values : null; if (vals != null) { if (vals.Length == 1) { var acsf = new AnimChannelStaticFloat(); acsf.Value = vals[0]; chanlist.Add(acsf); } else if (vals.Length == 3) { var acsv = new AnimChannelStaticVector3(); acsv.Value = new Vector3(vals[0], vals[1], vals[2]); chanlist.Add(acsv); } else if (vals.Length == 4) { var acsq = new AnimChannelStaticQuaternion(); acsq.Value = new Quaternion(vals[0], vals[1], vals[2], vals[3]); chanlist.Add(acsq); } else { } } else { } } else { int chanCount = framesData.Channels.Count; for (int c = 0; c < chanCount; c++) { var ochan = framesData.Channels[c]; var vals = ochan.Values; if (vals.Length == 1)//static channel... { var acsf = new AnimChannelStaticFloat(); acsf.Value = vals[0]; chanlist.Add(acsf); } else //if (vals.Length == onim.Frames) { float minval = float.MaxValue; float maxval = float.MinValue; float lastval = 0; float mindelta = float.MaxValue; foreach (var val in vals) { minval = Math.Min(minval, val); maxval = Math.Max(maxval, val); if (val != lastval) { float adelta = Math.Abs(val - lastval); mindelta = Math.Min(mindelta, adelta); } lastval = val; } if (mindelta == float.MaxValue) { mindelta = 0; } float range = maxval - minval; float minquant = range / 1048576.0f; float quantum = Math.Max(mindelta, minquant); var acqf = new AnimChannelQuantizeFloat(); acqf.Values = vals; acqf.Offset = minval; acqf.Quantum = quantum; chanlist.Add(acqf); } } if (chanCount == 4) { //assume it's a quaternion... add the extra quaternion channel var acq1 = new AnimChannelCachedQuaternion(AnimChannelType.CachedQuaternion2); acq1.QuatIndex = 3;//what else should it be? chanlist.Add(acq1); } } if (chanlist.Count == 4) { } //shouldn't happen AnimSequence aseq = new AnimSequence(); aseq.Channels = chanlist.ToArray(); aseqlist.Add(aseq); } } int remframes = anim.Frames; for (int i = 0; i < seqs.Count; i++) { var seq = seqs[i]; var aseqlist = aseqs[i]; seq.Unknown_00h = 0;//what to set this??? seq.NumFrames = (ushort)Math.Max(Math.Min(anim.SequenceFrameLimit, remframes), 0); seq.Sequences = aseqlist.ToArray(); seq.AssociateSequenceChannels(); remframes -= anim.SequenceFrameLimit; } anim.BoneIds = new ResourceSimpleList64_s <AnimationBoneId>(); anim.BoneIds.data_items = boneIds.ToArray(); anim.Sequences = new ResourcePointerList64 <Sequence>(); anim.Sequences.data_items = seqs.ToArray(); anim.Unknown_10h = hasRootMotion ? (byte)16 : (byte)0; anim.Unknown_1Ch = 0; //??? anim.AssignSequenceBoneIds(); var cliphash = anim.Hash; if (isUV) { var name = onim.Name.ToLowerInvariant(); var uvind = name.IndexOf("_uv_"); if (uvind < 0) { } var modelname = name.Substring(0, uvind); var geoindstr = name.Substring(uvind + 4); var geoind = 0u; uint.TryParse(geoindstr, out geoind); cliphash = JenkHash.GenHash(modelname) + geoind + 1; } else { } var clip = new ClipAnimation(); clip.Animation = anim; clip.StartTime = 0.0f; clip.EndTime = anim.Duration; clip.Rate = 1.0f; clip.Name = "pack:/" + onim.Name + ".clip"; //pack:/name.clip clip.Unknown_30h = 0; //what's this then? clip.Properties = new ClipPropertyMap(); clip.Properties.CreatePropertyMap(null); //TODO? clip.Tags = new ClipTagList(); //TODO? var cme = new ClipMapEntry(); cme.Clip = clip; cme.Hash = cliphash; clipmap.Add(cme); var ame = new AnimationMapEntry(); ame.Hash = anim.Hash;//is this right? what else to use? ame.Animation = anim; animmap.Add(ame); } ycd.ClipDictionary.CreateClipsMap(clipmap.ToArray()); ycd.ClipDictionary.CreateAnimationsMap(animmap.ToArray()); ycd.ClipDictionary.BuildMaps(); ycd.ClipDictionary.UpdateUsageCounts(); ycd.InitDictionaries(); byte[] data = ycd.Save(); return(data); }