/* Save all changes back out */ public void Save() { BinaryWriter writer = new BinaryWriter(File.OpenWrite(path_to_pak)); //Update all parameter values foreach (CathodeParameter parameter in parameters) { writer.BaseStream.Position = parameter.offset + 4; switch (parameter.dataType) { case CathodeDataType.POSITION: CathodeTransform cTransform = (CathodeTransform)parameter; writer.Write(cTransform.position.x); writer.Write(cTransform.position.y); writer.Write(cTransform.position.z); writer.Write(cTransform.rotation.x); writer.Write(cTransform.rotation.y); writer.Write(cTransform.rotation.z); break; case CathodeDataType.DIRECTION: CathodeVector3 cVector = (CathodeVector3)parameter; writer.Write(cVector.value.x); writer.Write(cVector.value.y); writer.Write(cVector.value.z); break; case CathodeDataType.INTEGER: CathodeInteger cInt = (CathodeInteger)parameter; writer.Write(cInt.value); break; case CathodeDataType.STRING: CathodeString cString = (CathodeString)parameter; writer.BaseStream.Position += 8; for (int i = 0; i < cString.initial_length; i++) { char to_write = (char)0x00; if (i < cString.value.Length) { to_write = cString.value[i]; } writer.Write((byte)to_write); } break; case CathodeDataType.FLOAT: CathodeFloat cFloat = (CathodeFloat)parameter; writer.Write(cFloat.value); break; } } //Update all selected parameter offsets & REDS references foreach (CathodeFlowgraph flowgraph in flowgraphs) { foreach (CathodeNodeEntity node in flowgraph.nodes) { foreach (CathodeParameterReference param_ref in node.nodeParameterReferences) { writer.BaseStream.Position = param_ref.editOffset; writer.Write((int)(param_ref.offset / 4)); } } foreach (CathodeResourceReference resRef in flowgraph.resources) { if (resRef == null || resRef.entryType != CathodeResourceReferenceType.RENDERABLE_INSTANCE) { continue; } writer.BaseStream.Position = resRef.editOffset + 32; writer.Write(resRef.entryIndexREDS); writer.Write(resRef.entryCountREDS); } } writer.Close(); }
/* Read all parameters from the PAK */ private void ReadParameters(BinaryReader reader) { reader.BaseStream.Position = parameter_offsets[0]; for (int i = 0; i < parameter_count; i++) { int length = (i == parameter_count - 1) ? flowgraph_offsets[0] - parameter_offsets[i] : parameter_offsets[i + 1] - parameter_offsets[i]; CathodeParameter this_parameter = new CathodeParameter(); CathodeDataType this_datatype = GetDataType(reader.ReadBytes(4)); switch (this_datatype) { case CathodeDataType.POSITION: this_parameter = new CathodeTransform(); //TODO: are these X/Y/Zs the right way around? ((CathodeTransform)this_parameter).position = new Vec3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); ((CathodeTransform)this_parameter).rotation = new Vec3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); break; case CathodeDataType.INTEGER: this_parameter = new CathodeInteger(); ((CathodeInteger)this_parameter).value = reader.ReadInt32(); break; case CathodeDataType.STRING: this_parameter = new CathodeString(); ((CathodeString)this_parameter).unk0 = reader.ReadBytes(4); // some kind of ID sometimes referenced in script and resource id ((CathodeString)this_parameter).unk1 = reader.ReadBytes(4); // sometimes flowgraph id ?! bool shouldStop = false; for (int x = 0; x < length - 8; x++) { byte thisByte = reader.ReadByte(); if (thisByte == 0x00) { shouldStop = true; continue; } if (shouldStop && thisByte != 0x00) { break; } ((CathodeString)this_parameter).value += (char)thisByte; } ((CathodeString)this_parameter).initial_length = length - 13; reader.BaseStream.Position -= 1; break; case CathodeDataType.BOOL: this_parameter = new CathodeBool(); ((CathodeBool)this_parameter).value = (reader.ReadInt32() == 1); break; case CathodeDataType.FLOAT: this_parameter = new CathodeFloat(); ((CathodeFloat)this_parameter).value = reader.ReadSingle(); break; case CathodeDataType.SHORT_GUID: this_parameter = new CathodeResource(); ((CathodeResource)this_parameter).resourceID = reader.ReadBytes(4); break; case CathodeDataType.DIRECTION: this_parameter = new CathodeVector3(); ((CathodeVector3)this_parameter).value = new Vec3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); break; case CathodeDataType.ENUM: this_parameter = new CathodeEnum(); ((CathodeEnum)this_parameter).enumID = reader.ReadBytes(4); ((CathodeEnum)this_parameter).enumIndex = reader.ReadInt32(); break; /* * case CathodeDataType.SPLINE_DATA: * this_parameter = new CathodeSpline(); * int start_offset = reader.ReadInt32(); //This just gives us a pointless offset * int num_points = reader.ReadInt32(); * * if (length - 12 != num_points * 24) * { * string dsfsdf = ""; //for some reason some have extra data at the end * } * * for (int x = 0; x < num_points; x++) * { * CathodeTransform this_point = new CathodeTransform(); * this_point.position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); * this_point.rotation = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); * ((CathodeSpline)this_parameter).splinePoints.Add(this_point); * } * break; */ default: this_parameter.unknownContent = reader.ReadBytes(length - 4); //Should never hit this! break; } this_parameter.offset = parameter_offsets[i]; this_parameter.dataType = this_datatype; parameters.Add(this_parameter); } }