Cutscene viewer progress, Hash updates

This commit is contained in:
dexy
2019-11-25 20:44:16 +11:00
Unverified
parent dfa62a9803
commit 5a869fa836
23 changed files with 2298 additions and 389 deletions
@@ -118,7 +118,7 @@ namespace CodeWalker.GameFiles
{ } //just testing
else
{
dates.Add(new CacheFileDate(line));//eg: 2740459947 130680580712018938 8944
dates.Add(new CacheFileDate(line));//eg: 2740459947 (hash of: platform:/data/cdimages/scaleform_frontend.rpf) 130680580712018938 8944
}
break;
}
+176 -5
View File
@@ -101,6 +101,11 @@ namespace CodeWalker.GameFiles
public CutConcatData[] concatDataList { get; set; } // PsoDataType.Array, 784, 1, (MetaName)2621475),//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.rage__cutfCutsceneFile2__SConcatData),
public CutHaltFrequency[] discardFrameList { get; set; } // PsoDataType.Array, 5280, 0, (MetaName)37)//ARRAYINFO, PsoDataType.Structure, 0, 0, MetaName.vHaltFrequency),
public Dictionary<int, CutObject> ObjectsDict { get; set; } = new Dictionary<int, CutObject>();
public override void ReadXml(XmlNode node)
{
fTotalDuration = Xml.GetChildFloatAttribute(node, "fTotalDuration", "value");
@@ -134,9 +139,98 @@ namespace CodeWalker.GameFiles
sectionSplitList = Xml.GetChildRawFloatArray(node, "sectionSplitList");
concatDataList = XmlMeta.ReadItemArrayNullable<CutConcatData>(node, "concatDataList");
discardFrameList = XmlMeta.ReadItemArrayNullable<CutHaltFrequency>(node, "discardFrameList");
AssociateObjects();
}
public void AssociateObjects()
{
ObjectsDict.Clear();
if (pCutsceneObjects != null)
{
foreach (var obj in pCutsceneObjects)
{
if (obj is CutObject cobj)
{
ObjectsDict[cobj.iObjectId] = cobj;
}
}
}
CutEventArgs getEventArgs(int i)
{
if (i < 0) return null;
if (i >= pCutsceneEventArgsList?.Length) return null;
var args = pCutsceneEventArgsList[i];
if (!(args is CutEventArgs))
{ }
return args as CutEventArgs;
}
CutObject getObject(int i)
{
CutObject o = null;
ObjectsDict.TryGetValue(i, out o);
return o;
}
if (pCutsceneEventArgsList != null)
{
foreach (var arg in pCutsceneEventArgsList)
{
if (arg is CutObjectIdEventArgs oarg)
{
oarg.Object = getObject(oarg.iObjectId);
}
if (arg is CutObjectIdListEventArgs larg)
{
var objs = new CutObject[larg.iObjectIdList?.Length ?? 0];
for (int i = 0; i < objs.Length; i++)
{
objs[i] = getObject(larg.iObjectIdList[i]);
}
larg.ObjectList = objs;
}
}
}
if (pCutsceneEventList != null)
{
foreach (var evt in pCutsceneEventList)
{
if (evt is CutObjectIdEvent oevt)
{
oevt.Object = getObject(oevt.iObjectId);
}
if (evt is CutEvent cevt)
{
cevt.EventArgs = getEventArgs(cevt.iEventArgsIndex);
}
else
{ }
}
}
if (pCutsceneLoadEventList != null)
{
foreach (var evt in pCutsceneLoadEventList)
{
if (evt is CutObjectIdEvent oevt)
{
oevt.Object = getObject(oevt.iObjectId);
}
if (evt is CutEvent cevt)
{
cevt.EventArgs = getEventArgs(cevt.iEventArgsIndex);
}
else
{ }
}
}
}
public static CutBase ConstructObject(string type)
{
switch (type)
@@ -233,6 +327,9 @@ namespace CodeWalker.GameFiles
{
UserData1 = (byte)Xml.GetChildUIntAttribute(node, "UserData1", "value");
UserData2 = (byte)Xml.GetChildUIntAttribute(node, "UserData2", "value");
if ((UserData1 != 0) || (UserData2 != 0))
{ }
}
public override string ToString()
@@ -248,6 +345,9 @@ namespace CodeWalker.GameFiles
public override void ReadXml(XmlNode node)
{
Items = CutsceneFile2.ReadObjectArray(node, "Items");
if (Items?.Length > 0)
{ }
}
public override string ToString()
@@ -358,7 +458,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
return iObjectId.ToString() + ": " + base.ToString();
return iObjectId.ToString() + ": " + base.ToString().Replace("CodeWalker.GameFiles.Cut", "");
}
}
[TC(typeof(EXP))] public class CutAssetManagerObject : CutObject // rage__cutfAssetManagerObject
@@ -376,6 +476,11 @@ namespace CodeWalker.GameFiles
base.ReadXml(node);
cName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "cName"));
}
public override string ToString()
{
return base.ToString() + ": " + cName.ToString();
}
}
[TC(typeof(EXP))] public class CutCameraObject : CutNamedObject // rage__cutfCameraObject
{
@@ -726,19 +831,74 @@ namespace CodeWalker.GameFiles
}
public enum CutEventType : int
{
LoadScene = 0,
LoadAnimation = 2,
LoadAudio = 4,
LoadModels = 6,
UnloadModels = 7,
LoadParticles = 8,
LoadOverlays = 10,
LoadGxt2 = 12,
EnableHideObject = 14,
DisableHideObject = 15,
EnableFixupModel = 16,
EnableBlockBounds = 18,
DisableBlockBounds = 19,
EnableScreenFade = 20,
DisableScreenFade = 21,
EnableAnimation = 22,
DisableAnimation = 23,
EnableParticleEffect = 24,
DisableParticleEffect = 25,
EnableOverlay = 26,
DisableOverlay = 27,
EnableAudio = 28,
DisableAudio = 29,
Subtitle = 30,
PedVariation = 34,
CameraCut = 43,
LoadRayfireDes = 46,
UnloadRayfireDes = 47,
EnableCamera = 48,
CameraUnk1 = 49,
CameraUnk2 = 50,
DisableCamera = 51,
DecalUnk1 = 52,
DecalUnk2 = 53,
CameraShadowCascade = 54,
CameraUnk3 = 55,
CameraUnk4 = 59,
CameraUnk5 = 63,
CameraUnk6 = 64,
PropUnk1 = 73,
EnableLight = 74,
DisableLight = 75,
CameraUnk7 = 76,
Unk1 = 77,
Unk2 = 78,
CameraUnk8 = 79,
VehicleUnk1 = 258,
PedUnk1 = 262,
}
[TC(typeof(EXP))] public class CutEvent : CutBase // rage__cutfEvent
{
public float fTime { get; set; } // PsoDataType.Float, 16, 0, 0),
public int iEventId { get; set; } // PsoDataType.SInt, 20, 0, 0),
public CutEventType iEventId { get; set; } // PsoDataType.SInt, 20, 0, 0),
public int iEventArgsIndex { get; set; } // PsoDataType.SInt, 24, 0, 0),
public object pChildEvents { get; set; } // PsoDataType.Structure, 32, 3, 0),
//public object pChildEvents { get; set; } // PsoDataType.Structure, 32, 3, 0),
public uint StickyId { get; set; } // PsoDataType.UInt, 40, 0, 0),
public bool IsChild { get; set; } // PsoDataType.Bool, 44, 0, 0)
public CutEventArgs EventArgs { get; set; }
public override void ReadXml(XmlNode node)
{
fTime = Xml.GetChildFloatAttribute(node, "fTime", "value");
iEventId = Xml.GetChildIntAttribute(node, "iEventId", "value");
iEventId = (CutEventType)Xml.GetChildIntAttribute(node, "iEventId", "value");
iEventArgsIndex = Xml.GetChildIntAttribute(node, "iEventArgsIndex", "value");
//pChildEvents = CutsceneFile2.ReadObject(node, "pChildEvents"); //seems never used
StickyId = Xml.GetChildUIntAttribute(node, "StickyId", "value");
@@ -746,13 +906,20 @@ namespace CodeWalker.GameFiles
var cNode = node.SelectSingleNode("pChildEvents");
if ((cNode?.ChildNodes?.Count > 0) || (cNode?.Attributes?.Count > 0))
{ }
{ }//nothing gets here?
}
public override string ToString()
{
return fTime.ToString("0.00") + " : " + iEventId.ToString();
}
}
[TC(typeof(EXP))] public class CutObjectIdEvent : CutEvent // rage__cutfObjectIdEvent
{
public int iObjectId { get; set; } // PsoDataType.SInt, 48, 0, 0)
public CutObject Object { get; set; }
public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
@@ -795,6 +962,8 @@ namespace CodeWalker.GameFiles
{
public int iObjectId { get; set; } // PsoDataType.SInt, 32, 0, 0)
public CutObject Object { get; set; }
public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
@@ -805,6 +974,8 @@ namespace CodeWalker.GameFiles
{
public int[] iObjectIdList { get; set; } // PsoDataType.Array, 32, 0, (MetaName)2)//ARRAYINFO, PsoDataType.SInt, 0, 0, 0),
public CutObject[] ObjectList { get; set; }
public override void ReadXml(XmlNode node)
{
base.ReadXml(node);
@@ -16,6 +16,7 @@ namespace CodeWalker.GameFiles
public Dictionary<MetaHash, ClipMapEntry> ClipMap { get; set; }
public Dictionary<MetaHash, AnimationMapEntry> AnimMap { get; set; }
public Dictionary<MetaHash, ClipMapEntry> CutsceneMap { get; set; } //used for ycd's that are indexed in cutscenes, since name hashes all appended with -n
public ClipMapEntry[] ClipMapEntries { get; set; }
public AnimationMapEntry[] AnimMapEntries { get; set; }
@@ -78,6 +79,29 @@ namespace CodeWalker.GameFiles
}
public void BuildCutsceneMap(int cutIndex)
{
CutsceneMap = new Dictionary<MetaHash, ClipMapEntry>();
var replstr = "-" + cutIndex.ToString();
foreach (var cme in ClipMapEntries)
{
var sn = cme?.Clip?.ShortName ?? "";
if (sn.EndsWith(replstr))
{
sn = sn.Substring(0, sn.Length - replstr.Length);
}
if (sn.EndsWith("_dual"))
{
sn = sn.Substring(0, sn.Length - 5);
}
JenkIndex.Ensure(sn);
var h = JenkHash.GenHash(sn);
CutsceneMap[h] = cme;
}
}
+27 -15
View File
@@ -48,6 +48,7 @@ namespace CodeWalker.GameFiles
public Dictionary<uint, RpfFileEntry> YbnDict { get; private set; }
public Dictionary<uint, RpfFileEntry> YcdDict { get; private set; }
public Dictionary<uint, RpfFileEntry> YnvDict { get; private set; }
public Dictionary<uint, RpfFileEntry> Gxt2Dict { get; private set; }
public Dictionary<uint, RpfFileEntry> AllYmapsDict { get; private set; }
@@ -1202,7 +1203,7 @@ namespace CodeWalker.GameFiles
{
var dat = RpfMan.GetFile<CacheDatFile>(dlccachefile);
if (dat == null)
{ continue; } //update\\x64\\dlcpacks\\mpspecialraces\\dlc.rpf\\x64\\data\\cacheloaderdata_dlc\\mpspecialraces_3336915258_cache_y.dat
{ continue; } //update\\x64\\dlcpacks\\mpspecialraces\\dlc.rpf\\x64\\data\\cacheloaderdata_dlc\\mpspecialraces_3336915258_cache_y.dat (hash of: mpspecialraces_interior_additions)
AllCacheFiles.Add(dat);
foreach (var node in dat.AllMapNodes)
{
@@ -1402,6 +1403,24 @@ namespace CodeWalker.GameFiles
string langstr2 = "americandlc.rpf";
string langstr3 = "american.rpf";
Gxt2Dict = new Dictionary<uint, RpfFileEntry>();
foreach (var rpf in AllRpfs)
{
foreach (var entry in rpf.AllEntries)
{
if (entry is RpfFileEntry fentry)
{
var p = entry.Path;
if (entry.NameLower.EndsWith(".gxt2") && (p.Contains(langstr) || p.Contains(langstr2) || p.Contains(langstr3)))
{
Gxt2Dict[entry.ShortNameHash] = fentry;
}
}
}
}
if (!DoFullStringIndex)
{
string globalgxt2path = "x64b.rpf\\data\\lang\\" + langstr + ".rpf\\global.gxt2";
@@ -1419,24 +1438,17 @@ namespace CodeWalker.GameFiles
List<Gxt2File> gxt2files = new List<Gxt2File>();
foreach (var rpf in AllRpfs)
foreach (var entry in Gxt2Dict.Values)
{
foreach (var entry in rpf.AllEntries)
var gxt2 = RpfMan.GetFile<Gxt2File>(entry);
if (gxt2 != null)
{
var p = entry.Path;
if (entry.NameLower.EndsWith(".gxt2") && (p.Contains(langstr)|| p.Contains(langstr2)|| p.Contains(langstr3)))
for (int i = 0; i < gxt2.TextEntries.Length; i++)
{
var gxt2 = RpfMan.GetFile<Gxt2File>(entry);
if (gxt2 != null)
{
for (int i = 0; i < gxt2.TextEntries.Length; i++)
{
var e = gxt2.TextEntries[i];
GlobalText.Ensure(e.Text, e.Hash);
}
gxt2files.Add(gxt2);
}
var e = gxt2.TextEntries[i];
GlobalText.Ensure(e.Text, e.Hash);
}
gxt2files.Add(gxt2);
}
}
@@ -3546,6 +3546,14 @@ namespace CodeWalker.GameFiles
@null = 987444055, // how best to handle this? C# doesn't like it
exportcamera = 962998194, //cutscene related stuff
@@ -16276,7 +16276,7 @@ namespace CodeWalker.GameFiles
{
public MetaHash Name { get; set; } //0 Name: INT_0Bh: 0
public uint Unused0 { get; set; } //4
public Array_uint Bounds { get; set; } //8 Bounds//3298223272: Array: 8: 1 {256: INT_0Bh: 0}
public Array_uint Bounds { get; set; } //8 Bounds: Array: 8: 1 {256: INT_0Bh: 0}
public ushort Flags { get; set; } //24 Flags: SHORT_0Fh: 24: 2097155
public ushort Unused1 { get; set; }//26
public uint Unused2 { get; set; }//28
@@ -16379,7 +16379,7 @@ namespace CodeWalker.GameFiles
{
public MetaHash Name { get; set; } //0 Name: INT_0Bh: 0
public uint Unused0 { get; set; } //4
public Array_uint Bounds { get; set; } //8 Bounds//3298223272: Array: 8: 1 {256: INT_0Bh: 0}
public Array_uint Bounds { get; set; } //8 Bounds: Array: 8: 1 {256: INT_0Bh: 0}
public override string ToString()
{
@@ -876,6 +876,70 @@ namespace CodeWalker.GameFiles
AssignSequenceBoneIds();
}
public struct FramePosition
{
public int Frame0;
public int Frame1;
public float Alpha0;
public float Alpha1;
}
public FramePosition GetFramePosition(float t)
{
bool ignoreLastFrame = true;//if last frame is equivalent to the first one, eg rollercoaster small light "globes" don't
FramePosition p = new FramePosition();
var nframes = (ignoreLastFrame) ? (Frames - 1) : Frames;
var curPos = (t / Duration) * nframes;
p.Frame0 = ((ushort)curPos) % Frames;
p.Frame1 = (p.Frame0 + 1);// % frames;
p.Alpha1 = (float)(curPos - Math.Floor(curPos));
p.Alpha0 = 1.0f - p.Alpha1;
return p;
}
public Vector4 EvaluateVector4(FramePosition frame, int boneIndex, bool interpolate)
{
var s = frame.Frame0 / SequenceFrameLimit;
int f0 = frame.Frame0 % SequenceFrameLimit;
int f1 = f0 + 1;
var seq = Sequences.data_items[s];
var aseq = seq.Sequences[boneIndex];
var v0 = aseq.EvaluateVector(f0);
var v1 = aseq.EvaluateVector(f1);
var v = interpolate ? (v0 * frame.Alpha0) + (v1 * frame.Alpha1) : v0;
return v;
}
public Quaternion EvaluateQuaternion(FramePosition frame, int boneIndex, bool interpolate)
{
var s = frame.Frame0 / SequenceFrameLimit;
int f0 = frame.Frame0 % SequenceFrameLimit;
int f1 = f0 + 1;
var seq = Sequences.data_items[s];
var aseq = seq.Sequences[boneIndex];
var q0 = aseq.EvaluateQuaternion(f0);
var q1 = aseq.EvaluateQuaternion(f1);
var q = interpolate ? Quaternion.Slerp(q0, q1, frame.Alpha1) : q0;
return q;
}
public int FindBoneIndex(ushort boneTag, byte track)
{
//TODO: make this use a dict??
if (BoneIds?.data_items != null)
{
for (int i = 0; i < BoneIds.data_items.Length; i++)
{
var b = BoneIds.data_items[i];
if ((b.BoneId == boneTag) && (b.Track == track)) return i;
}
}
return -1;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))] public struct AnimationBoneId : IMetaXmlItem
{
@@ -119,14 +119,14 @@ namespace CodeWalker.GameFiles
// structure data
public ulong ParametersPointer { get; set; }
public MetaHash Name { get; set; } //530103687, 2401522793, 1912906641
public MetaHash Name { get; set; } //decal_emissive_only, emissive, spec
public uint Unknown_Ch { get; set; } // 0x00000000
public byte ParameterCount { get; set; }
public byte RenderBucket { get; set; } // 2, 0,
public ushort Unknown_12h { get; set; } // 32768 HasComment?
public ushort ParameterSize { get; set; } //112, 208, 320 (with 16h) 10485872, 17826000, 26214720
public ushort ParameterDataSize { get; set; } //160, 272, 400
public MetaHash FileName { get; set; } //2918136469, 2635608835, 2247429097
public MetaHash FileName { get; set; } //decal_emissive_only.sps, emissive.sps, spec.sps
public uint Unknown_1Ch { get; set; } // 0x00000000
public uint RenderBucketMask { get; set; } //65284, 65281 DrawBucketMask? (1<<bucket) | 0xFF00
public ushort Unknown_24h { get; set; } //0 Instanced?