Render byte buffers from the application

This commit is contained in:
Simon Gellis 2024-10-16 00:25:31 -04:00
parent ce01974243
commit a4b81c2603
10 changed files with 156 additions and 24 deletions

12
assets.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef SHROOMS_VB_NATIVE_ASSETS_
#define SHROOMS_VB_NATIVE_ASSETS_
#include <stdint.h>
extern const uint8_t asset_lefteye_start;
const uint8_t *LEFT_EYE_DEFAULT = &asset_lefteye_start;
extern const uint8_t asset_righteye_start;
const uint8_t *RIGHT_EYE_DEFAULT = &asset_righteye_start;
#endif

15
assets/assets.s Normal file
View File

@ -0,0 +1,15 @@
.section .note.GNU-stack,"",@progbits
.section .bindata, "a", @progbits
.global asset_lefteye_start
.type asset_lefteye_start, @object
.global asset_righteye_start
.type asset_righteye_start, @object
.section .bindata
.balign 64
asset_lefteye_start:
.incbin "assets/lefteye.bin"
.balign 64
asset_righteye_start:
.incbin "assets/righteye.bin"

BIN
assets/lefteye.bin Normal file

Binary file not shown.

BIN
assets/righteye.bin Normal file

Binary file not shown.

7
game.c
View File

