input system rework
This commit is contained in:
parent
4efe80bb5a
commit
02b5ac4cc3
@ -26,8 +26,9 @@ set(TWN_TARGET townengine CACHE INTERNAL "")
|
|||||||
set(TWN_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
|
set(TWN_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
|
||||||
|
|
||||||
# feature configuration, set them with -DFEATURE=ON/OFF in cli
|
# feature configuration, set them with -DFEATURE=ON/OFF in cli
|
||||||
option(TWN_FEATURE_DYNLIB_GAME "Enable dynamic library loading support" ON)
|
option(TWN_USE_AMALGAM "Enable use of twn_amalgam.c as a single compilation unit" ON)
|
||||||
option(TWN_USE_AMALGAM "Enable use of twn_amalgam.c as a single compilation unit" ON)
|
option(TWN_FEATURE_DYNLIB_GAME "Enable dynamic library loading support" ON)
|
||||||
|
set(TWN_OUT_DIR ${CMAKE_SOURCE_DIR} CACHE PATH "Artifact destination")
|
||||||
|
|
||||||
# todo: figure out how to compile for dynamic linking instead
|
# todo: figure out how to compile for dynamic linking instead
|
||||||
if(EMSCRIPTEN)
|
if(EMSCRIPTEN)
|
||||||
@ -270,7 +271,9 @@ function(link_deps target)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
function(use_townengine target sources output_directory)
|
function(use_townengine sources output_directory)
|
||||||
|
cmake_path(GET TWN_OUT_DIR STEM LAST_ONLY target)
|
||||||
|
|
||||||
if(TWN_FEATURE_DYNLIB_GAME)
|
if(TWN_FEATURE_DYNLIB_GAME)
|
||||||
# game shared library, for reloading
|
# game shared library, for reloading
|
||||||
add_library(${target}_game SHARED ${sources})
|
add_library(${target}_game SHARED ${sources})
|
||||||
|
@ -13,4 +13,4 @@ set(SOURCE_FILES
|
|||||||
state.h
|
state.h
|
||||||
)
|
)
|
||||||
|
|
||||||
use_townengine(${PROJECT_NAME} "${SOURCE_FILES}" ${CMAKE_CURRENT_SOURCE_DIR})
|
use_townengine("${SOURCE_FILES}" ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
@ -69,8 +69,8 @@ void game_tick(void)
|
|||||||
ctx.udata = calloc(1, sizeof(State));
|
ctx.udata = calloc(1, sizeof(State));
|
||||||
}
|
}
|
||||||
|
|
||||||
input_action("add_a_bit", CONTROL_LEFT_MOUSE);
|
input_action("add_a_bit", "LCLICK");
|
||||||
input_action("add_a_lot", CONTROL_RIGHT_MOUSE);
|
input_action("add_a_lot", "RCLICK");
|
||||||
|
|
||||||
State *state = ctx.udata;
|
State *state = ctx.udata;
|
||||||
|
|
||||||
|
@ -20,4 +20,4 @@ set(SOURCE_FILES
|
|||||||
scenes/ingame.c scenes/ingame.h
|
scenes/ingame.c scenes/ingame.h
|
||||||
)
|
)
|
||||||
|
|
||||||
use_townengine(${PROJECT_NAME} "${SOURCE_FILES}" ${CMAKE_CURRENT_SOURCE_DIR})
|
use_townengine("${SOURCE_FILES}" ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
@ -22,8 +22,8 @@ void game_tick(void) {
|
|||||||
|
|
||||||
State *state = ctx.udata;
|
State *state = ctx.udata;
|
||||||
|
|
||||||
input_action("debug_toggle", CONTROL_BACKSPACE);
|
input_action("debug_toggle", "BACKSPACE");
|
||||||
input_action("debug_dump_atlases", CONTROL_HOME);
|
input_action("debug_dump_atlases", "HOME");
|
||||||
|
|
||||||
if (input_action_just_pressed("debug_toggle")) {
|
if (input_action_just_pressed("debug_toggle")) {
|
||||||
ctx.debug = !ctx.debug;
|
ctx.debug = !ctx.debug;
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
static void ingame_tick(State *state) {
|
static void ingame_tick(State *state) {
|
||||||
SceneIngame *scn = (SceneIngame *)state->scene;
|
SceneIngame *scn = (SceneIngame *)state->scene;
|
||||||
|
|
||||||
input_action("player_left", CONTROL_A);
|
input_action("player_left", "A");
|
||||||
input_action("player_right", CONTROL_D);
|
input_action("player_right", "D");
|
||||||
input_action("player_forward", CONTROL_W);
|
input_action("player_forward", "W");
|
||||||
input_action("player_backward", CONTROL_S);
|
input_action("player_backward", "S");
|
||||||
input_action("player_jump", CONTROL_SPACE);
|
input_action("player_jump", "SPACE");
|
||||||
input_action("player_run", CONTROL_LSHIFT);
|
input_action("player_run", "LSHIFT");
|
||||||
|
|
||||||
world_drawdef(scn->world);
|
world_drawdef(scn->world);
|
||||||
player_calc(scn->player);
|
player_calc(scn->player);
|
||||||
|
@ -13,7 +13,7 @@ static void title_tick(State *state) {
|
|||||||
SceneTitle *scn = (SceneTitle *)state->scene;
|
SceneTitle *scn = (SceneTitle *)state->scene;
|
||||||
(void)scn;
|
(void)scn;
|
||||||
|
|
||||||
input_action("ui_accept", CONTROL_RETURN);
|
input_action("ui_accept", "ENTER");
|
||||||
|
|
||||||
if (input_action_just_pressed("ui_accept")) {
|
if (input_action_just_pressed("ui_accept")) {
|
||||||
switch_to(state, ingame_scene);
|
switch_to(state, ingame_scene);
|
||||||
|
@ -17,4 +17,4 @@ set(SOURCE_FILES
|
|||||||
scenes/ingame.c scenes/ingame.h
|
scenes/ingame.c scenes/ingame.h
|
||||||
)
|
)
|
||||||
|
|
||||||
use_townengine(${PROJECT_NAME} "${SOURCE_FILES}" ${CMAKE_CURRENT_SOURCE_DIR})
|
use_townengine("${SOURCE_FILES}" ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
@ -24,8 +24,8 @@ void game_tick(void) {
|
|||||||
|
|
||||||
State *state = ctx.udata;
|
State *state = ctx.udata;
|
||||||
|
|
||||||
input_action("debug_toggle", CONTROL_BACKSPACE);
|
input_action("debug_toggle", "BACKSPACE");
|
||||||
input_action("debug_dump_atlases", CONTROL_HOME);
|
input_action("debug_dump_atlases", "HOME");
|
||||||
|
|
||||||
if (input_action_just_pressed("debug_toggle")) {
|
if (input_action_just_pressed("debug_toggle")) {
|
||||||
ctx.debug = !ctx.debug;
|
ctx.debug = !ctx.debug;
|
||||||
|
@ -188,14 +188,14 @@ static void draw_terrain(SceneIngame *scn) {
|
|||||||
static void ingame_tick(State *state) {
|
static void ingame_tick(State *state) {
|
||||||
SceneIngame *scn = (SceneIngame *)state->scene;
|
SceneIngame *scn = (SceneIngame *)state->scene;
|
||||||
|
|
||||||
input_action("player_left", CONTROL_A);
|
input_action("player_left", "A");
|
||||||
input_action("player_right", CONTROL_D);
|
input_action("player_right", "D");
|
||||||
input_action("player_forward", CONTROL_W);
|
input_action("player_forward", "W");
|
||||||
input_action("player_backward", CONTROL_S);
|
input_action("player_backward", "S");
|
||||||
input_action("player_jump", CONTROL_SPACE);
|
input_action("player_jump", "SPACE");
|
||||||
input_action("player_run", CONTROL_LSHIFT);
|
input_action("player_run", "LSHIFT");
|
||||||
input_action("mouse_capture_toggle", CONTROL_ESCAPE);
|
input_action("mouse_capture_toggle", "ESCAPE");
|
||||||
input_action("toggle_camera_mode", CONTROL_C);
|
input_action("toggle_camera_mode", "C");
|
||||||
|
|
||||||
if (scn->mouse_captured) {
|
if (scn->mouse_captured) {
|
||||||
const float sensitivity = 0.4f * (float)DEG2RAD; /* TODO: put this in a better place */
|
const float sensitivity = 0.4f * (float)DEG2RAD; /* TODO: put this in a better place */
|
||||||
|
@ -11,7 +11,7 @@ static void title_tick(State *state) {
|
|||||||
SceneTitle *scn = (SceneTitle *)state->scene;
|
SceneTitle *scn = (SceneTitle *)state->scene;
|
||||||
(void)scn;
|
(void)scn;
|
||||||
|
|
||||||
input_action("ui_accept", CONTROL_RETURN);
|
input_action("ui_accept", "RETURN");
|
||||||
|
|
||||||
if (input_action_just_pressed("ui_accept")) {
|
if (input_action_just_pressed("ui_accept")) {
|
||||||
switch_to(state, ingame_scene);
|
switch_to(state, ingame_scene);
|
||||||
|
@ -113,8 +113,8 @@ void game_tick(void) {
|
|||||||
|
|
||||||
Vec2 const mouse_snap = {floorf(ctx.mouse_position.x / 8) * 8, floorf(ctx.mouse_position.y / 8) * 8};
|
Vec2 const mouse_snap = {floorf(ctx.mouse_position.x / 8) * 8, floorf(ctx.mouse_position.y / 8) * 8};
|
||||||
|
|
||||||
input_action("up", CONTROL_LEFT_MOUSE);
|
input_action("up", "LCLICK");
|
||||||
input_action("down", CONTROL_RIGHT_MOUSE);
|
input_action("down", "RCLICK");
|
||||||
|
|
||||||
if (input_action_just_pressed("up"))
|
if (input_action_just_pressed("up"))
|
||||||
state->r += 1;
|
state->r += 1;
|
||||||
|
@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.21)
|
|||||||
cmake_policy(SET CMP0171 NEW)
|
cmake_policy(SET CMP0171 NEW)
|
||||||
project(twnlua LANGUAGES C)
|
project(twnlua LANGUAGES C)
|
||||||
|
|
||||||
option(TWN_OUT_DIR "Artifact destination" ${CMAKE_SOURCE_DIR})
|
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
endif()
|
endif()
|
||||||
@ -41,5 +39,4 @@ set(SOURCE_FILES
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/luabind.c
|
${CMAKE_CURRENT_SOURCE_DIR}/luabind.c
|
||||||
)
|
)
|
||||||
|
|
||||||
cmake_path(GET TWN_OUT_DIR STEM LAST_ONLY GAME_PROJECT_NAME)
|
use_townengine("${SOURCE_FILES}" ${TWN_OUT_DIR})
|
||||||
use_townengine(${GAME_PROJECT_NAME} "${SOURCE_FILES}" ${TWN_OUT_DIR})
|
|
||||||
|
@ -116,7 +116,6 @@ for procedure, procedure_desc in api["procedures"].items():
|
|||||||
elif procedure_desc["return"] == "char *":
|
elif procedure_desc["return"] == "char *":
|
||||||
binding += " lua_pushstring(L, %s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
binding += " lua_pushstring(L, %s(%s));\n" % (procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||||
elif type(procedure_desc["return"]) is dict or procedure_desc["return"] in api["types"]:
|
elif type(procedure_desc["return"]) is dict or procedure_desc["return"] in api["types"]:
|
||||||
# TODO: handle enums
|
|
||||||
type_desc = procedure_desc["return"] if type(procedure_desc["return"]) is dict else api["types"][procedure_desc["return"]]
|
type_desc = procedure_desc["return"] if type(procedure_desc["return"]) is dict else api["types"][procedure_desc["return"]]
|
||||||
binding += " %s result = %s(%s);\n" % (type_desc["c_type"], procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
binding += " %s result = %s(%s);\n" % (type_desc["c_type"], procedure, ", ".join(param["name"] for param in procedure_desc["params"]))
|
||||||
binding += to_table(type_desc, "result", 4)
|
binding += to_table(type_desc, "result", 4)
|
||||||
@ -150,21 +149,6 @@ for typename, typedesc in used_converters.items():
|
|||||||
raise BaseException("Unhandled converter field type '%s'" % (field["type"]))
|
raise BaseException("Unhandled converter field type '%s'" % (field["type"]))
|
||||||
converter += " lua_pop(L, %i);\n" % len(typedesc["fields"]);
|
converter += " lua_pop(L, %i);\n" % len(typedesc["fields"]);
|
||||||
|
|
||||||
# TODO: wild idea: use compile time built hash table
|
|
||||||
elif "enums" in typedesc:
|
|
||||||
storages += ["struct %sHashItem { char *key; %s value; };\nstatic struct %sHashItem *%s_map = NULL;\n" % (typename, typename, typename, typename.lower())]
|
|
||||||
|
|
||||||
# TODO: use arena
|
|
||||||
for enum in typedesc["enums"]:
|
|
||||||
initializer = " shput(%s_map, \"%s\", %s);" % (typename.lower(), enum, typedesc["enums"][enum])
|
|
||||||
initializers += [initializer]
|
|
||||||
|
|
||||||
deinitializers += [" shfree(%s_map);" % typename.lower()]
|
|
||||||
|
|
||||||
converter += " char const *value = lua_tostring(L, -1);\n";
|
|
||||||
converter += " %s = shget(%s_map, value);\n" % (typename.lower(), typename.lower())
|
|
||||||
converter += " lua_pop(L, 1);\n";
|
|
||||||
|
|
||||||
converter += " return %s;\n}\n" % (typename.lower())
|
converter += " return %s;\n}\n" % (typename.lower())
|
||||||
converters += [converter]
|
converters += [converter]
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ def to_lua_type_annot(typedesc):
|
|||||||
|
|
||||||
print("error(\"townengine lua api file is not supposed to be imported!\")")
|
print("error(\"townengine lua api file is not supposed to be imported!\")")
|
||||||
|
|
||||||
type_annotations, enum_annotations = {}, {}
|
type_annotations = {}
|
||||||
type_annotations["ctx"] = r"{ %s, udata: table }" % \
|
type_annotations["ctx"] = r"{ %s, udata: table }" % \
|
||||||
', '.join("%s: %s" % (f["name"], to_lua_type_annot(f["type"])) for f in api["types"]["Context"]["fields"])
|
', '.join("%s: %s" % (f["name"], to_lua_type_annot(f["type"])) for f in api["types"]["Context"]["fields"])
|
||||||
|
|
||||||
@ -41,12 +41,6 @@ for annot in type_annotations:
|
|||||||
print("---@type " + type_annotations[annot])
|
print("---@type " + type_annotations[annot])
|
||||||
print(r"%s = nil" % annot)
|
print(r"%s = nil" % annot)
|
||||||
|
|
||||||
enum_annotations["Control"] = \
|
|
||||||
'|'.join('\'"%s"\'' % e for e in api["types"]["Control"]["enums"])
|
|
||||||
|
|
||||||
for annot in enum_annotations:
|
|
||||||
print("---@alias %s %s" % (annot, enum_annotations[annot]))
|
|
||||||
|
|
||||||
procedure_annotations = {}
|
procedure_annotations = {}
|
||||||
for procedure, procedure_desc in api["procedures"].items():
|
for procedure, procedure_desc in api["procedures"].items():
|
||||||
procedure_annotations[procedure] = {}
|
procedure_annotations[procedure] = {}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/bin/env python3
|
#!/bin/env python3
|
||||||
|
|
||||||
from subprocess import getoutput, run
|
from subprocess import getoutput, run
|
||||||
|
from os import getcwd
|
||||||
from os.path import expandvars
|
from os.path import expandvars
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from sys import argv
|
from sys import argv
|
||||||
@ -22,6 +23,7 @@ cmake += ["-B", "build"]
|
|||||||
# TODO: have it --fast instead, where separate --no-debug would mean stripping the debug info
|
# TODO: have it --fast instead, where separate --no-debug would mean stripping the debug info
|
||||||
if "--release" in argv:
|
if "--release" in argv:
|
||||||
cmake += ["-DCMAKE_BUILD_TYPE=Release"]
|
cmake += ["-DCMAKE_BUILD_TYPE=Release"]
|
||||||
|
cmake += [f"-DTWN_OUT_DIR={getcwd()}"]
|
||||||
# pass arbitrary arguments over
|
# pass arbitrary arguments over
|
||||||
if "--" in argv:
|
if "--" in argv:
|
||||||
cmake += argv[argv.index("--")+1:]
|
cmake += argv[argv.index("--")+1:]
|
||||||
|
1
docs/wiki/.gitignore
vendored
Normal file
1
docs/wiki/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
!*.html
|
@ -5,9 +5,9 @@
|
|||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 style="margin-bottom:0in;">1. About Townengine</h1>
|
<h1 style="margin-bottom:0in;">T1. About Townengine</h1>
|
||||||
<a href="index.html">Go back
|
<a href="index.html">Go back
|
||||||
<p><a name="introduction"></a><strong>1.1 </strong><strong>Introduction</strong>
|
<p><a name="introduction"></a><strong>T1.1 </strong><strong>Introduction</strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Townengine, {twn}, is an opinionated game development framework designed around ideas of simplicity, managed state,
|
<p>Townengine, {twn}, is an opinionated game development framework designed around ideas of simplicity, managed state,
|
||||||
care for old devices, portability, language agnosticism, use-case orientation, iterability and low latency.
|
care for old devices, portability, language agnosticism, use-case orientation, iterability and low latency.
|
||||||
@ -34,7 +34,7 @@
|
|||||||
<p><b>Low latency.</b> Care is given to various incarnations of feared latency. Engine is fast to build, allowing for low commitment patches.
|
<p><b>Low latency.</b> Care is given to various incarnations of feared latency. Engine is fast to build, allowing for low commitment patches.
|
||||||
Startup time is profiled and optimized. Streaming is used as much as possible for asset load.
|
Startup time is profiled and optimized. Streaming is used as much as possible for asset load.
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p><a name="wiki"></a><strong>1.2 </strong><strong>Wiki</strong>
|
<p><a name="wiki"></a><strong>T1.2 </strong><strong>Wiki</strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Purpose of this wiki is to collect information on various usages of {twn} across the genres, FAQ style.
|
<p>Purpose of this wiki is to collect information on various usages of {twn} across the genres, FAQ style.
|
||||||
You're welcomed to contribute to it. It's written in HTML so basic you can edit it by hand.
|
You're welcomed to contribute to it. It's written in HTML so basic you can edit it by hand.
|
||||||
|
@ -5,20 +5,27 @@
|
|||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Townengine Wiki</h1>
|
<h1 style="margin-bottom:0in">Townengine Wiki</h1>
|
||||||
<table>
|
<a>Awesomeness</a>
|
||||||
<tr>
|
<table style="padding-top:1em">
|
||||||
<td><strong>1.</strong> <a href="#about-townengine">About Townengnine</a></td>
|
<tr><td>T1.</strong> <a href="#about-townengine">About Townengnine</a></td>
|
||||||
<td><strong>2.</strong> <a href="#making-2dot5d-shooters">Making 2.5D Shooters</a></td>
|
<td>G1.</strong> <a href="#making-2dot5d-shooters">Making 2.5D Shooters</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody></table>
|
<tr><td>T2.</strong> <a href="#input-system">Input System</a></td>
|
||||||
<p><a name="about-townengine"></a><strong>1. </strong><a href="about-townengine.html"><strong>About Townengine</strong></a></p>
|
</tr>
|
||||||
<blockquote>
|
</table>
|
||||||
<p style="margin:0">1.1 <a href="about-townengine.html#introduction">Introduction</a></p>
|
<p style="margin-bottom:0"><a name="about-townengine"></a>T1. </strong><a href="about-townengine.html">About Townengine</strong></a></p>
|
||||||
<p style="margin:0">1.2 <a href="about-townengine.html#wiki">Wiki</a></p>
|
<blockquote style="margin-top:0">
|
||||||
|
<p style="margin:0">T1.1 <a href="about-townengine.html#introduction">Introduction</a></p>
|
||||||
|
<p style="margin:0">T1.2 <a href="about-townengine.html#wiki">Wiki</a></p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p><a name="making-2dot5d-shooters"></a><strong>2. </strong><a href="making-2dot5d-shooters.html"><strong>Making 2.5D Shooters</strong></a></p>
|
<p style="margin-bottom:0"><a name="input-system"></a>T2. </strong><a href="input-system.html">Input System</strong></a></p>
|
||||||
<blockquote>
|
<blockquote style="margin-top:0">
|
||||||
|
<p style="margin:0">T2.1 <a href="input-system.html#design">Design</a></p>
|
||||||
|
<p style="margin:0">T2.2 <a href="input-system.html#api">API</a></p>
|
||||||
|
</blockquote>
|
||||||
|
<p style="margin-bottom:0"><a name="making-2dot5d-shooters"></a>G1. </strong><a href="making-2dot5d-shooters.html">Making 2.5D Shooters</strong></a></p>
|
||||||
|
<blockquote style="margin-top:0">
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
29
docs/wiki/input-system.html
Normal file
29
docs/wiki/input-system.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Townengine Wiki : Input System</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1 style="margin-bottom:0in;">T2. Input System</h1>
|
||||||
|
<a href="index.html">Go back
|
||||||
|
<p><a name="design"></a><strong>T2.1 </strong><strong>Design</strong>
|
||||||
|
<blockquote>
|
||||||
|
<p>One of goals is to make system that has the least variance in handling. We combine mouse inputs with keys
|
||||||
|
and don't use keycodes whatsoever. Key combinations are supported. Everything is represented with an encoded string:
|
||||||
|
<pre>[control+]+control</pre>
|
||||||
|
Any variant should be combinable, even things like mouse movement + key press.
|
||||||
|
<p>One current limitation of such design is that actions will only be reported in next frame after they
|
||||||
|
were first declared, creating delay. It's possible to fix it in the future however.
|
||||||
|
</blockquote>
|
||||||
|
<p><a name="api"></a><strong>T2.2 </strong><strong>API</strong>
|
||||||
|
<blockquote>
|
||||||
|
<p>It's rather small:<pre>
|
||||||
|
void input_action(const char *name, const char *control);
|
||||||
|
bool input_action_pressed(const char *name);
|
||||||
|
bool input_action_just_pressed(const char *name);
|
||||||
|
bool input_action_just_released(const char *name);
|
||||||
|
Vec2 input_action_position(const char *name);</pre>
|
||||||
|
</blockquote>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,19 +1,13 @@
|
|||||||
/* https://wiki.c2.com/?WikiStyle */
|
/* https://wiki.c2.com/?WikiStyle */
|
||||||
body { margin: 1em 2.3em 1em 1.5em; zoom: 150%; padding-bottom: 50px;}
|
body { margin: 1em 2.3em 1em 1.5em; zoom: 150%; padding-bottom: 1em; }
|
||||||
h1 { font-size: 2.1em;
|
h1 { font-size: 2.1em;
|
||||||
font-weight: bold;
|
font-weight: bold; }
|
||||||
}
|
p { margin-left: 0.2em; text-indent: 1em hanging; }
|
||||||
p { margin-left: 0.2em;
|
blockquote { font-style: normal; }
|
||||||
}
|
|
||||||
blockquote {
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
pre { margin: 0em 3em 0em 2em;
|
pre { margin: 0em 3em 0em 2em;
|
||||||
color: rgb(20%,20%,50%); background-color: rgb(100%,100%,100%);
|
color: rgb(20%,20%,50%); background-color: rgb(100%,100%,100%);
|
||||||
border: 1px solid rgb(50%,50%,50%);
|
border: 1px solid rgb(50%,50%,50%);
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
font-size: 0.85em;
|
margin-bottom: 2em;
|
||||||
white-space: pre;
|
white-space: pre; }
|
||||||
}
|
hr { color: rgb(30%,30%,60%); }
|
||||||
hr { color: rgb(30%,30%,60%);
|
|
||||||
}
|
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 style="margin-bottom:0in;">1. {About}</h1>
|
<h1 style="margin-bottom:0in;">X1. {About}</h1>
|
||||||
<a href="index.html">Go back
|
<a href="index.html">Go back
|
||||||
<p><a name="{Section}"></a><strong>1.1 </strong><strong>{Section}</strong>
|
<p><a name="{Section}"></a><strong>X1.1 </strong><strong>{Section}</strong>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Text
|
<p>Text
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
@ -1,433 +0,0 @@
|
|||||||
#ifndef TWN_CONTROL_H
|
|
||||||
#define TWN_CONTROL_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
Simple DirectMedia Layer
|
|
||||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* based on SDL2 */
|
|
||||||
/* main difference is that we combine mouse and scancode sources into one enum space */
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
CONTROL_SCANCODE_START = 0,
|
|
||||||
CONTROL_UNKNOWN = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Usage page 0x07
|
|
||||||
*
|
|
||||||
* These values are from usage page 0x07 (USB keyboard page).
|
|
||||||
*/
|
|
||||||
/* @{ */
|
|
||||||
|
|
||||||
CONTROL_A = 4,
|
|
||||||
CONTROL_B = 5,
|
|
||||||
CONTROL_C = 6,
|
|
||||||
CONTROL_D = 7,
|
|
||||||
CONTROL_E = 8,
|
|
||||||
CONTROL_F = 9,
|
|
||||||
CONTROL_G = 10,
|
|
||||||
CONTROL_H = 11,
|
|
||||||
CONTROL_I = 12,
|
|
||||||
CONTROL_J = 13,
|
|
||||||
CONTROL_K = 14,
|
|
||||||
CONTROL_L = 15,
|
|
||||||
CONTROL_M = 16,
|
|
||||||
CONTROL_N = 17,
|
|
||||||
CONTROL_O = 18,
|
|
||||||
CONTROL_P = 19,
|
|
||||||
CONTROL_Q = 20,
|
|
||||||
CONTROL_R = 21,
|
|
||||||
CONTROL_S = 22,
|
|
||||||
CONTROL_T = 23,
|
|
||||||
CONTROL_U = 24,
|
|
||||||
CONTROL_V = 25,
|
|
||||||
CONTROL_W = 26,
|
|
||||||
CONTROL_X = 27,
|
|
||||||
CONTROL_Y = 28,
|
|
||||||
CONTROL_Z = 29,
|
|
||||||
|
|
||||||
CONTROL_1 = 30,
|
|
||||||
CONTROL_2 = 31,
|
|
||||||
CONTROL_3 = 32,
|
|
||||||
CONTROL_4 = 33,
|
|
||||||
CONTROL_5 = 34,
|
|
||||||
CONTROL_6 = 35,
|
|
||||||
CONTROL_7 = 36,
|
|
||||||
CONTROL_8 = 37,
|
|
||||||
CONTROL_9 = 38,
|
|
||||||
CONTROL_0 = 39,
|
|
||||||
|
|
||||||
CONTROL_RETURN = 40,
|
|
||||||
CONTROL_ESCAPE = 41,
|
|
||||||
CONTROL_BACKSPACE = 42,
|
|
||||||
CONTROL_TAB = 43,
|
|
||||||
CONTROL_SPACE = 44,
|
|
||||||
|
|
||||||
CONTROL_MINUS = 45,
|
|
||||||
CONTROL_EQUALS = 46,
|
|
||||||
CONTROL_LEFTBRACKET = 47,
|
|
||||||
CONTROL_RIGHTBRACKET = 48,
|
|
||||||
CONTROL_BACKSLASH = 49, /**< Located at the lower left of the return
|
|
||||||
* key on ISO keyboards and at the right end
|
|
||||||
* of the QWERTY row on ANSI keyboards.
|
|
||||||
* Produces REVERSE SOLIDUS (backslash) and
|
|
||||||
* VERTICAL LINE in a US layout, REVERSE
|
|
||||||
* SOLIDUS and VERTICAL LINE in a UK Mac
|
|
||||||
* layout, NUMBER SIGN and TILDE in a UK
|
|
||||||
* Windows layout, DOLLAR SIGN and POUND SIGN
|
|
||||||
* in a Swiss German layout, NUMBER SIGN and
|
|
||||||
* APOSTROPHE in a German layout, GRAVE
|
|
||||||
* ACCENT and POUND SIGN in a French Mac
|
|
||||||
* layout, and ASTERISK and MICRO SIGN in a
|
|
||||||
* French Windows layout.
|
|
||||||
*/
|
|
||||||
CONTROL_NONUSHASH = 50, /**< ISO USB keyboards actually use this code
|
|
||||||
* instead of 49 for the same key, but all
|
|
||||||
* OSes I've seen treat the two codes
|
|
||||||
* identically. So, as an implementor, unless
|
|
||||||
* your keyboard generates both of those
|
|
||||||
* codes and your OS treats them differently,
|
|
||||||
* you should generate CONTROL_BACKSLASH
|
|
||||||
* instead of this code. As a user, you
|
|
||||||
* should not rely on this code because SDL
|
|
||||||
* will never generate it with most (all?)
|
|
||||||
* keyboards.
|
|
||||||
*/
|
|
||||||
CONTROL_SEMICOLON = 51,
|
|
||||||
CONTROL_APOSTROPHE = 52,
|
|
||||||
CONTROL_GRAVE = 53, /**< Located in the top left corner (on both ANSI
|
|
||||||
* and ISO keyboards). Produces GRAVE ACCENT and
|
|
||||||
* TILDE in a US Windows layout and in US and UK
|
|
||||||
* Mac layouts on ANSI keyboards, GRAVE ACCENT
|
|
||||||
* and NOT SIGN in a UK Windows layout, SECTION
|
|
||||||
* SIGN and PLUS-MINUS SIGN in US and UK Mac
|
|
||||||
* layouts on ISO keyboards, SECTION SIGN and
|
|
||||||
* DEGREE SIGN in a Swiss German layout (Mac:
|
|
||||||
* only on ISO keyboards), CIRCUMFLEX ACCENT and
|
|
||||||
* DEGREE SIGN in a German layout (Mac: only on
|
|
||||||
* ISO keyboards), SUPERSCRIPT TWO and TILDE in a
|
|
||||||
* French Windows layout, COMMERCIAL AT and
|
|
||||||
* NUMBER SIGN in a French Mac layout on ISO
|
|
||||||
* keyboards, and LESS-THAN SIGN and GREATER-THAN
|
|
||||||
* SIGN in a Swiss German, German, or French Mac
|
|
||||||
* layout on ANSI keyboards.
|
|
||||||
*/
|
|
||||||
CONTROL_COMMA = 54,
|
|
||||||
CONTROL_PERIOD = 55,
|
|
||||||
CONTROL_SLASH = 56,
|
|
||||||
|
|
||||||
CONTROL_CAPSLOCK = 57,
|
|
||||||
|
|
||||||
CONTROL_F1 = 58,
|
|
||||||
CONTROL_F2 = 59,
|
|
||||||
CONTROL_F3 = 60,
|
|
||||||
CONTROL_F4 = 61,
|
|
||||||
CONTROL_F5 = 62,
|
|
||||||
CONTROL_F6 = 63,
|
|
||||||
CONTROL_F7 = 64,
|
|
||||||
CONTROL_F8 = 65,
|
|
||||||
CONTROL_F9 = 66,
|
|
||||||
CONTROL_F10 = 67,
|
|
||||||
CONTROL_F11 = 68,
|
|
||||||
CONTROL_F12 = 69,
|
|
||||||
|
|
||||||
CONTROL_PRINTSCREEN = 70,
|
|
||||||
CONTROL_SCROLLLOCK = 71,
|
|
||||||
CONTROL_PAUSE = 72,
|
|
||||||
CONTROL_INSERT = 73, /**< insert on PC, help on some Mac keyboards (but
|
|
||||||
does send code 73, not 117) */
|
|
||||||
CONTROL_HOME = 74,
|
|
||||||
CONTROL_PAGEUP = 75,
|
|
||||||
CONTROL_DELETE = 76,
|
|
||||||
CONTROL_END = 77,
|
|
||||||
CONTROL_PAGEDOWN = 78,
|
|
||||||
CONTROL_RIGHT = 79,
|
|
||||||
CONTROL_LEFT = 80,
|
|
||||||
CONTROL_DOWN = 81,
|
|
||||||
CONTROL_UP = 82,
|
|
||||||
|
|
||||||
CONTROL_NUMLOCKCLEAR = 83, /**< num lock on PC, clear on Mac keyboards
|
|
||||||
*/
|
|
||||||
CONTROL_KP_DIVIDE = 84,
|
|
||||||
CONTROL_KP_MULTIPLY = 85,
|
|
||||||
CONTROL_KP_MINUS = 86,
|
|
||||||
CONTROL_KP_PLUS = 87,
|
|
||||||
CONTROL_KP_ENTER = 88,
|
|
||||||
CONTROL_KP_1 = 89,
|
|
||||||
CONTROL_KP_2 = 90,
|
|
||||||
CONTROL_KP_3 = 91,
|
|
||||||
CONTROL_KP_4 = 92,
|
|
||||||
CONTROL_KP_5 = 93,
|
|
||||||
CONTROL_KP_6 = 94,
|
|
||||||
CONTROL_KP_7 = 95,
|
|
||||||
CONTROL_KP_8 = 96,
|
|
||||||
CONTROL_KP_9 = 97,
|
|
||||||
CONTROL_KP_0 = 98,
|
|
||||||
CONTROL_KP_PERIOD = 99,
|
|
||||||
|
|
||||||
CONTROL_NONUSBACKSLASH = 100, /**< This is the additional key that ISO
|
|
||||||
* keyboards have over ANSI ones,
|
|
||||||
* located between left shift and Y.
|
|
||||||
* Produces GRAVE ACCENT and TILDE in a
|
|
||||||
* US or UK Mac layout, REVERSE SOLIDUS
|
|
||||||
* (backslash) and VERTICAL LINE in a
|
|
||||||
* US or UK Windows layout, and
|
|
||||||
* LESS-THAN SIGN and GREATER-THAN SIGN
|
|
||||||
* in a Swiss German, German, or French
|
|
||||||
* layout. */
|
|
||||||
CONTROL_APPLICATION = 101, /**< windows contextual menu, compose */
|
|
||||||
CONTROL_POWER = 102, /**< The USB document says this is a status flag,
|
|
||||||
* not a physical key - but some Mac keyboards
|
|
||||||
* do have a power key. */
|
|
||||||
CONTROL_KP_EQUALS = 103,
|
|
||||||
CONTROL_F13 = 104,
|
|
||||||
CONTROL_F14 = 105,
|
|
||||||
CONTROL_F15 = 106,
|
|
||||||
CONTROL_F16 = 107,
|
|
||||||
CONTROL_F17 = 108,
|
|
||||||
CONTROL_F18 = 109,
|
|
||||||
CONTROL_F19 = 110,
|
|
||||||
CONTROL_F20 = 111,
|
|
||||||
CONTROL_F21 = 112,
|
|
||||||
CONTROL_F22 = 113,
|
|
||||||
CONTROL_F23 = 114,
|
|
||||||
CONTROL_F24 = 115,
|
|
||||||
CONTROL_EXECUTE = 116,
|
|
||||||
CONTROL_HELP = 117, /**< AL Integrated Help Center */
|
|
||||||
CONTROL_MENU = 118, /**< Menu (show menu) */
|
|
||||||
CONTROL_SELECT = 119,
|
|
||||||
CONTROL_STOP = 120, /**< AC Stop */
|
|
||||||
CONTROL_AGAIN = 121, /**< AC Redo/Repeat */
|
|
||||||
CONTROL_UNDO = 122, /**< AC Undo */
|
|
||||||
CONTROL_CUT = 123, /**< AC Cut */
|
|
||||||
CONTROL_COPY = 124, /**< AC Copy */
|
|
||||||
CONTROL_PASTE = 125, /**< AC Paste */
|
|
||||||
CONTROL_FIND = 126, /**< AC Find */
|
|
||||||
CONTROL_MUTE = 127,
|
|
||||||
CONTROL_VOLUMEUP = 128,
|
|
||||||
CONTROL_VOLUMEDOWN = 129,
|
|
||||||
/* not sure whether there's a reason to enable these */
|
|
||||||
/* CONTROL_LOCKINGCAPSLOCK = 130, */
|
|
||||||
/* CONTROL_LOCKINGNUMLOCK = 131, */
|
|
||||||
/* CONTROL_LOCKINGSCROLLLOCK = 132, */
|
|
||||||
CONTROL_KP_COMMA = 133,
|
|
||||||
CONTROL_KP_EQUALSAS400 = 134,
|
|
||||||
|
|
||||||
CONTROL_INTERNATIONAL1 = 135, /**< used on Asian keyboards, see
|
|
||||||
footnotes in USB doc */
|
|
||||||
CONTROL_INTERNATIONAL2 = 136,
|
|
||||||
CONTROL_INTERNATIONAL3 = 137, /**< Yen */
|
|
||||||
CONTROL_INTERNATIONAL4 = 138,
|
|
||||||
CONTROL_INTERNATIONAL5 = 139,
|
|
||||||
CONTROL_INTERNATIONAL6 = 140,
|
|
||||||
CONTROL_INTERNATIONAL7 = 141,
|
|
||||||
CONTROL_INTERNATIONAL8 = 142,
|
|
||||||
CONTROL_INTERNATIONAL9 = 143,
|
|
||||||
CONTROL_LANG1 = 144, /**< Hangul/English toggle */
|
|
||||||
CONTROL_LANG2 = 145, /**< Hanja conversion */
|
|
||||||
CONTROL_LANG3 = 146, /**< Katakana */
|
|
||||||
CONTROL_LANG4 = 147, /**< Hiragana */
|
|
||||||
CONTROL_LANG5 = 148, /**< Zenkaku/Hankaku */
|
|
||||||
CONTROL_LANG6 = 149, /**< reserved */
|
|
||||||
CONTROL_LANG7 = 150, /**< reserved */
|
|
||||||
CONTROL_LANG8 = 151, /**< reserved */
|
|
||||||
CONTROL_LANG9 = 152, /**< reserved */
|
|
||||||
|
|
||||||
CONTROL_ALTERASE = 153, /**< Erase-Eaze */
|
|
||||||
CONTROL_SYSREQ = 154,
|
|
||||||
CONTROL_CANCEL = 155, /**< AC Cancel */
|
|
||||||
CONTROL_CLEAR = 156,
|
|
||||||
CONTROL_PRIOR = 157,
|
|
||||||
CONTROL_RETURN2 = 158,
|
|
||||||
CONTROL_SEPARATOR = 159,
|
|
||||||
CONTROL_OUT = 160,
|
|
||||||
CONTROL_OPER = 161,
|
|
||||||
CONTROL_CLEARAGAIN = 162,
|
|
||||||
CONTROL_CRSEL = 163,
|
|
||||||
CONTROL_EXSEL = 164,
|
|
||||||
|
|
||||||
CONTROL_KP_00 = 176,
|
|
||||||
CONTROL_KP_000 = 177,
|
|
||||||
CONTROL_THOUSANDSSEPARATOR = 178,
|
|
||||||
CONTROL_DECIMALSEPARATOR = 179,
|
|
||||||
CONTROL_CURRENCYUNIT = 180,
|
|
||||||
CONTROL_CURRENCYSUBUNIT = 181,
|
|
||||||
CONTROL_KP_LEFTPAREN = 182,
|
|
||||||
CONTROL_KP_RIGHTPAREN = 183,
|
|
||||||
CONTROL_KP_LEFTBRACE = 184,
|
|
||||||
CONTROL_KP_RIGHTBRACE = 185,
|
|
||||||
CONTROL_KP_TAB = 186,
|
|
||||||
CONTROL_KP_BACKSPACE = 187,
|
|
||||||
CONTROL_KP_A = 188,
|
|
||||||
CONTROL_KP_B = 189,
|
|
||||||
CONTROL_KP_C = 190,
|
|
||||||
CONTROL_KP_D = 191,
|
|
||||||
CONTROL_KP_E = 192,
|
|
||||||
CONTROL_KP_F = 193,
|
|
||||||
CONTROL_KP_XOR = 194,
|
|
||||||
CONTROL_KP_POWER = 195,
|
|
||||||
CONTROL_KP_PERCENT = 196,
|
|
||||||
CONTROL_KP_LESS = 197,
|
|
||||||
CONTROL_KP_GREATER = 198,
|
|
||||||
CONTROL_KP_AMPERSAND = 199,
|
|
||||||
CONTROL_KP_DBLAMPERSAND = 200,
|
|
||||||
CONTROL_KP_VERTICALBAR = 201,
|
|
||||||
CONTROL_KP_DBLVERTICALBAR = 202,
|
|
||||||
CONTROL_KP_COLON = 203,
|
|
||||||
CONTROL_KP_HASH = 204,
|
|
||||||
CONTROL_KP_SPACE = 205,
|
|
||||||
CONTROL_KP_AT = 206,
|
|
||||||
CONTROL_KP_EXCLAM = 207,
|
|
||||||
CONTROL_KP_MEMSTORE = 208,
|
|
||||||
CONTROL_KP_MEMRECALL = 209,
|
|
||||||
CONTROL_KP_MEMCLEAR = 210,
|
|
||||||
CONTROL_KP_MEMADD = 211,
|
|
||||||
CONTROL_KP_MEMSUBTRACT = 212,
|
|
||||||
CONTROL_KP_MEMMULTIPLY = 213,
|
|
||||||
CONTROL_KP_MEMDIVIDE = 214,
|
|
||||||
CONTROL_KP_PLUSMINUS = 215,
|
|
||||||
CONTROL_KP_CLEAR = 216,
|
|
||||||
CONTROL_KP_CLEARENTRY = 217,
|
|
||||||
CONTROL_KP_BINARY = 218,
|
|
||||||
CONTROL_KP_OCTAL = 219,
|
|
||||||
CONTROL_KP_DECIMAL = 220,
|
|
||||||
CONTROL_KP_HEXADECIMAL = 221,
|
|
||||||
|
|
||||||
CONTROL_LCTRL = 224,
|
|
||||||
CONTROL_LSHIFT = 225,
|
|
||||||
CONTROL_LALT = 226, /**< alt, option */
|
|
||||||
CONTROL_LGUI = 227, /**< windows, command (apple), meta */
|
|
||||||
CONTROL_RCTRL = 228,
|
|
||||||
CONTROL_RSHIFT = 229,
|
|
||||||
CONTROL_RALT = 230, /**< alt gr, option */
|
|
||||||
CONTROL_RGUI = 231, /**< windows, command (apple), meta */
|
|
||||||
|
|
||||||
CONTROL_MODE = 257, /**< I'm not sure if this is really not covered
|
|
||||||
* by any of the above, but since there's a
|
|
||||||
* special KMOD_MODE for it I'm adding it here
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* @} *//* Usage page 0x07 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Usage page 0x0C
|
|
||||||
*
|
|
||||||
* These values are mapped from usage page 0x0C (USB consumer page).
|
|
||||||
* See https://usb.org/sites/default/files/hut1_2.pdf
|
|
||||||
*
|
|
||||||
* There are way more keys in the spec than we can represent in the
|
|
||||||
* current scancode range, so pick the ones that commonly come up in
|
|
||||||
* real world usage.
|
|
||||||
*/
|
|
||||||
/* @{ */
|
|
||||||
|
|
||||||
CONTROL_AUDIONEXT = 258,
|
|
||||||
CONTROL_AUDIOPREV = 259,
|
|
||||||
CONTROL_AUDIOSTOP = 260,
|
|
||||||
CONTROL_AUDIOPLAY = 261,
|
|
||||||
CONTROL_AUDIOMUTE = 262,
|
|
||||||
CONTROL_MEDIASELECT = 263,
|
|
||||||
CONTROL_WWW = 264, /**< AL Internet Browser */
|
|
||||||
CONTROL_MAIL = 265,
|
|
||||||
CONTROL_CALCULATOR = 266, /**< AL Calculator */
|
|
||||||
CONTROL_COMPUTER = 267,
|
|
||||||
CONTROL_AC_SEARCH = 268, /**< AC Search */
|
|
||||||
CONTROL_AC_HOME = 269, /**< AC Home */
|
|
||||||
CONTROL_AC_BACK = 270, /**< AC Back */
|
|
||||||
CONTROL_AC_FORWARD = 271, /**< AC Forward */
|
|
||||||
CONTROL_AC_STOP = 272, /**< AC Stop */
|
|
||||||
CONTROL_AC_REFRESH = 273, /**< AC Refresh */
|
|
||||||
CONTROL_AC_BOOKMARKS = 274, /**< AC Bookmarks */
|
|
||||||
|
|
||||||
/* @} *//* Usage page 0x0C */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Walther keys
|
|
||||||
*
|
|
||||||
* These are values that Christian Walther added (for mac keyboard?).
|
|
||||||
*/
|
|
||||||
/* @{ */
|
|
||||||
|
|
||||||
CONTROL_BRIGHTNESSDOWN = 275,
|
|
||||||
CONTROL_BRIGHTNESSUP = 276,
|
|
||||||
CONTROL_DISPLAYSWITCH = 277, /**< display mirroring/dual display
|
|
||||||
switch, video mode switch */
|
|
||||||
CONTROL_KBDILLUMTOGGLE = 278,
|
|
||||||
CONTROL_KBDILLUMDOWN = 279,
|
|
||||||
CONTROL_KBDILLUMUP = 280,
|
|
||||||
CONTROL_EJECT = 281,
|
|
||||||
CONTROL_SLEEP = 282, /**< SC System Sleep */
|
|
||||||
|
|
||||||
CONTROL_APP1 = 283,
|
|
||||||
CONTROL_APP2 = 284,
|
|
||||||
|
|
||||||
/* @} *//* Walther keys */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Usage page 0x0C (additional media keys)
|
|
||||||
*
|
|
||||||
* These values are mapped from usage page 0x0C (USB consumer page).
|
|
||||||
*/
|
|
||||||
/* @{ */
|
|
||||||
|
|
||||||
CONTROL_AUDIOREWIND = 285,
|
|
||||||
CONTROL_AUDIOFASTFORWARD = 286,
|
|
||||||
|
|
||||||
/* @} *//* Usage page 0x0C (additional media keys) */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \name Mobile keys
|
|
||||||
*
|
|
||||||
* These are values that are often used on mobile phones.
|
|
||||||
*/
|
|
||||||
/* @{ */
|
|
||||||
|
|
||||||
CONTROL_SOFTLEFT = 287, /**< Usually situated below the display on phones and
|
|
||||||
used as a multi-function feature key for selecting
|
|
||||||
a software defined function shown on the bottom left
|
|
||||||
of the display. */
|
|
||||||
CONTROL_SOFTRIGHT = 288, /**< Usually situated below the display on phones and
|
|
||||||
used as a multi-function feature key for selecting
|
|
||||||
a software defined function shown on the bottom right
|
|
||||||
of the display. */
|
|
||||||
CONTROL_CALL = 289, /**< Used for accepting phone calls. */
|
|
||||||
CONTROL_ENDCALL = 290, /**< Used for rejecting phone calls. */
|
|
||||||
|
|
||||||
/* @} *//* Mobile keys */
|
|
||||||
|
|
||||||
/* Add any other keys here. */
|
|
||||||
|
|
||||||
CONTROL_SCANCODE_LIMIT = 512, /**< not a key, just marks the number of scancodes
|
|
||||||
for array bounds */
|
|
||||||
|
|
||||||
CONTROL_MOUSECODE_START = 512,
|
|
||||||
|
|
||||||
CONTROL_LEFT_MOUSE = 513,
|
|
||||||
CONTROL_RIGHT_MOUSE = 515,
|
|
||||||
CONTROL_MIDDLE_MOUSE = 514,
|
|
||||||
CONTROL_X1 = 516,
|
|
||||||
CONTROL_X2 = 517,
|
|
||||||
|
|
||||||
CONTROL_MOUSECODE_LIMIT = 532,
|
|
||||||
|
|
||||||
} Control;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,16 +1,14 @@
|
|||||||
#ifndef TWN_INPUT_H
|
#ifndef TWN_INPUT_H
|
||||||
#define TWN_INPUT_H
|
#define TWN_INPUT_H
|
||||||
|
|
||||||
#include "twn_types.h"
|
|
||||||
#include "twn_engine_api.h"
|
#include "twn_engine_api.h"
|
||||||
#include "twn_control.h"
|
#include "twn_types.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
TWN_API void input_action(const char *name, const char *control);
|
||||||
TWN_API void input_action(const char *name, Control control);
|
|
||||||
TWN_API bool input_action_pressed(const char *name);
|
TWN_API bool input_action_pressed(const char *name);
|
||||||
TWN_API bool input_action_just_pressed(const char *name);
|
TWN_API bool input_action_just_pressed(const char *name);
|
||||||
TWN_API bool input_action_just_released(const char *name);
|
TWN_API bool input_action_just_released(const char *name);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"header": "twn_input.h",
|
"header": "twn_input.h",
|
||||||
"params": [
|
"params": [
|
||||||
{ "name": "name", "type": "char *" },
|
{ "name": "name", "type": "char *" },
|
||||||
{ "name": "control", "type": "Control" }
|
{ "name": "control", "type": "char *" }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -354,242 +354,6 @@
|
|||||||
{ "name": "mouse_capture", "type": "bool" }
|
{ "name": "mouse_capture", "type": "bool" }
|
||||||
],
|
],
|
||||||
"c_type": "Context"
|
"c_type": "Context"
|
||||||
},
|
|
||||||
|
|
||||||
"Control": {
|
|
||||||
"enums": {
|
|
||||||
"A": 4,
|
|
||||||
"B": 5,
|
|
||||||
"C": 6,
|
|
||||||
"D": 7,
|
|
||||||
"E": 8,
|
|
||||||
"F": 9,
|
|
||||||
"G": 10,
|
|
||||||
"H": 11,
|
|
||||||
"I": 12,
|
|
||||||
"J": 13,
|
|
||||||
"K": 14,
|
|
||||||
"L": 15,
|
|
||||||
"M": 16,
|
|
||||||
"N": 17,
|
|
||||||
"O": 18,
|
|
||||||
"P": 19,
|
|
||||||
"Q": 20,
|
|
||||||
"R": 21,
|
|
||||||
"S": 22,
|
|
||||||
"T": 23,
|
|
||||||
"U": 24,
|
|
||||||
"V": 25,
|
|
||||||
"W": 26,
|
|
||||||
"X": 27,
|
|
||||||
"Y": 28,
|
|
||||||
"Z": 29,
|
|
||||||
"1": 30,
|
|
||||||
"2": 31,
|
|
||||||
"3": 32,
|
|
||||||
"4": 33,
|
|
||||||
"5": 34,
|
|
||||||
"6": 35,
|
|
||||||
"7": 36,
|
|
||||||
"8": 37,
|
|
||||||
"9": 38,
|
|
||||||
"0": 39,
|
|
||||||
"RETURN": 40,
|
|
||||||
"ESCAPE": 41,
|
|
||||||
"BACKSPACE": 42,
|
|
||||||
"TAB": 43,
|
|
||||||
"SPACE": 44,
|
|
||||||
"MINUS": 45,
|
|
||||||
"EQUALS": 46,
|
|
||||||
"LEFTBRACKET": 47,
|
|
||||||
"RIGHTBRACKET": 48,
|
|
||||||
"BACKSLASH": 49,
|
|
||||||
"NONUSHASH": 50,
|
|
||||||
"SEMICOLON": 51,
|
|
||||||
"APOSTROPHE": 52,
|
|
||||||
"GRAVE": 53,
|
|
||||||
"COMMA": 54,
|
|
||||||
"PERIOD": 55,
|
|
||||||
"SLASH": 56,
|
|
||||||
"CAPSLOCK": 57,
|
|
||||||
"F1": 58,
|
|
||||||
"F2": 59,
|
|
||||||
"F3": 60,
|
|
||||||
"F4": 61,
|
|
||||||
"F5": 62,
|
|
||||||
"F6": 63,
|
|
||||||
"F7": 64,
|
|
||||||
"F8": 65,
|
|
||||||
"F9": 66,
|
|
||||||
"F10": 67,
|
|
||||||
"F11": 68,
|
|
||||||
"F12": 69,
|
|
||||||
"PRINTSCREEN": 70,
|
|
||||||
"SCROLLLOCK": 71,
|
|
||||||
"PAUSE": 72,
|
|
||||||
"INSERT": 73,
|
|
||||||
"HOME": 74,
|
|
||||||
"PAGEUP": 75,
|
|
||||||
"DELETE": 76,
|
|
||||||
"END": 77,
|
|
||||||
"PAGEDOWN": 78,
|
|
||||||
"RIGHT": 79,
|
|
||||||
"LEFT": 80,
|
|
||||||
"DOWN": 81,
|
|
||||||
"UP": 82,
|
|
||||||
"NUMLOCKCLEAR": 83,
|
|
||||||
"KP_DIVIDE": 84,
|
|
||||||
"KP_MULTIPLY": 85,
|
|
||||||
"KP_MINUS": 86,
|
|
||||||
"KP_PLUS": 87,
|
|
||||||
"KP_ENTER": 88,
|
|
||||||
"KP_1": 89,
|
|
||||||
"KP_2": 90,
|
|
||||||
"KP_3": 91,
|
|
||||||
"KP_4": 92,
|
|
||||||
"KP_5": 93,
|
|
||||||
"KP_6": 94,
|
|
||||||
"KP_7": 95,
|
|
||||||
"KP_8": 96,
|
|
||||||
"KP_9": 97,
|
|
||||||
"KP_0": 98,
|
|
||||||
"KP_PERIOD": 99,
|
|
||||||
"NONUSBACKSLASH": 100,
|
|
||||||
"APPLICATION": 101,
|
|
||||||
"POWER": 102,
|
|
||||||
"KP_EQUALS": 103,
|
|
||||||
"F13": 104,
|
|
||||||
"F14": 105,
|
|
||||||
"F15": 106,
|
|
||||||
"F16": 107,
|
|
||||||
"F17": 108,
|
|
||||||
"F18": 109,
|
|
||||||
"F19": 110,
|
|
||||||
"F20": 111,
|
|
||||||
"F21": 112,
|
|
||||||
"F22": 113,
|
|
||||||
"F23": 114,
|
|
||||||
"F24": 115,
|
|
||||||
"EXECUTE": 116,
|
|
||||||
"HELP": 117,
|
|
||||||
"MENU": 118,
|
|
||||||
"SELECT": 119,
|
|
||||||
"STOP": 120,
|
|
||||||
"AGAIN": 121,
|
|
||||||
"UNDO": 122,
|
|
||||||
"CUT": 123,
|
|
||||||
"COPY": 124,
|
|
||||||
"PASTE": 125,
|
|
||||||
"FIND": 126,
|
|
||||||
"MUTE": 127,
|
|
||||||
"VOLUMEUP": 128,
|
|
||||||
"VOLUMEDOWN": 129,
|
|
||||||
"KP_COMMA": 133,
|
|
||||||
"KP_EQUALSAS400": 134,
|
|
||||||
"INTERNATIONAL1": 135,
|
|
||||||
"INTERNATIONAL2": 136,
|
|
||||||
"INTERNATIONAL3": 137,
|
|
||||||
"INTERNATIONAL4": 138,
|
|
||||||
"INTERNATIONAL5": 139,
|
|
||||||
"INTERNATIONAL6": 140,
|
|
||||||
"INTERNATIONAL7": 141,
|
|
||||||
"INTERNATIONAL8": 142,
|
|
||||||
"INTERNATIONAL9": 143,
|
|
||||||
"LANG1": 144,
|
|
||||||
"LANG2": 145,
|
|
||||||
"LANG3": 146,
|
|
||||||
"LANG4": 147,
|
|
||||||
"LANG5": 148,
|
|
||||||
"LANG6": 149,
|
|
||||||
"LANG7": 150,
|
|
||||||
"LANG8": 151,
|
|
||||||
"LANG9": 152,
|
|
||||||
"ALTERASE": 153,
|
|
||||||
"SYSREQ": 154,
|
|
||||||
"CANCEL": 155,
|
|
||||||
"CLEAR": 156,
|
|
||||||
"PRIOR": 157,
|
|
||||||
"RETURN2": 158,
|
|
||||||
"SEPARATOR": 159,
|
|
||||||
"OUT": 160,
|
|
||||||
"OPER": 161,
|
|
||||||
"CLEARAGAIN": 162,
|
|
||||||
"CRSEL": 163,
|
|
||||||
"EXSEL": 164,
|
|
||||||
"KP_00": 176,
|
|
||||||
"KP_000": 177,
|
|
||||||
"THOUSANDSSEPARATOR": 178,
|
|
||||||
"DECIMALSEPARATOR": 179,
|
|
||||||
"CURRENCYUNIT": 180,
|
|
||||||
"CURRENCYSUBUNIT": 181,
|
|
||||||
"KP_LEFTPAREN": 182,
|
|
||||||
"KP_RIGHTPAREN": 183,
|
|
||||||
"KP_LEFTBRACE": 184,
|
|
||||||
"KP_RIGHTBRACE": 185,
|
|
||||||
"KP_TAB": 186,
|
|
||||||
"KP_BACKSPACE": 187,
|
|
||||||
"KP_A": 188,
|
|
||||||
"KP_B": 189,
|
|
||||||
"KP_C": 190,
|
|
||||||
"KP_D": 191,
|
|
||||||
"KP_E": 192,
|
|
||||||
"KP_F": 193,
|
|
||||||
"KP_XOR": 194,
|
|
||||||
"KP_POWER": 195,
|
|
||||||
"KP_PERCENT": 196,
|
|
||||||
"KP_LESS": 197,
|
|
||||||
"KP_GREATER": 198,
|
|
||||||
"KP_AMPERSAND": 199,
|
|
||||||
"KP_DBLAMPERSAND": 200,
|
|
||||||
"KP_VERTICALBAR": 201,
|
|
||||||
"KP_DBLVERTICALBAR": 202,
|
|
||||||
"KP_COLON": 203,
|
|
||||||
"KP_HASH": 204,
|
|
||||||
"KP_SPACE": 205,
|
|
||||||
"KP_AT": 206,
|
|
||||||
"KP_EXCLAM": 207,
|
|
||||||
"KP_MEMSTORE": 208,
|
|
||||||
"KP_MEMRECALL": 209,
|
|
||||||
"KP_MEMCLEAR": 210,
|
|
||||||
"KP_MEMADD": 211,
|
|
||||||
"KP_MEMSUBTRACT": 212,
|
|
||||||
"KP_MEMMULTIPLY": 213,
|
|
||||||
"KP_MEMDIVIDE": 214,
|
|
||||||
"KP_PLUSMINUS": 215,
|
|
||||||
"KP_CLEAR": 216,
|
|
||||||
"KP_CLEARENTRY": 217,
|
|
||||||
"KP_BINARY": 218,
|
|
||||||
"KP_OCTAL": 219,
|
|
||||||
"KP_DECIMAL": 220,
|
|
||||||
"KP_HEXADECIMAL": 221,
|
|
||||||
"LCTRL": 224,
|
|
||||||
"LSHIFT": 225,
|
|
||||||
"LALT": 226,
|
|
||||||
"LGUI": 227,
|
|
||||||
"RCTRL": 228,
|
|
||||||
"RSHIFT": 229,
|
|
||||||
"RALT": 230,
|
|
||||||
"RGUI": 231,
|
|
||||||
"MODE": 257,
|
|
||||||
"KBDILLUMTOGGLE": 278,
|
|
||||||
"KBDILLUMDOWN": 279,
|
|
||||||
"KBDILLUMUP": 280,
|
|
||||||
"EJECT": 281,
|
|
||||||
"SLEEP": 282,
|
|
||||||
"APP1": 283,
|
|
||||||
"APP2": 284,
|
|
||||||
"AUDIOREWIND": 285,
|
|
||||||
"AUDIOFASTFORWARD": 286,
|
|
||||||
"SOFTLEFT": 287,
|
|
||||||
"SOFTRIGHT": 288,
|
|
||||||
"CALL": 289,
|
|
||||||
"ENDCALL": 290,
|
|
||||||
"LEFT_MOUSE": 513,
|
|
||||||
"RIGHT_MOUSE": 515,
|
|
||||||
"MIDDLE_MOUSE": 514,
|
|
||||||
"X1": 516,
|
|
||||||
"X2": 517
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
197
src/twn_input.c
197
src/twn_input.c
@ -1,7 +1,6 @@
|
|||||||
#include "twn_input_c.h"
|
#include "twn_input_c.h"
|
||||||
#include "twn_util.h"
|
#include "twn_util.h"
|
||||||
#include "twn_util_c.h"
|
#include "twn_util_c.h"
|
||||||
#include "twn_control.h"
|
|
||||||
#include "twn_engine_context_c.h"
|
#include "twn_engine_context_c.h"
|
||||||
#include "twn_input.h"
|
#include "twn_input.h"
|
||||||
|
|
||||||
@ -11,14 +10,131 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct ScancodeHashItem { char *const key; SDL_Scancode value; };
|
||||||
|
static struct ScancodeHashItem *control_to_scancode;
|
||||||
|
|
||||||
|
struct MouseButtonHashItem { char *const key; uint8_t value; };
|
||||||
|
static struct MouseButtonHashItem *control_to_mouse_mask;
|
||||||
|
|
||||||
|
/* prepares translation maps for controls */
|
||||||
|
static void init_control_maps(void) {
|
||||||
|
if (control_to_scancode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* these correspond to SDL_events.h definition, restricted to what deemed useful */
|
||||||
|
shput(control_to_scancode, "A", 4);
|
||||||
|
shput(control_to_scancode, "B", 5);
|
||||||
|
shput(control_to_scancode, "C", 6);
|
||||||
|
shput(control_to_scancode, "D", 7);
|
||||||
|
shput(control_to_scancode, "E", 8);
|
||||||
|
shput(control_to_scancode, "F", 9);
|
||||||
|
shput(control_to_scancode, "G", 10);
|
||||||
|
shput(control_to_scancode, "H", 11);
|
||||||
|
shput(control_to_scancode, "I", 12);
|
||||||
|
shput(control_to_scancode, "J", 13);
|
||||||
|
shput(control_to_scancode, "K", 14);
|
||||||
|
shput(control_to_scancode, "L", 15);
|
||||||
|
shput(control_to_scancode, "M", 16);
|
||||||
|
shput(control_to_scancode, "N", 17);
|
||||||
|
shput(control_to_scancode, "O", 18);
|
||||||
|
shput(control_to_scancode, "P", 19);
|
||||||
|
shput(control_to_scancode, "Q", 20);
|
||||||
|
shput(control_to_scancode, "R", 21);
|
||||||
|
shput(control_to_scancode, "S", 22);
|
||||||
|
shput(control_to_scancode, "T", 23);
|
||||||
|
shput(control_to_scancode, "U", 24);
|
||||||
|
shput(control_to_scancode, "V", 25);
|
||||||
|
shput(control_to_scancode, "W", 26);
|
||||||
|
shput(control_to_scancode, "X", 27);
|
||||||
|
shput(control_to_scancode, "Y", 28);
|
||||||
|
shput(control_to_scancode, "Z", 29);
|
||||||
|
shput(control_to_scancode, "1", 30);
|
||||||
|
shput(control_to_scancode, "2", 31);
|
||||||
|
shput(control_to_scancode, "3", 32);
|
||||||
|
shput(control_to_scancode, "4", 33);
|
||||||
|
shput(control_to_scancode, "5", 34);
|
||||||
|
shput(control_to_scancode, "6", 35);
|
||||||
|
shput(control_to_scancode, "7", 36);
|
||||||
|
shput(control_to_scancode, "8", 37);
|
||||||
|
shput(control_to_scancode, "9", 38);
|
||||||
|
shput(control_to_scancode, "0", 39);
|
||||||
|
shput(control_to_scancode, "RETURN", 40);
|
||||||
|
shput(control_to_scancode, "ENTER", 40); /* an alias */
|
||||||
|
shput(control_to_scancode, "ESCAPE", 41);
|
||||||
|
shput(control_to_scancode, "BACKSPACE", 42);
|
||||||
|
shput(control_to_scancode, "TAB", 43);
|
||||||
|
shput(control_to_scancode, "SPACE", 44);
|
||||||
|
shput(control_to_scancode, "MINUS", 45);
|
||||||
|
shput(control_to_scancode, "EQUALS", 46);
|
||||||
|
shput(control_to_scancode, "LEFTBRACKET", 47);
|
||||||
|
shput(control_to_scancode, "RIGHTBRACKET", 48);
|
||||||
|
shput(control_to_scancode, "BACKSLASH", 49);
|
||||||
|
shput(control_to_scancode, "NONUSHASH", 50);
|
||||||
|
shput(control_to_scancode, "SEMICOLON", 51);
|
||||||
|
shput(control_to_scancode, "APOSTROPHE", 52);
|
||||||
|
shput(control_to_scancode, "GRAVE", 53);
|
||||||
|
shput(control_to_scancode, "COMMA", 54);
|
||||||
|
shput(control_to_scancode, "PERIOD", 55);
|
||||||
|
shput(control_to_scancode, "SLASH", 56);
|
||||||
|
shput(control_to_scancode, "CAPSLOCK", 57);
|
||||||
|
shput(control_to_scancode, "F1", 58);
|
||||||
|
shput(control_to_scancode, "F2", 59);
|
||||||
|
shput(control_to_scancode, "F3", 60);
|
||||||
|
shput(control_to_scancode, "F4", 61);
|
||||||
|
shput(control_to_scancode, "F5", 62);
|
||||||
|
shput(control_to_scancode, "F6", 63);
|
||||||
|
shput(control_to_scancode, "F7", 64);
|
||||||
|
shput(control_to_scancode, "F8", 65);
|
||||||
|
shput(control_to_scancode, "F9", 66);
|
||||||
|
shput(control_to_scancode, "F10", 67);
|
||||||
|
shput(control_to_scancode, "F11", 68);
|
||||||
|
shput(control_to_scancode, "F12", 69);
|
||||||
|
shput(control_to_scancode, "PRINTSCREEN", 70);
|
||||||
|
shput(control_to_scancode, "SCROLLLOCK", 71);
|
||||||
|
shput(control_to_scancode, "PAUSE", 72);
|
||||||
|
shput(control_to_scancode, "INSERT", 73);
|
||||||
|
shput(control_to_scancode, "HOME", 74);
|
||||||
|
shput(control_to_scancode, "PAGEUP", 75);
|
||||||
|
shput(control_to_scancode, "DELETE", 76);
|
||||||
|
shput(control_to_scancode, "END", 77);
|
||||||
|
shput(control_to_scancode, "PAGEDOWN", 78);
|
||||||
|
shput(control_to_scancode, "RIGHT", 79);
|
||||||
|
shput(control_to_scancode, "LEFT", 80);
|
||||||
|
shput(control_to_scancode, "DOWN", 81);
|
||||||
|
shput(control_to_scancode, "UP", 82);
|
||||||
|
shput(control_to_scancode, "KPDIVIDE", 84);
|
||||||
|
shput(control_to_scancode, "KPMULTIPLY", 85);
|
||||||
|
shput(control_to_scancode, "KPMINUS", 86);
|
||||||
|
shput(control_to_scancode, "KPPLUS", 87);
|
||||||
|
shput(control_to_scancode, "KPENTER", 88);
|
||||||
|
shput(control_to_scancode, "KP1", 89);
|
||||||
|
shput(control_to_scancode, "KP2", 90);
|
||||||
|
shput(control_to_scancode, "KP3", 91);
|
||||||
|
shput(control_to_scancode, "KP4", 92);
|
||||||
|
shput(control_to_scancode, "KP5", 93);
|
||||||
|
shput(control_to_scancode, "KP6", 94);
|
||||||
|
shput(control_to_scancode, "KP7", 95);
|
||||||
|
shput(control_to_scancode, "KP8", 96);
|
||||||
|
shput(control_to_scancode, "KP9", 97);
|
||||||
|
shput(control_to_scancode, "KP0", 98);
|
||||||
|
shput(control_to_scancode, "LCTRL", 224);
|
||||||
|
shput(control_to_scancode, "LSHIFT", 225);
|
||||||
|
shput(control_to_scancode, "LALT", 226);
|
||||||
|
shput(control_to_scancode, "RCTRL", 228);
|
||||||
|
shput(control_to_scancode, "RSHIFT", 229);
|
||||||
|
|
||||||
|
/* TODO: support for double clicks */
|
||||||
|
shput(control_to_mouse_mask, "LCLICK", SDL_BUTTON(SDL_BUTTON_LEFT));
|
||||||
|
shput(control_to_mouse_mask, "MCLICK", SDL_BUTTON(SDL_BUTTON_MIDDLE));
|
||||||
|
shput(control_to_mouse_mask, "RCLICK", SDL_BUTTON(SDL_BUTTON_RIGHT));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void update_action_pressed_state(InputState *input, Action *action) {
|
static void update_action_pressed_state(InputState *input, Action *action) {
|
||||||
for (size_t i = 0; i < (uint64_t)ctx.keybind_slots; ++i) {
|
for (size_t i = 0; i < (uint64_t)ctx.keybind_slots; ++i) {
|
||||||
switch (action->bindings[i].source) {
|
switch (action->bindings[i].source) {
|
||||||
case BUTTON_SOURCE_NOT_SET:
|
case BUTTON_SOURCE_NOT_SET:
|
||||||
break;
|
break;
|
||||||
case BUTTON_SOURCE_KEYBOARD_CHARACTER:
|
|
||||||
CRY("Action pressed state updated failed", "BUTTON_SOURCE_KEYBOARD_CHARACTER isn't handled");
|
|
||||||
break;
|
|
||||||
case BUTTON_SOURCE_GAMEPAD:
|
case BUTTON_SOURCE_GAMEPAD:
|
||||||
CRY("Action pressed state updated failed", "BUTTON_SOURCE_GAMEPAD isn't handled");
|
CRY("Action pressed state updated failed", "BUTTON_SOURCE_GAMEPAD isn't handled");
|
||||||
break;
|
break;
|
||||||
@ -116,9 +232,6 @@ static void input_bind_code_to_action(InputState *input,
|
|||||||
case BUTTON_SOURCE_KEYBOARD_PHYSICAL:
|
case BUTTON_SOURCE_KEYBOARD_PHYSICAL:
|
||||||
is_already_bound = binding->code.scancode == code.scancode;
|
is_already_bound = binding->code.scancode == code.scancode;
|
||||||
break;
|
break;
|
||||||
case BUTTON_SOURCE_KEYBOARD_CHARACTER:
|
|
||||||
is_already_bound = binding->code.keycode == code.keycode;
|
|
||||||
break;
|
|
||||||
case BUTTON_SOURCE_GAMEPAD:
|
case BUTTON_SOURCE_GAMEPAD:
|
||||||
is_already_bound = binding->code.gamepad_button == code.gamepad_button;
|
is_already_bound = binding->code.gamepad_button == code.gamepad_button;
|
||||||
break;
|
break;
|
||||||
@ -177,9 +290,6 @@ static void input_unbind_code_from_action(InputState *input,
|
|||||||
case BUTTON_SOURCE_KEYBOARD_PHYSICAL:
|
case BUTTON_SOURCE_KEYBOARD_PHYSICAL:
|
||||||
is_bound = binding->code.scancode == code.scancode;
|
is_bound = binding->code.scancode == code.scancode;
|
||||||
break;
|
break;
|
||||||
case BUTTON_SOURCE_KEYBOARD_CHARACTER:
|
|
||||||
is_bound = binding->code.keycode == code.keycode;
|
|
||||||
break;
|
|
||||||
case BUTTON_SOURCE_GAMEPAD:
|
case BUTTON_SOURCE_GAMEPAD:
|
||||||
is_bound = binding->code.gamepad_button == code.gamepad_button;
|
is_bound = binding->code.gamepad_button == code.gamepad_button;
|
||||||
break;
|
break;
|
||||||
@ -208,10 +318,13 @@ static void input_unbind_code_from_action(InputState *input,
|
|||||||
|
|
||||||
void input_state_init(InputState *input) {
|
void input_state_init(InputState *input) {
|
||||||
sh_new_strdup(input->action_hash);
|
sh_new_strdup(input->action_hash);
|
||||||
|
init_control_maps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void input_state_deinit(InputState *input) {
|
void input_state_deinit(InputState *input) {
|
||||||
|
shfree(control_to_mouse_mask);
|
||||||
|
shfree(control_to_scancode);
|
||||||
input_reset_state(input);
|
input_reset_state(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,25 +377,73 @@ void input_state_update(InputState *input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Button *infer_control_desc(char const *control) {
|
||||||
|
Button *result = NULL;
|
||||||
|
char *copy = SDL_strdup(control);
|
||||||
|
|
||||||
|
char *saveptr = NULL;
|
||||||
|
char const *part = SDL_strtokr(copy, "+", &saveptr);
|
||||||
|
do {
|
||||||
|
struct ScancodeHashItem const *scancode = shgetp_null(control_to_scancode, part);
|
||||||
|
if (scancode) {
|
||||||
|
Button const button = {
|
||||||
|
.source = BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
||||||
|
.code.scancode = scancode->value,
|
||||||
|
};
|
||||||
|
arrpush(result, button);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MouseButtonHashItem const *mouse_button = shgetp_null(control_to_mouse_mask, part);
|
||||||
|
if (mouse_button) {
|
||||||
|
Button const button = {
|
||||||
|
.source = BUTTON_SOURCE_MOUSE,
|
||||||
|
.code.mouse_button = mouse_button->value,
|
||||||
|
};
|
||||||
|
arrpush(result, button);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn("Unknown control part given (%s)", part);
|
||||||
|
} while ((part = SDL_strtokr(NULL, "+", &saveptr)));
|
||||||
|
|
||||||
|
SDL_free(copy);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void input_action(char const *action_name,
|
void input_action(char const *action_name,
|
||||||
Control control)
|
char const *control)
|
||||||
{
|
{
|
||||||
SDL_assert_always(action_name);
|
SDL_assert_always(action_name);
|
||||||
|
|
||||||
if (CONTROL_SCANCODE_START <= control && control < CONTROL_SCANCODE_LIMIT)
|
Button *combo = infer_control_desc(control);
|
||||||
|
if (!combo) {
|
||||||
|
log_warn("Invalid control (%s) for action bind", control);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: */
|
||||||
|
if (arrlenu(combo) > 1) {
|
||||||
|
log_warn("TODO: Control combinations are not yet supported.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (combo[0].source == BUTTON_SOURCE_KEYBOARD_PHYSICAL)
|
||||||
input_bind_code_to_action(&ctx.input,
|
input_bind_code_to_action(&ctx.input,
|
||||||
action_name,
|
action_name,
|
||||||
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
||||||
(union ButtonCode) { .scancode = (SDL_Scancode)control });
|
(union ButtonCode) { .scancode = combo[0].code.scancode });
|
||||||
|
|
||||||
else if (CONTROL_MOUSECODE_START <= control && control < CONTROL_MOUSECODE_LIMIT) {
|
else if (combo[0].source == BUTTON_SOURCE_MOUSE)
|
||||||
uint8_t const mouse_button = (uint8_t)(control - CONTROL_MOUSECODE_START);
|
|
||||||
input_bind_code_to_action(&ctx.input,
|
input_bind_code_to_action(&ctx.input,
|
||||||
action_name,
|
action_name,
|
||||||
BUTTON_SOURCE_MOUSE,
|
BUTTON_SOURCE_MOUSE,
|
||||||
(union ButtonCode) { .mouse_button = (uint8_t)SDL_BUTTON(mouse_button)});
|
(union ButtonCode) { .mouse_button = combo[0].code.mouse_button });
|
||||||
} else
|
else
|
||||||
log_warn("(%s) Invalid control value given: %i.", __func__, control);
|
log_warn("(%s) Unsupported control source value given: %i.", __func__, control);
|
||||||
|
|
||||||
|
arrfree(combo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
union ButtonCode {
|
union ButtonCode {
|
||||||
SDL_Scancode scancode;
|
SDL_Scancode scancode;
|
||||||
SDL_Keycode keycode;
|
|
||||||
SDL_GameControllerButton gamepad_button;
|
SDL_GameControllerButton gamepad_button;
|
||||||
uint8_t mouse_button; /* SDL_BUTTON_ enum */
|
uint8_t mouse_button; /* SDL_BUTTON_ enum */
|
||||||
};
|
};
|
||||||
@ -22,7 +21,6 @@ union ButtonCode {
|
|||||||
typedef enum ButtonSource {
|
typedef enum ButtonSource {
|
||||||
BUTTON_SOURCE_NOT_SET,
|
BUTTON_SOURCE_NOT_SET,
|
||||||
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
||||||
BUTTON_SOURCE_KEYBOARD_CHARACTER,
|
|
||||||
BUTTON_SOURCE_GAMEPAD,
|
BUTTON_SOURCE_GAMEPAD,
|
||||||
BUTTON_SOURCE_MOUSE,
|
BUTTON_SOURCE_MOUSE,
|
||||||
} ButtonSource;
|
} ButtonSource;
|
||||||
@ -70,6 +68,14 @@ typedef struct InputState {
|
|||||||
} InputState;
|
} InputState;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ControlDesc {
|
||||||
|
union {
|
||||||
|
SDL_Scancode scancode;
|
||||||
|
uint8_t mouse_button;
|
||||||
|
};
|
||||||
|
} ControlDesc;
|
||||||
|
|
||||||
|
|
||||||
void input_state_init(InputState *input);
|
void input_state_init(InputState *input);
|
||||||
|
|
||||||
void input_state_deinit(InputState *input);
|
void input_state_deinit(InputState *input);
|
||||||
|
Loading…
Reference in New Issue
Block a user