示例#1
0
        private void ScriptList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Change what script to show strings from
            // This will update the StringList contents with a list of IDs for the selected script
            // Consider asking the user if they want to save the current input data if they've changed the text but didn't insert it

            // Load RMD script
            var path = e.AddedItems[0].ToString();

            currentRmd            = new RmdFile(path, 0x391);
            currentSelectedScript = System.IO.Path.GetFileName(path);

            if (currentRmd.Strings.Count > 1)
            {
                StatusBar.Text = String.Format("Loaded {0}... found {1} strings", e.AddedItems[0], currentRmd.Strings.Count);
            }
            else
            {
                StatusBar.Text = String.Format("Loaded {0}... found {1} string", e.AddedItems[0], currentRmd.Strings.Count);
            }

            // Remove anything from the string list from the old script
            StringList.Items.Clear();
            foreach (var str in currentRmd.Strings)
            {
                StringList.Items.Add(str.Key);
            }

            if (StringList.Items.Count > 0)
            {
                StringList.SelectedIndex = 0;
            }

            UpdateToggleInsertionContent();
        }
示例#2
0
        private List <Tuple <Bitmap, RectangleF> > DrawGlyphs(uint cmd, RmdFile targetFont, int x, int y)
        {
            var tiles = new List <Tuple <Bitmap, RectangleF> >();

            if (targetFont != null)
            {
                var    glyphMetrics = targetFont.FontMapping[cmd];
                Bitmap tile         = new Bitmap(glyphMetrics.Width, glyphMetrics.Height);
                using (Graphics g = Graphics.FromImage(tile))
                    g.DrawImage(targetFont.Font, new RectangleF(0, 0, glyphMetrics.Width, glyphMetrics.Height), glyphMetrics, GraphicsUnit.Pixel);
                tiles.Add(new Tuple <Bitmap, RectangleF>(tile, new RectangleF(x, y, glyphMetrics.Width, glyphMetrics.Height)));
            }
            else
            {
                Console.WriteLine("Could not find {0:x2} in font mapping", cmd);
            }

            return(tiles);
        }
示例#3
0
        public MainWindow()
        {
            InitializeComponent();

            translationDatabase    = LoadTranslationDatabase(translationDatbaseFilename);
            translationDLCDatabase = LoadTranslationDatabase(translationDLCDatbaseFilename, true);
            glyphDatabase          = LoadGlyphDatabase(glyphDatabaseFilename);
            reverseGlyphDatabase   = BuildReverseGlyphDatabase(glyphDatabase);

            var scriptsFolder = "scripts";

            if (!Directory.Exists(scriptsFolder))
            {
                MessageBox.Show(String.Format("Please place all *.rmd files into a folder named \"{0}\" and load the program again", scriptsFolder));
            }
            else
            {
                var scripts = Directory.EnumerateFiles(scriptsFolder, "*.rmd", SearchOption.AllDirectories);

                var basicCharSetPath = System.IO.Path.Combine(scriptsFolder, "BasicCharSet.rmd");
                if (File.Exists(basicCharSetPath))
                {
                    basicCharSetRmd = new RmdFile(basicCharSetPath, 0x81);
                }

                var basicRubySetPath = System.IO.Path.Combine(scriptsFolder, "BasicRubySet.rmd");
                if (File.Exists(basicRubySetPath))
                {
                    basicRubySetRmd = new RmdFile(basicRubySetPath, 0x881);
                }

                foreach (var script in scripts)
                {
                    ScriptList.Items.Add(script);
                }
            }
        }
