diff --git a/ACViewer/ACViewer.csproj b/ACViewer/ACViewer.csproj
index 177aaaa..cc33c1e 100644
--- a/ACViewer/ACViewer.csproj
+++ b/ACViewer/ACViewer.csproj
@@ -66,6 +66,8 @@
Designer
+
+
@@ -593,13 +595,18 @@
-
PreserveNewest
+
+
+
+
+
+
@@ -615,6 +622,9 @@
1.7.1
+
+ 13.0.1
+
diff --git a/ACViewer/Config/Config.cs b/ACViewer/Config/Config.cs
new file mode 100644
index 0000000..0a98b9a
--- /dev/null
+++ b/ACViewer/Config/Config.cs
@@ -0,0 +1,8 @@
+namespace ACViewer.Config
+{
+ public class Config
+ {
+ public string ACFolder { get; set; }
+ public bool AutomaticallyLoadDATsOnStartup { get; set; }
+ }
+}
diff --git a/ACViewer/Config/ConfigManager.cs b/ACViewer/Config/ConfigManager.cs
new file mode 100644
index 0000000..e568f3d
--- /dev/null
+++ b/ACViewer/Config/ConfigManager.cs
@@ -0,0 +1,51 @@
+using System;
+using System.IO;
+
+using Newtonsoft.Json;
+
+namespace ACViewer.Config
+{
+ public static class ConfigManager
+ {
+ private static string Filename = "ACViewer.json";
+
+ private static Config config;
+
+ public static Config Config
+ {
+ get
+ {
+ if (config == null)
+ config = new Config();
+
+ return config;
+ }
+ }
+
+ public static void SaveConfig()
+ {
+ var settings = new JsonSerializerSettings();
+ settings.Formatting = Formatting.Indented;
+
+ var json = JsonConvert.SerializeObject(config, settings);
+
+ File.WriteAllText(Filename, json);
+ }
+
+ public static void LoadConfig()
+ {
+ if (!File.Exists(Filename)) return;
+
+ var json = File.ReadAllText(Filename);
+
+ var _config = JsonConvert.DeserializeObject(json);
+
+ if (_config == null)
+ {
+ Console.WriteLine($"ConfigManager.LoadConfig() - failed to parse {Filename}");
+ return;
+ }
+ config = _config;
+ }
+ }
+}
diff --git a/ACViewer/Icons/HelpApplication_16x.png b/ACViewer/Icons/HelpApplication_16x.png
new file mode 100644
index 0000000..89be6c3
Binary files /dev/null and b/ACViewer/Icons/HelpApplication_16x.png differ
diff --git a/ACViewer/Icons/Question_16x.png b/ACViewer/Icons/Question_16x.png
new file mode 100644
index 0000000..07d43ab
Binary files /dev/null and b/ACViewer/Icons/Question_16x.png differ
diff --git a/ACViewer/Icons/Settings_16x.png b/ACViewer/Icons/Settings_16x.png
new file mode 100644
index 0000000..2e2a83d
Binary files /dev/null and b/ACViewer/Icons/Settings_16x.png differ
diff --git a/ACViewer/Icons/about.png b/ACViewer/Icons/about.png
new file mode 100644
index 0000000..777e7b0
Binary files /dev/null and b/ACViewer/Icons/about.png differ
diff --git a/ACViewer/Icons/help.png b/ACViewer/Icons/help.png
new file mode 100644
index 0000000..2c11cef
Binary files /dev/null and b/ACViewer/Icons/help.png differ
diff --git a/ACViewer/Icons/question-mark.png b/ACViewer/Icons/question-mark.png
new file mode 100644
index 0000000..734fefe
Binary files /dev/null and b/ACViewer/Icons/question-mark.png differ
diff --git a/ACViewer/Image.cs b/ACViewer/Image.cs
index 315070b..73ac6e5 100644
--- a/ACViewer/Image.cs
+++ b/ACViewer/Image.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
@@ -32,12 +33,10 @@ public static class Image
return colors;
}
- public static Texture2D GetTextureFromBitmap(GraphicsDevice device, Bitmap bitmap)
+ public static Texture2D GetTextureFromBitmap(GraphicsDevice device, string filename)
{
- var colors = GetColors(bitmap).ToArray();
- var texture = new Texture2D(device, bitmap.Width, bitmap.Height, false, SurfaceFormat.Color);
- texture.SetData(colors);
- return texture;
+ using (var fs = new FileStream(filename, FileMode.Open))
+ return Texture2D.FromStream(device, fs);
}
public static Texture2D GetTexture2DFromBitmap(GraphicsDevice device, Bitmap bitmap)
diff --git a/ACViewer/MapViewer.cs b/ACViewer/MapViewer.cs
index 4a34d5b..288a5a3 100644
--- a/ACViewer/MapViewer.cs
+++ b/ACViewer/MapViewer.cs
@@ -67,7 +67,7 @@ public MapViewer()
public void LoadContent()
{
- WorldMap = Image.GetTextureFromBitmap(GraphicsDevice, new Bitmap(new FileStream(@"Content\Images\highres.png", FileMode.Open)));
+ WorldMap = Image.GetTextureFromBitmap(GraphicsDevice, @"Content\Images\highres.png");
Highlight = new Texture2D(GraphicsDevice, 1, 1);
Highlight.SetData(new Microsoft.Xna.Framework.Color[1] { Microsoft.Xna.Framework.Color.Red });
diff --git a/ACViewer/View/About.xaml b/ACViewer/View/About.xaml
index f065211..97212ec 100644
--- a/ACViewer/View/About.xaml
+++ b/ACViewer/View/About.xaml
@@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ACViewer.View"
mc:Ignorable="d"
- Title="About" Height="170" Width="280" WindowStyle="ToolWindow" ResizeMode="NoResize">
+ Title="About" Height="170" Width="280" ResizeMode="NoResize" Icon="../Icons/Question_16x.png">
ACViewer - build 2022.01.28
diff --git a/ACViewer/View/FileExplorer.xaml.cs b/ACViewer/View/FileExplorer.xaml.cs
index 32eebd0..ce9566b 100644
--- a/ACViewer/View/FileExplorer.xaml.cs
+++ b/ACViewer/View/FileExplorer.xaml.cs
@@ -47,10 +47,7 @@ public partial class FileExplorer : UserControl, INotifyPropertyChanged
public List FileIDs
{
- get
- {
- return _fileIDs;
- }
+ get => _fileIDs;
set
{
_fileIDs = value;
@@ -177,7 +174,7 @@ private void FileType_SelectionChanged(object sender, SelectionChangedEventArgs
MainWindow.Status.WriteLine($"{selected.Name}s: {FileIDs.Count:N0}");
}
- private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
+ private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
diff --git a/ACViewer/View/MainMenu.xaml b/ACViewer/View/MainMenu.xaml
index 7b8d69f..6ed119b 100644
--- a/ACViewer/View/MainMenu.xaml
+++ b/ACViewer/View/MainMenu.xaml
@@ -16,7 +16,11 @@
@@ -43,8 +47,16 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/ACViewer/View/MainMenu.xaml.cs b/ACViewer/View/MainMenu.xaml.cs
index 0d8b686..8e048ea 100644
--- a/ACViewer/View/MainMenu.xaml.cs
+++ b/ACViewer/View/MainMenu.xaml.cs
@@ -1,5 +1,5 @@
-using System.Diagnostics;
-using System.Threading.Tasks;
+using System.ComponentModel;
+using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
@@ -42,29 +42,48 @@ public MainMenu()
Instance = this;
}
- private async void OpenFile_Click(object sender, RoutedEventArgs e)
+ private void OpenFile_Click(object sender, RoutedEventArgs e)
{
var openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "DAT files (*.dat)|*.dat|All files (*.*)|*.*";
- if (openFileDialog.ShowDialog() == true)
- {
- var files = openFileDialog.FileNames;
- if (files.Length < 1) return;
- var file = files[0];
- MainWindow.Status.WriteLine("Reading " + file);
+ var success = openFileDialog.ShowDialog();
+
+ if (success != true) return;
+
+ var filenames = openFileDialog.FileNames;
+
+ if (filenames.Length < 1) return;
+
+ var filename = filenames[0];
+
+ LoadDATs(filename);
+ }
+
+ public void LoadDATs(string filename)
+ {
+ MainWindow.Status.WriteLine("Reading " + filename);
+
+ var worker = new BackgroundWorker();
- await Task.Run(() => ReadDATFile(file));
+ worker.DoWork += (sender, doWorkEventArgs) =>
+ {
+ ReadDATFile(filename);
+ };
- //var cellFiles = DatManager.CellDat.AllFiles.Count;
- //var portalFiles = DatManager.PortalDat.AllFiles.Count;
+ worker.RunWorkerCompleted += (sender, runWorkerCompletedEventArgs) =>
+ {
+ /*var cellFiles = DatManager.CellDat.AllFiles.Count;
+ var portalFiles = DatManager.PortalDat.AllFiles.Count;
- //MainWindow.Status.WriteLine($"CellFiles={cellFiles}, PortalFiles={portalFiles}");
+ MainWindow.Status.WriteLine($"CellFiles={cellFiles}, PortalFiles={portalFiles}");*/
MainWindow.Status.WriteLine("Done");
GameView.PostInit();
- }
+ };
+
+ worker.RunWorkerAsync();
}
private void Export_Click(object sender, RoutedEventArgs e)
@@ -132,10 +151,10 @@ private void Export_Click(object sender, RoutedEventArgs e)
FileExport.ExportRaw(DatType.Portal, selectedFileID, saveFilename);
}
- public void ReadDATFile(string filename)
+ public static void ReadDATFile(string filename)
{
var fi = new System.IO.FileInfo(filename);
- var di = fi.Directory;
+ var di = fi.Attributes.HasFlag(System.IO.FileAttributes.Directory) ? new System.IO.DirectoryInfo(filename) : fi.Directory;
var loadCell = true;
DatManager.Initialize(di.FullName, true, loadCell);
@@ -144,6 +163,7 @@ public void ReadDATFile(string filename)
private void Options_Click(object sender, RoutedEventArgs e)
{
Options = new Options();
+ Options.WindowStartupLocation = WindowStartupLocation.CenterScreen;
Options.ShowDialog();
}
@@ -206,6 +226,7 @@ private void ShowLocation_Click(object sender, RoutedEventArgs e)
private void About_Click(object sender, RoutedEventArgs e)
{
var about = new About();
+ about.WindowStartupLocation = WindowStartupLocation.CenterScreen;
about.ShowDialog();
}
diff --git a/ACViewer/View/MainWindow.xaml.cs b/ACViewer/View/MainWindow.xaml.cs
index 202d52b..48d3d42 100644
--- a/ACViewer/View/MainWindow.xaml.cs
+++ b/ACViewer/View/MainWindow.xaml.cs
@@ -4,6 +4,8 @@
using System.Windows;
using System.Windows.Input;
+using ACViewer.Config;
+
namespace ACViewer.View
{
///
@@ -20,6 +22,20 @@ public MainWindow()
DataContext = this;
//WpfGame.UseASingleSharedGraphicsDevice = true;
+
+ LoadConfig();
+ }
+
+ private static Config.Config Config => ConfigManager.Config;
+
+ private static void LoadConfig()
+ {
+ ConfigManager.LoadConfig();
+
+ if (Config.AutomaticallyLoadDATsOnStartup)
+ {
+ MainMenu.Instance.LoadDATs(Config.ACFolder);
+ }
}
private DateTime lastUpdateTime { get; set; }
diff --git a/ACViewer/View/Options.xaml b/ACViewer/View/Options.xaml
index 653b65e..92b6e2e 100644
--- a/ACViewer/View/Options.xaml
+++ b/ACViewer/View/Options.xaml
@@ -5,8 +5,14 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ACViewer.View"
mc:Ignorable="d"
- Title="Options" Height="280" Width="380">
-
-
+ Title="Options" Height="156" Width="600" Icon="../Icons/Settings_16x.png">
+
+
+
+
+
+
+
+
diff --git a/ACViewer/View/Options.xaml.cs b/ACViewer/View/Options.xaml.cs
index a6f7eef..de45cae 100644
--- a/ACViewer/View/Options.xaml.cs
+++ b/ACViewer/View/Options.xaml.cs
@@ -1,15 +1,81 @@
-using System.Windows;
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows;
+//using System.Windows.Forms;
+
+using Microsoft.Win32;
+
+using ACViewer.Config;
namespace ACViewer.View
{
///
/// Interaction logic for Options.xaml
///
- public partial class Options : Window
+ public partial class Options : Window, INotifyPropertyChanged
{
+ public static Config.Config Config => ConfigManager.Config;
+
+ public string ACFolder
+ {
+ get => Config.ACFolder;
+ set
+ {
+ Config.ACFolder = value;
+ NotifyPropertyChanged("ACFolder");
+ }
+ }
+
+ public bool AutomaticallyLoadDATsOnStartup
+ {
+ get => Config.AutomaticallyLoadDATsOnStartup;
+ set
+ {
+ Config.AutomaticallyLoadDATsOnStartup = value;
+ NotifyPropertyChanged("AutomaticallyLoadACFolderOnStartup");
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
public Options()
{
InitializeComponent();
+
+ DataContext = this;
+ }
+
+ private void SelectACFolderButton_Click(object sender, RoutedEventArgs e)
+ {
+ //var folderBrowserDialog = new FolderBrowserDialog();
+ //folderBrowserDialog.ShowDialog();
+
+ var openFileDialog = new OpenFileDialog();
+
+ var success = openFileDialog.ShowDialog();
+
+ if (success != true) return;
+
+ var fi = new System.IO.FileInfo(openFileDialog.FileName);
+
+ ACFolder = fi.DirectoryName;
+ }
+
+ private void OKButton_Click(object sender, RoutedEventArgs e)
+ {
+ ConfigManager.SaveConfig();
+ Close();
+ }
+
+ private void CancelButton_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
diff --git a/ACViewer/WorldViewer.cs b/ACViewer/WorldViewer.cs
index 5242113..1361910 100644
--- a/ACViewer/WorldViewer.cs
+++ b/ACViewer/WorldViewer.cs
@@ -1,7 +1,5 @@
using System;
-using System.Collections.Generic;
using System.Diagnostics;
-using System.Threading;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
@@ -142,7 +140,7 @@ public async void LoadLandblocks(Vector2 startBlock, Vector2 endBlock)
var landblockID = centerX << 24 | centerY << 16 | 0xFFFF;
MainWindow.Status.WriteLine($"Loading {numBlocks} landblocks");
- await Task.Run(() => Thread.Sleep(50));
+ await Task.Delay(1);
//Landblocks = new Dictionary();
R_Landblock r_landblock = null;