make sure input bitmaps are 32bpp everywhere

This commit is contained in:
UnknownShadow200 2017-01-24 09:11:47 +11:00
parent c35692a8c6
commit 69d6bd228e
13 changed files with 70 additions and 88 deletions

View File

@ -86,8 +86,6 @@ namespace ClassicalSharp.Entities {
Bitmap bmp = (Bitmap)item.Data;
game.Graphics.DeleteTexture(ref TextureId);
if (!Platform.Is32Bpp(bmp))
game.Drawer2D.ConvertTo32Bpp(ref bmp);
uScale = 1; vScale = 1;
EnsurePow2(ref bmp);

View File

@ -38,6 +38,13 @@ namespace ClassicalSharp {
Graphics.MakeApiInfo();
ErrorHandler.AdditionalInfo = Graphics.ApiInfo;
#if ANDROID
Drawer2D = new CanvasDrawer2D(Graphics);
#else
Drawer2D = new GdiPlusDrawer2D(Graphics);
#endif
Options.Load();
Entities = new EntityList(this);
AcceptedUrls.Load();
@ -66,15 +73,9 @@ namespace ClassicalSharp {
BlockInfo.Init();
ModelCache = new ModelCache(this);
ModelCache.InitCache();
AsyncDownloader = AddComponent(new AsyncDownloader());
AsyncDownloader = AddComponent(new AsyncDownloader(Drawer2D));
Lighting = AddComponent(new BasicLighting());
#if ANDROID
Drawer2D = new CanvasDrawer2D(Graphics);
#else
Drawer2D = new GdiPlusDrawer2D(Graphics);
#endif
Drawer2D.UseBitmappedChat = ClassicMode || !Options.GetBool(OptionsKey.ArialChatFont, false);
Drawer2D.BlackTextShadows = Options.GetBool(OptionsKey.BlackTextShadows, false);

View File

@ -352,9 +352,8 @@ namespace ClassicalSharp {
/// <summary> Reads a bitmap from the stream (converting it to 32 bits per pixel if necessary),
/// and updates the native texture for it. </summary>
public bool UpdateTexture(ref int texId, string file, byte[] data, bool setSkinType) {
MemoryStream stream = new MemoryStream(data);
int maxSize = Graphics.MaxTextureDimensions;
using (Bitmap bmp = Platform.ReadBmp(stream)) {
using (Bitmap bmp = Platform.ReadBmp32Bpp(Drawer2D, data)) {
if (bmp.Width > maxSize || bmp.Height > maxSize) {
Chat.Add("&cUnable to use " + file + " from the texture pack.");
Chat.Add("&c Its size is (" + bmp.Width + "," + bmp.Height
@ -376,12 +375,7 @@ namespace ClassicalSharp {
throw new NotSupportedException("char.png has invalid dimensions");
}
if (!Platform.Is32Bpp(bmp)) {
using (Bitmap bmp32 = Drawer2D.ConvertTo32Bpp(bmp))
texId = Graphics.CreateTexture(bmp32, true);
} else {
texId = Graphics.CreateTexture(bmp, true);
}
texId = Graphics.CreateTexture(bmp, true);
return true;
}
}
@ -428,18 +422,13 @@ namespace ClassicalSharp {
void TextureChangedCore(object sender, TextureEventArgs e) {
byte[] data = e.Data;
if (e.Name == "terrain.png") {
MemoryStream stream = new MemoryStream(data);
Bitmap atlas = Platform.ReadBmp(stream);
Bitmap atlas = Platform.ReadBmp32Bpp(Drawer2D, data);
if (ChangeTerrainAtlas(atlas, null)) return;
atlas.Dispose();
} else if (e.Name == "cloud.png" || e.Name == "clouds.png") {
UpdateTexture(ref CloudsTex, e.Name, data, false);
} else if (e.Name == "default.png") {
MemoryStream stream = new MemoryStream(data);
Bitmap bmp = Platform.ReadBmp(stream);
if (!Platform.Is32Bpp(bmp))
Drawer2D.ConvertTo32Bpp(ref bmp);
Bitmap bmp = Platform.ReadBmp32Bpp(Drawer2D, data);
Drawer2D.SetFontBitmap(bmp);
Events.RaiseChatFontChanged();
}

View File

@ -22,15 +22,26 @@ namespace ClassicalSharp.Network {
readonly object downloadedLocker = new object();
Dictionary<string, DownloadedItem> downloaded = new Dictionary<string, DownloadedItem>();
string skinServer = null;
readonly IDrawer2D drawer;
public Request CurrentItem;
public int CurrentItemProgress = -3;
public IDrawer2D Drawer;
public AsyncDownloader(IDrawer2D drawer) { this.drawer = drawer; }
public AsyncDownloader() { }
public AsyncDownloader(string skinServer) { Init(skinServer); }
public void Init(Game game) { Init(game.skinServer); }
public void Ready(Game game) { }
public void Reset(Game game) {
lock (requestLocker)
requests.Clear();
handle.Set();
}
void Init(string skinServer) {
public void OnNewMap(Game game) { }
public void OnNewMapLoaded(Game game) { }
public void Init(string skinServer) {
this.skinServer = skinServer;
WebRequest.DefaultWebProxy = null;
@ -39,15 +50,7 @@ namespace ClassicalSharp.Network {
worker.IsBackground = true;
worker.Start();
}
public void Ready(Game game) { }
public void Reset(Game game) {
lock(requestLocker)
requests.Clear();
handle.Set();
}
public void OnNewMap(Game game) { }
public void OnNewMapLoaded(Game game) { }
/// <summary> Asynchronously downloads a skin. If 'skinName' points to the url then the skin is
/// downloaded from that url, otherwise it is downloaded from the url 'defaultSkinServer'/'skinName'.png </summary>
@ -100,7 +103,7 @@ namespace ClassicalSharp.Network {
void AddRequest(string url, bool priority, string identifier,
RequestType type, DateTime lastModified, string etag) {
lock(requestLocker) {
lock (requestLocker) {
Request request = new Request(url, identifier, type, lastModified, etag);
if (priority) {
requests.Insert(0, request);
@ -116,7 +119,7 @@ namespace ClassicalSharp.Network {
/// Note that this will *block** the calling thread as the method waits until the asynchronous
/// thread has exited the for loop. </summary>
public void Dispose() {
lock(requestLocker) {
lock (requestLocker) {
requests.Insert(0, null);
}
@ -248,7 +251,7 @@ namespace ClassicalSharp.Network {
object DownloadContent(Request request, HttpWebResponse response) {
if (request.Type == RequestType.Bitmap) {
MemoryStream data = DownloadBytes(response);
return Platform.ReadBmp(data);
return Platform.ReadBmp32Bpp(drawer, data);
} else if (request.Type == RequestType.String) {
MemoryStream data = DownloadBytes(response);
byte[] rawBuffer = data.GetBuffer();

View File

@ -11,7 +11,17 @@ using System.Drawing.Imaging;
namespace ClassicalSharp {
public static class Platform {
public static Bitmap ReadBmp32Bpp(IDrawer2D drawer, byte[] data) {
return ReadBmp32Bpp(drawer, new MemoryStream(data));
}
public static Bitmap ReadBmp32Bpp(IDrawer2D drawer, Stream src) {
Bitmap bmp = ReadBmp(src);
if (!Is32Bpp(bmp)) drawer.ConvertTo32Bpp(ref bmp);
return bmp;
}
public static Bitmap CreateBmp(int width, int height) {
#if !ANDROID
return new Bitmap(width, height);

View File

@ -40,8 +40,8 @@ namespace ClassicalSharp.Textures {
void TextureChanged(object sender, TextureEventArgs e) {
if (e.Name == "animations.png" || e.Name == "animation.png") {
MemoryStream stream = new MemoryStream(e.Data);
SetAtlas(Platform.ReadBmp(stream));
animBmp = Platform.ReadBmp32Bpp(game.Drawer2D, e.Data);
animsBuffer = new FastBitmap(animBmp, true, true);
} else if (e.Name == "animations.txt" || e.Name == "animation.txt") {
MemoryStream stream = new MemoryStream(e.Data);
StreamReader reader = new StreamReader(stream);
@ -51,14 +51,6 @@ namespace ClassicalSharp.Textures {
}
}
/// <summary> Sets the atlas bitmap that animation frames are contained within. </summary>
void SetAtlas(Bitmap bmp) {
if (!Platform.Is32Bpp(bmp))
game.Drawer2D.ConvertTo32Bpp(ref bmp);
this.animBmp = bmp;
animsBuffer = new FastBitmap(bmp, true, true);
}
/// <summary> Runs through all animations and if necessary updates the terrain atlas. </summary>
public unsafe void Tick(ScheduledTask task) {
if (useLavaAnim) {

View File

@ -25,11 +25,6 @@ namespace ClassicalSharp {
/// <summary> Updates the underlying atlas bitmap, fields, and texture. </summary>
public void UpdateState(BlockInfo info, Bitmap bmp) {
if (!Platform.Is32Bpp(bmp)) {
Utils.LogDebug("Converting terrain atlas to 32bpp image");
drawer.ConvertTo32Bpp(ref bmp);
}
AtlasBitmap = bmp;
elementSize = bmp.Width / ElementsPerRow;
using (FastBitmap fastBmp = new FastBitmap(bmp, true, true))

View File

@ -57,10 +57,6 @@ namespace ClassicalSharp.Textures {
game.World.TextureUrl = item.Url;
game.Events.RaiseTexturePackChanged();
if (!Platform.Is32Bpp(bmp)) {
Utils.LogDebug("Converting terrain atlas to 32bpp image");
game.Drawer2D.ConvertTo32Bpp(ref bmp);
}
if (!game.ChangeTerrainAtlas(bmp, null)) { bmp.Dispose(); return; }
TextureCache.Add(item.Url, bmp);
@ -71,7 +67,7 @@ namespace ClassicalSharp.Textures {
if (data == null) { // e.g. 404 errors
ExtractDefault(game);
} else if (url != game.World.TextureUrl) {
Bitmap bmp = GetBitmap(data);
Bitmap bmp = GetBitmap(game.Drawer2D, data);
if (bmp == null) { data.Dispose(); return; }
game.World.TextureUrl = url;
@ -110,9 +106,9 @@ namespace ClassicalSharp.Textures {
}
}
static Bitmap GetBitmap(FileStream fs) {
static Bitmap GetBitmap(IDrawer2D drawer, Stream src) {
try {
return Platform.ReadBmp(fs);
return Platform.ReadBmp32Bpp(drawer, src);
} catch (ArgumentException ex) {
ErrorHandler.LogError("Cache.GetBitmap", ex);
return null;

View File

@ -1,21 +1,21 @@
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.Drawing;
using OpenTK.Platform;
using ClassicalSharp;
namespace Launcher.Drawing {
/// <summary> Per-platform class used to transfer a framebuffer directly to the native window. </summary>
public abstract class PlatformDrawer {
/// <summary> Data describing the native window. </summary>
internal IWindowInfo info;
internal OpenTK.Platform.IWindowInfo info;
/// <summary> Initialises the variables for this platform drawer. </summary>
public abstract void Init();
/// <summary> Creates a framebuffer bitmap of the given dimensions. </summary>
public virtual Bitmap CreateFrameBuffer(int width, int height) {
return new Bitmap(width, height);
return Platform.CreateBmp(width, height);
}
/// <summary> Updates the variables when the native window changes dimensions. </summary>

View File

@ -41,7 +41,7 @@ namespace Launcher.Gui.Screens {
if (!fetcher.Done) return;
if (ResourceList.Files.Count > 0) {
ResourcePatcher patcher = new ResourcePatcher(fetcher);
ResourcePatcher patcher = new ResourcePatcher(fetcher, drawer);
patcher.Run();
}
@ -74,8 +74,10 @@ namespace Launcher.Gui.Screens {
}
void DownloadResources(int mouseX, int mouseY) {
if (game.Downloader == null)
game.Downloader = new AsyncDownloader("null");
if (game.Downloader == null) {
game.Downloader = new AsyncDownloader(drawer);
game.Downloader.Init("");
}
if (fetcher != null) return;
fetcher = game.fetcher;

View File

@ -47,25 +47,17 @@ namespace Launcher {
}
void ProcessZipEntry(string filename, byte[] data, ZipEntry entry) {
MemoryStream stream = new MemoryStream(data);
if (filename == "default.png") {
if (fontPng) return;
Bitmap bmp = new Bitmap(stream);
if (!Platform.Is32Bpp(bmp))
Drawer.ConvertTo32Bpp(ref bmp);
Bitmap bmp = Platform.ReadBmp32Bpp(Drawer, data);
Drawer.SetFontBitmap(bmp);
useBitmappedFont = !Options.GetBool(OptionsKey.ArialChatFont, false);
fontPng = true;
} else if (filename == "terrain.png") {
if (terrainPng) return;
Bitmap bmp = new Bitmap(stream);
if (!Platform.Is32Bpp(bmp))
Drawer.ConvertTo32Bpp(ref bmp);
Bitmap bmp = Platform.ReadBmp32Bpp(Drawer, data);
MakeClassicTextures(bmp);
bmp.Dispose();
terrainPng = true;
@ -80,7 +72,7 @@ namespace Launcher {
void MakeClassicTextures(Bitmap bmp) {
int elemSize = bmp.Width / 16;
Size size = new Size(tileSize, tileSize);
terrainBmp = new Bitmap(tileSize * 2, tileSize);
terrainBmp = Platform.CreateBmp(tileSize * 2, tileSize);
terrainPixels = new FastBitmap(terrainBmp, true, false);
// Precompute the scaled background

View File

@ -2,6 +2,7 @@
using System;
using System.Drawing;
using System.IO;
using ClassicalSharp;
namespace Launcher.Patcher {
@ -29,7 +30,7 @@ namespace Launcher.Patcher {
unsafe void PatchDefault(byte[] data, int y) {
// Sadly files in modern are 24 rgb, so we can't use fastbitmap here
using (Bitmap bmp = new Bitmap(new MemoryStream(data))) {
using (Bitmap bmp = Platform.ReadBmp32Bpp(drawer, data)) {
for (int tile = 0; tile < bmp.Height; tile += 16) {
CopyTile(tile, tile, y, bmp);
}
@ -37,7 +38,7 @@ namespace Launcher.Patcher {
}
unsafe void PatchCycle(byte[] data, int y) {
using (Bitmap bmp = new Bitmap(new MemoryStream(data))) {
using (Bitmap bmp = Platform.ReadBmp32Bpp(drawer, data)) {
int dst = 0;
for (int tile = 0; tile < bmp.Height; tile += 16, dst += 16) {
CopyTile(tile, dst, y, bmp);

View File

@ -11,14 +11,17 @@ namespace Launcher.Patcher {
public partial class ResourcePatcher {
public ResourcePatcher(ResourceFetcher fetcher) {
public ResourcePatcher(ResourceFetcher fetcher, IDrawer2D drawer) {
jarClassic = fetcher.jarClassic;
jar162 = fetcher.jar162;
pngTerrainPatch = fetcher.pngTerrainPatch;
pngGuiPatch = fetcher.pngGuiPatch;
this.drawer = drawer;
}
ZipReader reader;
ZipWriter writer;
IDrawer2D drawer;
Bitmap animBitmap;
List<string> existing = new List<string>();
@ -40,8 +43,8 @@ namespace Launcher.Patcher {
ExtractClassic();
ExtractModern();
if (pngGuiPatch != null) {
using (Bitmap guiBitmap = new Bitmap(new MemoryStream(pngGuiPatch)))
writer.WriteNewImage(guiBitmap, "gui.png");
using (Bitmap gui = Platform.ReadBmp32Bpp(drawer, pngGuiPatch))
writer.WriteNewImage(gui, "gui.png");
}
writer.WriteCentralDirectoryRecords();
}
@ -100,10 +103,10 @@ namespace Launcher.Patcher {
writer.WriteZipEntry(entry, data);
return;
} else if (!existing.Contains("terrain.png")){
using (Bitmap dstBitmap = new Bitmap(new MemoryStream(data)),
maskBitmap = new Bitmap(new MemoryStream(pngTerrainPatch))) {
PatchImage(dstBitmap, maskBitmap);
writer.WriteNewImage(dstBitmap, "terrain.png");
using (Bitmap dst = Platform.ReadBmp32Bpp(drawer, data),
mask = Platform.ReadBmp32Bpp(drawer, pngTerrainPatch)) {
PatchImage(dst, mask);
writer.WriteNewImage(dst, "terrain.png");
}
}
}
@ -117,7 +120,7 @@ namespace Launcher.Patcher {
using (Stream src = new MemoryStream(jar162)) {
// Grab animations and snow
animBitmap = new Bitmap(1024, 64, PixelFormat.Format32bppArgb);
animBitmap = Platform.CreateBmp(1024, 64);
reader.ShouldProcessZipEntry = ShouldProcessZipEntry_Modern;
reader.ProcessZipEntry = ProcessZipEntry_Modern;
reader.Extract(src);