Fixed known issues with texture pack loading

This commit is contained in:
William Moorehouse 2015-06-16 23:31:56 -04:00 committed by Drew DeVault
parent b799809d74
commit 3c2bb1a225
10 changed files with 197 additions and 20 deletions

View File

@ -0,0 +1,152 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TrueCraft.Core;
namespace TrueCraft.Client.Rendering
{
/// <summary>
/// Provides mappings from keys to textures.
/// </summary>
public sealed class TextureMapper : IDisposable
{
/// <summary>
///
/// </summary>
public static readonly IDictionary<string, Texture2D> Defaults =
new Dictionary<string, Texture2D>();
/// <summary>
///
/// </summary>
/// <param name="graphicsDevice"></param>
public static void LoadDefaults(GraphicsDevice graphicsDevice)
{
Defaults.Clear();
Defaults.Add("items.png", Texture2D.FromStream(graphicsDevice, File.OpenRead("Content/items.png")));
Defaults.Add("terrain.png", Texture2D.FromStream(graphicsDevice, File.OpenRead("Content/terrain.png")));
}
/// <summary>
///
/// </summary>
public TexturePack TexturePack { get; private set; }
/// <summary>
///
/// </summary>
private IDictionary<string, Texture2D> Customs { get; set; }
/// <summary>
///
/// </summary>
public bool IsDisposed { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="graphicsDevice"></param>
/// <param name="texturePack"></param>
public TextureMapper(GraphicsDevice graphicsDevice, TexturePack texturePack = null)
{
if (graphicsDevice == null)
throw new ArgumentException();
TexturePack = texturePack;
Customs = new Dictionary<string, Texture2D>();
IsDisposed = false;
if (TexturePack != null)
LoadTextures(graphicsDevice);
}
/// <summary>
///
/// </summary>
/// <param name="graphicsDevice"></param>
private void LoadTextures(GraphicsDevice graphicsDevice)
{
foreach (var entry in TexturePack.Archive.Entries)
{
// Make sure to 'silence' errors loading custom texture packs;
// they're unimportant as we can just use default textures.
try
{
var key = entry.FileName;
using (var stream = entry.OpenReader())
Customs.Add(key, Texture2D.FromStream(graphicsDevice, stream));
}
catch { }
}
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public Texture2D GetTexture(string key)
{
Texture2D result = null;
TryGetTexture(key, out result);
return result;
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="texture"></param>
/// <returns></returns>
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;
}
if (!hasTexture)
{
Texture2D defaultTexture = null;
var inDefault = TextureMapper.Defaults.TryGetValue(key, out defaultTexture);
texture = (inDefault) ? defaultTexture : null;
hasTexture = inDefault;
}
return hasTexture;
}
/// <summary>
///
/// </summary>
public void Dispose()
{
if (IsDisposed)
return;
foreach (var pair in Customs)
pair.Value.Dispose();
Customs.Clear();
Customs = null;
TexturePack = null;
IsDisposed = true;
}
}
}

View File

@ -114,6 +114,7 @@
<Compile Include="Rendering\FontRenderer.cs" />
<Compile Include="Rendering\FontStyle.cs" />
<Compile Include="Rendering\TexturePackExtensions.cs" />
<Compile Include="Rendering\TextureMapper.cs" />
<Compile Include="TrueCraftGame.cs" />
<Compile Include="MultiplayerClient.cs" />
<Compile Include="Handlers\PacketHandlers.cs" />

View File

@ -43,6 +43,7 @@ namespace TrueCraft.Client
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;
@ -126,7 +127,14 @@ namespace TrueCraft.Client
protected override void LoadContent()
{
TexturePack = new TexturePack(UserSettings.Local.SelectedTexturePack);
// Ensure we have default textures loaded.
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);
DejaVu = new FontRenderer(
new Font(Content, "Fonts/DejaVu", FontStyle.Regular),
new Font(Content, "Fonts/DejaVu", FontStyle.Bold),
@ -141,7 +149,7 @@ namespace TrueCraft.Client
OpaqueEffect.DirectionalLight1.SpecularColor = Color.Black.ToVector3();
OpaqueEffect.DirectionalLight2.SpecularColor = Color.Black.ToVector3();
OpaqueEffect.TextureEnabled = true;
OpaqueEffect.Texture = TexturePack.GetTexture(GraphicsDevice, "terrain.png");
OpaqueEffect.Texture = TextureMapper.GetTexture("terrain.png");
OpaqueEffect.FogEnabled = true;
OpaqueEffect.FogStart = 512f;
OpaqueEffect.FogEnd = 1000f;
@ -149,7 +157,7 @@ namespace TrueCraft.Client
TransparentEffect = new BasicEffect(GraphicsDevice);
TransparentEffect.TextureEnabled = true;
TransparentEffect.Texture = TexturePack.GetTexture(GraphicsDevice, "terrain.png");
TransparentEffect.Texture = TextureMapper.GetTexture("terrain.png");
base.LoadContent();
}

View File

@ -12,12 +12,7 @@ namespace TrueCraft.Core
/// <summary>
///
/// </summary>
public const string DescriptionFile = "pack.txt";
/// <summary>
///
/// </summary>
public const string ImageFile = "pack.png";
public const string DefaultID = "#Default";
/// <summary>
///
@ -56,6 +51,16 @@ namespace TrueCraft.Core
/// </summary>
public MemoryStream Image { get; private set; }
/// <summary>
///
/// </summary>
public TexturePack()
{
Path = TexturePack.DefaultID;
Name = "Default";
Archive = new ZipFile();
}
/// <summary>
///
/// </summary>
@ -65,7 +70,6 @@ namespace TrueCraft.Core
if (string.IsNullOrEmpty(path) || !File.Exists(path))
throw new ArgumentException();
Path = path;
var fileInfo = new FileInfo(path); // A bit weird, but it works.
Name = fileInfo.Name;
@ -82,7 +86,7 @@ namespace TrueCraft.Core
{
foreach (var entry in Archive.Entries)
{
if (entry.FileName == TexturePack.DescriptionFile)
if (entry.FileName == "pack.txt")
{
using (var stream = entry.OpenReader())
{
@ -90,7 +94,7 @@ namespace TrueCraft.Core
Description = reader.ReadToEnd();
}
}
else if (entry.FileName == TexturePack.ImageFile)
else if (entry.FileName == "pack.png")
{
using (var stream = entry.OpenReader())
{
@ -99,6 +103,9 @@ namespace TrueCraft.Core
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);
}
}
}

View File

@ -30,7 +30,7 @@ namespace TrueCraft.Core
Username = "";
Password = "";
LastIP = "";
SelectedTexturePack = "Default.zip";
SelectedTexturePack = TexturePack.DefaultID;
FavoriteServers = new FavoriteServer[0];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -0,0 +1 @@
No description available.

View File

@ -57,6 +57,12 @@
<Link>Xwt.Gtk.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\default-pack.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Content\default-pack.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Xwt.Gtk.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -85,9 +91,6 @@
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="Content\Default.zip">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Xwt.WPF.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@ -11,6 +11,8 @@ namespace TrueCraft.Launcher.Views
public class OptionView : VBox
{
public LauncherWindow Window { get; set; }
public Image DefaultImage { get; set; }
public string DefaultDescription { get; set; }
public Label OptionLabel { get; set; }
public Label TexturePackLabel { get; set; }
@ -27,6 +29,9 @@ namespace TrueCraft.Launcher.Views
public OptionView(LauncherWindow window)
{
DefaultImage = Image.FromFile("Content/default-pack.png");
DefaultDescription = File.ReadAllText("Content/default-pack.txt");
_texturePacks = new List<TexturePack>();
_lastTexturePack = null;
@ -89,8 +94,8 @@ namespace TrueCraft.Launcher.Views
private void LoadTexturePacks()
{
// We load Default.zip from a different directory.
var defaultPack = new TexturePack("Content/Default.zip");
// We load the default texture pack specially.
var defaultPack = new TexturePack();
_texturePacks.Add(defaultPack);
AddTexturePackRow(defaultPack);
@ -113,9 +118,9 @@ namespace TrueCraft.Launcher.Views
private void AddTexturePackRow(TexturePack pack)
{
var row = TexturePackStore.AddRow();
TexturePackStore.SetValue(row, TexturePackImageField, Image.FromStream(pack.Image).WithSize(IconSize.Medium));
TexturePackStore.SetValue(row, TexturePackImageField, (pack.Image == null) ? DefaultImage.WithSize(IconSize.Medium) : Image.FromStream(pack.Image).WithSize(IconSize.Medium));
TexturePackStore.SetValue(row, TexturePackNameField, pack.Name);
TexturePackStore.SetValue(row, TexturePackDescField, pack.Description);
TexturePackStore.SetValue(row, TexturePackDescField, pack.Description ?? DefaultDescription);
}
}
}