public static SPTCommand FromStream(BinaryReader r, int id, SPTBlock b) { string arg = ""; SPTCommand ret = null; while (r.BaseStream.Position + 1 < r.BaseStream.Length) { if (ret == null) { ret = new SPTCommand(id, b); } char c = r.ReadChar(); if (c == 0) { ret.args.Add(arg); arg = ""; } else if (c == 0x0D) { break; } else { arg += c; } } return(ret); }
public static void writeSPTFile(BinaryWriter w, SPTBlock block) { for (int i = 0; i < block.Elements.Count; ++i) { if (block.Elements[i] is SPTBlock) { writeSPTFile(w, (SPTBlock)block.Elements[i]); } else if (block.Elements[i] is SPTCommand) { SPTCommand c = ((SPTCommand)block.Elements[i]); if (c.GetArg(0)[0] == '{') { w.Write(Font10Converter.SHIFT_JIS.GetBytes("{" + (block.LineNumber + block.Size - 2) + "\0\r")); } else if (c.GetArg(0)[0] == '}') { w.Write(Font10Converter.SHIFT_JIS.GetBytes("}" + (block.LineNumber - 1) + "\0\r")); } else { byte[] ba = c.ToByteArray(); //byte[] wr = Encoding.Convert(Encoding.Unicode, Encoding.GetEncoding(1252), Encoding.Unicode.GetBytes(ws)); w.Write(ba); } } } }
private void btnSave_Click(object sender, EventArgs e) { if (sptFile == null) { return; } FileStream f = sptFile; BinaryWriter w = new BinaryWriter(f, Font10Converter.SHIFT_JIS); //List<SPTCommand> tempCommands = new List<SPTCommand>(fileCommands); UpdateMemory(); for (int cind = panel1.Controls.Count - 1; cind >= 0; cind--) { Translatable t = panel1.Controls[cind] as Translatable; if (t == null || t.commands.Count == 0) { continue; } SPTCommand first = t.commands[0]; List <SPTCommand> eng = t.GetEnglishCommands(); if (eng.Count != 0) { int idx = first.GetIndexInBlock(); first.Block.Elements.RemoveRange(idx, t.commands.Count); first.Block.Elements.InsertRange(idx, eng); t.commands = eng; } } UpdateLineNumbers(root); w.BaseStream.SetLength(0); w.BaseStream.Flush(); writeSPTFile(w, root); w.Flush(); Edited = false; status("Save completed."); }
private void loadSPT() { if (sptReader == null) { return; } panel1.Controls.Clear(); lastElement = null; Edited = false; // data structure set up int id = 0; root = new SPTBlock(0); blockHierarchy = new Stack <SPTBlock>(); blockHierarchy.Push(root); SPTCommand c; // case-specific flags bool needNewBlock = true; bool checkNameWinClose = false; while ((c = SPTCommand.FromStream(sptReader, id++, blockHierarchy.Peek())) != null) { // pre loop logic if (c.GetArg(0)[0] == '{') { SPTBlock b = new SPTBlock(id); b.Elements.Add(c); blockHierarchy.Peek().Elements.Add(b); blockHierarchy.Push(b); continue; } else if (c.GetArg(0)[0] == '}') { blockHierarchy.Pop().Elements.Add(c); continue; } blockHierarchy.Peek().Elements.Add(c); if (!(c.GetArg(0).Equals("message") || c.GetArg(0).Equals("message0"))) { needNewBlock = true; } //// if (c.GetArg(0).Equals("message") || c.GetArg(0).Equals("message0")) // start of message set { if (needNewBlock) { if (c.GetArg(1) != "mbox0") { addTranslatable(new Note("Found non-mbox0 message box, tell me about this", id)); } addTranslatable(new MessageBlock()); needNewBlock = false; } for (int i = 2; i < c.ArgCount; ++i) { string msg = c.GetArg(i); if (i + 1 < c.ArgCount) { msg += "§"; } lastElement.JapText += msg; } lastElement.JapText += "¶\r\n"; lastElement.commands.Add(c); } else if (c.GetArg(0).Equals("nameset0")) // setting talker name { if (c.GetArg(1).Equals("N0")) { addTranslatable(new Nameplate()); lastElement.JapText = c.GetArg(2); lastElement.commands.Add(c); } } else if (c.GetArg(0).Equals("nameset")) // check for azuma talking { if (c.GetArg(1).Equals("N0") && c.GetArg(2).StartsWith("00_")) { if (lastElement != null && lastElement.JapText.Equals("NO NAME:")) //it removes nameplate for azuma, have to ignore for this { panel1.Controls.Remove(lastElement); } lastElement = ((panel1.Controls.Count - 1 >= 0) ? (Translatable)panel1.Controls[panel1.Controls.Count - 1] : null); addTranslatable(new Note("AZUMA:")); } } else if (c.GetArg(0).Equals("actortext0") && c.GetArg(1).Equals("name_win")) // check if name window being hidden { checkNameWinClose = true; continue; } else if (c.GetArg(0).Equals("actordisp0") && c.GetArg(1).Equals("name_win") && c.GetArg(2).Equals("false") && checkNameWinClose) { addTranslatable(new Note("NO NAME:")); } else if (c.GetArg(0).Equals("scriptcall0") && c.GetArg(1).Equals("select")) { int nopts = Convert.ToInt32(c.GetArg(2)); addTranslatable(new Note("SELECTION (" + nopts + "):")); GenericTranslatable t = new GenericTranslatable(c); for (int i = 0; i < nopts + 1; ++i) { t.AddArg(new GenericTArgOpts(3 + i, (i > 0))); } addTranslatable(t); } else if (c.GetArg(0).Equals("scriptcall")) { addTranslatable(new Note("Note: This script calls \"" + c.GetArg(1) + ".spt\".")); } else if (c.GetArg(0).StartsWith("ifselect") || (c.ArgCount > 1 && c.GetArg(1).StartsWith("ifselect"))) { addTranslatable(new Note("IF-SELECT:")); GenericTranslatable t = new GenericTranslatable(c); t.AddArg(new GenericTArgOpts(c.GetArg(0).StartsWith("ifselect") ? 1 : 2, true)); addTranslatable(t); } else { // some non-known command. try finding japanese text. // arg 0 is always english command - it won't have japanese text. bool done = false; if (c.ArgCount > 1) { for (int i = 1; i < c.ArgCount && !done; ++i) { string arg = c.GetArg(i); // check if one of the first 3 characters is japanese for (int j = 0; j < Math.Min(3, arg.Length); ++j) { if (Font10Converter.IsJapanese(arg[j])) { addTranslatable(new Note("Unidentified Japanese text detected, tell me about this. Full command shown.", id)); GenericTranslatable t = new GenericTranslatable(c); for (int k = 0; k < c.ArgCount; ++k) { t.AddArg((GenericTArgOpts)k); } addTranslatable(t); done = true; break; } } } } } //// checkNameWinClose = false; // post loop logic } panel1.Focus(); // so the scroll bar works more intuitively UpdateFromMemory(); status("Loaded \"" + txtSPTPath.Text.Substring(txtSPTPath.Text.LastIndexOf('\\') + 1) + "\""); }