Esempio n. 1
0
        public void ToSource(YukaScript script, string path)
        {
            string sourcePath = Path.ChangeExtension(path, Constants.ykd);
            string stringPath = Path.ChangeExtension(path, Constants.csv);

            // write source code
            File.WriteAllText(sourcePath, script.Source());

            // write string data
            if (script.stringTable.Count > 0)
            {
                StreamWriter w = new StreamWriter(new FileStream(stringPath, FileMode.Create));
                w.WriteLine($"ID{CSVDelimiter}Speaker{CSVDelimiter}Original{CSVDelimiter}Translation{CSVDelimiter}TLC{CSVDelimiter}Edit{CSVDelimiter}QC{CSVDelimiter}Comments{CSVDelimiter}Generated");
                // write names
                bool flag = false;
                foreach (var entry in script.stringTable)
                {
                    if (entry.Key.StartsWith("N"))
                    {
                        if (!flag)
                        {
                            w.WriteLine(CSVDelimiter + "\r\n#Names:");
                            flag = true;
                        }
                        w.WriteLine(entry.Key + CSVDelimiter + CSVDelimiter + entry.Value.Text);
                    }
                }
                // write lines
                flag = false;
                foreach (var entry in script.stringTable)
                {
                    if (!entry.Key.StartsWith("N"))
                    {
                        if (!flag)
                        {
                            w.WriteLine(CSVDelimiter + "\r\n#Lines:");
                            flag = true;
                        }

                        string speaker = entry.Value.Speaker ?? "";
                        string line    = entry.Value.Text;
                        int    fontID  = entry.Value.FontID;

                        int fontSize = fontID >= 0 && fontID < 16 ? Constants.fontInfo[fontID].FullWidthHorizontalSpacing : TextUtils.defaultCharWidth;

                        string meta = '"' + (speaker + (fontSize != TextUtils.defaultCharWidth ? $"\ncw:{fontSize}" : "")).Trim() + '"';

                        line = '"' + line.Replace("\"", "\"\"") + '"';

                        w.WriteLine(entry.Key + CSVDelimiter + meta + CSVDelimiter + line);
                    }
                }
                w.Close();
            }
        }
Esempio n. 2
0
 public Decompiler(YukaScript script)
 {
     Script = script;
 }
Esempio n. 3
0
        /// <summary>
        /// Compiles an entire script into a binary script file (.yks)
        /// </summary>
        /// <param name="script">The script instance to compile</param>
        /// <param name="s">The output stream</param>
        /// <returns>The number of bytes written</returns>
        public long ToBinary(YukaScript script, Stream s)
        {
            long offset = s.Position;

            List <ScriptElement> flattened = new List <ScriptElement>();

            Console.ForegroundColor = ConsoleColor.Cyan;

            foreach (ScriptElement elem in script.commands)
            {
                List <ScriptElement> cmds = Flatten(elem, false);
                flattened.AddRange(cmds);
                if (cmds.Count == 0 && FlagCollection.current.Has('v'))
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("?????????????");
                    Console.ForegroundColor = ConsoleColor.Cyan;
                }
                foreach (ScriptElement cmd in cmds)
                {
                    if (cmd is DataScriptElement dse && dse.elem is ControlDataElement cde)
                    {
                        string name = cde.name;
                        if (!"else".Equals(name) && !"{".Equals(name) && !"}".Equals(name))
                        {
                            jumpLabels.Add(name, cde);
                        }
                    }
                    //Console.WriteLine(cmd);
                }
            }

            List <DataElement> code = new List <DataElement>();
            Dictionary <string, FuncDataElement> functions = new Dictionary <string, FuncDataElement>();

            foreach (ScriptElement elem in flattened)
            {
                if (elem is FuncCallScriptElement)
                {
                    string          name       = (elem as FuncCallScriptElement).name;
                    ScriptElement[] parameters = (elem as FuncCallScriptElement).parameters;

                    if (!functions.ContainsKey(name))
                    {
                        functions[name] = new FuncDataElement(name);
                    }
                    functions[name].lastOffset = code.Count;

                    code.Add(functions[name]);
                    code.Add(new RawDataElement(parameters.Length));

                    foreach (ScriptElement param in parameters)
                    {
                        if (param is DataScriptElement)
                        {
                            code.Add((param as DataScriptElement).elem);
                        }
                        else
                        {
                            throw new Exception("Expected DataScriptElement, got " + param.GetType().Name);
                        }
                    }
                }
                else if (elem is DataScriptElement)
                {
                    DataElement data = (elem as DataScriptElement).elem;

                    if (data is ControlDataElement)
                    {
                        (data as ControlDataElement).codeOffset = code.Count;
                    }

                    code.Add(data);
                }
                else
                {
                }
                if (FlagCollection.current.Has('v'))
                {
                    Console.WriteLine(elem);
                }
            }
            Console.ForegroundColor = ConsoleColor.Yellow;

            DataManager dataManager = new DataManager();
            List <Tuple <int, int, int, int> > index = new List <Tuple <int, int, int, int> >();
            List <int> codeData = new List <int>();

            foreach (DataElement elem in code)
            {
                if (elem is ControlDataElement)
                {
                    string name = (elem as ControlDataElement).name;
                    if (jumpLabels.ContainsKey(name))
                    {
                        (elem as ControlDataElement).link = jumpLabels[name];
                    }
                }

                if (elem is RawDataElement)
                {
                    codeData.Add((elem as RawDataElement).value);
                }
                else
                {
                    elem.WriteData(dataManager);
                    Tuple <int, int, int, int> entry = elem.GetIndex();
                    if (FlagCollection.current.Has('v'))
                    {
                        Console.WriteLine(entry);
                    }
                    int i = index.IndexOf(entry);
                    if (i == -1)
                    {
                        i = index.Count;
                        index.Add(entry);
                    }
                    codeData.Add(i);
                }
            }
            Console.ResetColor();

            BinaryWriter bw = new BinaryWriter(s);

            // write header
            s.Write(new byte[] { 0x59, 0x4B, 0x53, 0x30, 0x30, 0x31, 0x01, 0x00 }, 0, 8);
            s.Write(new byte[] { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 8);

            bw.Write(0x30);
            bw.Write(codeData.Count);
            bw.Write(0x30 + codeData.Count * 4);
            bw.Write(index.Count);
            bw.Write(0x30 + codeData.Count * 4 + index.Count * 16);
            bw.Write(dataManager.offset);
            bw.Write(tempVarID);
            bw.Write(0);

            // write code sector
            foreach (int cmd in codeData)
            {
                bw.Write(cmd);
            }

            // write index
            foreach (Tuple <int, int, int, int> entry in index)
            {
                bw.Write(entry.Item1);
                bw.Write(entry.Item2);
                bw.Write(entry.Item3);
                bw.Write(entry.Item4);
            }

            // write data sector
            dataManager.WriteTo(s);
            return(s.Position - offset);
        }