public void GetSQL(String ConnectionString) { SQLiteConnection Connection = new SQLiteConnection(ConnectionString); Connection.Open(); ScriptData.Clear(); TextAmount = 0; UnreferencedText = new List <KeyValuePair <int, string> >(); using (SQLiteTransaction Transaction = Connection.BeginTransaction()) using (SQLiteCommand Command = new SQLiteCommand(Connection)) { Command.CommandText = "SELECT english, PointerRef, IdentifyPointerRef FROM Text ORDER BY id"; SQLiteDataReader r = Command.ExecuteReader(); while (r.Read()) { String SQLText; try { SQLText = r.GetString(0).Replace("''", "'"); } catch (System.InvalidCastException) { SQLText = ""; } int PointerRef = r.GetInt32(1); int IdentPtrRef = r.GetInt32(2); if (PointerRef == 1) { // game code while (true) { int commandstart = SQLText.IndexOf('<'); int commandend = SQLText.IndexOf('>'); if (commandstart == -1) { break; } string cmd = SQLText.Substring(commandstart + 1, (commandend - commandstart) - 1); SQLText = SQLText.Substring(commandend + 1); ScriptEntry e = new ScriptEntry(); if (cmd.Contains(':')) { // command with args string[] bytestrs = cmd.Split(singleSpaceInArray, StringSplitOptions.RemoveEmptyEntries); string typestr = bytestrs[0].Replace(":", ""); switch (typestr) { case "FMV": e.Type = 0x05; break; case "Voice": e.Type = 0x08; break; case "Music": e.Type = 0x09; break; case "Sound": e.Type = 0x0A; break; case "LoadScript": e.Type = 0x19; break; case "Sprite": e.Type = 0x1E; break; case "Speaker": e.Type = 0x21; break; case "WaitPlayerInput": e.Type = 0x3A; break; case "WaitFrame": e.Type = 0x3B; break; case "SDR2-WaitPlayerInput": e.Type = 0x4B; break; case "SDR2-WaitFrame": e.Type = 0x4C; break; default: e.Type = HexUtils.ParseDecOrHexToByte(typestr); break; } byte[] args = new byte[bytestrs.Length - 1]; for (int i = 1; i < bytestrs.Length; ++i) { if (bytestrs[i].Contains('[') && bytestrs[i].Contains(']')) { args[i - 1] = (DanganUtil.NameToCharacterId(bytestrs[i].Replace("[", "").Replace("]", ""))); } else { args[i - 1] = (HexUtils.ParseDecOrHexToByte(bytestrs[i])); } } e.Arguments = args; } else { // command without args if (cmd == "__END__") { break; } // ending command processing for this entry switch (cmd) { case "WaitPlayerInput": e.Type = 0x3A; break; case "WaitFrame": e.Type = 0x3B; break; case "SDR2-WaitPlayerInput": e.Type = 0x4B; break; case "SDR2-WaitFrame": e.Type = 0x4C; break; default: e.Type = HexUtils.ParseDecOrHexToByte(cmd); break; } e.Arguments = new byte[0]; } ScriptData.Add(e); } } else if (PointerRef == 2) { // normal text if (SQLText.StartsWith("<REMOVE>")) { // remove this entry by simply not inserting it into the data // also find previous <WaitForPlayerInput> if it exists and remove it // ...also remove <WaitFrame>s although I'm not 100% on this if it's actually smart, // but we'll see this during testing I guess! // search through script data in reverse order until we find either the beginning // or the previous Text entry for (int i = ScriptData.Count - 1; i >= 0; --i) { if (ScriptData[i].Type == 0x02) // text entry { break; // we're done } // DR1: 0x3A -> WaitPlayerInput; 0x3B -> WaitFrame // SDR2: 0x4C -> WaitFrame; 0x4B -> WaitPlayerInput switch (DanganUtil.GameVersion) { case 1: if (ScriptData[i].Type == 0x3A || ScriptData[i].Type == 0x3B) { ScriptData.RemoveAt(i); } break; default: if (ScriptData[i].Type == 0x4C || ScriptData[i].Type == 0x4B) { ScriptData.RemoveAt(i); } break; } } } else { bool first = true; foreach (string s in SQLText.Split('\f')) { if (!first) { ScriptEntry wait = new ScriptEntry(); switch (DanganUtil.GameVersion) { case 1: wait.Type = 0x3A; break; default: wait.Type = 0x4B; break; } wait.Arguments = new byte[0]; ScriptData.Add(wait); } ScriptEntry e = new ScriptEntry(); e.Type = 0x02; e.Arguments = new byte[2]; //e.Arguments[0] = 0xFF; // will be fixed later in CreateFile() //e.Arguments[1] = 0xFF; e.Text = s; ScriptData.Add(e); first = false; } } } else if (PointerRef == 3) { // unreferenced text UnreferencedText.Add(new KeyValuePair <int, string>(IdentPtrRef, SQLText)); } else { throw new Exception("Unrecognized PointerRef type!"); } } Transaction.Rollback(); } return; }
public void GetSQL( String ConnectionString ) { SQLiteConnection Connection = new SQLiteConnection( ConnectionString ); Connection.Open(); ScriptData.Clear(); TextAmount = 0; UnreferencedText = new List<KeyValuePair<int, string>>(); using ( SQLiteTransaction Transaction = Connection.BeginTransaction() ) using ( SQLiteCommand Command = new SQLiteCommand( Connection ) ) { Command.CommandText = "SELECT english, PointerRef, IdentifyPointerRef FROM Text ORDER BY id"; SQLiteDataReader r = Command.ExecuteReader(); while ( r.Read() ) { String SQLText; try { SQLText = r.GetString( 0 ).Replace( "''", "'" ); } catch ( System.InvalidCastException ) { SQLText = ""; } int PointerRef = r.GetInt32( 1 ); int IdentPtrRef = r.GetInt32( 2 ); if ( PointerRef == 1 ) { // game code while ( true ) { int commandstart = SQLText.IndexOf( '<' ); int commandend = SQLText.IndexOf( '>' ); if ( commandstart == -1 ) { break; } string cmd = SQLText.Substring( commandstart + 1, ( commandend - commandstart ) - 1 ); SQLText = SQLText.Substring( commandend + 1 ); ScriptEntry e = new ScriptEntry(); if ( cmd.Contains( ':' ) ) { // command with args string[] bytestrs = cmd.Split( singleSpaceInArray, StringSplitOptions.RemoveEmptyEntries ); string typestr = bytestrs[0].Replace( ":", "" ); switch ( typestr ) { case "FMV": e.Type = 0x05; break; case "Voice": e.Type = 0x08; break; case "Music": e.Type = 0x09; break; case "Sound": e.Type = 0x0A; break; case "LoadScript": e.Type = 0x19; break; case "Sprite": e.Type = 0x1E; break; case "Speaker": e.Type = 0x21; break; case "WaitPlayerInput": e.Type = 0x3A; break; case "WaitFrame": e.Type = 0x3B; break; case "SDR2-WaitPlayerInput": e.Type = 0x4B; break; case "SDR2-WaitFrame": e.Type = 0x4C; break; default: e.Type = Util.ParseDecOrHexToByte( typestr ); break; } byte[] args = new byte[bytestrs.Length - 1]; for ( int i = 1; i < bytestrs.Length; ++i ) { if ( bytestrs[i].Contains( '[' ) && bytestrs[i].Contains( ']' ) ) { args[i - 1] = ( DanganUtil.NameToCharacterId( bytestrs[i].Replace( "[", "" ).Replace( "]", "" ) ) ); } else { args[i - 1] = ( Util.ParseDecOrHexToByte( bytestrs[i] ) ); } } e.Arguments = args; } else { // command without args if ( cmd == "__END__" ) { break; } // ending command processing for this entry switch ( cmd ) { case "WaitPlayerInput": e.Type = 0x3A; break; case "WaitFrame": e.Type = 0x3B; break; case "SDR2-WaitPlayerInput": e.Type = 0x4B; break; case "SDR2-WaitFrame": e.Type = 0x4C; break; default: e.Type = Util.ParseDecOrHexToByte( cmd ); break; } e.Arguments = new byte[0]; } ScriptData.Add( e ); } } else if ( PointerRef == 2 ) { // normal text if ( SQLText.StartsWith( "<REMOVE>" ) ) { // remove this entry by simply not inserting it into the data // also find previous <WaitForPlayerInput> if it exists and remove it // ...also remove <WaitFrame>s although I'm not 100% on this if it's actually smart, // but we'll see this during testing I guess! // search through script data in reverse order until we find either the beginning // or the previous Text entry for ( int i = ScriptData.Count - 1; i >= 0; --i ) { if ( ScriptData[i].Type == 0x02 ) { // text entry break; // we're done } // DR1: 0x3A -> WaitPlayerInput; 0x3B -> WaitFrame // SDR2: 0x4C -> WaitFrame; 0x4B -> WaitPlayerInput switch ( DanganUtil.GameVersion ) { case 1: if ( ScriptData[i].Type == 0x3A || ScriptData[i].Type == 0x3B ) { ScriptData.RemoveAt( i ); } break; default: if ( ScriptData[i].Type == 0x4C || ScriptData[i].Type == 0x4B ) { ScriptData.RemoveAt( i ); } break; } } } else { bool first = true; foreach ( string s in SQLText.Split( '\f' ) ) { if ( !first ) { ScriptEntry wait = new ScriptEntry(); switch ( DanganUtil.GameVersion ) { case 1: wait.Type = 0x3A; break; default: wait.Type = 0x4B; break; } wait.Arguments = new byte[0]; ScriptData.Add( wait ); } ScriptEntry e = new ScriptEntry(); e.Type = 0x02; e.Arguments = new byte[2]; //e.Arguments[0] = 0xFF; // will be fixed later in CreateFile() //e.Arguments[1] = 0xFF; e.Text = s; ScriptData.Add( e ); first = false; } } } else if ( PointerRef == 3 ) { // unreferenced text UnreferencedText.Add( new KeyValuePair<int, string>( IdentPtrRef, SQLText ) ); } else { throw new Exception( "Unrecognized PointerRef type!" ); } } Transaction.Rollback(); } return; }
public List <ScriptEntry> CreateScriptDataFromOriginal() { List <ScriptEntry> Script = new List <ScriptEntry>(); for (int i = HeaderSize; i < TextBlockLocation; i++) { if (OriginalFile[i] == 0x70) { i++; ScriptEntry entry = new ScriptEntry(); entry.Type = OriginalFile[i]; switch (entry.Type) { case 0x00: entry.Arguments = new byte[2]; break; case 0x01: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[3]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[4]; } break; case 0x02: entry.Arguments = new byte[2]; break; case 0x03: entry.Arguments = new byte[1]; break; case 0x04: entry.Arguments = new byte[4]; break; case 0x05: entry.Arguments = new byte[2]; break; case 0x06: entry.Arguments = new byte[8]; break; case 0x08: entry.Arguments = new byte[5]; break; case 0x09: entry.Arguments = new byte[3]; break; case 0x0A: entry.Arguments = new byte[3]; break; case 0x0B: entry.Arguments = new byte[2]; break; case 0x0C: entry.Arguments = new byte[2]; break; case 0x0D: entry.Arguments = new byte[3]; break; case 0x0E: entry.Arguments = new byte[2]; break; case 0x0F: entry.Arguments = new byte[3]; break; case 0x10: entry.Arguments = new byte[3]; break; case 0x11: entry.Arguments = new byte[4]; break; case 0x14: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[3]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[6]; } break; case 0x15: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[3]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[4]; } break; case 0x19: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[3]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[5]; } break; case 0x1A: entry.Arguments = new byte[0]; break; case 0x1B: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[3]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[5]; } break; case 0x1C: entry.Arguments = new byte[0]; break; case 0x1E: entry.Arguments = new byte[5]; break; case 0x1F: entry.Arguments = new byte[7]; break; case 0x20: entry.Arguments = new byte[5]; break; case 0x21: entry.Arguments = new byte[1]; break; case 0x22: entry.Arguments = new byte[3]; break; case 0x23: entry.Arguments = new byte[5]; break; case 0x25: entry.Arguments = new byte[2]; break; case 0x26: entry.Arguments = new byte[3]; break; case 0x27: entry.Arguments = new byte[1]; break; case 0x29: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[1]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[0xD]; } break; case 0x2A: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[2]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[0xC]; } break; case 0x2B: entry.Arguments = new byte[1]; break; case 0x2C: entry.Arguments = new byte[2]; break; case 0x2E: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[2]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[5]; } break; case 0x2F: entry.Arguments = new byte[10]; break; case 0x30: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[3]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[2]; } break; case 0x32: entry.Arguments = new byte[1]; break; case 0x33: entry.Arguments = new byte[4]; break; case 0x34: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[2]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[1]; } break; case 0x38: entry.Arguments = new byte[5]; break; case 0x39: entry.Arguments = new byte[5]; break; case 0x3A: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[0]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[4]; } break; case 0x3B: if (DanganUtil.GameVersion == 1) { entry.Arguments = new byte[0]; } else if (DanganUtil.GameVersion >= 2) { entry.Arguments = new byte[2]; } break; case 0x3C: entry.Arguments = new byte[0]; break; //case 0x47: entry.Arguments = new byte[5]; break; // this seems to actually be varargs case 0x4C: entry.Arguments = new byte[0]; break; case 0x4D: entry.Arguments = new byte[0]; break; default: List <byte> VariableLengthArgs = new List <byte>(); while (OriginalFile[i + 1] != 0x70) { VariableLengthArgs.Add(OriginalFile[i + 1]); ++i; } entry.Arguments = VariableLengthArgs.ToArray(); Script.Add(entry); continue; } for (int j = 0; j < entry.Arguments.Length; ++j) { entry.Arguments[j] = OriginalFile[i + 1]; ++i; } Script.Add(entry); } else { // reached end of file? for ( ; i < TextBlockLocation; i++) { if (OriginalFile[i] != 0x00) { throw new Exception("script entry doesn't start with 0x70 at 0x" + i.ToString("X6") + ", abort"); } } return(Script); } } return(Script); }
public List<ScriptEntry> CreateScriptDataFromOriginal() { List<ScriptEntry> Script = new List<ScriptEntry>(); for ( int i = HeaderSize; i < TextBlockLocation; i++ ) { if ( OriginalFile[i] == 0x70 ) { i++; ScriptEntry entry = new ScriptEntry(); entry.Type = OriginalFile[i]; switch ( entry.Type ) { case 0x00: entry.Arguments = new byte[2]; break; case 0x01: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[3]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[4]; } break; case 0x02: entry.Arguments = new byte[2]; break; case 0x03: entry.Arguments = new byte[1]; break; case 0x04: entry.Arguments = new byte[4]; break; case 0x05: entry.Arguments = new byte[2]; break; case 0x06: entry.Arguments = new byte[8]; break; case 0x08: entry.Arguments = new byte[5]; break; case 0x09: entry.Arguments = new byte[3]; break; case 0x0A: entry.Arguments = new byte[3]; break; case 0x0B: entry.Arguments = new byte[2]; break; case 0x0C: entry.Arguments = new byte[2]; break; case 0x0D: entry.Arguments = new byte[3]; break; case 0x0E: entry.Arguments = new byte[2]; break; case 0x0F: entry.Arguments = new byte[3]; break; case 0x10: entry.Arguments = new byte[3]; break; case 0x11: entry.Arguments = new byte[4]; break; case 0x14: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[3]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[6]; } break; case 0x15: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[3]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[4]; } break; case 0x19: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[3]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[5]; } break; case 0x1A: entry.Arguments = new byte[0]; break; case 0x1B: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[3]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[5]; } break; case 0x1C: entry.Arguments = new byte[0]; break; case 0x1E: entry.Arguments = new byte[5]; break; case 0x1F: entry.Arguments = new byte[7]; break; case 0x20: entry.Arguments = new byte[5]; break; case 0x21: entry.Arguments = new byte[1]; break; case 0x22: entry.Arguments = new byte[3]; break; case 0x23: entry.Arguments = new byte[5]; break; case 0x25: entry.Arguments = new byte[2]; break; case 0x26: entry.Arguments = new byte[3]; break; case 0x27: entry.Arguments = new byte[1]; break; case 0x29: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[1]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[0xD]; } break; case 0x2A: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[2]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[0xC]; } break; case 0x2B: entry.Arguments = new byte[1]; break; case 0x2C: entry.Arguments = new byte[2]; break; case 0x2E: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[2]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[5]; } break; case 0x2F: entry.Arguments = new byte[10]; break; case 0x30: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[3]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[2]; } break; case 0x32: entry.Arguments = new byte[1]; break; case 0x33: entry.Arguments = new byte[4]; break; case 0x34: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[2]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[1]; } break; case 0x38: entry.Arguments = new byte[5]; break; case 0x39: entry.Arguments = new byte[5]; break; case 0x3A: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[0]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[4]; } break; case 0x3B: if ( DanganUtil.GameVersion == 1 ) { entry.Arguments = new byte[0]; } else if ( DanganUtil.GameVersion >= 2 ) { entry.Arguments = new byte[2]; } break; case 0x3C: entry.Arguments = new byte[0]; break; //case 0x47: entry.Arguments = new byte[5]; break; // this seems to actually be varargs case 0x4C: entry.Arguments = new byte[0]; break; case 0x4D: entry.Arguments = new byte[0]; break; default: List<byte> VariableLengthArgs = new List<byte>(); while ( OriginalFile[i + 1] != 0x70 ) { VariableLengthArgs.Add( OriginalFile[i + 1] ); ++i; } entry.Arguments = VariableLengthArgs.ToArray(); Script.Add( entry ); continue; } for ( int j = 0; j < entry.Arguments.Length; ++j ) { entry.Arguments[j] = OriginalFile[i + 1]; ++i; } Script.Add( entry ); } else { // reached end of file? for ( ; i < TextBlockLocation; i++ ) { if ( OriginalFile[i] != 0x00 ) { throw new Exception( "script entry doesn't start with 0x70 at 0x" + i.ToString( "X6" ) + ", abort" ); } } return Script; } } return Script; }