ngunix/engine/draw.c
2015-08-31 22:03:24 +02:00

2891 lines
65 KiB
C

/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// draw.c -- this is the only file outside the refresh that touches the
// vid buffer
#include "globaldef.h"
// 2000-08-04 "Transparent" console background for software renderer by Norberto Alfredo Bensa/Maddes start
extern cvar_t *con_alpha;
//pixel_t ditherTable[32768][4];
pixel_t ditherTable[262144][4]; // leilei - 18-bit dithering. holy crap, is this table huge
byte fademask[] =
{
0x00, // invisible
0x14, // 25%
0x5a, // 50%
0xeb, // 75%
0xff, // solid
};
#define CON_ALPHASTATES (sizeof(fademask) / sizeof(fademask[0]))
// 2000-08-04 "Transparent" console background for software renderer by Norberto Alfredo Bensa/Maddes end
typedef struct {
vrect_t rect;
int width;
int height;
byte *ptexbytes;
int rowbytes;
} rectdesc_t;
static rectdesc_t r_rectdesc;
byte *draw_chars; // 8*8 graphic characters
qpic_t *draw_disc;
qpic_t *draw_backtile;
//=============================================================================
/* Support Routines */
typedef struct cachepic_s
{
char name[MAX_QPATH];
cache_user_t cache;
} cachepic_t;
#define MAX_CACHED_PICS 128
cachepic_t menu_cachepics[MAX_CACHED_PICS];
int menu_numcachepics;
qpic_t *Draw_PicFromWad (char *name)
{
return W_GetLumpName (name);
}
#ifdef _WIN32
extern qboolean WinNT;
#endif
/*
===============
BestColor
===============
*/
byte BestColor (int r, int g, int b, int start, int stop)
{
int i;
int dr, dg, db;
int bestdistortion, distortion;
int berstcolor;
byte *pal;
#ifdef _WIN32
// lei - nt hack, so we never see illegal colors on Windows NT
//if (WinNT){
// if(start == 0) start = 1;
// if(stop == 255) stop = 254;
// }
#endif
//
// let any color go to 0 as a last resort
//
bestdistortion = 256*256*4;
berstcolor = 0;
pal = host_basepal + 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;
berstcolor = i;
}
}
return berstcolor;
}
extern byte *host_otherpal;
/*
===============
BestColor
===============
*/
byte EGABestColor (int r, int g, int b)
{
int i;
int dr, dg, db;
int bestdistortion, distortion;
int berstcolor;
byte *pal;
//
// let any color go to 0 as a last resort
//
bestdistortion = 256*256*4;
berstcolor = 0;
pal = host_otherpal + 0*3;
for (i=0 ; i<= 254 ; 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;
berstcolor = i;
}
}
if (berstcolor > 256-host_fullbrights){
pal = host_basepal + 7*3;
for (i=8 ; i<= 15 ; 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;
berstcolor = i;
}
}
}
else
{
pal = host_basepal + 0*3;
for (i=0 ; i<= 8 ; 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;
berstcolor = i;
}
}
}
return berstcolor;
}
int BestCol (int r, int g, int b)
{
int i;
int dr, dg, db;
int bestdistortion, distortion;
int berstcolor;
byte *pal;
int start = 1;
int stop = 254;
bestdistortion = 256*256*4;
berstcolor = 0;
pal = host_basepal + 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;
berstcolor = i;
}
}
return berstcolor;
}
// COLOR Translation stuff
// Came straight out of image.c of Quake2 tools
byte palmap[32][32][32]; // For FindColor's fast 15-bit lookup
byte palmap2[64][64][64]; // Higher quality for lighting
unsigned char palmap3[65535]; // for 888rgb...
byte palmapnofb[32][32][32]; // for hl map conversion only
// this is just a lookup table version of the above
int FindColor (int r, int g, int b)
{
int bestcolor;
if (r > 255)r = 255;if (r < 0)r = 0;
if (g > 255)g = 255;if (g < 0)g = 0;
if (b > 255)b = 255;if (b < 0)b = 0;
bestcolor = palmap[r>>3][g>>3][b>>3];
return bestcolor;
}
int FindColorNoFB (int r, int g, int b)
{
int bestcolor;
if (r > 255)r = 255;if (r < 0)r = 0;
if (g > 255)g = 255;if (g < 0)g = 0;
if (b > 255)b = 255;if (b < 0)b = 0;
bestcolor = palmapnofb[r>>3][g>>3][b>>3];
return bestcolor;
}
int FindColor18 (int r, int g, int b)
{
int bestcolor;
if (r > 255)r = 255;if (r < 0)r = 0;
if (g > 255)g = 255;if (g < 0)g = 0;
if (b > 255)b = 255;if (b < 0)b = 0;
bestcolor = palmap2[r>>2][g>>2][b>>2];
return bestcolor;
}
struct rgba_t paleet[256];
/*
================
Draw_CachePic
================
*/
qpic_t *Draw_CachePic (char *path)
{
cachepic_t *pic;
int i;
qpic_t *dat;
for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
if (!strcmp (path, pic->name))
break;
if (i == menu_numcachepics)
{
if (menu_numcachepics == MAX_CACHED_PICS)
Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
menu_numcachepics++;
strcpy (pic->name, path);
}
dat = Cache_Check (&pic->cache);
if (dat)
return dat;
//
// load the pic from disk
//
COM_LoadCacheFile (path, &pic->cache);
dat = (qpic_t *)pic->cache.data;
if (!dat)
{
Con_Printf ("Draw_CachePic: failed to load %s\n", path);
return NULL;
}
// leilei - quick palette translation
if (rmap_ready){
int bah;
for (bah = 0; bah < dat->width*dat->height; bah++)
dat->data[bah] = coltranslate[dat->data[bah]];
}
// leilei - quick palette translation
SwapPic (dat);
return dat;
}
extern byte *host_colormap_nofb;
unsigned char d_15to8table[65536]; // 15to8
void MakeMy15to8(unsigned char *palette)
{
byte *pal;
unsigned r,g,b;
unsigned v;
int r1,g1,b1;
int j,k,l,m;
unsigned short i;
unsigned *table;
FILE *f;
char s[255];
// HWND hDlg, hProgress;
// float gamma;
// pal = host_basepal *3;
//
// 8 8 8 encoding
//
pal = palette;
table = d_8to24table;
for (i=0 ; i<256 ; i++)
{
r = pal[0];
g = pal[1];
b = pal[2];
pal += 3;
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
*table++ = v;
}
d_8to24table[255] &= 0xffffff; // 255 is transparent
table = d_8to24table;
for (i=0 ; i<257 ; i++)
{
r = pal[0];
g = pal[1];
b = pal[2];
pal += 3;
v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
*table++ = v;
}
// d_8to24table[255] &= 0xffffff; // 255 is transparent
// JACK: 3D distance calcs - k is last closest, l is the distance.
// FIXME: Precalculate this and cache to disk.
for (i=0; i < (1<<15); i++) {
/* Maps
000000000000000
000000000011111 = Red = 0x1F
000001111100000 = Blue = 0x03E0
111110000000000 = Grn = 0x7C00
*/
r = ((i & 0x1F) << 3)+4;
g = ((i & 0x03E0) >> 2)+4;
b = ((i & 0x7C00) >> 7)+4;
pal = (unsigned char *)d_8to24table;
for (v=0,k=0,l=10000*10000; v<256; v++,pal+=4) {
r1 = r-pal[0];
g1 = g-pal[1];
b1 = b-pal[2];
j = (r1*r1)+(g1*g1)+(b1*b1);
if (j<l) {
k=v;
l=j;
}
}
d_15to8table[i]=k;
}
}
byte *lmmap;
// are we done with lookup tables yet? I DONT THINK SO!
// despite the name these are actually gray
void IdnitColorColormaps (void) {
int levels, brights;
int l, c;
float frac;
float red, green, blue;
float range;
byte *cropped, *lump_p;
char savename[1024];
char dest[1024];
range = 2;
levels = 16;
brights = 1; // ignore 255 (transparent)
cropped = malloc((levels+256)*256);
lump_p = cropped;
Con_Printf ("\n ohhhh ");
// shaded levels
for (l=0;l<levels;l++)
{
frac = range - range*(float)l/(levels-1);
for (c=0 ; c<256-brights ; c++)
{
red = 128;
green = 128;
blue = 128;
red = (int)(red*frac+0.5);
green = (int)(green*frac+0.5);
blue = (int)(blue*frac+0.5);
lump_p[l] = BestColor(red,green,blue, 0, 255);
host_colormap[l] = lump_p[l];
}
Con_Printf ("shit");
}
}
/*
==============
GrabColormap - from qbism- from qlumpy
modified by leilei to make it cvarable
with overbright clamp simulating glquake's bad looks
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) //qbism - fixed, was a little screwy
{
int l, c, red, green, blue;
float frac, cscale, fracscaled;
float rscaled, gscaled, bscaled;
byte *colmap;
int RANGE = 2;
int COLORLEVELS = 64;
int PALBRIGHTS;
RANGE = 2;
if(!fullbrights) PALBRIGHTS = 0;
else
PALBRIGHTS = 256 - host_fullbrights;
colmap = host_colormap;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
if (!overbrights){ if (frac > 1) frac = 1;} // leilei - clamp it out for glsuck
for (c=0 ; c<256-PALBRIGHTS ; c++)
{
red = (int)((float)host_basepal[c*3]*frac);
green = (int)((float)host_basepal[c*3+1]*frac);
blue = (int)((float)host_basepal[c*3+2]*frac);
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*colmap++ = BestColor(red,green,blue, 0, 254);
}
for ( ; c<256 ; c++)
{
red = (int)host_basepal[c*3];
green = (int)host_basepal[c*3+1];
blue = (int)host_basepal[c*3+2];
*colmap++ = BestColor(red,green,blue, 0, 254);
}
}
}
byte additiveshade[16384];
void GrabColorMapNoFB (void) //have no fullbrights or overbrights for a luminance colormap for additive blends only
{
int l, c, red, green, blue;
float frac, cscale, fracscaled;
float rscaled, gscaled, bscaled;
byte *colmap;
int RANGE = 2;
int COLORLEVELS = 32;
int PALBRIGHTS;
RANGE = 2;
PALBRIGHTS = 2;
host_colormap_nofb = malloc(16900);
colmap = host_colormap_nofb;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
for (c=0 ; c<256 ; c++)
{
red = (int)((float)host_basepal[c*3]*frac);
green = (int)((float)host_basepal[c*3+1]*frac);
blue = (int)((float)host_basepal[c*3+2]*frac);
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*colmap++ = BestColor(red,green,blue, 0, 254);
}
}
}
void TranslateColorMapEGA (void)
{
int l, c, red, green, blue;
float frac, cscale, fracscaled;
float rscaled, gscaled, bscaled;
byte *colmap;
int RANGE = 2;
int COLORLEVELS = 64;
int PALBRIGHTS;
float sat = 2;
float s;
RANGE = 6;
if(!fullbrights) PALBRIGHTS = 0;
else
PALBRIGHTS = 256 - host_fullbrights;
colmap = host_colormap;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
if (!overbrights){ if (frac > 1) frac = 1;} // leilei - clamp it out for glsuck
for (c=0 ; c<256-PALBRIGHTS ; c++)
{
red = (int)((float)host_otherpal[c*3]*frac);
green = (int)((float)host_otherpal[c*3+1]*frac);
blue = (int)((float)host_otherpal[c*3+2]*frac);
s = (red * 0.33333) + (green * 0.33333) + (blue * 0.33333);
red = s + (red - s) * sat;
green = s + (green - s) * sat;
blue = s + (blue - s) * sat;
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*colmap++ = BestColor(red,green,blue, 0, 16);
}
for (; c<256 ; c++)
{
red = (int)host_otherpal[c*3];
green = (int)host_otherpal[c*3+1];
blue = (int)host_otherpal[c*3+2];
s = (red * 0.33333) + (green * 0.33333) + (blue * 0.33333);
red = s + (red - s) * sat;
green = s + (green - s) * sat;
blue = s + (blue - s) * sat;
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
*colmap++ = BestColor(red,green,blue, 0, 16);
}
}
}
/*
==============
GrabColormapEGA
==============
*/
void GrabColorMapEGA (void) //qbism - fixed, was a little screwy
{
int l, c, red, green, blue;
float frac, cscale, fracscaled;
float rscaled, gscaled, bscaled;
byte *colmap;
int RANGE = 5; // extra range for ega
int COLORLEVELS = 64;
int PALBRIGHTS;
if(!fullbrights) PALBRIGHTS = 0;
else
PALBRIGHTS = 256 - 247; // leilei - try to only do fullbrights for the highlights.
colmap = host_colormap;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
if (!overbrights){ if (frac > 1) frac = 1;} // leilei - clamp it out for glsuck
for (c=0 ; c<256-PALBRIGHTS ; c++)
{
red = (int)((float)host_basepal[c*3]*frac);
green = (int)((float)host_basepal[c*3+1]*frac);
blue = (int)((float)host_basepal[c*3+2]*frac);
*colmap++ = BestColor(red,green,blue, 0, 16);
}
for ( ; c<16 ; c++)
{
red = (int)host_basepal[c*3];
green = (int)host_basepal[c*3+1];
blue = (int)host_basepal[c*3+2];
*colmap++ = BestColor(red,green,blue, 0, 16);
}
}
}
extern cvar_t *temp2;
void GrabColorMapRGB (void) // leilei - for the r g b components looking ups etcetera.
{
int l, c, red, green, blue;
float frac, cscale, fracscaled, frick;
float rscaled, gscaled, bscaled;
// byte *colmap;
byte *colmapr;
byte *colmapg;
byte *colmapb;
int RANGE = 2;
int buh = 2;
int COLORLEVELS = 64;
int PALBRIGHTS;
int limit = 127;
Con_Printf("YES!\nYES!!\nYES!!!\n");
RANGE = 2; // was 2.
if(!fullbrights) PALBRIGHTS = 0;
else
PALBRIGHTS = 256 - host_fullbrights; // gotta still have 'em fullbrights!
PALBRIGHTS = 32;
// colmap = host_colormap;
colmapr = host_colormap_red;
colmapg = host_colormap_green;
colmapb = host_colormap_blue;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frick = (float)1/(COLORLEVELS-1);
frac = RANGE*(float)l/(COLORLEVELS-1);
// frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
if (!overbrights){ if (frac > 1) frac = 1;} // leilei - clamp it out for glsuck
if (!overbrights){ if (frick > 1) frick = 1;} // leilei - clamp it out for glsuck
for (c=0 ; c<256-PALBRIGHTS ; c++)
{
red = (int)((float)host_basepal[c*3]*frac);
green = (int)((float)host_basepal[c*3+1]*frac);
blue = (int)((float)host_basepal[c*3+2]*frac);
if (red > limit) red = limit;
if (green > limit) green = limit;
if (blue > limit) blue = limit;
*colmapr++ = red >> buh;
*colmapg++ = green >> buh;
*colmapb++ = blue >> buh;
}
for ( ; c<256 ; c++)
{
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
red = host_basepal[c*3] * 0.5;
green = host_basepal[c*3+1] * 0.5;
blue = host_basepal[c*3+2] * 0.5;
if (red > limit) red = limit;
if (green > limit) green = limit;
if (blue > limit) blue = limit;
*colmapr++ = red >> buh;
*colmapg++ = green >> buh; // because fullbrights get added.
*colmapb++ = blue >> buh;
}
}
}
// This version of the function tries to restrict to the 16x16 swatches
// so we don't have stuff like grays fading into blues or blues fading into grays
// and the overbrights won't turn into yellows. Stuff WILL look wrong.
// this is only a test. a test. a test. a test. a test. a test. a t
void GrabColorMapAlternative (void) //qbism - fixed, was a little screwy
{
int l, c, g, red, green, blue;
float frac, cscale, fracscaled;
float rscaled, gscaled, bscaled;
byte *colmap;
int RANGE = 2;
int COLORLEVELS = 64;
int PALBRIGHTS;
RANGE = 2;
if(!fullbrights) PALBRIGHTS = 0;
else
PALBRIGHTS = 256 - host_fullbrights;
colmap = host_colormap;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
if (!overbrights){ if (frac > 1) frac = 1;} // leilei - clamp it out for glsuck
for (c=0 ; c<256-PALBRIGHTS ; c+=16)
{
for (g=c ; g<c+16; g++){
red = (int)((float)host_basepal[g*3]*frac);
green = (int)((float)host_basepal[g*3+1]*frac);
blue = (int)((float)host_basepal[g*3+2]*frac);
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*colmap++ = BestColor(red,green,blue, c, c+16);
}
}
for ( ; c<256 ; c++)
{
red = (int)host_basepal[c*3];
green = (int)host_basepal[c*3+1];
blue = (int)host_basepal[c*3+2];
*colmap++ = BestColor(red,green,blue, 0, 254);
}
}
}
// Another alternative method where we try to saturate the darker colors so we can maintain the colors.
// a little less ugly than the top one because we still have access to all the colors
void GrabColorMapSaturation (void) //qbism - fixed, was a little screwy
{
int l, c, red, green, blue;
float satr, satg, satb;
float frac, cscale, fracscaled;
float rscaled, gscaled, bscaled;
float satty;
byte *colmap;
int RANGE = 2;
int COLORLEVELS = 64;
int PALBRIGHTS;
RANGE = 2;
if(!fullbrights) PALBRIGHTS = 0;
else
PALBRIGHTS = 256 - host_fullbrights;
colmap = host_colormap;
// shaded levels
for (l=0; l<COLORLEVELS; l++)
{
// frac = (float)l/(COLORLEVELS-1);
frac = RANGE - RANGE*(float)l/(COLORLEVELS-1);
satty = l * 2.8 / 64;
if (satty < 1)
satty = 1; // clampity
if (!overbrights){ if (frac > 1) frac = 1;} // leilei - clamp it out for glsuck
for (c=0 ; c<256-PALBRIGHTS ; c++)
{
red = (int)((float)host_basepal[c*3]*frac);
green = (int)((float)host_basepal[c*3+1]*frac);
blue = (int)((float)host_basepal[c*3+2]*frac);
satr = (red * 0.333) + (green * 0.333) + (blue * 0.333);
red = satr + (red - satr) * satty;
green = satr + (green - satr) * satty;
blue = satr + (blue - satr) * satty;
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
//
// note: 254 instead of 255 because 255 is the transparent color, and we
// don't want anything remapping to that
//
*colmap++ = BestColor(red,green,blue, 0, 254);
}
for ( ; c<256 ; c++)
{
red = (int)host_basepal[c*3];
green = (int)host_basepal[c*3+1];
blue = (int)host_basepal[c*3+2];
*colmap++ = BestColor(red,green,blue, 0, 254);
}
}
}
// 2001-09-18 New cvar system by Maddes (Init) start
/*
===============
Draw_Init_Cvars
===============
*/
void Draw_Init_Cvars (void)
{
}
// 2001-09-18 New cvar system by Maddes (Init) end
/*
===============
Draw_Init
===============
*/
//
// Our Friendly Neighborhood Lookup Tables
//
// TODO: Cache all to disk and load from disk when available
// gfx/addmap.lmp, gfx/mulmap.lmp, gfx/tinttab.lmp (hi hexen2)
// gfx/8to16.lmp, gfx/8to24.lmp, gfx/palmap.lmp, gfx/palmap2.lmp
// These are proposed filenames.
byte menumap[256][16]; // Used for menu backgrounds and simple colormod
byte gelmap[256]; // Unused id effect TO be used somehow. made redundant by menumap
byte remapmap[256]; // For translating an old palette to new on load
int translate_bsp;
int translate_mdl;
int translate_gfx;
int translate_spr;
float fademap[256]; // Used in generation of certain alpha tables
byte coltranslate[256]; // TranslateToCustomPal - used for taking one palette to another without going through a whole 8to24to15to8 thing
pixel_t addTable[256][256]; // Additive blending effect
pixel_t mulTable[256][256]; // Multiply blending effect (for colormod)
pixel_t transTable[256][256]; // Alpha blending by 33% and 66%
//pixel_t alphaTable[256][256]; // Alpha blending by row
pixel_t waterTable[256][256]; // Not cached to disk - for wateralpha only (THIS IS A STUPID but only sensible way to go for this)
int smoothtable[32768][3]; // a table for smoothing out things.... :(
int noisetable[512][5]; // a table for table
int wootel[32][32][32]; // alternate kernel blend
unsigned d_8to24table[256]; // a super important table here
void InitGel (byte *palette)
{
int i;
int r;
for (i=0 ; i<256 ; i++)
{
// r = (palette[i*3]>>4);
r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3);
gelmap[i] = /* 64 */ 0 + r;
}
}
// Gamepad notes:
// AUX29 - dpad up
// AUX32 - dpad left
// AUX30 - dpad right
// AUX31 - dpad down
extern cvar_t *temp2;
void InitWootel (void)
{
int i;
int r;
int ordered = 0;
float ay, ae;
int result;
int range = 32;
float spread = 1024;
//float spread = temp2->value;
for (i=1 ; i<range; i++)
{
ae = i / range;
for (r=0; r<32; r++){
ay = (RandomRange(0,spread));
result = (float)ay;
//if (result > 512) result = 512;
//if (result < 0) result = 0;
wootel[i][r][0] = result;
}
}
}
void InitNoise (void)
{
int i;
int r;
float ay, ae;
int result;
int range = 64;
float spread = 1024;
//float spread = temp2->value;
for (i=1 ; i<range; i++)
{
ae = i / range;
for (r=0; r<6; r++){
ay = (RandomRange(0,spread));
result = (float)ay;
//if (result > 512) result = 512;
//if (result < 0) result = 0;
noisetable[i][r] = result;
//noisetable[i][r] = (float)(range * ay);
}
}
for (r=0; r<6; r++){
noisetable[0][r] = 0; //yeah.... 0
//noisetable[64][r] = 64; //yeah...SIXTY FOUR
}
}
extern cvar_t *temp3;
void InitOrder (void)
{
int i;
int r;
int t;
float ay, ae;
int result;
int range = 64;
float spread = 1024;
//float spread = temp2->value;
for (i=1 ; i<range; i++)
{
ae = i / range;
t = (i & 1) << 1;
for (r=0; r<6; r++){
int eep, erp;
erp = (int)(range / (r + 1));
for (eep=0; eep<1024; eep+=erp)
{
ay = 2048;
if ((i & 1) != t)
ay -= 768;
}
result = (float)ay;
noisetable[i][r] = result;
}
}
for (r=0; r<6; r++){
noisetable[0][r] = 0; //yeah.... 0
}
}
void InitSimple (void)
{
int i;
int r;
float ay, ae;
int result;
int range = 64;
float spread = 1024;
//float spread = temp2->value;
for (i=1 ; i<range; i++)
{
ae = i / range;
for (r=0; r<6; r++){
int ef;
if (r == 0 || r == 2 || r == 4 || r == 6)
ef = 1024;
else
ef = 512;
ay = ef;
result = (float)ay;
//if (result > 512) result = 512;
//if (result < 0) result = 0;
noisetable[i][r] = result;
//noisetable[i][r] = (float)(range * ay);
}
}
for (r=0; r<6; r++){
noisetable[0][r] = 0; //yeah.... 0
//noisetable[64][r] = 64; //yeah...SIXTY FOUR
}
}
// leilei - smooth table for some 'smooth' things... like model shading
void InitSmooth (void)
{
int i;
int r;
int k;
float noiz;
float noiiz;
int range = 64;
InitNoise();
// InitOrder();
// InitSimple();
for (i=0 ; i<32768; i+=range)
{
for (r=0; r<range; r++){
for (k=0; k<6; k++){
smoothtable[i+r][k] = MID(1024, i + 512 - (noisetable[r][k]),16000);
}
}
}
smoothtable[0][0] = 0;
smoothtable[0][1] = 0;
smoothtable[0][2] = 0;
smoothtable[0][3] = 0;
smoothtable[0][4] = 0;
}
extern byte *host_origpal; // QUAKE palette only!
// makes a little remap table for our new palette to use
void InitRemap (byte *palette)
{
int i;
int r, g, b;
float sat = 3;
float s;
for (i=0 ; i<255 ; i++)
{
r = palette[i*3];
g = palette[i*3+1];
b = palette[i*3+2];
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
#ifdef EGAHACK
s = (r * 0.33333) + (g * 0.33333) + (b * 0.33333);
r = s + (r - s) * sat;
g = s + (g - s) * sat;
b = s + (b - s) * sat;
#endif
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
coltranslate[i] = BestColor(r,g,b, 0, 254);
remapmap [i] = BestColor(r,g,b, 0, 256-host_fullbrights); // no fullbrights...
}
coltranslate[256] = 256;
coltranslate[255] = 255; // null is null
rmap_ready = 1;
}
// makes a little remap table for our new palette to use
void InitRemapEGA (byte *palette)
{
int i;
int r;
int bah[3];
for (i=0 ; i<256 ; i++)
{
bah[0] = d_8to24table[palette[i]];
bah[1] = d_8to24table[palette[i+1]];
bah[2] = d_8to24table[palette[i+2]];
if (i > 256 - host_fullbrights){
coltranslate[i] = BestColor(bah[0], bah[1], bah[2], 9, 15);
remapmap[i] = BestColor(bah[0], bah[1], bah[2], 9, 15);
}
else
{
coltranslate[i] = BestColor(bah[0], bah[1], bah[2], 0, 8);
remapmap[i] = BestColor(bah[0], bah[1], bah[2], 0, 8);
}
}
rmap_ready = 1;
}
extern void PalmapStaticized ();
struct rgba_t r_palette[256];
int lookupcaching;
int nolookups;
// we make every lookup table in this function
// TODO: Caching to disk and loading if available
// TODO ALSO: Skipping of this by parameter
extern int inthedos;
void FogTableRefresh (void);
extern cvar_t *r_tranquality;
cvar_t *engoo_lookuppalette;
#ifdef _WIN32
extern unsigned char vid_curpal[256*3];
#endif
int erh;
int fbs[256];
void MassiveLookupTablesInit (void)
{
int i, j, l, c;
float red, green, blue;
int r, g, b;
int beastcolor;
int ugly;
unsigned char* thepaltouse;
InitSmooth();
#ifdef _WIN32
if (erh == 53)
thepaltouse = vid_curpal; // leilei - silly experiment to try adjusted palettes as a basis
// just for recalculating the big tables to see less color clashing
else
#endif
thepaltouse = host_basepal;
// if (COM_CheckParm ("-cache"))
// lookupcaching = 1; // try to cache it all for future loading
fprintf(stderr,"\nGenerating additive table... ");
for (l=0;l<255;l++)
{
for (c=0 ; c<255 ; c++)
{
red = thepaltouse[c*3] + thepaltouse[l*3];
green = thepaltouse[c*3+1] + thepaltouse[l*3+1];
blue = thepaltouse[c*3+2] + thepaltouse[l*3+2];
addTable[l][c] = BestColor(red,green,blue, 0, 254);
}
}
if(addTable)
fprintf(stderr,"[DONE]");
fprintf(stderr,"\nGenerating alpha table... ");
for (l=0;l<255;l++)
{
for (c=0 ; c<255 ; c++)
{
red = thepaltouse[c*3] *0.66 + (thepaltouse[l*3] * 0.33);
green = thepaltouse[c*3+1] *0.66 + (thepaltouse[l*3+1] * 0.33);
blue = thepaltouse[c*3+2] *0.66 + (thepaltouse[l*3+2] * 0.33);
transTable[l][c] = BestColor(red,green,blue, 0, 254);
}
}
if(transTable)
fprintf(stderr,"[DONE]");
if (COM_CheckParm ("-nolookups")){
nolookups = 1;
fprintf(stderr,"Color lookup tables are skipped\n");
return;
}
fprintf(stderr,"\n\n---------------------\nGenerating all the lookup tables\n(If your computer is slow, this will take up to 30 seconds. Use the -nolookups \nparameter if you find this unsettling)\nYou can also skip the 18-bit generation by passing -no18\nAlternatively, you can pass -ugly for faster but ugly generation\n---------------------\n\n");
if (COM_CheckParm ("-ugly")){
fprintf(stderr,"\n*** UGLY GENERATION MODE ON ***\n");
ugly = 1;}
else
ugly = 0;
// Do 24bit lookup
VID_SetPalette2 (thepaltouse);
fprintf(stderr,"\nGenerating 15-bit lookup table... ");
for (r=0 ; r<256 ; r+=8)
{
for (g=0 ; g<256 ; g+=8)
{
for (b=0 ; b<256 ; b+=8)
{
float lol = 3.6;
beastcolor = BestColor (r + lol, g + lol, b + lol, 0, 254);
palmap[r>>3][g>>3][b>>3] = beastcolor;
// andrewj's crud here
int k;
int pix = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
int rr = r - 4;
int gg = g - 4;
int bb = b - 4;
int col[4];
int ity[4];
byte *found;
for (k = 0 ; k < 4 ; k++)
{
col[k] = BestColor(rr + lol, gg + lol, bb + lol, 0, 254);
// apply error term
found = thepaltouse + col[k] * 3;
rr += (rr - (int)found[0]);
gg += (gg - (int)found[1]);
bb += (bb - (int)found[2]);
ity[k] = found[0] + found[1] + found[2];
}
// sort colors by intensity
for (rr = 0 ; rr < 4 ; rr++)
for (k = 0 ; k < 3 ; k++)
{
if (ity[k] < ity[k+1])
{
gg = col[k] ; col[k] = col[k+1] ; col[k+1] = gg;
gg = ity[k] ; ity[k] = ity[k+1] ; ity[k+1] = gg;
}
}
ditherTable[pix][0] = col[0];
ditherTable[pix][3] = col[1];
ditherTable[pix][2] = col[2];
ditherTable[pix][1] = col[3];
}
}
}
if (!palmap)
printf(stderr,"FAILED!\n");
else
fprintf(stderr,"[DONE]");
// Make the 18-bit lookup table here
// This is a HUGE 256kb table, the biggest there is here
// TODO: Option to enable this
// if (r_lightquality->value){
if (COM_CheckParm ("-no18"))
fprintf(stderr,"\n18-bit lookup generation skipped - High quality light mode DISABLED!\n");
else
{
fprintf(stderr,"\nGenerating 18-bit lookup table... ");
for (r=0 ; r<256 ; r+=4)
{
for (g=0 ; g<256 ; g+=4)
{
for (b=0 ; b<256 ; b+=4)
{
if (ugly)
beastcolor = FindColor (r, g, b);
else
beastcolor = BestColor (r, g, b, 0, 254);
palmap2[r>>2][g>>2][b>>2] = beastcolor;
}
}
}
if (!palmap2)
printf(stderr,"FAILED!\n");
else
fprintf(stderr,"[DONE]");
}
fprintf(stderr,"\nGenerating additive table... ");
for (l=0;l<255;l++)
{
for (c=0 ; c<255 ; c++)
{
red = thepaltouse[c*3] + thepaltouse[l*3];
green = thepaltouse[c*3+1] + thepaltouse[l*3+1];
blue = thepaltouse[c*3+2] + thepaltouse[l*3+2];
if (ugly) addTable[l][c] = FindColor(red,green,blue);
else
addTable[l][c] = BestColor(red,green,blue, 0, 254);
}
}
if (!addTable)
printf(stderr,"FAILED!\n");
else
fprintf(stderr,"[DONE]");
fprintf(stderr,"\nGenerating multiply blend table... ");
for (l=0;l<255;l++)
{
for (c=0 ; c<255 ; c++)
{
float ee, er, erp;
ee = 0.5;
er = 0.5;
erp = 0.03; // 0.1;
red = ((thepaltouse[l*3] * erp * (thepaltouse[c*3] * ee)) * er);
green = ((thepaltouse[l*3+1] * erp * (thepaltouse[c*3+1] * ee)) * er);
blue = ((thepaltouse[l*3+2] * erp * (thepaltouse[c*3+2] * ee)) * er);
if (red>255) red=255; if (green>255) green=255; if (blue>255) blue=255;
if (ugly)
mulTable[l][c] = FindColor(red,green,blue);
else
mulTable[l][c] = BestColor(red,green,blue, 0, 223);
}
}
if (!mulTable)
printf(stderr,"FAILED!\n");
else
fprintf(stderr,"[DONE]");
// if(palmap2)
PalmapStaticized();
// TODO: Caching lookups to disk, possibly folder unfriendly.
/* if (lookupcaching){
if (palmap)
COM_WriteFile ("palmap.lmp", palmap, 32768);
if (palmap2)
COM_WriteFile ("palmap2.lmp", palmap2, 262144);
if (addTable)
COM_WriteFile ("addmap.lmp", addTable, 65536);
if (mulTable)
COM_WriteFile ("mulmap.lmp", mulTable, 65536);
if (transTable)
COM_WriteFile ("tinttab.lmp", transTable, 65536);
if (ditherTable)
COM_WriteFile ("dithtab.lmp", ditherTable, 262144); // good lord this is huge.
}
*/
int ahe;
for (ahe=0; ahe<256; ahe++)
{
if (ahe < host_fullbrights)
fbs[ahe] = 0;
else
fbs[ahe] = mulTable[ahe][6];
}
GrabColorMapRGB();
}
// mangled a bit from grabcolormap
void SetFogMap (void);
void FogTableRefresh (void)
{
int ugly;
int l, c, red, green, blue;
float fogthik;
float frac;
float frac2;
float farc;
byte *colmap;
int RANGE = 1;
int COLORLEVELS = 64;
int PALBRIGHTS;
RANGE = 1;
ugly = (int)r_tranquality->value;
// TODO: Feed 'ese
// fogcolr = 0;
// fogcolg = 0;
// fogcolb = 0;
// fogthick= 100; // thickness of fog (100 = opaque, 50 = half... ok well you get it)
fogthik = fogthick * 0.01;
PALBRIGHTS = 0;
// Con_Printf ("Fog generating with %f %f %f %f", fogthick, fogcolr, fogcolg, fogcolb);
colmap = host_fogmap;
for (l=COLORLEVELS; l>0; l--)
{
frac = 2 - 2*(float)l/(COLORLEVELS) ;
frac2 = RANGE - RANGE/(float)l/(COLORLEVELS);
farc = 1 - ((frac / 2 ) * fogthik);
if (farc < 0)
farc = 0;
for (c=0 ; c<256-PALBRIGHTS ; c++)
{
red = ((int)((float)host_basepal[c*3] * farc) + (fogcolr / 2 * frac* fogthik));
green = ((int)((float)host_basepal[c*3+1] * farc) + (fogcolg / 2 * frac* fogthik));
blue = ((int)((float)host_basepal[c*3+2] * farc) + (fogcolb / 2 * frac* fogthik));
if (red>255)red=255;
if (green>255)green=255;
if (blue>255)blue=255;
if (red<0)red=0;
if (green<0)green=0;
if (blue<0)blue=0;
if (!ugly) *colmap++ = FindColor18(red,green,blue);
else
*colmap++ = BestColor(red,green,blue, 0, 254);
}
}
SetFogMap(); // set the static.
};
// auto-regenning water tables
// compared to transtable, findcolor is super fast but actually
// looks SLIGHTLY different to people with super eagle/sai eyes
// but not as much as one would lynch over
//
//
//
// This is also a good place to prototype new transparency lookup tables.
//
extern cvar_t *r_wateralpha;
extern int newwateralpha;
extern int oldwateralpha;
extern int oldwaterblend;
void WaterTableGet (void)
{
float ay, ae;
int i, j, l, c, o;
float red, green, blue;
int ooh;
ooh = (int)r_tranquality->value;
// Use these for now
ae = 0.66;
ay = 0.33;
// or not.
ay = r_wateralpha->value; // water surface
ae = 1 - ay; // base pixels
{
for (l=0;l<255;l++)
{
for (c=0 ; c<255 ; c++)
{
if (oldwaterblend == 1){ // additive
red = host_basepal[c*3] + (host_basepal[l*3] *ay);
green = host_basepal[c*3+1] + (host_basepal[l*3+1] *ay);
blue = host_basepal[c*3+2] + (host_basepal[l*3+2] *ay);
}
else if (oldwaterblend == 2){ // multiplicative
red = host_basepal[c*3] *ae + ((host_basepal[c*3] * (host_basepal[l*3] * 0.05)) * ay);
green = host_basepal[c*3+1] *ae + ((host_basepal[c*3+1]* (host_basepal[l*3+1] * 0.05)) * ay);
blue = host_basepal[c*3+2] *ae + ((host_basepal[c*3+2] * (host_basepal[l*3+2] * 0.05)) * ay);
}
else if (oldwaterblend == 4){ // multiplicative
red = host_basepal[c*3] *ae + ((host_basepal[l*3] * 0.1 * (host_basepal[c*3] * 0.5)) * ay);
green = host_basepal[c*3+1] *ae + ((host_basepal[l*3+1] * 0.1 * (host_basepal[c*3+1] * 0.5)) * ay);
blue = host_basepal[c*3+2] *ae + ((host_basepal[l*3+2] * 0.1 * (host_basepal[c*3+2] * 0.5)) * ay);
}
else if (oldwaterblend == 5){ // weird alpha thing
// how it works - goes through each color row from transparent(0) to opaque (16)
// this would also be used for the future (can you say decals?)
red = host_basepal[c*3] *(fademap[l] * ae) + (host_basepal[l*3] * (fademap[l]+0.3 * ay));
green = host_basepal[c*3+1] *(fademap[l] * ae) + (host_basepal[l*3+1] * (fademap[l]+0.3 * ay));
blue = host_basepal[c*3+2] * (fademap[l] * ae) + (host_basepal[l*3+2] * (fademap[l]+0.3 * ay));
}
/*
else if (oldwaterblend == 6){ // like above sort of
red = host_basepal[c*3] *host_basepal[l*3] + (host_basepal[l*3] * host_basepal[c*3]) / 768;
green = host_basepal[c*3+1] *host_basepal[l*3+1] + (host_basepal[l*3+1] * host_basepal[c*3+1]) / 768;
blue = host_basepal[c*3+2] *host_basepal[l*3+2]+ (host_basepal[l*3+2] * host_basepal[c*3+2]) / 768;
}
else if (oldwaterblend == 13){ // weird ass blend, black is black, but is a mix of alpha!?
red = host_basepal[c*3] *host_basepal[l*3] + (host_basepal[l*3] * host_basepal[c*3]) / 768;
green = host_basepal[c*3+1] *host_basepal[l*3+1] + (host_basepal[l*3+1] * host_basepal[c*3+1]) / 768;
blue = host_basepal[c*3+2] *host_basepal[l*3+2]+ (host_basepal[l*3+2] * host_basepal[c*3+2]) / 768;
}
*/
else
{
red = host_basepal[c*3] *ae + (host_basepal[l*3] * ay);
green = host_basepal[c*3+1] *ae + (host_basepal[l*3+1] * ay);
blue = host_basepal[c*3+2] *ae + (host_basepal[l*3+2] * ay);
}
if (red > 255) red = 255;
if (green > 255) green = 255;
if (blue > 255) blue = 255;
if (red < 0) red = 0;
if (green < 0) green = 0;
if (blue < 0) blue = 0;
if (ooh) waterTable[l][c] = BestColor(red,green,blue, 0, 255); // High quality color tables get best color
else if (palmap2) waterTable[l][c] = FindColor18(red,green,blue);
else waterTable[l][c] = FindColor(red,green,blue); // Since we do this live we must do this
// fast! or i'll cry.
}
}
}
}
void RemapMapTableGet (void)
{
int l;
for (l=0;l<255;l++)
remapmap[l] = 56;
}
void Draw_Init (void)
{
int i, j, l, c, r;
draw_chars = W_GetLumpName ("conchars");
draw_disc = W_GetLumpName ("disc");
draw_backtile = W_GetLumpName ("backtile");
r_rectdesc.width = draw_backtile->width;
r_rectdesc.height = draw_backtile->height;
r_rectdesc.ptexbytes = draw_backtile->data;
r_rectdesc.rowbytes = draw_backtile->width;
// Make the menu background table
// This has been extended to allow 16 others via r_menucolors
for (i=0 ; i<256 ; i++)
{
r = (host_basepal[i*3] + host_basepal[i*3+1] + host_basepal[i*3+2])/(16*3);
for (j=0; j<9; j++)
menumap[i][j] = (j * 16) + r;
for (j=14; j>7; j--)
menumap[i][j] = (j * 16) + 15 - r;
menumap[i][14] = 14*16 + r; // forward hack for the muzzleflash fire colors
// and yes, color ramp #15 is left all black. any further is possibly reserved for slow
// hexen 2 style menus which use a translucency table
}
// and no you can't skip it. i'll use it for colored text and other coolities
}
void RemapMenuMap (void)
{
int i, j, l, c, r;
// really for the 16 color mode
for (i=0 ; i<256 ; i++)
{
for (j=0; j<15; j++)
menumap[i][j] = coltranslate[menumap[i][j]];
}
};
int lilchar = 1;
/*
================
Draw_Character
Draws one 8*8 graphics character with 0 being transparent.
It can be clipped to the top of the screen to allow the console to be
smoothly scrolled off.
================
*/
void Draw_Character (int x, int y, int num)
{
byte *dest;
byte *source;
unsigned short *pusdest;
int drawline;
int row, col;
int ye; if(lilchar) ye = 4; else ye = 8;
num &= 255;
if (y <= -8)
return; // totally off screen
#ifdef PARANOID
if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y);
if (num < 0 || num > 255)
Sys_Error ("Con_DrawCharacter: char %i", num);
#endif
row = num>>4;
col = num&15;
source = draw_chars + (row<<10) + (col<<3);
if (y < 0)
{ // clipped
drawline = 8 + y;
source -= 128*y;
y = 0;
}
else
drawline = 8;
if (r_pixbytes == 1)
{
dest = vid.conbuffer + y*vid.conrowbytes + x;
while (drawline--)
{
if (source[0])
dest[0] = source[0];
if (source[1])
dest[1] = source[1];
if (source[2])
dest[2] = source[2];
if (source[3])
dest[3] = source[3];
if (source[4])
dest[4] = source[4];
if (source[5])
dest[5] = source[5];
if (source[6])
dest[6] = source[6];
if (source[7])
dest[7] = source[7];
source += 128;
dest += vid.conrowbytes;
}
}
else
{
// FIXME: pre-expand to native format?
pusdest = (unsigned short *)
((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1));
while (drawline--)
{
if (source[0])
pusdest[0] = d_8to16table[source[0]];
if (source[1])
pusdest[1] = d_8to16table[source[1]];
if (source[2])
pusdest[2] = d_8to16table[source[2]];
if (source[3])
pusdest[3] = d_8to16table[source[3]];
if (source[4])
pusdest[4] = d_8to16table[source[4]];
if (source[5])
pusdest[5] = d_8to16table[source[5]];
if (source[6])
pusdest[6] = d_8to16table[source[6]];
if (source[7])
pusdest[7] = d_8to16table[source[7]];
source += 128;
pusdest += (vid.conrowbytes >> 1);
}
}
}
void Draw_Character_Scaled (int x, int y, unsigned int num)
{
byte *source;
int drawline;
int u, v, row, col, s;
int height, width;
float vmax, umax;
num &= 255;
if (y <= -8)
return; // totally off screen
if (y > vid.vconheight - 8 || x < 0 || x > vid.vconwidth - 8)
return;
row = num>>4;
col = num&15;
source = draw_chars + (row<<10) + (col<<3);
if (y < 0)
{ // clipped
drawline = 8 + y;
source -= 128*y;
y = 0;
}
else
drawline = 8;
// if (y < 0)
// { // clipped
// drawline = 8 + y;
// source -= 256*y;
// y = 0;
// }
// else
// drawline = 8;
height = drawline;
width = 8;
vmax = height * vid.height / (float)vid.vconheight;
umax = width * vid.width / (float)vid.vconwidth;
{
byte *dest = vid.conbuffer + (y * vid.height / vid.vconheight) * vid.conrowbytes
+ (x * vid.width / vid.vconwidth);
for (v = 0; v < vmax; v++)
{
for (u = 0; u < umax; u++)
{
s = u * vid.vconwidth / vid.width
+ (v * vid.vconheight / vid.height) * 128;
if (source[s])
dest[u] = source[s];
}
dest += vid.conrowbytes;
}
}
}
/*
================
Draw_String
================
*/
void Draw_String (int x, int y, char *str)
{
while (*str)
{
Draw_Character (x, y, *str);
str++;
x += 8;
}
}
void Draw_String_Scaled (int x, int y, char *str)
{
while (*str)
{
Draw_Character_Scaled (x, y, *str);
str++;
x += 8;
}
}
/*
================
Draw_DebugChar
Draws a single character directly to the upper right corner of the screen.
This is for debugging lockups by drawing different chars in different parts
of the code.
================
*/
void Draw_DebugChar (char num)
{
byte *dest;
byte *source;
int drawline;
extern byte *draw_chars;
int row, col;
if (!vid.direct)
return; // don't have direct FB access, so no debugchars...
drawline = 8;
row = num>>4;
col = num&15;
source = draw_chars + (row<<10) + (col<<3);
dest = vid.direct + 312;
while (drawline--)
{
dest[0] = source[0];
dest[1] = source[1];
dest[2] = source[2];
dest[3] = source[3];
dest[4] = source[4];
dest[5] = source[5];
dest[6] = source[6];
dest[7] = source[7];
source += 128;
dest += 320;
}
}
/*
=============
Draw_Pic
=============
*/
void Draw_Pic (int x, int y, qpic_t *pic)
{
byte *dest, *source, tbyte;
unsigned short *pusdest;
int v, u;
/* if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
(unsigned)(y + pic->height) > vid.height)
{
Con_Printf("WARNING: Wrong coordinates for pic at %ix%i!\n", x, y);
return;
}
*/
if(x < 0) x = 0;
if(y < 0) y = 0;
if((x + pic->width) > vid.vconwidth) x = vid.vconwidth - pic->width;
if((y + pic->height) > vid.vconheight) x = vid.vconheight - pic->height;
source = pic->data;
if (r_pixbytes == 1)
{
dest = vid.buffer + y * vid.rowbytes + x;
if (pic->width & 7)
{ // general
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u++)
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
dest[u] = tbyte;
dest += vid.rowbytes;
source += pic->width;
}
}
else
{ // unwound
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u+=8)
{
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
dest[u] = tbyte;
if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
dest[u+1] = tbyte;
if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
dest[u+2] = tbyte;
if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
dest[u+3] = tbyte;
if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
dest[u+4] = tbyte;
if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
dest[u+5] = tbyte;
if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
dest[u+6] = tbyte;
if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
dest[u+7] = tbyte;
}
dest += vid.rowbytes;
source += pic->width;
}
}
}
else
{
// FIXME: pretranslate at load time?
pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u++)
{
tbyte = source[u];
if (tbyte != TRANSPARENT_COLOR)
{
pusdest[u] = d_8to16table[tbyte];
}
}
pusdest += vid.rowbytes >> 1;
source += pic->width;
}
}
}
void Draw_Pic_Scaled (int x, int y, qpic_t *pic)
{
byte *source, tbyte;
int v, u, s;
float vmax, umax;
if(x < 0) x = 0;
if(y < 0) y = 0;
if((x + pic->width) > vid.vconwidth) x = vid.vconwidth - pic->width;
if((y + pic->height) > vid.vconheight) x = vid.vconheight - pic->height;
source = pic->data;
vmax = pic->height * vid.height / (float)vid.vconheight;
umax = pic->width * vid.width / (float)vid.vconwidth;
byte *dest = vid.buffer + (y * vid.height / vid.vconheight) * vid.rowbytes + (x * vid.width / vid.vconwidth);
for (v = 0; v < vmax; v++)
{
for (u = 0; u < umax; u++)
{
s = u * vid.vconwidth / vid.width + (v * vid.vconheight / vid.height) * pic->width;
if ((tbyte = source[s]) != TRANSPARENT_COLOR)
dest[u] = tbyte;
}
dest += vid.rowbytes;
}
}
void Draw_Pic_Scaled_Two (int x, int y, qpic_t *pic, float scel)
{
byte *source, tbyte;
int v, u, s;
float vmax, umax;
float scal;
int scol;
if(x < 0) x = 0;
if(y < 0) y = 0;
if((x + pic->width) > vid.vconwidth) x = vid.vconwidth - pic->width;
if((y + pic->height) > vid.vconheight) x = vid.vconheight - pic->height;
source = pic->data;
scel = 2;
vmax = pic->height * vid.height / (float)vid.vconheight;
umax = pic->width * (scel / (scel * 2)) * vid.width / (float)vid.vconwidth;
{
byte *dest = vid.buffer + (y * vid.height / vid.vconheight) * vid.rowbytes
+ (x * vid.width / vid.vconwidth);
for (v = 0; v < vmax; v+=scel)
{
for (u = 0; u < umax; u++)
{
s = u * scel * vid.vconwidth / vid.width + (v * vid.vconheight / vid.height) * pic->width;
if ((tbyte = source[s]) != TRANSPARENT_COLOR)
{
dest[u] = tbyte;
}
}
dest += vid.rowbytes;
}
}
}
void Draw_PicCropped (int x, int y, qpic_t *pic)
{
byte *source, tbyte;
int v, u, height;
if ((x < 0) || (x+pic->width > vid.width))
{
Sys_Error("DrawPic: bad coordinates");
}
if (y >= vid.height || y+pic->height < 0)
{ // Totally off screen
return;
}
if (y+pic->height > vid.height)
{
height = vid.height-y;
}
else if (y < 0)
{
height = pic->height+y;
}
else
{
height = pic->height;
}
source = pic->data;
if (y < 0)
{
source += (pic->width * (-y));
y = 0;
}
if (r_pixbytes == 1)
{
byte *dest = vid.buffer + y * vid.rowbytes + x;
if (pic->width & 7)
{ // General
for (v = 0; v < height; v++)
{
for (u = 0; u < pic->width; u++)
{
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
{
dest[u] = tbyte;
}
}
dest += vid.rowbytes;
source += pic->width;
}
}
else
{ // Unwound
for (v = 0; v < height; v++)
{
for (u = 0; u < pic->width; u += 8)
{
if ((tbyte = source[u]) != TRANSPARENT_COLOR)
dest[u] = tbyte;
if ((tbyte = source[u+1]) != TRANSPARENT_COLOR)
dest[u+1] = tbyte;
if ((tbyte = source[u+2]) != TRANSPARENT_COLOR)
dest[u+2] = tbyte;
if ((tbyte = source[u+3]) != TRANSPARENT_COLOR)
dest[u+3] = tbyte;
if ((tbyte = source[u+4]) != TRANSPARENT_COLOR)
dest[u+4] = tbyte;
if ((tbyte = source[u+5]) != TRANSPARENT_COLOR)
dest[u+5] = tbyte;
if ((tbyte = source[u+6]) != TRANSPARENT_COLOR)
dest[u+6] = tbyte;
if ((tbyte = source[u+7]) != TRANSPARENT_COLOR)
dest[u+7] = tbyte;
}
dest += vid.rowbytes;
source += pic->width;
}
}
}
else /* r_pixbytes == 2 */
{
// FIXME: pretranslate at load time?
unsigned short *dest = (unsigned short *)vid.buffer + y * (vid.rowbytes>>1) + x;
// FIXME: transparency bits are missing
for (v = 0; v < height; v++)
{
for (u = 0; u < pic->width; u++)
{
tbyte = source[u];
if (tbyte != TRANSPARENT_COLOR)
{
dest[u] = d_8to16table[tbyte];
}
}
dest += vid.rowbytes>>1;
source += pic->width;
}
}
}
void Draw_PicCropped_Scaled (int x, int y, qpic_t *pic)
{
byte *source, tbyte;
int v, u, height, s;
float vmax, umax;
if ((x < 0) || (x+pic->width > vid.width))
{
Sys_Error("DrawPic: bad coordinates");
}
if (y >= vid.vconheight || y+pic->height < 0)
{ // Totally off screen
return;
}
if (y+pic->height > vid.vconheight)
{
height = vid.vconheight-y;
}
else if (y < 0)
{
height = pic->height+y;
}
else
{
height = pic->height;
}
source = pic->data;
if (y < 0)
{
source += (pic->width * (-y));
y = 0;
}
vmax = height * vid.height / (float)vid.vconheight;
umax = pic->width * vid.width / (float)vid.vconwidth;
{
byte *dest = vid.buffer + (y * vid.height/vid.vconheight) * vid.rowbytes
+ (x * vid.width / vid.vconwidth);
for (v = 0; v < vmax; v++)
{
for (u = 0; u < umax; u++)
{
s = u * vid.vconwidth / vid.width
+ (v * vid.vconheight / vid.height) * pic->width;
if ((tbyte = source[s]) != TRANSPARENT_COLOR)
{
dest[u] = tbyte;
}
}
dest += vid.rowbytes;
}
}
}
/*
=============
Draw_PicTranslate
=============
*/
void Draw_PicTranslate (int x, int y, qpic_t *pic, byte *translation)
{
byte *dest, *source, tbyte;
unsigned short *pusdest;
int v, u;
if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
(unsigned)(y + pic->height) > vid.height)
{
Sys_Error ("Draw_Pic: bad coordinates");
}
source = pic->data;
if (r_pixbytes == 1)
{
dest = vid.buffer + y * vid.rowbytes + x;
if (pic->width & 7)
{ // general
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u++)
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
dest[u] = translation[tbyte];
dest += vid.rowbytes;
source += pic->width;
}
}
else
{ // unwound
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u+=8)
{
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
dest[u] = translation[tbyte];
if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
dest[u+1] = translation[tbyte];
if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
dest[u+2] = translation[tbyte];
if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
dest[u+3] = translation[tbyte];
if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
dest[u+4] = translation[tbyte];
if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
dest[u+5] = translation[tbyte];
if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
dest[u+6] = translation[tbyte];
if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
dest[u+7] = translation[tbyte];
}
dest += vid.rowbytes;
source += pic->width;
}
}
}
else
{
// FIXME: pretranslate at load time?
pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u++)
{
tbyte = source[u];
if (tbyte != TRANSPARENT_COLOR)
{
pusdest[u] = d_8to16table[tbyte];
}
}
pusdest += vid.rowbytes >> 1;
source += pic->width;
}
}
}
/*
=============
Draw_PicTranslate_Scaled
=============
*/
void Draw_PicTranslate_Scaled (int x, int y, qpic_t *pic, byte *translation)
{
byte *source, tbyte;
int v, u, s;
float vmax, umax;
if (x < 0 || (x + pic->width) > vid.vconwidth ||
y < 0 || (y + pic->height) > vid.vconheight)
{
Sys_Error("DrawPic: bad coordinates\n");
}
source = pic->data;
vmax = pic->height * vid.height / (float)vid.vconheight;
umax = pic->width * vid.width / (float)vid.vconwidth;
{
byte *dest = vid.buffer + (y * vid.height / vid.vconheight) * vid.rowbytes
+ (x * vid.width / vid.vconwidth);
for (v = 0; v < vmax; v++)
{
for (u = 0; u < umax; u++)
{
s = u * vid.vconwidth / vid.width
+ (v * vid.vconheight / vid.height) * pic->width;
if ((tbyte = source[s]) != TRANSPARENT_COLOR)
{
dest[u] = translation[tbyte];
}
}
dest += vid.rowbytes;
}
}
}
void Draw_PicTranslatde_Scaled (int x, int y, qpic_t *pic, byte *translation)
{
byte *dest, *source, tbyte;
unsigned short *pusdest;
int v, u;
if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
(unsigned)(y + pic->height) > vid.height)
{
Sys_Error ("Draw_Pic: bad coordinates\n");
}
source = pic->data;
if (r_pixbytes == 1)
{
dest = vid.buffer + y * vid.rowbytes + x;
if (pic->width & 7)
{ // general
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u++)
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
dest[u] = translation[tbyte];
dest += vid.rowbytes;
source += pic->width;
}
}
else
{ // unwound
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u+=8)
{
if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
dest[u] = translation[tbyte];
if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
dest[u+1] = translation[tbyte];
if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
dest[u+2] = translation[tbyte];
if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
dest[u+3] = translation[tbyte];
if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
dest[u+4] = translation[tbyte];
if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
dest[u+5] = translation[tbyte];
if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
dest[u+6] = translation[tbyte];
if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
dest[u+7] = translation[tbyte];
}
dest += vid.rowbytes;
source += pic->width;
}
}
}
else
{
// FIXME: pretranslate at load time?
pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
for (v=0 ; v<pic->height ; v++)
{
for (u=0 ; u<pic->width ; u++)
{
tbyte = source[u];
if (tbyte != TRANSPARENT_COLOR)
{
pusdest[u] = d_8to16table[tbyte];
}
}
pusdest += vid.rowbytes >> 1;
source += pic->width;
}
}
}
void Draw_CharToConback (int num, byte *dest)
{
int row, col;
byte *source;
int drawline;
int x;
row = num>>4;
col = num&15;
source = draw_chars + (row<<10) + (col<<3);
drawline = 8;
while (drawline--)
{
for (x=0 ; x<8 ; x++)
if (source[x])
dest[x] = 0x60 + source[x];
source += 128;
dest += 320;
}
}
/*
================
Draw_ConsoleBackground
================
*/
void Draw_ConsoleBackground (int lines)
{
int x, y, v;
byte *src, *dest;
unsigned short *pusdest;
int f, fstep;
qpic_t *conback;
char ver[100];
conback = Draw_CachePic ("gfx/conback.lmp");
// hack the version number directly into the pic
#ifdef _WIN32
// sprintf (ver, "(%s, WinQuake) %4.2f", QIP_VERSION, (float)VERSION); // 2001-10-25 QIP version in the console background by Maddes
// dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); // 2001-10-25 Version printing fix by Maddes
#elif defined(X11)
// sprintf (ver, "(%s, X11 Quake %2.2f) %4.2f", QIP_VERSION, (float)X11_VERSION, (float)VERSION); // 2001-10-25 QIP version in the console background by Maddes
// dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); // 2001-10-25 Version printing fix by Maddes
#elif defined(__linux__)
// sprintf (ver, "(%s, Linux Quake %2.2f) %4.2f", QIP_VERSION, (float)LINUX_VERSION, (float)VERSION); // 2001-10-25 QIP version in the console background by Maddes
// dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); // 2001-10-25 Version printing fix by Maddes
#else
// sprintf (ver, "(%s) %4.2f", QIP_VERSION, VERSION); // 2001-10-25 QIP version in the console background by Maddes
// dest = conback->data + 320 - 43 + 320*186; // 2001-10-25 Version printing fix by Maddes
#endif
sprintf (ver, "%4.2f", VERSION); // 2001-10-25 QIP version in the console background by Maddes
dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); // 2001-10-25 Version printing fix by Maddes
for (x=0 ; x<strlen(ver) ; x++)
Draw_CharToConback (ver[x], dest+(x<<3));
// draw the pic
{
dest = vid.conbuffer;
for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
{
v = (vid.conheight - lines + y)*200/vid.conheight;
src = conback->data + v*320;
// 2000-08-04 "Transparent" console background for software renderer by Norberto Alfredo Bensa/Maddes start
f = 0;
fstep = 320*0x10000/vid.conwidth;
if (con_forcedup)
{
for (x = 0; x < vid.conwidth; x++, f+=fstep )
dest[x] = src[f >> 16];
}
else
{
int t;
t = con_alpha->value * (float)CON_ALPHASTATES;
if (t >= CON_ALPHASTATES)
{
t = CON_ALPHASTATES - 1;
}
t = fademask[t]>>((y&1)<<2);
for (x=0 ; x<vid.conwidth ; x+=4)
{
if (t&1) dest[x] = src[f>>16]; f+=fstep;
if (t&2) dest[x+1] = src[f>>16]; f+=fstep;
if (t&4) dest[x+2] = src[f>>16]; f+=fstep;
if (t&8) dest[x+3] = src[f>>16]; f+=fstep;
// 2000-08-04 "Transparent" console background for software renderer by Norberto Alfredo Bensa/Maddes end
}
}
}
}
}
/*
==============
R_DrawRect8
==============
*/
void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc,
int transparent)
{
byte t;
int i, j, srcdelta, destdelta;
byte *pdest;
pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x;
srcdelta = rowbytes - prect->width;
destdelta = vid.rowbytes - prect->width;
if (transparent)
{
for (i=0 ; i<prect->height ; i++)
{
for (j=0 ; j<prect->width ; j++)
{
t = *psrc;
if (t != TRANSPARENT_COLOR)
{
*pdest = t;
}
psrc++;
pdest++;
}
psrc += srcdelta;
pdest += destdelta;
}
}
else
{
for (i=0 ; i<prect->height ; i++)
{
memcpy (pdest, psrc, prect->width);
psrc += rowbytes;
pdest += vid.rowbytes;
}
}
}
/*
==============
R_DrawRect16
==============
*/
void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc,
int transparent)
{
byte t;
int i, j, srcdelta, destdelta;
unsigned short *pdest;
// FIXME: would it be better to pre-expand native-format versions?
pdest = (unsigned short *)vid.buffer +
(prect->y * (vid.rowbytes >> 1)) + prect->x;
srcdelta = rowbytes - prect->width;
destdelta = (vid.rowbytes >> 1) - prect->width;
if (transparent)
{
for (i=0 ; i<prect->height ; i++)
{
for (j=0 ; j<prect->width ; j++)
{
t = *psrc;
if (t != TRANSPARENT_COLOR)
{
*pdest = d_8to16table[t];
}
psrc++;
pdest++;
}
psrc += srcdelta;
pdest += destdelta;
}
}
else
{
for (i=0 ; i<prect->height ; i++)
{
for (j=0 ; j<prect->width ; j++)
{
*pdest = d_8to16table[*psrc];
psrc++;
pdest++;
}
psrc += srcdelta;
pdest += destdelta;
}
}
}
/*
=============
Draw_TileClear
This repeats a 64*64 tile graphic to fill the screen around a sized down
refresh window.
=============
*/
void Draw_TileClear (int x, int y, int w, int h)
{
int width, height, tileoffsetx, tileoffsety;
byte *psrc;
vrect_t vr;
r_rectdesc.rect.x = x;
r_rectdesc.rect.y = y;
r_rectdesc.rect.width = w;
r_rectdesc.rect.height = h;
vr.y = r_rectdesc.rect.y;
height = r_rectdesc.rect.height;
tileoffsety = vr.y % r_rectdesc.height;
while (height > 0)
{
vr.x = r_rectdesc.rect.x;
width = r_rectdesc.rect.width;
if (tileoffsety != 0)
vr.height = r_rectdesc.height - tileoffsety;
else
vr.height = r_rectdesc.height;
if (vr.height > height)
vr.height = height;
tileoffsetx = vr.x % r_rectdesc.width;
while (width > 0)
{
if (tileoffsetx != 0)
vr.width = r_rectdesc.width - tileoffsetx;
else
vr.width = r_rectdesc.width;
if (vr.width > width)
vr.width = width;
psrc = r_rectdesc.ptexbytes +
(tileoffsety * r_rectdesc.rowbytes) + tileoffsetx;
if (r_pixbytes == 1)
{
R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0);
}
else
{
R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0);
}
vr.x += vr.width;
width -= vr.width;
tileoffsetx = 0; // only the left tile can be left-clipped
}
vr.y += vr.height;
height -= vr.height;
tileoffsety = 0; // only the top tile can be top-clipped
}
}
/*
=============
Draw_Fill
Fills a box of pixels with a single color
=============
*/
void Draw_Fill (int x, int y, int w, int h, int c)
{
byte *dest;
unsigned short *pusdest;
unsigned uc;
int u, v;
if (r_pixbytes == 1)
{
dest = vid.buffer + y*vid.rowbytes + x;
for (v=0 ; v<h ; v++, dest += vid.rowbytes)
for (u=0 ; u<w ; u++)
dest[u] = c;
}
else
{
uc = d_8to16table[c];
pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
for (v=0 ; v<h ; v++, pusdest += (vid.rowbytes >> 1))
for (u=0 ; u<w ; u++)
pusdest[u] = uc;
}
}
void Draw_Fill_Scaled (int x, int y, int w, int h, int c)
{
int u, v;
float umax, vmax;
x = (x * vid.width) / vid.vconwidth;
y = (y * vid.height) / vid.vconheight;
if (x < 0 || x + w > vid.width ||
y < 0 || y + h > vid.height)
{
Con_Printf("Bad Draw_Fill SCALED(%d, %d, %d, %d, %c)\n", x, y, w, h, c);
return;
}
vmax = h * vid.height / (float)vid.vconheight;
umax = w * vid.width / (float)vid.vconwidth;
if (r_pixbytes == 1)
{
byte *dest = vid.buffer + y*vid.rowbytes + x;
for (v = 0; v < vmax; v++, dest += vid.rowbytes)
{
for (u = 0; u < umax; u++)
{
dest[u] = c;
}
}
}
}
//=============================================================================
extern cvar_t *r_menucolor;
/*
================
Draw_FadeScreen
================
*/
byte *obuf;
void Draw_FadeScreen (void)
{
int x,y;
byte *pbuf;
int mycol;
mycol = (int)r_menucolor->value;
VID_UnlockBuffer ();
S_ExtraUpdate ();
VID_LockBuffer ();
for (y=0 ; y<vid.height ; y++)
{
int t;
pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
t = (y & 1) << 1;
for (x=0 ; x<vid.width ; x++)
{
// Classic 0.8-1.06 look
if (mycol < 15){
pbuf[x] = menumap[pbuf[x]][mycol]; // new menu tint
}
else if (mycol == 17){
pbuf[x] = transTable[pbuf[x]][0]; // alpha blend a black
}
else if (mycol == 18){
pbuf[x] = transTable[42+rand()&5][ (pbuf[x])];
}
else if (mycol == 19){
pbuf[x] = transTable[pbuf[x+rand()&5]][ (pbuf[x+(rand()&(int)temp2->value)])];
}
else
{
// stupid v1.08 look:
if ((x & 3) != t)
pbuf[x] = 0;
}
}
}
VID_UnlockBuffer ();
S_ExtraUpdate ();
VID_LockBuffer ();
}
/*
================
Draw_BeginDisc
Draws the little blue disc in the corner of the screen.
Call before beginning any disc IO.
================
*/
void Draw_BeginDisc (void)
{
D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24);
}
/*
================
Draw_EndDisc
Erases the disc icon.
Call after completing any disc IO
================
*/
void Draw_EndDisc (void)
{
D_EndDirectRect (vid.width - 24, 0, 24, 24);
}