undar-lang/src/arch/emscripten/devices.c

244 lines
5.2 KiB
C

#include "devices.h"
#include <stdio.h>
#include <string.h>
#include <emscripten.h>
#include <emscripten/html5.h>
i32 console_open(void *data, u32 mode) {
USED(mode);
USED(data);
return 0;
}
i32 console_read(void *data, u8 *buffer, u32 size) {
USED(data);
for (u32 i = 0; i < size; i++) {
u8 ch = getchar();
if (ch == '\0' || 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);
return 0;
}
i32 console_ioctl(void *data, u32 cmd, const u8 *buffer) {
USED(data);
USED(cmd);
USED(buffer);
return -1;
}
i32 screen_open(void *data, u32 mode) {
USED(mode);
ScreenDeviceData *screen = (ScreenDeviceData *)data;
// Initialize with proper values
screen->width = 640;
screen->height = 480;
screen->size = 640 * 480;
screen->window = NULL;
screen->renderer = NULL;
screen->texture = NULL;
#ifdef __EMSCRIPTEN__
emscripten_set_canvas_element_size("#canvas", screen->width, screen->height);
#endif
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) {
fprintf(stderr, "Failed to create SDL window: %s\n", SDL_GetError());
return -1;
}
// Create renderer with hardware acceleration
screen->renderer = SDL_CreateRenderer(
screen->window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
if (!screen->renderer) {
fprintf(stderr, "Failed to create SDL renderer: %s\n", SDL_GetError());
return -1;
}
// Create the texture with RGB332 format
screen->texture = SDL_CreateTexture(
screen->renderer,
SDL_PIXELFORMAT_RGB332,
SDL_TEXTUREACCESS_STREAMING,
screen->width,
screen->height
);
if (!screen->texture) {
// If RGB332 isn't supported, try RGB888
screen->texture = SDL_CreateTexture(
screen->renderer,
SDL_PIXELFORMAT_RGB888,
SDL_TEXTUREACCESS_STREAMING,
screen->width,
screen->height
);
if (!screen->texture) {
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
return -1;
}
printf("Using RGB888 format (conversion needed)\n");
} else {
printf("Using direct RGB332 format\n");
}
return 0;
}
i32 screen_write(void *data, const u8 *buffer, u32 size) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
if (size > screen->size) {
printf("Screen write size mismatch: %d > %d\n", size, screen->size);
return -1;
}
if (!screen->screen_buffer) {
screen->screen_buffer = (u8*)buffer;
}
// Update texture with new frame data
SDL_UpdateTexture(screen->texture, NULL, buffer, screen->width);
screen->update = true;
return 0;
}
i32 screen_close(void *data) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
if (screen->texture) {
SDL_DestroyTexture(screen->texture);
screen->texture = NULL;
}
if (screen->renderer) {
SDL_DestroyRenderer(screen->renderer);
screen->renderer = NULL;
}
if (screen->window) {
SDL_DestroyWindow(screen->window);
screen->window = NULL;
}
return 0;
}
i32 screen_read(void *data, u8 *buffer, u32 size) {
USED(data);
USED(buffer);
USED(size);
return -1;
}
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;
}
}
i32 mouse_open(void *data, u32 mode) {
USED(mode);
return 0;
}
i32 mouse_read(void *data, u8 *buffer, u32 size) {
MouseDeviceData *mouse_data = (MouseDeviceData *)data;
if (size < 12) return -1;
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;
}
i32 keyboard_close(void *data) {
USED(data);
return 0;
}