示例#4
0
        private Tuple <Bitmap, string> DrawString(byte[][] text, double frameWidth, RmdFile currentRmd)
        {
            int glyphWidth = currentRmd.GlyphWidth;
            int glyphHeight = currentRmd.GlyphHeight;
            int requiredWidth = 0;
            int x = 0, y = 0;

            string outputText = "";

            // Calculate required image width and height
            int lines = 0;
            var tiles = new List <Tuple <Bitmap, RectangleF> >();

            for (int i = 0; i < text.Length; i++)
            {
                var c = text[i];

                var cmd = BitConverter.ToUInt16(c, 0);
                if (cmd >= 0x8080)
                {
                    string opcodeText = null;

                    // Control codes
                    if (cmd == 0x8080)
                    {
                        opcodeText = "n";
                    }
                    else if (cmd == 0x8081)
                    {
                        opcodeText = "a";
                    }
                    else if (cmd == 0x8082)
                    {
                        opcodeText = "b";
                    }
                    else if (cmd == 0x8090)
                    {
                        opcodeText = "ruby";
                    }
                    else if (cmd == 0x8091)
                    {
                        opcodeText = "/ruby";
                    }
                    else if (cmd == 0x8094)
                    {
                        opcodeText = "e";
                    }
                    else if (cmd == 0x8099)
                    {
                        opcodeText = "f";
                    }

                    opcodeText = "[" + opcodeText + " ";

                    if (cmd == 0x8090)
                    {
                        for (int j = 2; j < c.Length; j++)
                        {
                            opcodeText += String.Format("{0}", GetTextByGlypyId("BasicRubySet", (uint)basicRubySetRmd.CharsetOffset + c[j] - 1));
                        }
                    }
                    else
                    {
                        for (int j = 2; j < c.Length; j++)
                        {
                            opcodeText += String.Format("{0:x2} ", c[j]);
                        }
                    }

                    opcodeText = opcodeText.Trim() + "]";

                    if (opcodeText != null)
                    {
                        // Write text to be displayed
                        var tile = DrawTextToBitmap(opcodeText, glyphWidth * 0.75f, System.Drawing.Color.Yellow);

                        if (frameWidth != -1 && x + tile.Width >= frameWidth)
                        {
                            if (x > requiredWidth)
                            {
                                requiredWidth = x;
                            }

                            y += glyphHeight;
                            x  = 0;
                        }

                        tiles.Add(new Tuple <Bitmap, RectangleF>(tile, new RectangleF(x, y, tile.Width, tile.Height)));

                        x += tile.Width;

                        outputText += opcodeText;
                    }

                    if (cmd == 0x8080)
                    {
                        if (x > requiredWidth)
                        {
                            requiredWidth = x;
                        }

                        // New line
                        lines++;
                        x  = 0;
                        y += glyphHeight;
                    }
                }
                else
                {
                    if (frameWidth != -1 && x + glyphWidth >= frameWidth)
                    {
                        y += glyphHeight;
                        x  = 0;
                    }

                    RmdFile targetFont = null;
                    if (basicCharSetRmd != null && basicCharSetRmd.FontMapping.ContainsKey(cmd))
                    {
                        targetFont = basicCharSetRmd;
                    }
                    else if (basicRubySetRmd != null && basicRubySetRmd.FontMapping.ContainsKey(cmd))
                    {
                        targetFont = basicRubySetRmd;
                    }
                    else if (currentRmd != null && currentRmd.FontMapping.ContainsKey(cmd))
                    {
                        targetFont = currentRmd;
                    }
                    else
                    {
                        continue;
                    }

                    var tileGlyphs = DrawGlyphs(cmd, targetFont, x, y);
                    var tile       = tileGlyphs.Count > 0 ? tileGlyphs[0].Item1 : null;

                    if (tile != null)
                    {
                        tiles.AddRange(tileGlyphs);

                        using (MemoryStream s = new MemoryStream())
                        {
                            tile.Save(s, System.Drawing.Imaging.ImageFormat.Bmp);

                            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
                            {
                                var hash    = sha1.ComputeHash(s.GetBuffer());
                                var hashStr = BitConverter.ToString(hash).ToLower().Replace("-", ""); // Preferred format

                                if (hashStr == "d919fb1eb06492a666fbec418813f723e97a6e4f")            // No image
                                {
                                    outputText += " ";
                                }
                                else if (glyphDatabase.ContainsKey(hashStr))
                                {
                                    outputText += glyphDatabase[hashStr].Text;
                                }
                            }
                        }
                    }

                    if (targetFont.GlyphSizes.ContainsKey(cmd))
                    {
                        var w = targetFont.GlyphSizes[cmd].Item1;
                        var h = targetFont.GlyphSizes[cmd].Item2;
                        x += w;
                    }
                }
            }

            if (x > requiredWidth)
            {
                requiredWidth = x;
            }

            if (requiredWidth == 0)
            {
                requiredWidth = x;
            }

            var output = new Bitmap(requiredWidth + 1, (lines + 1) * glyphHeight);

            using (Graphics g = Graphics.FromImage(output))
            {
                foreach (var tile in tiles)
                {
                    g.DrawImage(tile.Item1, tile.Item2, new RectangleF(0, 0, tile.Item1.Width, tile.Item1.Height), GraphicsUnit.Pixel);
                }
            }

            outputText = outputText.Replace("[n]", "\n");
            if (String.IsNullOrWhiteSpace(outputText))
            {
                outputText = null;
            }

            return(new Tuple <Bitmap, string>(output, outputText));
        }
