/// <summary> /// Serialize the reference chain. This functions assumes that the Reference objects have already been written to file (i.e. the CODE chunk was before FUNC/VARI, /// which is normally always the case) /// </summary> public static void SerializeReferenceChain(UndertaleWriter writer, IList <UndertaleCode> codeList, IList <T> varList) { Dictionary <T, List <UndertaleInstruction> > references = CollectReferences(codeList); uint pos = writer.Position; foreach (T var in varList) { var.Occurrences = references.ContainsKey(var) ? (uint)references[var].Count : 0; if (var.Occurrences > 0) { var.FirstAddress = references[var][0]; for (int i = 0; i < references[var].Count; i++) { uint thisAddr = writer.GetAddressForUndertaleObject(references[var][i]); int addrDiff; if (i < references[var].Count - 1) { uint nextAddr = writer.GetAddressForUndertaleObject(references[var][i + 1]); addrDiff = (int)(nextAddr - thisAddr); } else { addrDiff = var.UnknownChainEndingValue; } writer.Position = writer.GetAddressForUndertaleObject(references[var][i].GetReference <T>()); writer.WriteInt24(addrDiff); } } else { var.FirstAddress = null; } } writer.Position = pos; }
internal override void SerializeChunk(UndertaleWriter writer) { // Update references Dictionary <UndertaleVariable, List <UndertaleInstruction> > references = UndertaleInstruction.Reference <UndertaleVariable> .CollectReferences(writer.undertaleData.Code); uint pos = writer.Position; foreach (UndertaleVariable var in List) { var.Occurrences = references.ContainsKey(var) ? (uint)references[var].Count : 0; if (var.Occurrences > 0) { var.FirstAddress = references[var][0]; for (int i = 0; i < references[var].Count; i++) { uint thisAddr = writer.GetAddressForUndertaleObject(references[var][i]); int addrDiff; if (i < references[var].Count - 1) { uint nextAddr = writer.GetAddressForUndertaleObject(references[var][i + 1]); addrDiff = (int)(nextAddr - thisAddr); } else { addrDiff = var.UnknownChainEndingValue; } // references[var][i].GetReference<UndertaleVariable>().NextOccurrenceOffset = addrDiff; /*if (addrDiff != references[var][i].GetReference<UndertaleVariable>().NextOccurrenceOffset) * Debug.WriteLine("VARI Changes at " + writer.GetAddressForUndertaleObject(references[var][i].GetReference<UndertaleVariable>()) + ": " + references[var][i].GetReference<UndertaleVariable>().NextOccurrenceOffset + " to " + addrDiff);*/ writer.Position = writer.GetAddressForUndertaleObject(references[var][i].GetReference <UndertaleVariable>()); writer.WriteInt24(addrDiff); } } else { var.FirstAddress = null; } } writer.Position = pos; writer.Write(InstanceVarCount); writer.Write(InstanceVarCountAgain); writer.Write(MaxLocalVarCount); foreach (UndertaleVariable var in List) { writer.WriteUndertaleObject(var); } }
internal override void SerializeChunk(UndertaleWriter writer) { // Update references Dictionary <UndertaleFunction, List <UndertaleInstruction> > references = UndertaleInstruction.Reference <UndertaleFunction> .CollectReferences(writer.undertaleData.Code); uint pos = writer.Position; // TODO: don't repeat the code from VARI, I spent 6 hours debugging the fact that I didn't copy one change from 0 to 1 between them :P foreach (UndertaleFunction var in Functions) { var.Occurrences = references.ContainsKey(var) ? (uint)references[var].Count : 0; if (var.Occurrences > 0) { var.FirstAddress = references[var][0]; for (int i = 0; i < references[var].Count; i++) { uint thisAddr = writer.GetAddressForUndertaleObject(references[var][i]); int addrDiff; if (i < references[var].Count - 1) { uint nextAddr = writer.GetAddressForUndertaleObject(references[var][i + 1]); addrDiff = (int)(nextAddr - thisAddr); } else { addrDiff = var.UnknownChainEndingValue; } // references[var][i].GetReference<UndertaleFunction>().NextOccurrenceOffset = addrDiff; /*if (addrDiff != references[var][i].GetReference<UndertaleFunction>().NextOccurrenceOffset) * Debug.WriteLine("FUNC Changes at " + writer.GetAddressForUndertaleObject(references[var][i].GetReference<UndertaleFunction>()) + ": " + references[var][i].GetReference<UndertaleFunction>().NextOccurrenceOffset + " to " + addrDiff);*/ writer.Position = writer.GetAddressForUndertaleObject(references[var][i].GetReference <UndertaleFunction>()); writer.WriteInt24(addrDiff); } } else { var.FirstAddress = null; } } writer.Position = pos; writer.WriteUndertaleObject(Functions); writer.WriteUndertaleObject(CodeLocals); }
public void Serialize(UndertaleWriter writer) { writer.WriteUndertaleString(Name); writer.Write(Occurrences); if (Occurrences > 0) { writer.Write(writer.GetAddressForUndertaleObject(FirstAddress)); } else { writer.Write((int)-1); } }
} // looks like an identifier or counter of some kind. Increases in every variable, but I can't find the pattern public void Serialize(UndertaleWriter writer) { writer.WriteUndertaleString(Name); if (writer.undertaleData.GeneralInfo?.BytecodeVersion >= 15) { writer.Write((int)InstanceType); writer.Write(VarID); } writer.Write(Occurrences); if (Occurrences > 0) { writer.Write(writer.GetAddressForUndertaleObject(FirstAddress)); } else { writer.Write((int)-1); } }
public void Serialize(UndertaleWriter writer) { writer.WriteUndertaleString(Name); writer.Write(Occurrences); if (Occurrences > 0) { uint addr = writer.GetAddressForUndertaleObject(FirstAddress); if (GMS2_3) { writer.Write((addr == 0) ? 0 : (addr + 4)); // in GMS 2.3, it points to the actual reference rather than the instruction } else { writer.Write(addr); } } else { writer.Write((int)-1); } }