From bfeb842bd3deaf3fe71e3a0085876a222bf3cd03 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 6 Jul 2024 16:32:01 +0300 Subject: [PATCH 1/3] pcx: fix support of bytes_per_line https://github.com/yquake2/yquake2/issues/1119 --- src/client/cl_cin.c | 10 ++++++++-- src/client/refresh/files/pcx.c | 8 +++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/client/cl_cin.c b/src/client/cl_cin.c index 44456c67..c135e21a 100644 --- a/src/client/cl_cin.c +++ b/src/client/cl_cin.c @@ -85,7 +85,7 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height) { byte *raw; pcx_t *pcx; - int x, y; + int x, y, bpl; int len, full_size; int dataByte, runLength; byte *out, *pix; @@ -115,6 +115,12 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height) return; } + bpl = LittleShort(pcx->bytes_per_line); + if (bpl <= pcx->xmax) + { + bpl = pcx->xmax + 1; + } + full_size = (pcx->ymax + 1) * (pcx->xmax + 1); out = Z_Malloc(full_size); @@ -140,7 +146,7 @@ SCR_LoadPCX(char *filename, byte **pic, byte **palette, int *width, int *height) for (y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1) { - for (x = 0; x <= pcx->xmax; ) + for (x = 0; x < bpl; ) { dataByte = *raw++; diff --git a/src/client/refresh/files/pcx.c b/src/client/refresh/files/pcx.c index 6ce5cb15..07b91f35 100644 --- a/src/client/refresh/files/pcx.c +++ b/src/client/refresh/files/pcx.c @@ -173,6 +173,12 @@ LoadPCX(const char *origname, byte **pic, byte **palette, int *width, int *heigh return; } + if (pcx->bytes_per_line <= pcx_width) + { + pcx->bytes_per_line = pcx_width + 1; + image_issues = true; + } + full_size = (pcx_height + 1) * (pcx_width + 1); out = malloc(full_size); if (!out) @@ -218,7 +224,7 @@ LoadPCX(const char *origname, byte **pic, byte **palette, int *width, int *heigh for (y = 0; y <= pcx_height; y++, pix += pcx_width + 1) { - for (x = 0; x <= pcx_width; ) + for (x = 0; x < pcx->bytes_per_line; ) { if (raw - (byte *)pcx > len) { From 79c71c7a689870b4f67dc904b42a0a8bad0bb6f3 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 6 Jul 2024 16:41:52 +0300 Subject: [PATCH 2/3] soft: get rid unused R_PolysetUpdateTables --- src/client/refresh/soft/header/local.h | 1 - src/client/refresh/soft/sw_alias.c | 2 -- src/client/refresh/soft/sw_polyset.c | 27 -------------------------- 3 files changed, 30 deletions(-) diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index 194c2275..da4f6c27 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -343,7 +343,6 @@ extern qboolean r_dowarp; extern affinetridesc_t r_affinetridesc; void D_WarpScreen(void); -void R_PolysetUpdateTables(void); //=======================================================================// diff --git a/src/client/refresh/soft/sw_alias.c b/src/client/refresh/soft/sw_alias.c index 6e3590fa..1726cf86 100644 --- a/src/client/refresh/soft/sw_alias.c +++ b/src/client/refresh/soft/sw_alias.c @@ -529,8 +529,6 @@ R_AliasSetupSkin(const entity_t *currententity, const model_t *currentmodel) r_affinetridesc.skinwidth = pskindesc->width; r_affinetridesc.skinheight = pskindesc->height; - R_PolysetUpdateTables (); // FIXME: precalc edge lookups - return true; } diff --git a/src/client/refresh/soft/sw_polyset.c b/src/client/refresh/soft/sw_polyset.c index a512fb72..acfd6a10 100644 --- a/src/client/refresh/soft/sw_polyset.c +++ b/src/client/refresh/soft/sw_polyset.c @@ -77,10 +77,6 @@ static light3_t d_lightbasestep, d_lightextrastep; static int d_sfracbasestep, d_tfracbasestep; static zvalue_t d_ziextrastep, d_zibasestep; -static byte *skintable[MAX_LBM_HEIGHT]; -int skinwidth; -static pixel_t *skinstart; - void (*d_pdrawspans)(const entity_t *currententity, spanpackage_t *pspanpackage); static void R_PolysetSetEdgeTable(void); @@ -131,29 +127,6 @@ static const byte irtable[256] = { // ====================== -/* -================ -R_PolysetUpdateTables -================ -*/ -void -R_PolysetUpdateTables (void) -{ - byte *s; - - if (r_affinetridesc.skinwidth != skinwidth || - r_affinetridesc.pskin != skinstart) - { - int i; - - skinwidth = r_affinetridesc.skinwidth; - skinstart = r_affinetridesc.pskin; - s = skinstart; - for (i=0 ; i Date: Sat, 6 Jul 2024 16:48:14 +0300 Subject: [PATCH 3/3] soft: scale model texture s,t values ref_gl renders use 0.0..1.0 float texture coordinates in gl commands and skin ratio/resolution could be any. ref_soft render uses absolute coordinates as result textures with different to expected size are applied incorrectly. Fix will not add support of scalled retextured skins, just fix case when ratio is incorrect after scale down such or place a incorrect pcx skin to the model directory. --- src/client/refresh/soft/header/local.h | 2 ++ src/client/refresh/soft/sw_alias.c | 6 +++-- src/client/refresh/soft/sw_polyset.c | 37 ++++++++++++++++++++------ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index da4f6c27..0df50bc3 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -221,6 +221,8 @@ typedef struct pixel_t *pskin; int skinwidth; int skinheight; + float scalewidth; + float scaleheight; } affinetridesc_t; typedef struct diff --git a/src/client/refresh/soft/sw_alias.c b/src/client/refresh/soft/sw_alias.c index 1726cf86..2426c303 100644 --- a/src/client/refresh/soft/sw_alias.c +++ b/src/client/refresh/soft/sw_alias.c @@ -526,8 +526,10 @@ R_AliasSetupSkin(const entity_t *currententity, const model_t *currentmodel) return false; r_affinetridesc.pskin = pskindesc->pixels[0]; - r_affinetridesc.skinwidth = pskindesc->width; - r_affinetridesc.skinheight = pskindesc->height; + r_affinetridesc.skinwidth = pskindesc->asset_width; + r_affinetridesc.skinheight = pskindesc->asset_height; + r_affinetridesc.scalewidth = (float)pskindesc->asset_width / s_pmdl->skinwidth; + r_affinetridesc.scaleheight = (float)pskindesc->asset_height / s_pmdl->skinheight; return true; } diff --git a/src/client/refresh/soft/sw_polyset.c b/src/client/refresh/soft/sw_polyset.c index acfd6a10..a3c8bbe0 100644 --- a/src/client/refresh/soft/sw_polyset.c +++ b/src/client/refresh/soft/sw_polyset.c @@ -273,27 +273,41 @@ FloorDivMod(int numer, int denom, int *quo, int *rem) #if defined(__i386__) || defined(__amd64__) q = numer / denom; r = numer - q * denom; + if (-1/2 || 1/-2 || -1/-2) { // long live C89 if (r < 0 && r < denom) { q += 1; r -= denom; } - } else { + } + else + { // C99 always truncates to 0 - if ((numer ^ denom) < 0 && r != 0) { + if ((numer ^ denom) < 0 && r != 0) + { q -= 1; r += denom; } } + if ((numer < 0) ^ (denom < 0)) + { assert(q <= 0); + } else + { assert(q >= 0); + } + if (denom < 0) + { assert(r > denom && r <= 0); + } else + { assert(r >= 0 && r < denom); + } #else float num = numer, den = denom; float x; @@ -754,8 +768,8 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp } static void -R_ProcessLeftEdge(compactvert_t *plefttop, compactvert_t *prighttop, - compactvert_t *pleftbottom) +R_ProcessLeftEdge(const compactvert_t *plefttop, const compactvert_t *prighttop, + const compactvert_t *pleftbottom) { light3_t working_lstepx; pixel_t *d_ptex; @@ -768,8 +782,8 @@ R_ProcessLeftEdge(compactvert_t *plefttop, compactvert_t *prighttop, v = plefttop->v; d_aspancount = plefttop->u - prighttop->u; - s = plefttop->s; - t = plefttop->t; + s = plefttop->s * r_affinetridesc.scalewidth; + t = plefttop->t * r_affinetridesc.scaleheight; i = (s >> SHIFT16XYZ) + (t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; d_ptex = &r_affinetridesc.pskin[i]; d_sfrac = s & 0xFFFF; @@ -794,7 +808,9 @@ R_ProcessLeftEdge(compactvert_t *plefttop, compactvert_t *prighttop, // ceil (), but plus a little bit) t = ubasestep < 0; for (i = 0; i < 3; i++) + { working_lstepx[i] = r_lstepx[i] - t; + } // base steps for drawers s = r_sstepy + r_sstepx * ubasestep; @@ -805,7 +821,9 @@ R_ProcessLeftEdge(compactvert_t *plefttop, compactvert_t *prighttop, d_tfracbasestep = t & 0xFFFF; for (i = 0; i < 3; i++) + { d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep; + } d_zibasestep = r_zistepy + r_zistepx * ubasestep; @@ -818,7 +836,9 @@ R_ProcessLeftEdge(compactvert_t *plefttop, compactvert_t *prighttop, d_tfracextrastep = t & 0xFFFF; for (i = 0; i < 3; i++) + { d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i]; + } d_ziextrastep = d_zibasestep + r_zistepx; @@ -833,7 +853,8 @@ R_RasterizeAliasPolySmooth static void R_RasterizeAliasPolySmooth(const entity_t *currententity) { - compactvert_t *plefttop, *prighttop, *pleftbottom, *prightbottom; + const compactvert_t *pleftbottom, *prightbottom; + const compactvert_t *plefttop, *prighttop; spanpackage_t *pstart; int originalcount; int leftheight, rightheight; @@ -924,7 +945,7 @@ R_PolysetSetEdgeTable ================ */ static void -R_PolysetSetEdgeTable (void) +R_PolysetSetEdgeTable(void) { int edgetableindex;