aboutsummaryrefslogtreecommitdiff
path: root/pu.c
diff options
context:
space:
mode:
Diffstat (limited to 'pu.c')
-rw-r--r--pu.c122
1 files changed, 121 insertions, 1 deletions
diff --git a/pu.c b/pu.c
index 8e19f10..3de2576 100644
--- a/pu.c
+++ b/pu.c
@@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 700
+#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -57,6 +58,9 @@ char R[]={
#ifndef __WRAPPER
+SDL_Window *window = NULL;
+SDL_Renderer *renderer = NULL;
+
// runs pu until exit code != 2,
// that exit code is an interrupt for talking to the emulated hardware
int emu() {
@@ -64,7 +68,24 @@ int emu() {
pu();
int e_code = m[ 0 ];
- if (e_code != 2) return e_code;
+ // Poll SDL events to handle window close, etc.
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ if (event.type == SDL_QUIT) {
+ if (renderer) SDL_DestroyRenderer(renderer);
+ if (window) SDL_DestroyWindow(window);
+ SDL_Quit();
+ return 0;
+ }
+ // Additional event handling can be added here if needed.
+ }
+
+ if (e_code != 2) {
+ if (renderer) SDL_DestroyRenderer(renderer);
+ if (window) SDL_DestroyWindow(window);
+ SDL_Quit();
+ return e_code;
+ }
// handle hardware interrupts
int int_code = m[ 1 ];
@@ -83,6 +104,105 @@ int emu() {
m[ 2 ] = getchar();
}
+ // 2: graphics operations via SDL2
+ else if (int_code == 2) {
+ int gfx_op = m[ 2 ];
+ switch (gfx_op) {
+ case 0: // Initialize window (parameters: width in m[3], height in m[4])
+ {
+ int width = m[ 3 ];
+ int height = m[ 4 ];
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError());
+ m[ 0 ] = 1; // Set e_code to indicate error
+ break;
+ }
+ window = SDL_CreateWindow(
+ "PU VM Graphics",
+ SDL_WINDOWPOS_CENTERED,
+ SDL_WINDOWPOS_CENTERED,
+ width,
+ height,
+ 0);
+ if (!window) {
+ fprintf(stderr, "SDL_CreateWindow failed: %s\n", SDL_GetError());
+ m[ 0 ] = 1; // Set e_code to indicate error
+ break;
+ }
+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
+ if (!renderer) {
+ fprintf(stderr, "SDL_CreateRenderer failed: %s\n", SDL_GetError());
+ m[ 0 ] = 1; // Set e_code to indicate error
+ break;
+ }
+
+ break;
+ }
+ case 1: // Set draw color (parameters: r in m[3], g in m[4], b in m[5], a in m[6])
+ {
+ Uint8 r = (Uint8) m[ 3 ];
+ Uint8 g = (Uint8) m[ 4 ];
+ Uint8 b = (Uint8) m[ 5 ];
+ Uint8 a = (Uint8) m[ 6 ];
+ SDL_SetRenderDrawColor(renderer, r, g, b, a);
+ break;
+ }
+ case 2: // Clear screen
+ SDL_RenderClear(renderer);
+ break;
+ case 3: // Present (flip buffers)
+ SDL_RenderPresent(renderer);
+ break;
+ case 4: // Draw point (parameters: x in m[3], y in m[4])
+ {
+ int x = m[ 3 ];
+ int y = m[ 4 ];
+ SDL_RenderDrawPoint(renderer, x, y);
+ break;
+ }
+ case 5: // Draw line (parameters: x1 in m[3], y1 in m[4], x2 in m[5], y2 in m[6])
+ {
+ int x1 = m[ 3 ];
+ int y1 = m[ 4 ];
+ int x2 = m[ 5 ];
+ int y2 = m[ 6 ];
+ SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
+ break;
+ }
+ case 6: // Fill rectangle (parameters: x in m[3], y in m[4], w in m[5], h in m[6])
+ {
+ int x = m[ 3 ];
+ int y = m[ 4 ];
+ int w = m[ 5 ];
+ int h = m[ 6 ];
+ SDL_Rect rect = { x, y, w, h };
+ SDL_RenderFillRect(renderer, &rect);
+ break;
+ }
+ case 7: // Draw rectangle outline (parameters: x in m[3], y in m[4], w in m[5], h in
+ // m[6])
+ {
+ int x = m[ 3 ];
+ int y = m[ 4 ];
+ int w = m[ 5 ];
+ int h = m[ 6 ];
+ SDL_Rect rect = { x, y, w, h };
+ SDL_RenderDrawRect(renderer, &rect);
+ break;
+ }
+ case 8: // Quit graphics
+ if (renderer) SDL_DestroyRenderer(renderer);
+ if (window) SDL_DestroyWindow(window);
+ SDL_Quit();
+ renderer = NULL;
+ window = NULL;
+ break;
+ default:
+ // Unknown graphics operation; ignored for simplicity.
+ break;
+ }
+ }
+
else {
// unknown interrupt. what to do?
}