Пример #1
0
        private void ReadSPTR(int size, ref BinaryReader reader)
        {
            if (HexenFaked)
            {
                int numScripts = size / 8;

                for (int i = 0; i < numScripts; i++)
                {
                    short      number  = reader.ReadInt16();
                    ScriptType type    = (ScriptType)reader.ReadByte();
                    int        argc    = reader.ReadByte();
                    int        address = reader.ReadInt32();

                    AcsScript script = new AcsScript(number, type, argc, address);
                    Scripts[number] = script;
                }
            }
            else
            {
                int numScripts = size / 12;

                for (int i = 0; i < numScripts; i++)
                {
                    short      number  = reader.ReadInt16();
                    ScriptType type    = (ScriptType)reader.ReadInt16();
                    int        address = reader.ReadInt32();
                    int        argc    = reader.ReadInt32();

                    AcsScript script = new AcsScript(number, type, argc, address);
                    Scripts[number] = script;
                }
            }
        }
Пример #2
0
        private void ReadSNAM(int size, ref BinaryReader reader)
        {
            string[] names = ReadStringTable(ref reader, false, false);

            for (int i = 0; i < names.Length; i++)
            {
                AcsScript s = Scripts[-(i + 1)];
                s.Name = names[i];
            }
        }
Пример #3
0
        private void ReadAcs95(ref BinaryReader reader)
        {
            int numPointers = reader.ReadInt32();

            for (int i = 0; i < numPointers; i++)
            {
                int number  = reader.ReadInt32();
                int pointer = reader.ReadInt32();
                int argc    = reader.ReadInt32();

                int        id      = number % 1000;
                int        typeNum = number / 1000;
                ScriptType type    = (ScriptType)typeNum;

                Console.WriteLine("Script " + id + " is of type " + type);

                long pos = InputStream.Position;

                AcsScript script = new AcsScript(number, type, argc, pointer);

                InputStream.Seek(pointer, SeekOrigin.Begin);

                int len = 0;
                while (reader.ReadInt32() != (int)OpcodeEnum.Terminate)
                {
                    len++;
                }

                InputStream.Seek(pointer, SeekOrigin.Begin);

                script.Code = AcsInstruction.ReadCode(this, ref reader, len);

                InputStream.Seek(pos, SeekOrigin.Begin);

                Scripts[number] = script;
            }

            int stringCount = reader.ReadInt32();

            for (int i = 0; i < stringCount; i++)
            {
                int  pointer = reader.ReadInt32();
                long pos     = InputStream.Position;

                InputStream.Seek(pointer, SeekOrigin.Begin);
                StringTable.Add(ReadString());

                InputStream.Seek(pos, SeekOrigin.Begin);
            }
        }
Пример #4
0
        private int FindClosestPointer(int p)
        {
            const int def = Int32.MaxValue;
            int       r   = def;

            foreach (var pair in Scripts)
            {
                AcsScript script = pair.Value;
                int       ptr    = script.Pointer;

                if (p > ptr || p == ptr)
                {
                    continue;
                }

                r = Math.Min(ptr, r);
            }

            for (int i = 0; i < FunctionList.Count; i++)
            {
                int ptr = FunctionList[i].Pointer;

                if (p > ptr || p == ptr)
                {
                    continue;
                }

                r = Math.Min(ptr, r);
            }

            if (r == def && DirOffset > p)
            {
                r = DirOffset;
            }

            if (r == def)
            {
                r = (int)InputStream.Length - 1;
            }

            Console.WriteLine($"Closest to {p} is {r}");

            return(r);
        }
Пример #5
0
        private void ReadCode(ref BinaryReader reader)
        {
            foreach (var script in Scripts)
            {
                int       num = script.Key;
                AcsScript s   = script.Value;

                s.CodeSize = FindClosestPointer(s.Pointer) - s.Pointer;

                InputStream.Seek(s.Pointer, SeekOrigin.Begin);
                s.Code = AcsInstruction.ReadCode(this, ref reader, s.CodeSize);
            }

            foreach (var func in FunctionList)
            {
                func.CodeSize = FindClosestPointer(func.Pointer) - func.Pointer;

                InputStream.Seek(func.Pointer, SeekOrigin.Begin);
                func.Code = AcsInstruction.ReadCode(this, ref reader, func.CodeSize);
            }
        }
