846 lines
15 KiB
C++
846 lines
15 KiB
C++
/***
|
|
*
|
|
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
|
*
|
|
* This product contains software technology licensed from Id
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
****/
|
|
|
|
#include "qlumpy.h"
|
|
#include "math.h"
|
|
|
|
#pragma warning(disable : 4244)
|
|
|
|
typedef struct
|
|
{
|
|
short ofs, length;
|
|
} row_t;
|
|
|
|
typedef struct
|
|
{
|
|
int width, height;
|
|
int widthbits, heightbits;
|
|
unsigned char data[4];
|
|
} qtex_t;
|
|
|
|
typedef struct
|
|
{
|
|
int width, height;
|
|
byte data[4]; // variably sized
|
|
} qpic_t;
|
|
|
|
|
|
// Font stuff
|
|
|
|
#define NUM_GLYPHS 256
|
|
const unsigned kFontMarker = 254;
|
|
|
|
typedef struct
|
|
{
|
|
short startoffset;
|
|
short charwidth;
|
|
} charinfo;
|
|
|
|
typedef struct
|
|
{
|
|
int width, height;
|
|
int rowcount;
|
|
int rowheight;
|
|
charinfo fontinfo[NUM_GLYPHS];
|
|
byte data[4];
|
|
} qfont_t;
|
|
|
|
|
|
extern qboolean fTransparent255;
|
|
|
|
|
|
#define SCRN(x, y) (*(byteimage + (y)*byteimagewidth + x))
|
|
|
|
void GrabPalette16(void);
|
|
|
|
extern qboolean do16bit;
|
|
|
|
/*
|
|
==============
|
|
GrabRaw
|
|
|
|
filename RAW x y width height
|
|
==============
|
|
*/
|
|
void GrabRaw(void)
|
|
{
|
|
int x, y, xl, yl, xh, yh, w, h;
|
|
byte* screen_p;
|
|
int linedelta;
|
|
|
|
GetToken(false);
|
|
xl = atoi(token);
|
|
GetToken(false);
|
|
yl = atoi(token);
|
|
GetToken(false);
|
|
w = atoi(token);
|
|
GetToken(false);
|
|
h = atoi(token);
|
|
|
|
if (xl == -1)
|
|
{
|
|
xl = yl = 0;
|
|
w = byteimagewidth;
|
|
h = byteimageheight;
|
|
}
|
|
|
|
xh = xl + w;
|
|
yh = yl + h;
|
|
|
|
screen_p = byteimage + yl * byteimagewidth + xl;
|
|
linedelta = byteimagewidth - w;
|
|
|
|
for (y = yl; y < yh; y++)
|
|
{
|
|
for (x = xl; x < xh; x++)
|
|
{
|
|
*lump_p++ = *screen_p;
|
|
*screen_p++ = 0;
|
|
}
|
|
screen_p += linedelta;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
==============
|
|
GrabPalette
|
|
|
|
filename PALETTE [startcolor endcolor]
|
|
==============
|
|
*/
|
|
void GrabPalette(void)
|
|
{
|
|
int start, end, length;
|
|
|
|
if (TokenAvailable())
|
|
{
|
|
GetToken(false);
|
|
start = atoi(token);
|
|
GetToken(false);
|
|
end = atoi(token);
|
|
}
|
|
else
|
|
{
|
|
start = 0;
|
|
end = 255;
|
|
}
|
|
|
|
length = 3 * (end - start + 1);
|
|
memcpy(lump_p, lbmpalette + start * 3, length);
|
|
lump_p += length;
|
|
}
|
|
|
|
|
|
/*
|
|
==============
|
|
GrabPic
|
|
|
|
filename qpic x y width height
|
|
==============
|
|
*/
|
|
void GrabPic(void)
|
|
{
|
|
int x, y, xl, yl, xh, yh;
|
|
int width;
|
|
qpic_t* header;
|
|
|
|
GetToken(false);
|
|
xl = atoi(token);
|
|
GetToken(false);
|
|
yl = atoi(token);
|
|
GetToken(false);
|
|
xh = xl + atoi(token);
|
|
GetToken(false);
|
|
yh = yl + atoi(token);
|
|
|
|
if (xl == -1)
|
|
{
|
|
xl = yl = 0;
|
|
xh = byteimagewidth;
|
|
yh = byteimageheight;
|
|
}
|
|
|
|
if (xh < xl || yh < yl || xl < 0 || yl < 0) // || xh>319 || yh>239)
|
|
Error("GrabPic: Bad size: %i, %i, %i, %i", xl, yl, xh, yh);
|
|
|
|
//
|
|
// fill in header
|
|
//
|
|
header = (qpic_t*)lump_p;
|
|
width = xh - xl;
|
|
header->width = LittleLong(width);
|
|
header->height = LittleLong(yh - yl);
|
|
|
|
//
|
|
// start grabbing posts
|
|
//
|
|
lump_p = (byte*)header->data;
|
|
|
|
for (y = yl; y < yh; y++)
|
|
for (x = xl; x < xh; x++)
|
|
*lump_p++ = SCRN(x, y);
|
|
|
|
// New for 16bpp display
|
|
if (do16bit)
|
|
GrabPalette16();
|
|
}
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
COLORMAP GRABBING
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
/*
|
|
===============
|
|
BestColor
|
|
===============
|
|
*/
|
|
byte BestColor(int r, int g, int b, int start, int stop)
|
|
{
|
|
int i;
|
|
int dr, dg, db;
|
|
int bestdistortion, distortion;
|
|
int bestcolor;
|
|
byte* pal;
|
|
|
|
//
|
|
// let any color go to 0 as a last resort
|
|
//
|
|
bestdistortion = ((int)r * r + (int)g * g + (int)b * b) * 2;
|
|
bestcolor = 0;
|
|
|
|
pal = lbmpalette + start * 3;
|
|
for (i = start; i <= stop; i++)
|
|
{
|
|
dr = r - (int)pal[0];
|
|
dg = g - (int)pal[1];
|
|
db = b - (int)pal[2];
|
|
pal += 3;
|
|
distortion = dr * dr + dg * dg + db * db;
|
|
if (distortion < bestdistortion)
|
|
{
|
|
if (!distortion)
|
|
return i; // perfect match
|
|
|
|
bestdistortion = distortion;
|
|
bestcolor = i;
|
|
}
|
|
}
|
|
|
|
return bestcolor;
|
|
}
|
|
|
|
|
|
/*
|
|
==============
|
|
GrabColormap
|
|
|
|
filename COLORMAP levels fullbrights
|
|
the first map is an identiy 0-255
|
|
the final map is all black except for the fullbrights
|
|
the remaining maps are evenly spread
|
|
fullbright colors start at the top of the palette.
|
|
==============
|
|
*/
|
|
void GrabColormap(void)
|
|
{
|
|
int levels, brights;
|
|
int l, c;
|
|
float frac, red, green, blue;
|
|
|
|
GetToken(false);
|
|
levels = atoi(token);
|
|
GetToken(false);
|
|
brights = atoi(token);
|
|
|
|
// identity lump
|
|
for (l = 0; l < 256; l++)
|
|
*lump_p++ = l;
|
|
|
|
// shaded levels
|
|
for (l = 1; l < levels; l++)
|
|
{
|
|
frac = 1.0 - (float)l / (levels - 1);
|
|
for (c = 0; c < 256 - brights; c++)
|
|
{
|
|
red = lbmpalette[c * 3];
|
|
green = lbmpalette[c * 3 + 1];
|
|
blue = lbmpalette[c * 3 + 2];
|
|
|
|
red = (int)(red * frac + 0.5);
|
|
green = (int)(green * frac + 0.5);
|
|
blue = (int)(blue * frac + 0.5);
|
|
|
|
//
|
|
// note: 254 instead of 255 because 255 is the transparent color, and we
|
|
// don't want anything remapping to that
|
|
//
|
|
*lump_p++ = BestColor(red, green, blue, 0, 254);
|
|
}
|
|
for (; c < 256; c++)
|
|
*lump_p++ = c;
|
|
}
|
|
|
|
*lump_p++ = brights;
|
|
}
|
|
|
|
/*
|
|
==============
|
|
GrabColormap2
|
|
|
|
experimental -- not used by quake
|
|
|
|
filename COLORMAP2 range levels fullbrights
|
|
fullbright colors start at the top of the palette.
|
|
Range can be greater than 1 to allow overbright color tables.
|
|
|
|
the first map is all 0
|
|
the last (levels-1) map is at range
|
|
==============
|
|
*/
|
|
void GrabColormap2(void)
|
|
{
|
|
int levels, brights;
|
|
int l, c;
|
|
float frac, red, green, blue;
|
|
float range;
|
|
|
|
GetToken(false);
|
|
range = atof(token);
|
|
GetToken(false);
|
|
levels = atoi(token);
|
|
GetToken(false);
|
|
brights = atoi(token);
|
|
|
|
// shaded levels
|
|
for (l = 0; l < levels; l++)
|
|
{
|
|
frac = range - range * (float)l / (levels - 1);
|
|
for (c = 0; c < 256 - brights; c++)
|
|
{
|
|
red = lbmpalette[c * 3];
|
|
green = lbmpalette[c * 3 + 1];
|
|
blue = lbmpalette[c * 3 + 2];
|
|
|
|
red = (int)(red * frac + 0.5);
|
|
green = (int)(green * frac + 0.5);
|
|
blue = (int)(blue * frac + 0.5);
|
|
|
|
//
|
|
// note: 254 instead of 255 because 255 is the transparent color, and we
|
|
// don't want anything remapping to that
|
|
//
|
|
*lump_p++ = BestColor(red, green, blue, 0, 254);
|
|
}
|
|
|
|
// fullbrights allways stay the same
|
|
for (; c < 256; c++)
|
|
*lump_p++ = c;
|
|
}
|
|
|
|
*lump_p++ = brights;
|
|
}
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
MIPTEX GRABBING
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
char name[16];
|
|
unsigned width, height;
|
|
unsigned offsets[4]; // four mip maps stored
|
|
} miptex_t;
|
|
|
|
byte pixdata[256];
|
|
|
|
float linearpalette[256][3];
|
|
float d_red, d_green, d_blue;
|
|
int colors_used;
|
|
int color_used[256];
|
|
float maxdistortion;
|
|
|
|
byte AddColor(float r, float g, float b)
|
|
{
|
|
int i;
|
|
for (i = 0; i < 255; i++)
|
|
{
|
|
if (!color_used[i])
|
|
{
|
|
linearpalette[i][0] = r;
|
|
linearpalette[i][1] = g;
|
|
linearpalette[i][2] = b;
|
|
if (r < 0)
|
|
r = 0.0;
|
|
if (r > 1.0)
|
|
r = 1.0;
|
|
lbmpalette[i * 3 + 0] = pow(r, 1.0 / 2.2) * 255;
|
|
if (g < 0)
|
|
g = 0.0;
|
|
if (g > 1.0)
|
|
g = 1.0;
|
|
lbmpalette[i * 3 + 1] = pow(g, 1.0 / 2.2) * 255;
|
|
if (b < 0)
|
|
b = 0.0;
|
|
if (b > 1.0)
|
|
b = 1.0;
|
|
lbmpalette[i * 3 + 2] = pow(b, 1.0 / 2.2) * 255;
|
|
color_used[i] = 1;
|
|
colors_used++;
|
|
return i;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
=============
|
|
AveragePixels
|
|
=============
|
|
*/
|
|
byte AveragePixels(int count)
|
|
{
|
|
float r, g, b;
|
|
int i;
|
|
int vis;
|
|
int pix;
|
|
float dr, dg, db;
|
|
float bestdistortion, distortion;
|
|
int bestcolor;
|
|
|
|
vis = 0;
|
|
r = g = b = 0;
|
|
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
pix = pixdata[i];
|
|
r += linearpalette[pix][0];
|
|
g += linearpalette[pix][1];
|
|
b += linearpalette[pix][2];
|
|
}
|
|
|
|
r /= count;
|
|
g /= count;
|
|
b /= count;
|
|
|
|
r += d_red;
|
|
g += d_green;
|
|
b += d_blue;
|
|
|
|
//
|
|
// find the best color
|
|
//
|
|
// bestdistortion = r*r + g*g + b*b;
|
|
bestdistortion = 3.0;
|
|
bestcolor = -1;
|
|
|
|
for (i = 0; i < 255; i++)
|
|
{
|
|
if (color_used[i])
|
|
{
|
|
pix = i; //pixdata[i];
|
|
|
|
dr = r - linearpalette[i][0];
|
|
dg = g - linearpalette[i][1];
|
|
db = b - linearpalette[i][2];
|
|
|
|
distortion = dr * dr + dg * dg + db * db;
|
|
if (distortion < bestdistortion)
|
|
{
|
|
if (!distortion)
|
|
{
|
|
d_red = d_green = d_blue = 0; // no distortion yet
|
|
return pix; // perfect match
|
|
}
|
|
|
|
bestdistortion = distortion;
|
|
bestcolor = pix;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (bestdistortion > 0.001 && colors_used < 255)
|
|
{
|
|
// printf("%f %f %f\n", r, g, b );
|
|
bestcolor = AddColor(r, g, b);
|
|
d_red = d_green = d_blue = 0;
|
|
bestdistortion = 0;
|
|
}
|
|
else
|
|
{
|
|
// error diffusion
|
|
d_red = r - linearpalette[bestcolor][0];
|
|
d_green = g - linearpalette[bestcolor][1];
|
|
d_blue = b - linearpalette[bestcolor][2];
|
|
}
|
|
|
|
if (bestdistortion > maxdistortion)
|
|
maxdistortion = bestdistortion;
|
|
return bestcolor;
|
|
}
|
|
|
|
|
|
/*
|
|
==============
|
|
GrabMip
|
|
|
|
filename MIP x y width height
|
|
must be multiples of sixteen
|
|
==============
|
|
*/
|
|
void GrabMip(void)
|
|
{
|
|
int i, j, x, y, xl, yl, xh, yh, w, h;
|
|
byte *screen_p, *source, testpixel;
|
|
int linedelta;
|
|
miptex_t* qtex;
|
|
int miplevel, mipstep;
|
|
int xx, yy, pix;
|
|
int count;
|
|
|
|
GetToken(false);
|
|
xl = atoi(token);
|
|
GetToken(false);
|
|
yl = atoi(token);
|
|
GetToken(false);
|
|
w = atoi(token);
|
|
GetToken(false);
|
|
h = atoi(token);
|
|
|
|
if (xl == -1)
|
|
{
|
|
xl = yl = 0;
|
|
w = byteimagewidth;
|
|
h = byteimageheight;
|
|
}
|
|
|
|
if ((w & 15) || (h & 15))
|
|
Error("line %i: miptex sizes must be multiples of 16", scriptline);
|
|
|
|
xh = xl + w;
|
|
yh = yl + h;
|
|
|
|
qtex = (miptex_t*)lump_p;
|
|
qtex->width = LittleLong(w);
|
|
qtex->height = LittleLong(h);
|
|
strcpy(qtex->name, lumpname);
|
|
|
|
lump_p = (byte*)&qtex->offsets[4];
|
|
|
|
screen_p = byteimage + yl * byteimagewidth + xl;
|
|
linedelta = byteimagewidth - w;
|
|
|
|
source = lump_p;
|
|
qtex->offsets[0] = LittleLong(lump_p - (byte*)qtex);
|
|
|
|
for (y = yl; y < yh; y++)
|
|
{
|
|
for (x = xl; x < xh; x++)
|
|
{
|
|
pix = *screen_p;
|
|
*screen_p++ = 0;
|
|
// if (pix == 255)
|
|
// pix = 0;
|
|
*lump_p++ = pix;
|
|
}
|
|
screen_p += linedelta;
|
|
}
|
|
|
|
// calculate gamma corrected linear palette
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
for (j = 0; j < 3; j++)
|
|
{
|
|
float f;
|
|
f = lbmpalette[i * 3 + j] / 255.0;
|
|
linearpalette[i][j] = pow(f, 2.2); // assume textures are done at 2.2, we want to remap them at 1.0
|
|
}
|
|
}
|
|
|
|
maxdistortion = 0;
|
|
if (!fTransparent255)
|
|
{
|
|
// figure out what palette entries are actually used
|
|
colors_used = 0;
|
|
for (i = 0; i < 256; i++)
|
|
color_used[i] = 0;
|
|
|
|
for (x = 0; x < w; x++)
|
|
{
|
|
for (y = 0; y < h; y++)
|
|
{
|
|
if (!color_used[source[y * w + x]])
|
|
{
|
|
color_used[source[y * w + x]] = 1;
|
|
colors_used++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// assume palette full if it's a transparent texture
|
|
colors_used = 256;
|
|
for (i = 0; i < 256; i++)
|
|
color_used[i] = 1;
|
|
}
|
|
// printf("colors_used %d : ", colors_used );
|
|
|
|
|
|
//
|
|
// subsample for greater mip levels
|
|
//
|
|
|
|
for (miplevel = 1; miplevel < 4; miplevel++)
|
|
{
|
|
int pixTest;
|
|
d_red = d_green = d_blue = 0; // no distortion yet
|
|
qtex->offsets[miplevel] = LittleLong(lump_p - (byte*)qtex);
|
|
|
|
mipstep = 1 << miplevel;
|
|
pixTest = (int)((float)(mipstep * mipstep) * 0.4); // 40% of pixels
|
|
|
|
for (y = 0; y < h; y += mipstep)
|
|
{
|
|
for (x = 0; x < w; x += mipstep)
|
|
{
|
|
count = 0;
|
|
for (yy = 0; yy < mipstep; yy++)
|
|
for (xx = 0; xx < mipstep; xx++)
|
|
{
|
|
testpixel = source[(y + yy) * w + x + xx];
|
|
|
|
// If 255 is not transparent, or this isn't a transparent pixel, add it in to the image filter
|
|
if (!fTransparent255 || testpixel != 255)
|
|
{
|
|
pixdata[count] = testpixel;
|
|
count++;
|
|
}
|
|
}
|
|
if (count <= pixTest) // Solid pixels account for < 40% of this pixel, make it transparent
|
|
{
|
|
*lump_p++ = 255;
|
|
}
|
|
else
|
|
{
|
|
*lump_p++ = AveragePixels(count);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// printf(" %d %f\n", colors_used, maxdistortion );
|
|
|
|
if (do16bit)
|
|
GrabPalette16();
|
|
}
|
|
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
PALETTE GRABBING
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
|
|
void GrabPalette16(void)
|
|
{
|
|
// Write out palette in 16bit mode
|
|
*(unsigned short*)lump_p = 256; // palette size
|
|
lump_p += sizeof(short);
|
|
|
|
memcpy(lump_p, lbmpalette, 768);
|
|
lump_p += 768;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
FONT GRABBING
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
|
|
/*
|
|
==============
|
|
GrabFont
|
|
|
|
font x y width height startglyph
|
|
==============
|
|
*/
|
|
void GrabFont(void)
|
|
{
|
|
int x, y, y2, xl, x2, yl, xh, yh, i, j;
|
|
int index, offset;
|
|
int iCurX; // current x in destination
|
|
int iMaxX; // max x in destination
|
|
|
|
byte *pbuf, *pCur;
|
|
qfont_t* header;
|
|
|
|
|
|
iMaxX = 255;
|
|
iCurX = 0;
|
|
|
|
// Set up header
|
|
header = (qfont_t*)lump_p;
|
|
memset(header, 0, sizeof(qfont_t));
|
|
|
|
GetToken(false);
|
|
header->width = header->rowheight = atoi(token); //mwh why does width equal rowheight?
|
|
header->height = 1;
|
|
lump_p = (byte*)header->data;
|
|
pCur = (byte*)lump_p;
|
|
memset(lump_p, 0xFF, 256 * 160);
|
|
|
|
GetToken(false);
|
|
index = atoi(token);
|
|
|
|
while (index != -1)
|
|
{
|
|
// Get/Process source bitmap coordinates
|
|
GetToken(false);
|
|
xl = atoi(token);
|
|
GetToken(false);
|
|
yl = atoi(token);
|
|
GetToken(false);
|
|
xh = xl - 1 + atoi(token);
|
|
GetToken(false);
|
|
yh = atoi(token) - 1;
|
|
if (xl == -1)
|
|
{
|
|
xl = yl = 0;
|
|
xh = byteimagewidth;
|
|
yh = byteimageheight;
|
|
}
|
|
|
|
if (xh < xl || yh < yl || xl < 0 || yl < 0)
|
|
Error("GrabFont line %1: Bad size: %i, %i, %i, %i", scriptline, xl, yl, xh, yh);
|
|
|
|
//
|
|
// Fill in font information
|
|
// Create a bitmap that is up to 256 wide and as tall as we need to accomadate the font.
|
|
// We limit the bitmap to 256 because some 3d boards have problems with textures bigger
|
|
// than that.
|
|
//
|
|
for (y = yl; y < yh; y += header->rowheight + 1)
|
|
{
|
|
// Make sure we're at a marker
|
|
if (y != yl)
|
|
{
|
|
for (y2 = y - header->rowheight; y2 < yh; y2++)
|
|
if (kFontMarker == (unsigned)SCRN(xl, y2))
|
|
break;
|
|
|
|
if (y2 == yh)
|
|
break;
|
|
else if (y2 != y)
|
|
Error("GrabFont line %d: rowheight doesn't seem to match bitmap (%d, %d)\n", scriptline, y, y2);
|
|
}
|
|
|
|
for (x = xl; x < xh;)
|
|
{
|
|
// find next marker
|
|
for (x2 = x + 1; x2 < xh; x2++)
|
|
if (kFontMarker == (unsigned)SCRN(x2, y))
|
|
break;
|
|
|
|
// check for end of row
|
|
if (x2 == xh)
|
|
break;
|
|
|
|
// Set up glyph information
|
|
if (index >= NUM_GLYPHS)
|
|
{
|
|
printf("GrabFont: Glyph out of range\n");
|
|
goto getout;
|
|
}
|
|
|
|
// Fill in glyph info
|
|
header->fontinfo[index].charwidth = x2 - x - 1;
|
|
|
|
// update header
|
|
|
|
// output glyph data
|
|
iCurX += header->fontinfo[index].charwidth;
|
|
|
|
// Will this glyph fit on this row?
|
|
if (iCurX >= iMaxX)
|
|
{
|
|
// Nope -- move to next row
|
|
pCur = (byte*)lump_p + 256 * header->rowheight * header->height;
|
|
header->height++;
|
|
iCurX = header->fontinfo[index].charwidth;
|
|
}
|
|
|
|
// copy over the glyph bytes
|
|
pbuf = pCur;
|
|
header->fontinfo[index].startoffset = pCur - (byte*)header->data;
|
|
|
|
|
|
for (j = 1; j <= header->rowheight; j++)
|
|
{
|
|
byte* psrc = byteimage + (y + j) * byteimagewidth + (x + 1);
|
|
|
|
for (i = x + 1; i < x2; i++)
|
|
*pbuf++ = *psrc++;
|
|
|
|
pbuf = pCur + j * 256;
|
|
}
|
|
|
|
// move the lump pointer to point at the next possible glyph
|
|
pCur += header->fontinfo[index].charwidth;
|
|
x = x2;
|
|
index++;
|
|
}
|
|
}
|
|
|
|
// Get next ASCII index
|
|
getout:
|
|
GetToken(false);
|
|
index = atoi(token);
|
|
}
|
|
|
|
// advance the lump pointer so that the last row is saved.
|
|
lump_p += (256 * header->rowheight) * header->height;
|
|
|
|
// JAY: Round up to the next power of 2 for GL
|
|
offset = header->height * header->rowheight;
|
|
|
|
y = (offset > 128) ? 256 : (offset > 64) ? 128
|
|
: (offset > 32) ? 64
|
|
: (offset > 16) ? 32
|
|
: 16;
|
|
if (offset != y)
|
|
{
|
|
printf("Rounding font from 256x%d to 256x%d\n", offset, y);
|
|
lump_p += (256 * (y - offset));
|
|
}
|
|
header->rowcount = header->height;
|
|
header->height = y;
|
|
|
|
if (do16bit)
|
|
GrabPalette16();
|
|
}
|