示例#1
0
文件: Program.cs 项目: xesf/LifeDISA
        public static void Dump(string filename, TextWriter writer)
        {
            List <int>               indentation   = new List <int>();
            List <int>               elseIndent    = new List <int>();
            HashSet <int>            gotosToIgnore = new HashSet <int>();
            Dictionary <int, string> switchEvalVar = new Dictionary <int, string>();
            List <Tuple <int, int> > switchDefault = new List <Tuple <int, int> >();

            bool consecutiveIfs = false;

            allBytes = File.ReadAllBytes(filename);

            pos = 0;

            while (pos < allBytes.Length)
            {
                while (indentation.Contains(pos))
                {
                    indentation.RemoveAt(indentation.IndexOf(pos));
                    WriteLine(writer, indentation.Count(), "END\r\n");
                }

                if (elseIndent.Contains(pos))
                {
                    elseIndent.RemoveAt(elseIndent.IndexOf(pos));
                    WriteLine(writer, indentation.Count() - 1, "ELSE\r\n");
                }

                Tuple <int, int> defaultCase = switchDefault.FirstOrDefault(x => x.Item1 == pos);
                if (defaultCase != null)
                {
                    switchDefault.RemoveAt(switchDefault.IndexOf(defaultCase));
                    WriteLine(writer, indentation.Count(), "DEFAULT\r\n");
                    indentation.Add(defaultCase.Item2);
                }

                int oldPos = pos;
                int actor  = -1;
                int curr   = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                if ((curr & 0x8000) == 0x8000)
                {
                    curr  = curr & 0x7FFF;
                    pos  += 2;
                    actor = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                }

                LifeEnum life = (LifeEnum)Enum.ToObject(typeof(LifeEnum), curr);

                //skip gotos
                if (life == LifeEnum.GOTO && gotosToIgnore.Contains(oldPos))
                {
                    pos += 4;
                    continue;
                }

                string lifeString = life.ToString();
                if (lifeString.StartsWith("IF"))
                {
                    lifeString = "IF";
                }
                else if (lifeString == "MULTI_CASE")
                {
                    lifeString = "CASE";
                }
                if (actor != -1)
                {
                    lifeString = objectsByIndex[actor] + "." + lifeString;
                }

                if (consecutiveIfs)
                {
                    writer.Write(" AND ");
                    consecutiveIfs = false;
                }
                else
                {
                    WriteLine(writer, indentation.Count(x => x > pos), lifeString + " ");
                }

                pos += 2;

                switch (life)
                {
                case LifeEnum.IF_EGAL:
                case LifeEnum.IF_DIFFERENT:
                case LifeEnum.IF_SUP_EGAL:
                case LifeEnum.IF_SUP:
                case LifeEnum.IF_INF_EGAL:
                case LifeEnum.IF_INF:
                    string paramA = evalvar();
                    string paramB = evalvar();

                    string paramAShort = paramA.Split('.').Last();
                    if (paramAShort == "INHAND" || paramAShort == "COL_BY" || paramAShort == "HIT_BY" || paramAShort == "HIT" || paramAShort == "COLLIDING_ACTOR")
                    {
                        paramB = objectsByIndex[int.Parse(paramB)];
                    }

                    if (paramAShort == "ANIM")
                    {
                        paramB = vars.GetText("ANIMS", paramB);
                    }

                    if (paramAShort == "BODY")
                    {
                        paramB = vars.GetText("BODYS", paramB);
                    }

                    if (paramAShort == "KEYBOARD_INPUT")
                    {
                        paramB = vars.GetText("KEYBOARD INPUT", paramB);
                    }

                    if (paramAShort.StartsWith("POSREL"))
                    {
                        paramB = vars.GetText("POSREL", paramB);
                    }

                    switch (life)
                    {
                    case LifeEnum.IF_EGAL:
                        writer.Write("{0} == {1}", paramA, paramB);
                        break;

                    case LifeEnum.IF_DIFFERENT:
                        writer.Write("{0} <> {1}", paramA, paramB);
                        break;

                    case LifeEnum.IF_SUP_EGAL:
                        writer.Write("{0} >= {1}", paramA, paramB);
                        break;

                    case LifeEnum.IF_SUP:
                        writer.Write("{0} > {1}", paramA, paramB);
                        break;

                    case LifeEnum.IF_INF_EGAL:
                        writer.Write("{0} <= {1}", paramA, paramB);
                        break;

                    case LifeEnum.IF_INF:
                        writer.Write("{0} < {1}", paramA, paramB);
                        break;
                    }

                    //read goto
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;

                    //detect if else
                    int beforeGoto = pos + curr * 2 - 4;
                    int next       = ReadShort(allBytes[beforeGoto + 0], allBytes[beforeGoto + 1]);
                    if (next == (int)LifeEnum.GOTO)
                    {
                        gotosToIgnore.Add(beforeGoto);
                        elseIndent.Add(pos + curr * 2);
                        indentation.Add(beforeGoto + 4 + ReadShort(allBytes[beforeGoto + 2], allBytes[beforeGoto + 3]) * 2);
                    }
                    else
                    {
                        indentation.Add(pos + curr * 2);
                    }

                    //check if next instruction is also an if
                    int previousPos = pos;
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;

                    if (curr == (int)LifeEnum.IF_EGAL ||
                        curr == (int)LifeEnum.IF_DIFFERENT ||
                        curr == (int)LifeEnum.IF_INF ||
                        curr == (int)LifeEnum.IF_INF_EGAL ||
                        curr == (int)LifeEnum.IF_SUP ||
                        curr == (int)LifeEnum.IF_SUP_EGAL)
                    {
                        //skip if evaluated vars
                        int dummyActor;

                        evalvarImpl(out dummyActor);
                        evalvarImpl(out dummyActor);

                        //check if the two if end up at same place
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        pos += 2;

                        if ((beforeGoto + 4) == (pos + curr * 2))
                        {
                            consecutiveIfs = true;
                            indentation.RemoveAt(indentation.Count - 1);
                        }
                    }

                    pos = previousPos;
                    break;

                case LifeEnum.GOTO:                         //should never be called
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", pos + curr * 2);
                    break;

                case LifeEnum.SWITCH:
                    string paramS = evalvar();
                    writer.Write("{0}", paramS);

                    //find end of switch
                    bool endOfSwitch = false;
                    int  gotoPos     = pos;

                    //fix for #353 : IF appearing just after switch (while a CASE is expected)
                    while (ReadShort(allBytes[gotoPos + 0], allBytes[gotoPos + 1]) != (int)LifeEnum.CASE &&
                           ReadShort(allBytes[gotoPos + 0], allBytes[gotoPos + 1]) != (int)LifeEnum.MULTI_CASE)
                    {
                        gotoPos += 2;
                    }

                    int switchEndGoto = -1;
                    do
                    {
                        int casePos = ReadShort(allBytes[gotoPos + 0], allBytes[gotoPos + 1]);
                        if (casePos == (int)LifeEnum.CASE)
                        {
                            switchEvalVar.Add(gotoPos, paramS);
                            gotoPos += 4;                                     //skip case + value

                            //goto just after case
                            gotoPos += 2 + ReadShort(allBytes[gotoPos + 0], allBytes[gotoPos + 1]) * 2;
                            if (ReadShort(allBytes[gotoPos - 4], allBytes[gotoPos - 3]) == (int)LifeEnum.GOTO)
                            {
                                gotosToIgnore.Add(gotoPos - 4);                                       //goto at the end of the case statement (end of switch)
                                if (switchEndGoto == -1)
                                {
                                    switchEndGoto = gotoPos + ReadShort(allBytes[gotoPos - 2], allBytes[gotoPos - 1]) * 2;
                                }
                            }
                        }
                        else if (casePos == (int)LifeEnum.MULTI_CASE)
                        {
                            switchEvalVar.Add(gotoPos, paramS);
                            gotoPos += 2;                                     //skip multi case
                            casePos  = ReadShort(allBytes[gotoPos + 0], allBytes[gotoPos + 1]);
                            gotoPos += 2 + casePos * 2;                       //skip values

                            //goto just after case
                            gotoPos += 2 + ReadShort(allBytes[gotoPos + 0], allBytes[gotoPos + 1]) * 2;
                            if (ReadShort(allBytes[gotoPos - 4], allBytes[gotoPos - 3]) == (int)LifeEnum.GOTO)
                            {
                                gotosToIgnore.Add(gotoPos - 4);                                       //goto at the end of the case statement (end of switch)
                                if (switchEndGoto == -1)
                                {
                                    //end of switch
                                    switchEndGoto = gotoPos + ReadShort(allBytes[gotoPos - 2], allBytes[gotoPos - 1]) * 2;
                                }
                            }
                        }
                        else
                        {
                            endOfSwitch = true;
                        }
                    }while(!endOfSwitch);

                    //should be equal, otherwise there is a default case
                    if (switchEndGoto != -1 && switchEndGoto != gotoPos)
                    {
                        switchDefault.Add(new Tuple <int, int>(gotoPos, switchEndGoto)); //default start + end pos
                        indentation.Add(switchEndGoto);                                  //end of switch
                    }
                    else
                    {
                        indentation.Add(gotoPos);                                 //end of switch
                    }

                    break;

                case LifeEnum.SOUND:
                {
                    string param = evalvar();
                    writer.Write("{0}", vars.GetText("SOUNDS", param));
                    break;
                }

                case LifeEnum.BODY:
                {
                    string param = evalvar();
                    writer.Write("{0}", vars.GetText("BODYS", param));
                    break;
                }

                case LifeEnum.SAMPLE_THEN:
                    string param1 = evalvar();
                    writer.Write("{0} ", param1);
                    string param2 = evalvar();
                    writer.Write("{0}", param2);
                    break;

                case LifeEnum.CAMERA_TARGET:
                case LifeEnum.TAKE:
                case LifeEnum.IN_HAND:
                case LifeEnum.DELETE:
                case LifeEnum.FOUND:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", objectsByIndex[curr]);
                    break;

                case LifeEnum.FOUND_NAME:
                case LifeEnum.MESSAGE:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", namesByIndex[curr]);
                    break;

                case LifeEnum.FOUND_FLAG:
                case LifeEnum.FLAGS:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("0x{0:X4}", curr);
                    break;

                case LifeEnum.LIFE:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", vars.GetText("LIFES", curr));
                    break;

                case LifeEnum.FOUND_BODY:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", vars.GetText("BODYS", curr));
                    break;

                case LifeEnum.NEXT_MUSIC:
                case LifeEnum.MUSIC:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", vars.GetText("MUSIC", curr));
                    break;

                case LifeEnum.ANIM_REPEAT:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", vars.GetText("ANIMS", curr));
                    break;

                case LifeEnum.COPY_ANGLE:
                case LifeEnum.TEST_COL:
                case LifeEnum.SPECIAL:
                case LifeEnum.LIFE_MODE:
                case LifeEnum.FOUND_WEIGHT:
                case LifeEnum.ALLOW_INVENTORY:
                case LifeEnum.WATER:
                case LifeEnum.RND_FREQ:
                case LifeEnum.LIGHT:
                case LifeEnum.SHAKING:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", curr);
                    break;

                case LifeEnum.READ:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} ", curr);
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} ", curr);
                    if (IsCDROMVersion)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        pos += 2;
                        writer.Write("{0}", curr);
                    }
                    break;

                case LifeEnum.PUT_AT:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} ", objectsByIndex[curr]);
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", objectsByIndex[curr]);
                    break;

                case LifeEnum.MOVE:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} ", trackModes[curr]);
                    int trackmode = curr;
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    if (trackmode == 3)
                    {
                        writer.Write("{0}", vars.GetText("TRACKS", curr));
                    }
                    else
                    {
                        writer.Write("{0}", curr);
                    }
                    break;

                case LifeEnum.ANIM_ONCE:
                case LifeEnum.ANIM_ALL_ONCE:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} ", vars.GetText("ANIMS", curr));
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", vars.GetText("ANIMS", curr));
                    break;

                case LifeEnum.SET_BETA:
                case LifeEnum.SET_ALPHA:
                case LifeEnum.HIT_OBJECT:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} ", curr);
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0}", curr);
                    break;

                case LifeEnum.CASE:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;

                    string lastSwitchVar = switchEvalVar[pos - 4].Split('.').Last();
                    if (lastSwitchVar == "INHAND" || lastSwitchVar == "COL_BY" || lastSwitchVar == "HIT_BY" ||
                        lastSwitchVar == "HIT" || lastSwitchVar == "COLLIDING_ACTOR")
                    {
                        writer.Write("{0}", objectsByIndex[curr]);
                    }
                    else if (lastSwitchVar == "ACTION")
                    {
                        writer.Write("{0}", getActionName(curr));
                    }
                    else if (lastSwitchVar == "ANIM")
                    {
                        writer.Write("{0}", vars.GetText("ANIMS", curr));
                    }
                    else if (lastSwitchVar == "BODY")
                    {
                        writer.Write("{0}", vars.GetText("BODYS", curr));
                    }
                    else if (lastSwitchVar == "KEYBOARD_INPUT")
                    {
                        writer.Write("{0}", vars.GetText("KEYBOARD INPUT", curr));
                    }
                    else if (lastSwitchVar.StartsWith("POSREL"))
                    {
                        writer.Write("{0}", vars.GetText("POSREL", curr));
                    }
                    else
                    {
                        writer.Write("{0}", curr);
                    }

                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;

                    indentation.Add(pos + curr * 2);
                    break;

                case LifeEnum.MULTI_CASE:
                    int numcases = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    string lastSwitchVarb = switchEvalVar[pos - 4].Split('.').Last();

                    for (int n = 0; n < numcases; n++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        pos += 2;

                        if (lastSwitchVarb == "INHAND" || lastSwitchVarb == "COL_BY" || lastSwitchVarb == "HIT_BY" ||
                            lastSwitchVarb == "HIT" || lastSwitchVarb == "COLLIDING_ACTOR")
                        {
                            writer.Write("{0}", objectsByIndex[curr]);
                        }
                        else if (lastSwitchVarb == "ACTION")
                        {
                            writer.Write("{0}", getActionName(curr));
                        }
                        else if (lastSwitchVarb == "ANIM")
                        {
                            writer.Write("{0}", vars.GetText("ANIMS", curr));
                        }
                        else if (lastSwitchVarb == "BODY")
                        {
                            writer.Write("{0}", vars.GetText("BODYS", curr));
                        }
                        else if (lastSwitchVarb == "KEYBOARD_INPUT")
                        {
                            writer.Write("{0}", vars.GetText("KEYBOARD INPUT", curr));
                        }
                        else if (lastSwitchVarb.StartsWith("POSREL"))
                        {
                            writer.Write("{0}", vars.GetText("POSREL", curr));
                        }
                        else
                        {
                            writer.Write("{0}", curr);
                        }

                        if (n > 0)
                        {
                            writer.Write(" ");
                        }
                        else
                        {
                            writer.Write(", ");
                        }
                    }

                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    indentation.Add(pos + curr * 2);
                    break;

                case LifeEnum.ENDLIFE:
                case LifeEnum.RETURN:
                case LifeEnum.END_SEQUENCE:
                case LifeEnum.DO_MAX_ZV:
                case LifeEnum.GAME_OVER:
                case LifeEnum.WAIT_GAME_OVER:
                case LifeEnum.STOP_HIT_OBJECT:
                case LifeEnum.START_CHRONO:
                case LifeEnum.UP_COOR_Y:
                case LifeEnum.DO_MOVE:
                case LifeEnum.MANUAL_ROT:
                case LifeEnum.GET_HARD_CLIP:
                case LifeEnum.DO_ROT_ZV:
                case LifeEnum.DO_REAL_ZV:
                case LifeEnum.DO_CARRE_ZV:
                    break;

                case LifeEnum.HIT:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", vars.GetText("ANIMS", curr));
                    pos += 2;


                    for (int n = 0; n < 3; n++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", curr);
                        pos += 2;
                    }
                    writer.Write("{0} ", evalvar());


                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", vars.GetText("ANIMS", curr));
                    pos += 2;
                    break;

                case LifeEnum.DEF_ZV:
                case LifeEnum.FIRE:
                    for (int n = 0; n < 6; n++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", curr);
                        pos += 2;
                    }
                    break;


                case LifeEnum.ANIM_MOVE:
                    for (int i = 0; i < 7; i++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", vars.GetText("ANIMS", curr));
                        pos += 2;
                    }
                    break;

                case LifeEnum.THROW:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", vars.GetText("ANIMS", curr));
                    pos += 2;

                    for (int i = 0; i < 2; i++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", curr);
                        pos += 2;
                    }

                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", objectsByIndex[curr]);
                    pos += 2;

                    for (int i = 0; i < 2; i++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", curr);
                        pos += 2;
                    }

                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", vars.GetText("ANIMS", curr));
                    pos += 2;
                    break;

                case LifeEnum.PICTURE:
                case LifeEnum.ANGLE:
                    int alpha = curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    int beta = curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    int gamma = curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} {1} {2}", alpha, beta, gamma);
                    break;

                case LifeEnum.CHANGEROOM:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("E{0}", curr);
                    pos += 2;
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("R{0} ", curr);
                    pos += 2;

                    for (int n = 0; n < 3; n++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", curr);
                        pos += 2;
                    }
                    break;

                case LifeEnum.REP_SAMPLE:
                    writer.Write("{0} ", evalvar());
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", curr);
                    pos += 2;
                    break;

                case LifeEnum.DROP:
                    string ev = evalvar();
                    int    obj;
                    if (int.TryParse(ev, out obj))
                    {
                        ev = objectsByIndex[obj];
                    }
                    writer.Write("{0} ", ev);
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write("{0} ", objectsByIndex[curr]);
                    pos += 2;
                    break;

                case LifeEnum.PUT:
                    for (int n = 0; n < 9; n++)
                    {
                        curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                        writer.Write("{0} ", curr);
                        pos += 2;
                    }
                    break;

                case LifeEnum.ANIM_SAMPLE:
                    string eval = evalvar();
                    writer.Write(vars.GetText("SOUNDS", eval) + " ");
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write(vars.GetText("ANIMS", curr) + " ");
                    pos += 2;
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write(curr);
                    pos += 2;
                    break;

                case LifeEnum.SET:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write(vars.GetText("VARS", curr, "VAR" + curr) + " = ");
                    pos += 2;
                    writer.Write("{0}", evalvar());
                    break;

                case LifeEnum.ADD:
                case LifeEnum.SUB:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write(vars.GetText("VARS", curr, "VAR" + curr) + " ");
                    pos += 2;
                    writer.Write("{0}", evalvar());
                    break;

                case LifeEnum.INC:
                case LifeEnum.DEC:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    writer.Write(vars.GetText("VARS", curr, "VAR" + curr) + " ");
                    pos += 2;
                    break;

                case LifeEnum.C_VAR:
                    curr = ReadShort(allBytes[pos + 0], allBytes[pos + 1]);
                    pos += 2;
                    writer.Write("{0} = {1}", curr, evalvar());
                    break;

                default:
                    throw new NotImplementedException(life.ToString());
                }

                if (!consecutiveIfs)
                {
                    writer.WriteLine();
                }
            }
        }
