From 5d8141c2df3f2a66e72dabc45f36f3c76d21570d Mon Sep 17 00:00:00 2001 From: viandoxdev Date: Sun, 28 Aug 2022 02:29:43 +0200 Subject: [PATCH] init --- .ccls | 1 + .gitignore | 4 ++ Makefile | 38 +++++++++++++++++ hashmap.c | 91 +++++++++++++++++++++++++++++++++++++++++ hashmap.h | 6 +++ hid.c | 17 ++++++++ hid.h | 7 ++++ main.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.h | 11 +++++ net.c | 0 net.h | 4 ++ 11 files changed, 296 insertions(+) create mode 100644 .ccls create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 hashmap.c create mode 100644 hashmap.h create mode 100644 hid.c create mode 100644 hid.h create mode 100644 main.c create mode 100644 main.h create mode 100644 net.c create mode 100644 net.h diff --git a/.ccls b/.ccls new file mode 100644 index 0000000..e671fa2 --- /dev/null +++ b/.ccls @@ -0,0 +1 @@ +clang diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..14f1512 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.ccls-cache +build +jsfw +plan diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..acff31d --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +Q=@ +CC=gcc +CFLAGS=-g -Wall +LDFLAGS= +BUILD_DIR=./build +BIN=jsfw + +RUNARGS=client /dev/input/js0 localhost 7776 + +SOURCES=main.c hid.c + +OBJECTS:=$(patsubst %.c,$(BUILD_DIR)/%.o,$(SOURCES)) + +.PHONY: run +run: $(BIN) + @echo "RUN $(BIN) $(RUNARGS)" + $(Q) chmod +x $(BIN) + $(Q) ./$(BIN) $(RUNARGS) + +$(BIN): $(OBJECTS) + @echo "LD $@" + $(Q) $(CC) $(LDFLAGS) $^ -o $@ + +$(BUILD_DIR)/%.o: %.c | $(BUILD_DIR) + @echo "CC $<" + $(Q) $(CC) $(CFLAGS) -c $< -o $@ + +.PRECIOUS: $(BUILD_DIR) +$(BUILD_DIR): + @echo "MKDIR" + $(Q) mkdir -p $(BUILD_DIR) + +.PHONY: clean +clean: + @echo "CLEAN" + $(Q) rm -fr $(BUILD_DIR) + $(Q) rm -fr $(BIN) + diff --git a/hashmap.c b/hashmap.c new file mode 100644 index 0000000..942cbce --- /dev/null +++ b/hashmap.c @@ -0,0 +1,91 @@ +#include "hashmap.h" +#include + +int seed = 0; + +void init_seed() { + if(seed) return; + seed = random(); +} + +// All the code from here: +// Is taken from the internet because I needed a simple hash function +// -------------------------------------------------------- + +#define PRIME1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */ +#define PRIME2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */ +#define PRIME3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */ +#define PRIME4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */ +#define PRIME5 0x165667B1U /*!< 0b00010110010101100110011110110001 */ + +uint32_t _rotl(const uint32_t value, int shift) { + if ((shift &= sizeof(value)*8 - 1) == 0) + return value; + return (value << shift) | (value >> (sizeof(value)*8 - shift)); +} + +uint32_t _rotr(const uint32_t value, int shift) { + if ((shift &= sizeof(value)*8 - 1) == 0) + return value; + return (value >> shift) | (value << (sizeof(value)*8 - shift)); +} + +uint32_t hash(uint8_t * data, int len) { + int end = len; + int offset = 0; + int h32; + if (len >= 16) { + int limit = end - 16; + uint32_t v1 = seed + PRIME1 + PRIME2; + uint32_t v2 = seed + PRIME2; + uint32_t v3 = seed; + uint32_t v4 = seed - PRIME1; + + do { + v1 += (*(uint32_t*)(data + offset)) * PRIME2; + v1 = _rotl(v1, 13); + v1 *= PRIME1; + offset += 4; + v2 += (*(uint32_t*)(data + offset)) * PRIME2; + v2 = _rotl(v2, 13); + v2 *= PRIME1; + offset += 4; + v3 += (*(uint32_t*)(data + offset)) * PRIME2; + v3 = _rotl(v3, 13); + v3 *= PRIME1; + offset += 4; + v4 += (*(uint32_t*)(data + offset)) * PRIME2; + v4 = _rotl(v4, 13); + v4 *= PRIME1; + offset += 4; + } while(offset <= limit); + // main loop ends + // mix + h32 = _rotl(v1, 1) + _rotl(v2, 7) + _rotl(v3, 12) + _rotl(v4, 18); + } else { + h32 = seed + PRIME5; + } + + for(h32 += len; offset <= end - 4; offset += 4) { + h32 += (*(uint32_t*)(data + offset)) * PRIME3; + h32 = _rotl(h32, 17) * PRIME4; + } + + while(offset < end) { + h32 += (data[offset] & 255) * PRIME5; + h32 = _rotl(h32, 11) * PRIME1; + ++offset; + } + + h32 ^= h32 >> 15; + h32 *= PRIME2; + h32 ^= h32 >> 13; + h32 *= PRIME3; + h32 ^= h32 >> 16; + return h32; +} + +// -------------------------------------------------------- +// To here + + diff --git a/hashmap.h b/hashmap.h new file mode 100644 index 0000000..1db6307 --- /dev/null +++ b/hashmap.h @@ -0,0 +1,6 @@ +#ifndef HASHMAP_H +#define HASHMAP_H +#include + + +#endif diff --git a/hid.c b/hid.c new file mode 100644 index 0000000..dc86bae --- /dev/null +++ b/hid.c @@ -0,0 +1,17 @@ +#include +#include +#include + +void hid_main() { + DIR *d; + struct dirent *dir; + d = opendir("/sys/class/hidraw"); + if(d) { + while ((dir = readdir(d)) != NULL) { + if(dir->d_type != DT_LNK) continue; + printf("%s\n", dir->d_ino); + } + closedir(d); + } + exit(0); +} diff --git a/hid.h b/hid.h new file mode 100644 index 0000000..c987e44 --- /dev/null +++ b/hid.h @@ -0,0 +1,7 @@ +#ifndef HID_H +#define HID_H + + +void hid_main(); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..c93e338 --- /dev/null +++ b/main.c @@ -0,0 +1,117 @@ +// vi: set shiftwidth=4 : set softtabstop=4 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" +#include "hid.h" + +const char* USAGE[] = { + "jsfw client [input] [address] [port]\n", + "jsfw server [port]\n", +}; +const size_t EVENT_SIZE = sizeof(struct js_event); + +void joystick_debug(Joystick * js) { + printf("Joystick"); + if(js->name) printf(" (%s)", js->name); + printf(": %u buttons, %u axes\n", js->button_count, js->axis_count); +} + +void panicf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + exit(1); +} + +uint16_t parse_port(const char * str) { + long long n = atoll(str); + if(n < 0 || n > UINT16_MAX) + panicf("Invalid port: Expected a number in the range 0..%d, got %lld\n", UINT16_MAX, n); + return n; +} + +void server(uint16_t port) { + printf("Server (port: %u).\n", port); + panicf("Uninplemented\n"); +} + +void client(char * input, char * address, uint16_t port) { + hid_main(); + printf("JSFW Client (%s -> %s:%d)\n", input, address, port); + int fd = open(input, O_RDONLY); + if(fd < 0) panicf("Couldn't open %s", input); + + Joystick js = {}; + + char name[256]; + int name_len = ioctl(fd, JSIOCGNAME(256), name); + if(name_len >= 0) { + js.name = malloc(name_len); + if(js.name) strncpy(js.name, name, name_len); + } + + ioctl(fd, JSIOCGBUTTONS, &js.button_count); + ioctl(fd, JSIOCGAXES, &js.axis_count); + + joystick_debug(&js); + + struct js_event events[128]; + while(1) { + int bytes = read(fd, events, EVENT_SIZE); + if(bytes < EVENT_SIZE) { + printf("Got %d bytes, expected at least %lu", bytes, EVENT_SIZE); + continue; + } + int count = bytes / EVENT_SIZE; + for(int i = 0; i < count; i++) { + struct js_event event = events[i]; + printf("EV | type(%d) number(%d) value(%d) ts(%d)\n", event.type, event.number, event.value, event.time); + } + } +} + +int main(int argc, char* argv[]) { + if(argc < 2) { + printf("Usage: %s", USAGE[0]); + printf(" %s", USAGE[1]); + return 1; + } + + char* mode = argv[1]; + + if(strcmp(mode, "server") == 0) { + + if(argc < 3) + panicf("Usage: %s", USAGE[1]); + + uint16_t port = parse_port(argv[2]); + server(port); + + } else if(strcmp(mode, "client") == 0) { + + if(argc < 5) + panicf("Usage: %s", USAGE[0]); + + char * input = argv[2]; + char * address = argv[3]; + uint16_t port = parse_port(argv[4]); + client(input, address, port); + + } else { + printf("Unknown mode: '%s'\n", mode); + printf("Usage: %s", USAGE[0]); + printf(" %s", USAGE[1]); + return 1; + } + + return 0; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..f7d68fc --- /dev/null +++ b/main.h @@ -0,0 +1,11 @@ +#ifndef MAIN_H +#define MAIN_H +#include + +typedef struct { + char * name; + uint8_t button_count; + uint8_t axis_count; +} Joystick; + +#endif diff --git a/net.c b/net.c new file mode 100644 index 0000000..e69de29 diff --git a/net.h b/net.h new file mode 100644 index 0000000..4765a53 --- /dev/null +++ b/net.h @@ -0,0 +1,4 @@ +#ifndef NET_H +#define NET_H + +#endif