Add smallinput

This commit is contained in:
Miloslav Číž 2020-10-17 20:59:07 +02:00
parent bc09cfa339
commit a611bc84ff
3 changed files with 240 additions and 65 deletions

View File

@ -63,6 +63,7 @@ source code stats (80 column wrapping, a lot of empty lines):
| --------------------------------------| ------- | --------- |
| game.h (main game logic) | TODO | TODO |
| raycastlib.h (ray casting library) | TODO | TODO |
| smallinput.h (test helper) | TODO | TODO |
| images.h, levels.h, sounds.h (assets) | TODO | TODO |
| settings.h, constants.h | TODO | TODO |
| **total** | TODO | TODO |
@ -250,6 +251,7 @@ main_*.* fronted implement. for various platforms, passed to compiler
palette.h game 256 color palette
raycastlib.h ray casting library
settings.h game settings that users can change (FPS, resolution, ...)
smallinput.h helper for some frontends and tests, not needed for the game
sounds.h sounds from assets folder converted to C
texts.h game texts
make.sh compiling script constaining compiler settings

View File

@ -24,6 +24,8 @@
#include <sys/time.h>
#include <time.h>
#include "smallinput.h"
#define SFG_SCREEN_RESOLUTION_X 127
#define SFG_SCREEN_RESOLUTION_Y 42
#define SFG_DITHERED_SHADOW 1
@ -43,33 +45,6 @@ const char shades[] = // adjust according to your terminal
uint32_t timeStart;
typedef struct
{
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
} InputEvent;
InputEvent event;
#define TOTAL_KEYS 9
uint16_t keyCodes[TOTAL_KEYS] =
{
KEY_W,
KEY_S,
KEY_A,
KEY_D,
KEY_SPACE,
KEY_H,
KEY_J,
KEY_K,
KEY_Q
};
uint8_t keyStates[TOTAL_KEYS];
uint32_t getTime()
{
struct timeval now;
@ -104,6 +79,12 @@ void SFG_sleepMs(uint16_t timeMs)
void SFG_getMouseOffset(int16_t *x, int16_t *y)
{
int32_t a,b;
input_getMousePos(&a,&b);
*x = a;
*y = b;
input_setMousePos(0,0);
}
void SFG_processEvent(uint8_t event, uint8_t data)
@ -114,15 +95,15 @@ int8_t SFG_keyPressed(uint8_t key)
{
switch (key)
{
case SFG_KEY_UP: return keyStates[0]; break;
case SFG_KEY_RIGHT: return keyStates[3]; break;
case SFG_KEY_DOWN: return keyStates[1]; break;
case SFG_KEY_LEFT: return keyStates[2]; break;
case SFG_KEY_A: return keyStates[5]; break;
case SFG_KEY_B: return keyStates[6]; break;
case SFG_KEY_C: return keyStates[7]; break;
case SFG_KEY_MAP: return keyStates[8]; break;
case SFG_KEY_JUMP: return keyStates[4]; break;
case SFG_KEY_UP: return input_getKey('w') || input_getKey(SMALLINPUT_ARROW_UP); break;
case SFG_KEY_RIGHT: return input_getKey('d') || input_getKey(SMALLINPUT_ARROW_RIGHT); break;
case SFG_KEY_DOWN: return input_getKey('s') || input_getKey(SMALLINPUT_ARROW_DOWN); break;
case SFG_KEY_LEFT: return input_getKey('a') || input_getKey(SMALLINPUT_ARROW_LEFT); break;
case SFG_KEY_A: return input_getKey('g'); break;
case SFG_KEY_B: return input_getKey('h') || input_getKey(SMALLINPUT_MOUSE_L); break;
case SFG_KEY_C: return input_getKey('j'); break;
case SFG_KEY_MAP: return input_getKey(SMALLINPUT_TAB); break;
case SFG_KEY_JUMP: return input_getKey(' '); break;
default: return 0; break;
}
}
@ -145,26 +126,17 @@ void handleSignal(int signal)
int main()
{
int devFile;
signal(SIGINT,handleSignal);
signal(SIGQUIT,handleSignal);
signal(SIGTERM,handleSignal);
timeStart = getTime();
devFile = open("/dev/input/event0",O_RDONLY);
// ^ replace with your specific keyboard file
fcntl(devFile, F_SETFL, O_NONBLOCK);
input_init();
SFG_init();
screen[SCREENSIZE - 1] = 0; // string terminator
for (uint16_t i = 0; i < TOTAL_KEYS; ++i)
keyStates[i] = 0;
for (uint16_t i = 1; i <= SFG_SCREEN_RESOLUTION_Y; ++i)
screen[i * (SFG_SCREEN_RESOLUTION_X + 1) - 1] = '\n';
@ -177,24 +149,8 @@ int main()
while (running)
{
while (1)
{
int n = read(devFile, &event, sizeof(event));
if (n <= 0)
break;
if (event.type == EV_KEY && (event.value == 1 || event.value == 0))
{
for (uint8_t i = 0; i < TOTAL_KEYS; ++i)
if (event.code == keyCodes[i])
{
keyStates[i] = event.value;
break;
}
}
}
input_update();
puts("\033[0;0H"); // move cursor to 0;0
puts(screen);
fflush(stdout);
@ -202,6 +158,8 @@ int main()
if (!SFG_mainLoopBody())
running = 0;
}
puts("\033[?25h"); // show cursor
input_end();
}

215
smallinput.h Normal file
View File

@ -0,0 +1,215 @@
/**
@file smallinput.h
Small API for getting keyboard/mouse input, with possiblity to record it and
play back.
The Linux Input API requires root pirivileges (sudo).
by Milsolav "drummyfish" Ciz, released under CC0 1.0 (public domain)
*/
#ifndef _SMALLINPUT_H
#define _SMALLINPUT_H
#include <stdint.h>
#define SMALLINPUT_KEY_NONE 0
#define SMALLINPUT_ARROW_UP 128
#define SMALLINPUT_ARROW_RIGHT 129
#define SMALLINPUT_ARROW_DOWN 130
#define SMALLINPUT_ARROW_LEFT 131
#define SMALLINPUT_SPACE ' '
#define SMALLINPUT_BACKSPACE 8
#define SMALLINPUT_TAB 9
#define SMALLINPUT_RETURN 13
#define SMALLINPUT_SHIFT 14
#define SMALLINPUT_ESCAPE 27
#define SMALLINPUT_DELETE 127
#define SMALLINPUT_MOUSE_L 253
#define SMALLINPUT_MOUSE_M 254
#define SMALLINPUT_MOUSE_R 255
uint8_t input_keyStates[256];
int32_t input_mousePosition[2];
uint32_t input_frame = 0;
#if 1 // TODO: add other options for input handling (SDL, xinput, ...)
/*
This is using Linux Input Subsystem API. Defines can be found in
include/uapi/linux/input-event-codes.h.
*/
#include <fcntl.h>
#include <linux/input.h>
#include <sys/time.h>
#include <unistd.h>
typedef struct
{
struct timeval time;
uint16_t type;
uint16_t code;
int32_t value;
} LinuxInputEvent;
#define INPUT_KEYBOARD_FILE "/dev/input/event0"
#define INPUT_MOUSE_FILE "/dev/input/event1"
int input_keyboardFile = 0;
int input_mouseFile = 0;
/**
Maps this library's key codes to linux input key codes.
*/
static const int input_linuxCodes[256] =
{
#define no KEY_RESERVED
no,no,no,no,no,no,no,no,KEY_BACKSPACE,KEY_TAB,no,no,no,KEY_ENTER,KEY_LEFTSHIFT,no,
no,no,no,no,no,no,no,no,no,no,no,KEY_ESC,no,no,no,no,
KEY_SPACE,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,KEY_A,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J,KEY_K,KEY_L,KEY_M,KEY_N,KEY_O,
KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T,KEY_U,KEY_V,KEY_W,KEY_X,KEY_Y,KEY_Z,no,no,no,no,no,
no,KEY_A,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J,KEY_K,KEY_L,KEY_M,KEY_N,KEY_O,
KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T,KEY_U,KEY_V,KEY_W,KEY_X,KEY_Y,KEY_Z,no,no,no,no,KEY_DELETE,
KEY_UP,KEY_RIGHT,KEY_DOWN,KEY_LEFT,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,
no,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no
#undef no
};
#endif
/**
Initializes the library.
*/
void input_init(void)
{
input_mousePosition[0] = 0;
input_mousePosition[1] = 0;
input_frame = 0;
for (int16_t i = 0; i < 256; ++i)
input_keyStates[i] = 0;
input_keyboardFile = open(INPUT_KEYBOARD_FILE, O_RDONLY);
fcntl(input_keyboardFile, F_SETFL, O_NONBLOCK);
input_mouseFile = open(INPUT_MOUSE_FILE, O_RDONLY);
fcntl(input_mouseFile, F_SETFL, O_NONBLOCK);
}
void input_end(void)
{
close(input_keyboardFile);
close(input_mouseFile);
}
/**
Should be called once every main loop iteration to retrieve current input
state.
*/
void input_update(void)
{
LinuxInputEvent event;
while (1) // keyboard
{
if (read(input_keyboardFile, &event, sizeof(event)) <= 0)
break;
if (event.type == EV_KEY && (event.value == 1 || event.value == 0))
for (uint16_t i = 0; i < 256; ++i)
if (event.code == input_linuxCodes[i])
{
input_keyStates[i] = event.value;
break;
}
}
while (1) // mouse
{
if (read(input_mouseFile, &event, sizeof(event)) <= 0)
break;
if (event.type == EV_REL)
input_mousePosition[event.code % 2] += event.value;
else if (event.type == EV_KEY)
{
input_keyStates[
event.code == BTN_LEFT ? SMALLINPUT_MOUSE_L :
(event.code == BTN_RIGHT ? SMALLINPUT_MOUSE_R : SMALLINPUT_MOUSE_M)]
= event.value;
}
}
for (uint16_t i = 0; i < 256; ++i)
if (input_keyStates[i] && input_keyStates[i] < 255)
input_keyStates[i]++;
input_frame++;
}
/**
Returns the number of input frames for which given key has been pressed (> 1:
key is pressed, == 1: key was just pressed, == 0: key is not pressed).
*/
static inline uint8_t input_getKey(uint8_t key)
{
if (key >= 'a' && key <= 'z')
key = 'A' + (key - 'a');
return input_keyStates[key];
}
/**
Gets the mouse position.
*/
static inline void input_getMousePos(int16_t *x, int16_t *y)
{
*x = input_mousePosition[0];
*y = input_mousePosition[1];
}
static inline void input_setMousePos(int32_t x, int32_t y)
{
input_mousePosition[0] = x;
input_mousePosition[1] = y;
}
#if 0 // this can be used to test this
mates
#include <stdio.h>
int main(void)
{
input_init();
while (1)
{
input_update();
puts("\n\n\n\n");
for (uint16_t i = 0; i < 256; ++i)
printf("%d (%c): %d, ",i,i,input_keyStates[i]);
printf("mouse: %d %d (%d %d %d)\n",input_mousePosition[0],input_mousePosition[1],input_getKey(SMALLINPUT_MOUSE_L),input_getKey(SMALLINPUT_MOUSE_M),input_getKey(SMALLINPUT_MOUSE_R));
puts("");
usleep(10000);
}
input_end();
}
#endif
#endif