-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTextureManager.cs
99 lines (82 loc) · 3.62 KB
/
TextureManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
using HarmonyLib;
using SlimDX.Direct3D9;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Zbx1425.DXDynamicTexture {
public static class TextureManager {
internal static Harmony Harmony;
internal static Dictionary<string, TextureHandle> Handles = new Dictionary<string, TextureHandle>();
internal static string DllDir;
internal static Device DXDevice;
static TextureManager() {
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
}
public static void Initialize() {
Harmony = new Harmony("cn.zbx1425.dxdynamictexture");
Harmony.Patch(typeof(Texture).GetMethods()
.Where(m => m.Name == "FromFile" && m.GetParameters().Length == 11)
.FirstOrDefault(),
null, new HarmonyMethod(typeof(TextureManager), "FromFilePostfix")
);
TouchManager.Initialize();
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
if (args.Name.Contains("Harmony")) {
if (DllDir == null) DllDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (Environment.Version.Major >= 4) {
return Assembly.LoadFile(Path.Combine(DllDir, "Harmony-net48.dll"));
} else {
return Assembly.LoadFile(Path.Combine(DllDir, "Harmony-net35.dll"));
}
}
return null;
}
private static void FromFilePostfix(ref Texture __result, Device device, string fileName) {
var normalizedName = fileName.Replace('\\', '/').ToLowerInvariant();
foreach (var item in Handles) {
if (normalizedName.EndsWith(item.Key)) {
__result = Handles[item.Key].GetOrCreate(device);
}
}
DXDevice = device;
}
public static TextureHandle Register(string fileNameEnding, int width, int height) {
if (fileNameEnding.Trim().Length == 0) throw new ArgumentException("Must not be empty.", "fileNameEnding");
if (!IsPowerOfTwo(width)) throw new ArgumentException("Must be a integral power of 2.", "width");
if (!IsPowerOfTwo(height)) throw new ArgumentException("Must be a integral power of 2.", "height");
fileNameEnding = fileNameEnding.ToLowerInvariant().Replace('\\', '/');
if (Handles.ContainsKey(fileNameEnding)) return Handles[fileNameEnding];
var result = new TextureHandle(width, height);
Handles.Add(fileNameEnding, result);
return result;
}
public static TextureHandle Register(Texture texture) {
foreach (var item in Handles) {
if (item.Value?.DXTexture == texture) return item.Value;
}
var result = new TextureHandle(texture);
string guidString;
do {
guidString = Guid.NewGuid().ToString();
} while (Handles.ContainsKey(guidString));
Handles.Add(guidString, result);
return result;
}
internal static bool IsPowerOfTwo(int x) {
return (x & (x - 1)) == 0;
}
public static void Dispose() {
foreach (var item in Handles) {
if (item.Value != null && item.Value.IsCreated) item.Value.Dispose();
}
}
public static void Clear() {
Dispose();
Handles.Clear();
}
}
}