diff --git a/TrueCraft.Client/Content/default-pack.png b/TrueCraft.Client/Content/default-pack.png
new file mode 100644
index 0000000..cf893db
Binary files /dev/null and b/TrueCraft.Client/Content/default-pack.png differ
diff --git a/TrueCraft.Client/Content/default-pack.txt b/TrueCraft.Client/Content/default-pack.txt
new file mode 100644
index 0000000..b90cfbc
--- /dev/null
+++ b/TrueCraft.Client/Content/default-pack.txt
@@ -0,0 +1 @@
+No description available.
\ No newline at end of file
diff --git a/TrueCraft.Client/Rendering/Mesh.cs b/TrueCraft.Client/Rendering/Mesh.cs
index 91a8109..43d8cd8 100644
--- a/TrueCraft.Client/Rendering/Mesh.cs
+++ b/TrueCraft.Client/Rendering/Mesh.cs
@@ -38,7 +38,7 @@ namespace TrueCraft.Client.Rendering
lock (_syncLock)
{
_vertices = new VertexBuffer(_graphicsDevice, VertexPositionNormalTexture.VertexDeclaration,
- value.Length, BufferUsage.WriteOnly);
+ (value.Length + 1), BufferUsage.WriteOnly);
_vertices.SetData(value);
}
@@ -119,7 +119,7 @@ namespace TrueCraft.Client.Rendering
_indices[index].Dispose();
_indices[index] = new IndexBuffer(_graphicsDevice, typeof(int),
- indices.Length, BufferUsage.WriteOnly);
+ (indices.Length + 1), BufferUsage.WriteOnly);
_indices[index].SetData(indices);
}
}
diff --git a/TrueCraft.Client/Rendering/TextureMapper.cs b/TrueCraft.Client/Rendering/TextureMapper.cs
index aac19de..4f2e162 100644
--- a/TrueCraft.Client/Rendering/TextureMapper.cs
+++ b/TrueCraft.Client/Rendering/TextureMapper.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TrueCraft.Core;
+using Ionic.Zip;
namespace TrueCraft.Client.Rendering
{
@@ -34,7 +35,7 @@ namespace TrueCraft.Client.Rendering
///
///
///
- public TexturePack TexturePack { get; private set; }
+ private GraphicsDevice Device { get; set; }
///
///
@@ -50,38 +51,54 @@ namespace TrueCraft.Client.Rendering
///
///
///
- ///
- public TextureMapper(GraphicsDevice graphicsDevice, TexturePack texturePack = null)
+ public TextureMapper(GraphicsDevice graphicsDevice)
{
if (graphicsDevice == null)
throw new ArgumentException();
- TexturePack = texturePack;
+ Device = graphicsDevice;
Customs = new Dictionary();
IsDisposed = false;
-
- if (TexturePack != null)
- LoadTextures(graphicsDevice);
}
///
///
///
- ///
- private void LoadTextures(GraphicsDevice graphicsDevice)
+ ///
+ ///
+ public void AddTexture(string key, Texture2D texture)
{
- foreach (var entry in TexturePack.Archive.Entries)
+ if (string.IsNullOrEmpty(key) || (texture == null))
+ throw new ArgumentException();
+
+ if (Customs.ContainsKey(key))
+ Customs[key] = texture;
+ else
+ Customs.Add(key, texture);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void AddTexturePack(TexturePack texturePack)
+ {
+ if (texturePack == null)
+ return;
+
+ // Make sure to 'silence' errors loading custom texture packs;
+ // they're unimportant as we can just use default textures.
+ try
{
- // Make sure to 'silence' errors loading custom texture packs;
- // they're unimportant as we can just use default textures.
- try
+ var archive = new ZipFile(Path.Combine(TexturePack.TexturePackPath, texturePack.Name));
+ foreach (var entry in archive.Entries)
{
var key = entry.FileName;
using (var stream = entry.OpenReader())
- Customs.Add(key, Texture2D.FromStream(graphicsDevice, stream));
+ AddTexture(key, Texture2D.FromStream(Device, stream));
}
- catch { }
}
+ catch { return; }
}
///
@@ -93,6 +110,9 @@ namespace TrueCraft.Client.Rendering
{
Texture2D result = null;
TryGetTexture(key, out result);
+ if (result == null)
+ throw new InvalidOperationException();
+
return result;
}
@@ -104,23 +124,19 @@ namespace TrueCraft.Client.Rendering
///
public bool TryGetTexture(string key, out Texture2D texture)
{
- // -> Try to load from external texture pack
- // -> Try to load from default texture pack
- // -> Fail gracefully
-
if (string.IsNullOrEmpty(key))
throw new ArgumentException();
bool hasTexture = false;
texture = null;
- if (TexturePack != null)
- {
- Texture2D customTexture = null;
- var inCustom = Customs.TryGetValue(key, out customTexture);
- texture = (inCustom) ? customTexture : null;
- hasTexture = inCustom;
- }
+ // -> Try to load from custom textures
+ Texture2D customTexture = null;
+ var inCustom = Customs.TryGetValue(key, out customTexture);
+ texture = (inCustom) ? customTexture : null;
+ hasTexture = inCustom;
+
+ // -> Try to load from default textures
if (!hasTexture)
{
Texture2D defaultTexture = null;
@@ -129,6 +145,7 @@ namespace TrueCraft.Client.Rendering
hasTexture = inDefault;
}
+ // -> Fail gracefully
return hasTexture;
}
@@ -145,7 +162,7 @@ namespace TrueCraft.Client.Rendering
Customs.Clear();
Customs = null;
- TexturePack = null;
+ Device = null;
IsDisposed = true;
}
}
diff --git a/TrueCraft.Client/Rendering/TexturePackExtensions.cs b/TrueCraft.Client/Rendering/TexturePackExtensions.cs
deleted file mode 100644
index 7fa81ea..0000000
--- a/TrueCraft.Client/Rendering/TexturePackExtensions.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Microsoft.Xna.Framework.Graphics;
-using System;
-using TrueCraft.Core;
-using Ionic.Zip;
-
-namespace TrueCraft.Client.Rendering
-{
- public static class TexturePackExtensions
- {
- ///
- ///
- ///
- ///
- ///
- ///
- public static Texture2D GetTexture(this TexturePack instance, GraphicsDevice graphicsDevice, string entryName)
- {
- ZipEntry entry = null;
- foreach (var item in instance.Archive.Entries)
- {
- if (item.FileName == entryName)
- {
- entry = item;
- break;
- }
- }
-
- if (entry == null)
- return null;
-
- Texture2D texture = null;
- using (var reader = entry.OpenReader())
- texture = Texture2D.FromStream(graphicsDevice, reader);
- return texture;
- }
- }
-}
diff --git a/TrueCraft.Client/TrueCraft.Client.csproj b/TrueCraft.Client/TrueCraft.Client.csproj
index 1c043c6..b37fc48 100644
--- a/TrueCraft.Client/TrueCraft.Client.csproj
+++ b/TrueCraft.Client/TrueCraft.Client.csproj
@@ -68,8 +68,6 @@
..\lib\Ionic.Zip.Reduced.dll
-
-
@@ -89,7 +87,6 @@
-
@@ -147,6 +144,12 @@
+
+ PreserveNewest
+
+
+ PreserveNewest
+
PreserveNewest
diff --git a/TrueCraft.Client/TrueCraftGame.cs b/TrueCraft.Client/TrueCraftGame.cs
index ad60449..b747325 100644
--- a/TrueCraft.Client/TrueCraftGame.cs
+++ b/TrueCraft.Client/TrueCraftGame.cs
@@ -42,7 +42,6 @@ namespace TrueCraft.Client
private MouseComponent MouseComponent { get; set; }
private GameTime GameTime { get; set; }
private Microsoft.Xna.Framework.Vector3 Delta { get; set; }
- private TexturePack TexturePack { get; set; }
private TextureMapper TextureMapper { get; set; }
private BasicEffect OpaqueEffect, TransparentEffect;
@@ -52,9 +51,9 @@ namespace TrueCraft.Client
Window.Title = "TrueCraft";
Content.RootDirectory = "Content";
Graphics = new GraphicsDeviceManager(this);
- Graphics.IsFullScreen = false;
- Graphics.PreferredBackBufferWidth = 1280;
- Graphics.PreferredBackBufferHeight = 720;
+ Graphics.IsFullScreen = UserSettings.Local.IsFullscreen;
+ Graphics.PreferredBackBufferWidth = UserSettings.Local.WindowResolution.Width;
+ Graphics.PreferredBackBufferHeight = UserSettings.Local.WindowResolution.Height;
Client = client;
EndPoint = endPoint;
NextPhysicsUpdate = DateTime.MinValue;
@@ -131,9 +130,9 @@ namespace TrueCraft.Client
TextureMapper.LoadDefaults(GraphicsDevice);
// Load any custom textures if needed.
- TexturePack = (UserSettings.Local.SelectedTexturePack != TexturePack.DefaultID) ?
- new TexturePack(UserSettings.Local.SelectedTexturePack) : null;
- TextureMapper = new TextureMapper(GraphicsDevice, TexturePack);
+ TextureMapper = new TextureMapper(GraphicsDevice);
+ if (UserSettings.Local.SelectedTexturePack != TexturePack.Default.Name)
+ TextureMapper.AddTexturePack(TexturePack.FromArchive(Path.Combine(TexturePack.TexturePackPath, UserSettings.Local.SelectedTexturePack)));
DejaVu = new FontRenderer(
new Font(Content, "Fonts/DejaVu", FontStyle.Regular),
diff --git a/TrueCraft.Core/TexturePack.cs b/TrueCraft.Core/TexturePack.cs
index 614fbf3..e9c735a 100644
--- a/TrueCraft.Core/TexturePack.cs
+++ b/TrueCraft.Core/TexturePack.cs
@@ -12,7 +12,18 @@ namespace TrueCraft.Core
///
///
///
- public const string DefaultID = "#Default";
+ public static readonly TexturePack Unknown = new TexturePack(
+ "?",
+ File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/default-pack.png")),
+ File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/default-pack.txt")));
+
+ ///
+ ///
+ ///
+ public static readonly TexturePack Default = new TexturePack(
+ "Default",
+ File.OpenRead(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/pack.png")),
+ File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/pack.txt")));
///
///
@@ -21,7 +32,7 @@ namespace TrueCraft.Core
{
get
{
- return System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
+ return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
".truecraft/texturepacks/");
}
}
@@ -29,7 +40,47 @@ namespace TrueCraft.Core
///
///
///
- public string Path { get; private set; }
+ ///
+ public static TexturePack FromArchive(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ throw new ArgumentException();
+
+ string description = Unknown.Description;
+ Stream image = Unknown.Image;
+ try
+ {
+ var archive = new ZipFile(path);
+ foreach (var entry in archive.Entries)
+ {
+ if (entry.FileName == "pack.txt")
+ {
+ using (var stream = entry.OpenReader())
+ {
+ using (var reader = new StreamReader(stream))
+ description = reader.ReadToEnd().TrimEnd('\n', '\r', ' ');
+ }
+ }
+ else if (entry.FileName == "pack.png")
+ {
+ using (var stream = entry.OpenReader())
+ {
+ var buffer = new byte[entry.UncompressedSize];
+ stream.Read(buffer, 0, buffer.Length);
+ image = new MemoryStream((int)entry.UncompressedSize);
+ image.Write(buffer, 0, buffer.Length);
+
+ // Fixes 'GLib.GException: Unrecognized image file format' on Linux.
+ image.Seek(0, SeekOrigin.Begin);
+ }
+ }
+ }
+ }
+ catch { return null; }
+
+ string name = new FileInfo(path).Name;
+ return new TexturePack(name, image, description);
+ }
///
///
@@ -39,7 +90,7 @@ namespace TrueCraft.Core
///
///
///
- public ZipFile Archive { get; private set; }
+ public Stream Image { get; private set; }
///
///
@@ -49,88 +100,14 @@ namespace TrueCraft.Core
///
///
///
- public MemoryStream Image { get; private set; }
-
- ///
- ///
- ///
- public bool IsCorrupt { get; private set; }
-
- ///
- ///
- ///
- public TexturePack()
+ ///
+ ///
+ ///
+ public TexturePack(string name, Stream image, string description)
{
- Path = TexturePack.DefaultID;
- Archive = new ZipFile();
- Name = "Default";
- }
-
- ///
- ///
- ///
- ///
- public TexturePack(string path)
- {
- if (string.IsNullOrEmpty(path) || !File.Exists(path))
- MakeDefault();
-
- Path = path;
- var fileInfo = new FileInfo(path); // A bit weird, but it works.
- Name = fileInfo.Name;
- try { Archive = new ZipFile(path); }
- catch { IsCorrupt = true; }
-
- GetPackInfo();
- }
-
- ///
- ///
- ///
- private void MakeDefault()
- {
- Path = TexturePack.DefaultID;
- Archive = new ZipFile();
- Name = "Default";
- Image = null;
- Description = null;
- }
-
- ///
- ///
- ///
- ///
- private void GetPackInfo()
- {
- try
- {
- foreach (var entry in Archive.Entries)
- {
- if (entry.FileName == "pack.txt")
- {
- using (var stream = entry.OpenReader())
- {
- using (var reader = new StreamReader(stream))
- Description = reader.ReadToEnd();
- }
- }
- else if (entry.FileName == "pack.png")
- {
- using (var stream = entry.OpenReader())
- {
- // Better way to do this?
- var buffer = new byte[entry.UncompressedSize];
- stream.Read(buffer, 0, buffer.Length);
- Image = new MemoryStream((int)entry.UncompressedSize);
- Image.Write(buffer, 0, buffer.Length);
-
- // Fixes 'GLib.GException: Unrecognized image file format' on Linux.
- Image.Seek(0, SeekOrigin.Begin);
- }
- }
- }
- }
- catch { IsCorrupt = true; }
+ Name = name;
+ Image = image;
+ Description = description;
}
}
}
diff --git a/TrueCraft.Core/UserSettings.cs b/TrueCraft.Core/UserSettings.cs
index 86a9543..8ead5d9 100644
--- a/TrueCraft.Core/UserSettings.cs
+++ b/TrueCraft.Core/UserSettings.cs
@@ -23,6 +23,8 @@ namespace TrueCraft.Core
public string LastIP { get; set; }
public string SelectedTexturePack { get; set; }
public FavoriteServer[] FavoriteServers { get; set; }
+ public bool IsFullscreen { get; set; }
+ public WindowResolution WindowResolution { get; set; }
public UserSettings()
{
@@ -30,8 +32,14 @@ namespace TrueCraft.Core
Username = "";
Password = "";
LastIP = "";
- SelectedTexturePack = TexturePack.DefaultID;
+ SelectedTexturePack = TexturePack.Default.Name;
FavoriteServers = new FavoriteServer[0];
+ IsFullscreen = false;
+ WindowResolution = new WindowResolution()
+ {
+ Width = 1280,
+ Height = 720
+ };
}
public void Load()
@@ -52,4 +60,40 @@ namespace TrueCraft.Core
public string Name { get; set; }
public string Address { get; set; }
}
+
+ public class WindowResolution
+ {
+ public static readonly WindowResolution[] Defaults =
+ new WindowResolution[]
+ {
+ // (from Wikipedia/other)
+ WindowResolution.FromString("800 x 600"), // SVGA
+ WindowResolution.FromString("960 x 640"), // DVGA
+ WindowResolution.FromString("1024 x 600"), // WSVGA
+ WindowResolution.FromString("1024 x 768"), // XGA
+ WindowResolution.FromString("1280 x 1024"), // SXGA
+ WindowResolution.FromString("1600 x 1200"), // UXGA
+ WindowResolution.FromString("1920 x 1080"), // big
+ WindowResolution.FromString("1920 x 1200"), // really big
+ WindowResolution.FromString("4096 x 2160"), // huge
+ };
+
+ public static WindowResolution FromString(string str)
+ {
+ var tmp = str.Split('x');
+ return new WindowResolution()
+ {
+ Width = int.Parse(tmp[0].Trim()),
+ Height = int.Parse(tmp[1].Trim())
+ };
+ }
+
+ public int Width { get; set; }
+ public int Height { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format("{0} x {1}", Width, Height);
+ }
+ }
}
\ No newline at end of file
diff --git a/TrueCraft.Launcher/Views/OptionView.cs b/TrueCraft.Launcher/Views/OptionView.cs
index 5442775..92d13b0 100644
--- a/TrueCraft.Launcher/Views/OptionView.cs
+++ b/TrueCraft.Launcher/Views/OptionView.cs
@@ -11,16 +11,14 @@ namespace TrueCraft.Launcher.Views
public class OptionView : VBox
{
public LauncherWindow Window { get; set; }
- public Image DefaultImage { get; set; }
- public string DefaultDescription { get; set; }
- public Image UnknownImage { get; set; }
- public string UnknownDescription { get; set; }
public Label OptionLabel { get; set; }
+ public Label ResolutionLabel { get; set; }
+ public ComboBox ResolutionComboBox { get; set; }
+ public CheckBox FullscreenCheckBox { get; set; }
public Label TexturePackLabel { get; set; }
public DataField TexturePackImageField { get; set; }
- public DataField TexturePackNameField { get; set; }
- public DataField TexturePackDescField { get; set; }
+ public DataField TexturePackTextField { get; set; }
public ListStore TexturePackStore { get; set; }
public ListView TexturePackListView { get; set; }
public Button OpenFolderButton { get; set; }
@@ -31,15 +29,6 @@ namespace TrueCraft.Launcher.Views
public OptionView(LauncherWindow window)
{
- DefaultImage = Image.FromFile(
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/pack.png"));
- DefaultDescription = File.ReadAllText(
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/pack.txt"));
- UnknownImage = Image.FromFile(
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/default-pack.png"));
- UnknownDescription = File.ReadAllText(
- Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content/default-pack.txt"));
-
_texturePacks = new List();
_lastTexturePack = null;
@@ -51,11 +40,40 @@ namespace TrueCraft.Launcher.Views
Font = Font.WithSize(16),
TextAlignment = Alignment.Center
};
+
+ ResolutionLabel = new Label("Select a resolution...");
+ ResolutionComboBox = new ComboBox();
+
+ int resolutionIndex = -1;
+ for (int i = 0; i < WindowResolution.Defaults.Length; i++)
+ {
+ ResolutionComboBox.Items.Add(WindowResolution.Defaults[i].ToString());
+
+ if (resolutionIndex == -1)
+ {
+ resolutionIndex =
+ ((WindowResolution.Defaults[i].Width == UserSettings.Local.WindowResolution.Width) &&
+ (WindowResolution.Defaults[i].Height == UserSettings.Local.WindowResolution.Height)) ? i : -1;
+ }
+ }
+
+ if (resolutionIndex == -1)
+ {
+ ResolutionComboBox.Items.Add(UserSettings.Local.WindowResolution.ToString());
+ resolutionIndex = ResolutionComboBox.Items.Count - 1;
+ }
+
+ ResolutionComboBox.SelectedIndex = resolutionIndex;
+ FullscreenCheckBox = new CheckBox()
+ {
+ Label = "Fullscreen mode",
+ State = (UserSettings.Local.IsFullscreen) ? CheckBoxState.On : CheckBoxState.Off
+ };
+
TexturePackLabel = new Label("Select a texture pack...");
TexturePackImageField = new DataField();
- TexturePackNameField = new DataField();
- TexturePackDescField = new DataField();
- TexturePackStore = new ListStore(TexturePackImageField, TexturePackNameField, TexturePackDescField);
+ TexturePackTextField = new DataField();
+ TexturePackStore = new ListStore(TexturePackImageField, TexturePackTextField);
TexturePackListView = new ListView
{
MinHeight = 200,
@@ -67,14 +85,27 @@ namespace TrueCraft.Launcher.Views
BackButton = new Button("Back");
TexturePackListView.Columns.Add("Image", TexturePackImageField);
- TexturePackListView.Columns.Add("Text", TexturePackNameField, TexturePackDescField);
+ TexturePackListView.Columns.Add("Text", TexturePackTextField);
+
+ ResolutionComboBox.SelectionChanged += (sender, e) =>
+ {
+ UserSettings.Local.WindowResolution =
+ WindowResolution.FromString(ResolutionComboBox.SelectedText);
+ UserSettings.Local.Save();
+ };
+
+ FullscreenCheckBox.Clicked += (sender, e) =>
+ {
+ UserSettings.Local.IsFullscreen = !UserSettings.Local.IsFullscreen;
+ UserSettings.Local.Save();
+ };
TexturePackListView.SelectionChanged += (sender, e) =>
{
var texturePack = _texturePacks[TexturePackListView.SelectedRow];
if (_lastTexturePack != texturePack)
{
- UserSettings.Local.SelectedTexturePack = texturePack.Path;
+ UserSettings.Local.SelectedTexturePack = texturePack.Name;
UserSettings.Local.Save();
}
};
@@ -94,6 +125,9 @@ namespace TrueCraft.Launcher.Views
LoadTexturePacks();
this.PackStart(OptionLabel);
+ this.PackStart(ResolutionLabel);
+ this.PackStart(ResolutionComboBox);
+ this.PackStart(FullscreenCheckBox);
this.PackStart(TexturePackLabel);
this.PackStart(TexturePackListView);
this.PackStart(OpenFolderButton);
@@ -103,9 +137,8 @@ namespace TrueCraft.Launcher.Views
private void LoadTexturePacks()
{
// We load the default texture pack specially.
- var defaultPack = new TexturePack();
- _texturePacks.Add(defaultPack);
- AddTexturePackRow(defaultPack);
+ _texturePacks.Add(TexturePack.Default);
+ AddTexturePackRow(TexturePack.Default);
// Make sure to create the texture pack directory if there is none.
if (!Directory.Exists(TexturePack.TexturePackPath))
@@ -117,8 +150,8 @@ namespace TrueCraft.Launcher.Views
if (!zip.EndsWith(".zip"))
continue;
- var texturePack = new TexturePack(zip);
- if (!texturePack.IsCorrupt)
+ var texturePack = TexturePack.FromArchive(zip);
+ if (texturePack != null)
{
_texturePacks.Add(texturePack);
AddTexturePackRow(texturePack);
@@ -129,19 +162,9 @@ namespace TrueCraft.Launcher.Views
private void AddTexturePackRow(TexturePack pack)
{
var row = TexturePackStore.AddRow();
- var isDefault = (pack.Path == TexturePack.DefaultID);
- if (isDefault)
- {
- TexturePackStore.SetValue(row, TexturePackImageField, DefaultImage.WithSize(IconSize.Medium));
- TexturePackStore.SetValue(row, TexturePackNameField, pack.Name);
- TexturePackStore.SetValue(row, TexturePackDescField, DefaultDescription);
- }
- else
- {
- TexturePackStore.SetValue(row, TexturePackImageField, (pack.Image == null) ? UnknownImage.WithSize(IconSize.Medium) : Image.FromStream(pack.Image).WithSize(IconSize.Medium));
- TexturePackStore.SetValue(row, TexturePackNameField, pack.Name);
- TexturePackStore.SetValue(row, TexturePackDescField, pack.Description ?? UnknownDescription);
- }
+
+ TexturePackStore.SetValue(row, TexturePackImageField, Image.FromStream(pack.Image).WithSize(IconSize.Medium));
+ TexturePackStore.SetValue(row, TexturePackTextField, pack.Name + "\r\n" + pack.Description);
}
}
}