249 lines
6.3 KiB
C
249 lines
6.3 KiB
C
#include "devices.h"
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
i32 console_open(void *data, u32 mode) {
|
|
USED(mode);
|
|
USED(data);
|
|
/* Nothing to open — stdin/stdout are always available */
|
|
return 0; /* Success */
|
|
}
|
|
|
|
i32 console_read(void *data, u8 *buffer, u32 size) {
|
|
USED(data);
|
|
for (u32 i = 0; i < size; i++) {
|
|
u8 ch = getchar();
|
|
if (ch == '\0')
|
|
break;
|
|
if (ch == '\n')
|
|
break;
|
|
buffer[i] = ch;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
i32 console_write(void *data, const u8 *buffer, u32 size) {
|
|
USED(data);
|
|
for (u32 i = 0; i < size; i++) {
|
|
putchar(buffer[i]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
i32 console_close(void *data) {
|
|
USED(data);
|
|
/* Nothing to close — stdin/stdout are process-owned */
|
|
return 0;
|
|
}
|
|
|
|
i32 console_ioctl(void *data, u32 cmd, const u8 *buffer) {
|
|
USED(data);
|
|
USED(cmd);
|
|
USED(buffer);
|
|
return -1; /* Unsupported */
|
|
}
|
|
|
|
i32 screen_open(void *data, u32 mode) {
|
|
USED(mode);
|
|
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
|
|
|
screen->window =
|
|
SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
|
|
SDL_WINDOWPOS_CENTERED, screen->width, screen->height,
|
|
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
|
|
|
|
if (!screen->window)
|
|
return -1;
|
|
|
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
|
|
return 0;
|
|
}
|
|
|
|
i32 screen_read(void *data, u8 *buffer, u32 size) {
|
|
USED(data);
|
|
USED(buffer);
|
|
USED(size);
|
|
return -1;
|
|
}
|
|
|
|
i32 screen_write(void *data, const u8 *buffer, u32 size) {
|
|
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
|
|
|
if (size > screen->size * sizeof(u8)) {
|
|
return -1;
|
|
}
|
|
|
|
if (!screen->surface && screen->window) {
|
|
const u8 *pixel_buffer = buffer;
|
|
int pitch = screen->width; // bytes per row
|
|
|
|
screen->surface = SDL_CreateRGBSurfaceFrom((void *)pixel_buffer,
|
|
screen->width, screen->height,
|
|
8, // bits per pixel
|
|
pitch,
|
|
0xE0, // R mask (RGB332)
|
|
0x1C, // G mask
|
|
0x03, // B mask
|
|
0x00 // no alpha
|
|
);
|
|
|
|
if (!screen->surface) {
|
|
fprintf(stderr, "SDL_CreateRGBSurfaceFrom failed: %s\n", SDL_GetError());
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
SDL_BlitScaled(screen->surface, NULL,
|
|
SDL_GetWindowSurface(screen->window), NULL);
|
|
SDL_UpdateWindowSurface(screen->window);
|
|
|
|
return 0;
|
|
}
|
|
|
|
i32 screen_close(void *data) {
|
|
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
|
|
|
if (screen->window) {
|
|
SDL_DestroyWindow(screen->window);
|
|
screen->window = NULL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer) {
|
|
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
|
|
|
switch (cmd) {
|
|
case IOCTL_GET_INFO: {
|
|
u8 *info = (u8 *)buffer;
|
|
u32 size;
|
|
memcpy(&size, &info[0], sizeof(u32));
|
|
|
|
if (size < 16) {
|
|
return -1;
|
|
}
|
|
|
|
memcpy(&info[4], &screen->pos, sizeof(u32));
|
|
memcpy(&info[8], &screen->size, sizeof(u32));
|
|
memcpy(&info[12], &screen->width, sizeof(u32));
|
|
memcpy(&info[16], &screen->height, sizeof(u32));
|
|
return 0;
|
|
}
|
|
|
|
default:
|
|
return -1; // Error
|
|
}
|
|
}
|
|
|
|
/* MOUSE */
|
|
i32 mouse_open(void *data, u32 mode) {
|
|
USED(data);
|
|
USED(mode);
|
|
return 0;
|
|
}
|
|
|
|
i32 mouse_read(void *data, u8 *buffer, u32 size) {
|
|
MouseDeviceData *mouse_data = (MouseDeviceData *)data;
|
|
|
|
if (size < 12)
|
|
return -1;
|
|
|
|
SDL_PumpEvents();
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
switch (event.type) {
|
|
// Mouse events
|
|
case SDL_MOUSEMOTION:
|
|
mouse_data->x = event.motion.x;
|
|
mouse_data->y = event.motion.y;
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
if (event.button.button == SDL_BUTTON_LEFT) mouse_data->btn1 = 1;
|
|
if (event.button.button == SDL_BUTTON_RIGHT) mouse_data->btn2 = 1;
|
|
if (event.button.button == SDL_BUTTON_MIDDLE) mouse_data->btn3 = 1;
|
|
if (event.button.button == SDL_BUTTON_X1) mouse_data->btn4 = 1;
|
|
break;
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
if (event.button.button == SDL_BUTTON_LEFT) mouse_data->btn1 = 0;
|
|
if (event.button.button == SDL_BUTTON_RIGHT) mouse_data->btn2 = 0;
|
|
if (event.button.button == SDL_BUTTON_MIDDLE) mouse_data->btn3 = 0;
|
|
if (event.button.button == SDL_BUTTON_X1) mouse_data->btn4 = 0;
|
|
break;
|
|
|
|
// Touch events (map to mouse_data as left-click equivalent)
|
|
case SDL_FINGERMOTION:
|
|
case SDL_FINGERDOWN:
|
|
case SDL_FINGERUP: {
|
|
|
|
float x = event.tfinger.x * 640;
|
|
float y = event.tfinger.y * 480;
|
|
|
|
mouse_data->x = (int)x;
|
|
mouse_data->y = (int)y;
|
|
|
|
// Only treat the first finger as mouse input (ignore multi-touch beyond 1 finger)
|
|
if (event.tfinger.fingerId == 0) {
|
|
if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION) {
|
|
mouse_data->btn1 = 1;
|
|
} else if (event.type == SDL_FINGERUP) {
|
|
mouse_data->btn1 = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
u8 *info = (u8 *)buffer;
|
|
memcpy(&info[0], &mouse_data->x, sizeof(u32));
|
|
memcpy(&info[4], &mouse_data->y, sizeof(u32));
|
|
memcpy(&info[8], &mouse_data->btn1, sizeof(u8));
|
|
memcpy(&info[9], &mouse_data->btn2, sizeof(u8));
|
|
memcpy(&info[10], &mouse_data->btn3, sizeof(u8));
|
|
memcpy(&info[11], &mouse_data->btn4, sizeof(u8));
|
|
return 0;
|
|
}
|
|
|
|
i32 mouse_write(void *data, const u8 *buffer, u32 size) {
|
|
USED(data);
|
|
USED(buffer);
|
|
USED(size);
|
|
return -1;
|
|
}
|
|
|
|
i32 mouse_close(void *data) {
|
|
USED(data);
|
|
return 0;
|
|
}
|
|
|
|
i32 keyboard_open(void *data, u32 mode) {
|
|
USED(data);
|
|
USED(mode);
|
|
return 0;
|
|
}
|
|
|
|
i32 keyboard_read(void *data, u8 *buffer, u32 size) {
|
|
KeyboardDeviceData *kbd = (KeyboardDeviceData *)data;
|
|
|
|
if (size < (u32)kbd->key_count)
|
|
return -1;
|
|
|
|
memcpy(buffer, kbd->keys, kbd->key_count);
|
|
return 0;
|
|
}
|
|
|
|
i32 keyboard_write(void *data, const u8 *buffer, u32 size) {
|
|
USED(data);
|
|
USED(buffer);
|
|
USED(size);
|
|
return -1; /* not writable */
|
|
}
|
|
|
|
i32 keyboard_close(void *data) {
|
|
USED(data);
|
|
return 0;
|
|
}
|