Пример #6
0
        public void Disassemble(Stream outputStream)
        {
            OutputStream = outputStream;

            AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();

            WriteLine("// Disassembled by " + assemblyName.Name + " version " + assemblyName.Version);
            WriteLine("//");
            WriteLine("// String Table:");
            for (int i = 0; i < StringTable.Count; i++)
            {
                WriteLine($"//  {i,4} " + StringTable[i]);
            }

            WriteLine();

            if (Format == AcsFormat.Acs95)
            {
                WriteLine("#include \"common.acs\"");
            }
            else
            {
                WriteLine("#include \"zcommon.acs\"");
            }

            WriteLine();
            foreach (var library in Libraries)
            {
                WriteLine($"#import \"{library}\"");
            }
            WriteLine();

            WriteLine("// ================================================== MAP ARRAYS");
            WriteLine();

            if (ImportedMapArrays.Count > 0)
            {
                WriteLine($"/* Imported map arrays ({ImportedMapArrays.Count}:");
                foreach (KeyValuePair <int, ImportedArray> pair in ImportedMapArrays)
                {
                    int           index = pair.Key;
                    ImportedArray array = pair.Value;

                    WriteLine($"/* imported - index {index:x4} */ int {array.Name}[{array.Size}];");
                }
                WriteLine("//*/");
            }

            foreach (var pair in MapArrays)
            {
                int      index    = pair.Key;
                MapArray mapArray = pair.Value;
                int[]    array    = mapArray.Values;

                string name = (!String.IsNullOrEmpty(mapArray.Name) ? mapArray.Name : $"_a_{index:x4}_");
                string type = (mapArray.IsString ? "str" : "int");

                Write($"{type} {name}[{array.Length}] = " + "{");
                for (int i = 0; i < array.Length; i++)
                {
                    if (mapArray.IsString)
                    {
                        string s;
                        int    sI = array[i];

                        if (sI < StringTable.Count)
                        {
                            s = StringTable[array[i]];
                        }
                        else
                        {
                            s = "(DeACC: Invalid string index " + sI + ")";
                        }
                        Write($"\"{s}\"");
                    }
                    else
                    {
                        Write(array[i].ToString());
                    }

                    if (i < array.Length - 1)
                    {
                        Write(", ");
                    }
                }
                WriteLine("};");
            }

            WriteLine();
            WriteLine("// ================================================== MAP VARIABLES");
            WriteLine();

            if (ImportedMapVariables.Count > 0)
            {
                WriteLine($"/* Imported map variables ({ImportedMapVariables.Count}:");
                foreach (KeyValuePair <int, string> pair in ImportedMapVariables)
                {
                    int    index = pair.Key;
                    string name  = pair.Value;

                    WriteLine($"int {name}; // imported - index {index:x4}");
                }
                WriteLine("//*/");
            }

            foreach (var pair in MapVariables)
            {
                int         index = pair.Key;
                MapVariable var   = pair.Value;

                string type = (var.IsString ? "str" : "int");

                WriteLine($"{type} {var.Name} = {var.Value};");
            }

            WriteLine();
            WriteLine("// ================================================== FUNCTIONS");
            WriteLine();

            foreach (KeyValuePair <string, AcsFunction> pair in FunctionMap)
            {
                string      name     = pair.Key;
                AcsFunction function = pair.Value;

                string returnType = (function.Returns ? "int" : "void");
                string args;

                if (function.NumberOfArguments > 0)
                {
                    args = "";
                    for (int i = 0; i < function.NumberOfArguments; i++)
                    {
                        args += $"int _p_{ParameterCounter:x4}_";
                        ParameterCounter++;

                        if (i < function.NumberOfArguments - 1)
                        {
                            args += ", ";
                        }
                    }
                }
                else
                {
                    args = "void";
                }

                WriteLine($"// Pointer: {function.Pointer}; Size = {function.CodeSize}");
                WriteLine($"function {returnType} {name} ({args})");
                WriteLine("{");
                WriteCode(function.Code);
                WriteLine("}");
                WriteLine();
            }

            WriteLine();
            WriteLine("// ================================================== SCRIPTS");
            WriteLine();

            foreach (KeyValuePair <int, AcsScript> pair in Scripts)
            {
                int       number = pair.Key;
                AcsScript script = pair.Value;

                string args  = "(void)";
                string type  = "";
                string flags = "";

                if (script.NumberOfArguments > 0)
                {
                    args = "(";
                    for (int i = 0; i < script.NumberOfArguments; i++)
                    {
                        args += $"int _p_{ParameterCounter:x4}_";
                        ParameterCounter++;

                        if (i < script.NumberOfArguments - 1)
                        {
                            args += ", ";
                        }
                    }
                    args += ")";
                }
                else if (script.NumberOfArguments == 0 && script.Type != ScriptType.Closed)
                {
                    args = "";
                }

                if (script.Type != ScriptType.Closed)
                {
                    type = script.Type.ToString().ToUpper();
                }

                if ((script.Flags & (int)ScriptFlags.Net) != 0)
                {
                    flags += "NET ";
                }

                if ((script.Flags & (int)ScriptFlags.Clientside) != 0)
                {
                    flags += "CLIENTSIDE ";
                }

                string argsSpace = (String.IsNullOrEmpty(args) ? "" : " ");
                string typeSpace = (script.Type != ScriptType.Closed ? " " : "");

                string name = (String.IsNullOrEmpty(script.Name) ? number.ToString() : $"\"{script.Name}\"");

                WriteLine($"// Pointer: {script.Pointer}; Size = {script.CodeSize}");
                WriteLine($"Script {name}{argsSpace}{args}{typeSpace}{type} {flags}");

                WriteLine("{");
                WriteCode(script.Code);
                WriteLine("}");
                WriteLine();
            }
        }