diff options
Diffstat (limited to 'pu.c')
| -rw-r--r-- | pu.c | 122 |
1 files changed, 121 insertions, 1 deletions
@@ -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? } |
