commit 5d8141c2df3f2a66e72dabc45f36f3c76d21570d Author: viandoxdev Date: Sun Aug 28 02:29:43 2022 +0200 init 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