-static rtexture_t *GL_TextureForSkinLayer(const unsigned char *in, int width, int height, const char *name, const unsigned int *palette, int textureflags, qboolean force)
-{
- int i;
- if (!force)
- {
- for (i = 0;i < width*height;i++)
- if (((unsigned char *)&palette[in[i]])[3] > 0)
- break;
- if (i == width*height)
- return NULL;
- }
- return R_LoadTexture2D (loadmodel->texturepool, name, width, height, in, TEXTYPE_PALETTE, textureflags, palette);
-}
-
-typedef struct imageskin_s
-{
- unsigned char *basepixels;int basepixels_width;int basepixels_height;
- unsigned char *nmappixels;int nmappixels_width;int nmappixels_height;
- unsigned char *glowpixels;int glowpixels_width;int glowpixels_height;
- unsigned char *glosspixels;int glosspixels_width;int glosspixels_height;
- unsigned char *pantspixels;int pantspixels_width;int pantspixels_height;
- unsigned char *shirtpixels;int shirtpixels_width;int shirtpixels_height;
- unsigned char *maskpixels;int maskpixels_width;int maskpixels_height;
-}
-imageskin_t;
-
-int Mod_LoadSkinFrame(skinframe_t *skinframe, const char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture)
-{
- int j;
- imageskin_t s;
- char name[MAX_QPATH];
- memset(&s, 0, sizeof(s));
- memset(skinframe, 0, sizeof(*skinframe));
- Image_StripImageExtension(basename, name, sizeof(name));
- skinframe->base = r_texture_notexture;
- if (cls.state == ca_dedicated)
- return false;
-
- s.basepixels = loadimagepixels(name, false, 0, 0);
- if (s.basepixels == NULL)
- return false;
- s.basepixels_width = image_width;
- s.basepixels_height = image_height;
-
- for (j = 3;j < s.basepixels_width * s.basepixels_height * 4;j += 4)
- if (s.basepixels[j] < 255)
- break;
- if (j < s.basepixels_width * s.basepixels_height * 4)
- {
- // has transparent pixels
- s.maskpixels = (unsigned char *)Mem_Alloc(loadmodel->mempool, s.basepixels_width * s.basepixels_height * 4);
- s.maskpixels_width = s.basepixels_width;
- s.maskpixels_height = s.basepixels_height;
- memcpy(s.maskpixels, s.basepixels, s.maskpixels_width * s.maskpixels_height * 4);
- for (j = 0;j < s.basepixels_width * s.basepixels_height * 4;j += 4)
- {
- s.maskpixels[j+0] = 255;
- s.maskpixels[j+1] = 255;
- s.maskpixels[j+2] = 255;
- }
- }
-
- // _luma is supported for tenebrae compatibility
- // (I think it's a very stupid name, but oh well)
- if ((s.glowpixels = loadimagepixels(va("%s_glow", name), false, 0, 0)) != NULL
- || (s.glowpixels = loadimagepixels(va("%s_luma", name), false, 0, 0)) != NULL)
- {
- s.glowpixels_width = image_width;
- s.glowpixels_height = image_height;
- }
- // _norm is the name used by tenebrae
- // (I don't like the name much)
- if ((s.nmappixels = loadimagepixels(va("%s_norm", name), false, 0, 0)) != NULL)
- {
- s.nmappixels_width = image_width;
- s.nmappixels_height = image_height;
- }
- else
- {
- unsigned char *bumppixels;
- if ((bumppixels = loadimagepixels(va("%s_bump", name), false, 0, 0)) != NULL)
- {
- if (r_shadow_bumpscale_bumpmap.value > 0)
- {
- s.nmappixels = (unsigned char *)Mem_Alloc(loadmodel->mempool, image_width * image_height * 4);
- s.nmappixels_width = image_width;
- s.nmappixels_height = image_height;
- Image_HeightmapToNormalmap(bumppixels, s.nmappixels, s.nmappixels_width, s.nmappixels_height, false, r_shadow_bumpscale_bumpmap.value);
- }
- Mem_Free(bumppixels);
- }
- else
- {
- if (r_shadow_bumpscale_basetexture.value > 0)
- {
- s.nmappixels = (unsigned char *)Mem_Alloc(loadmodel->mempool, s.basepixels_width * s.basepixels_height * 4);
- s.nmappixels_width = s.basepixels_width;
- s.nmappixels_height = s.basepixels_height;
- Image_HeightmapToNormalmap(s.basepixels, s.nmappixels, s.nmappixels_width, s.nmappixels_height, false, r_shadow_bumpscale_basetexture.value);
- }
- }
- }
- if ((s.glosspixels = loadimagepixels(va("%s_gloss", name), false, 0, 0)) != NULL)
- {
- s.glosspixels_width = image_width;
- s.glosspixels_height = image_height;
- }
- if ((s.pantspixels = loadimagepixels(va("%s_pants", name), false, 0, 0)) != NULL)
- {
- s.pantspixels_width = image_width;
- s.pantspixels_height = image_height;
- }
- if ((s.shirtpixels = loadimagepixels(va("%s_shirt", name), false, 0, 0)) != NULL)
- {
- s.shirtpixels_width = image_width;
- s.shirtpixels_height = image_height;
- }
-
- skinframe->base = R_LoadTexture2D (loadmodel->texturepool, basename, s.basepixels_width, s.basepixels_height, s.basepixels, TEXTYPE_RGBA, textureflags, NULL);
- if (s.nmappixels != NULL)
- skinframe->nmap = R_LoadTexture2D (loadmodel->texturepool, va("%s_nmap", basename), s.nmappixels_width, s.nmappixels_height, s.nmappixels, TEXTYPE_RGBA, textureflags, NULL);
- if (s.glosspixels != NULL)
- skinframe->gloss = R_LoadTexture2D (loadmodel->texturepool, va("%s_gloss", basename), s.glosspixels_width, s.glosspixels_height, s.glosspixels, TEXTYPE_RGBA, textureflags, NULL);
- if (s.glowpixels != NULL && loadglowtexture)
- skinframe->glow = R_LoadTexture2D (loadmodel->texturepool, va("%s_glow", basename), s.glowpixels_width, s.glowpixels_height, s.glowpixels, TEXTYPE_RGBA, textureflags, NULL);
- if (s.maskpixels != NULL)
- skinframe->fog = R_LoadTexture2D (loadmodel->texturepool, va("%s_mask", basename), s.maskpixels_width, s.maskpixels_height, s.maskpixels, TEXTYPE_RGBA, textureflags, NULL);
- if (loadpantsandshirt)
- {
- if (s.pantspixels != NULL)
- skinframe->pants = R_LoadTexture2D (loadmodel->texturepool, va("%s_pants", basename), s.pantspixels_width, s.pantspixels_height, s.pantspixels, TEXTYPE_RGBA, textureflags, NULL);
- if (s.shirtpixels != NULL)
- skinframe->shirt = R_LoadTexture2D (loadmodel->texturepool, va("%s_shirt", basename), s.shirtpixels_width, s.shirtpixels_height, s.shirtpixels, TEXTYPE_RGBA, textureflags, NULL);
- }
- if (!skinframe->base)
- skinframe->base = r_texture_notexture;
- if (!skinframe->nmap)
- skinframe->nmap = r_texture_blanknormalmap;
-
- if (s.basepixels)
- Mem_Free(s.basepixels);
- if (s.maskpixels)
- Mem_Free(s.maskpixels);
- if (s.nmappixels)
- Mem_Free(s.nmappixels);
- if (s.glowpixels)
- Mem_Free(s.glowpixels);
- if (s.glosspixels)
- Mem_Free(s.glosspixels);
- if (s.pantspixels)
- Mem_Free(s.pantspixels);
- if (s.shirtpixels)
- Mem_Free(s.shirtpixels);
-
- return true;
-}
-
-int Mod_LoadSkinFrame_Internal(skinframe_t *skinframe, const char *basename, int textureflags, int loadpantsandshirt, int loadglowtexture, const unsigned char *skindata, int width, int height, int bitsperpixel, const unsigned int *palette, const unsigned int *alphapalette)
-{
- int i;
- unsigned char *temp1, *temp2;
- memset(skinframe, 0, sizeof(*skinframe));
- if (cls.state == ca_dedicated)
- return false;
- if (!skindata)
- return false;
- if (bitsperpixel == 32)
- {
- if (r_shadow_bumpscale_basetexture.value > 0)
- {
- temp1 = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 8);
- temp2 = temp1 + width * height * 4;
- Image_HeightmapToNormalmap(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, textureflags | TEXF_ALPHA, NULL);
- Mem_Free(temp1);
- }
- skinframe->base = skinframe->merged = R_LoadTexture2D(loadmodel->texturepool, basename, width, height, skindata, TEXTYPE_RGBA, textureflags, NULL);
- if (textureflags & TEXF_ALPHA)
- {
- for (i = 3;i < width * height * 4;i += 4)
- if (skindata[i] < 255)
- break;
- if (i < width * height * 4)
- {
- unsigned char *fogpixels = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 4);
- memcpy(fogpixels, skindata, width * height * 4);
- for (i = 0;i < width * height * 4;i += 4)
- fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
- skinframe->fog = R_LoadTexture2D(loadmodel->texturepool, va("%s_fog", basename), width, height, fogpixels, TEXTYPE_RGBA, textureflags, NULL);
- Mem_Free(fogpixels);
- }
- }
- }
- else if (bitsperpixel == 8)
- {
- if (r_shadow_bumpscale_basetexture.value > 0)
- {
- temp1 = (unsigned char *)Mem_Alloc(loadmodel->mempool, width * height * 8);
- temp2 = temp1 + width * height * 4;
- if (bitsperpixel == 32)
- Image_HeightmapToNormalmap(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- else
- {
- // use either a custom palette or the quake palette
- Image_Copy8bitRGBA(skindata, temp1, width * height, palette ? palette : palette_complete);
- Image_HeightmapToNormalmap(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
- }
- skinframe->nmap = R_LoadTexture2D(loadmodel->texturepool, va("%s_nmap", basename), width, height, temp2, TEXTYPE_RGBA, textureflags | TEXF_ALPHA, NULL);
- Mem_Free(temp1);
- }
- // use either a custom palette, or the quake palette
- skinframe->base = skinframe->merged = GL_TextureForSkinLayer(skindata, width, height, va("%s_merged", basename), palette ? palette : (loadglowtexture ? palette_nofullbrights : ((textureflags & TEXF_ALPHA) ? palette_transparent : palette_complete)), textureflags, true); // all
- if (!palette && loadglowtexture)
- skinframe->glow = GL_TextureForSkinLayer(skindata, width, height, va("%s_glow", basename), palette_onlyfullbrights, textureflags, false); // glow
- if (!palette && loadpantsandshirt)
- {
- skinframe->pants = GL_TextureForSkinLayer(skindata, width, height, va("%s_pants", basename), palette_pantsaswhite, textureflags, false); // pants
- skinframe->shirt = GL_TextureForSkinLayer(skindata, width, height, va("%s_shirt", basename), palette_shirtaswhite, textureflags, false); // shirt
- }
- if (skinframe->pants || skinframe->shirt)
- skinframe->base = GL_TextureForSkinLayer(skindata, width, height, va("%s_nospecial", basename),loadglowtexture ? palette_nocolormapnofullbrights : palette_nocolormap, textureflags, false); // no special colors
- if (textureflags & TEXF_ALPHA)
- {
- // if not using a custom alphapalette, use the quake one
- if (!alphapalette)
- alphapalette = palette_alpha;
- for (i = 0;i < width * height;i++)
- if (((unsigned char *)alphapalette)[skindata[i]*4+3] < 255)
- break;
- if (i < width * height)
- skinframe->fog = GL_TextureForSkinLayer(skindata, width, height, va("%s_fog", basename), alphapalette, textureflags, true); // fog mask
- }
- }
- else
- return false;
- if (!skinframe->nmap)
- skinframe->nmap = r_texture_blanknormalmap;
- return true;
-}
-