Going full circle to actual **Sony PlayStation 1 (PSX)** hardware is the ultimate move for a game with this retro low-poly aesthetic. Below is valid, complete **C source code targeted for the official PS1 Psy-Q / Nugget SDK**. It sets up the PS1 GPU, configures double-buffering and ordering tables, handles PS1 controller input, renders the park ground, HUD, and 3D textured/colored quad primitives for the characters. --- ## 🎮 PS1 C Source Code (`main.c`) ```c #include #include #include #include #include #include #define OT_LEN 1024 // Ordering Table length for Z-buffering/depth #define PACKET_LEN 2048 // Primitive packet buffer size #define SCREEN_X 320 // Classic PS1 NTSC resolution width #define SCREEN_Y 240 // Height // Double buffering structure typedef struct { DRAWENV draw; DISPENV disp; } DB; DB db[2]; // Double buffer state int side; // Current buffer index (0 or 1) u_long ot[2][OT_LEN]; // Ordering Table array char packetArea[2][PACKET_LEN]; // Primitive packet buffer memory char *nextpacket; // Pointer to next available packet space // Controller buffers static u_char padbuf[2][34]; // Game State Structures typedef struct { VECTOR pos; // PS1 Fixed-point position vector (X, Y, Z) SVECTOR rot; // Rotation vector int health; } Entity; Entity player = { { 0, 0, 1000 }, { 0, 0, 0 }, 85 }; Entity enemy = { { -400, 0, 1200 }, { 0, 0, 0 }, 100 }; Entity rex = { { 400, -100, 1400 }, { 0, 0, 0 }, 100 }; // Function Prototypes void InitPSX(void); void DisplayFrame(void); void UpdateGame(u_long pad); void DrawFlatQuad(int x, int y, int z, int w, int h, CVECTOR color); void DrawHUD(void); // ----------------------------------------------------------------------------- // MAIN ENTRY POINT // ----------------------------------------------------------------------------- int main(void) { u_long pad; InitPSX(); while (1) { // Read Controller 1 pad = PadRead(0); // Update Game Logic UpdateGame(pad); // Clear the Ordering Table for the current frame buffer ClearOTagR(ot[side], OT_LEN); nextpacket = packetArea[side]; // --- RENDER SCENE --- // 1. Draw Park Ground (Green Polygon) CVECTOR grassColor = { 60, 140, 40, 0 }; DrawFlatQuad(0, 300, 1200, 1600, 800, grassColor); // 2. Draw "Rex" (Big Nose Guy) CVECTOR rexColor = { 220, 160, 100, 0 }; DrawFlatQuad(rex.pos.vx, rex.pos.vy, rex.pos.vz, 160, 240, rexColor); // 3. Draw Muddy Enemy Dog ("Fuck you" dog) CVECTOR enemyColor = { 150, 140, 50, 0 }; DrawFlatQuad(enemy.pos.vx, enemy.pos.vy, enemy.pos.vz, 180, 120, enemyColor); // 4. Draw Player (Yellow Dog) CVECTOR playerColor = { 240, 200, 30, 0 }; DrawFlatQuad(player.pos.vx, player.pos.vy, player.pos.vz, 140, 100, playerColor); // 5. Draw PS1 Style HUD (Health Bar) DrawHUD(); // Swap buffers and draw DisplayFrame(); } return 0; } // ----------------------------------------------------------------------------- // INITIALIZATION & GPU SETUP // ----------------------------------------------------------------------------- void InitPSX(void) { // Reset GPU ResetGraph(0); // Set up Double Buffering (320x240 NTSC) SetDefDrawEnv(&db[0].draw, 0, 0, SCREEN_X, SCREEN_Y); SetDefDrawEnv(&db[1].draw, 0, SCREEN_Y, SCREEN_X, SCREEN_Y); SetDefDispEnv(&db[0].disp, 0, SCREEN_Y, SCREEN_X, SCREEN_Y); SetDefDispEnv(&db[1].disp, 0, 0, SCREEN_X, SCREEN_Y); // Set Clear Screen Color (PS1 Sky Blue) setRGB0(&db[0].draw, 100, 160, 220); setRGB0(&db[1].draw, 100, 160, 220); db[0].draw.isbg = 1; db[1].draw.isbg = 1; // Apply environments PutDrawEnv(&db[0].draw); PutDispEnv(&db[0].disp); // Initialize Geometry Transformation Engine (GTE) InitGeom(); SetGeomOffset(SCREEN_X / 2, SCREEN_Y / 2); // Center of screen SetGeomScreen(240); // FOV / Perspective distance // Initialize Pad Controllers PadInitDirect(padbuf[0], padbuf[1]); PadStart(); // Enable Display Output SetDispMask(1); side = 0; } // ----------------------------------------------------------------------------- // GAMEPLAY & CONTROLLER INPUT // ----------------------------------------------------------------------------- void UpdateGame(u_long pad) { int speed = 12; // PS1 Controller D-Pad Input if (!(pad & _PAD(0, PADLup))) player.pos.vz += speed; if (!(pad & _PAD(0, PADLdown))) player.pos.vz -= speed; if (!(pad & _PAD(0, PADLleft))) player.pos.vx -= speed; if (!(pad & _PAD(0, PADLright))) player.pos.vx += speed; // Enemy AI Chase if (enemy.pos.vx < player.pos.vx) enemy.pos.vx += 2; if (enemy.pos.vx > player.pos.vx) enemy.pos.vx -= 2; if (enemy.pos.vz < player.pos.vz) enemy.pos.vz += 2; if (enemy.pos.vz > player.pos.vz) enemy.pos.vz -= 2; } // ----------------------------------------------------------------------------- // RENDER PRIMITIVES TO GPU // ----------------------------------------------------------------------------- void DrawFlatQuad(int x, int y, int z, int w, int h, CVECTOR color) { POLY_F4 *quad; SVECTOR v[4]; VECTOR p; long interpolatedZ, flag, sz; quad = (POLY_F4 *)nextpacket; setPolyF4(quad); setRGB0(quad, color.r, color.g, color.b); // Vertices relative to center v[0].vx = x - w/2; v[0].vy = y - h/2; v[0].vz = z; v[1].vx = x + w/2; v[1].vy = y - h/2; v[1].vz = z; v[2].vx = x - w/2; v[2].vy = y + h/2; v[2].vz = z; v[3].vx = x + w/2; v[3].vy = y + h/2; v[3].vz = z; // Transform 3D coordinates using GTE RotTransPers(&v[0], (long*)&quad->x0, &interpolatedZ, &flag); RotTransPers(&v[1], (long*)&quad->x1, &interpolatedZ, &flag); RotTransPers(&v[2], (long*)&quad->x2, &interpolatedZ, &flag); RotTransPers(&v[3], (long*)&quad->x3, &interpolatedZ, &flag); // Simple depth sorting into Ordering Table sz = interpolatedZ >> 2; if (sz > 0 && sz < OT_LEN) { AddPrim(ot[side] + sz, quad); nextpacket += sizeof(POLY_F4); } } void DrawHUD(void) { TILE *bgTile, *fgTile; // Red Background Bar Frame bgTile = (TILE *)nextpacket; setTile(bgTile); setXY0(bgTile, 20, 20); setWH(bgTile, 120, 12); setRGB0(bgTile, 180, 0, 0); // Dark Red AddPrim(ot[side], bgTile); // HUD drawn at OT depth 0 (front) nextpacket += sizeof(TILE); // Green Health Fill Bar fgTile = (TILE *)nextpacket; setTile(fgTile); setXY0(fgTile, 22, 22); setWH(fgTile, (116 * player.health) / 100, 8); setRGB0(fgTile, 0, 220, 0); // Bright Green AddPrim(ot[side], fgTile); nextpacket += sizeof(TILE); } // ----------------------------------------------------------------------------- // SWAP BUFFERS & VSYNC // ----------------------------------------------------------------------------- void DisplayFrame(void) { DrawSync(0); // Wait for GPU to finish drawing current frame VSync(0); // Wait for vertical blank (60Hz lock) // Put Display & Draw Environments PutDrawEnv(&db[side].draw); PutDispEnv(&db[side].disp); // Render Ordering Table to screen DrawOTag(ot[side] + OT_LEN - 1); // Swap double buffer index side ^= 1; } ``` --- ## 🛠️ How to Compile for PS1 Hardware / Emulator To turn this C code into an executable `.EXE` or playable `.ISO` / `.BIN/.CUE` disc image: 1. **Toolchain Needed**: Install a modern PS1 SDK compiler such as **[Nugget + GCC MIPS]** or the open-source **[PSXSDK]**. 2. **Build Makefile**: ```makefile TARGET = barkpark OBJS = main.o CC = mipsel-none-elf-gcc CFLAGS = -O2 -G0 -Wall LDFLAGS= -Ttext 0x80010000 -lpsx all: $(TARGET).exe $(TARGET).exe: $(OBJS) $(CC) $(OBJS) $(LDFLAGS) -o $@ ``` 3. **Packaging to ISO**: Use `mkpsxiso` or `psxavenc` to turn `barkpark.exe` into a `.bin`/`.cue` disc image. 4. **Testing**: Run the output in a PS1 emulator like **DuckStation**, **PCSX-Redux**, or flash it directly to an original PS1 console using an **XStation / PSIO** ODE.