Ejemplo n.º 1
0
        public S2AScript(string script, string[] args, string type)
        {
            context = this;

            Console.WriteLine("Parsing script...");
            try {
                ParseScriptInit("=type '" + type.ToLowerInvariant() + "'\n" + File.ReadAllText(script).Replace("\t", "").Replace("\r", ""), args, -1);
            } catch (Exception e) {
                error(e.ToString());
            }
        }
Ejemplo n.º 2
0
 // helper method to collect some variables used in conversion
 private void InitConvertVars()
 {
     try {
         // get global subscript
         endian = S2AScript.GetEquate("endian").val;
         offset = Parse.BasicUint(S2AScript.GetEquate("offset").val);
         if (debug)
         {
             Debug("--> InitConvertVars: endian=" + endian + " offset=" + toHexString(offset, 4));
         }
     } catch (Exception e) {
         cvterror(null, new Exception("Missing equates when getting convert variables! Required equates are: 'endian' and 'offset'.", e).ToString());
     }
 }
Ejemplo n.º 3
0
        // function to calculate the optimized arrays of items or array items to quickly return items for certain types of requests
        public GenericScriptItem[] Optimize()
        {
            Optimized = new GenericScriptItem[0x100];

            foreach (GenericScriptItem entry in Items)
            {
                switch (entry.type)
                {
                case ScriptItemType.NULL:
                    screrr(entry.line, "Type of item is NULL! This is most likely a programming error in SMPS2ASM!");
                    break;

                case ScriptItemType.Equate:
                    ScriptEquate eq = (entry as ScriptEquate);
                    // only pre-calculated equates are possible to be used
                    if (!eq.CheckEvaluate())
                    {
                        S2AScript.screrr(entry.line, "Equates that are being optimized into a look-up-table must be possible to be pre-calculated! Equate with contents '" + eq.val + "' failed to be pre-calculated.");
                    }
                    // get offset
                    int v;
                    if (!Parse.DoubleToInt(GetEquate(eq.equ).value, out v))
                    {
                        screrr(entry.line, "Equate value can not be accurately converted from double floating point to int! Equate with contents '" + eq.val + "' failed to be conveted to 32-bit signed integer.");
                    }

                    // save entry or throw error.
                    if (Optimized[v] == null)
                    {
                        Optimized[v] = entry;
                    }
                    else
                    {
                        screrr(entry.line, "Entity " + entry.identifier + " conflicts with " + Optimized[v].identifier + " at line " + Optimized[v].line +
                               ", both trying to occupy the value " + v + " (0x" + v.ToString("X2") + ")! Optimization requires no such conflicts.");
                    }
                    break;

                case ScriptItemType.Macro:
                    ScriptMacro ma = (entry as ScriptMacro);
                    // collect range
                    int rangeStart, rangeEnd;
                    if (!ma.GetRange(0, out rangeStart, out rangeEnd))
                    {
                        S2AScript.screrr(entry.line, "Unable to parse first level macro range. Macro range of '" + (ma.pre.Length > 0 ? ma.pre[0] : "") + "' is not valid.");
                    }

                    // if true, there is only 1 level to this macro
                    bool onlylevel = ma.pre.Length == 1;
                    for (int i = rangeStart; i <= rangeEnd; i++)
                    {
                        if (onlylevel)
                        {
                            if (Optimized[i] == null)
                            {
                                Optimized[i] = ma;
                            }

                            else if (Optimized[i].type == ScriptItemType.ArrayItem)
                            {
                                (Optimized[i] as ScriptArrayItem).CombineFree(ma);
                            }

                            else
                            {
                                screrr(entry.line, "Entity " + entry.identifier + " conflicts with " + Optimized[i].identifier + " at line " + Optimized[i].line +
                                       ", both trying to occupy the value " + i + " (0x" + i.ToString("X2") + ")! Optimization requires no such conflicts.");
                            }
                        }
                        else
                        {
                            if (Optimized[i] == null)
                            {
                                Optimized[i] = new ScriptArrayItem(parent);
                                (Optimized[i] as ScriptArrayItem).Combine(ma, 1);
                            }
                            else if (Optimized[i].type == ScriptItemType.ArrayItem)
                            {
                                (Optimized[i] as ScriptArrayItem).Combine(ma, 1);
                            }

                            else
                            {
                                screrr(entry.line, "Entity " + entry.identifier + " conflicts with " + Optimized[i].identifier + " at line " + Optimized[i].line +
                                       ", both trying to occupy the value " + i + " (0x" + i.ToString("X2") + ")! Optimization requires no such conflicts.");
                            }
                        }
                    }
                    break;

                case ScriptItemType.ArrayItem:
                    screrr(entry.line, "Unoptimized list contains a pre-occupied technical element that may not be interpreted. This is likely a programming error, please report to devs!");
                    break;

                case ScriptItemType.Import:
                    ScriptArray sc = context.GetSubscript((entry as ScriptImport).name);
                    if (sc.Optimized == null)
                    {
                        sc.Optimize();
                    }
                    Optimized = ConvertSMPS.context.Combine(new GenericScriptItem[][] { Optimized, sc.Optimized });
                    break;

                // all these items are invalid inside the LUT.
                default:
                    screrr(entry.line, "Optimized look-up-table may only contain unoptimizable elements! Look-up-tables may contain either Equates, or macros.");
                    break;
                }
            }
            return(Optimized);
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            Console.Title = "SMPS2ASM/NAT  Built: " + new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime.ToShortDateString() + " " + new FileInfo(Assembly.GetExecutingAssembly().Location).LastWriteTime.ToShortTimeString();

            // args[input file with ext, Sound driver name, label, extra: may be used by script]
            // get the exe folder
            string[] a = args;

            //check if we have a debug option
opcheck:
            if (args.Length > 0 && args[0] == "-d")
            {
                args  = args.Skip(1).ToArray();
                debug = true;
                goto opcheck;
            }

            //check if we have a pause option
            if (args.Length > 0 && args[0] == "-p")
            {
                args  = args.Skip(1).ToArray();
                pause = true;
                goto opcheck;
            }

            //check if we have a type option
            if (args.Length > 1 && args[0] == "-t")
            {
                type = args[1];
                args = args.Skip(2).ToArray();
                goto opcheck;
            }

            //check if a script file was dragged in
            if (args.Length > 0)
            {
                if (File.Exists(args[0]) && args[0].EndsWith(".smpss"))
                {
                    folder = Environment.CurrentDirectory;
                    string script = args[0];
                    args = args.Skip(1).ToArray();

                    // check if all arguments are gotten
                    if (args.Length < 2)
                    {
                        pause = true;
                        args  = ConsoleArguments.Get(args, new ArgHandler[] {
                            new ArgHandler("Music file name with extension:", chkfilext2),
                            new ArgHandler("Project name:", chkname),
                        }, new ButtonHandler[] {
                            new ButtonHandler(ConsoleKey.Escape, "Quit the program", quitprg, quitcl),
                            new ButtonHandler(ConsoleKey.F1, "Pause program at the end", pauseprg, pausecl),
                            new ButtonHandler(ConsoleKey.F2, "Print debug info", debugprg, debugcl),
                        });
                    }
                    else
                    {
                        args[0] = chkfilext2(args[0], true);
                        args[1] = chkname(args[1], true);
                    }

                    string[] ax = new string[1 + args.Length];
                    ax[0] = args[0];
                    ax[2] = args[1];
                    ax[1] = script;

                    for (int i = 3; i < ax.Length; i++)
                    {
                        ax[i] = args[i - 1];
                    }

                    args = ax;
                    goto oops;
                }
            }

            // check if all arguments are gotten
            if (args.Length < 3)
            {
                folder = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Environment.CurrentDirectory), @""));
                pause  = true;
                args   = ConsoleArguments.Get(args, new ArgHandler[] {
                    new ArgHandler("Music file name with extension:", chkfilext),
                    new ArgHandler("Sound driver folder name:", chkfolext),
                    new ArgHandler("Project name:", chkname),
                }, new ButtonHandler[] {
                    new ButtonHandler(ConsoleKey.Escape, "Quit the program", quitprg, quitcl),
                    new ButtonHandler(ConsoleKey.F1, "Pause program at the end", pauseprg, pausecl),
                    new ButtonHandler(ConsoleKey.F2, "Print debug info", debugprg, debugcl),
                });
            }
            else
            {
                folder  = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Environment.CurrentDirectory), @""));
                args[0] = chkfilext(args[0], true);
                args[1] = chkfolext(args[1], true);
                args[2] = chkname(args[2], true);
            }

            // time how long this will take