示例#5
0
        private void DumpText_Click(object sender, RoutedEventArgs e)
        {
            const string outputFoldername = "output_text";

            if (!Directory.Exists(outputFoldername))
            {
                Directory.CreateDirectory(outputFoldername);
            }

            // Generate an image for every string in a file, and then generate an image based on all of those images
            var scripts = ScriptList.Items;
            int dumpedStrings = 0, dumpedScripts = 0;

            foreach (string file in scripts)
            {
                var baseFilename = System.IO.Path.GetFileNameWithoutExtension(file);

                if (String.Compare(baseFilename, "BasicCharSet", true) == 0 || String.Compare(baseFilename, "BasicRubySet", true) == 0 || String.Compare(baseFilename, "msg_0", true) == 0)
                {
                    continue;
                }

                RmdFile rmd = new RmdFile(file, 0x391);

                if (rmd.Strings != null)
                {
                    foreach (var str in rmd.Strings)
                    {
                        var d   = DrawString(str.Value, -1, rmd);
                        var key = System.IO.Path.GetFileName(file);

                        if (String.Compare(key, String.Format("msg_{0}", str.Key)) == 0)
                        {
                            MessageBox.Show("Found msg that broke expected format of no double keys");
                        }

                        if (!translationDatabase.ContainsKey(str.Key))
                        {
                            translationDatabase[str.Key] = new TranslationEntry();
                        }

                        if (d.Item2 != null)
                        {
                            translationDatabase[str.Key].OriginalText = d.Item2;
                            dumpedStrings++;
                        }
                        else
                        {
                            translationDatabase[str.Key].OriginalText = "";
                        }
                    }
                }

                dumpedScripts++;
            }

            SaveTranslationDatabase(System.IO.Path.Combine(outputFoldername, translationDatbaseFilename));
            LoadTranslationDatabase(translationDatbaseFilename); // Get rid of all the extra entries we created for dumping

            Console.WriteLine("Finished dumping {0} strings from {1} scripts!", dumpedStrings, dumpedScripts);
            MessageBox.Show(String.Format("Finished dumping {0} strings from {1} scripts!", dumpedStrings, dumpedScripts));
        }
