From 96507a596a43e7f5af8672b61442a898a3b79c77 Mon Sep 17 00:00:00 2001 From: erysdren Date: Mon, 22 Sep 2025 05:24:50 -0500 Subject: [PATCH 01/17] examples: start overhauling ex.h --- examples/ex.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/examples/ex.h b/examples/ex.h index c040949..cceb2a3 100644 --- a/examples/ex.h +++ b/examples/ex.h @@ -1,6 +1,41 @@ // ex.h: provides a standard interface for video and keyboard for the // example programs to use. +#include +#include +#include + +#include +#include +#include + +#include + +/* return codes from ex* functions */ +enum { + PL_EXIT_FAILURE = -1, + PL_EXIT_CONTINUE = 0, + PL_EXIT_SUCCESS = 1 +}; + +/* load your files and allocate your buffers here */ +/* NOTE: will be called before a graphics context is ready */ +/* return a value in *appstate and it will get passed in subsequent calls */ +/* return the appropriate PL_EXIT_* code to exit or continue */ +int exInit(void **appstate, int argc, char **argv); + +/* called for each frame the program is running */ +/* return the appropriate PL_EXIT_* code to exit or continue */ +int exIterate(void *appstate); + +/* called each time the user presses a key */ +/* return the appropriate PL_EXIT_* code to exit or continue */ +int exKeyEvent(void *appstate, int key); + +/* called when the program is shutting down */ +/* code will be whatever PL_EXIT_* value caused the program to exit */ +void exQuit(void *appstate, int code); + #if defined(PLUSH_EXAMPLE_SDL2) #include "ex_sdl2.h" #elif defined(PLUSH_EXAMPLE_SDL3) From 6e2385f9f3b43bd7afd9588f78b1b8a251065110 Mon Sep 17 00:00:00 2001 From: erysdren Date: Mon, 22 Sep 2025 05:35:23 -0500 Subject: [PATCH 02/17] examples: ex1: overhaul --- examples/ex1.c | 130 +++++++++++++++++++++++-------------------------- 1 file changed, 61 insertions(+), 69 deletions(-) diff --git a/examples/ex1.c b/examples/ex1.c index fbbcedd..5ad3c94 100644 --- a/examples/ex1.c +++ b/examples/ex1.c @@ -1,85 +1,77 @@ // Ex1.c: simple Plush example // Rotates a flat shaded cube -#include -#include -#include -#include - -// Include the plush header file -#include - -// Include our example graphics interface module #include "ex.h" // Our variables -pl_Light *TheLight; // Our light -pl_Obj *TheCube; // Our cube object -pl_Mat *CubeMat; // The material for the cube -pl_Mat *AllMaterials[2]; // Used for creating palette -pl_Cam *TheCamera; // Our camera -uint8_t TheFrameBuffer[W*H]; // Our framebuffer to render to -uint8_t ThePalette[768]; +static pl_Light *TheLight; // Our light +static pl_Obj *TheCube; // Our cube object +static pl_Mat *CubeMat; // The material for the cube +static pl_Cam *TheCamera; // Our camera +static uint8_t TheFrameBuffer[W*H]; // Our framebuffer to render to +static uint8_t ThePalette[768]; -int main(int argc, char **argv) { // Main -#if defined(DJGPP) || defined(__WATCOMC__) - // Put the fpu in a low precision, no exception state - _control87(MCW_EM|PC_24,MCW_EM|MCW_PC); -#endif +int exInit(void **appstate, int argc, char **argv) +{ + CubeMat = plMatCreate(); // Create the material for the cube + CubeMat->NumGradients = 100; // Have it use 100 colors + CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded + plMatInit(CubeMat); // Initialize the material - exSetGraphics(); // Set graphics + plMatMakeOptPal(ThePalette,1,255,&CubeMat,1); // Create a nice palette - CubeMat = plMatCreate(); // Create the material for the cube - CubeMat->NumGradients = 100; // Have it use 100 colors - CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded - plMatInit(CubeMat); // Initialize the material + ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black - AllMaterials[0] = CubeMat; // Make list of materials - AllMaterials[1] = 0; // Null terminate list of materials - plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette + plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette - ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black + exSetPalette(ThePalette); // Set the palette - plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette + TheCube = plObjCreate(NULL); + TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube - // Convert std 8 bit/chan palette to vga's 6 bit/chan palette - // for (i = 0; i < 768; i ++) ThePalette[i] >>= 2; - exSetPalette(ThePalette); // Set the palette - - TheCube = plObjCreate(NULL); - TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube + // Create the camera + TheCamera = plCamCreate(W, // Screen width + H, // Screen height + W*3.0/(H*4.0), // Aspect ratio + 90.0, // Field of view + TheFrameBuffer, // Framebuffer + NULL); // ZBuffer (none) + TheCamera->Z = -300; // Back the camera up from the origin + + TheLight = plLightSet(plLightCreate(), // Create a light to be set up + PL_LIGHT_VECTOR, // vector light + 0.0,0.0,0.0, // rotation angles + 1.0, // intensity + 1.0); // falloff, not used for vector lights + return PL_EXIT_CONTINUE; +} - TheCamera = plCamCreate(W, // Screen width - H, // Screen height - W*3.0/(H*4.0), // Aspect ratio - 90.0, // Field of view - TheFrameBuffer, // Framebuffer - NULL // ZBuffer (none) - ); // Create the camera - TheCamera->Z = -300; // Back the camera up from the origin +int exIterate(void *appstate) +{ + TheCube->Xa += 1.0; // Rotate by 1 degree on each axis + TheCube->Ya += 1.0; + TheCube->Za += 1.0; + memset(TheFrameBuffer,0,W*H); // clear framebuffer for next frame + plRenderBegin(TheCamera); // Start rendering with the camera + plRenderLight(TheLight); // Render our light + plRenderObj(TheCube); // Render our object + plRenderEnd(); // Finish rendering + exWaitVSync(); // Sync with retrace + memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} - TheLight = plLightSet(plLightCreate(), // Create a light to be set up - PL_LIGHT_VECTOR, // vector light - 0.0,0.0,0.0, // rotation angles - 1.0, // intensity - 1.0); // falloff, not used for vector lights - - while (!exGetKey()) { // While the keyboard hasn't been touched - TheCube->Xa += 1.0; // Rotate by 1 degree on each axis - TheCube->Ya += 1.0; - TheCube->Za += 1.0; - memset(TheFrameBuffer,0,W*H); // clear framebuffer for next frame - plRenderBegin(TheCamera); // Start rendering with the camera - plRenderLight(TheLight); // Render our light - plRenderObj(TheCube); // Render our object - plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen - } - plMatDelete(CubeMat); - plObjDelete(TheCube); - plCamDelete(TheCamera); - plLightDelete(TheLight); - exSetText(); // Restore text mode - return 0; // Quit +void exQuit(void *appstate, int code) +{ + plMatDelete(CubeMat); + plMdlDelete(TheCube->Model); + plObjDelete(TheCube); + plCamDelete(TheCamera); + plLightDelete(TheLight); } From c1373575ab2d9ac9ecc380f8bbc6a4f2d295b795 Mon Sep 17 00:00:00 2001 From: erysdren Date: Tue, 30 Sep 2025 13:48:11 -0500 Subject: [PATCH 03/17] examples: ex_sdl3.h: overhaul --- examples/ex.h | 6 +-- examples/ex_sdl3.h | 107 ++++++++++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/examples/ex.h b/examples/ex.h index cceb2a3..bda58ed 100644 --- a/examples/ex.h +++ b/examples/ex.h @@ -13,9 +13,9 @@ /* return codes from ex* functions */ enum { - PL_EXIT_FAILURE = -1, - PL_EXIT_CONTINUE = 0, - PL_EXIT_SUCCESS = 1 + PL_EXIT_CONTINUE = -1, + PL_EXIT_SUCCESS = 0, + PL_EXIT_FAILURE = 1 }; /* load your files and allocate your buffers here */ diff --git a/examples/ex_sdl3.h b/examples/ex_sdl3.h index 3b85934..b686ce9 100644 --- a/examples/ex_sdl3.h +++ b/examples/ex_sdl3.h @@ -11,29 +11,29 @@ #define H (480) #endif -static uint8_t *exGraphMem = NULL; -static SDL_Window *exWindow = NULL; -static SDL_Renderer *exRenderer = NULL; -static SDL_Texture *exTexture = NULL; -static SDL_Surface *exWindowSurface = NULL; -static SDL_Surface *exSurface = NULL; -static int exMouseButtons = 0; -static int exMouseX = 0; -static int exMouseY = 0; -static int exMouseDeltaX = 0; -static int exMouseDeltaY = 0; - -static int exClockPerSecond(void) +uint8_t *exGraphMem = NULL; +SDL_Window *exWindow = NULL; +SDL_Renderer *exRenderer = NULL; +SDL_Texture *exTexture = NULL; +SDL_Surface *exWindowSurface = NULL; +SDL_Surface *exSurface = NULL; +int exMouseButtons = 0; +int exMouseX = 0; +int exMouseY = 0; +int exMouseDeltaX = 0; +int exMouseDeltaY = 0; + +int exClockPerSecond(void) { return 1000; } -static int exClock(void) +int exClock(void) { return (int)SDL_GetTicks(); } -static int exGetKey(void) +int exGetKey(void) { SDL_Event event; int lastkey = 0; @@ -78,20 +78,7 @@ static int exGetKey(void) return lastkey; } -static void exWaitVSync(void) -{ - if (SDL_LockTexture(exTexture, NULL, &exWindowSurface->pixels, &exWindowSurface->pitch)) - { - SDL_BlitSurface(exSurface, NULL, exWindowSurface, NULL); - SDL_UnlockTexture(exTexture); - } - - SDL_RenderClear(exRenderer); - SDL_RenderTexture(exRenderer, exTexture, NULL, NULL); - SDL_RenderPresent(exRenderer); -} - -static void exSetPalette(uint8_t palette[768]) +void exSetPalette(uint8_t palette[768]) { int i; SDL_Color colors[256]; @@ -107,40 +94,78 @@ static void exSetPalette(uint8_t palette[768]) SDL_SetPaletteColors(SDL_CreateSurfacePalette(exSurface), colors, 0, 256); } -static void exSetGraphics(void) +int exBegin(int argc, char **argv, const char *title) { - uint32_t format; + int r = PL_EXIT_CONTINUE; + void *appstate = NULL; + + if ((r = exInit(&appstate, argc, argv)) != PL_EXIT_CONTINUE) + return r; - SDL_Init(SDL_INIT_VIDEO); + if (!SDL_Init(SDL_INIT_VIDEO)) + return 1; - exWindow = SDL_CreateWindow("Plush Example", W, H, SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE); + if (!SDL_CreateWindowAndRenderer(title, W, H, SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE, &exWindow, &exRenderer)) + return 1; - exRenderer = SDL_CreateRenderer(exWindow, NULL); SDL_SetRenderVSync(exRenderer, 1); SDL_SetRenderLogicalPresentation(exRenderer, W, H, SDL_LOGICAL_PRESENTATION_LETTERBOX); - format = SDL_GetWindowPixelFormat(exWindow); - - exTexture = SDL_CreateTexture(exRenderer, format, SDL_TEXTUREACCESS_STREAMING, W, H); + exTexture = SDL_CreateTexture(exRenderer, SDL_GetWindowPixelFormat(exWindow), SDL_TEXTUREACCESS_STREAMING, W, H); + if (!exTexture) + return 1; SDL_SetTextureScaleMode(exTexture, SDL_SCALEMODE_NEAREST); - exWindowSurface = SDL_CreateSurfaceFrom(W, H, format, NULL, 0); + exWindowSurface = SDL_CreateSurfaceFrom(W, H, SDL_GetWindowPixelFormat(exWindow), NULL, 0); + if (!exWindowSurface) + return 1; exSurface = SDL_CreateSurface(W, H, SDL_PIXELFORMAT_INDEX8); + if (!exSurface) + return 1; exGraphMem = (uint8_t *)exSurface->pixels; SDL_ShowWindow(exWindow); -} -static void exSetText(void) -{ + while (r == PL_EXIT_CONTINUE) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_EVENT_QUIT: + goto done; + + case SDL_EVENT_KEY_DOWN: + r = exKeyEvent(appstate, event.key.key); + break; + } + } + + r = exIterate(appstate); + + if (SDL_LockTexture(exTexture, NULL, &exWindowSurface->pixels, &exWindowSurface->pitch)) + { + SDL_BlitSurface(exSurface, NULL, exWindowSurface, NULL); + SDL_UnlockTexture(exTexture); + } + + SDL_RenderClear(exRenderer); + SDL_RenderTexture(exRenderer, exTexture, NULL, NULL); + SDL_RenderPresent(exRenderer); + } + +done: + exQuit(appstate, r); SDL_DestroySurface(exWindowSurface); SDL_DestroySurface(exSurface); SDL_DestroyTexture(exTexture); SDL_DestroyRenderer(exRenderer); SDL_DestroyWindow(exWindow); SDL_Quit(); + return r; } From 5c4ad1da0dced79cdaa2edf65904e554875451e8 Mon Sep 17 00:00:00 2001 From: erysdren Date: Fri, 3 Oct 2025 09:53:50 -0500 Subject: [PATCH 04/17] examples: ex_sdl3.h: update --- examples/ex_sdl3.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/ex_sdl3.h b/examples/ex_sdl3.h index b686ce9..f641e4b 100644 --- a/examples/ex_sdl3.h +++ b/examples/ex_sdl3.h @@ -130,7 +130,7 @@ int exBegin(int argc, char **argv, const char *title) SDL_ShowWindow(exWindow); - while (r == PL_EXIT_CONTINUE) + while (true) { SDL_Event event; while (SDL_PollEvent(&event)) @@ -141,12 +141,14 @@ int exBegin(int argc, char **argv, const char *title) goto done; case SDL_EVENT_KEY_DOWN: - r = exKeyEvent(appstate, event.key.key); + if ((r = exKeyEvent(appstate, event.key.key)) != PL_EXIT_CONTINUE) + goto done; break; } } - r = exIterate(appstate); + if ((r = exIterate(appstate)) != PL_EXIT_CONTINUE) + goto done; if (SDL_LockTexture(exTexture, NULL, &exWindowSurface->pixels, &exWindowSurface->pitch)) { From e141b2988983512e12dc60c8aa50af559105705e Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 12:03:58 -0500 Subject: [PATCH 05/17] examples: ex_sdl3.h: update --- examples/ex_sdl3.h | 74 ++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/examples/ex_sdl3.h b/examples/ex_sdl3.h index f641e4b..c5fb296 100644 --- a/examples/ex_sdl3.h +++ b/examples/ex_sdl3.h @@ -33,51 +33,6 @@ int exClock(void) return (int)SDL_GetTicks(); } -int exGetKey(void) -{ - SDL_Event event; - int lastkey = 0; - - exMouseDeltaX = exMouseDeltaY = 0; - - while (SDL_PollEvent(&event)) - { - switch (event.type) - { - case SDL_EVENT_QUIT: - lastkey = 27; - break; - - case SDL_EVENT_MOUSE_BUTTON_DOWN: - if (event.button.button == SDL_BUTTON_LEFT) - exMouseButtons |= 1; - if (event.button.button == SDL_BUTTON_RIGHT) - exMouseButtons |= 2; - break; - - case SDL_EVENT_MOUSE_BUTTON_UP: - if (event.button.button == SDL_BUTTON_LEFT) - exMouseButtons &= ~1; - if (event.button.button == SDL_BUTTON_RIGHT) - exMouseButtons &= ~2; - break; - - case SDL_EVENT_MOUSE_MOTION: - exMouseX = event.motion.x; - exMouseY = event.motion.y; - exMouseDeltaX = event.motion.xrel; - exMouseDeltaY = event.motion.yrel; - break; - - case SDL_EVENT_KEY_DOWN: - lastkey = event.key.key; - break; - } - } - - return lastkey; -} - void exSetPalette(uint8_t palette[768]) { int i; @@ -99,9 +54,6 @@ int exBegin(int argc, char **argv, const char *title) int r = PL_EXIT_CONTINUE; void *appstate = NULL; - if ((r = exInit(&appstate, argc, argv)) != PL_EXIT_CONTINUE) - return r; - if (!SDL_Init(SDL_INIT_VIDEO)) return 1; @@ -130,8 +82,13 @@ int exBegin(int argc, char **argv, const char *title) SDL_ShowWindow(exWindow); + if ((r = exInit(&appstate, argc, argv)) != PL_EXIT_CONTINUE) + return r; + while (true) { + exMouseDeltaX = exMouseDeltaY = 0; + SDL_Event event; while (SDL_PollEvent(&event)) { @@ -140,6 +97,27 @@ int exBegin(int argc, char **argv, const char *title) case SDL_EVENT_QUIT: goto done; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + if (event.button.button == SDL_BUTTON_LEFT) + exMouseButtons |= 1; + if (event.button.button == SDL_BUTTON_RIGHT) + exMouseButtons |= 2; + break; + + case SDL_EVENT_MOUSE_BUTTON_UP: + if (event.button.button == SDL_BUTTON_LEFT) + exMouseButtons &= ~1; + if (event.button.button == SDL_BUTTON_RIGHT) + exMouseButtons &= ~2; + break; + + case SDL_EVENT_MOUSE_MOTION: + exMouseX = event.motion.x; + exMouseY = event.motion.y; + exMouseDeltaX = event.motion.xrel; + exMouseDeltaY = event.motion.yrel; + break; + case SDL_EVENT_KEY_DOWN: if ((r = exKeyEvent(appstate, event.key.key)) != PL_EXIT_CONTINUE) goto done; From 7b38abbc2774c7308bfaab06781df51bb2e2196e Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 12:04:08 -0500 Subject: [PATCH 06/17] examples: ex1: update --- examples/ex1.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/ex1.c b/examples/ex1.c index 5ad3c94..6deec55 100644 --- a/examples/ex1.c +++ b/examples/ex1.c @@ -56,7 +56,6 @@ int exIterate(void *appstate) plRenderLight(TheLight); // Render our light plRenderObj(TheCube); // Render our object plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen return PL_EXIT_CONTINUE; } @@ -75,3 +74,8 @@ void exQuit(void *appstate, int code) plCamDelete(TheCamera); plLightDelete(TheLight); } + +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "ex1: Simple Plush example"); +} From 9ebfd3dbbc57338fe308241264b21e6304014f56 Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 21:51:30 -0500 Subject: [PATCH 07/17] examples: ex2: update --- examples/ex2.c | 205 ++++++++++++++++++++++++------------------------- 1 file changed, 102 insertions(+), 103 deletions(-) diff --git a/examples/ex2.c b/examples/ex2.c index 8f0c378..bc686e7 100644 --- a/examples/ex2.c +++ b/examples/ex2.c @@ -3,110 +3,109 @@ // The cube is now a different colored cube then ex1.c // ZBuffering has been added, as well as dynamic framebuffer allocation -#include -#include -#include -#include - -// Include the plush header file -#include - -// Include our example graphics interface module #include "ex.h" // Our variables -pl_Light *TheLight; // Our light -pl_Obj *TheCube; // Our cube object -pl_Mat *CubeMat; // The material for the cube -pl_Mat *AllMaterials[2]; // Used for creating palette -pl_Cam *TheCamera; // Our camera -uint8_t *TheFrameBuffer; // Our framebuffer to render to -float *TheZBuffer; // Our zbuffer -uint8_t ThePalette[768]; - -int main(int argc, char **argv) { // Main -#if defined(DJGPP) || defined(__WATCOMC__) - // Put the fpu in a low precision, no exception state - _control87(MCW_EM|PC_24,MCW_EM|MCW_PC); -#endif - exSetGraphics(); // Set graphics - - TheFrameBuffer = (uint8_t *) plMalloc(W*H); // Alloc framebuffer - if (!TheFrameBuffer) { - exSetText(); - printf("Out of memory!\n"); - exit(1); - } - // Alloc z-buffer - TheZBuffer = (float *) plMalloc(W*H*sizeof(float)); - - CubeMat = plMatCreate(); // Create the material for the cube - CubeMat->NumGradients = 100; // Have it use 100 colors - CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded - - CubeMat->Ambient[0] = 32; // Set red ambient component - CubeMat->Ambient[1] = 0; // Set green ambient component - CubeMat->Ambient[2] = 16; // Set blue ambient component - - CubeMat->Diffuse[0] = 200; // Set red diffuse component - CubeMat->Diffuse[1] = 100; // Set green diffuse component - CubeMat->Diffuse[2] = 150; // Set blue diffuse component - - plMatInit(CubeMat); // Initialize the material - - AllMaterials[0] = CubeMat; // Make list of materials - AllMaterials[1] = 0; // Null terminate list of materials - plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette - - ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black - - plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette - - // Convert std 8 bit/chan palette to vga's 6 bit/chan palette - // for (i = 0; i < 768; i ++) ThePalette[i] >>= 2; - exSetPalette(ThePalette); // Set the palette - - TheCube = plObjCreate(NULL); - TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube - - TheCamera = plCamCreate(W, // Screen width - H, // Screen height - W*3.0/(H*4.0), // Aspect ratio - 90.0, // Field of view - TheFrameBuffer, // Framebuffer - TheZBuffer // ZBuffer - ); // Create the camera - TheCamera->Z = -300; // Back the camera up from the origin - TheCamera->Sort = 0; // We don't need to sort since zbuffering takes care - // of it for us! - - TheLight = plLightSet(plLightCreate(), // Create a light to be set up - PL_LIGHT_VECTOR, // vector light - 0.0,0.0,0.0, // rotation angles - 1.0, // intensity - 1.0); // falloff, not used for vector lights - - while (!exGetKey()) { // While the keyboard hasn't been touched - TheCube->Xa += 1.0; // Rotate by 1 degree on each axis - TheCube->Ya += 1.0; - TheCube->Za += 1.0; - - // clear zbuffer for next frame - memset(TheZBuffer,0,W*H*sizeof(float)); - memset(TheFrameBuffer,0,W*H); // clear framebuffer for next frame - plRenderBegin(TheCamera); // Start rendering with the camera - plRenderLight(TheLight); // Render our light - plRenderObj(TheCube); // Render our object - plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen - } - plFree(TheFrameBuffer); - plFree(TheZBuffer); - plMatDelete(CubeMat); - plObjDelete(TheCube); - plCamDelete(TheCamera); - plLightDelete(TheLight); - exSetText(); // Restore text mode - return 0; // Quit +static pl_Light *TheLight; // Our light +static pl_Obj *TheCube; // Our cube object +static pl_Mat *CubeMat; // The material for the cube +static pl_Mat *AllMaterials[2]; // Used for creating palette +static pl_Cam *TheCamera; // Our camera +static uint8_t *TheFrameBuffer; // Our framebuffer to render to +static float *TheZBuffer; // Our zbuffer +static uint8_t ThePalette[768]; + +int exInit(void **appstate, int argc, char **argv) +{ + TheFrameBuffer = (uint8_t *)plMalloc(W*H*sizeof(uint8_t)); // Alloc framebuffer + if (!TheFrameBuffer) + return PL_EXIT_FAILURE; + + // Alloc z-buffer + TheZBuffer = (float *)plMalloc(W*H*sizeof(float)); + if (!TheZBuffer) + return PL_EXIT_FAILURE; + + CubeMat = plMatCreate(); // Create the material for the cube + CubeMat->NumGradients = 100; // Have it use 100 colors + CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded + + CubeMat->Ambient[0] = 32; // Set red ambient component + CubeMat->Ambient[1] = 0; // Set green ambient component + CubeMat->Ambient[2] = 16; // Set blue ambient component + + CubeMat->Diffuse[0] = 200; // Set red diffuse component + CubeMat->Diffuse[1] = 100; // Set green diffuse component + CubeMat->Diffuse[2] = 150; // Set blue diffuse component + + plMatInit(CubeMat); // Initialize the material + + AllMaterials[0] = CubeMat; // Make list of materials + AllMaterials[1] = 0; // Null terminate list of materials + plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette + + ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black + + plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette + + exSetPalette(ThePalette); // Set the palette + + TheCube = plObjCreate(NULL); + TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube + + // Create the camera + TheCamera = plCamCreate(W, // Screen width + H, // Screen height + W*3.0/(H*4.0), // Aspect ratio + 90.0, // Field of view + TheFrameBuffer, // Framebuffer + TheZBuffer); // ZBuffer + TheCamera->Z = -300; // Back the camera up from the origin + TheCamera->Sort = 0; // We don't need to sort since zbuffering takes care + // of it for us! + + TheLight = plLightSet(plLightCreate(), // Create a light to be set up + PL_LIGHT_VECTOR, // vector light + 0.0,0.0,0.0, // rotation angles + 1.0, // intensity + 1.0); // falloff, not used for vector lights + + return PL_EXIT_CONTINUE; +} + +int exIterate(void *appstate) +{ + TheCube->Xa += 1.0; // Rotate by 1 degree on each axis + TheCube->Ya += 1.0; + TheCube->Za += 1.0; + + plMemSet(TheZBuffer,0,W*H*sizeof(float)); // clear zbuffer for next frame + plMemSet(TheFrameBuffer,0,W*H*sizeof(uint8_t)); // clear framebuffer for next frame + plRenderBegin(TheCamera); // Start rendering with the camera + plRenderLight(TheLight); // Render our light + plRenderObj(TheCube); // Render our object + plRenderEnd(); // Finish rendering + plMemCpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +void exQuit(void *appstate, int code) +{ + plFree(TheFrameBuffer); + plFree(TheZBuffer); + plMatDelete(CubeMat); + plObjDelete(TheCube); + plCamDelete(TheCamera); + plLightDelete(TheLight); +} + +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "ex2: Simple Plush example"); } From 26df28cc888c4ae394d1b809492c68cfec9beef2 Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 21:58:12 -0500 Subject: [PATCH 08/17] examples: ex3: update --- examples/ex3.c | 282 ++++++++++++++++++++++++------------------------- 1 file changed, 141 insertions(+), 141 deletions(-) diff --git a/examples/ex3.c b/examples/ex3.c index 0539cc1..9dc8477 100644 --- a/examples/ex3.c +++ b/examples/ex3.c @@ -4,148 +4,148 @@ // Also rotates the lightsource around // Added from ex2: frees up memory at the end (good to do :) -#include -#include -#include -#include - -// Include the plush header file -#include - -// Include our example graphics interface module #include "ex.h" // Our variables -pl_Light *TheLight; // Our light -float TheLight_Xa, TheLight_Ya, TheLight_Za; - // The rotation angles of our light -pl_Obj *TheCube; // Our cube object -pl_Obj *TheTorus; // Our torus object -pl_Mat *CubeMat; // The material for the cube -pl_Mat *TorusMat; // The material for the torus -pl_Mat *AllMaterials[3]; // Used for creating palette -pl_Cam *TheCamera; // Our camera -uint8_t *TheFrameBuffer; // Our framebuffer to render to -float *TheZBuffer; // Our zbuffer -uint8_t ThePalette[768]; - -int main(int argc, char **argv) { // Main -#if defined(DJGPP) || defined(__WATCOMC__) - // Put the fpu in a low precision, no exception state - _control87(MCW_EM|PC_24,MCW_EM|MCW_PC); -#endif - exSetGraphics(); // Set graphics - - TheFrameBuffer = (uint8_t *) plMalloc(W*H); // Alloc framebuffer - if (!TheFrameBuffer) { - exSetText(); - printf("Out of memory!\n"); - exit(1); - } - // Alloc z-buffer - TheZBuffer = (float *) plMalloc(W*H*sizeof(float)); - - CubeMat = plMatCreate(); // Create the material for the cube - CubeMat->NumGradients = 100; // Have it use 100 colors - CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded - - CubeMat->Ambient[0] = 32; // Set red ambient component - CubeMat->Ambient[1] = 0; // Set green ambient component - CubeMat->Ambient[2] = 16; // Set blue ambient component - - CubeMat->Diffuse[0] = 200; // Set red diffuse component - CubeMat->Diffuse[1] = 100; // Set green diffuse component - CubeMat->Diffuse[2] = 150; // Set blue diffuse component - - plMatInit(CubeMat); // Initialize the material - - TorusMat = plMatCreate(); // Create the material for the torus - TorusMat->NumGradients = 100; // Have it use 100 colors - TorusMat->ShadeType = PL_SHADE_GOURAUD; // Make the torus gouraud shaded - TorusMat->Shininess = 10; // Make the torus a bit more shiny - - TorusMat->Ambient[0] = 0; // Set red ambient component - TorusMat->Ambient[1] = 12; // Set green ambient component - TorusMat->Ambient[2] = 4; // Set blue ambient component - - TorusMat->Diffuse[0] = 20; // Set red diffuse component - TorusMat->Diffuse[1] = 60; // Set green diffuse component - TorusMat->Diffuse[2] = 70; // Set blue diffuse component - - TorusMat->Specular[0] = 100; // Set red specular component - TorusMat->Specular[1] = 200; // Set green specular component - TorusMat->Specular[2] = 150; // Set blue specular component - - AllMaterials[0] = CubeMat; // Make list of materials - AllMaterials[1] = TorusMat; // Make list of materials - AllMaterials[2] = 0; // Null terminate list of materials - plMatMakeOptPal(ThePalette,1,255,AllMaterials,2); // Create a nice palette - - ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black - - plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette - plMatMapToPal(TorusMat,ThePalette,0,255); // Map the material to our palette - - // Convert std 8 bit/chan palette to vga's 6 bit/chan palette - // for (i = 0; i < 768; i ++) ThePalette[i] >>= 2; - exSetPalette(ThePalette); // Set the palette - - TheCube = plObjCreate(NULL); - TheTorus = plObjCreate(NULL); - TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube - TheTorus->Model = plMakeTorus(40.0,100.0,10,8,TorusMat); // Create the torus - - TheTorus->Xp = -70.0; // Shift the torus to the left a bit - - TheCamera = plCamCreate(W, // Screen width - H, // Screen height - W*3.0/(H*4.0), // Aspect ratio - 90.0, // Field of view - TheFrameBuffer, // Framebuffer - TheZBuffer // ZBuffer - ); // Create the camera - TheCamera->Z = -300; // Back the camera up from the origin - TheCamera->Sort = 0; // We don't need to sort since zbuffering takes care - // of it for us! - - TheLight = plLightCreate(); // Create the light. Will be set up every frame - - while (!exGetKey()) { // While the keyboard hasn't been touched - TheCube->Xa += 1.0; // Rotate cube by 1 degree on each axis - TheCube->Ya += 1.0; - TheCube->Za += 1.0; - - TheTorus->Xa += 1.9; // Rotate the torus - TheTorus->Ya -= 1.0; - TheTorus->Za += 0.3; - - TheLight_Za += 1.0; // Rotate the light - TheLight_Xa = 50.0; - - plLightSet(TheLight, PL_LIGHT_VECTOR, // Set the newly rotated light - TheLight_Xa, TheLight_Ya, TheLight_Za, // angles - 1.0, // intensity - 1.0); // falloff, not used for vector lights - - // clear zbuffer for next frame - memset(TheZBuffer,0,W*H*sizeof(float)); - memset(TheFrameBuffer,0,W*H); // clear framebuffer for next frame - plRenderBegin(TheCamera); // Start rendering with the camera - plRenderLight(TheLight); // Render our light - plRenderObj(TheCube); // Render our cube - plRenderObj(TheTorus); // Render our torus - plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen - } - plFree(TheFrameBuffer); // Free up memory - plFree(TheZBuffer); - plCamDelete(TheCamera); - plLightDelete(TheLight); - plObjDelete(TheCube); - plObjDelete(TheTorus); - plMatDelete(CubeMat); - plMatDelete(TorusMat); - exSetText(); // Restore text mode - return 0; // Quit +static pl_Light *TheLight; // Our light +static float TheLight_Xa, TheLight_Ya, TheLight_Za; // The rotation angles of our light +static pl_Obj *TheCube; // Our cube object +static pl_Obj *TheTorus; // Our torus object +static pl_Mat *CubeMat; // The material for the cube +static pl_Mat *TorusMat; // The material for the torus +static pl_Mat *AllMaterials[3]; // Used for creating palette +static pl_Cam *TheCamera; // Our camera +static uint8_t *TheFrameBuffer; // Our framebuffer to render to +static float *TheZBuffer; // Our zbuffer +static uint8_t ThePalette[768]; + +int exInit(void **appstate, int argc, char **argv) +{ + TheFrameBuffer = (uint8_t *)plMalloc(W*H*sizeof(uint8_t)); // Alloc framebuffer + if (!TheFrameBuffer) + return PL_EXIT_FAILURE; + + // Alloc z-buffer + TheZBuffer = (float *)plMalloc(W*H*sizeof(float)); + if (!TheZBuffer) + return PL_EXIT_FAILURE; + + CubeMat = plMatCreate(); // Create the material for the cube + CubeMat->NumGradients = 100; // Have it use 100 colors + CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded + + CubeMat->Ambient[0] = 32; // Set red ambient component + CubeMat->Ambient[1] = 0; // Set green ambient component + CubeMat->Ambient[2] = 16; // Set blue ambient component + + CubeMat->Diffuse[0] = 200; // Set red diffuse component + CubeMat->Diffuse[1] = 100; // Set green diffuse component + CubeMat->Diffuse[2] = 150; // Set blue diffuse component + + plMatInit(CubeMat); // Initialize the material + + TorusMat = plMatCreate(); // Create the material for the torus + TorusMat->NumGradients = 100; // Have it use 100 colors + TorusMat->ShadeType = PL_SHADE_GOURAUD; // Make the torus gouraud shaded + TorusMat->Shininess = 10; // Make the torus a bit more shiny + + TorusMat->Ambient[0] = 0; // Set red ambient component + TorusMat->Ambient[1] = 12; // Set green ambient component + TorusMat->Ambient[2] = 4; // Set blue ambient component + + TorusMat->Diffuse[0] = 20; // Set red diffuse component + TorusMat->Diffuse[1] = 60; // Set green diffuse component + TorusMat->Diffuse[2] = 70; // Set blue diffuse component + + TorusMat->Specular[0] = 100; // Set red specular component + TorusMat->Specular[1] = 200; // Set green specular component + TorusMat->Specular[2] = 150; // Set blue specular component + + AllMaterials[0] = CubeMat; // Make list of materials + AllMaterials[1] = TorusMat; // Make list of materials + AllMaterials[2] = 0; // Null terminate list of materials + plMatMakeOptPal(ThePalette,1,255,AllMaterials,2); // Create a nice palette + + ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black + + plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette + plMatMapToPal(TorusMat,ThePalette,0,255); // Map the material to our palette + + exSetPalette(ThePalette); // Set the palette + + TheCube = plObjCreate(NULL); + TheTorus = plObjCreate(NULL); + TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube + TheTorus->Model = plMakeTorus(40.0,100.0,10,8,TorusMat); // Create the torus + + TheTorus->Xp = -70.0; // Shift the torus to the left a bit + + // Create the camera + TheCamera = plCamCreate(W, // Screen width + H, // Screen height + W*3.0/(H*4.0), // Aspect ratio + 90.0, // Field of view + TheFrameBuffer, // Framebuffer + TheZBuffer); // ZBuffer + TheCamera->Z = -300; // Back the camera up from the origin + TheCamera->Sort = 0; // We don't need to sort since zbuffering takes care + // of it for us! + + TheLight = plLightCreate(); // Create the light. Will be set up every frame + + return PL_EXIT_CONTINUE; +} + +int exIterate(void *appstate) +{ + TheCube->Xa += 1.0; // Rotate cube by 1 degree on each axis + TheCube->Ya += 1.0; + TheCube->Za += 1.0; + + TheTorus->Xa += 1.9; // Rotate the torus + TheTorus->Ya -= 1.0; + TheTorus->Za += 0.3; + + TheLight_Za += 1.0; // Rotate the light + TheLight_Xa = 50.0; + + plLightSet(TheLight, + PL_LIGHT_VECTOR, // Set the newly rotated light + TheLight_Xa, TheLight_Ya, TheLight_Za, // angles + 1.0, // intensity + 1.0); // falloff, not used for vector lights + + // clear zbuffer for next frame + plMemSet(TheZBuffer,0,W*H*sizeof(float)); + plMemSet(TheFrameBuffer,0,W*H*sizeof(uint8_t)); // clear framebuffer for next frame + plRenderBegin(TheCamera); // Start rendering with the camera + plRenderLight(TheLight); // Render our light + plRenderObj(TheCube); // Render our cube + plRenderObj(TheTorus); // Render our torus + plRenderEnd(); // Finish rendering + plMemCpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +void exQuit(void *appstate, int code) +{ + plFree(TheFrameBuffer); // Free up memory + plFree(TheZBuffer); + plCamDelete(TheCamera); + plLightDelete(TheLight); + plObjDelete(TheCube); + plObjDelete(TheTorus); + plMatDelete(CubeMat); + plMatDelete(TorusMat); +} + +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "ex3: Simple Plush example"); } From d4cffad966348d63cdaad05acc76e2f394aef08f Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 22:03:04 -0500 Subject: [PATCH 09/17] examples: ex4: update --- examples/ex4.c | 205 ++++++++++++++++++++++++------------------------- 1 file changed, 100 insertions(+), 105 deletions(-) diff --git a/examples/ex4.c b/examples/ex4.c index b960df9..b35ce34 100644 --- a/examples/ex4.c +++ b/examples/ex4.c @@ -2,112 +2,107 @@ // Rotates a flat shaded texture mapped cube // Reads texture from texture1.pcx -#include -#include -#include -#include - -// Include the plush header file -#include - -// Include our example graphics interface module #include "ex.h" // Our variables -pl_Light *TheLight; // Our light -pl_Obj *TheCube; // Our cube object -pl_Mat *CubeMat; // The material for the cube -pl_Mat *AllMaterials[2]; // Used for creating palette -pl_Cam *TheCamera; // Our camera -uint8_t TheFrameBuffer[W*H]; // Our framebuffer to render to -uint8_t ThePalette[768]; - -int main(int argc, char **argv) { // Main - int done; - // Show user controls - printf("Controls:\n" - " SPACE: toggle perspective correction\n" - " ESC: quit\n" - " Hit any key to begin\n"); -#if 0 - while (!exGetKey()); // Wait for key - while (exGetKey()); // Make sure no other keys are in the queue -#endif - -#if defined(DJGPP) || defined(__WATCOMC__) - // Put the fpu in a low precision, no exception state - _control87(MCW_EM|PC_24,MCW_EM|MCW_PC); -#endif - exSetGraphics(); // Set graphics - - CubeMat = plMatCreate(); // Create the material for the cube - CubeMat->NumGradients = 256; // Have it use 256 colors - CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded - CubeMat->Texture = plReadPCXTex("texture1.pcx", - 1, // Rescale the texture if necessary - 1 // Tell it to optimize the texture's palette - ); - CubeMat->PerspectiveCorrect = 0; // No correction by default - // These are 128 by default, but make it to bright for this app - CubeMat->Diffuse[0] = CubeMat->Diffuse[1] = CubeMat->Diffuse[2] = 0; - plMatInit(CubeMat); // Initialize the material - - AllMaterials[0] = CubeMat; // Make list of materials - AllMaterials[1] = 0; // Null terminate list of materials - plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette - - ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black - - plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette - - // Convert std 8 bit/chan palette to vga's 6 bit/chan palette - // for (i = 0; i < 768; i ++) ThePalette[i] >>= 2; - exSetPalette(ThePalette); // Set the palette - - TheCube = plObjCreate(NULL); - TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube - - TheCamera = plCamCreate(W, // Screen width - H, // Screen height - W*3.0/(H*4.0), // Aspect ratio - 60.0, // Field of view - TheFrameBuffer, // Framebuffer - NULL // ZBuffer (none) - ); // Create the camera - TheCamera->Z = -300; // Back the camera up from the origin - - TheLight = plLightSet(plLightCreate(), // Create a light to be set up - PL_LIGHT_VECTOR, // vector light - 0.0,0.0,0.0, // rotation angles - 1.0, // intensity - 1.0); // falloff, not used for vector lights - - done = 0; - while (!done) { // While the keyboard hasn't been touched - TheCube->Xa += 1.0; // Rotate by 1 degree on each axis - TheCube->Ya += 1.0; - TheCube->Za += 1.0; - memset(TheFrameBuffer,0,W*H); // clear framebuffer for next frame - plRenderBegin(TheCamera); // Start rendering with the camera - plRenderLight(TheLight); // Render our light - plRenderObj(TheCube); // Render our object - plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen - switch (exGetKey()) { - case 0: break; // no key - case 27: done = 1; break; // esc - case ' ': // space - CubeMat->PerspectiveCorrect ^= 8; // Toggle whether or not it's 8 - plMatInit(CubeMat); - break; - } - } - plTexDelete(CubeMat->Texture); - plMatDelete(CubeMat); - plObjDelete(TheCube); - plCamDelete(TheCamera); - plLightDelete(TheLight); - exSetText(); // Restore text mode - return 0; // Quit +static pl_Light *TheLight; // Our light +static pl_Obj *TheCube; // Our cube object +static pl_Mat *CubeMat; // The material for the cube +static pl_Mat *AllMaterials[2]; // Used for creating palette +static pl_Cam *TheCamera; // Our camera +static uint8_t TheFrameBuffer[W*H]; // Our framebuffer to render to +static uint8_t ThePalette[768]; + +int exInit(void **appstate, int argc, char **argv) +{ + // Show user controls + printf("Controls:\n" + " SPACE: toggle perspective correction\n" + " ESC: quit\n" + " Hit any key to begin\n"); + + CubeMat = plMatCreate(); // Create the material for the cube + CubeMat->NumGradients = 256; // Have it use 256 colors + CubeMat->ShadeType = PL_SHADE_FLAT; // Make the cube flat shaded + CubeMat->Texture = plReadPCXTex("texture1.pcx", + 1, // Rescale the texture if necessary + 1); // Tell it to optimize the texture's palette + CubeMat->PerspectiveCorrect = 0; // No correction by default + // These are 128 by default, but make it to bright for this app + CubeMat->Diffuse[0] = CubeMat->Diffuse[1] = CubeMat->Diffuse[2] = 0; + plMatInit(CubeMat); // Initialize the material + + AllMaterials[0] = CubeMat; // Make list of materials + AllMaterials[1] = 0; // Null terminate list of materials + plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette + + ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black + + plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette + + exSetPalette(ThePalette); // Set the palette + + TheCube = plObjCreate(NULL); + TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube + + // Create the camera + TheCamera = plCamCreate(W, // Screen width + H, // Screen height + W*3.0/(H*4.0), // Aspect ratio + 60.0, // Field of view + TheFrameBuffer, // Framebuffer + NULL); // ZBuffer (none) + TheCamera->Z = -300; // Back the camera up from the origin + + TheLight = plLightSet(plLightCreate(), // Create a light to be set up + PL_LIGHT_VECTOR, // vector light + 0.0,0.0,0.0, // rotation angles + 1.0, // intensity + 1.0); // falloff, not used for vector lights + + return PL_EXIT_CONTINUE; +} + +int exIterate(void *appstate) +{ + TheCube->Xa += 1.0; // Rotate by 1 degree on each axis + TheCube->Ya += 1.0; + TheCube->Za += 1.0; + plMemSet(TheFrameBuffer,0,W*H); // clear framebuffer for next frame + plRenderBegin(TheCamera); // Start rendering with the camera + plRenderLight(TheLight); // Render our light + plRenderObj(TheCube); // Render our object + plRenderEnd(); // Finish rendering + plMemCpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + switch (key) + { + case 27: // esc + return PL_EXIT_SUCCESS; + + case ' ': + CubeMat->PerspectiveCorrect ^= 8; // Toggle whether or not it's 8 + plMatInit(CubeMat); + break; + } + + return PL_EXIT_CONTINUE; +} + +void exQuit(void *appstate, int code) +{ + plTexDelete(CubeMat->Texture); + plMatDelete(CubeMat); + plObjDelete(TheCube); + plCamDelete(TheCamera); + plLightDelete(TheLight); +} + +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "ex4: Simple Plush example"); } From 01b83106a8efb81aa763953141d4eed965543b90 Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 22:10:02 -0500 Subject: [PATCH 10/17] examples: duckdemo: update --- examples/duckdemo.c | 231 +++++++++++++++++++++++--------------------- 1 file changed, 119 insertions(+), 112 deletions(-) diff --git a/examples/duckdemo.c b/examples/duckdemo.c index 92c002e..1488009 100644 --- a/examples/duckdemo.c +++ b/examples/duckdemo.c @@ -5,136 +5,143 @@ ** For more information on Plush, see http://nullsoft.home.ml.org/plush/ */ -#include -#include -#include - -#include - #include "ex.h" -pl_Mat *Material1, *Material2; // Materials for the duck -pl_Cam *Camera; // Camera -pl_Obj *Object; // The duck -pl_Light *Light; // Light source - -uint8_t framebuffer[W*H]; // Our framebuffer to render to - -void SetUpColors(); +static pl_Mat *Material1, *Material2; // Materials for the duck +static pl_Cam *Camera; // Camera +static pl_Obj *Object; // The duck +static pl_Light *Light; // Light source -int main(int argc, char **argv) { - float *zbuffer; // Our zbuffer +static uint8_t framebuffer[W*H]; // Our framebuffer to render to +static float *zbuffer; // Our zbuffer - printf("%s\n%s\n\n",plVersionString,plCopyrightString); // I like to do this +static void SetUpColors(void); - exSetGraphics(); // Set graphics +int exInit(void **appstate, int argc, char **argv) +{ + printf("%s\n%s\n\n",plVersionString,plCopyrightString); // I like to do this - Material1 = plMatCreate(); - Material2 = plMatCreate(); + Material1 = plMatCreate(); + Material2 = plMatCreate(); - SetUpColors(); // Init palette + SetUpColors(); // Init palette - Object = plRead3DSObj("duckdemo.3ds",Material1); - if (!Object) { - perror("Can't load duckdemo.3ds"); - return 1; - } + Object = plRead3DSObj("duckdemo.3ds",Material1); + if (!Object) + { + printf("Can't load duckdemo.3ds\n"); + return PL_EXIT_FAILURE; + } - // First child is an eye, child of child is eye - plMdlSetMat(Object->Children->Model,Material2); - plMdlSetMat(Object->Children->Children->Model,Material2); - // Child of eye is other eye, make it child of duck - plObjAddChild(Object, plObjRemoveParent(Object->Children->Children)); + // First child is an eye, child of child is eye + plMdlSetMat(Object->Children->Model,Material2); + plMdlSetMat(Object->Children->Children->Model,Material2); + // Child of eye is other eye, make it child of duck + plObjAddChild(Object, plObjRemoveParent(Object->Children->Children)); - plMdlScale(Object->Model,0.1); // Scale object down... + plMdlScale(Object->Model,0.1); // Scale object down... - Object->BackfaceCull = 0; // We want to be able to see through the duck - Object->BackfaceIllumination = 1; + Object->BackfaceCull = 0; // We want to be able to see through the duck + Object->BackfaceIllumination = 1; - Light = plLightCreate(); // Create a lightsource - plLightSet(Light,PL_LIGHT_VECTOR,0,0,0,1.0,1.0); // Vector light, 1.0 intensity + Light = plLightCreate(); // Create a lightsource + plLightSet(Light,PL_LIGHT_VECTOR,0,0,0,1.0,1.0); // Vector light, 1.0 intensity - if ((argc > 1 && !strcmp(argv[1],"-nozb")) || - (argc > 2 && !strcmp(argv[2],"-nozb"))) zbuffer = 0; - else - zbuffer = (float *) plMalloc(sizeof(float)*W*H); + if ((argc > 1 && !strcmp(argv[1],"-nozb")) || + (argc > 2 && !strcmp(argv[2],"-nozb"))) zbuffer = 0; + else + zbuffer = (float *) plMalloc(sizeof(float)*W*H); - Camera = plCamCreate(W,H, // Create camera - W*3.0/(H*4.0), // Aspect ratio (usually 1.0) - 80.0, framebuffer, zbuffer); - Camera->Z = -500; // move the camera back a bit - if (zbuffer) Camera->Sort = 0; // Sorting not necessary w/ zbuffer - else Camera->Sort = 1; + Camera = plCamCreate(W,H, // Create camera + W*3.0/(H*4.0), // Aspect ratio (usually 1.0) + 80.0, framebuffer, zbuffer); + Camera->Z = -500; // move the camera back a bit + if (zbuffer) Camera->Sort = 0; // Sorting not necessary w/ zbuffer + else Camera->Sort = 1; + return PL_EXIT_CONTINUE; +} - while (!exGetKey()) { - Object->Xa += 2.0; // Rotate object - Object->Ya += 2.0; - Object->Za += 2.0; +int exIterate(void *appstate) +{ + Object->Xa += 2.0; // Rotate object + Object->Ya += 2.0; + Object->Za += 2.0; + + plMemSet(framebuffer, 0, sizeof(framebuffer)); // clear framebuffer & zbuffer + if (Camera->zBuffer) + plMemSet(Camera->zBuffer,0,sizeof(float)*Camera->ScreenWidth*Camera->ScreenHeight); + + plRenderBegin(Camera); // Render to camera + plRenderLight(Light); // Render light + plRenderObj(Object); // Render duck + plRenderEnd(); // Finish rendering + plMemCpy(exGraphMem,framebuffer,sizeof(framebuffer)); // dump to screen + return PL_EXIT_CONTINUE; +} - memset(framebuffer, 0, sizeof(framebuffer)); // clear framebuffer & zbuffer - if (Camera->zBuffer) memset(Camera->zBuffer,0,sizeof(float)* - Camera->ScreenWidth*Camera->ScreenHeight); +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} - plRenderBegin(Camera); // Render to camera - plRenderLight(Light); // Render light - plRenderObj(Object); // Render duck - plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,framebuffer,sizeof(framebuffer)); // dump to screen - } - plObjDelete(Object); // Free duck - plLightDelete(Light); // Free light - plCamDelete(Camera); // Free camera +void exQuit(void *appstate, int code) +{ + plObjDelete(Object); // Free duck + plLightDelete(Light); // Free light + plCamDelete(Camera); // Free camera + plFree(zbuffer); +} - plFree(zbuffer); - exSetText(); // Restore text mode - //printf("Try \"duckdemo 640x480\" or \"duckdemo 320x200 -nozb\" etc\n"); - return 0; +static void SetUpColors(void) +{ + uint8_t pal[768]; // Our rgb triplet palette + pl_Mat *AllMaterials[2]; + memset(pal,0,768); + + //Material1->Priority = 0; // setup material 1 + Material1->NumGradients = 200; + Material1->Diffuse[0] = 203; + Material1->Diffuse[1] = 212; + Material1->Diffuse[2] = 0; + Material1->Specular[0] = 128; + Material1->Specular[1] = 56; + Material1->Specular[2] = 0; + Material1->Shininess = 15; + Material1->Ambient[0] = Material1->Ambient[1] = Material1->Ambient[2] = 0; + Material1->Transparent = 0; + Material1->Environment = NULL; + Material1->Texture = NULL; // Could do plReadTexturePCX() here for texture... + Material1->ShadeType = PL_SHADE_GOURAUD; + plMatInit(Material1); + + //Material2->Priority = 1; // setup material 2 + Material2->NumGradients = 100; + Material2->Diffuse[0] = 0; + Material2->Diffuse[1] = 0; + Material2->Diffuse[2] = 0; + Material2->Specular[0] = 160; + Material2->Specular[1] = 130; + Material2->Specular[2] = 0; + Material2->Shininess = 5; + Material2->Ambient[0] = Material2->Ambient[1] = Material2->Ambient[2] = 0; + Material2->Transparent = 0; + Material2->Environment = NULL; + Material2->Texture = NULL; + Material2->ShadeType = PL_SHADE_GOURAUD; + plMatInit(Material2); + + AllMaterials[0] = Material1; + AllMaterials[1] = Material2; + plMatMakeOptPal(pal,1,255,AllMaterials,2); // Create a nice palette + pal[0] = pal[1] = pal[2] = 0; // Color 0 is black + plMatMapToPal(Material1,pal,0,255); // Map the material to our palette + plMatMapToPal(Material2,pal,0,255); // Map the material to our palette + + exSetPalette(pal); // Set the palette } -void SetUpColors() { - uint8_t pal[768]; // Our rgb triplet palette - pl_Mat *AllMaterials[2]; - memset(pal,0,768); - - //Material1->Priority = 0; // setup material 1 - Material1->NumGradients = 200; - Material1->Diffuse[0] = 203; - Material1->Diffuse[1] = 212; - Material1->Diffuse[2] = 0; - Material1->Specular[0] = 128; - Material1->Specular[1] = 56; - Material1->Specular[2] = 0; - Material1->Shininess = 15; - Material1->Ambient[0] = Material1->Ambient[1] = Material1->Ambient[2] = 0; - Material1->Transparent = 0; - Material1->Environment = NULL; - Material1->Texture = NULL; // Could do plReadTexturePCX() here for texture... - Material1->ShadeType = PL_SHADE_GOURAUD; - plMatInit(Material1); - - //Material2->Priority = 1; // setup material 2 - Material2->NumGradients = 100; - Material2->Diffuse[0] = 0; - Material2->Diffuse[1] = 0; - Material2->Diffuse[2] = 0; - Material2->Specular[0] = 160; - Material2->Specular[1] = 130; - Material2->Specular[2] = 0; - Material2->Shininess = 5; - Material2->Ambient[0] = Material2->Ambient[1] = Material2->Ambient[2] = 0; - Material2->Transparent = 0; - Material2->Environment = NULL; - Material2->Texture = NULL; - Material2->ShadeType = PL_SHADE_GOURAUD; - plMatInit(Material2); - - AllMaterials[0] = Material1; - AllMaterials[1] = Material2; - plMatMakeOptPal(pal,1,255,AllMaterials,2); // Create a nice palette - pal[0] = pal[1] = pal[2] = 0; // Color 0 is black - plMatMapToPal(Material1,pal,0,255); // Map the material to our palette - plMatMapToPal(Material2,pal,0,255); // Map the material to our palette - - exSetPalette(pal); // Set the palette +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "DUCKDEMO: a Plush demo program."); } From 66cd0aaab964fb5525dce7ad84e46b65b4ef6029 Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 22:24:17 -0500 Subject: [PATCH 11/17] examples: teapot: update --- examples/teapot.c | 89 ++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/examples/teapot.c b/examples/teapot.c index 6ecad33..37ffce9 100644 --- a/examples/teapot.c +++ b/examples/teapot.c @@ -1,28 +1,18 @@ // teapot.c: OBJ model loading example // owo -#include -#include -#include -#include - -#include - #include "ex.h" -pl_Light *light; -pl_Obj *teapot; -pl_Mat *material; -pl_Cam *camera; -uint8_t framebuffer[W * H]; -float zbuffer[W * H]; -uint8_t palette[768]; +static pl_Light *light; +static pl_Obj *teapot; +static pl_Mat *material; +static pl_Cam *camera; +static uint8_t framebuffer[W * H]; +static float zbuffer[W * H]; +static uint8_t palette[768]; -int main(int argc, char **argv) +int exInit(void **appstate, int argc, char **argv) { - /* setup graphics mode */ - exSetGraphics(); - /* create material */ /* these ambient/diffuse/specular values are taken from Haiku's GLTeapot */ material = plMatCreate(); @@ -59,37 +49,48 @@ int main(int argc, char **argv) /* create light */ light = plLightSet(plLightCreate(), PL_LIGHT_VECTOR, 0.0, 0.0, 0.0, 1.0, 1.0); - /* main loop */ - while (!exGetKey()) - { - /* rotate model */ - teapot->Xa += 1.0; - teapot->Ya += 1.0; - teapot->Za += 1.0; - - /* clear back buffer */ - memset(zbuffer, 0, sizeof(zbuffer)); - memset(framebuffer, 0, sizeof(framebuffer)); - - /* render frame */ - plRenderBegin(camera); - plRenderLight(light); - plRenderObj(teapot); - plRenderEnd(); - - /* wait for vsync, then copy to screen */ - exWaitVSync(); - memcpy(exGraphMem, framebuffer, sizeof(framebuffer)); - } + return PL_EXIT_CONTINUE; +} + +int exIterate(void *appstate) +{ + /* rotate model */ + teapot->Xa += 1.0; + teapot->Ya += 1.0; + teapot->Za += 1.0; + + /* clear back buffer */ + plMemSet(zbuffer, 0, sizeof(zbuffer)); + plMemSet(framebuffer, 0, sizeof(framebuffer)); + + /* render frame */ + plRenderBegin(camera); + plRenderLight(light); + plRenderObj(teapot); + plRenderEnd(); + + /* copy to screen */ + plMemCpy(exGraphMem, framebuffer, sizeof(framebuffer)); + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +void exQuit(void *appstate, int code) +{ /* clean up */ plCamDelete(camera); plLightDelete(light); plObjDelete(teapot); plMatDelete(material); +} - /* shut down video */ - exSetText(); - - return 0; +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "teapot: OBJ model loading example"); } From cb633727fb1b03ccc4a53990633d12d6bdc522bb Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 22:32:31 -0500 Subject: [PATCH 12/17] examples: flurry: update --- examples/flurry.c | 282 ++++++++++++++++++++++++---------------------- 1 file changed, 148 insertions(+), 134 deletions(-) diff --git a/examples/flurry.c b/examples/flurry.c index 8fd975b..49cebeb 100644 --- a/examples/flurry.c +++ b/examples/flurry.c @@ -13,146 +13,160 @@ #include "ex.h" -uint8_t *framebuffer; - #define NUM_ITERS 4 #define BOX_DIST 2.75 #define BOX_ROTFACTOR 2.6 -void makeBoxes(pl_Obj *obj, float s, - pl_Mat **m, int i); // Makes hierarchy of cubes -void rotateBoxes(pl_Obj *obj, float r); // Rotates hierarchy - -int main(int argc, char **argv) { - int i, done = 0; - - pl_Mat *mat[NUM_ITERS]; // Materials - pl_Obj *obj; // Head object - pl_Light *light; - pl_Cam *cam; - - float ar; - int c; - uint8_t pal[768]; - - printf("Flurry v1.0 -- Mode13 specific version\n" - "Copyright (c) 1996, Justin Frankel\n"); - printf("Using:\n" - " %s\n",plVersionString); - - exSetGraphics(); // Set graphics - - framebuffer = (uint8_t *) plMalloc(W*H); - ar = (W/(float) H) * (3.0/4.0); // Calc aspect ratio - - cam = plCamCreate(W,H,ar,90.0,framebuffer,NULL); - cam->Sort = 1; - cam->Z = -350; - - // Initialize materials - memset(&mat,0,sizeof(mat)); - for (i = 0; i < NUM_ITERS; i ++) { - mat[i] = plMatCreate(); - mat[i]->NumGradients = 200; - mat[i]->Transparent = 2; - mat[i]->Ambient[0] = mat[i]->Ambient[1] = mat[i]->Ambient[2] = 20; - mat[i]->Shininess = 3; - mat[i]->ShadeType = PL_SHADE_GOURAUD; - //mat[i]->Priority = i; - } - mat[0]->Diffuse[0] = 190; mat[0]->Diffuse[1] = 190; mat[0]->Diffuse[2] = 0; - mat[0]->Specular[0] = 240; mat[0]->Specular[1] = 240; mat[0]->Specular[2] = 0; - mat[1]->Diffuse[0] = 0; mat[1]->Diffuse[1] = 0; mat[1]->Diffuse[2] = 100; - mat[1]->Specular[0] = 0; mat[1]->Specular[1] = 0; mat[1]->Specular[2] = 100; - mat[2]->Diffuse[0] = 0; mat[2]->Diffuse[1] = 130; mat[2]->Diffuse[2] = 0; - mat[2]->Specular[0] = 0; mat[2]->Specular[1] = 130; mat[2]->Specular[2] = 0; - mat[3]->Diffuse[0] = 100; mat[3]->Diffuse[1] = 0; mat[3]->Diffuse[2] = 0; - mat[3]->Specular[0] = 100; mat[3]->Specular[1] = 0; mat[3]->Specular[2] = 0; - - for (i = 0; i < NUM_ITERS; i ++) - plMatInit(mat[i]); - - memset(pal,0,768); - plMatMakeOptPal(pal,1,255,mat,NUM_ITERS); // Create a nice palette - pal[0] = pal[1] = pal[2] = 0; // Color 0 is black - for (i = 0; i < NUM_ITERS; i ++) - plMatMapToPal(mat[i],pal,0,255); // Map the material to our palette - exSetPalette(pal); // Set the new palette via mode 13 function - - // Make objects - obj = plObjCreate(NULL); - obj->Model = plMakeBox(100,100,100,mat[0]); - makeBoxes(obj,100.0,mat+1,NUM_ITERS-1); - - // Setup light - light = plLightCreate(); - plLightSet(light,PL_LIGHT_VECTOR,0,0,0,1.0,1.0); - - while (!done) { - rotateBoxes(obj,1.0); - memset(framebuffer,0,W*H); - plRenderBegin(cam); - plRenderLight(light); - plRenderObj(obj); - plRenderEnd(); - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,framebuffer,W*H); // dump to screen - while ((c = exGetKey())) switch(c) { - case 27: done = 1; break; - case '-': cam->Fov += 1.0; if (cam->Fov > 170) cam->Fov = 170; break; - case '=': cam->Fov -= 1.0; if (cam->Fov < 10) cam->Fov = 10; break; - } - } - for (i = 0; i < NUM_ITERS; i++) - plMatDelete(mat[i]); - plFree(framebuffer); - plObjDelete(obj); - plLightDelete(light); - plCamDelete(cam); - exSetText(); // Restore text mode - return 0; +static pl_Mat *mat[NUM_ITERS]; // Materials +static pl_Obj *obj; // Head object +static pl_Light *light; +static pl_Cam *cam; +static uint8_t *framebuffer; +static uint8_t pal[768]; + +static void makeBoxes(pl_Obj *obj, float s, pl_Mat **m, int i); // Makes hierarchy of cubes +static void rotateBoxes(pl_Obj *obj, float r); // Rotates hierarchy + +int exInit(void **appstate, int argc, char **argv) +{ + int i; + float ar; + + printf("Flurry v1.0 -- Mode13 specific version\n" + "Copyright (c) 1996, Justin Frankel\n"); + printf("Using:\n" + " %s\n",plVersionString); + + framebuffer = (uint8_t *)plMalloc(W*H); + ar = (W/(float) H) * (3.0/4.0); // Calc aspect ratio + + cam = plCamCreate(W,H,ar,90.0,framebuffer,NULL); + cam->Sort = 1; + cam->Z = -350; + + // Initialize materials + plMemSet(&mat,0,sizeof(mat)); + for (i = 0; i < NUM_ITERS; i ++) + { + mat[i] = plMatCreate(); + mat[i]->NumGradients = 200; + mat[i]->Transparent = 2; + mat[i]->Ambient[0] = mat[i]->Ambient[1] = mat[i]->Ambient[2] = 20; + mat[i]->Shininess = 3; + mat[i]->ShadeType = PL_SHADE_GOURAUD; + } + mat[0]->Diffuse[0] = 190; mat[0]->Diffuse[1] = 190; mat[0]->Diffuse[2] = 0; + mat[0]->Specular[0] = 240; mat[0]->Specular[1] = 240; mat[0]->Specular[2] = 0; + mat[1]->Diffuse[0] = 0; mat[1]->Diffuse[1] = 0; mat[1]->Diffuse[2] = 100; + mat[1]->Specular[0] = 0; mat[1]->Specular[1] = 0; mat[1]->Specular[2] = 100; + mat[2]->Diffuse[0] = 0; mat[2]->Diffuse[1] = 130; mat[2]->Diffuse[2] = 0; + mat[2]->Specular[0] = 0; mat[2]->Specular[1] = 130; mat[2]->Specular[2] = 0; + mat[3]->Diffuse[0] = 100; mat[3]->Diffuse[1] = 0; mat[3]->Diffuse[2] = 0; + mat[3]->Specular[0] = 100; mat[3]->Specular[1] = 0; mat[3]->Specular[2] = 0; + + for (i = 0; i < NUM_ITERS; i ++) + plMatInit(mat[i]); + + plMemSet(pal,0,768); + plMatMakeOptPal(pal,1,255,mat,NUM_ITERS); // Create a nice palette + pal[0] = pal[1] = pal[2] = 0; // Color 0 is black + for (i = 0; i < NUM_ITERS; i ++) + plMatMapToPal(mat[i],pal,0,255); // Map the material to our palette + exSetPalette(pal); // Set the new palette via mode 13 function + + // Make objects + obj = plObjCreate(NULL); + obj->Model = plMakeBox(100,100,100,mat[0]); + makeBoxes(obj,100.0,mat+1,NUM_ITERS-1); + + // Setup light + light = plLightCreate(); + plLightSet(light,PL_LIGHT_VECTOR,0,0,0,1.0,1.0); + + return PL_EXIT_CONTINUE; +} + +int exIterate(void *appstate) +{ + rotateBoxes(obj,1.0); + plMemSet(framebuffer,0,W*H); + plRenderBegin(cam); + plRenderLight(light); + plRenderObj(obj); + plRenderEnd(); + plMemCpy(exGraphMem,framebuffer,W*H); // dump to screen + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + switch (key) + { + case 27: return PL_EXIT_SUCCESS; + case '-': cam->Fov += 1.0; if (cam->Fov > 170) cam->Fov = 170; break; + case '=': cam->Fov -= 1.0; if (cam->Fov < 10) cam->Fov = 10; break; + } + + return PL_EXIT_CONTINUE; +} +void exQuit(void *appstate, int code) +{ + int i; + for (i = 0; i < NUM_ITERS; i++) + plMatDelete(mat[i]); + plFree(framebuffer); + plObjDelete(obj); + plLightDelete(light); + plCamDelete(cam); +} + +static void makeBoxes(pl_Obj *obj, float s, pl_Mat **m, int i) +{ + pl_Obj *child; + if (!i) return; + child = plObjCreate(obj); + child->Model = plMakeBox(s/2,s/2,s/2,*m); + child->Xp = s*BOX_DIST;; + child = plObjCreate(obj); + child->Model = plMakeBox(s/2,s/2,s/2,*m); + child->Xp = -s*BOX_DIST; + child = plObjCreate(obj); + child->Model = plMakeBox(s/2,s/2,s/2,*m); + child->Yp = s*BOX_DIST; + child = plObjCreate(obj); + child->Model = plMakeBox(s/2,s/2,s/2,*m); + child->Yp = -s*BOX_DIST; + child = plObjCreate(obj); + child->Model = plMakeBox(s/2,s/2,s/2,*m); + child->Zp = s*BOX_DIST; + child = plObjCreate(obj); + child->Model = plMakeBox(s/2,s/2,s/2,*m); + child->Zp = -s*BOX_DIST; + + child = obj->Children; + while (child) + { + makeBoxes(child,s/2,m+1,i-1); + child = child->NextSibling; + } } -void makeBoxes(pl_Obj *obj, float s, pl_Mat **m, int i) { - pl_Obj *child; - if (!i) return; - child = plObjCreate(obj); - child->Model = plMakeBox(s/2,s/2,s/2,*m); - child->Xp = s*BOX_DIST;; - child = plObjCreate(obj); - child->Model = plMakeBox(s/2,s/2,s/2,*m); - child->Xp = -s*BOX_DIST; - child = plObjCreate(obj); - child->Model = plMakeBox(s/2,s/2,s/2,*m); - child->Yp = s*BOX_DIST; - child = plObjCreate(obj); - child->Model = plMakeBox(s/2,s/2,s/2,*m); - child->Yp = -s*BOX_DIST; - child = plObjCreate(obj); - child->Model = plMakeBox(s/2,s/2,s/2,*m); - child->Zp = s*BOX_DIST; - child = plObjCreate(obj); - child->Model = plMakeBox(s/2,s/2,s/2,*m); - child->Zp = -s*BOX_DIST; - - child = obj->Children; - while (child) - { - makeBoxes(child,s/2,m+1,i-1); - child = child->NextSibling; - } +static void rotateBoxes(pl_Obj *obj, float r) +{ + pl_Obj *child; + if (!obj) return; + obj->Ya += r; + obj->Xa += r; + + child = obj->Children; + while (child) + { + rotateBoxes(child,r*BOX_ROTFACTOR); + child = child->NextSibling; + } } -void rotateBoxes(pl_Obj *obj, float r) { - pl_Obj *child; - if (!obj) return; - obj->Ya += r; - obj->Xa += r; - - child = obj->Children; - while (child) - { - rotateBoxes(child,r*BOX_ROTFACTOR); - child = child->NextSibling; - } +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "Flurry: a Plush demo program."); } From 3006e3acb210cf99cef1c954286ac79179de7b5b Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 23:18:58 -0500 Subject: [PATCH 13/17] examples: logo: update --- examples/logo.c | 75 +++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/examples/logo.c b/examples/logo.c index 03af953..22db8c5 100644 --- a/examples/logo.c +++ b/examples/logo.c @@ -1,28 +1,18 @@ // logo.c: plush logo // owo -#include -#include -#include -#include - -#include - #include "ex.h" -pl_Light *light; -pl_Obj *logo; -pl_Mat *material; -pl_Cam *camera; -uint8_t framebuffer[W * H]; -float zbuffer[W * H]; -uint8_t palette[768]; +static pl_Light *light; +static pl_Obj *logo; +static pl_Mat *material; +static pl_Cam *camera; +static uint8_t framebuffer[W * H]; +static float zbuffer[W * H]; +static uint8_t palette[768]; -int main(int argc, char **argv) +int exInit(void **appstate, int argc, char **argv) { - /* setup graphics mode */ - exSetGraphics(); - /* create material */ material = plMatCreate(); material->NumGradients = 2500; @@ -51,32 +41,43 @@ int main(int argc, char **argv) /* create light */ light = plLightSet(plLightCreate(), PL_LIGHT_VECTOR, 0.0, 0.0, 0.0, 1.0, 1.0); - /* main loop */ - while (!exGetKey()) - { - /* clear back buffer */ - memset(zbuffer, 0, sizeof(zbuffer)); - memset(framebuffer, 0, sizeof(framebuffer)); + return PL_EXIT_CONTINUE; +} - /* render frame */ - plRenderBegin(camera); - plRenderLight(light); - plRenderObj(logo); - plRenderEnd(); +int exIterate(void *appstate) +{ + /* clear back buffer */ + plMemSet(zbuffer, 0, sizeof(zbuffer)); + plMemSet(framebuffer, 0, sizeof(framebuffer)); + + /* render frame */ + plRenderBegin(camera); + plRenderLight(light); + plRenderObj(logo); + plRenderEnd(); - /* wait for vsync, then copy to screen */ - exWaitVSync(); - memcpy(exGraphMem, framebuffer, sizeof(framebuffer)); - } + /* copy to screen */ + plMemCpy(exGraphMem, framebuffer, sizeof(framebuffer)); + + return PL_EXIT_CONTINUE; +} +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +void exQuit(void *appstate, int code) +{ /* clean up */ plCamDelete(camera); plLightDelete(light); plObjDelete(logo); plMatDelete(material); +} - /* shut down video */ - exSetText(); - - return 0; +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "Plush Logo"); } From 9a9842714a34ba9019ae98278545d748f5028c00 Mon Sep 17 00:00:00 2001 From: erysdren Date: Sat, 4 Oct 2025 23:22:03 -0500 Subject: [PATCH 14/17] examples: triangle: update --- examples/triangle.c | 67 +++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/examples/triangle.c b/examples/triangle.c index 2d7d14d..fae7aeb 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -4,26 +4,16 @@ // note: not actually rainbow colored until i implement vertex colour support // -- erysdren -#include -#include -#include -#include - -#include - #include "ex.h" -pl_Obj *triangle; -pl_Mat *material; -pl_Cam *camera; -uint8_t framebuffer[W * H]; -uint8_t palette[768]; +static pl_Obj *triangle; +static pl_Mat *material; +static pl_Cam *camera; +static uint8_t framebuffer[W * H]; +static uint8_t palette[768]; -int main(int argc, char **argv) +int exInit(void **appstate, int argc, char **argv) { - /* setup graphics mode */ - exSetGraphics(); - /* create triangle model */ triangle = plObjCreate(NULL); triangle->Model = plMdlCreate(3, 1); @@ -75,29 +65,40 @@ int main(int argc, char **argv) camera->Y = 96; camera->Z = -300; - /* main loop */ - while (!exGetKey()) - { - /* clear framebuffer */ - memset(framebuffer, 0, sizeof(framebuffer)); + return PL_EXIT_CONTINUE; +} - /* render frame */ - plRenderBegin(camera); - plRenderObj(triangle); - plRenderEnd(); +int exIterate(void *appstate) +{ + /* clear framebuffer */ + plMemSet(framebuffer, 0, sizeof(framebuffer)); + + /* render frame */ + plRenderBegin(camera); + plRenderObj(triangle); + plRenderEnd(); - /* wait for vsync, then copy to screen */ - exWaitVSync(); - memcpy(exGraphMem, framebuffer, sizeof(framebuffer)); - } + /* copy to screen */ + plMemCpy(exGraphMem, framebuffer, sizeof(framebuffer)); + + return PL_EXIT_CONTINUE; +} +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +void exQuit(void *appstate, int code) +{ /* clean up */ plCamDelete(camera); plObjDelete(triangle); plMatDelete(material); +} - /* shut down video */ - exSetText(); - - return 0; +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "triangle: obligatory rainbow colored triangle"); } From cd06c0be7b7fbffa8984f3d212d1c54bc6b0cec7 Mon Sep 17 00:00:00 2001 From: erysdren Date: Sun, 5 Oct 2025 11:20:03 -0500 Subject: [PATCH 15/17] examples: texture: update --- examples/texture.c | 94 +++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 52 deletions(-) diff --git a/examples/texture.c b/examples/texture.c index 4a0807f..768832c 100644 --- a/examples/texture.c +++ b/examples/texture.c @@ -1,54 +1,19 @@ // texture.c: custom texture example // owo -#include -#include -#include -#include - -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - #include "ex.h" #include "texture1.h" -pl_Light *light; -pl_Obj *model; -pl_Mat *material; -pl_Cam *camera; -uint8_t framebuffer[W * H]; -uint8_t palette[768]; +static pl_Light *light; +static pl_Obj *model; +static pl_Mat *material; +static pl_Cam *camera; +static uint8_t framebuffer[W * H]; +static uint8_t palette[768]; -static void main_loop(void) +int exInit(void **appstate, int argc, char **argv) { - /* rotate model */ - model->Xa += 1.0; - model->Ya += 1.0; - model->Za += 1.0; - - /* clear back buffer */ - memset(framebuffer, 0, W * H); - - /* render frame */ - plRenderBegin(camera); - plRenderLight(light); - plRenderObj(model); - plRenderEnd(); - - /* wait for vsync, then copy to screen */ - exWaitVSync(); - memcpy(exGraphMem, framebuffer, W * H); -} - -int main(int argc, char **argv) -{ - /* setup graphics mode */ - exSetGraphics(); - /* create material */ material = plMatCreate(); material->NumGradients = 256; @@ -75,22 +40,47 @@ int main(int argc, char **argv) /* create light */ light = plLightSet(plLightCreate(), PL_LIGHT_VECTOR, 0.0, 0.0, 0.0, 1.0, 1.0); - /* main loop */ -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(main_loop, 0, true); -#else - while (!exGetKey()) - main_loop(); -#endif + return PL_EXIT_CONTINUE; +} +void exQuit(void *appstate, int code) +{ /* clean up */ plCamDelete(camera); plLightDelete(light); plObjDelete(model); plMatDelete(material); +} + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +int exIterate(void *appstate) +{ + /* rotate model */ + model->Xa += 1.0; + model->Ya += 1.0; + model->Za += 1.0; + + /* clear back buffer */ + plMemSet(framebuffer, 0, W * H); - /* shut down video */ - exSetText(); + /* render frame */ + plRenderBegin(camera); + plRenderLight(light); + plRenderObj(model); + plRenderEnd(); - return 0; + /* copy to screen */ + plMemCpy(exGraphMem, framebuffer, W * H); + + return PL_EXIT_CONTINUE; +} + +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "texture: custom texture example"); } From e5d5e63a2eb69ba08ce233295375a035d65c924f Mon Sep 17 00:00:00 2001 From: erysdren Date: Sun, 5 Oct 2025 11:25:18 -0500 Subject: [PATCH 16/17] examples: texenv: update --- examples/texenv.c | 195 +++++++++++++++++++++------------------------- 1 file changed, 90 insertions(+), 105 deletions(-) diff --git a/examples/texenv.c b/examples/texenv.c index 52948f3..c3c47cb 100644 --- a/examples/texenv.c +++ b/examples/texenv.c @@ -1,113 +1,98 @@ // texenv.c: environment mapping example // owo -#include -#include -#include -#include - -// Include the plush header file -#include - // Include our example graphics interface module #include "ex.h" // Our variables -pl_Light *TheLight; // Our light -pl_Obj *TheCube; // Our cube object -pl_Mat *CubeMat; // The material for the cube -pl_Mat *AllMaterials[2]; // Used for creating palette -pl_Cam *TheCamera; // Our camera -uint8_t TheFrameBuffer[W*H]; // Our framebuffer to render to -uint8_t ThePalette[768]; - -int main(int argc, char **argv) { // Main - int done; - // Show user controls - printf("Controls:\n" - " ESC: quit\n" - " Hit any key to begin\n"); -#if 0 - while (!exGetKey()); // Wait for key - while (exGetKey()); // Make sure no other keys are in the queue -#endif - -#if defined(DJGPP) || defined(__WATCOMC__) - // Put the fpu in a low precision, no exception state - _control87(MCW_EM|PC_24,MCW_EM|MCW_PC); -#endif - exSetGraphics(); // Set graphics - - CubeMat = plMatCreate(); // Create the material for the cube - CubeMat->NumGradients = 256; // Have it use 256 colors - CubeMat->ShadeType = PL_SHADE_GOURAUD; // Make the cube flat shaded - CubeMat->Texture = plReadPCXTex("texture1.pcx", - 1, // Rescale the texture if necessary - 1 // Tell it to optimize the texture's palette - ); - CubeMat->Environment = plReadPCXTex("chrome_steel1.pcx", - 1, // Rescale the texture if necessary - 1 // Tell it to optimize the texture's palette - ); - CubeMat->TexEnvMode = PL_TEXENV_ADD; - CubeMat->EnvScaling = 1; - // These are 128 by default, but make it to bright for this app - CubeMat->Diffuse[0] = CubeMat->Diffuse[1] = CubeMat->Diffuse[2] = 0; - plMatInit(CubeMat); // Initialize the material - - AllMaterials[0] = CubeMat; // Make list of materials - AllMaterials[1] = 0; // Null terminate list of materials - plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette - - ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black - - plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette - - // Convert std 8 bit/chan palette to vga's 6 bit/chan palette - // for (i = 0; i < 768; i ++) ThePalette[i] >>= 2; - exSetPalette(ThePalette); // Set the palette - - TheCube = plObjCreate(NULL); - TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube - - TheCamera = plCamCreate(W, // Screen width - H, // Screen height - W*3.0/(H*4.0), // Aspect ratio - 60.0, // Field of view - TheFrameBuffer, // Framebuffer - NULL // ZBuffer (none) - ); // Create the camera - TheCamera->Z = -300; // Back the camera up from the origin - - TheLight = plLightSet(plLightCreate(), // Create a light to be set up - PL_LIGHT_VECTOR, // vector light - 0.0,0.0,0.0, // rotation angles - 1.0, // intensity - 1.0); // falloff, not used for vector lights - - done = 0; - while (!done) { // While the keyboard hasn't been touched - TheCube->Xa += 1.0; // Rotate by 1 degree on each axis - TheCube->Ya += 1.0; - TheCube->Za += 1.0; - memset(TheFrameBuffer,0,W*H); // clear framebuffer for next frame - plRenderBegin(TheCamera); // Start rendering with the camera - plRenderLight(TheLight); // Render our light - plRenderObj(TheCube); // Render our object - plRenderEnd(); // Finish rendering - exWaitVSync(); // Sync with retrace - memcpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen - switch (exGetKey()) { - case 0: break; // no key - case 27: done = 1; break; // esc - } - } - plTexDelete(CubeMat->Texture); - plTexDelete(CubeMat->Environment); - plMatDelete(CubeMat); - plObjDelete(TheCube); - plCamDelete(TheCamera); - plLightDelete(TheLight); - exSetText(); // Restore text mode - return 0; // Quit +static pl_Light *TheLight; // Our light +static pl_Obj *TheCube; // Our cube object +static pl_Mat *CubeMat; // The material for the cube +static pl_Mat *AllMaterials[2]; // Used for creating palette +static pl_Cam *TheCamera; // Our camera +static uint8_t TheFrameBuffer[W*H]; // Our framebuffer to render to +static uint8_t ThePalette[768]; + +int exInit(void **appstate, int argc, char **argv) +{ + CubeMat = plMatCreate(); // Create the material for the cube + CubeMat->NumGradients = 256; // Have it use 256 colors + CubeMat->ShadeType = PL_SHADE_GOURAUD; // Make the cube flat shaded + CubeMat->Texture = plReadPCXTex("texture1.pcx", + true, // Rescale the texture if necessary + true); // Tell it to optimize the texture's palette + CubeMat->Environment = plReadPCXTex("chrome_steel1.pcx", + true, // Rescale the texture if necessary + true); // Tell it to optimize the texture's palette + CubeMat->TexEnvMode = PL_TEXENV_ADD; + CubeMat->EnvScaling = 1; + // These are 128 by default, but make it to bright for this app + CubeMat->Diffuse[0] = CubeMat->Diffuse[1] = CubeMat->Diffuse[2] = 0; + plMatInit(CubeMat); // Initialize the material + + AllMaterials[0] = CubeMat; // Make list of materials + AllMaterials[1] = 0; // Null terminate list of materials + plMatMakeOptPal(ThePalette,1,255,AllMaterials,1); // Create a nice palette + + ThePalette[0] = ThePalette[1] = ThePalette[2] = 0; // Color 0 is black + + plMatMapToPal(CubeMat,ThePalette,0,255); // Map the material to our palette + + exSetPalette(ThePalette); // Set the palette + + TheCube = plObjCreate(NULL); + TheCube->Model = plMakeBox(100.0,100.0,100.0,CubeMat); // Create the cube + + // Create the camera + TheCamera = plCamCreate(W, // Screen width + H, // Screen height + W*3.0/(H*4.0), // Aspect ratio + 60.0, // Field of view + TheFrameBuffer, // Framebuffer + NULL); // ZBuffer (none) + TheCamera->Z = -300; // Back the camera up from the origin + + TheLight = plLightSet(plLightCreate(), // Create a light to be set up + PL_LIGHT_VECTOR, // vector light + 0.0,0.0,0.0, // rotation angles + 1.0, // intensity + 1.0); // falloff, not used for vector lights + + return PL_EXIT_CONTINUE; +} + +int exIterate(void *appstate) +{ + TheCube->Xa += 1.0; // Rotate by 1 degree on each axis + TheCube->Ya += 1.0; + TheCube->Za += 1.0; + plMemSet(TheFrameBuffer,0,W*H); // clear framebuffer for next frame + plRenderBegin(TheCamera); // Start rendering with the camera + plRenderLight(TheLight); // Render our light + plRenderObj(TheCube); // Render our object + plRenderEnd(); // Finish rendering + plMemCpy(exGraphMem,TheFrameBuffer,W*H); // dump to screen + return PL_EXIT_CONTINUE; +} + + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +void exQuit(void *appstate, int code) +{ + plTexDelete(CubeMat->Texture); + plTexDelete(CubeMat->Environment); + plMatDelete(CubeMat); + plObjDelete(TheCube); + plCamDelete(TheCamera); + plLightDelete(TheLight); +} + +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "texenv: environment mapping example"); } From 5711decf9b94f17baf256ab6b297df3acdfe182f Mon Sep 17 00:00:00 2001 From: erysdren Date: Sun, 5 Oct 2025 21:14:39 -0500 Subject: [PATCH 17/17] examples: sprite: update --- examples/sprite.c | 123 ++++++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 60 deletions(-) diff --git a/examples/sprite.c b/examples/sprite.c index 77cdee8..3cda970 100644 --- a/examples/sprite.c +++ b/examples/sprite.c @@ -1,35 +1,25 @@ // sprite.c: a more complex scene with a rotating camera and a sprite plane // owo -#include -#include -#include -#include - -#include - #include "ex.h" #define NUM_MATERIALS 2 -pl_Light *light1, *light2; -pl_Obj *world; -pl_Obj *sprite; -pl_Mat *materials[NUM_MATERIALS]; -pl_Cam *camera; -uint8_t framebuffer[W * H]; -float zbuffer[W * H]; -uint8_t palette[768]; -float camera_angle = 0; -float light1_angle = 0; - -int main(int argc, char **argv) +static pl_Light *light1, *light2; +static pl_Obj *world; +static pl_Obj *sprite; +static pl_Mat *materials[NUM_MATERIALS]; +static pl_Cam *camera; +static uint8_t framebuffer[W * H]; +static float zbuffer[W * H]; +static uint8_t palette[768]; +static float camera_angle = 0; +static float light1_angle = 0; + +int exInit(void **appstate, int argc, char **argv) { int i; - /* setup graphics mode */ - exSetGraphics(); - /* create materials */ materials[0] = plMatCreate(); materials[0]->ShadeType = PL_SHADE_GOURAUD; @@ -82,40 +72,53 @@ int main(int argc, char **argv) light1 = plLightSet(plLightCreate(), PL_LIGHT_VECTOR, -90.0, 30.0, -45.0, 1.0, 1.0); light2 = plLightSet(plLightCreate(), PL_LIGHT_POINT, 0.0, 24.0, 0.0, 1.0, 256.0); - /* main loop */ - while (!exGetKey()) - { - /* clear back buffer */ - memset(zbuffer, 0, sizeof(zbuffer)); - memset(framebuffer, 0, sizeof(framebuffer)); - - /* rotate camera */ - camera_angle += 0.01; - camera->X = 160 * cos(camera_angle); - camera->Z = 160 * sin(camera_angle); - camera->Pan = 90 + atan2(camera->Z, camera->X) * 180 / PL_PI; - - /* rotate sprite to face camera */ - sprite->Xa = 90; - sprite->Ya = camera->Pan; - - /* rotate vector light */ - light1_angle -= 0.01; - light1->Xp = cos(light1_angle); - light1->Zp = sin(light1_angle); - - /* render frame */ - plRenderBegin(camera); - plRenderLight(light1); - plRenderLight(light2); - plRenderObj(world); - plRenderObj(sprite); - plRenderEnd(); - - /* wait for vsync, then copy to screen */ - exWaitVSync(); - memcpy(exGraphMem, framebuffer, sizeof(framebuffer)); - } + return PL_EXIT_CONTINUE; +} + +int exKeyEvent(void *appstate, int key) +{ + // any keypress will trigger an exit + return PL_EXIT_SUCCESS; +} + +int exIterate(void *appstate) +{ + /* clear back buffer */ + plMemSet(zbuffer, 0, sizeof(zbuffer)); + plMemSet(framebuffer, 0, sizeof(framebuffer)); + + /* rotate camera */ + camera_angle += 0.01; + camera->X = 160 * cos(camera_angle); + camera->Z = 160 * sin(camera_angle); + camera->Pan = 90 + atan2(camera->Z, camera->X) * 180 / PL_PI; + + /* rotate sprite to face camera */ + sprite->Xa = 90; + sprite->Ya = camera->Pan; + + /* rotate vector light */ + light1_angle -= 0.01; + light1->Xp = cos(light1_angle); + light1->Zp = sin(light1_angle); + + /* render frame */ + plRenderBegin(camera); + plRenderLight(light1); + plRenderLight(light2); + plRenderObj(world); + plRenderObj(sprite); + plRenderEnd(); + + /* copy to screen */ + plMemCpy(exGraphMem, framebuffer, sizeof(framebuffer)); + + return PL_EXIT_CONTINUE; +} + +void exQuit(void *appstate, int code) +{ + int i; /* clean up */ plCamDelete(camera); @@ -124,9 +127,9 @@ int main(int argc, char **argv) plObjDelete(world); for (i = 0; i < NUM_MATERIALS; i++) plMatDelete(materials[i]); +} - /* shut down video */ - exSetText(); - - return 0; +int main(int argc, char **argv) +{ + return exBegin(argc, argv, "sprite"); }