示例#1
0
        private static void ParseScripts(byte[] jsmb, byte[] symb)
        {
            //string[] symbolNames = new string[symb.Length / 32];
            if (symb == null)
            {
                return;
            }
            symbolNames = System.Text.Encoding.ASCII.GetString(symb).Replace(" ", "").Replace("\0", "").Split('\n');
            //for(int i = 0; i<symbolNames.Length; i++)
            //    symbolNames[i] = System.Text.Encoding.ASCII.GetString(symb, i * 32, 32).TrimEnd('\0', '\n', ' ');
            //File.WriteAllBytes("D:/symb.test", symb);
            jsm = new SJSM();
            //File.WriteAllBytes("D:\\test.jsm", jsmb);
            using (Stream str = new MemoryStream(jsmb))
                using (BinaryReader br = new BinaryReader(str))
                {
                    jsm.cDoorEntity       = br.ReadByte();
                    jsm.cWalkmeshEntity   = br.ReadByte();
                    jsm.cBackgroundEntity = br.ReadByte();
                    jsm.cOtherEntity      = br.ReadByte();
                    jsm.offsetSecOne      = br.ReadUInt16();
                    jsm.offsetScriptData  = br.ReadUInt16();
                    EntryPointEntity[] epe = new EntryPointEntity[jsm.cDoorEntity + jsm.cOtherEntity + jsm.cWalkmeshEntity + jsm.cBackgroundEntity];
                    for (int i = 0; i < epe.Length; i++)
                    {
                        ushort bb = br.ReadUInt16();
                        epe[i].scriptCount = (byte)((bb & 0x7F) + 1);
                        epe[i].label       = (byte)(bb >> 7);
                        // was throwing exception
                        epe[i].labelASM = symbolNames != null && epe[i].label < symbolNames.Length ? symbolNames[epe[i].label] : "";
                    }
                    int SYMscriptNameStartingPoint = jsm.cDoorEntity + jsm.cOtherEntity + jsm.cWalkmeshEntity + jsm.cBackgroundEntity;
                    jsm.EntityEntryPoints = epe;
                    EntryPointScript[] eps = new EntryPointScript[(jsm.offsetScriptData - jsm.offsetSecOne) / 2 - 1];
                    for (int i = 0; i < eps.Length; i++)
                    {
                        ushort bb = br.ReadUInt16();
                        eps[i].position = (ushort)((bb & 0x7FFF) * 4);
                        eps[i].flag     = (byte)(bb >> 15);
                    }
                    ushort eof = br.ReadUInt16();
                    jsm.entryPointScripts = eps;

                    //br.BaseStream.Seek(jsm.offsetScriptData, SeekOrigin.Begin);

                    ScriptSystem = new List <ScriptEntry>();
                    List <ScriptOpcode> scriptChunk = new List <ScriptOpcode>();
                    int scriptLabelPointer          = 0;
                    while (br.BaseStream.Position != br.BaseStream.Length)
                    {
                        if (br.BaseStream.Position == br.BaseStream.Length)
                        {
                            break; //??
                        }
                        uint binaryOpcode = br.ReadUInt32();
                        uint parameter    = 0;
                        uint opcode       = 0;
                        if ((binaryOpcode & 0xFFFFFF00) == 0) //when only function
                        {
                            opcode    = binaryOpcode;
                            parameter = 0;
                        }
                        else
                        {
                            opcode    = binaryOpcode >> 16;
                            opcode    = (opcode >> 8) | opcode << 8 & 0xFF00;
                            parameter = binaryOpcode & 0xFFFF;
                        }
                        if (opcode == 5 && scriptChunk.Count != 0) //label
                        {
                            ushort entityNumber = 0;
                            if (symbolNames != null && SYMscriptNameStartingPoint + scriptLabelPointer < symbolNames.Length)
                            {
                                entityNumber = (ushort)FindEntity(symbolNames[SYMscriptNameStartingPoint + scriptLabelPointer]);
                            }
                            int locId = ScriptSystem.Count(x => x.Entity == entityNumber);
                            ScriptSystem.Add(new ScriptEntry()
                            {
                                Entity     = entityNumber,
                                ScriptName = (SYMscriptNameStartingPoint + scriptLabelPointer + 1 < symbolNames.Length ? symbolNames[SYMscriptNameStartingPoint + scriptLabelPointer++] : ""),
                                ID         = scriptChunk[0].parameter,
                                localID    = (ushort)locId++,
                                Scripts    = scriptChunk.ToArray()
                            });
                            scriptChunk.Clear();
                        }

                        scriptChunk.Add(new ScriptOpcode()
                        {
                            parameter    = (ushort)parameter,
                            opcodeBinary = (ushort)opcode,
                            opcodeASM    = Enum.GetName(typeof(JSMopcodes), opcode),
                            opcode       = (JSMopcodes)opcode
                        });
                        if (br.BaseStream.Position == br.BaseStream.Length)
                        {
                            ushort entityNumber = 0;
                            if (symbolNames != null && SYMscriptNameStartingPoint + scriptLabelPointer < symbolNames.Length)
                            {
                                entityNumber = (ushort)FindEntity(symbolNames[SYMscriptNameStartingPoint + scriptLabelPointer]);
                            }
                            int locId = ScriptSystem.Count(x => x.Entity == entityNumber);
                            ScriptSystem.Add(new ScriptEntry()
                            {
                                Entity     = entityNumber,
                                ScriptName = (SYMscriptNameStartingPoint + scriptLabelPointer + 1 < symbolNames.Length ? symbolNames[SYMscriptNameStartingPoint + scriptLabelPointer++]:""),
                                ID         = scriptChunk[0].parameter,
                                localID    = (ushort)locId++,
                                Scripts    = scriptChunk.ToArray()
                            });
                            break;
                        }
                    }

                    /*
                     * okay, my notes on JSM:
                     * so the exec is always Lines first, they tend to always contain 8 IDs like touch touchoff etc
                     * it begins with setline
                     *
                     * next are doors, yes?
                     * they are like open, close, on, off
                     * so you have to test the location of the player and see if he triggers any of this script
                     *
                     * next are other things
                     * finally an character entity- director. He plays like if we should call some functions or not
                     *
                     * it's like RET(8) makes it never use the code again in a loop of execution
                     *
                     * so it all plays normally, because almost everytime it's RET of the function. All action is triggered by like PUSH or TALK
                     *
                     * Other functions are not normally playing. See bgroom_4. Default code is actually playing the monitor.on functions
                     *
                     * So for sure I'll need to read .SYM, then pair the names with script IDs, then sort by the exec priority and read only the 0 and 1 as default and init scripts
                     * everything else leave for triggering. Ugh, that's going to be painful
                     *
                     */
                }
        }
