summaryrefslogtreecommitdiff
path: root/script-editor/MainForm.cs
diff options
context:
space:
mode:
Diffstat (limited to 'script-editor/MainForm.cs')
-rw-r--r--script-editor/MainForm.cs410
1 files changed, 410 insertions, 0 deletions
diff --git a/script-editor/MainForm.cs b/script-editor/MainForm.cs
new file mode 100644
index 0000000..110eb61
--- /dev/null
+++ b/script-editor/MainForm.cs
@@ -0,0 +1,410 @@
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows.Forms;
+
+namespace VPScriptEditor
+{
+ public partial class VPScriptEditor
+ {
+ private Pointer[] inputPtr, outputPtr;
+ private int currPointerNb;
+ private string outputFileName;
+ private FontFile vpFont;
+ private Bitmap conersBmp;
+
+ public VPScriptEditor()
+ {
+ InitializeComponent();
+
+ StreamReader dfile = System.IO.File.OpenText(System.Windows.Forms.Application.StartupPath + @"\database\VP-database.xml");
+ vpFont = new FontFile(dfile, Color.Black);
+ dfile.Close();
+
+ Stream imgStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("VPScriptEditor.corners.png");
+ if (imgStream == null)
+ throw new Exception("Can't open embedded image");
+
+ conersBmp = new Bitmap(imgStream);
+
+ this.ActiveControl = txtbxOutputPtr;
+ }
+
+ private Pointer[] parseXML(String content)
+ {
+ Match match = Regex.Match(content.Replace("\r\n", "\n"), "^<roomscripts>\\n*((?:.|\\n)*?)(?:\\n\\n)?</roomscripts>\\n*$");
+ if (!match.Success)
+ throw new Exception("Bad script format!");
+
+ MatchCollection matches = Regex.Matches(match.Groups[1].Value, "<ptr n=\"(\\d+)\" room=\"(.+?)\"/>\\n(<nowindowdetected/>|<window (type=\"fixed\"|x=\"(.+?)\" y=\"(.+?)\" width=\"(.+?)\" height=\"(.+?)\")/>)\\n((?:.|\\n)*?)(?=(?:\\n\\n<ptr n=\"\\d+\".*/>|$))");
+
+ Pointer[] pointers = new Pointer[matches.Count];
+
+ for (int i = 0; i < matches.Count; i++)
+ {
+ int nb = int.Parse(matches[i].Groups[1].Value);
+
+ if (nb <= 0 || nb > matches.Count)
+ throw new Exception("Pointer no " + nb + " out of range!");
+
+ if (pointers[nb - 1] != null)
+ throw new Exception("Duplicate pointer no " + nb);
+
+ pointers[nb - 1] = new Pointer(matches[i].Groups[2].Value, matches[i].Groups[5].Value.Length > 0 ? WindowType.Normal : (matches[i].Groups[4].Value.Length > 0 ? WindowType.Fixed : WindowType.None), matches[i].Groups[5].Value, matches[i].Groups[6].Value, matches[i].Groups[7].Value, matches[i].Groups[8].Value, matches[i].Groups[9].Value);
+ }
+
+ return pointers;
+ }
+
+ private void OpenMenuItem_Click(System.Object sender, System.EventArgs e)
+ {
+ StreamReader sr = null;
+
+ try
+ {
+ OpenFileDialog ofd = new OpenFileDialog();
+ ofd.Title = "Select *original* script file";
+ ofd.Filter = "Valkyrie Profile script files (*.xml)|*.xml|" + "All files|*.*";
+ if (ofd.ShowDialog() != DialogResult.OK)
+ return;
+
+ String origFileName = ofd.FileName;
+ sr = new StreamReader(ofd.OpenFile());
+ inputPtr = parseXML(sr.ReadToEnd());
+ sr.Close();
+
+ ofd.Title = "Select *translated* script file";
+
+ while (true)
+ {
+ if (ofd.ShowDialog() != DialogResult.OK)
+ return;
+
+ if ((outputFileName = ofd.FileName) == origFileName)
+ MessageBox.Show("Select a different file than the original script!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ else
+ {
+ sr = new StreamReader(ofd.OpenFile());
+ outputPtr = parseXML(sr.ReadToEnd());
+ break;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message);
+ }
+ finally
+ {
+ if (sr != null) sr.Close();
+ }
+
+ initInterface();
+ }
+
+ public string[] getText(string input)
+ {
+ string input_new = Regex.Replace(Regex.Replace(input, "<st rep=\"(\\d+)\"/>(.+?)<rrep/>", new MatchEvaluator(delegate(Match m) { return new String(m.Groups[2].Value[0], int.Parse(m.Groups[1].Value)); })), "<.+?/>", "");
+ return Regex.Split(input_new, "\r\n");
+ }
+
+ public void updateInputPtr()
+ {
+ Pointer p = inputPtr[currPointerNb];
+
+ txtbxRoom.Text = p.rooms;
+ txtbxInputX.Text = p.x;
+ txtbxInputY.Text = p.y;
+ txtbxInputWidth.Text = p.width;
+ txtbxInputHeight.Text = p.height;
+ txtbxInputPtr.Text = p.content.Replace("\n", "\r\n");
+ }
+
+ public void updateOutputPtr()
+ {
+ Pointer p = outputPtr[currPointerNb];
+
+ txtbxOutputX.Text = p.x;
+ txtbxOutputY.Text = p.y;
+ txtbxOutputWidth.Text = p.width;
+ txtbxOutputHeight.Text = p.height;
+ txtbxOutputPtr.Text = p.content.Replace("\n", "\r\n");
+
+ bttnResize.Enabled = p.type == WindowType.Normal;
+ }
+
+ public void updateInterface()
+ {
+ bttnNext.Enabled = currPointerNb < inputPtr.Length - 1;
+ bttnPrevious.Enabled = currPointerNb > 0;
+
+ txtbxPointerNumber.Text = Convert.ToString(currPointerNb + 1);
+
+ updateInputPtr();
+ updateOutputPtr();
+ pnlInput.Invalidate();
+ pnlOutput.Invalidate();
+ }
+
+ public void updateTitle()
+ {
+ this.Text = "VPScriptEditor - " + Path.GetFileName(outputFileName);
+ }
+
+ public void initInterface()
+ {
+ currPointerNb = 0;
+ txtbxPointerNumber.Enabled = true;
+ bttnReset.Enabled = true;
+ SaveMenuItem.Enabled = SaveAsMenuItem.Enabled = true;
+
+ updateInterface();
+ updateTitle();
+ }
+
+ private void bttnNext_Click(System.Object sender, System.EventArgs e)
+ {
+ saveCurrentPointer();
+ ++currPointerNb;
+ updateInterface();
+ }
+
+ private void bttnPrevious_Click(System.Object sender, System.EventArgs e)
+ {
+ saveCurrentPointer();
+ --currPointerNb;
+ updateInterface();
+ }
+
+ private void bttnReset_Click(System.Object sender, System.EventArgs e)
+ {
+ outputPtr[currPointerNb] = new Pointer(inputPtr[currPointerNb]);
+ updateOutputPtr();
+ }
+
+ private void ExitMenuItem_Click(System.Object sender, System.EventArgs e)
+ {
+ Application.Exit();
+ }
+
+ private void gotoPointer()
+ {
+ saveCurrentPointer();
+
+ try
+ {
+ int nb = int.Parse(txtbxPointerNumber.Text);
+ if (nb > 0 && nb <= inputPtr.Length)
+ currPointerNb = nb - 1;
+ else
+ {
+ MessageBox.Show("Pointer out of range. Please enter a number between 1 and " + inputPtr.Length + ".", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ return;
+ }
+ }
+ catch (System.FormatException)
+ {
+ MessageBox.Show("Incorrect pointer number", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
+ return;
+ }
+ finally
+ {
+ txtbxPointerNumber.Text = System.Convert.ToString(currPointerNb + 1);
+ }
+
+ updateInterface();
+ }
+
+ private bool saveOutputXML(string fileName)
+ {
+ saveCurrentPointer();
+
+ StreamWriter sw = null;
+ try
+ {
+ StringBuilder str = new StringBuilder("<roomscripts>\n\n");
+
+ for (int i = 0; i < outputPtr.Length; i++)
+ {
+ Pointer p = outputPtr[i];
+
+ str.Append("<ptr n=\"" + (i + 1) + "\" room=\"" + p.rooms + "\"/>\n");
+ if (p.type == WindowType.None)
+ str.Append("<nowindowdetected/>");
+ else
+ if (p.type == WindowType.Fixed)
+ str.Append("<window type=\"fixed\"/>");
+ else
+ str.Append("<window x=\"" + p.x + "\" y=\"" + p.y + "\" width=\"" + p.width + "\" height=\"" + p.height + "\"/>");
+
+ str.Append("\n");
+ str.Append(p.content.Replace("\r\n", "\n"));
+ str.Append("\n\n");
+ }
+
+ str.Append("</roomscripts>\n");
+
+ sw = new StreamWriter(fileName);
+ sw.Write(str);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return false;
+ }
+ finally
+ {
+ if (sw != null) sw.Close();
+ }
+ return true;
+ }
+
+ private void SaveMenuItem_Click(System.Object sender, System.EventArgs e)
+ {
+ saveOutputXML(outputFileName);
+ }
+
+ private void SaveAsMenuItem_Click(object sender, EventArgs e)
+ {
+ SaveFileDialog sfd = new SaveFileDialog();
+ sfd.Title = "Save as";
+ sfd.Filter = "Valkyrie Profile script files (*.xml)|*.xml|" + "All files|*.*";
+
+ if (sfd.ShowDialog() != DialogResult.OK)
+ return;
+
+ if (saveOutputXML(sfd.FileName))
+ {
+ outputFileName = sfd.FileName;
+ updateTitle();
+ }
+ }
+
+ public void saveCurrentPointer()
+ {
+ outputPtr[currPointerNb] = new Pointer(inputPtr[currPointerNb].rooms, inputPtr[currPointerNb].type, txtbxOutputX.Text, txtbxOutputY.Text, txtbxOutputWidth.Text, txtbxOutputHeight.Text, txtbxOutputPtr.Text.Replace("\r\n", "\n"));
+ }
+
+ private void bttnResize_Click(System.Object sender, System.EventArgs e)
+ {
+ String[] text = getText(txtbxOutputPtr.Text);
+ int w = 0, h = 0;
+
+ for (int j = 0; j <= text.Length - 1; j++)
+ {
+ int curr_w = 0;
+
+ foreach (char ch in text[j])
+ try
+ {
+ curr_w += vpFont.getSymbolWidth(ch);
+ }
+ catch (System.Collections.Generic.KeyNotFoundException ex) { }
+
+ w = curr_w > w ? curr_w : w;
+ h += 14;
+ }
+
+ txtbxOutputWidth.Text = System.Convert.ToString(w);
+ txtbxOutputHeight.Text = System.Convert.ToString(h);
+
+ pnlOutput.Invalidate();
+ }
+
+ private Bitmap drawPointer(String[] text, string xStr, string yStr, string wStr, string hStr)
+ {
+ Bitmap bmp = new Bitmap(320, 240, PixelFormat.Format32bppArgb);
+ Graphics gBmp = Graphics.FromImage(bmp);
+ gBmp.CompositingMode = CompositingMode.SourceOver;
+
+ gBmp.FillRectangle(Brushes.White, 0, 0, bmp.Width, bmp.Height);
+
+ int x_base, x_curr, y_curr;
+
+ try
+ {
+ x_base = x_curr = int.Parse(xStr);
+ y_curr = int.Parse(yStr);
+ }
+ catch (System.FormatException e)
+ {
+ x_curr = x_base = y_curr = 10;
+ }
+
+ try
+ {
+ int h = int.Parse(hStr), w = int.Parse(wStr);
+
+ SolidBrush innerBrush = new SolidBrush(Color.FromArgb(248, 216, 96)), outerBrush = new SolidBrush(Color.FromArgb(88, 64, 8));
+
+ gBmp.FillRectangle(outerBrush, x_curr - 8, y_curr, 1, h);
+ gBmp.FillRectangle(innerBrush, x_curr - 7, y_curr, 2, h);
+ gBmp.FillRectangle(outerBrush, x_curr - 2, y_curr - 7, w + 5, 1);
+ gBmp.FillRectangle(innerBrush, x_curr - 2, y_curr - 6, w + 5, 2);
+ gBmp.FillRectangle(outerBrush, x_curr + w + 9, y_curr, 1, h);
+ gBmp.FillRectangle(innerBrush, x_curr + w + 7, y_curr, 2, h);
+ gBmp.FillRectangle(outerBrush, x_curr - 2, y_curr + h + 6, w + 5, 1);
+ gBmp.FillRectangle(innerBrush, x_curr - 2, y_curr + h + 4, w + 5, 2);
+
+ gBmp.DrawImage(conersBmp, x_curr - 8, y_curr - 7, new Rectangle(0, 0, 7, 7), GraphicsUnit.Pixel);
+ gBmp.DrawImage(conersBmp, x_curr - 8, y_curr + h, new Rectangle(0, 7, 7, 7), GraphicsUnit.Pixel);
+ gBmp.DrawImage(conersBmp, x_curr + w + 3, y_curr - 7, new Rectangle(7, 0, 7, 7), GraphicsUnit.Pixel);
+ gBmp.DrawImage(conersBmp, x_curr + w + 3, y_curr + h, new Rectangle(7, 7, 7, 7), GraphicsUnit.Pixel);
+ }
+ catch (System.FormatException e) { }
+
+ for (int j = 0; j <= text.Length - 1; j++)
+ {
+ foreach (char ch in text[j])
+ try
+ {
+ gBmp.DrawImage(vpFont.getBitmap(ch), x_curr, y_curr);
+ x_curr += vpFont.getSymbolWidth(ch);
+ }
+ catch (System.Collections.Generic.KeyNotFoundException e) { }
+
+ x_curr = x_base;
+ y_curr += 14;
+ }
+
+ return bmp;
+ }
+
+ private void pnlInput_Paint(object sender, PaintEventArgs e)
+ {
+ e.Graphics.DrawImage(drawPointer(getText(txtbxInputPtr.Text), txtbxInputX.Text, txtbxInputY.Text, txtbxInputWidth.Text, txtbxInputHeight.Text), 0, 0);
+ }
+
+ private void pnlOutput_Paint(object sender, PaintEventArgs e)
+ {
+ e.Graphics.DrawImage(drawPointer(getText(txtbxOutputPtr.Text), txtbxOutputX.Text, txtbxOutputY.Text, txtbxOutputWidth.Text, txtbxOutputHeight.Text), 0, 0);
+ }
+
+ private void txtbxOutput_TextChanged(object sender, EventArgs e)
+ {
+ pnlOutput.Invalidate();
+ }
+
+ private void txtbxPointerNumber_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if (e.KeyChar == (char)Keys.Return)
+ {
+ e.Handled = true;
+ gotoPointer();
+ }
+ }
+
+ private void txtbxOutputPtr_KeyPress(object sender, KeyPressEventArgs e)
+ {
+ if (!vpFont.containsSymbol(e.KeyChar) && e.KeyChar >= ' ')
+ {
+ e.Handled = true;
+ System.Media.SystemSounds.Beep.Play();
+ }
+ }
+ }
+} \ No newline at end of file