#include "doomdef.h"
#include "deh_main.h"
#include "i_system.h"
#include "z_zone.h"
#include "w_wad.h"
#include "r_local.h"
#include "v_video.h"
#include "doomstat.h"
#define MAXWIDTH 1120
#define MAXHEIGHT 832
#define SBARHEIGHT 32
byte* viewimage;
int viewwidth;
int scaledviewwidth;
int viewheight;
int viewwindowx;
int viewwindowy;
byte* ylookup[MAXHEIGHT];
int columnofs[MAXWIDTH];
byte translations[3][256];
static byte *background_buffer = NULL;
lighttable_t* dc_colormap;
int dc_x;
int dc_yl;
int dc_yh;
fixed_t dc_iscale;
fixed_t dc_texturemid;
byte* dc_source;
int dccount;
void R_DrawColumn (void)
{
int count;
byte* dest;
fixed_t frac;
fixed_t fracstep;
count = dc_yh - dc_yl;
if (count < 0)
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH
|| dc_yl < 0
|| dc_yh >= SCREENHEIGHT)
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
#endif
dest = ylookup[dc_yl] + columnofs[dc_x];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
#if 0#endif
void R_DrawColumnLow (void)
{
int count;
byte* dest;
byte* dest2;
fixed_t frac;
fixed_t fracstep;
int x;
count = dc_yh - dc_yl;
if (count < 0)
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH
|| dc_yl < 0
|| dc_yh >= SCREENHEIGHT)
{
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
}
#endif
x = dc_x << 1;
dest = ylookup[dc_yl] + columnofs[x];
dest2 = ylookup[dc_yl] + columnofs[x+1];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
*dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
dest += SCREENWIDTH;
dest2 += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
#define FUZZTABLE 50
#define FUZZOFF (SCREENWIDTH)
int fuzzoffset[FUZZTABLE] =
{
FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
};
int fuzzpos = 0;
void R_DrawFuzzColumn (void)
{
int count;
byte* dest;
fixed_t frac;
fixed_t fracstep;
if (!dc_yl)
dc_yl = 1;
if (dc_yh == viewheight-1)
dc_yh = viewheight - 2;
count = dc_yh - dc_yl;
if (count < 0)
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH
|| dc_yl < 0 || dc_yh >= SCREENHEIGHT)
{
I_Error ("R_DrawFuzzColumn: %i to %i at %i",
dc_yl, dc_yh, dc_x);
}
#endif
dest = ylookup[dc_yl] + columnofs[dc_x];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
*dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
if (++fuzzpos == FUZZTABLE)
fuzzpos = 0;
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
void R_DrawFuzzColumnLow (void)
{
int count;
byte* dest;
byte* dest2;
fixed_t frac;
fixed_t fracstep;
int x;
if (!dc_yl)
dc_yl = 1;
if (dc_yh == viewheight-1)
dc_yh = viewheight - 2;
count = dc_yh - dc_yl;
if (count < 0)
return;
x = dc_x << 1;
#ifdef RANGECHECK
if ((unsigned)x >= SCREENWIDTH
|| dc_yl < 0 || dc_yh >= SCREENHEIGHT)
{
I_Error ("R_DrawFuzzColumn: %i to %i at %i",
dc_yl, dc_yh, dc_x);
}
#endif
dest = ylookup[dc_yl] + columnofs[x];
dest2 = ylookup[dc_yl] + columnofs[x+1];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
*dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
*dest2 = colormaps[6*256+dest2[fuzzoffset[fuzzpos]]];
if (++fuzzpos == FUZZTABLE)
fuzzpos = 0;
dest += SCREENWIDTH;
dest2 += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
byte* dc_translation;
byte* translationtables;
void R_DrawTranslatedColumn (void)
{
int count;
byte* dest;
fixed_t frac;
fixed_t fracstep;
count = dc_yh - dc_yl;
if (count < 0)
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= SCREENWIDTH
|| dc_yl < 0
|| dc_yh >= SCREENHEIGHT)
{
I_Error ( "R_DrawColumn: %i to %i at %i",
dc_yl, dc_yh, dc_x);
}
#endif
dest = ylookup[dc_yl] + columnofs[dc_x];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
dest += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
void R_DrawTranslatedColumnLow (void)
{
int count;
byte* dest;
byte* dest2;
fixed_t frac;
fixed_t fracstep;
int x;
count = dc_yh - dc_yl;
if (count < 0)
return;
x = dc_x << 1;
#ifdef RANGECHECK
if ((unsigned)x >= SCREENWIDTH
|| dc_yl < 0
|| dc_yh >= SCREENHEIGHT)
{
I_Error ( "R_DrawColumn: %i to %i at %i",
dc_yl, dc_yh, x);
}
#endif
dest = ylookup[dc_yl] + columnofs[x];
dest2 = ylookup[dc_yl] + columnofs[x+1];
fracstep = dc_iscale;
frac = dc_texturemid + (dc_yl-centery)*fracstep;
do
{
*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
*dest2 = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
dest += SCREENWIDTH;
dest2 += SCREENWIDTH;
frac += fracstep;
} while (count--);
}
void R_InitTranslationTables (void)
{
int i;
translationtables = Z_Malloc (256*3, PU_STATIC, 0);
for (i=0 ; i<256 ; i++)
{
if (i >= 0x70 && i<= 0x7f)
{
translationtables[i] = 0x60 + (i&0xf);
translationtables [i+256] = 0x40 + (i&0xf);
translationtables [i+512] = 0x20 + (i&0xf);
}
else
{
translationtables[i] = translationtables[i+256]
= translationtables[i+512] = i;
}
}
}
int ds_y;
int ds_x1;
int ds_x2;
lighttable_t* ds_colormap;
fixed_t ds_xfrac;
fixed_t ds_yfrac;
fixed_t ds_xstep;
fixed_t ds_ystep;
byte* ds_source;
int dscount;
void R_DrawSpan (void)
{
unsigned int position, step;
byte *dest;
int count;
int spot;
unsigned int xtemp, ytemp;
#ifdef RANGECHECK
if (ds_x2 < ds_x1
|| ds_x1<0
|| ds_x2>=SCREENWIDTH
|| (unsigned)ds_y>SCREENHEIGHT)
{
I_Error( "R_DrawSpan: %i to %i at %i",
ds_x1,ds_x2,ds_y);
}
#endif
position = ((ds_xfrac << 10) & 0xffff0000)
| ((ds_yfrac >> 6) & 0x0000ffff);
step = ((ds_xstep << 10) & 0xffff0000)
| ((ds_ystep >> 6) & 0x0000ffff);
dest = ylookup[ds_y] + columnofs[ds_x1];
count = ds_x2 - ds_x1;
do
{
ytemp = (position >> 4) & 0x0fc0;
xtemp = (position >> 26);
spot = xtemp | ytemp;
*dest++ = ds_colormap[ds_source[spot]];
position += step;
} while (count--);
}
#if 0#endif
void R_DrawSpanLow (void)
{
unsigned int position, step;
unsigned int xtemp, ytemp;
byte *dest;
int count;
int spot;
#ifdef RANGECHECK
if (ds_x2 < ds_x1
|| ds_x1<0
|| ds_x2>=SCREENWIDTH
|| (unsigned)ds_y>SCREENHEIGHT)
{
I_Error( "R_DrawSpan: %i to %i at %i",
ds_x1,ds_x2,ds_y);
}
#endif
position = ((ds_xfrac << 10) & 0xffff0000)
| ((ds_yfrac >> 6) & 0x0000ffff);
step = ((ds_xstep << 10) & 0xffff0000)
| ((ds_ystep >> 6) & 0x0000ffff);
count = (ds_x2 - ds_x1);
ds_x1 <<= 1;
ds_x2 <<= 1;
dest = ylookup[ds_y] + columnofs[ds_x1];
do
{
ytemp = (position >> 4) & 0x0fc0;
xtemp = (position >> 26);
spot = xtemp | ytemp;
*dest++ = ds_colormap[ds_source[spot]];
*dest++ = ds_colormap[ds_source[spot]];
position += step;
} while (count--);
}
void
R_InitBuffer
( int width,
int height )
{
int i;
viewwindowx = (SCREENWIDTH-width) >> 1;
for (i=0 ; i<width ; i++)
columnofs[i] = viewwindowx + i;
if (width == SCREENWIDTH)
viewwindowy = 0;
else
viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
for (i=0 ; i<height ; i++)
ylookup[i] = I_VideoBuffer + (i+viewwindowy)*SCREENWIDTH;
}
void R_FillBackScreen (void)
{
byte* src;
byte* dest;
int x;
int y;
patch_t* patch;
char *name1 = DEH_String("FLOOR7_2");
char *name2 = DEH_String("GRNROCK");
char *name;
if (scaledviewwidth == SCREENWIDTH)
{
if (background_buffer != NULL)
{
Z_Free(background_buffer);
background_buffer = NULL;
}
return;
}
if (background_buffer == NULL)
{
background_buffer = Z_Malloc(SCREENWIDTH * (SCREENHEIGHT - SBARHEIGHT),
PU_STATIC, NULL);
}
if (gamemode == commercial)
name = name2;
else
name = name1;
src = W_CacheLumpName(name, PU_CACHE);
dest = background_buffer;
for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
{
for (x=0 ; x<SCREENWIDTH/64 ; x++)
{
memcpy (dest, src+((y&63)<<6), 64);
dest += 64;
}
if (SCREENWIDTH&63)
{
memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
dest += (SCREENWIDTH&63);
}
}
V_UseBuffer(background_buffer);
patch = W_CacheLumpName(DEH_String("brdr_t"),PU_CACHE);
for (x=0 ; x<scaledviewwidth ; x+=8)
V_DrawPatch(viewwindowx+x, viewwindowy-8, patch);
patch = W_CacheLumpName(DEH_String("brdr_b"),PU_CACHE);
for (x=0 ; x<scaledviewwidth ; x+=8)
V_DrawPatch(viewwindowx+x, viewwindowy+viewheight, patch);
patch = W_CacheLumpName(DEH_String("brdr_l"),PU_CACHE);
for (y=0 ; y<viewheight ; y+=8)
V_DrawPatch(viewwindowx-8, viewwindowy+y, patch);
patch = W_CacheLumpName(DEH_String("brdr_r"),PU_CACHE);
for (y=0 ; y<viewheight ; y+=8)
V_DrawPatch(viewwindowx+scaledviewwidth, viewwindowy+y, patch);
V_DrawPatch(viewwindowx-8,
viewwindowy-8,
W_CacheLumpName(DEH_String("brdr_tl"),PU_CACHE));
V_DrawPatch(viewwindowx+scaledviewwidth,
viewwindowy-8,
W_CacheLumpName(DEH_String("brdr_tr"),PU_CACHE));
V_DrawPatch(viewwindowx-8,
viewwindowy+viewheight,
W_CacheLumpName(DEH_String("brdr_bl"),PU_CACHE));
V_DrawPatch(viewwindowx+scaledviewwidth,
viewwindowy+viewheight,
W_CacheLumpName(DEH_String("brdr_br"),PU_CACHE));
V_RestoreBuffer();
}
void
R_VideoErase
( unsigned ofs,
int count )
{
if (background_buffer != NULL)
{
memcpy(I_VideoBuffer + ofs, background_buffer + ofs, count);
}
}
void R_DrawViewBorder (void)
{
int top;
int side;
int ofs;
int i;
if (scaledviewwidth == SCREENWIDTH)
return;
top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2;
side = (SCREENWIDTH-scaledviewwidth)/2;
R_VideoErase (0, top*SCREENWIDTH+side);
ofs = (viewheight+top)*SCREENWIDTH-side;
R_VideoErase (ofs, top*SCREENWIDTH+side);
ofs = top*SCREENWIDTH + SCREENWIDTH-side;
side <<= 1;
for (i=1 ; i<viewheight ; i++)
{
R_VideoErase (ofs, side);
ofs += SCREENWIDTH;
}
V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT);
}