示例#2
0
        private static void Init()
        {
            ArchiveWorker aw = new ArchiveWorker($"{Memory.Archives.A_FIELD}.fs");

            string[] test = aw.GetListOfFiles();
            if (Memory.FieldHolder.FieldID >= Memory.FieldHolder.fields.Length ||
                Memory.FieldHolder.FieldID < 0)
            {
                return;
            }
            var CollectionEntry = test.Where(x => x.ToLower().Contains(Memory.FieldHolder.fields[Memory.FieldHolder.FieldID]));

            if (!CollectionEntry.Any())
            {
                return;
            }
            string fieldArchive = CollectionEntry.First();
            int    fieldLen     = fieldArchive.Length - 2;

            fieldArchive = fieldArchive.Substring(0, fieldLen);
            byte[] fs = ArchiveWorker.GetBinaryFile(Memory.Archives.A_FIELD, $"{fieldArchive}fs");
            byte[] fi = ArchiveWorker.GetBinaryFile(Memory.Archives.A_FIELD, $"{fieldArchive}fi");
            byte[] fl = ArchiveWorker.GetBinaryFile(Memory.Archives.A_FIELD, $"{fieldArchive}fl");
            if (fs == null || fi == null || fl == null)
            {
                return;
            }
            string[] test_ = ArchiveWorker.GetBinaryFileList(fl);
            string   mim   = null;
            string   map   = null;

            try
            {
                mim = test_.First(x => x.ToLower().Contains(".mim"));
            }
            catch {}
            try
            {
                map = test_.First(x => x.ToLower().Contains(".map"));
            }
            catch {}

            if (mim != null && map != null)
            {
                byte[] mimb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, mim);
                byte[] mapb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, map);

                ParseBackground(mimb, mapb);
            }

#if DEBUG
            if (Memory.FieldHolder.FieldID == 180)
            {
                goto safeDebugpoint;                                    //delete me
            }
#endif
            //let's start with scripts
            byte[] jsm   = null;
            byte[] sy    = null;
            string s_jsm = null;
            string s_sy  = null;
            try
            {
                s_jsm = test_.First(x => x.ToLower().Contains(".jsm"));
            }
            catch { }
            try
            {
                s_sy = test_.First(x => x.ToLower().Contains(".sy"));
            }
            catch { }
            if (s_jsm != null && s_sy != null)
            {
                jsm = ArchiveWorker.FileInTwoArchives(fi, fs, fl, s_jsm);
                sy  = ArchiveWorker.FileInTwoArchives(fi, fs, fl, s_sy);

                ParseScripts(jsm, sy);
            }
            Stack = new List <int>();
#if DEBUG
            OutputAllParsedScripts();
#endif

            //string mch = test_.Where(x => x.ToLower().Contains(".mch")).First();
            //string one = test_.Where(x => x.ToLower().Contains(".one")).First();
            //string msd = test_.Where(x => x.ToLower().Contains(".msd")).First();
            //string inf = test_.Where(x => x.ToLower().Contains(".inf")).First();
            //string id = test_.Where(x => x.ToLower().Contains(".id")).First();
            //string ca = test_.Where(x => x.ToLower().Contains(".ca")).First();
            //string tdw = test_.Where(x => x.ToLower().Contains(".tdw")).First();
            //string msk = test_.Where(x => x.ToLower().Contains(".msk")).First();
            //string rat = test_.Where(x => x.ToLower().Contains(".rat")).First();
            //string pmd = test_.Where(x => x.ToLower().Contains(".pmd")).First();
            //string sfx = test_.Where(x => x.ToLower().Contains(".sfx")).First();

            //byte[] mchb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, mch); //Field character models
            //byte[] oneb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, one); //Field character models container
            //byte[] msdb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, msd); //dialogs
            //byte[] infb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, inf); //gateways
            //byte[] idb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, id); //walkmesh
            //byte[] cab = ArchiveWorker.FileInTwoArchives(fi, fs, fl, ca); //camera
            //byte[] tdwb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, tdw); //extra font
            //byte[] mskb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, msk); //movie cam
            //byte[] ratb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, rat); //battle on field
            //byte[] pmdb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, pmd); //particle info
            //byte[] sfxb = ArchiveWorker.FileInTwoArchives(fi, fs, fl, sfx); //sound effects



safeDebugpoint:
            mod++;
            return;
        }