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 "")
|
||||
|
||||
# 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
|
||||
if(EMSCRIPTEN)
|
||||
@ -270,7 +271,9 @@ function(link_deps target)
|
||||
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)
|
||||
# game shared library, for reloading
|
||||
add_library(${target}_game SHARED ${sources})
|
||||
|
@ -13,4 +13,4 @@ set(SOURCE_FILES
|
||||
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));
|
||||
}
|
||||
|
||||
input_action("add_a_bit", CONTROL_LEFT_MOUSE);
|
||||
input_action("add_a_lot", CONTROL_RIGHT_MOUSE);
|
||||
input_action("add_a_bit", "LCLICK");
|
||||
input_action("add_a_lot", "RCLICK");
|
||||
|
||||
State *state = ctx.udata;
|
||||
|
||||
|
@ -20,4 +20,4 @@ set(SOURCE_FILES
|
||||
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;
|
||||
|
||||
input_action("debug_toggle", CONTROL_BACKSPACE);
|
||||
input_action("debug_dump_atlases", CONTROL_HOME);
|
||||
input_action("debug_toggle", "BACKSPACE");
|
||||
input_action("debug_dump_atlases", "HOME");
|
||||
|
||||
if (input_action_just_pressed("debug_toggle")) {
|
||||
ctx.debug = !ctx.debug;
|
||||
|
@ -11,12 +11,12 @@
|
||||
static void ingame_tick(State *state) {
|
||||
SceneIngame *scn = (SceneIngame *)state->scene;
|
||||
|
||||
input_action("player_left", CONTROL_A);
|
||||
input_action("player_right", CONTROL_D);
|
||||
input_action("player_forward", CONTROL_W);
|
||||
input_action("player_backward", CONTROL_S);
|
||||
input_action("player_jump", CONTROL_SPACE);
|
||||
input_action("player_run", CONTROL_LSHIFT);
|
||||
input_action("player_left", "A");
|
||||
input_action("player_right", "D");
|
||||
input_action("player_forward", "W");
|
||||
input_action("player_backward", "S");
|
||||
input_action("player_jump", "SPACE");
|
||||
input_action("player_run", "LSHIFT");
|
||||
|
||||
world_drawdef(scn->world);
|
||||
player_calc(scn->player);
|
||||
|
@ -13,7 +13,7 @@ static void title_tick(State *state) {
|
||||
SceneTitle *scn = (SceneTitle *)state->scene;
|
||||
(void)scn;
|
||||
|
||||
input_action("ui_accept", CONTROL_RETURN);
|
||||
input_action("ui_accept", "ENTER");
|
||||
|
||||
if (input_action_just_pressed("ui_accept")) {
|
||||
switch_to(state, ingame_scene);
|
||||
|
@ -17,4 +17,4 @@ set(SOURCE_FILES
|
||||
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;
|
||||
|
||||
input_action("debug_toggle", CONTROL_BACKSPACE);
|
||||
input_action("debug_dump_atlases", CONTROL_HOME);
|
||||
input_action("debug_toggle", "BACKSPACE");
|
||||
input_action("debug_dump_atlases", "HOME");
|
||||
|
||||
if (input_action_just_pressed("debug_toggle")) {
|
||||
ctx.debug = !ctx.debug;
|
||||
|
@ -188,14 +188,14 @@ static void draw_terrain(SceneIngame *scn) {
|
||||
static void ingame_tick(State *state) {
|
||||
SceneIngame *scn = (SceneIngame *)state->scene;
|
||||
|
||||
input_action("player_left", CONTROL_A);
|
||||
input_action("player_right", CONTROL_D);
|
||||
input_action("player_forward", CONTROL_W);
|
||||
input_action("player_backward", CONTROL_S);
|
||||
input_action("player_jump", CONTROL_SPACE);
|
||||
input_action("player_run", CONTROL_LSHIFT);
|
||||
input_action("mouse_capture_toggle", CONTROL_ESCAPE);
|
||||
input_action("toggle_camera_mode", CONTROL_C);
|
||||
input_action("player_left", "A");
|
||||
input_action("player_right", "D");
|
||||
input_action("player_forward", "W");
|
||||
input_action("player_backward", "S");
|
||||
input_action("player_jump", "SPACE");
|
||||
input_action("player_run", "LSHIFT");
|
||||
input_action("mouse_capture_toggle", "ESCAPE");
|
||||
input_action("toggle_camera_mode", "C");
|
||||
|
||||
if (scn->mouse_captured) {
|
||||
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;
|
||||
(void)scn;
|
||||
|
||||
input_action("ui_accept", CONTROL_RETURN);
|
||||
input_action("ui_accept", "RETURN");
|
||||
|
||||
if (input_action_just_pressed("ui_accept")) {
|
||||
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};
|
||||
|
||||
input_action("up", CONTROL_LEFT_MOUSE);
|
||||
input_action("down", CONTROL_RIGHT_MOUSE);
|
||||
input_action("up", "LCLICK");
|
||||
input_action("down", "RCLICK");
|
||||
|
||||
if (input_action_just_pressed("up"))
|
||||
state->r += 1;
|
||||
|
@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.21)
|
||||
cmake_policy(SET CMP0171 NEW)
|
||||
project(twnlua LANGUAGES C)
|
||||
|
||||
option(TWN_OUT_DIR "Artifact destination" ${CMAKE_SOURCE_DIR})
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
endif()
|
||||
@ -41,5 +39,4 @@ set(SOURCE_FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/luabind.c
|
||||
)
|
||||
|
||||
cmake_path(GET TWN_OUT_DIR STEM LAST_ONLY GAME_PROJECT_NAME)
|
||||
use_townengine(${GAME_PROJECT_NAME} "${SOURCE_FILES}" ${TWN_OUT_DIR})
|
||||
use_townengine("${SOURCE_FILES}" ${TWN_OUT_DIR})
|
||||
|
@ -116,7 +116,6 @@ for procedure, procedure_desc in api["procedures"].items():
|
||||
elif procedure_desc["return"] == "char *":
|
||||
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"]:
|
||||
# TODO: handle enums
|
||||
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 += 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"]))
|
||||
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())
|
||||
converters += [converter]
|
||||
|
||||
|
@ -33,7 +33,7 @@ def to_lua_type_annot(typedesc):
|
||||
|
||||
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 }" % \
|
||||
', '.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(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 = {}
|
||||
for procedure, procedure_desc in api["procedures"].items():
|
||||
procedure_annotations[procedure] = {}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#!/bin/env python3
|
||||
|
||||
from subprocess import getoutput, run
|
||||
from os import getcwd
|
||||
from os.path import expandvars
|
||||
from pathlib import Path
|
||||
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
|
||||
if "--release" in argv:
|
||||
cmake += ["-DCMAKE_BUILD_TYPE=Release"]
|
||||
cmake += [f"-DTWN_OUT_DIR={getcwd()}"]
|
||||
# pass arbitrary arguments over
|
||||
if "--" in argv:
|
||||
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">
|
||||
</head>
|
||||
<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
|
||||
<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>
|
||||
<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.
|
||||
@ -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.
|
||||
Startup time is profiled and optimized. Streaming is used as much as possible for asset load.
|
||||
</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>
|
||||
<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.
|
||||
|
@ -5,20 +5,27 @@
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Townengine Wiki</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<td><strong>1.</strong> <a href="#about-townengine">About Townengnine</a></td>
|
||||
<td><strong>2.</strong> <a href="#making-2dot5d-shooters">Making 2.5D Shooters</a></td>
|
||||
<h1 style="margin-bottom:0in">Townengine Wiki</h1>
|
||||
<a>Awesomeness</a>
|
||||
<table style="padding-top:1em">
|
||||
<tr><td>T1.</strong> <a href="#about-townengine">About Townengnine</a></td>
|
||||
<td>G1.</strong> <a href="#making-2dot5d-shooters">Making 2.5D Shooters</a></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
<p><a name="about-townengine"></a><strong>1. </strong><a href="about-townengine.html"><strong>About Townengine</strong></a></p>
|
||||
<blockquote>
|
||||
<p style="margin:0">1.1 <a href="about-townengine.html#introduction">Introduction</a></p>
|
||||
<p style="margin:0">1.2 <a href="about-townengine.html#wiki">Wiki</a></p>
|
||||
<tr><td>T2.</strong> <a href="#input-system">Input System</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="margin-bottom:0"><a name="about-townengine"></a>T1. </strong><a href="about-townengine.html">About Townengine</strong></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>
|
||||
<p><a name="making-2dot5d-shooters"></a><strong>2. </strong><a href="making-2dot5d-shooters.html"><strong>Making 2.5D Shooters</strong></a></p>
|
||||
<blockquote>
|
||||
<p style="margin-bottom:0"><a name="input-system"></a>T2. </strong><a href="input-system.html">Input System</strong></a></p>
|
||||
<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>
|
||||
</body>
|
||||
</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 */
|
||||
body { margin: 1em 2.3em 1em 1.5em; zoom: 150%; padding-bottom: 50px;}
|
||||
h1 { font-size: 2.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
p { margin-left: 0.2em;
|
||||
}
|
||||
blockquote {
|
||||
font-style: normal;
|
||||
}
|
||||
body { margin: 1em 2.3em 1em 1.5em; zoom: 150%; padding-bottom: 1em; }
|
||||
h1 { font-size: 2.1em;
|
||||
font-weight: bold; }
|
||||
p { margin-left: 0.2em; text-indent: 1em hanging; }
|
||||
blockquote { font-style: normal; }
|
||||
pre { margin: 0em 3em 0em 2em;
|
||||
color: rgb(20%,20%,50%); background-color: rgb(100%,100%,100%);
|
||||
border: 1px solid rgb(50%,50%,50%);
|
||||
padding: 1em;
|
||||
font-size: 0.85em;
|
||||
white-space: pre;
|
||||
}
|
||||
hr { color: rgb(30%,30%,60%);
|
||||
}
|
||||
color: rgb(20%,20%,50%); background-color: rgb(100%,100%,100%);
|
||||
border: 1px solid rgb(50%,50%,50%);
|
||||
padding: 1em;
|
||||
margin-bottom: 2em;
|
||||
white-space: pre; }
|
||||
hr { color: rgb(30%,30%,60%); }
|
||||
|
@ -5,9 +5,9 @@
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="margin-bottom:0in;">1. {About}</h1>
|
||||
<h1 style="margin-bottom:0in;">X1. {About}</h1>
|
||||
<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>
|
||||
<p>Text
|
||||
</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
|
||||
#define TWN_INPUT_H
|
||||
|
||||
#include "twn_types.h"
|
||||
#include "twn_engine_api.h"
|
||||
#include "twn_control.h"
|
||||
#include "twn_types.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
TWN_API void input_action(const char *name, Control control);
|
||||
TWN_API void input_action(const char *name, const char *control);
|
||||
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_released(const char *name);
|
||||
|
@ -8,7 +8,7 @@
|
||||
"header": "twn_input.h",
|
||||
"params": [
|
||||
{ "name": "name", "type": "char *" },
|
||||
{ "name": "control", "type": "Control" }
|
||||
{ "name": "control", "type": "char *" }
|
||||
]
|
||||
},
|
||||
|
||||
@ -354,242 +354,6 @@
|
||||
{ "name": "mouse_capture", "type": "bool" }
|
||||
],
|
||||
"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_util.h"
|
||||
#include "twn_util_c.h"
|
||||
#include "twn_control.h"
|
||||
#include "twn_engine_context_c.h"
|
||||
#include "twn_input.h"
|
||||
|
||||
@ -11,14 +10,131 @@
|
||||
#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) {
|
||||
for (size_t i = 0; i < (uint64_t)ctx.keybind_slots; ++i) {
|
||||
switch (action->bindings[i].source) {
|
||||
case BUTTON_SOURCE_NOT_SET:
|
||||
break;
|
||||
case BUTTON_SOURCE_KEYBOARD_CHARACTER:
|
||||
CRY("Action pressed state updated failed", "BUTTON_SOURCE_KEYBOARD_CHARACTER isn't handled");
|
||||
break;
|
||||
case BUTTON_SOURCE_GAMEPAD:
|
||||
CRY("Action pressed state updated failed", "BUTTON_SOURCE_GAMEPAD isn't handled");
|
||||
break;
|
||||
@ -116,9 +232,6 @@ static void input_bind_code_to_action(InputState *input,
|
||||
case BUTTON_SOURCE_KEYBOARD_PHYSICAL:
|
||||
is_already_bound = binding->code.scancode == code.scancode;
|
||||
break;
|
||||
case BUTTON_SOURCE_KEYBOARD_CHARACTER:
|
||||
is_already_bound = binding->code.keycode == code.keycode;
|
||||
break;
|
||||
case BUTTON_SOURCE_GAMEPAD:
|
||||
is_already_bound = binding->code.gamepad_button == code.gamepad_button;
|
||||
break;
|
||||
@ -177,9 +290,6 @@ static void input_unbind_code_from_action(InputState *input,
|
||||
case BUTTON_SOURCE_KEYBOARD_PHYSICAL:
|
||||
is_bound = binding->code.scancode == code.scancode;
|
||||
break;
|
||||
case BUTTON_SOURCE_KEYBOARD_CHARACTER:
|
||||
is_bound = binding->code.keycode == code.keycode;
|
||||
break;
|
||||
case BUTTON_SOURCE_GAMEPAD:
|
||||
is_bound = binding->code.gamepad_button == code.gamepad_button;
|
||||
break;
|
||||
@ -208,10 +318,13 @@ static void input_unbind_code_from_action(InputState *input,
|
||||
|
||||
void input_state_init(InputState *input) {
|
||||
sh_new_strdup(input->action_hash);
|
||||
init_control_maps();
|
||||
}
|
||||
|
||||
|
||||
void input_state_deinit(InputState *input) {
|
||||
shfree(control_to_mouse_mask);
|
||||
shfree(control_to_scancode);
|
||||
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,
|
||||
Control control)
|
||||
char const *control)
|
||||
{
|
||||
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,
|
||||
action_name,
|
||||
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) {
|
||||
uint8_t const mouse_button = (uint8_t)(control - CONTROL_MOUSECODE_START);
|
||||
else if (combo[0].source == BUTTON_SOURCE_MOUSE)
|
||||
input_bind_code_to_action(&ctx.input,
|
||||
action_name,
|
||||
BUTTON_SOURCE_MOUSE,
|
||||
(union ButtonCode) { .mouse_button = (uint8_t)SDL_BUTTON(mouse_button)});
|
||||
} else
|
||||
log_warn("(%s) Invalid control value given: %i.", __func__, control);
|
||||
(union ButtonCode) { .mouse_button = combo[0].code.mouse_button });
|
||||
else
|
||||
log_warn("(%s) Unsupported control source value given: %i.", __func__, control);
|
||||
|
||||
arrfree(combo);
|
||||
}
|
||||
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
union ButtonCode {
|
||||
SDL_Scancode scancode;
|
||||
SDL_Keycode keycode;
|
||||
SDL_GameControllerButton gamepad_button;
|
||||
uint8_t mouse_button; /* SDL_BUTTON_ enum */
|
||||
};
|
||||
@ -22,7 +21,6 @@ union ButtonCode {
|
||||
typedef enum ButtonSource {
|
||||
BUTTON_SOURCE_NOT_SET,
|
||||
BUTTON_SOURCE_KEYBOARD_PHYSICAL,
|
||||
BUTTON_SOURCE_KEYBOARD_CHARACTER,
|
||||
BUTTON_SOURCE_GAMEPAD,
|
||||
BUTTON_SOURCE_MOUSE,
|
||||
} ButtonSource;
|
||||
@ -70,6 +68,14 @@ typedef struct InputState {
|
||||
} InputState;
|
||||
|
||||
|
||||
typedef struct ControlDesc {
|
||||
union {
|
||||
SDL_Scancode scancode;
|
||||
uint8_t mouse_button;
|
||||
};
|
||||
} ControlDesc;
|
||||
|
||||
|
||||
void input_state_init(InputState *input);
|
||||
|
||||
void input_state_deinit(InputState *input);
|
||||
|
Loading…
Reference in New Issue
Block a user