diff options
| author | kkard2 <[email protected]> | 2026-06-10 14:06:55 +0200 |
|---|---|---|
| committer | kkard2 <[email protected]> | 2026-06-10 14:06:55 +0200 |
| commit | f961306d40654ac6a1ab7c262af7af74401dc693 (patch) | |
| tree | 6e2b0366f0ec077eadb815b35718312d1c79ea33 /src/driver_emulator.cpp | |
init
Diffstat (limited to 'src/driver_emulator.cpp')
| -rw-r--r-- | src/driver_emulator.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/driver_emulator.cpp b/src/driver_emulator.cpp new file mode 100644 index 0000000..d808fcd --- /dev/null +++ b/src/driver_emulator.cpp @@ -0,0 +1,169 @@ +#include <raylib.h> +#include <stdlib.h> + +#include <sys/socket.h> +#include <netinet/in.h> +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#define WIFI_HOTSPOT_IP "127.0.0.1" + +static uint16_t display_framebuffer[DISPLAY_WIDTH * DISPLAY_HEIGHT]; +static bool display_state; + +void display_setup(void) { + InitWindow(DISPLAY_WIDTH, DISPLAY_HEIGHT, "ILI9341 screen"); +} + +void display_on(void) { + display_state = true; +} + +void display_off(void) { + display_state = false; +} + +void display_begin(void) {} + +void display_end(void) { + BeginDrawing(); + if (display_state) { + for (int32_t y = 0; y < DISPLAY_HEIGHT; y++) { + for (int32_t x = 0; x < DISPLAY_WIDTH; x++) { + uint16_t c = display_framebuffer[y * DISPLAY_WIDTH + x]; + uint8_t r = (c & 0b1111100000000000) >> 8; + uint8_t g = (c & 0b0000011111100000) >> 3; + uint8_t b = (c & 0b0000000000011111) << 3; + DrawPixel(x, y, (Color){ r, g, b, 255 }); + } + } + } else { + for (int32_t y = 0; y < DISPLAY_HEIGHT; y++) { + for (int32_t x = 0; x < DISPLAY_WIDTH; x++) { + DrawPixel(x, y, (Color){ 0, 0, 0, 255 }); + } + } + } + EndDrawing(); + + if (WindowShouldClose()) { + CloseWindow(); + exit(1); + } +} + +void display_clear(uint16_t color) { + for (int i = 0; i < DISPLAY_WIDTH * DISPLAY_HEIGHT; i++) + display_framebuffer[i] = color; +} + +void display_set_pixel(int32_t x, int32_t y, uint16_t color) { + if (x < 0 || x >= DISPLAY_WIDTH || y < 0 || y >= DISPLAY_HEIGHT) + return; + display_framebuffer[y * DISPLAY_WIDTH + x] = color; +} + + +void button_setup(void) { } +bool button_get(void) { + PollInputEvents(); + return IsKeyDown(KEY_SPACE); +} + + +static int server_fd = -1; +static WifiHandler current_handler = nullptr; + +static void set_nonblocking(int fd) { + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); +} + +void wifi_setup(void) { } + +void wifi_hotspot_start(const char *ssid, const char *password, WifiHandler handler) { + (void)ssid; (void)password; + current_handler = handler; + + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { printf("socket failed: %s\n", strerror(errno)); return; } + + int opt = 1; + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) + printf("setsockopt failed: %s\n", strerror(errno)); + + set_nonblocking(server_fd); + + struct sockaddr_in addr = {}; + addr.sin_family = AF_INET; + addr.sin_port = htons(8080); + addr.sin_addr.s_addr = INADDR_ANY; + + if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { printf("bind failed: %s\n", strerror(errno)); return; } + + if (listen(server_fd, 4) < 0) + { printf("listen failed: %s\n", strerror(errno)); return; } + + printf("emulated hotspot at http://localhost:8080\n"); +} + +void wifi_hotspot_stop(void) { + if (server_fd >= 0) { + close(server_fd); + server_fd = -1; + printf("stopped hotspot\n"); + } +} + +void wifi_tick(void) { + if (server_fd < 0) return; + + int client = accept(server_fd, nullptr, nullptr); + if (client < 0) { // no pending connection, non-blocking + if (errno != EAGAIN && errno != EWOULDBLOCK) + printf("accept error: %s\n", strerror(errno)); + return; + } + printf("got connection\n"); + + char buf[2048] = {}; + read(client, buf, sizeof(buf) - 1); + + // parse first line: "GET /uri HTTP/1.1" + char method[8] = {}, uri[256] = {}; + sscanf(buf, "%7s %255s", method, uri); + + // find body after \r\n\r\n + const char *body = strstr(buf, "\r\n\r\n"); + if (body) body += 4; + + WifiRequest req = { + .uri = uri, + .method = method, + .body = (body && *body) ? body : nullptr, + }; + + WifiResponse res = current_handler(&req); + + char header[256]; + snprintf(header, sizeof(header), + "HTTP/1.1 %d OK\r\n" + "Content-Type: %s\r\n" + "Content-Length: %zu\r\n" + "Connection: close\r\n" + "\r\n", + res.status, res.content_type, strlen(res.body) + ); + + write(client, header, strlen(header)); + write(client, res.body, strlen(res.body)); + close(client); +} + + +uint32_t millis() { + return (uint32_t)(GetTime() * 1000); +} |