示例#6
0
        private void DumpGlyphs_Click(object sender, RoutedEventArgs e)
        {
            // Dump all unique glyphs used in the scripts
            const string outputFoldername = "output_glyphs";

            if (!Directory.Exists(outputFoldername))
            {
                Directory.CreateDirectory(outputFoldername);
            }

            int dumped = 0;

            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
            {
                var scripts = ScriptList.Items;
                foreach (string file in scripts)
                {
                    var baseFilename = System.IO.Path.GetFileNameWithoutExtension(file);

                    string outputFilename = System.IO.Path.Combine(outputFoldername, baseFilename + ".png");

                    RmdFile rmd = new RmdFile(file, 0x391);
                    foreach (var gm in rmd.FontMapping)
                    {
                        Rectangle glyphMetrics = gm.Value;

                        Bitmap glyphOrig  = new Bitmap(glyphMetrics.Width, glyphMetrics.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                        Bitmap glyphBlack = new Bitmap(glyphMetrics.Width, glyphMetrics.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                        using (Graphics g1 = Graphics.FromImage(glyphOrig))
                            using (Graphics g2 = Graphics.FromImage(glyphBlack))
                            {
                                g1.DrawImage(rmd.Font, new RectangleF(0, 0, glyphMetrics.Width, glyphMetrics.Height), glyphMetrics, GraphicsUnit.Pixel);

                                g2.Clear(Color.Black);
                                g2.DrawImage(rmd.Font, new RectangleF(0, 0, glyphMetrics.Width, glyphMetrics.Height), glyphMetrics, GraphicsUnit.Pixel);
                            }

                        using (MemoryStream s = new MemoryStream())
                        {
                            glyphOrig.Save(s, System.Drawing.Imaging.ImageFormat.Bmp);

                            var hash = sha1.ComputeHash(s.GetBuffer());

                            var hashStr = BitConverter.ToString(hash).ToLower().Replace("-", ""); // Preferred format

                            if (hashStr != "d919fb1eb06492a666fbec418813f723e97a6e4f")            // No glyph
                            {
                                if (!glyphDatabase.ContainsKey(hashStr))
                                {
                                    var baseGlyphFilename   = String.Format("{0:d6}.png", dumped);
                                    var outputGlyphFilename = Path.Combine(outputFoldername, baseGlyphFilename);

                                    Console.WriteLine("Saving {0}...", outputGlyphFilename);

                                    if (Directory.Exists(outputGlyphFilename))
                                    {
                                        Directory.CreateDirectory(outputGlyphFilename);
                                    }

                                    glyphBlack.Save(outputGlyphFilename);

                                    glyphDatabase[hashStr]            = new GlyphEntry();
                                    glyphDatabase[hashStr].Filename   = baseGlyphFilename;
                                    glyphDatabase[hashStr].Text       = "";
                                    glyphDatabase[hashStr].References = new List <Tuple <string, uint> >();

                                    dumped++;
                                }

                                glyphDatabase[hashStr].References.Add(new Tuple <string, uint>(baseFilename, gm.Key));
                            }
                        }
                    }
                }
            }

            var outputDatabaseFilename = Path.Combine(outputFoldername, glyphDatabaseFilename);

            SaveGlyphDatabase(outputDatabaseFilename);

            Console.WriteLine("Finished dumping {0} glyphs!", dumped);
            MessageBox.Show(String.Format("Finished dumping {0} glyphs!", dumped));
        }
示例#7
0
        private void DumpScripts_Click(object sender, RoutedEventArgs e)
        {
            const string outputFoldername = "output";

            if (!Directory.Exists(outputFoldername))
            {
                Directory.CreateDirectory(outputFoldername);
            }

            // Generate an image for every string in a file, and then generate an image based on all of those images

            var scripts = ScriptList.Items;
            int dumped  = 0;

            foreach (string file in scripts)
            {
                var baseFilename = System.IO.Path.GetFileNameWithoutExtension(file);

                if (String.Compare(baseFilename, "BasicCharSet", true) == 0 || String.Compare(baseFilename, "BasicRubySet", true) == 0 || String.Compare(baseFilename, "msg_0", true) == 0)
                {
                    continue;
                }

                string outputFilename = System.IO.Path.Combine(outputFoldername, baseFilename + ".png");
                Console.WriteLine("Saving {0}...", outputFilename);

                RmdFile rmd = new RmdFile(file, 0x391);

                if (rmd.Strings != null)
                {
                    var scriptHeader = DrawTextToBitmap(System.IO.Path.GetFileName(file), 30, System.Drawing.Color.LightBlue);

                    List <Tuple <ulong, Bitmap, Bitmap> > images = new List <Tuple <ulong, Bitmap, Bitmap> >();
                    foreach (var str in rmd.Strings)
                    {
                        var header = DrawTextToBitmap(String.Format("{0}:", str.Key), 20, System.Drawing.Color.Red);
                        var d      = DrawString(str.Value, -1, rmd);
                        images.Add(new Tuple <ulong, Bitmap, Bitmap>(str.Key, header, d.Item1));

                        var key = System.IO.Path.GetFileName(file);

                        if (String.Compare(key, String.Format("msg_{0}", str.Key)) == 0)
                        {
                            MessageBox.Show("Found msg that broke expected format of no double keys");
                        }

                        if (!translationDatabase.ContainsKey(str.Key))
                        {
                            translationDatabase[str.Key] = new TranslationEntry();

                            if (d.Item2 != null)
                            {
                                translationDatabase[str.Key].Text = d.Item2;
                            }
                            else
                            {
                                translationDatabase[str.Key].Text = "";
                            }
                        }
                    }

                    int xpadding = 10, ypadding = 10;
                    int w = scriptHeader.Width + xpadding, h = scriptHeader.Height + 20 + ypadding;
                    foreach (var image in images)
                    {
                        if (image.Item2.Width > w)
                        {
                            w = image.Item2.Width;
                        }

                        if (image.Item3.Width > w)
                        {
                            w = image.Item3.Width;
                        }

                        h += image.Item2.Height + 10;
                        h += image.Item3.Height + 20;
                    }

                    Bitmap output = new Bitmap(w + xpadding * 2, h + ypadding * 2);
                    int    x = xpadding, y = ypadding;
                    using (Graphics g = Graphics.FromImage(output))
                    {
                        g.Clear(System.Drawing.Color.Black);

                        g.DrawImage(scriptHeader, x, y);
                        y += scriptHeader.Height + 20;

                        foreach (var image in images)
                        {
                            g.DrawImage(image.Item2, x, y);
                            y += image.Item2.Height + 10;

                            g.DrawImage(image.Item3, x, y);
                            y += image.Item3.Height + 20;
                        }
                    }

                    output.Save(outputFilename);
                    dumped++;
                }
            }

            SaveTranslationDatabase(System.IO.Path.Combine(outputFoldername, translationDatbaseFilename));
            LoadTranslationDatabase(translationDatbaseFilename); // Get rid of all the extra entries we created for dumping

            Console.WriteLine("Finished dumping {0} scripts!", dumped);
            MessageBox.Show(String.Format("Finished dumping {0} scripts!", dumped));
        }
示例#8
0
        private void ToggleScriptMode_Click(object sender, RoutedEventArgs e)
        {
            translationDatabase    = LoadTranslationDatabase(translationDatbaseFilename);
            translationDLCDatabase = LoadTranslationDatabase(translationDLCDatbaseFilename, true);

            var scriptsFolder = "scripts";
            var DLCFolder     = "scripts_dlc";

            ScriptList.SelectedIndex = -1;

            if (ToggleScriptMode.Content.ToString().Contains("DLC"))
            {
                if (!Directory.Exists(DLCFolder))
                {
                    MessageBox.Show(String.Format("Please place all *.rmd files into a folder named \"{0}\" and load the program again.", DLCFolder));
                }
                else
                {
                    var dlc = Directory.EnumerateFiles(DLCFolder, "*.rmd", SearchOption.AllDirectories);

                    var basicCharSetPath = System.IO.Path.Combine(DLCFolder, "BasicCharSet.rmd");
                    if (File.Exists(basicCharSetPath))
                    {
                        basicCharSetRmd = new RmdFile(basicCharSetPath, 0x81);
                    }

                    var basicRubySetPath = System.IO.Path.Combine(DLCFolder, "BasicRubySet.rmd");
                    if (File.Exists(basicRubySetPath))
                    {
                        basicRubySetRmd = new RmdFile(basicRubySetPath, 0x881);
                    }

                    ScriptList.Items.Clear();

                    foreach (var dlc_script in dlc)
                    {
                        ScriptList.Items.Add(dlc_script);
                    }
                    ToggleScriptMode.Content = "Switch to base";

                    DumpGlyphs.IsEnabled  = false;
                    DumpScripts.IsEnabled = false;
                    DumpText.IsEnabled    = false;
                }
            }
            else
            {
                if (!Directory.Exists(scriptsFolder))
                {
                    MessageBox.Show(String.Format("Please place all *.rmd files into a folder named \"{0}\" and load the program again.", scriptsFolder));
                }
                else
                {
                    var scripts = Directory.EnumerateFiles(scriptsFolder, "*.rmd", SearchOption.AllDirectories);

                    var basicCharSetPath = System.IO.Path.Combine(scriptsFolder, "BasicCharSet.rmd");
                    if (File.Exists(basicCharSetPath))
                    {
                        basicCharSetRmd = new RmdFile(basicCharSetPath, 0x81);
                    }

                    var basicRubySetPath = System.IO.Path.Combine(scriptsFolder, "BasicRubySet.rmd");
                    if (File.Exists(basicRubySetPath))
                    {
                        basicRubySetRmd = new RmdFile(basicRubySetPath, 0x881);
                    }

                    ScriptList.Items.Clear();

                    foreach (var script in scripts)
                    {
                        ScriptList.Items.Add(script);
                    }
                    ToggleScriptMode.Content = "Switch to DLC";

                    DumpGlyphs.IsEnabled  = true;
                    DumpScripts.IsEnabled = true;
                    DumpText.IsEnabled    = true;
                }
            }
        }