wip sw renderer...bsp is borked, also lots of other things

This commit is contained in:
asrael 2026-01-21 23:19:50 -06:00
parent 415d424057
commit c771fa665d
56 changed files with 8151 additions and 1261 deletions

View file

@ -1,42 +1,12 @@
#include "pxl8_colormap.h"
#include <string.h>
static void rgb_to_hsl(u8 r, u8 g, u8 b, i32* h, i32* s, i32* l) {
i32 max = r > g ? (r > b ? r : b) : (g > b ? g : b);
i32 min = r < g ? (r < b ? r : b) : (g < b ? g : b);
i32 chroma = max - min;
*l = (max + min) / 2;
if (chroma == 0) {
*h = 0;
*s = 0;
} else {
i32 denom = 255 - (*l > 127 ? 2 * (*l) - 255 : 255 - 2 * (*l));
if (denom <= 0) denom = 1;
*s = (chroma * 255) / denom;
if (*s > 255) *s = 255;
if (max == (i32)r) {
*h = (((i32)g - (i32)b) * 60) / chroma;
if (*h < 0) *h += 360;
} else if (max == (i32)g) {
*h = 120 + (((i32)b - (i32)r) * 60) / chroma;
} else {
*h = 240 + (((i32)r - (i32)g) * 60) / chroma;
}
}
}
static u8 find_closest_color(const u32* palette, u8 target_r, u8 target_g, u8 target_b) {
u8 best_idx = 1;
u32 best_dist = 0xFFFFFFFF;
u8 dynamic_end = PXL8_DYNAMIC_RANGE_START + PXL8_DYNAMIC_RANGE_COUNT;
i32 th, ts, tl;
rgb_to_hsl(target_r, target_g, target_b, &th, &ts, &tl);
for (u32 i = 1; i < PXL8_FULLBRIGHT_START; i++) {
if (i >= PXL8_DYNAMIC_RANGE_START && i < dynamic_end) {
continue;
@ -47,17 +17,10 @@ static u8 find_closest_color(const u32* palette, u8 target_r, u8 target_g, u8 ta
u8 pg = (c >> 8) & 0xFF;
u8 pb = (c >> 16) & 0xFF;
i32 ph, ps, pl;
rgb_to_hsl(pr, pg, pb, &ph, &ps, &pl);
i32 dh = th - ph;
if (dh > 180) dh -= 360;
if (dh < -180) dh += 360;
i32 ds = ts - ps;
i32 dl = tl - pl;
u32 dist = (u32)(dh * dh * 4 + ds * ds + dl * dl);
i32 dr = (i32)target_r - (i32)pr;
i32 dg = (i32)target_g - (i32)pg;
i32 db = (i32)target_b - (i32)pb;
u32 dist = (u32)(dr * dr + dg * dg + db * db);
if (dist < best_dist) {
best_dist = dist;
@ -69,26 +32,19 @@ static u8 find_closest_color(const u32* palette, u8 target_r, u8 target_g, u8 ta
return best_idx;
}
void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette, const pxl8_level_tint* tint) {
if (!cm || !palette) return;
void pxl8_set_colormap(pxl8_colormap* cm, const u8* data, u32 size) {
if (!cm || !data || size == 0) return;
u32 copy_size = size > PXL8_COLORMAP_SIZE ? PXL8_COLORMAP_SIZE : size;
memcpy(cm->table, data, copy_size);
}
u8 dark_r, dark_g, dark_b;
if (tint && tint->tint_strength > 0.0f) {
f32 t = tint->tint_strength;
f32 inv = 1.0f - t;
dark_r = (u8)(tint->dark_r * inv + tint->tint_r * t);
dark_g = (u8)(tint->dark_g * inv + tint->tint_g * t);
dark_b = (u8)(tint->dark_b * inv + tint->tint_b * t);
} else if (tint) {
dark_r = tint->dark_r;
dark_g = tint->dark_g;
dark_b = tint->dark_b;
} else {
dark_r = dark_g = dark_b = 0;
}
static void generate_light_table(pxl8_colormap* cm, const u32* palette, pxl8_light_color light_color) {
pxl8_rgb light = pxl8_light_colors[light_color];
u32 base_row = (u32)light_color * PXL8_LIGHT_LEVELS;
for (u32 light = 0; light < PXL8_LIGHT_LEVELS; light++) {
f32 brightness = (f32)light / (f32)(PXL8_LIGHT_LEVELS - 1);
for (u32 level = 0; level < PXL8_LIGHT_LEVELS; level++) {
f32 brightness = (f32)level / (f32)(PXL8_LIGHT_LEVELS - 1);
u32 row = base_row + level;
for (u32 pal_idx = 0; pal_idx < 256; pal_idx++) {
u8 result_idx;
@ -103,14 +59,65 @@ void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette, const pxl8_le
u8 g = (c >> 8) & 0xFF;
u8 b = (c >> 16) & 0xFF;
u8 target_r = (u8)(dark_r + (r - dark_r) * brightness);
u8 target_g = (u8)(dark_g + (g - dark_g) * brightness);
u8 target_b = (u8)(dark_b + (b - dark_b) * brightness);
f32 lr = (f32)light.r / 255.0f;
f32 lg = (f32)light.g / 255.0f;
f32 lb = (f32)light.b / 255.0f;
u8 target_r = (u8)(r * brightness * lr);
u8 target_g = (u8)(g * brightness * lg);
u8 target_b = (u8)(b * brightness * lb);
result_idx = find_closest_color(palette, target_r, target_g, target_b);
}
cm->table[light * 256 + pal_idx] = result_idx;
cm->table[row * 256 + pal_idx] = result_idx;
}
}
}
static void generate_blend_table(pxl8_colormap* cm, const u32* palette) {
for (u32 src = 0; src < 256; src++) {
u32 row = PXL8_LIGHT_ROWS + src;
u8 sr, sg, sb;
if (src == PXL8_TRANSPARENT) {
sr = sg = sb = 0;
} else {
u32 sc = palette[src];
sr = sc & 0xFF;
sg = (sc >> 8) & 0xFF;
sb = (sc >> 16) & 0xFF;
}
for (u32 dst = 0; dst < 256; dst++) {
u8 result_idx;
if (src == PXL8_TRANSPARENT) {
result_idx = (u8)dst;
} else {
u32 dc = palette[dst];
u8 dr = dc & 0xFF;
u8 dg = (dc >> 8) & 0xFF;
u8 db = (dc >> 16) & 0xFF;
u8 blend_r = (u8)((sr + dr) / 2);
u8 blend_g = (u8)((sg + dg) / 2);
u8 blend_b = (u8)((sb + db) / 2);
result_idx = find_closest_color(palette, blend_r, blend_g, blend_b);
}
cm->table[row * 256 + dst] = result_idx;
}
}
}
void pxl8_colormap_generate(pxl8_colormap* cm, const u32* palette) {
if (!cm || !palette) return;
for (u32 light = 0; light < PXL8_LIGHT_COLORS; light++) {
generate_light_table(cm, palette, (pxl8_light_color)light);
}
generate_blend_table(cm, palette);
}