oops:
            timer = new Stopwatch();
            timer.Start();

            // remove bin folder from path
            //		if (folder.EndsWith("\\bin") || folder.EndsWith("\\bin\\")) folder = folder.Substring(0, folder.LastIndexOf("\\"));

            // removes the extension of input file and adds .asm as the extension of output file
            string fileout;

            if (args[0].IndexOf(".", args[0].LastIndexOf("\\")) > 0)
            {
                fileout = args[0].Substring(0, args[0].LastIndexOf(".")) + ".asm";
            }
            else
            {
                fileout = args[0] + ".asm";
            }

            // init debugwriter and put in debug info
            if (debug)
            {
                string db;
                if (args[0].IndexOf(".", args[0].LastIndexOf("\\")) > 0)
                {
                    db = args[0].Substring(0, args[0].LastIndexOf(".")) + ".smpsd";
                }
                else
                {
                    db = args[0] + ".smpsd";
                }

                //init stream
                dbWr = new StreamWriter(db);

                // write info about args
                Debug("--; args=[" + string.Join(", ", a) + "]");
                Debug("--; filein=" + args[0]);
                Debug("--; fileout=" + fileout);
                Debug("--; folder=" + folder);
                Debug("--; script=" + args[1]);
                Debug("--; lable=" + args[2]);
                Debug("--; type=" + type);
            }

            // get new SMPS object
            ConvertSMPS cvt = new ConvertSMPS(args[0], fileout, args[2]);

            // get the file for smps2asm script
            S2AScript scr = new S2AScript(args[1], args.Skip(3).ToArray(), type);

            // print timer info
            long tra = timer.ElapsedMilliseconds;

            Console.WriteLine("Script translated! Took " + tra + " ms!");

            // restart timer
            timer.Reset();
            timer.Start();

            // do teh conversion
            cvt.Convert(scr);

            // print timer info
            long con = timer.ElapsedMilliseconds;

            Console.WriteLine("File converted! Took " + con + " ms!");

            // restart timer
            timer.Reset();
            timer.Start();

            // write teh file
            Output.DoIt(cvt);

            // print timer info
            long pot = timer.ElapsedMilliseconds;

            Console.WriteLine("File saved to disk! Took " + pot + " ms!");
            Console.WriteLine("Conversion done! Took " + (pot + tra + con) + " ms!");

            if (debug)
            {
                Debug(new string('-', 80));
                Debug("--; Time for Script " + tra + " ms");
                Debug("--; Time for Convert " + con + " ms");
                Debug("--; Time for Save " + pot + " ms");
                Debug("--; Time for Total " + (pot + tra + con) + " ms");
                dbWr.Flush();
            }
            if (pause)
            {
                Console.ReadKey();
            }
        }