@ -1,3 +1,4 @@
#include <assets.h>
#include <game.h> #include <game.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <time.h> #include <time.h>
@ -11,13 +12,17 @@ int sleepNanos(long int ns) {
#define MAX_STEP_CLOCKS 20000 #define MAX_STEP_CLOCKS 20000
int runGame(VB *sim) { int runGame(VB *sim, GraphicsContext *gfx) {
uint32_t clocks; uint32_t clocks;
SDL_Event event; SDL_Event event;
gfxUpdateLeftEye(gfx, LEFT_EYE_DEFAULT);
gfxUpdateRightEye(gfx, RIGHT_EYE_DEFAULT);
while (1) { while (1) {
clocks = MAX_STEP_CLOCKS; clocks = MAX_STEP_CLOCKS;
vbEmulate(sim, &clocks); vbEmulate(sim, &clocks);
gfxRender(gfx);
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) { if (event.type == SDL_QUIT) {
return 0; return 0;

3
game.h
View File

@ -1,8 +1,9 @@
#ifndef SHROOMS_VB_NATIVE_GAME_ #ifndef SHROOMS_VB_NATIVE_GAME_
#define SHROOMS_VB_NATIVE_GAME_ #define SHROOMS_VB_NATIVE_GAME_
#include "graphics.h"
#include "shrooms-vb-core/core/vb.h" #include "shrooms-vb-core/core/vb.h"
int runGame(VB *sim); int runGame(VB *sim, GraphicsContext *gfx);
#endif #endif

92
graphics.c Normal file
View File

@ -0,0 +1,92 @@
#include <graphics.h>
static void copyScreenTexture(uint8_t *dst, const uint8_t *src, int pitch) {
int x, y, i;
uint8_t color;
int delta = pitch / 384;
for (y = 0; y < 224; ++y) {
for (x = 0; x < 384; x += 1) {
color = src[(y * 384) + x];
for (i = 0; i < delta; ++i) {
dst[(y * pitch) + (x * delta) + i] = color;
}
}
}
}
int gfxInit(GraphicsContext *gfx) {
gfx->window = SDL_CreateWindow("Shrooms VB",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
1536, 896, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (!gfx->window) {
fprintf(stderr, "Error creating window: %s\n", SDL_GetError());
return 1;
}
gfx->winSurface = SDL_GetWindowSurface(gfx->window);
if (!gfx->winSurface) {
fprintf(stderr, "Error getting surface: %s\n", SDL_GetError());
goto cleanup_window;
}
gfx->renderer = SDL_GetRenderer(gfx->window);
if (!gfx->renderer) {
fprintf(stderr, "Error getting renderer: %s\n", SDL_GetError());
goto cleanup_window;
}
gfx->leftEye = SDL_CreateTexture(gfx->renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, 384, 224);
if (!gfx->leftEye) {
fprintf(stderr, "Error creating left eye texture: %s\n", SDL_GetError());
goto cleanup_window;
}
SDL_SetTextureColorMod(gfx->leftEye, 255, 0, 0);
gfx->rightEye = SDL_CreateTexture(gfx->renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, 384, 224);
if (!gfx->rightEye) {
fprintf(stderr, "Error creating left eye texture: %s\n", SDL_GetError());
goto cleanup_left_eye;
}
SDL_SetTextureColorMod(gfx->rightEye, 0, 0, 255);
SDL_SetTextureBlendMode(gfx->rightEye, SDL_BLENDMODE_ADD);
return 0;
cleanup_left_eye:
SDL_DestroyTexture(gfx->leftEye);
cleanup_window:
SDL_DestroyWindow(gfx->window);
return 1;
}
void gfxDestroy(GraphicsContext *gfx) {
SDL_DestroyTexture(gfx->rightEye);
SDL_DestroyTexture(gfx->leftEye);
SDL_DestroyWindow(gfx->window);
}
static void gfxUpdateEye(SDL_Texture *eye, const uint8_t *bytes) {
void *target;
int pitch;
if (SDL_LockTexture(eye, NULL, &target, &pitch)) {
fprintf(stderr, "Error locking buffer for eye: %s\n", SDL_GetError());
return;
}
copyScreenTexture(target, bytes, pitch);
SDL_UnlockTexture(eye);
}
void gfxUpdateLeftEye(GraphicsContext *gfx, const uint8_t *bytes) {
gfxUpdateEye(gfx->leftEye, bytes);
}
void gfxUpdateRightEye(GraphicsContext *gfx, const uint8_t *bytes) {
gfxUpdateEye(gfx->rightEye, bytes);
}
void gfxRender(GraphicsContext *gfx) {
SDL_RenderClear(gfx->renderer);
SDL_RenderCopy(gfx->renderer, gfx->leftEye, NULL, NULL);
SDL_RenderCopy(gfx->renderer, gfx->rightEye, NULL, NULL);
SDL_RenderPresent(gfx->renderer);
}

22
graphics.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef SHROOMS_VB_NATIVE_GRAPHICS_
#define SHROOMS_VB_NATIVE_GRAPHICS_
#include <SDL2/SDL.h>
typedef struct {
SDL_Window *window;
SDL_Surface *winSurface;
SDL_Renderer *renderer;
SDL_Texture *leftEye;
SDL_Texture *rightEye;
} GraphicsContext;
int gfxInit(GraphicsContext *gfx);
void gfxDestroy(GraphicsContext *gfx);
void gfxUpdateLeftEye(GraphicsContext *gfx, const uint8_t *bytes);
void gfxUpdateRightEye(GraphicsContext *gfx, const uint8_t *bytes);
void gfxRender(GraphicsContext *gfx);
#endif

25
main.c
View File

@ -1,5 +1,6 @@
#include <cli.h> #include <cli.h>
#include <game.h> #include <game.h>
#include <graphics.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "shrooms-vb-core/core/vb.h" #include "shrooms-vb-core/core/vb.h"
#include <stdio.h> #include <stdio.h>
@ -51,8 +52,7 @@ int main(int argc, char **argv) {
VB *sim; VB *sim;
uint8_t *rom; uint8_t *rom;
uint32_t romSize; uint32_t romSize;
SDL_Surface *winSurface; GraphicsContext gfx;
SDL_Window *window;
CLIArgs args; CLIArgs args;
int status; int status;
@ -74,27 +74,12 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
window = SDL_CreateWindow("Shrooms VB", if (gfxInit(&gfx)) {
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SDL_Quit();
384, 224, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (!window) {
fprintf(stderr, "Error creating window: %s\n", SDL_GetError());
return 1; return 1;
} }
winSurface = SDL_GetWindowSurface(window); status = runGame(sim, &gfx);
if (!winSurface) {
fprintf(stderr, "Error getting surface: %s\n", SDL_GetError());
return 1;
}
SDL_FillRect(winSurface, NULL, SDL_MapRGB(winSurface->format, 255, 0, 0));
SDL_UpdateWindowSurface(window);
status = runGame(sim);
SDL_DestroyWindow(window);
SDL_Quit(); SDL_Quit();
return status; return status;
} }

View File

@ -11,7 +11,7 @@ else
endif endif
build: build:
@$(CC) cli.c game.c main.c -I . \ @$(CC) cli.c game.c graphics.c main.c assets/assets.s -I . \
$(SHROOMSFLAGS) $(SDL2FLAGS) \ $(SHROOMSFLAGS) $(SDL2FLAGS) \
-D POSIX_C_SOURCE=199309L \ -D POSIX_C_SOURCE=199309L \
-o shrooms-vb \ -o shrooms-vb \