mirror of
https://github.com/isledecomp/LEGOIslandRebuilder.git
synced 2024-11-27 17:45:42 -05:00
added saving/loading
This commit is contained in:
parent
4492c53cae
commit
db58ba6518
2 changed files with 428 additions and 203 deletions
|
@ -5,6 +5,7 @@ using System.Windows.Forms;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Media;
|
using System.Media;
|
||||||
|
using System.Xml;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace Rebuilder
|
namespace Rebuilder
|
||||||
|
@ -20,6 +21,9 @@ namespace Rebuilder
|
||||||
SoundPlayer sound_player = new SoundPlayer();
|
SoundPlayer sound_player = new SoundPlayer();
|
||||||
int last_played_row = -1;
|
int last_played_row = -1;
|
||||||
|
|
||||||
|
List<string> replace_src = new List<string>();
|
||||||
|
List<string> replace_dst = new List<string>();
|
||||||
|
|
||||||
public MusicInjector()
|
public MusicInjector()
|
||||||
{
|
{
|
||||||
Text = "Music Injector";
|
Text = "Music Injector";
|
||||||
|
@ -27,6 +31,7 @@ namespace Rebuilder
|
||||||
Visible = false;
|
Visible = false;
|
||||||
Width = 720;
|
Width = 720;
|
||||||
Height = 540;
|
Height = 540;
|
||||||
|
CenterToScreen();
|
||||||
|
|
||||||
table.ReadOnly = true;
|
table.ReadOnly = true;
|
||||||
table.RowHeadersVisible = false;
|
table.RowHeadersVisible = false;
|
||||||
|
@ -80,13 +85,12 @@ namespace Rebuilder
|
||||||
|
|
||||||
private void OnClose(object sender, FormClosingEventArgs e)
|
private void OnClose(object sender, FormClosingEventArgs e)
|
||||||
{
|
{
|
||||||
|
ConvertTableToReplaceData();
|
||||||
sound_player.Stop();
|
sound_player.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnShow(object sender, EventArgs e)
|
private bool Prepare()
|
||||||
{
|
{
|
||||||
CenterToScreen();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(jukebox_si_path))
|
if (string.IsNullOrEmpty(jukebox_si_path))
|
||||||
{
|
{
|
||||||
FindJukeboxSI();
|
FindJukeboxSI();
|
||||||
|
@ -99,13 +103,23 @@ namespace Rebuilder
|
||||||
MessageBoxButtons.OK,
|
MessageBoxButtons.OK,
|
||||||
MessageBoxIcon.Error
|
MessageBoxIcon.Error
|
||||||
);
|
);
|
||||||
Close();
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Extract();
|
Extract();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnShow(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (!Prepare())
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FindJukeboxSI()
|
private void FindJukeboxSI()
|
||||||
|
@ -282,10 +296,8 @@ namespace Rebuilder
|
||||||
ofd.Filter = "WAVE Audio (*.wav)|*.wav";
|
ofd.Filter = "WAVE Audio (*.wav)|*.wav";
|
||||||
if (ofd.ShowDialog() == DialogResult.OK)
|
if (ofd.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
Font f = new Font(table.Font, FontStyle.Bold);
|
SetCellBold(table.Rows[e.RowIndex].Cells[0]);
|
||||||
|
SetCellBold(table.Rows[e.RowIndex].Cells[1]);
|
||||||
table.Rows[e.RowIndex].Cells[0].Style.Font = f;
|
|
||||||
table.Rows[e.RowIndex].Cells[1].Style.Font = f;
|
|
||||||
|
|
||||||
table.Rows[e.RowIndex].Cells[1].Value = ofd.FileName;
|
table.Rows[e.RowIndex].Cells[1].Value = ofd.FileName;
|
||||||
}
|
}
|
||||||
|
@ -293,8 +305,8 @@ namespace Rebuilder
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table.Rows[e.RowIndex].Cells[0].Style.Font = table.Font;
|
SetCellNormal(table.Rows[e.RowIndex].Cells[0]);
|
||||||
table.Rows[e.RowIndex].Cells[1].Style.Font = table.Font;
|
SetCellNormal(table.Rows[e.RowIndex].Cells[1]);
|
||||||
|
|
||||||
table.Rows[e.RowIndex].Cells[1].Value = filenames[e.RowIndex];
|
table.Rows[e.RowIndex].Cells[1].Value = filenames[e.RowIndex];
|
||||||
}
|
}
|
||||||
|
@ -306,7 +318,7 @@ namespace Rebuilder
|
||||||
private void Extract()
|
private void Extract()
|
||||||
{
|
{
|
||||||
int file_count = 0;
|
int file_count = 0;
|
||||||
temp_extract_path = Path.GetTempPath() + "lire/jukebox";
|
temp_extract_path = Path.GetTempPath() + "LEGOIslandRebuilder/jukebox";
|
||||||
Directory.CreateDirectory(temp_extract_path);
|
Directory.CreateDirectory(temp_extract_path);
|
||||||
|
|
||||||
using (FileStream stream = new FileStream(jukebox_si_path, FileMode.Open, FileAccess.Read))
|
using (FileStream stream = new FileStream(jukebox_si_path, FileMode.Open, FileAccess.Read))
|
||||||
|
@ -463,9 +475,30 @@ namespace Rebuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert replace data to table
|
||||||
|
for (int i=0;i<replace_src.Count;i++)
|
||||||
|
{
|
||||||
|
int index = filenames.IndexOf(replace_dst[i]);
|
||||||
|
|
||||||
|
table.Rows[index].Cells[1].Value = replace_src[i];
|
||||||
|
|
||||||
|
SetCellBold(table.Rows[index].Cells[0]);
|
||||||
|
SetCellBold(table.Rows[index].Cells[1]);
|
||||||
|
}
|
||||||
|
|
||||||
//Console.WriteLine("\nDone! Extracted " + file_count + " files\n");
|
//Console.WriteLine("\nDone! Extracted " + file_count + " files\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SetCellNormal(DataGridViewCell cell)
|
||||||
|
{
|
||||||
|
cell.Style.Font = new Font(Control.DefaultFont, FontStyle.Regular);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetCellBold(DataGridViewCell cell)
|
||||||
|
{
|
||||||
|
cell.Style.Font = new Font(Control.DefaultFont, FontStyle.Bold);
|
||||||
|
}
|
||||||
|
|
||||||
static void WriteString(FileStream stream, string text)
|
static void WriteString(FileStream stream, string text)
|
||||||
{
|
{
|
||||||
byte[] b = System.Text.Encoding.ASCII.GetBytes(text);
|
byte[] b = System.Text.Encoding.ASCII.GetBytes(text);
|
||||||
|
@ -512,27 +545,27 @@ namespace Rebuilder
|
||||||
stream.Write(write_bytes, 0, write_bytes.Length);
|
stream.Write(write_bytes, 0, write_bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Insert(string output_fn)
|
private void ConvertTableToReplaceData()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(jukebox_si_path))
|
replace_src.Clear();
|
||||||
{
|
replace_dst.Clear();
|
||||||
FindJukeboxSI();
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(jukebox_si_path))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < filenames.Count; i++)
|
for (int i = 0; i < filenames.Count; i++)
|
||||||
{
|
{
|
||||||
if (table.Rows[i].Cells[1].Value.ToString() != filenames[i])
|
if (table.Rows[i].Cells[1].Value.ToString() != filenames[i])
|
||||||
{
|
{
|
||||||
File.Copy(table.Rows[i].Cells[1].Value.ToString(), temp_extract_path + "/" + filenames[i], true);
|
replace_src.Add(table.Rows[i].Cells[1].Value.ToString());
|
||||||
|
replace_dst.Add(filenames[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reconstruct(output_fn);
|
public void Insert(string output_fn)
|
||||||
|
{
|
||||||
|
if (Prepare())
|
||||||
|
{
|
||||||
|
Reconstruct(output_fn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Reconstruct(string output_fn)
|
private void Reconstruct(string output_fn)
|
||||||
|
@ -757,159 +790,164 @@ namespace Rebuilder
|
||||||
|
|
||||||
Int32 millis = 0;
|
Int32 millis = 0;
|
||||||
|
|
||||||
if (File.Exists(temp_extract_path + "/" + wav_fn))
|
string wav_file;
|
||||||
|
|
||||||
|
int replace_index = replace_dst.IndexOf(wav_fn);
|
||||||
|
if (replace_index == -1)
|
||||||
{
|
{
|
||||||
using (FileStream wav_str = new FileStream(temp_extract_path + "/" + wav_fn, FileMode.Open, FileAccess.Read))
|
// We won't replace this file so just use the original
|
||||||
{
|
wav_file = temp_extract_path + "/" + wav_fn;
|
||||||
//Console.WriteLine("Inserting " + wav_fn);
|
|
||||||
|
|
||||||
// Ignore first part of the wav header
|
|
||||||
if (!SeekUntil(wav_str, "WAVE") || !SeekUntil(wav_str, "fmt "))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Invalid file at " + wav_fn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wav_str.Position += 4;
|
|
||||||
|
|
||||||
long old_pos = out_stream.Position;
|
|
||||||
out_stream.Position = wave_header_pos;
|
|
||||||
|
|
||||||
// Copy WAV header data
|
|
||||||
byte[] wav_header = new byte[16];
|
|
||||||
wav_str.Read(wav_header, 0, wav_header.Length);
|
|
||||||
out_stream.Write(wav_header, 0, wav_header.Length);
|
|
||||||
|
|
||||||
// Total data size in MxCh is the WAV's data size + 4
|
|
||||||
if (!SeekUntil(wav_str, "data"))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Invalid file at " + wav_fn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
byte[] data_size_bytes = new byte[4];
|
|
||||||
wav_str.Read(data_size_bytes, 0, data_size_bytes.Length);
|
|
||||||
Int32 wav_data_size = (BitConverter.ToInt32(data_size_bytes, 0));
|
|
||||||
data_size_bytes = BitConverter.GetBytes((Int32)(wav_data_size + 4));
|
|
||||||
out_stream.Write(data_size_bytes, 0, data_size_bytes.Length);
|
|
||||||
long wav_end = wav_str.Position + wav_data_size;
|
|
||||||
|
|
||||||
// Re-skip latter 4 bytes of MxCh header
|
|
||||||
out_stream.Position = old_pos;
|
|
||||||
|
|
||||||
// Write first FLC chunk
|
|
||||||
/*
|
|
||||||
if (flc_id != -1)
|
|
||||||
{
|
|
||||||
int index = ids.IndexOf(flc_id);
|
|
||||||
int remainder = (int)(si_buffer_size - (out_stream.Position % si_buffer_size));
|
|
||||||
|
|
||||||
if (data[index][0].Length > remainder)
|
|
||||||
{
|
|
||||||
WriteZeroes(out_stream, (int)remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_stream.Write(data[index][0], 0, data[index][0].Length);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Loop over data in WAV
|
|
||||||
// Write out WAV file chunking along the way
|
|
||||||
int max_wav_data = BitConverter.ToInt32(wav_header, 8);
|
|
||||||
int max_chunk_size = max_wav_data + 22;
|
|
||||||
while (wav_str.Position < wav_end)
|
|
||||||
{
|
|
||||||
// SI files are also buffered at 20000h (or 131072 bytes), so we can only write that much at a time
|
|
||||||
Int32 this_chunk_max = (Int32)Math.Min(max_chunk_size, si_buffer_size - (out_stream.Position % si_buffer_size));
|
|
||||||
|
|
||||||
if (this_chunk_max <= 22)
|
|
||||||
{
|
|
||||||
WriteZeroes(out_stream, this_chunk_max);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Int16 flags = 0;
|
|
||||||
if (this_chunk_max < max_chunk_size)
|
|
||||||
{
|
|
||||||
flags = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
this_chunk_max -= 8;
|
|
||||||
|
|
||||||
int actual_wav_chunk_size = this_chunk_max - 14;
|
|
||||||
|
|
||||||
int actual_data_chunk_size = max_wav_data;
|
|
||||||
|
|
||||||
if (wav_str.Position + actual_wav_chunk_size > wav_end)
|
|
||||||
{
|
|
||||||
flags = 0;
|
|
||||||
actual_wav_chunk_size = (int)(wav_end - wav_str.Position);
|
|
||||||
this_chunk_max = actual_wav_chunk_size + 14;
|
|
||||||
actual_data_chunk_size = actual_wav_chunk_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteMxChHeader(out_stream, this_chunk_max, flags, wav_id, millis, actual_data_chunk_size);
|
|
||||||
|
|
||||||
byte[] wav_bytes = new byte[actual_wav_chunk_size];
|
|
||||||
wav_str.Read(wav_bytes, 0, actual_wav_chunk_size);
|
|
||||||
out_stream.Write(wav_bytes, 0, actual_wav_chunk_size);
|
|
||||||
|
|
||||||
// If we had to split this chunk in half, write the second half now
|
|
||||||
if (flags == 16)
|
|
||||||
{
|
|
||||||
int remaining_wav_data = max_wav_data - actual_wav_chunk_size;
|
|
||||||
|
|
||||||
while (remaining_wav_data > 0)
|
|
||||||
{
|
|
||||||
int true_max_chunk_size = Math.Min(remaining_wav_data + 22, si_buffer_size);
|
|
||||||
int true_wav_data_size = true_max_chunk_size - 22;
|
|
||||||
|
|
||||||
WriteMxChHeader(out_stream, true_max_chunk_size - 8, flags, wav_id, millis, true_wav_data_size);
|
|
||||||
|
|
||||||
byte[] joining_wav_bytes = new byte[true_wav_data_size];
|
|
||||||
wav_str.Read(joining_wav_bytes, 0, true_wav_data_size);
|
|
||||||
out_stream.Write(joining_wav_bytes, 0, true_wav_data_size);
|
|
||||||
|
|
||||||
remaining_wav_data -= true_wav_data_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
millis += 1000;
|
|
||||||
|
|
||||||
// If we have FLC chunks
|
|
||||||
/*
|
|
||||||
if (flc_id != -1 && wav_str.Position < wav_end)
|
|
||||||
{
|
|
||||||
// Write 10 FLC chunks
|
|
||||||
for (int i=0;i<10;i++)
|
|
||||||
{
|
|
||||||
int flc_data_index = ids.IndexOf(flc_id);
|
|
||||||
int flc_write_ind = (flc_write_count*2) % data[flc_data_index].Count;
|
|
||||||
|
|
||||||
//if (flc_write_ind >= data[flc_data_index].Count)
|
|
||||||
//{
|
|
||||||
//break;
|
|
||||||
//}
|
|
||||||
|
|
||||||
long remainder = si_buffer_size - (out_stream.Position % si_buffer_size);
|
|
||||||
|
|
||||||
if (data[flc_data_index][flc_write_ind].Length > remainder)
|
|
||||||
{
|
|
||||||
WriteZeroes(out_stream, (int)remainder);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_stream.Write(data[flc_data_index][flc_write_ind], 0, data[flc_data_index][flc_write_ind].Length);
|
|
||||||
|
|
||||||
flc_write_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine(wav_fn + " doesn't exist. Make sure you 'extract' all files from the SI file before trying to 'insert'.");
|
wav_file = replace_src[replace_index];
|
||||||
return;
|
}
|
||||||
|
|
||||||
|
using (FileStream wav_str = new FileStream(wav_file, FileMode.Open, FileAccess.Read))
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Inserting " + wav_fn);
|
||||||
|
|
||||||
|
// Ignore first part of the wav header
|
||||||
|
if (!SeekUntil(wav_str, "WAVE") || !SeekUntil(wav_str, "fmt "))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid file at " + wav_fn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wav_str.Position += 4;
|
||||||
|
|
||||||
|
long old_pos = out_stream.Position;
|
||||||
|
out_stream.Position = wave_header_pos;
|
||||||
|
|
||||||
|
// Copy WAV header data
|
||||||
|
byte[] wav_header = new byte[16];
|
||||||
|
wav_str.Read(wav_header, 0, wav_header.Length);
|
||||||
|
out_stream.Write(wav_header, 0, wav_header.Length);
|
||||||
|
|
||||||
|
// Total data size in MxCh is the WAV's data size + 4
|
||||||
|
if (!SeekUntil(wav_str, "data"))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid file at " + wav_fn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte[] data_size_bytes = new byte[4];
|
||||||
|
wav_str.Read(data_size_bytes, 0, data_size_bytes.Length);
|
||||||
|
Int32 wav_data_size = (BitConverter.ToInt32(data_size_bytes, 0));
|
||||||
|
data_size_bytes = BitConverter.GetBytes((Int32)(wav_data_size + 4));
|
||||||
|
out_stream.Write(data_size_bytes, 0, data_size_bytes.Length);
|
||||||
|
long wav_end = wav_str.Position + wav_data_size;
|
||||||
|
|
||||||
|
// Re-skip latter 4 bytes of MxCh header
|
||||||
|
out_stream.Position = old_pos;
|
||||||
|
|
||||||
|
// Write first FLC chunk
|
||||||
|
/*
|
||||||
|
if (flc_id != -1)
|
||||||
|
{
|
||||||
|
int index = ids.IndexOf(flc_id);
|
||||||
|
int remainder = (int)(si_buffer_size - (out_stream.Position % si_buffer_size));
|
||||||
|
|
||||||
|
if (data[index][0].Length > remainder)
|
||||||
|
{
|
||||||
|
WriteZeroes(out_stream, (int)remainder);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_stream.Write(data[index][0], 0, data[index][0].Length);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Loop over data in WAV
|
||||||
|
// Write out WAV file chunking along the way
|
||||||
|
int max_wav_data = BitConverter.ToInt32(wav_header, 8);
|
||||||
|
int max_chunk_size = max_wav_data + 22;
|
||||||
|
while (wav_str.Position < wav_end)
|
||||||
|
{
|
||||||
|
// SI files are also buffered at 20000h (or 131072 bytes), so we can only write that much at a time
|
||||||
|
Int32 this_chunk_max = (Int32)Math.Min(max_chunk_size, si_buffer_size - (out_stream.Position % si_buffer_size));
|
||||||
|
|
||||||
|
if (this_chunk_max <= 22)
|
||||||
|
{
|
||||||
|
WriteZeroes(out_stream, this_chunk_max);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Int16 flags = 0;
|
||||||
|
if (this_chunk_max < max_chunk_size)
|
||||||
|
{
|
||||||
|
flags = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_chunk_max -= 8;
|
||||||
|
|
||||||
|
int actual_wav_chunk_size = this_chunk_max - 14;
|
||||||
|
|
||||||
|
int actual_data_chunk_size = max_wav_data;
|
||||||
|
|
||||||
|
if (wav_str.Position + actual_wav_chunk_size > wav_end)
|
||||||
|
{
|
||||||
|
flags = 0;
|
||||||
|
actual_wav_chunk_size = (int)(wav_end - wav_str.Position);
|
||||||
|
this_chunk_max = actual_wav_chunk_size + 14;
|
||||||
|
actual_data_chunk_size = actual_wav_chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteMxChHeader(out_stream, this_chunk_max, flags, wav_id, millis, actual_data_chunk_size);
|
||||||
|
|
||||||
|
byte[] wav_bytes = new byte[actual_wav_chunk_size];
|
||||||
|
wav_str.Read(wav_bytes, 0, actual_wav_chunk_size);
|
||||||
|
out_stream.Write(wav_bytes, 0, actual_wav_chunk_size);
|
||||||
|
|
||||||
|
// If we had to split this chunk in half, write the second half now
|
||||||
|
if (flags == 16)
|
||||||
|
{
|
||||||
|
int remaining_wav_data = max_wav_data - actual_wav_chunk_size;
|
||||||
|
|
||||||
|
while (remaining_wav_data > 0)
|
||||||
|
{
|
||||||
|
int true_max_chunk_size = Math.Min(remaining_wav_data + 22, si_buffer_size);
|
||||||
|
int true_wav_data_size = true_max_chunk_size - 22;
|
||||||
|
|
||||||
|
WriteMxChHeader(out_stream, true_max_chunk_size - 8, flags, wav_id, millis, true_wav_data_size);
|
||||||
|
|
||||||
|
byte[] joining_wav_bytes = new byte[true_wav_data_size];
|
||||||
|
wav_str.Read(joining_wav_bytes, 0, true_wav_data_size);
|
||||||
|
out_stream.Write(joining_wav_bytes, 0, true_wav_data_size);
|
||||||
|
|
||||||
|
remaining_wav_data -= true_wav_data_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
millis += 1000;
|
||||||
|
|
||||||
|
// If we have FLC chunks
|
||||||
|
/*
|
||||||
|
if (flc_id != -1 && wav_str.Position < wav_end)
|
||||||
|
{
|
||||||
|
// Write 10 FLC chunks
|
||||||
|
for (int i=0;i<10;i++)
|
||||||
|
{
|
||||||
|
int flc_data_index = ids.IndexOf(flc_id);
|
||||||
|
int flc_write_ind = (flc_write_count*2) % data[flc_data_index].Count;
|
||||||
|
|
||||||
|
//if (flc_write_ind >= data[flc_data_index].Count)
|
||||||
|
//{
|
||||||
|
//break;
|
||||||
|
//}
|
||||||
|
|
||||||
|
long remainder = si_buffer_size - (out_stream.Position % si_buffer_size);
|
||||||
|
|
||||||
|
if (data[flc_data_index][flc_write_ind].Length > remainder)
|
||||||
|
{
|
||||||
|
WriteZeroes(out_stream, (int)remainder);
|
||||||
|
}
|
||||||
|
|
||||||
|
out_stream.Write(data[flc_data_index][flc_write_ind], 0, data[flc_data_index][flc_write_ind].Length);
|
||||||
|
|
||||||
|
flc_write_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write ending chunk
|
// Write ending chunk
|
||||||
|
@ -948,17 +986,39 @@ namespace Rebuilder
|
||||||
|
|
||||||
public int ReplaceCount()
|
public int ReplaceCount()
|
||||||
{
|
{
|
||||||
int count = 0;
|
return replace_src.Count;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < filenames.Count; i++)
|
public void LoadData(XmlReader stream)
|
||||||
|
{
|
||||||
|
if (stream.IsEmptyElement)
|
||||||
{
|
{
|
||||||
if (table.Rows[i].Cells[1].Value.ToString() != filenames[i])
|
return;
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
string tag = stream.Name;
|
||||||
|
|
||||||
|
while (stream.Read() && !(stream.Name == tag && stream.NodeType == XmlNodeType.EndElement))
|
||||||
|
{
|
||||||
|
if (stream.IsStartElement() && stream.Name == "replace")
|
||||||
|
{
|
||||||
|
replace_dst.Add(stream.GetAttribute("original"));
|
||||||
|
|
||||||
|
stream.Read();
|
||||||
|
replace_src.Add(stream.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveData(XmlWriter stream)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < replace_src.Count; i++)
|
||||||
|
{
|
||||||
|
stream.WriteStartElement("replace");
|
||||||
|
stream.WriteAttributeString("original", replace_dst[i]);
|
||||||
|
stream.WriteString(replace_src[i]);
|
||||||
|
stream.WriteEndElement(); // replace
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.IO;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace Rebuilder
|
namespace Rebuilder
|
||||||
{
|
{
|
||||||
|
@ -258,6 +259,9 @@ namespace Rebuilder
|
||||||
ResumeLayout(true);
|
ResumeLayout(true);
|
||||||
|
|
||||||
CenterToScreen();
|
CenterToScreen();
|
||||||
|
|
||||||
|
Shown += new EventHandler(OnStartup);
|
||||||
|
FormClosing += new FormClosingEventHandler(OnClosing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Write(FileStream fs, byte[] bytes, long pos = -1)
|
private void Write(FileStream fs, byte[] bytes, long pos = -1)
|
||||||
|
@ -345,7 +349,7 @@ namespace Rebuilder
|
||||||
// Redirect JUKEBOX.SI if we're inserting music
|
// Redirect JUKEBOX.SI if we're inserting music
|
||||||
if (music_injector.ReplaceCount() > 0)
|
if (music_injector.ReplaceCount() > 0)
|
||||||
{
|
{
|
||||||
Uri uri1 = new Uri(dir + "/jukebox");
|
Uri uri1 = new Uri(Path.GetTempPath() + "jukebox");
|
||||||
Uri uri2 = new Uri(source_dir + "/ISLE.EXE");
|
Uri uri2 = new Uri(source_dir + "/ISLE.EXE");
|
||||||
Uri relative = uri2.MakeRelativeUri(uri1);
|
Uri relative = uri2.MakeRelativeUri(uri1);
|
||||||
string jukebox_path = "\\" + relative.ToString().Replace("/", "\\");
|
string jukebox_path = "\\" + relative.ToString().Replace("/", "\\");
|
||||||
|
@ -386,24 +390,43 @@ namespace Rebuilder
|
||||||
incompatibilities += redirect_saves.Text + "\n";
|
incompatibilities += redirect_saves.Text + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (RegistryKey src = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Mindscape\\LEGO Island", false))
|
RegistryKey src = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Mindscape\\LEGO Island", false);
|
||||||
using (RegistryKey dst = Registry.CurrentUser.CreateSubKey("Software\\Mindscape\\LEGO Island"))
|
if (src == null)
|
||||||
{
|
{
|
||||||
// Copy config data from HKLM to HKCU
|
src = Registry.LocalMachine.OpenSubKey("SOFTWARE\\WOW6432Node\\Mindscape\\LEGO Island", false);
|
||||||
CopyRegistryKey(src, dst);
|
}
|
||||||
|
|
||||||
// Set full screen value
|
if (src == null)
|
||||||
dst.SetValue("Full Screen", run_fullscreen.Checked ? "YES" : "NO");
|
{
|
||||||
|
if (MessageBox.Show("Failed to find LEGO Island's registry entries. Some patches may fail. Do you wish to continue?",
|
||||||
// Redirect save path
|
"Failed to find registry keys",
|
||||||
if (redirect_saves.Checked)
|
MessageBoxButtons.YesNo,
|
||||||
|
MessageBoxIcon.Warning) == DialogResult.No)
|
||||||
{
|
{
|
||||||
string new_save_dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\LEGO Island\\";
|
return false;
|
||||||
Directory.CreateDirectory(new_save_dir);
|
|
||||||
dst.SetValue("savepath", new_save_dir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (RegistryKey dst = Registry.CurrentUser.CreateSubKey("Software\\Mindscape\\LEGO Island"))
|
||||||
|
{
|
||||||
|
// Copy config data from HKLM to HKCU
|
||||||
|
CopyRegistryKey(src, dst);
|
||||||
|
|
||||||
|
// Set full screen value
|
||||||
|
dst.SetValue("Full Screen", run_fullscreen.Checked ? "YES" : "NO");
|
||||||
|
|
||||||
|
// Redirect save path
|
||||||
|
if (redirect_saves.Checked)
|
||||||
|
{
|
||||||
|
string new_save_dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\LEGO Island\\";
|
||||||
|
Directory.CreateDirectory(new_save_dir);
|
||||||
|
dst.SetValue("savepath", new_save_dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return string.IsNullOrEmpty(incompatibilities) || IncompatibleBuildMessage(incompatibilities);
|
return string.IsNullOrEmpty(incompatibilities) || IncompatibleBuildMessage(incompatibilities);
|
||||||
}
|
}
|
||||||
|
@ -471,7 +494,7 @@ namespace Rebuilder
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string temp_path = Path.GetTempPath() + "lire";
|
string temp_path = Path.GetTempPath() + "LEGOIslandRebuilder";
|
||||||
Directory.CreateDirectory(temp_path);
|
Directory.CreateDirectory(temp_path);
|
||||||
|
|
||||||
string dir = "";
|
string dir = "";
|
||||||
|
@ -544,21 +567,24 @@ namespace Rebuilder
|
||||||
// Perform music insertion if necessary
|
// Perform music insertion if necessary
|
||||||
if (music_injector.ReplaceCount() > 0)
|
if (music_injector.ReplaceCount() > 0)
|
||||||
{
|
{
|
||||||
music_injector.Insert(temp_path + "/JUKEBOX.SI");
|
music_injector.Insert(Path.GetTempPath() + "JUKEBOX.SI");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set new EXE's compatibility mode to 256-colors
|
// Set new EXE's compatibility mode to 256-colors
|
||||||
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", true))
|
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", true))
|
||||||
{
|
{
|
||||||
key.CreateSubKey(temp_path + "\\ISLE.EXE");
|
if (key != null)
|
||||||
|
{
|
||||||
|
key.CreateSubKey(temp_path + "\\ISLE.EXE");
|
||||||
|
|
||||||
if (run_fullscreen.Checked)
|
if (run_fullscreen.Checked)
|
||||||
{
|
{
|
||||||
key.SetValue(temp_path + "\\ISLE.EXE", "HIGHDPIAWARE DWM8And16BitMitigation");
|
key.SetValue(temp_path + "\\ISLE.EXE", "HIGHDPIAWARE DWM8And16BitMitigation");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
key.SetValue(temp_path + "\\ISLE.EXE", "HIGHDPIAWARE DWM8And16BitMitigation 256COLOR");
|
key.SetValue(temp_path + "\\ISLE.EXE", "HIGHDPIAWARE DWM8And16BitMitigation 256COLOR");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,6 +617,145 @@ namespace Rebuilder
|
||||||
Process.Start("http://www.itsmattkc.com/");
|
Process.Start("http://www.itsmattkc.com/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetSettingsPath()
|
||||||
|
{
|
||||||
|
string settings_path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/LEGOIslandRebuilder/settings.xml";
|
||||||
|
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(settings_path));
|
||||||
|
|
||||||
|
return settings_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStartup(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// Load settings
|
||||||
|
string settings_path = GetSettingsPath();
|
||||||
|
|
||||||
|
if (File.Exists(settings_path))
|
||||||
|
{
|
||||||
|
XmlReader stream = XmlReader.Create(settings_path);
|
||||||
|
|
||||||
|
while (stream.Read())
|
||||||
|
{
|
||||||
|
if (stream.NodeType == XmlNodeType.Element && stream.IsStartElement())
|
||||||
|
{
|
||||||
|
if (stream.Name == "turnspeed")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
turn_speed_control.Value = decimal.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "movespeed")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
movement_speed_control.Value = decimal.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "fullscreen")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
run_fullscreen.Checked = bool.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "stayactive")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
stay_active_when_window_is_defocused.Checked = bool.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "redirecttoappdata")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
redirect_saves.Checked = bool.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "showadvanced")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
advanced_button.Checked = bool.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "overrideres")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
override_resolution.Checked = bool.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "overridereswidth")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
res_width.Value = decimal.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "overrideresheight")
|
||||||
|
{
|
||||||
|
stream.Read();
|
||||||
|
res_height.Value = decimal.Parse(stream.Value);
|
||||||
|
}
|
||||||
|
else if (stream.Name == "musicinjection")
|
||||||
|
{
|
||||||
|
music_injector.LoadData(stream);
|
||||||
|
UpdateMusicInjectorBtnText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
// Save settings
|
||||||
|
|
||||||
|
string settings_path = GetSettingsPath();
|
||||||
|
|
||||||
|
XmlWriter stream = XmlWriter.Create(settings_path);
|
||||||
|
|
||||||
|
stream.WriteStartDocument();
|
||||||
|
|
||||||
|
stream.WriteStartElement("settings");
|
||||||
|
|
||||||
|
stream.WriteStartElement("turnspeed");
|
||||||
|
stream.WriteString(turn_speed_control.Value.ToString());
|
||||||
|
stream.WriteEndElement(); // turnspeed
|
||||||
|
|
||||||
|
stream.WriteStartElement("movespeed");
|
||||||
|
stream.WriteString(movement_speed_control.Value.ToString());
|
||||||
|
stream.WriteEndElement(); // movespeed
|
||||||
|
|
||||||
|
stream.WriteStartElement("fullscreen");
|
||||||
|
stream.WriteString(run_fullscreen.Checked.ToString());
|
||||||
|
stream.WriteEndElement(); // fullscreen
|
||||||
|
|
||||||
|
stream.WriteStartElement("stayactive");
|
||||||
|
stream.WriteString(stay_active_when_window_is_defocused.Checked.ToString());
|
||||||
|
stream.WriteEndElement(); // stayactive
|
||||||
|
|
||||||
|
stream.WriteStartElement("redirecttoappdata");
|
||||||
|
stream.WriteString(redirect_saves.Checked.ToString());
|
||||||
|
stream.WriteEndElement(); // redirecttoappdata
|
||||||
|
|
||||||
|
stream.WriteStartElement("showadvanced");
|
||||||
|
stream.WriteString(advanced_button.Checked.ToString());
|
||||||
|
stream.WriteEndElement(); // showadvanced
|
||||||
|
|
||||||
|
stream.WriteStartElement("overrideres");
|
||||||
|
stream.WriteString(override_resolution.Checked.ToString());
|
||||||
|
stream.WriteEndElement(); // overrideres
|
||||||
|
|
||||||
|
stream.WriteStartElement("overridereswidth");
|
||||||
|
stream.WriteString(res_width.Value.ToString());
|
||||||
|
stream.WriteEndElement(); // overridereswidth
|
||||||
|
|
||||||
|
stream.WriteStartElement("overrideresheight");
|
||||||
|
stream.WriteString(res_height.Value.ToString());
|
||||||
|
stream.WriteEndElement(); // overrideresheight
|
||||||
|
|
||||||
|
stream.WriteStartElement("musicinjection");
|
||||||
|
music_injector.SaveData(stream);
|
||||||
|
stream.WriteEndElement(); // musicinjection
|
||||||
|
|
||||||
|
stream.WriteEndElement(); // settings
|
||||||
|
|
||||||
|
stream.WriteEndDocument();
|
||||||
|
|
||||||
|
stream.Close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
static void Main()
|
static void Main()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue