ultimecia

A ps1 emulator in c
Log | Files | Refs

commit 571cfe7222bcf82dab665e381ae400ad48c7c4a3
parent 37e5c88641681eee72078375a2e40abc47568a98
Author: root <root@lunarcry>
Date:   Mon, 14 Oct 2024 18:52:08 +0000

Cow is wireframed correctly, looking happy!!

Diffstat:
Msrc/sr/makefile | 2+-
Msrc/sr/sr.c | 279+++++++++++++++++++++++++++++++++++++++++++------------------------------------
2 files changed, 153 insertions(+), 128 deletions(-)

diff --git a/src/sr/makefile b/src/sr/makefile @@ -1,5 +1,5 @@ build: - cc sr.c -o renderer -L/usr/local/lib -I/usr/local/include -lSDL2 + cc sr.c -g -o renderer -L/usr/local/lib -I/usr/local/include -lSDL2 run: ./renderer diff --git a/src/sr/sr.c b/src/sr/sr.c @@ -7,148 +7,153 @@ #include <math.h> #include <SDL2/SDL.h> -#define W 128 -#define H 128 +#define W 512 +#define H 512 +#define WIN_W 512 +#define WIN_H 512 typedef void v; typedef uint8_t u8;typedef uint16_t u16;typedef uint32_t u32;typedef uint64_t u64;typedef int8_t i8;typedef int16_t i16;typedef int32_t i32;typedef int64_t i64;typedef uint8_t Bool; typedef struct { u32 *data; } FB; typedef struct {u8 b;u8 g;u8 r; u8 a;} C; typedef struct { - double x, y, z; + double x, y, z; } point; typedef struct { - u32 x, y; + u32 x, y; } vec2i; typedef struct { - double x, y, z; + double x, y, z; } vec3f; typedef struct { } scene; -FB fb; SDL_Window* win; SDL_Renderer* ren; +FB fb; +SDL_Window* win; +SDL_Renderer* ren; +vec3f **vertices; +int **faces; + C* new_C(u32 b) { - C* c = malloc(sizeof(C)); - c->r = (u8)(b & 0xff); - c->g = (u8)((b >> 8) & 0xff); - c->b = (u8)((b >> 16) & 0xff); - c->a = (u8)((b >> 24) & 0xff); - return c; + C* c = malloc(sizeof(C)); + c->r = (u8)(b & 0xff); + c->g = (u8)((b >> 8) & 0xff); + c->b = (u8)((b >> 16) & 0xff); + c->a = (u8)((b >> 24) & 0xff); + return c; }; v new_fb() { fb.data = malloc(W*H*sizeof(u32));} void FB_set(int x, int y, C c) { (!fb.data || x<0 || y<0 || x>=W || y>=H) ? 0 : memcpy(fb.data + ((x + y * W)), &c, 4); } C* FB_get(int x, int y) { - void* c = (!fb.data || x<0 || y<0 || x>=W || y>=H) ? (void*)0 : (void*)(new_C(fb.data[(x+y*W)])); - return (C*)c; + void* c = (!fb.data || x<0 || y<0 || x>=W || y>=H) ? (void*)0 : (void*)(new_C(fb.data[(x+y*W)])); + return (C*)c; } void line(int x0, int y0, int x1, int y1, C color) { - int x,y,dx,dy,sx,sy,e,e2,p; - - dx = abs(x1-x0); - sx = x0 < x1 ? 1 : -1; - dy = -abs(y1-y0); - sy = y0 < y1 ? 1 : -1; - e = dx + dy; - - while (1) { - FB_set(x0, y0, color); - if (x0 == x1 && y0 == y1) break; - e2 = 2 * e; - if (e2 >= dy) { - e += dy; - x0 += sx; - } - if (e2 <= dx) { - e += dx; - y0 += sy; - } - } + int x,y,dx,dy,sx,sy,e,e2,p; + + dx = abs(x1-x0); + sx = x0 < x1 ? 1 : -1; + dy = -abs(y1-y0); + sy = y0 < y1 ? 1 : -1; + e = dx + dy; + + while (1) { + FB_set(x0, y0, color); + if (x0 == x1 && y0 == y1) break; + e2 = 2 * e; + if (e2 >= dy) { + e += dy; + x0 += sx; + } + if (e2 <= dx) { + e += dx; + y0 += sy; + } + } } void init_sdl() { - SDL_Init(SDL_INIT_VIDEO); - win= SDL_CreateWindow("Ultimecia", 600, 600, 512, 512, SDL_WINDOW_SHOWN); - ren = SDL_CreateRenderer(win, -1, 0); + SDL_Init(SDL_INIT_VIDEO); + win= SDL_CreateWindow("Ultimecia", 600, 600, WIN_W, WIN_H, SDL_WINDOW_SHOWN); + ren = SDL_CreateRenderer(win, -1, 0); + SDL_RenderSetLogicalSize(ren, 512, 512); } void drw_ls() { - line(0, 0, 256, 256, (C){0xff, 0xff, 0xff, 0xff}); - line(23, 30,90, 50, (C){0xff, 0x0, 0x0, 255}); - line(127,0, 0, 127, (C){0, 255, 0, 255}); + line(0, 0, 256, 256, (C){0xff, 0xff, 0xff, 0xff}); + line(23, 30,90, 50, (C){0xff, 0x0, 0x0, 255}); + line(127,0, 0, 127, (C){0, 255, 0, 255}); } -void parse_obj() +int +parse_obj(int *fcount, int *ecount) { - FILE *f; - char *line; - char *tokens[128], *p; - size_t len; - ssize_t read; - vec3f *vertices[10000]; - u32 *faces; - long pos; - int edge_count; - - f = fopen("cow.obj", "rb"); - - fseek(f, 0, SEEK_END); - pos = ftell(f); - fseek(f, 0, SEEK_SET); - - faces = malloc(sizeof(u32)*pos); - line = NULL; - edge_count = 0; - while ((read = getline(&line, &len, f)) != -1) { - if(strstr(line, "v ") != NULL) { - int i; - printf("Original string %s\n", line); - i = 0; - for ((p = strtok(line, " ")); p; (p = strtok(NULL, " "))) - tokens[i++] = p; - vertices[edge_count]->x = atof(tokens[1]); - vertices[edge_count]->y = atof(tokens[2]); - vertices[edge_count]->z = atof(tokens[3]); - edge_count++; - } - } - - fclose(f); - if (line) - free(line); - - SDL_Quit(); - exit(EXIT_SUCCESS); - - //if (!line.compare(0, 2, "v ")) { - // iss >> trash; - // Vec3f v; - // for (int i=0;i<3;i++) iss >> v.raw[i]; - // verts_.push_back(v); - - //} else if (!line.compare(0, 2, "f ")) { - // std::vector<int> f; - // int itrash, idx; - // iss >> trash; - // while (iss >> idx >> trash >> itrash >> trash >> itrash) { - // idx--; // in wavefront obj all indices start at 1, not zero - // f.push_back(idx); - - // } - // faces_.push_back(f); - //} + FILE *f; + char *line; + char *tokens[128], *p; + size_t len; + ssize_t read; + long pos; + int edge_count, face_count; + + f = fopen("cow.obj", "rb"); + + fseek(f, 0, SEEK_END); + pos = ftell(f); + fseek(f, 0, SEEK_SET); + + line = NULL; + edge_count = 0; + face_count = 0; + + while ((read = getline(&line, &len, f)) != -1) { + int i; + i = 0; + if (strstr(line, "v ") != NULL) { + for ((p = strtok(line, " ")); p; (p = strtok(NULL, " "))) + tokens[i++] = p; + + vertices = realloc(vertices, (edge_count + 1) * sizeof(vec3f*)); + vertices[edge_count] = malloc(sizeof(vec3f)); + + vertices[edge_count]->x = atof(tokens[1]); + vertices[edge_count]->y = atof(tokens[2]); + vertices[edge_count++]->z = atof(tokens[3]); + } + + if (strstr(line, "f ") != NULL) { + for ((p = strtok(line, " ")); p; (p = strtok(NULL, " "))) + tokens[i++] = p; + + faces = realloc(faces, (face_count + 1) * sizeof(int*)); + faces[face_count] = malloc(sizeof(int)*3); + + faces[face_count][0] = atoi(tokens[1]) - 1; + faces[face_count][1] = atoi(tokens[2]) - 1; + faces[face_count++][2] = atoi(tokens[3]) - 1; + } + } + + fclose(f); + if (line) + free(line); + + *fcount = face_count; + *ecount = edge_count; + return 1; } @@ -156,32 +161,52 @@ void parse_obj() int main() { - init_sdl(); - - SDL_Event ev; - i8 res = 1; - new_fb(); memset(fb.data, 0, (u32)(W*H)*sizeof(u32)); - drw_ls(); - - SDL_Texture* texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 128, 128); - - SDL_SetRenderDrawColor(ren, 0x33, 0x33, 0xff, 0xff); - SDL_RenderClear(ren); - SDL_UpdateTexture(texture, NULL, fb.data, W * sizeof(Uint32)); - SDL_RenderCopy(ren, texture, NULL, NULL); - SDL_RenderPresent(ren); - - parse_obj(); - - while(1) { - SDL_Delay(33); - while(SDL_PollEvent(&ev) != 0) { - switch(ev.type) { - case SDL_QUIT: - SDL_Quit(); - exit(1); - } - } - } - return 0; + init_sdl(); + + SDL_Event ev; + i8 res = 1; + new_fb(); memset(fb.data, 0, (u32)(W*H)*sizeof(u32)); + + SDL_Texture* texture = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 512, 512); + + SDL_SetRenderDrawColor(ren, 0x33, 0x33, 0xff, 0xff); + SDL_RenderClear(ren); + + int fcount, ecount; + int ho = parse_obj(&fcount, &ecount); + + for (int i=0; i<fcount-1; i++) { + int *face = faces[i]; + + for (int j=0; j<3; j++) { + vec3f *v0 = vertices[face[j]]; + vec3f *v1 = vertices[face[(j+1)%3]]; + int x0 = 256 + (v0->x+1.)*64/2.; + int y0 = 512 - (256 + (v0->y+1.)*64/2.); + int x1 = 256 + (v1->x+1.)*64/2.; + int y1 = 512 - (256 + (v1->y+1.)*64/2.); + line(x0, y0, x1, y1, (C){0xff, 0x33, 0x33, rand() % 0xff}); + } + } + + SDL_UpdateTexture(texture, NULL, fb.data, W * sizeof(Uint32)); + SDL_RenderCopy(ren, texture, NULL, NULL); + SDL_RenderPresent(ren); + + while(1) { + SDL_Delay(33); + 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; }