ultimecia

A ps1 emulator in c
Log | Files | Refs

commit c338c94a7b282fe9da78e4ce19dbdf81258f198a
parent e3ec2d2175f83466b3ab7734c34cd015d8443605
Author: root <root@lunarcry>
Date:   Mon, 23 Sep 2024 15:32:45 +0000

Not a lot to add. Trivial renderer implementation.
Let's write a software renderer. Should be fun..

Diffstat:
Mbuild.sh | 2+-
Msrc/gpu.c | 15+++++++++++++++
Msrc/gpu.h | 2++
Msrc/main.c | 4++++
Asrc/renderer.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/renderer.h | 34++++++++++++++++++++++++++++++++++
6 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/build.sh b/build.sh @@ -1 +1 @@ -cc -Wall -Wpedantic -static -Wall -pedantic -g src/*.c -o bin/ultimecia +cc -Wall -Wpedantic -Wall -pedantic -g src/*.c -o bin/ultimecia -lSDL2 diff --git a/src/gpu.c b/src/gpu.c @@ -4,6 +4,7 @@ #include "gpu.h" #include "types.h" #include "defs.h" +#include "renderer.h" u8 HOR_RES_from_fields(u8 hr1, u8 hr2) { return (hr2 & 1) | ((hr1 & 3) << 1); } u32 HOR_RES_into_status(u8 hr) {return ((u32)hr) << 16; } @@ -16,6 +17,7 @@ GPU_new(void) gpu = (GPU*)malloc(sizeof(GPU)); memset(gpu, 0, sizeof(GPU)); gpu->display_disabled = 1; + gpu->ren = RENDERER_new(); return gpu; } @@ -347,6 +349,19 @@ GPU_gp0_quad_mono_opaque(GPU* gpu) void GPU_gp0_triangle_shaded_opaque(GPU* gpu) { + R_Position positions[3]; + R_Color colors[3]; + + positions[0] = POSITION_from_gp0(gpu->gp0_command.buffer[1]); + positions[1] = POSITION_from_gp0(gpu->gp0_command.buffer[3]); + positions[2] = POSITION_from_gp0(gpu->gp0_command.buffer[5]); + + colors[0] = COLOR_from_gp0(gpu->gp0_command.buffer[0]); + colors[1] = COLOR_from_gp0(gpu->gp0_command.buffer[2]); + colors[2] = COLOR_from_gp0(gpu->gp0_command.buffer[4]); + + // gpu->ren->push_triangle(positions, colors); + fprintf(stdout, "Draw triangle shaded\n"); } diff --git a/src/gpu.h b/src/gpu.h @@ -1,6 +1,7 @@ #pragma once #include "types.h" +#include "renderer.h" typedef enum _GP0_MODE { GP0_MODE_COMMAND, @@ -87,6 +88,7 @@ typedef struct _GPU { u32 gp0_words_remaining; void (*gp0_command_method) (struct _GPU*); + RENDERER* ren; } GPU; /* GPU */ diff --git a/src/main.c b/src/main.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <SDL2/SDL.h> #include "types.h" #include "cpu.h" @@ -9,6 +10,7 @@ #include "mem.h" #include "defs.h" #include "gpu.h" +#include "renderer.h" int main(int argc, char **argv) @@ -31,5 +33,7 @@ main(int argc, char **argv) free(inter); free(cpu); + SDL_Quit(); + return 0; } diff --git a/src/renderer.c b/src/renderer.c @@ -0,0 +1,66 @@ +/* This is the renderer */ + +#include <SDL2/SDL.h> +#include <stdint.h> +#include "types.h" +#include "renderer.h" + +RENDERER* +RENDERER_new() +{ + RENDERER* ren; + + SDL_Init(SDL_INIT_VIDEO); + + ren = malloc(sizeof(RENDERER)); + ren->window = SDL_CreateWindow("Ultimecia", 0, 0, 1024, 512, SDL_WINDOW_RESIZABLE); + ren->renderer = SDL_CreateRenderer(ren->window, -1, SDL_RENDERER_SOFTWARE); + ren->framebuffer = malloc(sizeof(u32) * 320 * 240); + memset(ren->framebuffer, 0, sizeof(u32)* 320 * 240); + ren->nvertices = 0; + + return ren; +} + +R_Position +POSITION_from_gp0(u32 val) +{ + R_Position pos; + pos.x = (i16)val; + pos.y = (i16)(val >> 16); + + return pos; +} + +R_Color +COLOR_from_gp0(u32 val) +{ + R_Color c; + c.r = (u8)val; + c.g = (u8)(val >> 8); + c.b = (u8)(val >> 16); + + return c; +} + +void +RENDERER_draw() +{ + return; +} + +void +RENDERER_push_triangle(RENDERER* ren, R_Position positions[3], R_Color colors[3]) +{ + u8 i; + + if (ren->nvertices + 3 > 1) { + printf("Vertex attribute buffer full, forcing draw...\n"); + RENDERER_draw(); + } + + for (i = 0; i < 3; i++) { + ren->nvertices++; + } + +} +\ No newline at end of file diff --git a/src/renderer.h b/src/renderer.h @@ -0,0 +1,34 @@ +#pragma once + +#include <SDL2/SDL.h> +#include "types.h" + +typedef struct _R_Position { + i16 x; + i16 y; +} R_Position; + +typedef struct _R_Color { + u8 r; + u8 g; + u8 b; +} R_Color; + + +typedef struct _RENDERER { + SDL_Window* window; + SDL_Surface* surface; + SDL_Renderer* renderer; + R_Position* positions; + R_Color* colors; + u32* framebuffer; + u32 nvertices; /* Current number or vertices in the buffers */ +} RENDERER; + +RENDERER* RENDERER_new(); +R_Position POSITION_from_gp0(u32 val); +R_Color COLOR_from_gp0(u32 val); +void RENDERER_push_triangle(RENDERER*, R_Position[3], R_Color[3]); +void RENDERER_draw(); + +