You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.5 KiB
Lua
105 lines
3.5 KiB
Lua
local base = string.match(..., "(.-)[^%.]+%.[^%.]+$")
|
|
local enums = require(base.."ev_api.decls").enums
|
|
local eh = require(base.."helper.enum")
|
|
local ffi = require("ffi")
|
|
local fh = require(base.."helper.ffi_struct")
|
|
|
|
local ff_trigger = require(base.."ev_api.ff_trigger").new
|
|
local ff_replay = require(base.."ev_api.ff_replay").new
|
|
|
|
local ff_constant_effect = require(base.."ev_api.ff_constant_effect").new
|
|
local ff_ramp_effect = require(base.."ev_api.ff_ramp_effect").new
|
|
local ff_condition_effect = require(base.."ev_api.ff_condition_effect").new
|
|
local ff_periodic_effect = require(base.."ev_api.ff_periodic_effect").new
|
|
local ff_rumble_effect = require(base.."ev_api.ff_rumble_effect").new
|
|
|
|
local format = string.format
|
|
|
|
local mt, index = {}, {}
|
|
|
|
-- COMMON CRAP
|
|
local FF_EFFECT = eh.filter_min_max(
|
|
enums.FF, enums.FF.EFFECT_MIN, enums.FF.EFFECT_MAX)
|
|
index.FF_EFFECT = FF_EFFECT
|
|
fh.gen_enum_accessor(index, FF_EFFECT, "type")
|
|
fh.gen_raw_accessor(index, "id")
|
|
|
|
local DIRECTION = eh.make_enum{
|
|
{"DOWN", 0}, {"LEFT", 0x4000}, {"UP", 0x8000}, {"RIGHT", 0xc000},
|
|
}
|
|
index.DIRECTION = DIRECTION
|
|
fh.gen_enum_accessor(index, DIRECTION, "direction")
|
|
|
|
fh.gen_wrap_accessor(index, "trigger", ff_trigger)
|
|
fh.gen_wrap_accessor(index, "replay", ff_replay)
|
|
|
|
-- UNION MAGIC
|
|
local function check_union(self, name, exp_type)
|
|
if self.raw.type ~= exp_type then
|
|
error("Wrong enum variant "..self.type.." while getting "..name)
|
|
end
|
|
end
|
|
|
|
local function typechecked_acc(name, exp_type, wrap)
|
|
index["get_"..name] = function(self)
|
|
check_union(self, name, exp_type)
|
|
return wrap(self.raw.u[name])
|
|
end
|
|
index["set_"..name] = function(self, ...)
|
|
check_union(self, name, exp_type)
|
|
self.raw.u[name] = wrap(...).raw
|
|
end
|
|
end
|
|
|
|
typechecked_acc("constant", FF_EFFECT.CONSTANT, ff_constant_effect)
|
|
typechecked_acc("ramp", FF_EFFECT.RAMP, ff_ramp_effect)
|
|
typechecked_acc("periodic", FF_EFFECT.PERIODIC, ff_periodic_effect)
|
|
|
|
local valid_conditions = {
|
|
[FF_EFFECT.SPRING] = true, [FF_EFFECT.FRICTION] = true,
|
|
[FF_EFFECT.DAMPER] = true, [FF_EFFECT.INERTIA] = true,
|
|
}
|
|
for i=0,1 do
|
|
name = "condition"..i
|
|
index["get_"..name] = function(self)
|
|
if not valid_conditions[self.raw.type] then
|
|
error("Wrong enum variant "..self.type.." while getting "..name)
|
|
end
|
|
return ff_condition_effect(self.raw.u.condition[i])
|
|
end
|
|
index["set_"..name] = function(self, ...)
|
|
if not valid_conditions[self.raw.type] then
|
|
error("Wrong enum variant "..self.type.." while getting "..name)
|
|
end
|
|
self.raw.u.condition[i] = ff_condition_effect(...).raw
|
|
end
|
|
end
|
|
|
|
typechecked_acc("rumble", FF_EFFECT.RUMBLE, ff_rumble_effect)
|
|
|
|
-- MISC
|
|
-- hack: we need to set type before setting code
|
|
local orig_set = fh.base_funcs.set_from_table
|
|
function index:set_from_table(tbl)
|
|
if tbl.type then self.type = tbl.type end
|
|
orig_set(self, tbl)
|
|
end
|
|
|
|
function index:tostring()
|
|
local t, subs = self.type, ""
|
|
if t == "CONSTANT" then subs = ", constant="..self.constant:tostring()
|
|
elseif t == "RAMP" then subs = ", ramp="..self.ramp:tostring()
|
|
elseif t == "PERIODIC" then subs = ", periodic="..self.periodic:tostring()
|
|
elseif t == "SPRING" or t == "FRICTION" or t == "DAMPER" or t == "INERTIA" then
|
|
subs = format(", condition0=%s, condition1=%s",
|
|
self.condition0, self.condition1)
|
|
elseif t == "RUMBLE" then subs = ", rumble="..self.rumble:tostring() end
|
|
|
|
return format(
|
|
"ff_effect{type=%s, id=%d, direction=%s, trigger=%s, replay=%s%s}",
|
|
self.type, self.id, self.direction, self.trigger, self.replay, subs)
|
|
end
|
|
mt.__tostring = index.tostring
|
|
|
|
return fh.base(mt, index, ffi.typeof("struct ff_effect"))
|