diff --git a/src/Makefile b/src/Makefile index d77da55..b0c5f71 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,8 +3,8 @@ # Native build (gcc) CC_NATIVE = gcc CFLAGS_NATIVE = -g -std=c89 -Wall -Wextra -Werror -Wno-unused-parameter -I. -LDFLAGS_NATIVE = -LDLIBS_NATIVE = +LDFLAGS_NATIVE = +LDLIBS_NATIVE = -lSDL2 # WASM build (emscripten) CC_WASM = emcc diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c index 78c527f..2fe33bb 100644 --- a/src/arch/linux/main.c +++ b/src/arch/linux/main.c @@ -1,6 +1,7 @@ #include "../../debug.h" #include "../../test.h" #include "../../vm.h" +#include int main(int argc, char **argv) { VM vm = {0}; @@ -9,9 +10,80 @@ int main(int argc, char **argv) { vm.stack_size = STACK_SIZE; vm.memory_size = MEMORY_SIZE; - test_loop_compile(vm.memory); + uint32_t end = test_loop_compile(vm.memory); + /* test_add_function_compile(vm.memory); */ + /* test_recursive_function_compile(vm.memory); */ + uint32_t buffer_size = 640 * 480 * sizeof(uint32_t); - while (step_vm(&vm)){} + Device screen; + screen.type = SCREEN; + screen.s = (Screen){.width = (uint8_t)480, + .height = (uint8_t)640, + .allocated = {end, buffer_size}, + .buffer = &vm.memory[end]}; + vm.devices[vm.dp++] = screen; + vm.mp += buffer_size; + + /* Create window and renderer */ + SDL_Window *window = SDL_CreateWindow( + "Reality Engine VM", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + screen.s.width, screen.s.height, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + + SDL_Renderer *renderer = SDL_CreateRenderer( + window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + /* Create texture for 640x480 buffer */ + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, + screen.s.width, screen.s.height); + + /* Enable nearest-neighbor scaling (preserves pixel art) */ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); /* "0" = nearest-neighbor */ + + while (step_vm(&vm)) { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + return 0; + case SDL_MOUSEBUTTONDOWN: + /* event.button.x, event.button.y, event.button.button */ + break; + case SDL_MOUSEMOTION: + /* handleInput(event.motion.x, event.motion.y, 0); 0 for no button */ + break; + case SDL_FINGERDOWN: + /* handleInput(event.tfinger.x * screen.s.width, */ + /* event.tfinger.y * screen.s.height, 1); // 1 for touch */ + break; + case SDL_FINGERMOTION: + /* handleInput(event.tfinger.x * screen.s.width, */ + /* event.tfinger.y * screen.s.height, 0); // 0 for no button */ + break; + } + } + + SDL_UpdateTexture(texture, NULL, screen.s.buffer, + screen.s.width * sizeof(uint32_t)); + + SDL_RenderClear(renderer); + + /* Optional: Set logical size to maintain 640x480 aspect ratio */ + /* (Scales to fit screen while preserving pixel grid) */ + SDL_Rect output_rect; + SDL_RenderGetViewport(renderer, &output_rect); + float scale_x = (float)output_rect.w / screen.s.width; + float scale_y = (float)output_rect.h / screen.s.height; + float scale = SDL_min(scale_x, scale_y); + + SDL_Rect dstrect = {(int)((output_rect.w - screen.s.width * scale) / 2), + (int)((output_rect.h - screen.s.height * scale) / 2), + (int)(screen.s.width * scale), + (int)(screen.s.height * scale)}; + + SDL_RenderCopy(renderer, texture, NULL, &dstrect); + SDL_RenderPresent(renderer); + } core_dump(&vm); return 0; } diff --git a/src/opcodes.h b/src/opcodes.h index 0768d63..f0580d0 100644 --- a/src/opcodes.h +++ b/src/opcodes.h @@ -22,15 +22,31 @@ typedef struct frame_s { Slice allocated; /* start and end of global allocated block */ } Frame; +typedef struct screen_t { + uint8_t width; + uint8_t height; + Slice allocated; + Value *buffer; +} Screen; + +typedef union device_u { + uint8_t type; + Screen s; +} Device; + #define MEMORY_SIZE 65536 #define FRAMES_SIZE 128 #define STACK_SIZE 256 +#define DEVICES_SIZE 8 typedef struct vm_s { uint32_t pc; /* Program counter */ - uint32_t fp; /* Frame pointer (last allocated value) */ + uint32_t fp; /* Frame pointer (current frame) */ uint32_t sp; /* stack pointer (top of stack) */ uint32_t rp; /* return stack pointer (top of stack) */ uint32_t mp; /* Memory pointer (last allocated value) */ + uint32_t dp; /* device pointer (last allocated device) */ + uint8_t devices_size; + Device devices[DEVICES_SIZE]; uint32_t frames_size; Frame frames[FRAMES_SIZE]; /* function call frames */ uint32_t stack_size; @@ -100,6 +116,14 @@ typedef enum { OP_CMP_STRING, /* cmps : dest = (str == src2) as bool */ } Opcode; +typedef enum { + SCREEN, + MOUSE, + KEYBOARD, + CONTROLLER, + AUDIO, +} Devicecode; + /* defines a uint32 opcode */ #define OP(opcode, a, b, c) ((opcode << 24) | (a << 16) | (b << 8) | c)