ultimecia

A ps1 emulator in c
Log | Files | Refs

commit ff8527854d6689c4d2ec20d4160bfba782da0905
parent 7485052cf5412b55b91f2fde562b46cad727f7a3
Author: root <root@lunarcry>
Date:   Wed, 23 Oct 2024 18:03:35 +0000

SR: Renderer what seems to be the playstation logo.. But the colors are f*ed up.
    I need to implement gouraud shading to interpolate the colors that the bios sents me.
    I should tidy up the code as well, as it starts getting messy

Diffstat:
MMISFORTUNES | 8++++++++
Dbuild.sh | 2--
Amakefile | 2++
Msrc/gpu.c | 26++++++++++++++++----------
Msrc/main.c | 21+++++++++++++++++++++
Msrc/sr.c | 81++++++++++++++++++++++++++++---------------------------------------------------
Msrc/sr.h | 8+++++---
7 files changed, 81 insertions(+), 67 deletions(-)

diff --git a/MISFORTUNES b/MISFORTUNES @@ -8,3 +8,11 @@ fault... the question is why UNSTUCK So the solution was (for now) to change CMD_BUFFER to non pointer. Sometime i need to see this kind of problem because this is not the first time I encounter pointer invalidation without any free. + +-- Global Variables -- +23102024 + +Don't ever use global variables. +I had REN_FB_set (fb was the global framebuffer) checking fb.data and not the framebuffer parameter +that i passed in the new iteration of the function!!!! BE careful of global vars. + diff --git a/build.sh b/build.sh @@ -1,2 +0,0 @@ -#cc -Wall -Wpedantic -Wall -pedantic -g src/*.c -o bin/ultimecia -I/usr/local/include -L/usr/local/lib -lSDL2 -cc -g src/*.c -o bin/ultimecia -I/usr/local/include -L/usr/local/lib -lSDL2 diff --git a/makefile b/makefile @@ -0,0 +1,2 @@ +build: + cc -O3 -g src/*.c -o bin/ultimecia -I/usr/local/include -L/usr/local/lib -lSDL2 diff --git a/src/gpu.c b/src/gpu.c @@ -307,17 +307,22 @@ GPU_gp0_drawing_area_bottom_right(GPU* gpu) void GPU_gp0_drawing_offset(GPU* gpu) { - u16 x, y; - u32 val; - - val = gpu->gp0_command.buffer[0]; - x = (u16)(val & 0x7ff); - y = (u16)((val >> 11) & 0x7ff); - - /* Values here are 11bit 2s complement signed values, we need to force sign extension */ - gpu->drawing_x_offset = ((i16)(x << 5)) >> 5; - gpu->drawing_y_offset = ((i16)(y << 5)) >> 5; + u16 x, y; + u32 val; + val = gpu->gp0_command.buffer[0]; + x = (u16)(val & 0x7ff); + y = (u16)((val >> 11) & 0x7ff); + + /* Values here are 11bit 2s complement signed values, we need to force sign extension */ + gpu->drawing_x_offset = ((i16)(x << 5)) >> 5; + gpu->drawing_y_offset = ((i16)(y << 5)) >> 5; + + /* + This is a hack because I haven't implemented gpu timings yet. + But gp0_drawing_offset is called every frame apparently. + */ + REN_display(gpu->ren); } void @@ -363,6 +368,7 @@ GPU_gp0_triangle_shaded_opaque(GPU* gpu) colors[2] = COLOR_from_gp0(gpu->gp0_command.buffer[4]); REN_push_triangle(gpu->ren, positions, colors); + //REN_display(gpu->ren); fprintf(stdout, "Draw triangle shaded\n"); } diff --git a/src/main.c b/src/main.c @@ -28,8 +28,29 @@ main(int argc, char **argv) inter = new_interconnect(); cpu = new_cpu(inter); + ren = inter->gpu->ren; + SDL_RenderClear(ren->renderer); + while(1) { CPU_run_next_instruction(cpu); + + //while(SDL_PollEvent(&ev) != 0) { + // switch(ev.type) { + // case SDL_QUIT: + // SDL_Quit(); + // exit(1); + // + // case SDL_KEYDOWN: + // if (ev.key.keysym.sym == SDLK_q) { + // SDL_Quit(); + // exit(1); + // } else if (ev.key.keysym.sym == SDLK_a) { + // SDL_Log("A pressed"); + // } + // default: + // break; + // } + //} } free(inter->bios->data); diff --git a/src/sr.c b/src/sr.c @@ -134,7 +134,7 @@ C_new(u32 b) v new_fb() { fb.data = malloc(W*H*sizeof(u32));} void FB_set(i32 x, i32 y, C c) { (!fb.data || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(fb.data + ((x + y * W)), &c, 4); } -void REN_FB_set(REN* ren, i32 x, i32 y, C c) { (!fb.data || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(ren->fb + ((x + y * W)), &c, 4); } +void REN_FB_set(REN* ren, i32 x, i32 y, C c) { (!ren->fb || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(ren->fb + ((x + y * W)), &c, 4); } //C* //FB_get(i32 x, i32 y) @@ -180,8 +180,8 @@ REN_new() REN* ren; SDL_Init(SDL_INIT_VIDEO); ren = (REN*)malloc(sizeof(REN)); - ren->window = SDL_CreateWindow("Ultimecia", 400, 400, WIN_W, WIN_H, SDL_WINDOW_RESIZABLE); - ren->renderer = SDL_CreateRenderer(ren->window, -1, SDL_RENDERER_SOFTWARE); + ren->window = SDL_CreateWindow("Ultimecia", 400, 400, WIN_W, WIN_H, SDL_WINDOW_SHOWN); + ren->renderer = SDL_CreateRenderer(ren->window, -1, 0); ren->tex = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, W, H); ren->verts = NULL; ren->colors = NULL; @@ -271,7 +271,7 @@ draw_obj(i32 fcount) void triangle(REN* ren, ivec2 t0, ivec2 t1, ivec2 t2, C color) { - // sort the vertices, t0, t1, t2 lower−to−upper (bubblesort yay!) + // SORT the vertices, t0, t1, t2 lower−to−upper (bubblesort yay!) ivec2 temp; if (t0.y>t1.y) VEC2I_SWAP(t0, t1); @@ -314,13 +314,19 @@ REN_push_triangle(REN* ren, ivec2 verts[3], C colors[3]) { u8 i; long VERTEX_BUFFER_LEN = 64*1024; + ivec2 t0[3] = {{10, 70}, {50, 160}, {70, 80}}; - if (ren->nvertices + 3 > 100) { + if (ren->nvertices + 3 > 1000) { printf("Vertex attribute buffer full, forcing draw...\n"); - for(int i = 0; i < ren->nvertices-2; i++) + for(int i = 0; i < ren->nvertices-2; i++) { triangle(ren, ren->verts[i], ren->verts[i+1], ren->verts[i+2], ren->colors[i]); - } + triangle(ren, ren->verts[i], ren->verts[i+1], ren->verts[i+2], ren->colors[i+1]); + triangle(ren, ren->verts[i], ren->verts[i+1], ren->verts[i+2], ren->colors[i+2]); + //triangle(ren, t0[0],t0[1], t0[2], C_new(0xffffffff));//ren->colors[i]); + //printf("Vert 1 -> x: %d, y: %d\nVert 2 -> x: %d, y: %d\nVert 3 -> x: %d, y: %d\n", ren->verts[i].x, ren->verts[i].y, ren->verts[i+1].x, ren->verts[i+1].y, ren->verts[i+2].x, ren->verts[i+3].y); + } + } ren->verts = realloc(ren->verts, sizeof(ivec2) * (ren->nvertices + 3)); ren->colors = realloc(ren->colors, sizeof(C) * (ren->nvertices + 3)); for (i = 0; i < 3; i++) { @@ -330,50 +336,21 @@ REN_push_triangle(REN* ren, ivec2 verts[3], C colors[3]) } } -i32 -haha_main() +void +REN_draw(REN* ren) +{ + SDL_RenderClear(ren->renderer); + SDL_UpdateTexture(ren->tex, NULL, ren->fb, W * sizeof(u32)); + SDL_RenderCopy(ren->renderer, ren->tex, NULL, NULL); + + // With this uncommented it fucks it up and it doesn't draw + //ren->nvertices=0; +} + +void +REN_display(REN* ren) { - //init_sdl(); - - //SDL_Event ev; - - SDL_RenderClear(ren); - - //i32 fcount, ecount; - //i32 ho = parse_obj(&fcount, &ecount); - - //draw_obj(fcount); - - //ivec2 t0[3] = {{10, 70}, {50, 160}, {70, 80}}; - //ivec2 t1[3] = {{180, 50}, {150, 1}, {70, 180}}; - //ivec2 t2[3] = {{180, 150}, {120, 160}, {130, 180}}; - //triangle(t0[0], t0[1], t0[2],C_new(0xff000000)); - //triangle(t1[0], t1[1], t1[2],C_new(0xffff0000)); - //triangle(t2[0], t2[1], t2[2],C_new(0x000ff000)); - //ivec2 v0 = {0, 0}; - //ivec2 v1 = {W, 0}; - //ivec2 v2 = {W/2, H}; - //triangle(v0, v1, v2,C_new(0xff000000)); - - //FB_flip_vert(fb.data); - - //SDL_UpdateTexture(texture, NULL, fb.data, W * sizeof(u32)); - //SDL_RenderCopy(ren->ren, texture, NULL, NULL); - //SDL_RenderPresent(ren); - - //while(1) { - // while(SDL_PollEvent(&ev) != 0) { - // switch(ev.type) { - // case SDL_QUIT: - // SDL_Quit(); - // exit(1); - // } - // switch(ev.key.keysym.sym) { - // case SDLK_q: - // SDL_Quit(); - // exit(1); - // } - // } - //} - return 0; + REN_draw(ren); + SDL_RenderPresent(ren->renderer); + //SDL_Delay(1000); } diff --git a/src/sr.h b/src/sr.h @@ -2,8 +2,9 @@ #include <SDL2/SDL.h> -#define W 1024 -#define H 1024 +#define W 640 +#define H 480 + #define WIN_W 1024 #define WIN_H 1024 @@ -40,4 +41,5 @@ REN* REN_new(); ivec2 POSITION_from_gp0(u32 val); C COLOR_from_gp0(u32 val); void REN_push_triangle(REN*, ivec2[3], C[3]); -void RENDERER_draw(); +void REN_draw(REN* ren); +void REN_display(REN* ren);