commit 79e0ebcdf3c6f14cb2967dadb3c6f4888b786248
parent 1865c6d720ef2c79549253e1c76108ab749c4c9c
Author: Edea Kramer <edea@lunarcry.home>
Date: Tue, 17 Dec 2024 18:54:30 +0200
Long time..
- Probably looks okay. Now I am stuck again with quads.
- I have to look at the rasterization algo again.
Diffstat:
8 files changed, 263 insertions(+), 90 deletions(-)
diff --git a/makefile b/makefile
@@ -1,5 +1,5 @@
bsd:
- cc -O3 -g src/*.c -o bin/ultimecia -I/usr/local/include -L/usr/local/lib -lprofiler -lSDL2
+ cc -O0 -g src/*.c -o bin/ultimecia -I/usr/local/include -L/usr/local/lib -lSDL2
win:
cc -O3 -g src/*.c -o bin/ultimecia -I/mingw64/include/SDL2 -L/mingw64/lib -lmingw32 -lSDL2main -lSDL2
diff --git a/src/cpu.c b/src/cpu.c
@@ -617,9 +617,9 @@ op_lh(CPU* cpu, instruction* i)
void
op_lhu(CPU* cpu, instruction* i)
{
- u32 v, addr;
+ u32 v, addr;
- addr = reg(cpu, i->s) + i->imm_se;
+ addr = reg(cpu, i->s) + i->imm_se;
if (addr % 2 == 0)
{
diff --git a/src/defs.h b/src/defs.h
@@ -16,7 +16,7 @@ static const int debug = 0; // Set to 0 to disable debug prints
#define LOG_ERROR 4
// Set the current log level
-#define CURRENT_LOG_LEVEL LOG_ERROR
+#define CURRENT_LOG_LEVEL LOG_DEBUG
#define LOG(level, fmt, ...) \
do { if (level >= CURRENT_LOG_LEVEL) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
diff --git a/src/gpu.c b/src/gpu.c
@@ -350,7 +350,26 @@ GPU_gp0_mask_bit_setting(GPU* gpu)
void
GPU_gp0_quad_mono_opaque(GPU* gpu)
{
- LOG(LOG_DEBUG, "Draw quad pls\n", NULL);
+ // LOG(LOG_DEBUG, "Draw quad pls\n", NULL);
+ // ivec2 positions[4];
+ // C colors[4];
+
+ // positions[0] = POSITION_from_gp0(gpu->gp0_command.buffer[1]);
+ // positions[1] = POSITION_from_gp0(gpu->gp0_command.buffer[2]);
+ // positions[2] = POSITION_from_gp0(gpu->gp0_command.buffer[3]);
+ // positions[3] = POSITION_from_gp0(gpu->gp0_command.buffer[4]);
+ // LOG(LOG_DEBUG, "Vertex 0, x: %d, y: %d\n", positions[0].x, positions[0].y);
+ // LOG(LOG_DEBUG, "Vertex 1, x: %d, y: %d\n", positions[1].x, positions[1].y);
+ // LOG(LOG_DEBUG, "Vertex 2, x: %d, y: %d\n", positions[2].x, positions[2].y);
+ // LOG(LOG_DEBUG, "Vertex 3, x: %d, y: %d\n", positions[3].x, positions[3].y);
+
+ // colors[0] = colors[1] = colors[2] = colors[3] = COLOR_from_gp0(gpu->gp0_command.buffer[0]);
+ // LOG(LOG_DEBUG, "Color 0, r: %d, g: %d, b: %d\n", colors[0].r, colors[0].g, colors[0].b);
+ // //LOG(LOG_DEBUG, "Color 1, x: %d, y: %d\n", positions[1].x, positions[1].y);
+ // //LOG(LOG_DEBUG, "Color 2, x: %d, y: %d\n", positions[2].x, positions[2].y);
+ // //LOG(LOG_DEBUG, "Color 3, x: %d, y: %d\n", positions[3].x, positions[3].y);
+
+ // REN_push_quad(gpu->ren, positions, colors);
}
void
@@ -375,13 +394,43 @@ GPU_gp0_triangle_shaded_opaque(GPU* gpu)
void
GPU_gp0_quad_texture_blend_opaque(GPU* gpu)
{
- LOG(LOG_DEBUG, "Draw quad texture blending\n", NULL);
+ //ivec2 positions[4];
+ //C colors[4];
+
+ //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]);
+ //positions[3] = POSITION_from_gp0(gpu->gp0_command.buffer[7]);
+
+ //colors[0] =(C) {0x00, 0x00, 0x80};//COLOR_from_gp0(gpu->gp0_command.buffer[0]);
+ //colors[1] =(C) {0x00, 0x00, 0x80};//COLOR_from_gp0(gpu->gp0_command.buffer[2]);
+ //colors[2] =(C) {0x00, 0x00, 0x80};//COLOR_from_gp0(gpu->gp0_command.buffer[4]);
+ //colors[3] =(C) {0x00, 0x00, 0x80};//COLOR_from_gp0(gpu->gp0_command.buffer[6]);
+
+ //REN_push_quad(gpu->ren, positions, colors);
+ //LOG(LOG_DEBUG, "Draw quad texture blending\n", NULL);
}
void
GPU_gp0_quad_shaded_opaque(GPU* gpu)
{
- LOG(LOG_DEBUG, "Draw quad shaded\n", NULL);
+ //LOG(LOG_DEBUG, "Draw quad pls\n", NULL);
+ //ivec2 positions[4];
+ //C colors[4];
+
+ //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]);
+ //positions[3] = POSITION_from_gp0(gpu->gp0_command.buffer[7]);
+
+ //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]);
+ //colors[3] = COLOR_from_gp0(gpu->gp0_command.buffer[6]);
+
+ //REN_push_quad(gpu->ren, positions, colors);
+
+ //LOG(LOG_DEBUG, "Draw quad shaded\n", NULL);
}
void
diff --git a/src/shaders.c b/src/shaders.c
@@ -0,0 +1,10 @@
+#include "gpu.h"
+
+void
+SHADERS_gradient_shader(float alpha, float beta, float gamma, C* out_color) {
+ // Example shader: simple gradient based on alpha and beta
+ out_color->r = (uint8_t)(alpha * 255); // Gradient in red
+ out_color->g = (uint8_t)(beta * 255); // Gradient in green
+ out_color->b = (uint8_t)(gamma * 255); // Gradient in blue
+}
+
diff --git a/src/shaders.h b/src/shaders.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "gpu.h"
+
+void SHADERS_gradient_shader(float, float, float, C*);
diff --git a/src/sr.c b/src/sr.c
@@ -10,6 +10,7 @@
#include "types.h"
#include "sr.h"
#include "defs.h"
+#include "shaders.h"
ivec2
@@ -122,119 +123,226 @@ REN_new()
{
REN* ren;
ren = (REN*)malloc(sizeof(REN));
- ren->window = SDL_CreateWindow("Ultimecia", 400, 750, WIN_W, WIN_H, SDL_WINDOW_SHOWN);
+ ren->window = SDL_CreateWindow("Ultimecia", 2560 / 2 , 1440 / 2, WIN_W, WIN_H, SDL_WINDOW_SHOWN);
ren->renderer = SDL_CreateRenderer(ren->window, -1, 0);
ren->tex = SDL_CreateTexture(ren->renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, W, H);
ren->verts = NULL;
ren->colors = NULL;
- ren->fb = malloc(W*H*sizeof(u32));
+ ren->verts = (ivec2*)malloc(sizeof(ivec2) * 10000);
+ ren->colors = (C*)malloc(sizeof(C) * 10000);
+ ren->fb = (u32*)malloc(W*H*sizeof(u32));
memset(ren->fb, 0, (u32)(W*H)*sizeof(u32));
ren->nvertices = 0;
return ren;
}
-
-
-void
-REN_triangle(REN* ren, ivec2 verts[3], C colors[3]) {
- ivec2 temp, t0, t1, t2;
- C c0 = colors[0], c1 = colors[1], c2 = colors[2];
- t0 = verts[0]; t1 = verts[1]; t2 = verts[2];
-
- if (t0.y > t1.y) { VEC2I_SWAP(t0, t1); C_SWAP(c0, c1); }
- if (t0.y > t2.y) { VEC2I_SWAP(t0, t2); C_SWAP(c0, c2); }
- if (t1.y > t2.y) { VEC2I_SWAP(t1, t2); C_SWAP(c1, c2); }
-
- i32 total_height = t2.y - t0.y;
- i32 height_first_half = t1.y - t0.y;
- i32 height_second_half = t2.y - t1.y;
- float alpha_step = 1.0f / total_height;
- float alpha = 0.0f;
-
- for (i32 i = 0; i < total_height; i++, alpha += alpha_step) {
- i32 second_half = (i > height_first_half) || (t1.y == t0.y);
- i32 segment_height = second_half ? height_second_half : height_first_half;
- float beta = (float)(i - (second_half ? height_first_half : 0)) / segment_height;
-
- // Interpolated points for this scanline
- ivec2 A = {
- t0.x + (t2.x - t0.x) * alpha,
- t0.y + i
- };
-
- ivec2 B = second_half
- ? (ivec2){ t1.x + (t2.x - t1.x) * beta, t1.y + (i - height_first_half) }
- : (ivec2){ t0.x + (t1.x - t0.x) * beta, t0.y + i };
-
- // Interpolated colors for this scanline
- C color_a = {
- c0.r + (c2.r - c0.r) * alpha,
- c0.g + (c2.g - c0.g) * alpha,
- c0.b + (c2.b - c0.b) * alpha
- };
-
- C color_b = second_half
- ? (C){
- c1.r + (c2.r - c1.r) * beta,
- c1.g + (c2.g - c1.g) * beta,
- c1.b + (c2.b - c1.b) * beta
- }
- : (C){
- c0.r + (c1.r - c0.r) * beta,
- c0.g + (c1.g - c0.g) * beta,
- c0.b + (c1.b - c0.b) * beta
- };
-
- // Sort A and B for left-to-right filling
- if (A.x > B.x) {
- VEC2I_SWAP(A, B);
- C_SWAP(color_a, color_b);
- }
-
- // Fill the horizontal span between A and B, interpolating color
- for (i32 x = A.x; x <= B.x; x++) {
- float t = (float)(x - A.x) / (B.x - A.x);
-
- // Linearly interpolate color across the span
- C color = {
- color_a.r + (color_b.r - color_a.r) * t,
- color_a.g + (color_b.g - color_a.g) * t,
- color_a.b + (color_b.b - color_a.b) * t
- };
-
- REN_FB_set(ren, x, A.y, color);
- }
- }
+void REN_triangle(REN* ren, ivec2 verts[3], C colors[3])
+{
+ // Sort vertices by y-coordinate
+ ivec2 t0, t1, t2;
+ C c0, c1, c2;
+
+ t0 = verts[0], t1 = verts[1], t2 = verts[2];
+ c0 = colors[0], c1 = colors[1], c2 = colors[2];
+
+ if (t0.y > t1.y) { VEC2I_SWAP(t0, t1); C_SWAP(c0, c1); }
+ if (t0.y > t2.y) { VEC2I_SWAP(t0, t2); C_SWAP(c0, c2); }
+ if (t1.y > t2.y) { VEC2I_SWAP(t1, t2); C_SWAP(c1, c2); }
+
+ int total_height = t2.y - t0.y;
+ if (total_height == 0) return; // Degenerate triangle
+
+ for (int y = t0.y; y <= t2.y; y++) {
+ int is_upper = (y < t1.y || t1.y == t0.y);
+
+ // Alpha (long edge)
+ float alpha = (float)(y - t0.y) / (float)(t2.y - t0.y);
+ int Ax = t0.x + (int)((t2.x - t0.x) * alpha);
+ C colorA = {
+ (u8)(c0.r + (c2.r - c0.r) * alpha),
+ (u8)(c0.g + (c2.g - c0.g) * alpha),
+ (u8)(c0.b + (c2.b - c0.b) * alpha)
+ };
+
+ // Beta (short edge)
+ float beta = is_upper
+ ? (float)(y - t0.y) / (float)(t1.y - t0.y)
+ : (float)(y - t1.y) / (float)(t2.y - t1.y);
+ int Bx = is_upper
+ ? t0.x + (int)((t1.x - t0.x) * beta)
+ : t1.x + (int)((t2.x - t1.x) * beta);
+
+ C colorB = is_upper
+ ? (C){
+ (u8)(c0.r + (c1.r - c0.r) * beta),
+ (u8)(c0.g + (c1.g - c0.g) * beta),
+ (u8)(c0.b + (c1.b - c0.b) * beta)
+ }
+ : (C){
+ (u8)(c1.r + (c2.r - c1.r) * beta),
+ (u8)(c1.g + (c2.g - c1.g) * beta),
+ (u8)(c1.b + (c2.b - c1.b) * beta)
+ };
+
+ // Ensure left-to-right order
+ if (Ax > Bx) {
+ int temp_x = Ax; Ax = Bx; Bx = temp_x;
+ C temp_c = colorA; colorA = colorB; colorB = temp_c;
+ }
+
+ // Draw scanline
+ for (int x = Ax; x <= Bx; x++) {
+ float t = (float)(x - Ax) / (float)(Bx - Ax + 1e-6f); // Avoid divide by zero
+ C color = {
+ (u8)(colorA.r + (colorB.r - colorA.r) * t),
+ (u8)(colorA.g + (colorB.g - colorA.g) * t),
+ (u8)(colorA.b + (colorB.b - colorA.b) * t)
+ };
+
+ REN_FB_set(ren, x, y, color);
+ }
+ }
}
+//void REN_triangle(REN* ren, ivec2 verts[3], C colors[3])
+//{
+// // Sort vertices by y-coordinate
+// ivec2 t0, t1, t2;
+// C c0, c1, c2;
+//
+// t0 = verts[0], t1 = verts[1], t2 = verts[2];
+// c0 = colors[0], c1 = colors[1], c2 = colors[2];
+//
+// if (t0.y > t1.y) { VEC2I_SWAP(t0, t1); C_SWAP(c0, c1); }
+// if (t0.y > t2.y) { VEC2I_SWAP(t0, t2); C_SWAP(c0, c2); }
+// if (t1.y > t2.y) { VEC2I_SWAP(t1, t2); C_SWAP(c1, c2); }
+//
+// int inv_total_height = t2.y - t0.y;
+// //if (inv_total_height == 0) return;
+//
+// for (int y = t0.y; y <= t2.y; y++) {
+// int is_upper = y < t1.y || t1.y == t0.y;
+//
+// int alpha = (y - t0.y) * inv_total_height;
+//
+// // Interpolate along the long edge (t0 → t2)
+// int Ax = t0.x + (t2.x - t0.x) * alpha;
+// C colorA = {
+// (u8)(c0.r + (c2.r - c0.r) * alpha),
+// (u8)(c0.g + (c2.g - c0.g) * alpha),
+// (u8)(c0.b + (c2.b - c0.b) * alpha)
+// };
+//
+//
+// // Interpolate along the short edge (t0 → t1 or t1 → t2)
+// int beta = is_upper
+// ? (y - t0.y) / (t1.y - t0.y)
+// : (y - t1.y) / (t2.y - t1.y);
+//
+// int Bx = is_upper
+// ? t0.x + (t1.x - t0.x) * beta
+// : t1.x + (t2.x - t1.x) * beta;
+//
+// //if (Bx < 0) Bx = 0; // Clamp to minimum screen boundary
+// //if (Bx > W) Bx = W; // Clamp to maximum boundary
+//
+//
+// C colorB = is_upper
+// ? (C){
+// (u8)(c0.r + (c1.r - c0.r) * beta),
+// (u8)(c0.g + (c1.g - c0.g) * beta),
+// (u8)(c0.b + (c1.b - c0.b) * beta)
+// }
+// : (C){
+// (u8)(c1.r + (c2.r - c1.r) * beta),
+// (u8)(c1.g + (c2.g - c1.g) * beta),
+// (u8)(c1.b + (c2.b - c1.b) * beta)
+// };
+//
+// // C colorB = (C){ c0.r + (c1.r - c0.r) * beta, c0.g + (c1.g - c0.g) * beta, c0.b + (c1.b - c0.b) * beta };
+//
+// // Ensure left-to-right order
+// if (Ax > Bx) {
+// int temp_x = Ax; Ax = Bx; Bx = temp_x;
+// C temp_c = colorA; colorA = colorB; colorB = temp_c;
+// LOG(LOG_DEBUG, "IM IN %d \n", Ax);
+// }
+//
+// // Draw the scanline
+// for (int x = Ax; x <= Bx; x++) {
+// int t = (x - Ax) / (Bx - Ax + 1e-6f); // Prevent divide-by-zero
+// C color = {
+// (u8)(colorA.r + (colorB.r - colorA.r) * t),
+// (u8)(colorA.g + (colorB.g - colorA.g) * t),
+// (u8)(colorA.b + (colorB.b - colorA.b) * t)
+// };
+//
+// REN_FB_set(ren, x, y, color);
+// }
+// }
+//}
+
void
REN_push_triangle(REN* ren, ivec2 verts[3], C colors[3])
{
u8 i;
- ivec2 tmp[3];
-
- if (ren->nvertices + 3 > 10) {
- LOG(LOG_DEBUG, "Vertex attribute buffer full, forcing draw... and NVERTICES IS %d\n", ren->nvertices);
+
+ if (ren->nvertices > 9)
+ {
+ LOG(LOG_DEBUG, "Vertex attribute buffer full push_triangle, forcing draw... and NVERTICES IS %d\n", ren->nvertices);
for(int i = 0; i < ren->nvertices-3; i+=3)
- REN_triangle(ren, ren->verts+i, ren->colors+1);
+ REN_triangle(ren, ren->verts+i, ren->colors+i);
+ ren->nvertices=0;
+ }
+
+ //if (ren->nvertices + 3 >= ren->capacity) {
+ // ren->capacity *= 2; // Double the capacity
+ // ren->verts = (ivec2*)realloc(ren->verts, sizeof(ivec2) * ren->capacity);
+ // ren->colors = (C*)realloc(ren->colors, sizeof(C) * ren->capacity);
+ //}
+
+ //ren->verts = (ivec2*)realloc(ren->verts, sizeof(ivec2) * (ren->nvertices + 3));
+ //ren->colors = (C*)realloc(ren->colors, sizeof(C) * (ren->nvertices + 3));
+
+ for (i = 0; i < 3; i++) {
+ ren->verts[ren->nvertices] = verts[i];
+ ren->colors[ren->nvertices] = colors[i];
+ ren->nvertices++;
+ }
+}
+
+void
+REN_push_quad(REN* ren, ivec2 verts[4], C colors[4])
+{
+ u8 i;
+
+ if (ren->nvertices > 9)
+ {
+ LOG(LOG_DEBUG, "Vertex attribute buffer full push_squad, forcing draw... and NVERTICES IS %d\n", ren->nvertices);
+ for(int i = 0; i < ren->nvertices-3;i+=3)
+ REN_triangle(ren, ren->verts+i, ren->colors+i);
ren->nvertices=0;
}
- ren->verts = realloc(ren->verts, sizeof(ivec2) * (ren->nvertices + 3));
- ren->colors = realloc(ren->colors, sizeof(C) * (ren->nvertices + 3));
+ //ren->verts = (ivec2*)realloc(ren->verts, sizeof(ivec2) * (ren->nvertices + 4));
+ //ren->colors = (C*)realloc(ren->colors, sizeof(C) * (ren->nvertices + 4));
for (i = 0; i < 3; i++) {
ren->verts[ren->nvertices] = verts[i];
ren->colors[ren->nvertices] = colors[i];
ren->nvertices++;
}
+
+ for (i = 1; i < 4; i++) {
+ ren->verts[ren->nvertices] = verts[i];
+ ren->colors[ren->nvertices] = colors[i];
+ ren->nvertices++;
+ }
}
void
REN_draw(REN* ren)
{
- SDL_SetRenderDrawColor(ren->renderer, 0x33, 0x33, 0x33, 0xff);
- SDL_RenderClear(ren->renderer);
SDL_UpdateTexture(ren->tex, NULL, ren->fb, W * sizeof(u32));
SDL_RenderCopy(ren->renderer, ren->tex, NULL, NULL);
}
diff --git a/src/sr.h b/src/sr.h
@@ -39,5 +39,6 @@ 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 REN_push_quad(REN*, ivec2[4], C[4]);
void REN_draw(REN* ren);
void REN_display(REN* ren);