Ejemplo n.º 1
0
        private CodeLine ReadCodeLine()
        {
            CodeLine code = new CodeLine(currentLine, (int)fs.Position);

            if (!gotoPosLine.ContainsKey((int)fs.Position))
            {
                // 位置 下标
                gotoPosLine.Add((int)fs.Position, currentLine);
            }

            int codeLength = 0;
            int codeOffset = 0;


            if (script.version == 2)
            {
                // [xx]   [xx]
                // opcode len
                code.opcodeIndex = br.ReadByte();
                codeLength       = br.ReadByte() * 2;
                codeOffset      += 2;
            }
            else if (script.version == 3)
            {
                // [xx xx] [xx]
                // len     opcode
                codeLength       = br.ReadUInt16() - 2;
                code.opcodeIndex = br.ReadByte();
                codeOffset++;
            }
            long savePosition = fs.Position;

            fs.Seek(-codeOffset, SeekOrigin.Current);
            code.bytes = br.ReadBytes(codeLength);
            fs.Seek(savePosition, SeekOrigin.Begin);

            if (!opcodeDict.ContainsKey(code.opcodeIndex))
            {
                throw new Exception("未知的opcode!");
            }
            code.opcode = opcodeDict[code.opcodeIndex].opcode;

            int      infoCount = 0;
            CodeInfo info      = null;

            if (script.version == 2)
            {
                info         = new CodeInfo(0);
                info.count   = 1;
                info.data    = new UInt16[1];
                info.data[0] = br.ReadUInt16();
                //fs.Seek(-2, SeekOrigin.Current);
                codeOffset += 2;
                code.info   = info;
            }
            else if (script.version == 3)
            {
                info = new CodeInfo(br.ReadByte());
                codeOffset++;
                infoCount = info.count;
                // END指令info.count需要减一
                if (code.opcode == "END")
                {
                    infoCount--;
                }
                else if (code.opcode == "LOG" && infoCount == 7)
                {
                    infoCount = 3;
                }

                while (codeLength - 2 < infoCount * 2)
                {
                    infoCount--;
                }
                info.data = new UInt16[infoCount];

                for (int i = 0; i < infoCount; i++)
                {
                    info.data[i] = br.ReadUInt16();
                    codeOffset  += 2;
                }
                code.info = info;
            }


            // 参数类型列表
            code.paramTypes = opcodeDict[code.opcodeIndex].param.ToArray();
            // 读取已知参数数据
            code.paramDatas = ReadParamData(code.paramTypes, codeLength, ref codeOffset);
            // 处理未知参数数据
            while (codeOffset + 1 < codeLength)
            {
                byte[] temp = br.ReadBytes(2);
                codeOffset += 2;
                code.paramDatas.Add(new ParamData(DataType.Byte2, temp, ScriptUtil.Byte2Hex(temp, false, true)));
            }
            if (codeOffset < codeLength)
            {
                byte[] temp = br.ReadBytes(1);
                codeOffset++;
                if (script.version == 2 && temp[0] == 0x00)
                {
                    // 最后多出的单字节,若为0x00则舍弃
                }
                else
                {
                    code.paramDatas.Add(new ParamData(DataType.Byte, temp, ScriptUtil.Byte2Hex(temp, false, true)));
                }
            }
            // 长度非偶数,最后会有补位
            if (codeLength % 2 != 0)
            {
                br.ReadByte();
            }

            // 判断是否含跳转
            foreach (var param in code.paramDatas)
            {
                if (param.type == DataType.Position)
                {
                    code.isPosition = true;
                    labelPos.Add((int)(uint)param.value);
                }
            }


            currentLine++;
            return(code);
        }
Ejemplo n.º 2
0
 public void ReadScript_SetCodeLine(CodeLine code)
 {
     script.lines.Add(code);
 }