From a06c0703a7a284562515714ddca62b3be6442485 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 22 Jun 2024 14:05:14 +0300 Subject: [PATCH] renders: share palette load by refimport_t --- src/client/header/client.h | 2 + src/client/refresh/files/pcx.c | 242 ---------------------------- src/client/refresh/gl1/gl1_main.c | 4 +- src/client/refresh/gl3/gl3_main.c | 2 +- src/client/refresh/gl4/gl4_main.c | 2 +- src/client/refresh/ref_shared.h | 2 - src/client/refresh/soft/sw_image.c | 4 +- src/client/refresh/vk/vk_image.c | 2 +- src/client/vid/header/ref.h | 2 + src/client/vid/image.c | 250 ++++++++++++++++++++++++++++- src/client/vid/vid.c | 2 + 11 files changed, 261 insertions(+), 253 deletions(-) diff --git a/src/client/header/client.h b/src/client/header/client.h index 28bfc3f1..a42aa24b 100644 --- a/src/client/header/client.h +++ b/src/client/header/client.h @@ -510,6 +510,8 @@ void V_AddLight (vec3_t org, float intensity, float r, float g, float b); void V_AddLightStyle (int style, float r, float g, float b); void VID_ImageDecode(const char *filename, byte **pic, byte **palette, int *width, int *height, int *bytesPerPixel); +void VID_GetPalette(byte **colormap, unsigned *d_8to24table); +void VID_GetPalette24to8(const byte *d_8to24table, byte** d_16to8table); void CL_RegisterTEntSounds (void); void CL_RegisterTEntModels (void); diff --git a/src/client/refresh/files/pcx.c b/src/client/refresh/files/pcx.c index c82f90d8..be41eab4 100644 --- a/src/client/refresh/files/pcx.c +++ b/src/client/refresh/files/pcx.c @@ -74,245 +74,3 @@ GetPCXInfo(const char *origname, int *width, int *height) return; } - -static byte -Convert24to8(const byte *d_8to24table, const int rgb[3]) -{ - int i, best, diff; - - best = 255; - diff = 1 << 20; - - for (i = 0; i < 256; i ++) - { - int j, curr_diff; - - curr_diff = 0; - - for (j = 0; j < 3; j++) - { - int v; - - v = d_8to24table[i * 4 + j] - rgb[j]; - curr_diff += v * v; - } - - if (curr_diff < diff) - { - diff = curr_diff; - best = i; - } - } - - return best; -} - -static void -GenerateColormap(const byte *palette, byte *out_colormap) -{ - // https://quakewiki.org/wiki/Quake_palette - int num_fullbrights = 32; /* the last 32 colours will be full bright */ - int x; - - for (x = 0; x < 256; x++) - { - int y; - - for (y = 0; y < 64; y++) - { - if (x < 256 - num_fullbrights) - { - int rgb[3], i; - - for (i = 0; i < 3; i++) - { - /* divide by 32, rounding to nearest integer */ - rgb[i] = (palette[x * 4 + i] * (63 - y) + 16) >> 5; - if (rgb[i] > 255) - { - rgb[i] = 255; - } - } - - out_colormap[y*256+x] = Convert24to8(palette, rgb); - } - else - { - /* this colour is a fullbright, just keep the original colour */ - out_colormap[y*256+x] = x; - } - } - } -} - -void -GetPCXPalette24to8(const byte *d_8to24table, byte** d_16to8table) -{ - unsigned char * table16to8; - char tablefile[] = "pics/16to8.dat"; - - *d_16to8table = NULL; - ri.FS_LoadFile(tablefile, (void **)&table16to8); - - if (!table16to8) - { - R_Printf(PRINT_ALL, "%s: Couldn't load %s\n", __func__, tablefile); - } - - *d_16to8table = malloc(0x10000); - if (!(*d_16to8table)) - { - Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for d_16to8table", __func__); - /* code never returns after ERR_FATAL */ - return; - } - - if (table16to8) - { - // Use predefined convert map - memcpy(*d_16to8table, table16to8, 0x10000); - ri.FS_FreeFile((void *)table16to8); - } - else - { - // create new one - unsigned int r; - - R_Printf(PRINT_ALL, "%s: Generate 16 to 8 bit table\n", __func__); - - for (r = 0; r < 32; r++) - { - int g; - - for (g = 0; g < 64; g++) - { - int b; - - for (b = 0; b < 32; b++) - { - int c, rgb[3]; - - rgb[0] = r << 3; - rgb[1] = g << 2; - rgb[2] = b << 3; - - c = r | ( g << 5 ) | ( b << 11 ); - - // set color with minimal difference - (*d_16to8table)[c & 0xFFFF] = Convert24to8(d_8to24table, rgb); - } - } - } - } -} - -/* -=============== -GetPCXPalette -=============== -*/ -void -GetPCXPalette(byte **colormap, unsigned *d_8to24table) -{ - char filename[] = "pics/colormap.pcx"; - byte *pal; - - /* get the palette and colormap */ - LoadPCX(filename, colormap, &pal, NULL, NULL); - if (!*colormap || !pal) - { - int width = 0, height = 0; - byte *pic = NULL; - - if (LoadSTB("pics/colormap", "bmp", &pic, &width, &height) && - width == 256 && height == 320) - { - int i; - - memcpy(d_8to24table, pic, 256 * 4); - d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */ - - /* generate colormap */ - *colormap = malloc(256 * 320); - if (!(*colormap)) - { - Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for colormap", __func__); - /* code never returns after ERR_FATAL */ - return; - } - - for (i = 0; i < (256 * 320); i ++) - { - int j, rgb[3]; - - for(j = 0; j < 3; j++) - { - rgb[j] = pic[i * 4 + j]; - } - (*colormap)[i] = Convert24to8((byte *)d_8to24table, rgb); - } - - free(pic); - return; - } - - if (pic) - { - free(pic); - } - } - - if (!*colormap || !pal) - { - int i; - - R_Printf(PRINT_ALL, "%s: Couldn't load %s, use generated palette\n", - __func__, filename); - - /* palette r:2bit, g:3bit, b:3bit */ - for (i = 0; i < 256; i++) - { - unsigned v; - - v = (255U<<24) + (((i >> 0) & 0x3) << (6 + 0)) + - (((i >> 2) & 0x7) << (5 + 8)) + - (((i >> 5) & 0x7) << (5 + 16)); - d_8to24table[i] = LittleLong(v); - } - - d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */ - - /* generate colormap */ - *colormap = malloc(256 * 320); - if (!(*colormap)) - { - Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for colormap", __func__); - /* code never returns after ERR_FATAL */ - return; - } - - GenerateColormap((const byte *)d_8to24table, *colormap); - return; - } - else - { - int i; - - for (i = 0; i < 256; i++) - { - unsigned v; - int r, g, b; - - r = pal[i*3+0]; - g = pal[i*3+1]; - b = pal[i*3+2]; - - v = (255U<<24) + (r<<0) + (g<<8) + (b<<16); - d_8to24table[i] = LittleLong(v); - } - - d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent - - free(pal); - } -} diff --git a/src/client/refresh/gl1/gl1_main.c b/src/client/refresh/gl1/gl1_main.c index c71777cf..f9576d45 100644 --- a/src/client/refresh/gl1/gl1_main.c +++ b/src/client/refresh/gl1/gl1_main.c @@ -1434,8 +1434,8 @@ RI_Init(void) R_Printf(PRINT_ALL, "ref_gl1::R_Init() - DEBUG mode enabled\n"); #endif - GetPCXPalette(&colormap, d_8to24table); - GetPCXPalette24to8((byte *)d_8to24table, &gl_state.d_16to8table); + ri.VID_GetPalette(&colormap, d_8to24table); + ri.VID_GetPalette24to8((byte *)d_8to24table, &gl_state.d_16to8table); free(colormap); R_Register(); diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 164c3079..4acc34ee 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -502,7 +502,7 @@ GL3_Init(void) return false; } - GetPCXPalette(&colormap, d_8to24table); + ri.VID_GetPalette(&colormap, d_8to24table); free(colormap); GL3_Register(); diff --git a/src/client/refresh/gl4/gl4_main.c b/src/client/refresh/gl4/gl4_main.c index de563903..931ad990 100644 --- a/src/client/refresh/gl4/gl4_main.c +++ b/src/client/refresh/gl4/gl4_main.c @@ -498,7 +498,7 @@ GL4_Init(void) return false; } - GetPCXPalette (&colormap, d_8to24table); + ri.VID_GetPalette(&colormap, d_8to24table); free(colormap); GL4_Register(); diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index 29bca151..26219c6c 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -105,8 +105,6 @@ extern struct image_s* LoadM32(const char *origname, const char *namewe, imagety extern struct image_s* LoadSWL(const char *origname, const char *namewe, imagetype_t type, loadimage_t load_image); extern void FixFileExt(const char *origname, const char *ext, char *filename, size_t size); -extern void GetPCXPalette(byte **colormap, unsigned *d_8to24table); -extern void GetPCXPalette24to8(const byte *d_8to24table, byte** d_16to8table); extern void LoadPCX(const char *origname, byte **pic, byte **palette, int *width, int *height); extern void GetPCXInfo(const char *origname, int *width, int *height); extern void GetWalInfo(const char *name, int *width, int *height); diff --git a/src/client/refresh/soft/sw_image.c b/src/client/refresh/soft/sw_image.c index 1f054128..796ca1f3 100644 --- a/src/client/refresh/soft/sw_image.c +++ b/src/client/refresh/soft/sw_image.c @@ -707,8 +707,8 @@ R_InitImages (void) registration_sequence = 1; image_max = 0; - GetPCXPalette(&vid_colormap, (unsigned *)d_8to24table); - GetPCXPalette24to8(d_8to24table, &d_16to8table); + ri.VID_GetPalette(&vid_colormap, (unsigned *)d_8to24table); + ri.VID_GetPalette24to8(d_8to24table, &d_16to8table); vid_alphamap = vid_colormap + 64*256; R_InitTextures (); } diff --git a/src/client/refresh/vk/vk_image.c b/src/client/refresh/vk/vk_image.c index ca4730b9..404f96c6 100644 --- a/src/client/refresh/vk/vk_image.c +++ b/src/client/refresh/vk/vk_image.c @@ -1378,7 +1378,7 @@ void Vk_InitImages (void) intensitytable[i] = j; } - GetPCXPalette (&colormap, d_8to24table); + ri.VID_GetPalette(&colormap, d_8to24table); free(colormap); overbright = vk_overbrightbits->value; diff --git a/src/client/vid/header/ref.h b/src/client/vid/header/ref.h index 3682cb05..e6a0ae97 100644 --- a/src/client/vid/header/ref.h +++ b/src/client/vid/header/ref.h @@ -256,6 +256,8 @@ typedef struct /* load image from file */ void (IMPORT *VID_ImageDecode)( const char *filename, byte **pic, byte **palette, int *width, int *height, int *bytesPerPixel); + void (IMPORT *VID_GetPalette)(byte **colormap, unsigned *d_8to24table); + void (IMPORT *VID_GetPalette24to8)(const byte *d_8to24table, byte** d_16to8table); qboolean (IMPORT *GLimp_InitGraphics)(int fullscreen, int *pwidth, int *pheight); qboolean (IMPORT *GLimp_GetDesktopMode)(int *pwidth, int *pheight); diff --git a/src/client/vid/image.c b/src/client/vid/image.c index 2b72c537..0692520e 100644 --- a/src/client/vid/image.c +++ b/src/client/vid/image.c @@ -220,7 +220,6 @@ PCX_Decode(const byte *raw, int len, byte **pic, byte **palette, } } - void VID_ImageDecode(const char *filename, byte **pic, byte **palette, int *width, int *height, int *bytesPerPixel) @@ -258,7 +257,6 @@ VID_ImageDecode(const char *filename, byte **pic, byte **palette, // so fix it fixQuitScreen(*pic); } - } else { @@ -284,3 +282,251 @@ VID_ImageDecode(const char *filename, byte **pic, byte **palette, FS_FreeFile(raw); } + +static byte +Convert24to8(const byte *d_8to24table, const int rgb[3]) +{ + int i, best, diff; + + best = 255; + diff = 1 << 20; + + for (i = 0; i < 256; i ++) + { + int j, curr_diff; + + curr_diff = 0; + + for (j = 0; j < 3; j++) + { + int v; + + v = d_8to24table[i * 4 + j] - rgb[j]; + curr_diff += v * v; + } + + if (curr_diff < diff) + { + diff = curr_diff; + best = i; + } + } + + return best; +} + +static void +GenerateColormap(const byte *palette, byte *out_colormap) +{ + // https://quakewiki.org/wiki/Quake_palette + int num_fullbrights = 32; /* the last 32 colours will be full bright */ + int x; + + for (x = 0; x < 256; x++) + { + int y; + + for (y = 0; y < 64; y++) + { + if (x < 256 - num_fullbrights) + { + int rgb[3], i; + + for (i = 0; i < 3; i++) + { + /* divide by 32, rounding to nearest integer */ + rgb[i] = (palette[x * 4 + i] * (63 - y) + 16) >> 5; + if (rgb[i] > 255) + { + rgb[i] = 255; + } + } + + out_colormap[y*256+x] = Convert24to8(palette, rgb); + } + else + { + /* this colour is a fullbright, just keep the original colour */ + out_colormap[y*256+x] = x; + } + } + } +} + +/* +=============== +VID_GetPalette +=============== +*/ +void +VID_GetPalette(byte **colormap, unsigned *d_8to24table) +{ + const char * filename; + int bytesPerPixel; + byte *pal = NULL; + + filename = "pics/colormap.pcx"; + + /* get the palette and colormap */ + VID_ImageDecode(filename, colormap, &pal, NULL, NULL, + &bytesPerPixel); + if (!*colormap || !pal) + { + int width = 0, height = 0; + byte *pic = NULL; + + filename = "pics/colormap.bmp"; + + VID_ImageDecode(filename, &pic, NULL, &width, &height, &bytesPerPixel); + if (pic && width == 256 && height == 320) + { + int i; + + memcpy(d_8to24table, pic, 256 * 4); + d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */ + + /* generate colormap */ + *colormap = malloc(256 * 320); + if (!(*colormap)) + { + Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for colormap", __func__); + /* code never returns after ERR_FATAL */ + return; + } + + for (i = 0; i < (256 * 320); i ++) + { + int j, rgb[3]; + + for(j = 0; j < 3; j++) + { + rgb[j] = pic[i * 4 + j]; + } + (*colormap)[i] = Convert24to8((byte *)d_8to24table, rgb); + } + + free(pic); + return; + } + + if (pic) + { + free(pic); + } + } + + if (!*colormap || !pal) + { + int i; + + Com_Printf("%s: Couldn't load %s, use generated palette\n", + __func__, filename); + + /* palette r:2bit, g:3bit, b:3bit */ + for (i = 0; i < 256; i++) + { + unsigned v; + + v = (255U<<24) + (((i >> 0) & 0x3) << (6 + 0)) + + (((i >> 2) & 0x7) << (5 + 8)) + + (((i >> 5) & 0x7) << (5 + 16)); + d_8to24table[i] = LittleLong(v); + } + + d_8to24table[255] &= LittleLong(0xffffff); /* 255 is transparent */ + + /* generate colormap */ + *colormap = malloc(256 * 320); + if (!(*colormap)) + { + Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for colormap", __func__); + /* code never returns after ERR_FATAL */ + return; + } + + GenerateColormap((const byte *)d_8to24table, *colormap); + return; + } + else + { + int i; + + for (i = 0; i < 256; i++) + { + unsigned v; + int r, g, b; + + r = pal[i*3+0]; + g = pal[i*3+1]; + b = pal[i*3+2]; + + v = (255U<<24) + (r<<0) + (g<<8) + (b<<16); + d_8to24table[i] = LittleLong(v); + } + + d_8to24table[255] &= LittleLong(0xffffff); // 255 is transparent + + free(pal); + } +} + +void +VID_GetPalette24to8(const byte *d_8to24table, byte** d_16to8table) +{ + unsigned char * table16to8; + const char tablefile[] = "pics/16to8.dat"; + + *d_16to8table = NULL; + FS_LoadFile(tablefile, (void **)&table16to8); + + if (!table16to8) + { + Com_Printf("%s: Couldn't load %s\n", __func__, tablefile); + } + + *d_16to8table = malloc(0x10000); + if (!(*d_16to8table)) + { + Com_Error(ERR_FATAL, "%s: Couldn't allocate memory for d_16to8table", __func__); + /* code never returns after ERR_FATAL */ + return; + } + + if (table16to8) + { + // Use predefined convert map + memcpy(*d_16to8table, table16to8, 0x10000); + FS_FreeFile((void *)table16to8); + } + else + { + // create new one + unsigned int r; + + Com_Printf("%s: Generate 16 to 8 bit table\n", __func__); + + for (r = 0; r < 32; r++) + { + int g; + + for (g = 0; g < 64; g++) + { + int b; + + for (b = 0; b < 32; b++) + { + int c, rgb[3]; + + rgb[0] = r << 3; + rgb[1] = g << 2; + rgb[2] = b << 3; + + c = r | ( g << 5 ) | ( b << 11 ); + + // set color with minimal difference + (*d_16to8table)[c & 0xFFFF] = Convert24to8(d_8to24table, rgb); + } + } + } + } +} diff --git a/src/client/vid/vid.c b/src/client/vid/vid.c index 3c445010..eec94a38 100644 --- a/src/client/vid/vid.c +++ b/src/client/vid/vid.c @@ -448,6 +448,8 @@ VID_LoadRenderer(void) ri.Vid_MenuInit = VID_MenuInit; ri.Vid_WriteScreenshot = VID_WriteScreenshot; ri.VID_ImageDecode = VID_ImageDecode; + ri.VID_GetPalette = VID_GetPalette; + ri.VID_GetPalette24to8 = VID_GetPalette24to8; ri.Vid_RequestRestart = VID_RequestRestart; // Exchange our export struct with the renderers import struct.