Difference between revisions of "Common Organization of Controls Kit Manual"
m (→Obtaining the values) |
m (→See also) |
||
(22 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
<source lang="Lua"> | <source lang="Lua"> | ||
{ default1 = { | { default1 = { | ||
− | up = { primary = { "keyboard", "up" }, secondary = { "mouse axis", "y", " | + | up = { primary = { "keyboard", "up" }, secondary = { "mouse axis", "y", "negative", "positive cutoff" }, |
− | down = { primary = { "keyboard", "down" }, secondary = { "mouse axis", "y", " | + | down = { primary = { "keyboard", "down" }, secondary = { "mouse axis", "y", "positive", "positive cutoff" } }, |
default2 = { ... } | default2 = { ... } | ||
}</source> | }</source> | ||
Line 24: | Line 24: | ||
end | end | ||
</source> | </source> | ||
− | These variables (except for mouse axis) contain decimal values ranged -1 to 1 (0 to 1 in | + | These variables (except for mouse axis) contain decimal values ranged -1 to 1 (0 to 1 in "cutoff" and "whole" mode), which you can use for analog control. Mouse axis-bound variables would store pretty arbitrary numbers, with undefined range, only influenced by mouse factor and offset. |
You can also use library callbacks just like normal input callbacks: | You can also use library callbacks just like normal input callbacks: | ||
Line 39: | Line 39: | ||
=== Updating controls === | === Updating controls === | ||
− | You simply put update function to your "love.update" callback, and that's it. It is suggested to put it to beginning of the function. Placing it to other callbacks, such as "love.keypressed" is not necessary at all due to LÖVE's way of handling them. | + | You simply put update function ([[cock.updateAll]]) to your "love.update" callback, and that's it. It is suggested to put it to beginning of the function. Placing it to other callbacks, such as "love.keypressed" is not necessary at all due to LÖVE's way of handling them. |
== Enabling user to edit controls == | == Enabling user to edit controls == | ||
− | The library have special function to assume "input capture" mode, in which any incoming user input will be captured and automatically binded to provided key. You may specify whether or not you want to lock input callbacks and update function, and ignore mouse motion, during input capture mode. You can abort this mode using | + | The library have a special function to assume "input capture" mode ([[cock.setCapture]]), in which any incoming user input will be captured and automatically binded to provided key. You may specify whether or not you want to lock input callbacks and update function, and ignore mouse motion, during input capture mode. You can abort this mode using [[cock.cancelCapture]]. In input capture mode, if mouse motion capture is enabled, the library will temporairly center the mouse and then set it back once input is captured, but it will not hide it because, with all the possible user implementations of mouse cursor, it's simply meaningless, so make sure you hide your cursor during capture, otherwise it'll weirdly jump to the center of the screen and back. In this case you would normally want to use [[Common Organization Of Controls Kit Callbacks|controlcaptured]] callback, with [[cock.bind]] at the end. |
− | You can bind the device and key manually, using the | + | You can bind the device and key manually, using the [[cock.bind]] function. |
− | You can implement "arbitrary binds per action" using search for unused options | + | You can implement "arbitrary binds per action" using search for unused options via [[cock.getEmptyOption]]. It will return next unused option, and since for gathering input, option name is irrelevant, you can simply bind keys to free options arbitrairly. If the function fails to find empty option, you'd have to create a new option with [[cock.addOption]] rather than binding to unexisted option. This is due to internal structure of the library. |
− | '''NOTE:''' in input capture mode, the library would temporary replace your input callbacks and update function with it's own wrappers for them, until some input is provided, which could interfere with other libraries/modules that would do the same, so use it with care. The rule of thumb is to only allow one callbacks replacement at a time, or only allow nested replacements, but never intersecting replacements. If none of your other code would do that in a separate thread, but would do that in main thread, enabling both locks ensures safe capture. If your code doesn't do that at all, having locks enabled may be not necessary | + | '''NOTE:''' in input capture mode, the library would temporary replace your input callbacks and update function with it's own wrappers for them, until some input is provided, which could interfere with other libraries/modules that would do the same (or even with itself), so use it with care. Make sure you do not assume another input capture while being in input capture, this creates an infinite recursion and the game will instantly bluescreen with a stack overflow error. The rule of thumb is to only allow one callbacks replacement at a time, or only allow nested replacements, but never intersecting replacements. If none of your other code would do that in a separate thread, but would do that in main thread, enabling both locks ensures safe capture. If your code doesn't do that at all, having locks enabled may be not necessary. |
== Advanced features == | == Advanced features == | ||
Line 54: | Line 54: | ||
=== Mouse offset and scaling factor === | === Mouse offset and scaling factor === | ||
− | For simplicity of aquiring values from control table, it handles this two math operations for you. It subtracts actual mouse position from an offset, and then multiplies result by scaling factor, per axis. This creates an easy way to set mouse centre point and mouse sensevity. | + | For simplicity of aquiring values from control table, it handles this two math operations for you. It subtracts actual mouse position from an offset ([[cock.setMouseOffset]]), and then multiplies result by scaling factor([[cock.setMouseFactor]]), per axis. This creates an easy way to set mouse centre point and mouse sensevity. |
=== Delta and inversion modes, cutoff modes === | === Delta and inversion modes, cutoff modes === | ||
− | + | These mode alter the behavior of input readings. Inversion modes are negating the input (reverse axis and swap "pressed" and "released" states for keys), and delta mode would report change in the value rather than actual value. Uses for inversion are obvious, and delta modes can report only keypresses/releases, and velocities of the axis-like input devices. | |
− | + | More read: [[Common Organization of Controls Kit Modes]] | |
=== Joystick hat modes === | === Joystick hat modes === | ||
− | Default mode for joystick hat is 8-way diagonal, the other | + | Default mode for joystick hat is "8-way" diagonal input, just like default LÖVE's joystick hats, the other are variants of "4-way". Using this feature you can make axis horizontally or vertically biased, or even radially biased. You can also "split" the axis into 4 directions and it would report values per each direciton, effectively treating dpad like 4 keys rather than directional pad. |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | More read: [[Common Organization of Controls Kit Hat modes]] | |
− | + | You can change the modes on fly as necessary with [[cock.setJoystickHatMode]]. | |
− | + | === Deadzones === | |
− | + | You can define deadzones per-axis with [[cock.setJoystickDeadzone]]. This function works pretty straightforward. You might want to know a little detail about it's implementaiton, that is it first subtracts threshold from the value and then amplifies it by another number that results in axis being "shrinked", starting at threshold point and ending at 1 like normal, rather than instantly jumping from 0 to threshold parameter and such. | |
− | + | === Joystick hat remapping === | |
− | + | Due to the way some joysticks' hats are handled, you may want to map some of joysticks' buttons to a virtual joystick hat with [[cock.remapJoystickHat]]. To do that, you simply use corresponding function and pass it exactly 4 joystick buttons to use. After that, the joystick will have specified hat "remapped", and it'll work like regular joystick hat. Note that once you started remapping, it will instantly switch to "remapped hat" mode, and incomplete remapping will result in incomplete operability. | |
− | == Joystick hat remapping == | ||
− | Due to the way some joysticks' hats are handled, you may want to map some of joysticks' buttons to a virtual joystick hat. To do that, you simply use corresponding function and pass it exactly 4 joystick buttons to use. After that, the joystick will have specified hat "remapped", and it'll work like regular joystick hat. | ||
== Displaying setup == | == Displaying setup == | ||
− | Library provides handful of feedback functions, such as conversion from literal to numerical values and vice versa, for returning binded controls, for finding unused options. | + | Library provides handful of feedback functions, such as conversion from literal to numerical values and vice versa, for returning binded controls, for finding unused options. More on this you can find in the demos. |
== Function index == | == Function index == | ||
Line 95: | Line 83: | ||
== See also == | == See also == | ||
+ | * [[Common Organization of Controls Kit Fields]] | ||
+ | * [[Common Organization of Controls Kit Modes]] | ||
+ | * [[Common Organization of Controls Kit Callbacks]] | ||
+ | * [[Common Organization of Controls Kit Hat modes]] | ||
+ | * [[Common Organization of Controls Kit Input devices]] | ||
+ | * [[Common Organization of Controls Kit Input keys]] | ||
+ | * [[Common Organization of Controls Kit Setup data]] | ||
* [[Common Organization of Controls Kit]] | * [[Common Organization of Controls Kit]] |
Latest revision as of 17:53, 2 September 2013
Contents
Basic use
The library designed to be reasonably easy to use while maintain great flexibility and features.
Preparations
First thing you need to do is, obviously, require the library. Then, you create a new control object using cock.new. You can optionally fill it with data at instant, or may do it later. Then you optionally load saved settings, via serialization for an instance. After that (but not before!) you can reload joystick with cock.reloadJoysticks, that essentially will search for previously used joystick and set it up. If you don't have controls to load, you assign default controls, joystick modes and mouse values with cock.setControls (if you didn't do it upon creation).
Controls data format
Functions cock.new and cock.setControls are accepting data in specific format that needs to be maintained. It is defined as following:
{ default1 = {
up = { primary = { "keyboard", "up" }, secondary = { "mouse axis", "y", "negative", "positive cutoff" },
down = { primary = { "keyboard", "down" }, secondary = { "mouse axis", "y", "positive", "positive cutoff" } },
default2 = { ... }
}
It will define you controls "up" and "down" to be accessed later, with two options to use ("primary" and "secondary"), one with keyboard only control and another with mouse only, and pushes it to "default1" controls set. You can then use defined defaults with cock.setDefault to e.g. restore controls to default, or set them up as such if there's no user-edited controls.
Obtaining the values
This is done really easy: you simply access your control class "current" or "previous" table's child named as your defined control.
if control.current.up > 0 then
player.y = player.y - 100 * dt
elseif control.current.down > 0 then
player.y = player.y + 100 * dt
end
These variables (except for mouse axis) contain decimal values ranged -1 to 1 (0 to 1 in "cutoff" and "whole" mode), which you can use for analog control. Mouse axis-bound variables would store pretty arbitrary numbers, with undefined range, only influenced by mouse factor and offset.
You can also use library callbacks just like normal input callbacks:
function cock.controlpressed ( id, key, val )
if key == "up" then
player.accel = 1
end
end
By default, all library callbacks are disabled, so to use them you have to enable them via cock.setCallbacks.
The library also have effecient getters and setters for that, but you are strongly discouraged to use them.
Updating controls
You simply put update function (cock.updateAll) to your "love.update" callback, and that's it. It is suggested to put it to beginning of the function. Placing it to other callbacks, such as "love.keypressed" is not necessary at all due to LÖVE's way of handling them.
Enabling user to edit controls
The library have a special function to assume "input capture" mode (cock.setCapture), in which any incoming user input will be captured and automatically binded to provided key. You may specify whether or not you want to lock input callbacks and update function, and ignore mouse motion, during input capture mode. You can abort this mode using cock.cancelCapture. In input capture mode, if mouse motion capture is enabled, the library will temporairly center the mouse and then set it back once input is captured, but it will not hide it because, with all the possible user implementations of mouse cursor, it's simply meaningless, so make sure you hide your cursor during capture, otherwise it'll weirdly jump to the center of the screen and back. In this case you would normally want to use controlcaptured callback, with cock.bind at the end.
You can bind the device and key manually, using the cock.bind function.
You can implement "arbitrary binds per action" using search for unused options via cock.getEmptyOption. It will return next unused option, and since for gathering input, option name is irrelevant, you can simply bind keys to free options arbitrairly. If the function fails to find empty option, you'd have to create a new option with cock.addOption rather than binding to unexisted option. This is due to internal structure of the library.
NOTE: in input capture mode, the library would temporary replace your input callbacks and update function with it's own wrappers for them, until some input is provided, which could interfere with other libraries/modules that would do the same (or even with itself), so use it with care. Make sure you do not assume another input capture while being in input capture, this creates an infinite recursion and the game will instantly bluescreen with a stack overflow error. The rule of thumb is to only allow one callbacks replacement at a time, or only allow nested replacements, but never intersecting replacements. If none of your other code would do that in a separate thread, but would do that in main thread, enabling both locks ensures safe capture. If your code doesn't do that at all, having locks enabled may be not necessary.
Advanced features
This library was created with robust design in mind, so it supports a bit of handy advanced features that otherwisely would be needed to implemented by the programmer, which is not always convenient.
Mouse offset and scaling factor
For simplicity of aquiring values from control table, it handles this two math operations for you. It subtracts actual mouse position from an offset (cock.setMouseOffset), and then multiplies result by scaling factor(cock.setMouseFactor), per axis. This creates an easy way to set mouse centre point and mouse sensevity.
Delta and inversion modes, cutoff modes
These mode alter the behavior of input readings. Inversion modes are negating the input (reverse axis and swap "pressed" and "released" states for keys), and delta mode would report change in the value rather than actual value. Uses for inversion are obvious, and delta modes can report only keypresses/releases, and velocities of the axis-like input devices.
More read: Common Organization of Controls Kit Modes
Joystick hat modes
Default mode for joystick hat is "8-way" diagonal input, just like default LÖVE's joystick hats, the other are variants of "4-way". Using this feature you can make axis horizontally or vertically biased, or even radially biased. You can also "split" the axis into 4 directions and it would report values per each direciton, effectively treating dpad like 4 keys rather than directional pad.
More read: Common Organization of Controls Kit Hat modes
You can change the modes on fly as necessary with cock.setJoystickHatMode.
Deadzones
You can define deadzones per-axis with cock.setJoystickDeadzone. This function works pretty straightforward. You might want to know a little detail about it's implementaiton, that is it first subtracts threshold from the value and then amplifies it by another number that results in axis being "shrinked", starting at threshold point and ending at 1 like normal, rather than instantly jumping from 0 to threshold parameter and such.
Joystick hat remapping
Due to the way some joysticks' hats are handled, you may want to map some of joysticks' buttons to a virtual joystick hat with cock.remapJoystickHat. To do that, you simply use corresponding function and pass it exactly 4 joystick buttons to use. After that, the joystick will have specified hat "remapped", and it'll work like regular joystick hat. Note that once you started remapping, it will instantly switch to "remapped hat" mode, and incomplete remapping will result in incomplete operability.
Displaying setup
Library provides handful of feedback functions, such as conversion from literal to numerical values and vice versa, for returning binded controls, for finding unused options. More on this you can find in the demos.
Function index
cock.addJoystick | Hooks up new joystick. |
cock.addOption | Creates new input option. |
cock.bind | Binds given input. |
cock.cancelCapture | Cancels input capture. |
cock.convertAxis | Converts axis. |
cock.convertDelta | Converts delta. |
cock.convertDevice | Converts device. |
cock.convertInverse | Converts inverse. |
cock.convertJoystick | Converts joystick. |
cock.convertJoystickHat | Converts joystick hat. |
cock.convertJoystickHatMode | Converts hat mode. |
cock.convertKey | Converts key. |
cock.delete | Deletes object. |
cock.deleteJoystick | Deletes joystick. |
cock.deleteOption | Deletes input option. |
cock.explodeCapturedData | Explodes longdata. |
cock.find | Find object. |
cock.getBinded | Gets binded controls. |
cock.getCapture | Gets capture state. |
cock.getEmptyOption | Finds unused option. |
cock.getJoystickDeadzone | Gets deadzones. |
cock.getJoystickHatMode | Sets hat modes. |
cock.getJoysticksList | Lists joysticks. |
cock.getMouseFactor | Gets mouse factor. |
cock.getMouseOffset | Gets mouse offset. |
cock.new | Creates new object. |
cock.reloadJoysticks | Reloads joysticks. |
cock.remapJoystickHat | Maps buttons to hats. |
cock.setCallbacks | Toggles callbacks. |
cock.setCapture | User-edit controls. |
cock.setControls | Creates control layouts. |
cock.setDefault | Reverts to defaults. |
cock.setDefaultXBox360 | (BROKEN) Creates XBox360 layout. |
cock.setJoystickDeadzone | Sets deadzones. |
cock.setJoystickHatMode | Sets hat modes. |
cock.setMouseFactor | Sets mouse factor. |
cock.setMouseOffset | Sets mouse offset. |
cock.unbind | Unbinds map. |
cock.update | Updates object. |
cock.updateAll | Updates all objects. |
See also
- Common Organization of Controls Kit Fields
- Common Organization of Controls Kit Modes
- Common Organization of Controls Kit Callbacks
- Common Organization of Controls Kit Hat modes
- Common Organization of Controls Kit Input devices
- Common Organization of Controls Kit Input keys
- Common Organization of Controls Kit Setup data
- Common Organization of Controls Kit