示例#2
0
        static void ParseArguments(LifeEnum life, Instruction ins)
        {
            switch (life)
            {
            case LifeEnum.IF_EGAL:
            case LifeEnum.IF_DIFFERENT:
            case LifeEnum.IF_SUP_EGAL:
            case LifeEnum.IF_SUP:
            case LifeEnum.IF_INF_EGAL:
            case LifeEnum.IF_INF:
                EvalEnum evalEnum;
                string   paramA = Evalvar(out evalEnum);
                string   paramB = Evalvar();

                paramB = GetConditionName(evalEnum, paramB);

                switch (life)
                {
                case LifeEnum.IF_EGAL:
                    ins.Add("{0} == {1}", paramA, paramB);
                    break;

                case LifeEnum.IF_DIFFERENT:
                    ins.Add("{0} <> {1}", paramA, paramB);
                    break;

                case LifeEnum.IF_SUP_EGAL:
                    ins.Add("{0} >= {1}", paramA, paramB);
                    break;

                case LifeEnum.IF_SUP:
                    ins.Add("{0} > {1}", paramA, paramB);
                    break;

                case LifeEnum.IF_INF_EGAL:
                    ins.Add("{0} <= {1}", paramA, paramB);
                    break;

                case LifeEnum.IF_INF:
                    ins.Add("{0} < {1}", paramA, paramB);
                    break;
                }

                ins.Goto = GetParam() * 2 + pos;
                break;

            case LifeEnum.GOTO:                     //should never be called
                ins.Goto = GetParam() * 2 + pos;
                break;

            case LifeEnum.SWITCH:
                ins.Add(Evalvar(out ins.EvalEnum));
                break;

            case LifeEnum.CASE:
                ins.Add(GetParam());
                ins.Goto = GetParam() * 2 + pos;
                break;

            case LifeEnum.MULTI_CASE:
                int numcases = GetParam();
                for (int n = 0; n < numcases; n++)
                {
                    ins.Add(GetParam());
                }

                ins.Goto = GetParam() * 2 + pos;
                break;

            case LifeEnum.IF_IN:
            case LifeEnum.IF_OUT:
                switch (life)
                {
                case LifeEnum.IF_IN:
                    ins.Add("{0} in ({1}, {2})", Evalvar(), Evalvar(), Evalvar());
                    break;

                case LifeEnum.IF_OUT:
                    ins.Add("{0} not in ({1}, {2})", Evalvar(), Evalvar(), Evalvar());
                    break;
                }

                ins.Goto = GetParam() * 2 + pos;
                break;

            case LifeEnum.SOUND:
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD3)
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                }
                else if (config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                }
                else if (config.Version == GameVersion.TIMEGATE)
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, Evalvar()));
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                }
                else
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, Evalvar()));
                }
                break;

            case LifeEnum.BODY:
                ins.Add(vars.GetText(VarEnum.BODYS, Evalvar()));
                break;

            case LifeEnum.SAMPLE_THEN:
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD3 || config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                }
                else
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, Evalvar()));
                    ins.Add(vars.GetText(VarEnum.SOUNDS, Evalvar()));
                }
                break;

            case LifeEnum.DELETE:
            case LifeEnum.IN_HAND:
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD3 || config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetObjectName(Evalvar()));
                }
                else
                {
                    ins.Add(GetObjectName(GetParam()));
                }
                break;

            case LifeEnum.CAMERA_TARGET:
            case LifeEnum.TAKE:
            case LifeEnum.FOUND:
                ins.Add(GetObjectName(GetParam()));
                break;

            case LifeEnum.FOUND_NAME:
            case LifeEnum.MESSAGE:
                ins.Add(GetMessage(GetParam()));
                break;

            case LifeEnum.FOUND_FLAG:
                ins.Add(GetFlags(GetParam(), foundFlagsNames));
                break;

            case LifeEnum.FLAGS:
                ins.Add(GetFlags(GetParam(), flagsNames));
                break;

            case LifeEnum.LIFE:
                ins.Add(vars.GetText(VarEnum.LIFES, GetParam()));
                break;

            case LifeEnum.FOUND_BODY:
                ins.Add(vars.GetText(VarEnum.BODYS, GetParam()));
                break;

            case LifeEnum.NEXT_MUSIC:
            case LifeEnum.MUSIC:
                ins.Add(vars.GetText(VarEnum.MUSIC, GetParam()));
                break;

            case LifeEnum.ANIM_REPEAT:
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                break;

            case LifeEnum.SPECIAL:
                ins.Add(vars.GetText(VarEnum.SPECIAL, GetParam()));
                break;

            case LifeEnum.STOP_SAMPLE:
                if (config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetParam());
                }
                break;

            case LifeEnum.READ_ON_PICTURE:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.ANIM_RESET:
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.DO_ROT_CLUT:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.PLAY_SEQUENCE:
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD3 || config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                }
                else
                {
                    ins.Add(GetParam());
                }
                break;

            case LifeEnum.FIRE_UP_DOWN:
                ins.Add(Evalvar());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(Evalvar());
                break;

            case LifeEnum.DEF_ABS_ZV:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.STAGE_LIFE:
            case LifeEnum.SET_GROUND:
            case LifeEnum.SET_INVENTORY:
            case LifeEnum.COPY_ANGLE:
            case LifeEnum.TEST_COL:
            case LifeEnum.LIFE_MODE:
            case LifeEnum.FOUND_WEIGHT:
            case LifeEnum.ALLOW_INVENTORY:
            case LifeEnum.WATER:
            case LifeEnum.RND_FREQ:
            case LifeEnum.LIGHT:
            case LifeEnum.SHAKING:
                ins.Add(GetParam());
                break;

            case LifeEnum.FADE_MUSIC:
                ins.Add(GetParam());
                if (config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetParam());
                }
                break;

            case LifeEnum.READ:
                ins.Add(GetParam());
                ins.Add(GetParam());
                if (config.Version == GameVersion.AITD1)
                {
                    ins.Add(GetParam());
                }
                break;

            case LifeEnum.PUT_AT:
                ins.Add(GetObjectName(GetParam()));
                ins.Add(GetObjectName(GetParam()));
                if (config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetObjectName(GetParam()));
                }
                break;

            case LifeEnum.TRACKMODE:
            {
                int curr = GetParam();
                ins.Add(vars.GetText(VarEnum.TRACKMODE, curr));

                switch (curr)
                {
                case 0:                                 //none
                case 1:                                 //manual
                    GetParam();
                    break;

                case 2:                                 //follow
                    ins.Add(GetObjectName(GetParam()));
                    break;

                case 3:                                 //track
                    ins.Add(vars.GetText(VarEnum.TRACKS, GetParam()));
                    break;

                default:
                    ins.Add(GetParam());
                    break;
                }
                break;
            }

            case LifeEnum.ANIM_ONCE:
            case LifeEnum.ANIM_ALL_ONCE:
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                break;

            case LifeEnum.ANIM_HYBRIDE_REPEAT:
            case LifeEnum.ANIM_HYBRIDE_ONCE:
            case LifeEnum.SET_BETA:
            case LifeEnum.SET_ALPHA:
            case LifeEnum.HIT_OBJECT:
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.ENDLIFE:
                break;

            case LifeEnum.PLUIE:
            case LifeEnum.DEL_INVENTORY:
            case LifeEnum.CONTINUE_TRACK:
            case LifeEnum.RESET_MOVE_MANUAL:
            case LifeEnum.END_SEQUENCE:
            case LifeEnum.UP_COOR_Y:
            case LifeEnum.GET_HARD_CLIP:
            case LifeEnum.RETURN:
            case LifeEnum.DO_MAX_ZV:
            case LifeEnum.GAME_OVER:
            case LifeEnum.WAIT_GAME_OVER:
            case LifeEnum.STOP_HIT_OBJECT:
            case LifeEnum.START_CHRONO:
            case LifeEnum.DO_MOVE:
            case LifeEnum.MANUAL_ROT:
            case LifeEnum.DO_ROT_ZV:
            case LifeEnum.DO_REAL_ZV:
            case LifeEnum.DO_CARRE_ZV:
            case LifeEnum.DO_NORMAL_ZV:
            case LifeEnum.CALL_INVENTORY:
            case LifeEnum.PROTECT:
            case LifeEnum.STOP_CLUT:
            case LifeEnum.UNKNOWN_6:
                break;

            case LifeEnum.UNKNOWN_5:
                int count = GetParam();
                for (int i = 0; i < count; i++)
                {
                    ins.Add(Evalvar());
                }
                break;

            case LifeEnum.SET_VOLUME_SAMPLE:
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.MUSIC_B:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.START_FADE_IN_MUSIC:
            case LifeEnum.START_FADE_IN_MUSIC_LOOP:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.MUSIC_AND_LOOP:
            case LifeEnum.FADE_OUT_MUSIC_STOP:
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.HIT:
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(Evalvar());
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                break;

            case LifeEnum.DEF_ZV:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.FIRE:
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD2_DEMO || config.Version == GameVersion.AITD3 || config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(vars.GetText(VarEnum.ANIMS, Evalvar()));
                }
                else
                {
                    ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                }
                ins.Add(GetParam());                         //shoot frame
                ins.Add(GetParam());                         //hotpoint
                ins.Add(GetParam());                         //range
                ins.Add(GetParam());                         //hitforce
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD2_DEMO || config.Version == GameVersion.AITD3 || config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetParam());
                    ins.Add(vars.GetText(VarEnum.ANIMS, Evalvar()));
                }
                else
                {
                    ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                }
                break;

            case LifeEnum.ANIM_MOVE:
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                break;

            case LifeEnum.THROW:
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetObjectName(GetParam()));
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                break;

            case LifeEnum.ANGLE:
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.PICTURE:
                if (config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                    ins.Add(Evalvar());
                }
                else if (config.Version == GameVersion.TIMEGATE)
                {
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                    ins.Add(Evalvar());
                }
                else
                {
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                    ins.Add(GetParam());
                }
                break;

            case LifeEnum.CHANGEROOM:
                ins.Add("E{0}R{1}", GetParam(), GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.REP_SAMPLE:
                if (config.Version == GameVersion.AITD2 || config.Version == GameVersion.AITD3 || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, GetParam()));
                }
                else
                {
                    ins.Add(vars.GetText(VarEnum.SOUNDS, Evalvar()));
                }
                ins.Add(GetParam());
                break;

            case LifeEnum.DEF_SEQUENCE_SAMPLE:
                pos = GetParam() * 4 + pos;
                break;

            case LifeEnum.DROP:
                ins.Add(GetObjectName(Evalvar()));
                ins.Add(GetObjectName(GetParam()));
                break;

            case LifeEnum.PUT:
                ins.Add(GetObjectName(GetParam()));
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add("E{1}R{0}", GetParam(), GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                ins.Add(GetParam());
                break;

            case LifeEnum.ANIM_SAMPLE:
                ins.Add(vars.GetText(VarEnum.SOUNDS, Evalvar()));
                ins.Add(vars.GetText(VarEnum.ANIMS, GetParam()));
                ins.Add(GetParam());
                if (config.Version == GameVersion.TIMEGATE || config.Version == GameVersion.TIMEGATE_DEMO)
                {
                    ins.Add(GetParam());
                }
                break;

            case LifeEnum.SET:
            {
                int    curr  = GetParam();
                string name  = vars.GetText(VarEnum.VARS, curr, "var_" + curr);
                string value = Evalvar();

                int result;
                if (name == "player_current_action" && int.TryParse(value, out result))
                {
                    value = GetFlags(result, foundFlagsNames);
                }

                ins.Add("{0} = {1}", name, value);
                break;
            }

            case LifeEnum.ADD:
            case LifeEnum.SUB:
            {
                int curr = GetParam();
                ins.Add(vars.GetText(VarEnum.VARS, curr, "var_" + curr));
                ins.Add(Evalvar());
                break;
            }

            case LifeEnum.INC:
            case LifeEnum.DEC:
            {
                int curr = GetParam();
                ins.Add(vars.GetText(VarEnum.VARS, curr, "var_" + curr));
                break;
            }

            case LifeEnum.C_VAR:
            {
                int curr = GetParam();
                ins.Add("{0} = {1}", vars.GetText(VarEnum.CVARS, curr, "cvar_" + curr), Evalvar());
                break;
            }

            case LifeEnum.BODY_RESET:
                ins.Add(Evalvar());
                ins.Add(Evalvar());
                break;

            default:
                throw new NotImplementedException(life.ToString());
            }
        }