-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatusicons.lua
152 lines (132 loc) · 5.94 KB
/
statusicons.lua
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
-- Some code pulled from statustimers - Copyright (c) 2022 Heals
-------------------------------------------------------------------------------
-- imports
-------------------------------------------------------------------------------
local d3d8 = require('d3d8');
local ffi = require('ffi');
-------------------------------------------------------------------------------
-- local state
-------------------------------------------------------------------------------
local d3d8_device = d3d8.get_device();
-------------------------------------------------------------------------------
-- local constants
-------------------------------------------------------------------------------
local icon_cache = T{
};
-- this table implements overrides for certain icons to handle
-- local buffs_table = nil;
local id_overrides = T{
};
-------------------------------------------------------------------------------
-- local functions
-------------------------------------------------------------------------------
-- load a dummy icon placeholder for a missing status and return a texture pointer
---@return ffi.cdata* texture_ptr the loaded texture object or nil on error
local function load_dummy_icon()
local icon_path = ('%s\\libs\\status\\icons\\dummy.png'):fmt(addon.path);
local dx_texture_ptr = ffi.new('IDirect3DTexture8*[1]');
if (ffi.C.D3DXCreateTextureFromFileA(d3d8_device, icon_path, dx_texture_ptr) == ffi.C.S_OK) then
return d3d8.gc_safe_release(ffi.cast('IDirect3DTexture8*', dx_texture_ptr[0]));
end
return nil;
end
-- load a status icon from the games own resources and return a texture pointer
---@param status_id number the status id to load the icon for
---@return ffi.cdata* texture_ptr the loaded texture object or nil on error
local function load_status_icon_from_resource(status_id)
if (status_id == nil or status_id < 0 or status_id > 0x3FF) then
return nil;
end
local id_key = ("_%d"):fmt(status_id);
if (id_overrides:haskey(id_key)) then
status_id = id_overrides[id_key];
end
local icon = AshitaCore:GetResourceManager():GetStatusIconByIndex(status_id);
if (icon ~= nil) then
local dx_texture_ptr = ffi.new('IDirect3DTexture8*[1]');
if (ffi.C.D3DXCreateTextureFromFileInMemoryEx(d3d8_device, icon.Bitmap, icon.ImageSize, 0xFFFFFFFF, 0xFFFFFFFF, 1, 0, ffi.C.D3DFMT_A8R8G8B8, ffi.C.D3DPOOL_MANAGED, ffi.C.D3DX_DEFAULT, ffi.C.D3DX_DEFAULT, 0xFF000000, nil, nil, dx_texture_ptr) == ffi.C.S_OK) then
return d3d8.gc_safe_release(ffi.cast('IDirect3DTexture8*', dx_texture_ptr[0]));
end
end
return load_dummy_icon();
end
-- load a status icon from a theme pack and return a texture pointer
---@param theme string path to the theme's root directory
---@param status_id number the status id to load the icon for
---@return ffi.cdata* texture_ptr the loaded texture object or nil on error
local function load_status_icon_from_theme(status_id, theme)
if (status_id == nil or status_id < 0 or status_id > 0x3FF) then
return nil;
end
local icon_path = nil;
local supports_alpha = false;
T{'.png', '.jpg', '.jpeg', '.bmp'}:forieach(function(ext, _)
if (icon_path ~= nil) then
return;
end
supports_alpha = ext == '.png';
icon_path = ('%s\\libs\\status\\icons\\%s\\%d'):append(ext):fmt(addon.path, theme, status_id);
local handle = io.open(icon_path, 'r');
if (handle ~= nil) then
handle.close();
else
icon_path = nil;
end
end);
if (icon_path == nil) then
-- fallback to internal icon resources
return load_status_icon_from_resource(status_id);
end
local dx_texture_ptr = ffi.new('IDirect3DTexture8*[1]');
if (supports_alpha) then
-- use the native transaparency
if (ffi.C.D3DXCreateTextureFromFileA(d3d8_device, icon_path, dx_texture_ptr) == ffi.C.S_OK) then
return d3d8.gc_safe_release(ffi.cast('IDirect3DTexture8*', dx_texture_ptr[0]));
end
else
-- use black as colour-key for transparency
if (ffi.C.D3DXCreateTextureFromFileExA(d3d8_device, icon_path, 0xFFFFFFFF, 0xFFFFFFFF, 1, 0, ffi.C.D3DFMT_A8R8G8B8, ffi.C.D3DPOOL_MANAGED, ffi.C.D3DX_DEFAULT, ffi.C.D3DX_DEFAULT, 0xFF000000, nil, nil, dx_texture_ptr) == ffi.C.S_OK) then
return d3d8.gc_safe_release(ffi.cast('IDirect3DTexture8*', dx_texture_ptr[0]));
end
end
return load_dummy_icon();
end
local statusIcons = {};
-- return a list of all sub directories
---@return table theme_paths
statusIcons.get_status_theme_paths = function()
local path = ('%s\\libs\\status\\icons'):fmt(addon.path);
return ashita.fs.get_directory(path);
end
-- return an image pointer for a status_id
---@param status_id number the status id number of the requested icon
---@return number texture_ptr_id a number representing the texture_ptr or nil
statusIcons.get_icon_image = function(status_id)
if (not icon_cache:haskey(status_id)) then
local tex_ptr = load_status_icon_from_resource(status_id);
if (tex_ptr == nil) then
return nil;
end
icon_cache[status_id] = tex_ptr;
end
return tonumber(ffi.cast("uint32_t", icon_cache[status_id]));
end
-- return an image pointer for a status_id
---@param theme string the name of the theme directory
---@param status_id number the status id number of the requested icon
---@return number texture_ptr_id a number representing the texture_ptr or nil
statusIcons.get_icon_from_theme = function(status_id, theme)
if (not icon_cache:haskey(status_id)) then
local tex_ptr = load_status_icon_from_theme(status_id, theme);
if (tex_ptr == nil) then
return nil;
end
icon_cache[status_id] = tex_ptr;
end
return tonumber(ffi.cast("uint32_t", icon_cache[status_id]));
end
-- reset the icon cache and release all resources
statusIcons.clear_cache = function()
icon_cache = T{};
end;
return statusIcons;