public AGSGameData() { setup = new AGSGameSetupStruct(); save_guid = new char[0]; save_extension = new char[0]; save_folder = new char[0]; font_flags = new byte[0]; font_outlines = new byte[0]; sprite_flags = new byte[0]; inventoryItems = new AGSInventoryItem[0]; cursors = new AGSCursorInfo[0]; dictionary = new AGSDictionary(); globalScript = new AGSScript(); dialogScript = new AGSScript(); scriptModules = new AGSScript[0]; views = new AGSView[0]; characters = new AGSCharacter[0]; globalMessages = new string[0]; dialogs = new AGSDialog[0]; audioStorage = new AGSAudioStorage(); customPropertiesSchema = new AGSCustomProperiesSchema(); roomsDebugInfo = new AGSRoomDebugInfo[0]; globalvars = new AGSInteractionVariable[0]; views272 = new AGSView272[0]; oldDialogStrings = new List <string>(); guis = new AGSGUI[0]; buttons = new AGSGUIButton[0]; labels = new AGSGUILabel[0]; inventoryWindows = new AGSGUIInventoryWindow[0]; sliders = new AGSGUISlider[0]; textboxes = new AGSGUITextBox[0]; listboxes = new AGSGUIListBox[0]; }
private static int GetExportIndex(AGSScript script, int offset) { int index = -1; for (int i = 0; i < script.Exports.Length; ++i) { int functionOffset = script.Exports[i].Pointer & 0x00FFFFFF; if (functionOffset == offset) { index = i; break; } } Debug.Assert(index != -1); return(index); }
private static int GetStringIndex(AGSScript script, int offset) { int acc = 0; int i = 0; for (; i < script.Strings.Length; ++i) { if (acc == offset) { break; } acc += script.Strings[i].Length + 1; } Debug.Assert(acc == offset); return(i); }
public void LoadFromStream(BinaryReader r) { // verify signature char[] dta_sig = r.ReadChars(DTA_SIGNATURE.Length); string dta_sig_string = new string(dta_sig); Debug.Assert(DTA_SIGNATURE == dta_sig_string); // parse dta header Int32 dta_version = r.ReadInt32(); Int32 strlen = r.ReadInt32(); string engine_version = r.ReadFixedCString(strlen); // parse capability strings if (dta_version >= 48) // 3.4.1 { Int32 capabilities_count = r.ReadInt32(); for (int i = 0; i < capabilities_count; ++i) { string capability = r.ReadString(); } } // parse game setup struct base AGSAlignedStream ar = new AGSAlignedStream(r); setup.LoadFromStream(ar, dta_version); if (dta_version > 32) // 3.x { // parse save game info save_guid = r.ReadChars(40); save_extension = r.ReadChars(20); save_folder = r.ReadChars(50); } // parse font info if (dta_version < 50) // 3.5 { font_flags = r.ReadBytes(setup.fonts_count); font_outlines = r.ReadBytes(setup.fonts_count); if (dta_version >= 48) // 3.4.1 { for (int i = 0; i < setup.fonts_count; ++i) { Int32 font_offset_y = r.ReadInt32(); if (dta_version >= 49) // 3.4.1_2 { Int32 font_linespacing = r.ReadInt32(); } } } } else { for (int i = 0; i < setup.fonts_count; ++i) { Int32 flags = r.ReadInt32(); Int32 sizePt = r.ReadInt32(); Int32 outline = r.ReadInt32(); Int32 yOffset = r.ReadInt32(); Int32 lineSpacing = Math.Max(0, r.ReadInt32()); } } // parse sprite flags Int32 sprites_count_max = 6000; if (dta_version >= 24) // pre 2.5.6 { sprites_count_max = r.ReadInt32(); } sprite_flags = r.ReadBytes(sprites_count_max); // parse inventory items info inventoryItems = new AGSInventoryItem[setup.inventory_items_count]; AGSAlignedStream ar1 = new AGSAlignedStream(r); for (int i = 0; i < setup.inventory_items_count; ++i) { inventoryItems[i] = new AGSInventoryItem(); inventoryItems[i].LoadFromStream(ar1); //NOTE(adm244): reset aligned stream?? } // parse cursors info AGSAlignedStream ar2 = new AGSAlignedStream(r); cursors = new AGSCursorInfo[setup.cursors_count]; for (int i = 0; i < cursors.Length; ++i) { cursors[i] = new AGSCursorInfo(); cursors[i].LoadFromStream(ar2); } characters = new AGSCharacter[setup.characters_count]; if (dta_version > 32) // 3.x { // parse characters interaction scripts for (int i = 0; i < characters.Length; ++i) { characters[i] = new AGSCharacter(); characters[i].interactions.LoadFromStream(r); } // parse inventory items interaction scripts for (int i = 1; i < inventoryItems.Length; ++i) { //inventoryItems[i] = new AGSInventoryItem(); inventoryItems[i].interactions.LoadFromStream(r); } } else // 2.72 and older { for (int i = 0; i < characters.Length; ++i) { characters[i] = new AGSCharacter(); characters[i].interactions_old.LoadFromStream(r); } for (int i = 0; i < inventoryItems.Length; ++i) { //inventoryItems[i] = new AGSInventoryItem(); inventoryItems[i].interactions_old.LoadFromStream(r); } Int32 globalvars_count = r.ReadInt32(); globalvars = new AGSInteractionVariable[globalvars_count]; for (int i = 0; i < globalvars.Length; ++i) { globalvars[i] = new AGSInteractionVariable(); globalvars[i].LoadFromStream(r); } } // parse dictionary if (setup.load_dictionary != 0) { dictionary.LoadFromStream(r); } // parse global script globalScript.ReadFromStream(r); // parse dialog script if (dta_version > 37) // 3.1.0 { dialogScript.ReadFromStream(r); } // parse other scripts if (dta_version >= 31) // 2.7.0 { Int32 modules_count = r.ReadInt32(); scriptModules = new AGSScript[modules_count]; for (int i = 0; i < scriptModules.Length; ++i) { scriptModules[i] = new AGSScript(); scriptModules[i].ReadFromStream(r); } } // parse views if (dta_version > 32) // 3.x { views = new AGSView[setup.views_count]; for (int i = 0; i < views.Length; ++i) { views[i] = new AGSView(); views[i].LoadFromStream(r); } } else // 2.7.2 and older { views272 = new AGSView272[setup.views_count]; for (int i = 0; i < views272.Length; ++i) { views272[i] = new AGSView272(); views272[i].LoadFromStream(r); } } // parse characters AGSAlignedStream ar3 = new AGSAlignedStream(r); for (int i = 0; i < characters.Length; ++i) { characters[i].LoadFromStream(ar3); ar.Reset(); } if (dta_version >= 21) // 2.54 { //TODO(adm244): real parsing r.BaseStream.Seek(20 * 50, SeekOrigin.Current); } ParseGlobalMessages(r, dta_version); ParseDialogs(r); if (dta_version <= 37) // 3.0 and older { for (int i = 0; i < dialogs.Length; ++i) { dialogs[i].old_dialog_code = r.ReadBytes(dialogs[i].code_size); Int32 scriptSize = r.ReadInt32(); byte[] encodedStr = r.ReadBytes(scriptSize); dialogs[i].old_dialog_script = AGSEncryption.DecryptAvis(encodedStr); } if (dta_version <= 25) // 2.60 and older { while (true) { uint mark = r.ReadUInt32(); r.BaseStream.Seek(-sizeof(UInt32), SeekOrigin.Current); if (mark == GUI_SIGNATURE) { break; } string dialogString = r.ReadCString(); oldDialogStrings.Add(dialogString); } } else { while (true) { Int32 length = r.ReadInt32(); if ((UInt32)length == GUI_SIGNATURE) { r.BaseStream.Seek(-sizeof(UInt32), SeekOrigin.Current); break; } byte[] encodedStr = r.ReadBytes(length); oldDialogStrings.Add(AGSEncryption.DecryptAvis(encodedStr)); } } } int gui_version = ParseGUIs(r); ParseGUIControls(r, gui_version); if (dta_version >= 25) // 2.60+ { ParsePlugins(r); ParseCustomProperties(r); ParseObjectsScriptNames(r, dta_version); } if (dta_version >= 41) // 3.2.0+ { audioStorage = new AGSAudioStorage(); audioStorage.LoadFromStream(r); } if (dta_version >= 36) // 2.8 ??? { ParseRoomsDebugInfo(r); } }
//TODO(adm244): parse fixups in AGSScript and convert them, so that we only pass here AGSScript and ip public static AGSInstruction DisassembleInstruction(AGSScript script, AGSFixupType[] fixups, int[] code, int ip) { AGSInstruction instruction = new AGSInstruction(); byte instanceId = (byte)((code[ip] >> 24) & 0xFF); Int32 opcodeRaw = (Int32)(code[ip] & 0x00FFFFFF); Debug.Assert(Enum.IsDefined(typeof(AGSOpcodes), opcodeRaw)); AGSOpcodes opcode = (AGSOpcodes)(opcodeRaw); for (int i = 0; i < Instructions.Length; ++i) { if (Instructions[i].Opcode == opcode) { instruction.InstanceId = instanceId; instruction.Opcode = opcode; instruction.Mnemonic = Instructions[i].Mnemonic; Debug.Assert((ip + Instructions[i].ArgumentsCount) < code.Length); instruction.Arguments = new AGSArgument[Instructions[i].ArgumentsCount]; for (int arg = 0; arg < instruction.ArgumentsCount; ++arg) { int index = ip + arg + 1; int value = code[index]; instruction.Arguments[arg].Type = AGSArgumentType.None; instruction.Arguments[arg].IntValue = 0; instruction.Arguments[arg].FloatValue = float.NaN; instruction.Arguments[arg].Name = string.Empty; switch (Instructions[i].Arguments[arg]) { //NOTE(adm244): integer literal can also store a float number // e.g. movlit instruction can load floats as well as ints case AGSBinaryArgumentType.IntLiteral: { AGSFixupType fixuptype = fixups[index]; //Debug.Assert(Enum.IsDefined(typeof(AGSArgumentType), type)); AGSArgumentType type = GetArgumentType(fixuptype, Instructions[i].Arguments[arg]); instruction.Arguments[arg].Type = type; switch (type) { case AGSArgumentType.IntConstant: case AGSArgumentType.StackOffset: //FIX(adm244): get actual stack value from StackOffset instruction.Arguments[arg].IntValue = value; break; case AGSArgumentType.ImportsOffset: instruction.Arguments[arg].Name = script.Imports[value]; break; case AGSArgumentType.FunctionOffset: int exportIndex = GetExportIndex(script, value); instruction.Arguments[arg].Name = script.Exports[exportIndex].Name; break; case AGSArgumentType.StringsOffset: int stringIndex = GetStringIndex(script, value); instruction.Arguments[arg].Name = '"' + script.Strings[stringIndex] + '"'; break; default: Debug.Assert(false, "Unknown argument type!"); break; } } break; case AGSBinaryArgumentType.FloatLiteral: instruction.Arguments[arg].Type = AGSArgumentType.FloatConstant; instruction.Arguments[arg].FloatValue = IEEE754Utils.Int32BitsToFloat(value); break; case AGSBinaryArgumentType.Register: instruction.Arguments[arg].Type = AGSArgumentType.RegisterIndex; instruction.Arguments[arg].IntValue = value; instruction.Arguments[arg].Name = RegisterNames[value]; break; default: Debug.Assert(false, "Unknown binary argument type!"); break; } Debug.Assert(instruction.Arguments[arg].Type != AGSArgumentType.None); } break; } } //NOTE(adm244): swap arguments to match "mov <dest>, <src>" pattern if (instruction.Opcode == AGSOpcodes.REGTOREG) { Debug.Assert(instruction.ArgumentsCount == 2); AGSArgument temp = instruction.Arguments[0]; instruction.Arguments[0] = instruction.Arguments[1]; instruction.Arguments[1] = temp; } return(instruction); }
public void ReadSCOM3Block(BinaryReader reader, int roomVersion) { SCOM3 = new AGSScript(); SCOM3.ReadFromStream(reader); }
public AGSRoomScript() { SCOM3 = new AGSScript(); SourceCode = string.Empty; }