From a4b81c2603a25c4020dbedeef0f20115b398b26b Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Wed, 16 Oct 2024 00:25:31 -0400 Subject: [PATCH] Render byte buffers from the application --- assets.h | 12 ++++++ assets/assets.s | 15 ++++++++ assets/lefteye.bin | Bin 0 -> 86016 bytes assets/righteye.bin | Bin 0 -> 86016 bytes game.c | 9 ++++- game.h | 3 +- graphics.c | 92 ++++++++++++++++++++++++++++++++++++++++++++ graphics.h | 22 +++++++++++ main.c | 25 +++--------- makefile | 2 +- 10 files changed, 156 insertions(+), 24 deletions(-) create mode 100644 assets.h create mode 100644 assets/assets.s create mode 100644 assets/lefteye.bin create mode 100644 assets/righteye.bin create mode 100644 graphics.c create mode 100644 graphics.h diff --git a/assets.h b/assets.h new file mode 100644 index 0000000..01b59af --- /dev/null +++ b/assets.h @@ -0,0 +1,12 @@ +#ifndef SHROOMS_VB_NATIVE_ASSETS_ +#define SHROOMS_VB_NATIVE_ASSETS_ + +#include + +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 diff --git a/assets/assets.s b/assets/assets.s new file mode 100644 index 0000000..686c221 --- /dev/null +++ b/assets/assets.s @@ -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" diff --git a/assets/lefteye.bin b/assets/lefteye.bin new file mode 100644 index 0000000000000000000000000000000000000000..f17761d6e8a924d2865f4c6530a1bd13b08e3cec GIT binary patch literal 86016 zcmeI*3v%Ns5I|9HGMm&UJ^i6kBjFiOl`vSj${T_BbHLb1rCuJ-=6Y~_R^Yj9vH)`1 z^m;x&+dI9r{u}-u-V*qK82r#(^0#B?kj>*@0X_H2Kl}$<_nI&7y%y+ep;v~qaRSMo z&p+dsU$)%(v;SX04a!h|+xYt7pYvys^6O^po3HXM82+!FM&;l?O7^{WlfRuq@71Ez zRRZGw)Z@qB26+Fy%JtoLT7Q22_O9Dy<#Yk|>#}BP2mu5TKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**zDHntjQ#o^2}b%G1;+0F?KhG#=Pwdq|9{b9G1SWi*#DQ4 z(%=^fu>Zeku^8&*0_^|GNonwl1la#yv{(%Fasl@L<)k#Ypuqko2iAx!NHlavi~XU! z#fCGK-Wp$Q!ixW5(m&)3QL43+fAueI zdd*rjn#k72;pDtq#*Y);x1`15W_0pfQx@ti@GNRFwWU32FR#CFWq)2&GPn8)$t7L4 zHgZes&ZLeL{!t&jMC+#@3)9b!WJp;L<$m(tO1;SNzEV|HFU^!rybCW_?#JOYnRk3R zP1u-arXJcoMQcV=Kw+X@jzv5-&}mVtm+Lf~$hd2Gns7KKvlJDEP65S< zp^-fer^&tH!)e0p+0fB)yO#EU{jHPE@w0!3x*>IUN+|e z{_+ZNo$M;{ZIc{*X=HzGzrJ7+>UlUR^N!KZgw-hwEzEGi7-1E6XmC6-$OI#lP zWb*WqtEs)dt%YB7>lt+X?Ss3Y@8RZQdD5WGa6?Jc%N9mLN%Xr0_$$YGujxS&XM-Wh zP125UukPn}Q!UXDwuZHuop-h_qdvyUX!Yezdlq^X`-iHLrzO zzN2P$ILAVFdhSlx)pVK`%ZNK%N|k6_QKuM5a!twcy_r%l%D0dAf5Lz68o%!!C$?|n z*ueHAx42|B60LLc`1#(Js>ORBhxg1o#&)VayP9fp1+)#6*{=jH2_~x<)}EK}ryQ^T znkXfs!wB0rvk2tH2m$39$cX z$GJe%t_)B2W)Jhx32KyI5}&*!&{`!3^b z{WttSys-Fx82r#(^0#B?kj>*@0X_H2Kl}$<_nI&7y%y+ep;v~qaRSMo&p+dsU$)%( zv;SX04a!h|+xYt7pYvys^6O^po3HXM82+!FM&;l?O7^{WlfRuq@71EzRRZGw)Z@qB a26+Fy%JtoLT7Q22_O9Dy<#Yk|>+uH_XWy*= literal 0 HcmV?d00001 diff --git a/assets/righteye.bin b/assets/righteye.bin new file mode 100644 index 0000000000000000000000000000000000000000..d323a3c6a96249d86985a120af240b94a58f18e0 GIT binary patch literal 86016 zcmeI*U6R`>5I|vX(wo#Kefx(-jYMvo2Ly$Wk_ZGyz(*T-r0&cP4j9;6@CcM~ip7)op!b+!>i&GR! z>c>legQc|ev)&T-r6Q|7TWC#lQ>uziOZqcORSSSW`iGn$%55#>|N56_`knRGctp0o z4ky=bnZHi>3`xty$>`*#rYzM{;91sW>XXi*v%UVnmHoO)sXXc{B)4?k`j9QLJCnLj z_^m#Ah}OFx3)A~871GvIIp6$`a$i(h4 zWot##Kw;v(oQr&ZK<9~idpT~yiHcp*+l0e0nWd~SbQ&m56z5#z^8+lO3mVzmaGKf; zFK!cV_lAy^+qJa+>TjKNwx9Du)P~gEDc$_@##4~nXzly!n``;0=4hb(Qy5{}5b-fR#t>5nIK4IG%$}aRT{_+ZNo$M-k z`Stex(#Zb${Q81PsQ2Nd${n+v39C~WTAJY^q$4d2#Z&H)Po;9iy(KS~zB74wsnyb6 z-}ZzbI`s@X{`SG$_xEt~v|MS@R=A;*>0t{asTBHI6a1Cq9&5Uh#NJ>?a+0#^+pGKe z*;Gq5gzdq4o9;il0L=~Qfq4X-;pFQ5^1TTQSHz~7>B;eQ{*m+4&-Qjvm}`Txac)wQg=;j}|eSdFX?y5HnRIbSRsJUA9hI4JR)pc*eX>TyI^Q2RE#z-@2 zsfh+><4&Xcm{zkloVLYgSKSGpf|j#WeE~$Jr*@X@r+jPe+~?gXHELc9v3ys}?r^S+ zcDn9P*wu8Jmdl7ITq>1p9C1%ElHyvD^XFqq!)V`L?tg{<+%^8*KXz;n;|O58l2aTq z8_Cu=dH#NGTh->hkHcr>j=7U6&#so5TmfwpW%eV1OM%I1g+0$(_*KqVe=U@j(P5-{ zFk9#Q6RxGE<3vFgSFr$5u1wKfQh$VI^e{uumS@*Oxk>-}5ox*HKj}}nmYPzfGN!mP z?R!ZnE~3)-Z0{=;($PXHhGmOxW$iJyQJV2;e`*J$l7IB<7^}&vB1l@eheP zDgJZZqu1Z__fP1{oMRzK5tu3PevSPzb8hsFz~2PMM!)}{(BH;DJp!`?i2qsg^t*xp z@xQ_0pfp!RbULW1c?7x^7Olc0P(-VDlmpw0>u9;dHP*JfcRfw z6&S-T0pfp_JpHa9K>V+;3XEZv0P#Odo_<#lApTca1;#K-fcT#!ProY&5dSNz0%MpZ zK>W{=r{5I>i2oH*b$HJ34D%27C=si9-mLI4Q1m5TK@z8an#)>bYud$@0Wl0Pl$=~-fM}z7A6egr@Ku4eEyjb39Ucz|MU{5zXiU2_-Frl zn*U{Ae3dW3@PC{i|L4h@9#j0=KGallF==-!44kFLeRV LV|;(~& #include #include #include @@ -11,13 +12,17 @@ int sleepNanos(long int ns) { #define MAX_STEP_CLOCKS 20000 -int runGame(VB *sim) { +int runGame(VB *sim, GraphicsContext *gfx) { uint32_t clocks; SDL_Event event; + gfxUpdateLeftEye(gfx, LEFT_EYE_DEFAULT); + gfxUpdateRightEye(gfx, RIGHT_EYE_DEFAULT); + while (1) { clocks = MAX_STEP_CLOCKS; vbEmulate(sim, &clocks); + gfxRender(gfx); while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { return 0; @@ -25,4 +30,4 @@ int runGame(VB *sim) { } sleepNanos((MAX_STEP_CLOCKS - clocks) * 50); } -} \ No newline at end of file +} diff --git a/game.h b/game.h index fe292d4..9984eea 100644 --- a/game.h +++ b/game.h @@ -1,8 +1,9 @@ #ifndef SHROOMS_VB_NATIVE_GAME_ #define SHROOMS_VB_NATIVE_GAME_ +#include "graphics.h" #include "shrooms-vb-core/core/vb.h" -int runGame(VB *sim); +int runGame(VB *sim, GraphicsContext *gfx); #endif \ No newline at end of file diff --git a/graphics.c b/graphics.c new file mode 100644 index 0000000..6c3c0eb --- /dev/null +++ b/graphics.c @@ -0,0 +1,92 @@ +#include + +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); +} + diff --git a/graphics.h b/graphics.h new file mode 100644 index 0000000..aa4485b --- /dev/null +++ b/graphics.h @@ -0,0 +1,22 @@ +#ifndef SHROOMS_VB_NATIVE_GRAPHICS_ +#define SHROOMS_VB_NATIVE_GRAPHICS_ + +#include + +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 diff --git a/main.c b/main.c index 4174a74..eb7eedf 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "shrooms-vb-core/core/vb.h" #include @@ -51,8 +52,7 @@ int main(int argc, char **argv) { VB *sim; uint8_t *rom; uint32_t romSize; - SDL_Surface *winSurface; - SDL_Window *window; + GraphicsContext gfx; CLIArgs args; int status; @@ -74,27 +74,12 @@ int main(int argc, char **argv) { return 1; } - window = SDL_CreateWindow("Shrooms VB", - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - 384, 224, SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); - if (!window) { - fprintf(stderr, "Error creating window: %s\n", SDL_GetError()); + if (gfxInit(&gfx)) { + SDL_Quit(); return 1; } - winSurface = SDL_GetWindowSurface(window); - 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); + status = runGame(sim, &gfx); SDL_Quit(); - return status; } diff --git a/makefile b/makefile index 48ff4c6..62f6b92 100644 --- a/makefile +++ b/makefile @@ -11,7 +11,7 @@ else endif build: - @$(CC) cli.c game.c main.c -I . \ + @$(CC) cli.c game.c graphics.c main.c assets/assets.s -I . \ $(SHROOMSFLAGS) $(SDL2FLAGS) \ -D POSIX_C_SOURCE=199309L \ -o shrooms-vb \