Ejemplo n.º 5
0
        // convert main script
        public void Convert(S2AScript scr)
        {
            if (debug)
            {
                Debug("Prepare conversion");
            }
            this.scr             = scr;
            UnunsedChk           = new List <uint>();
            Lables               = new List <OffsetString>();
            Lines                = new List <OffsetString>();
            data                 = File.ReadAllBytes(filein);
            skipped              = new bool[data.Length + 1];
            skipped[data.Length] = true;             // skip last byte for output
            if (debug)
            {
                Debug(new string('-', 80));
            }

            // run conveter
            string[] a = null;
            if (debug)
            {
                Debug("--> Start conversion with subscript ''");
            }
            try {
                ConvertRun(scr.subscripts[""].Items, ref a, baselable, out bool asses, out string c);
            } catch (DataException) { }

            // convert unused data
            if (scr.subscripts.ContainsKey("unused"))
            {
                List <GenericScriptItem> uscr = scr.subscripts["unused"].Items;

                for (int i = 0; i < UnunsedChk.Count; i++)
                {
                    uint p = UnunsedChk[i];

                    // check if this is not used
                    if (skipped[p])
                    {
                        continue;
                    }

                    foreach (OffsetString o in Lines)
                    {
                        if (o.offset <= p && o.offset + o.length >= p)
                        {
                            goto next;
                        }
                    }

                    // unused, deal with it
                    try {
                        pos = p;
                        ConvertRun(uscr, ref a, baselable, out bool asses, out string c);
                    } catch (DataException) { }

                    next :;
                }
            }
            if (debug)
            {
                Debug(new string('-', 80));
            }
        }