buldthensnip/pkg/base/lib_crosshair.lua
2015-03-01 05:14:26 +00:00

189 lines
7.6 KiB
Lua

--[[
This file is part of Ice Lua Components.
Ice Lua Components is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Ice Lua Components is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Ice Lua Components. If not, see <http://www.gnu.org/licenses/>.
]]
local DEFAULT_CROSSHAIR = {
dot = true,
lines = true,
size = 4,
thickness = 1,
gap = 3,
colour = {255, 0, 0},
outline = false,
outline_colour = {0, 0, 0},
outline_thickness = 1,
style = "classic",
}
local function crosshair_parse_config(config)
config = config or {}
local crosshair = {}
for k, v in pairs(DEFAULT_CROSSHAIR) do
if config[k] ~= nil then
crosshair[k] = config[k]
else
crosshair[k] = v
end
end
return crosshair
end
local function colour_array_to_int(colour)
if #colour == 4 then
return argb_split_to_merged(colour[1], colour[2], colour[3], colour[4])
elseif #colour == 3 then
return argb_split_to_merged(colour[1], colour[2], colour[3], 255)
elseif #colour == 1 then
return argb_split_to_merged(colour[1], colour[1], colour[1], 255)
else
error("Invalid colour array - should be of format: [L], [R, G, B], or [R, G, B, A]")
end
end
-- TODO: Image lib? More C functions?
local function draw_outline(image, x, y, width, height, thickness, colour)
common.img_rect_fill(image, x - thickness, y, thickness, height, colour) -- Left
common.img_rect_fill(image, x + width, y, thickness, height, colour) -- Right
common.img_rect_fill(image, x, y - thickness, width, thickness, colour) -- Top
common.img_rect_fill(image, x, y + height, width, thickness, colour) -- Bottom
end
crosshair_styles = {}
function crosshair_styles.classic(config)
-- Local variables make everything better
local thickness = config.thickness
local outline_thickness = config.outline_thickness
local size = config.size
local gap = config.gap
-- We may want different w/h in future versions/styles, so everything has an x/y version
local offset_x = 0
local offset_y = 0
local offset_centre_x = size + gap
local offset_centre_y = size + gap
local width = (offset_centre_x * 2) + thickness
local height = (offset_centre_y * 2) + thickness
local offset_n_x = width
local offset_n_y = height
if config.outline then
width = width + (outline_thickness * 2)
height = height + (outline_thickness * 2)
offset_x = offset_x + outline_thickness
offset_y = offset_y + outline_thickness
offset_n_x = width - outline_thickness
offset_n_y = height - outline_thickness
offset_centre_x = offset_centre_x + outline_thickness
offset_centre_y = offset_centre_y + outline_thickness
end
local colour = colour_array_to_int(config.colour)
local outline_colour = colour_array_to_int(config.outline_colour)
-- Crosshair
local crosshair = common.img_new(width, height)
-- Centre dot
if config.dot then
-- Dot
common.img_rect_fill(crosshair, offset_centre_x, offset_centre_y, thickness, thickness, colour)
-- Outline
if config.outline then
draw_outline(crosshair, offset_centre_x, offset_centre_y, thickness, thickness, outline_thickness, outline_colour)
end
end
-- Horizontal/vertical lines
if config.lines then
local offset_right_x = offset_centre_x + thickness + gap
local offset_bottom_y = offset_centre_y + thickness + gap
-- Lines
common.img_rect_fill(crosshair, offset_x, offset_centre_y, size, thickness, colour) -- Left
common.img_rect_fill(crosshair, offset_right_x, offset_centre_y, size, thickness, colour) -- Right
common.img_rect_fill(crosshair, offset_centre_x, offset_y, thickness, size, colour) -- Top
common.img_rect_fill(crosshair, offset_centre_x, offset_bottom_y, thickness, size, colour) -- Bottom
-- Outline
if config.outline then
draw_outline(crosshair, offset_x, offset_centre_y, size, thickness, outline_thickness, outline_colour) -- Left
draw_outline(crosshair, offset_right_x, offset_centre_y, size, thickness, outline_thickness, outline_colour) -- Right
draw_outline(crosshair, offset_centre_x, offset_y, thickness, size, outline_thickness, outline_colour) -- Top
draw_outline(crosshair, offset_centre_x, offset_bottom_y, thickness, size, outline_thickness, outline_colour) -- Bottom
end
end
-- Hit marker
crosshair_hit = common.img_new(width, height)
-- For now, we replace the entire crosshair with a separate hitmarker crosshair, so copy the crosshair into the hitmarker
client.img_blit_to(crosshair_hit, crosshair, 0, 0)
-- Draw outline first, so we can draw the fill over the intersection
hm_line_length = size
hm_offset_right = offset_n_x - hm_line_length
hm_offset_right_far = offset_n_x - thickness
hm_offset_bottom = offset_n_y - hm_line_length
hm_offset_bottom_far = offset_n_y - thickness
if config.outline then
-- Top-left
draw_outline(crosshair_hit, offset_x, offset_y, hm_line_length, thickness, outline_thickness, outline_colour)
draw_outline(crosshair_hit, offset_x, offset_y, thickness, hm_line_length, outline_thickness, outline_colour)
-- Top-right
draw_outline(crosshair_hit, hm_offset_right, offset_y, hm_line_length, thickness, outline_thickness, outline_colour)
draw_outline(crosshair_hit, hm_offset_right_far, offset_y, thickness, hm_line_length, outline_thickness, outline_colour)
-- Bottom-left
draw_outline(crosshair_hit, offset_x, hm_offset_bottom_far, hm_line_length, thickness, outline_thickness, outline_colour)
draw_outline(crosshair_hit, offset_x, hm_offset_bottom, thickness, hm_line_length, outline_thickness, outline_colour)
-- Bottom-right
draw_outline(crosshair_hit, hm_offset_right, hm_offset_bottom_far, hm_line_length, thickness, outline_thickness, outline_colour)
draw_outline(crosshair_hit, hm_offset_right_far, hm_offset_bottom, thickness, hm_line_length, outline_thickness, outline_colour)
end
-- Top-left
common.img_rect_fill(crosshair_hit, offset_x, offset_y, hm_line_length, thickness, colour)
common.img_rect_fill(crosshair_hit, offset_x, offset_y, thickness, hm_line_length, colour)
-- Top-right
common.img_rect_fill(crosshair_hit, hm_offset_right, offset_y, hm_line_length, thickness, colour)
common.img_rect_fill(crosshair_hit, hm_offset_right_far, offset_y, thickness, hm_line_length, colour)
-- Bottom-left
common.img_rect_fill(crosshair_hit, offset_x, hm_offset_bottom_far, hm_line_length, thickness, colour)
common.img_rect_fill(crosshair_hit, offset_x, hm_offset_bottom, thickness, hm_line_length, colour)
-- Bottom-right
common.img_rect_fill(crosshair_hit, hm_offset_right, hm_offset_bottom_far, hm_line_length, thickness, colour)
common.img_rect_fill(crosshair_hit, hm_offset_right_far, hm_offset_bottom, thickness, hm_line_length, colour)
return crosshair, crosshair_hit
end
function crosshair_generate_images(config)
-- TODO: Perhaps draw outline and crosshair at full alpha on separate images, then merge them?
-- This would stop overlapping areas from having different alpha than the rest
local config = crosshair_parse_config(config)
local gen = crosshair_styles[config.style]
if gen == null then
error("Invalid crosshair style selected")
else
return gen(config)
end
end