Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Iskhodnyy_kod_Doom

.pdf
Скачиваний:
7
Добавлен:
13.02.2015
Размер:
1.01 Mб
Скачать

#include "w_wad.h"

#include "r_local.h"

//Needs access to LFB (guess what). #include "v_video.h"

//State.

#include "doomstat.h"

//

?

 

#define MAXWIDTH

1120

#define MAXHEIGHT

832

//

status bar height at bottom of screen

#define SBARHEIGHT

32

//

//All drawing to the view buffer is accomplished in this file.

//The other refresh files only know about ccordinates,

//not the architecture of the frame buffer.

//Conveniently, the frame buffer is a linear one,

//and we need only the base address,

//and the total size == width*height*depth/8.,

//

byte*

viewimage;

int

viewwidth;

int

scaledviewwidth;

int

viewheight;

int

viewwindowx;

int

viewwindowy;

byte*

ylookup[MAXHEIGHT];

int

columnofs[MAXWIDTH];

//Color tables for different players,

//translate a limited part to another

//(color ramps used for suit colors).

byte

translations[3][256];

//

//R_DrawColumn

//Source is the top of the column to scale.

lighttable_t*

dc_colormap;

int

dc_x;

int

dc_yl;

int

dc_yh;

fixed_t

dc_iscale;

fixed_t

dc_texturemid;

//

first pixel in a column (possibly virtual)

byte*

dc_source;

//

just for profiling

 

int

dccount;

//

// A column is a vertical slice/span from a wall texture that,

631

//given the DOOM style restrictions on the view orientation,

//will always have constant z depth.

//Thus a special case loop for very fast rendering can

//be used. It has also been used with Wolfenstein 3D.

//

void R_DrawColumn (void)

{

int

count;

byte*

dest;

fixed_t

frac;

fixed_t

fracstep;

count = dc_yh - dc_yl;

// Zero length, column does not exceed a pixel. 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

//Framebuffer destination address.

//Use ylookup LUT to avoid multiply with ScreenWidth.

//Use columnofs LUT for subwindows?

dest = ylookup[dc_yl] + columnofs[dc_x];

//Determine scaling,

//which is the only mapping to be done. fracstep = dc_iscale;

frac = dc_texturemid + (dc_yl-centery)*fracstep;

//Inner loop that does the actual texture mapping,

//e.g. a DDA-lile scaling.

//This is as fast as it gets.

do

{

//Re-map color indices from wall texture column

//using a lighting/special effects LUT.

*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];

dest += SCREENWIDTH; frac += fracstep;

} while (count--);

}

//UNUSED.

//Loop unrolled. #if 0

void R_DrawColumn (void)

{

int

count;

byte*

source;

byte*

dest;

byte*

colormap;

unsigned

frac;

unsigned

fracstep;

unsigned

fracstep2;

632

unsigned

 

fracstep3;

unsigned

 

fracstep4;

count = dc_yh - dc_yl +

1;

source

=

dc_source;

 

colormap

= dc_colormap;

 

dest =

ylookup[dc_yl] +

columnofs[dc_x];

fracstep

= dc_iscale<<9;

 

frac =

(dc_texturemid +

(dc_yl-centery)*dc_iscale)<<9;

fracstep2 = fracstep+fracstep; fracstep3 = fracstep2+fracstep; fracstep4 = fracstep3+fracstep;

while (count >= 8)

{

dest[0] = colormap[source[frac>>25]];

dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]]; dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]]; dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]];

frac += fracstep4;

dest[SCREENWIDTH*4] = colormap[source[frac>>25]]; dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]]; dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]]; dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]];

frac += fracstep4; dest += SCREENWIDTH*8; count -= 8;

}

while (count > 0)

{

*dest = colormap[source[frac>>25]]; dest += SCREENWIDTH;

frac += fracstep; count--;

}

}

#endif

void R_DrawColumnLow (void)

{

int

count;

byte*

dest;

byte*

dest2;

fixed_t

frac;

fixed_t

fracstep;

count = dc_yh - dc_yl;

// Zero length. if (count < 0) return;

#ifdef RANGECHECK

if ((unsigned)dc_x >= SCREENWIDTH

||dc_yl < 0

||dc_yh >= SCREENHEIGHT)

{

633

I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);

}

//dccount++;

#endif

//Blocky mode, need to multiply by 2. dc_x <<= 1;

dest = ylookup[dc_yl] + columnofs[dc_x]; dest2 = ylookup[dc_yl] + columnofs[dc_x+1];

fracstep = dc_iscale;

frac = dc_texturemid + (dc_yl-centery)*fracstep;

do

{

// Hack. Does not work corretly.

*dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; dest += SCREENWIDTH;

dest2 += SCREENWIDTH; frac += fracstep;

} while (count--);

}

//

// Spectre/Invisibility.

//

#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;

//

//Framebuffer postprocessing.

//Creates a fuzzy image by copying pixels

//from adjacent ones to left and right.

//Used with an all black colormap, this

//could create the SHADOW effect,

//i.e. spectres and invisible players.

void R_DrawFuzzColumn (void)

{

int

count;

byte*

dest;

fixed_t

frac;

fixed_t

fracstep;

// Adjust borders. Low...

if (!dc_yl) dc_yl = 1;

634

//

.. and

high.

if

(dc_yh

== viewheight-1)

 

dc_yh

= viewheight - 2;

count = dc_yh - dc_yl;

// Zero length. 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

//Keep till detailshift bug in blocky mode fixed,

//or blocky mode removed.

/* WATCOM code if (detailshift)

{

if (dc_x & 1)

{

outpw (GC_INDEX,GC_READMAP+(2<<8) ); outp (SC_INDEX+1,12);

}

else

{

outpw (GC_INDEX,GC_READMAP); outp (SC_INDEX+1,3);

}

dest = destview + dc_yl*80 + (dc_x>>1);

}

else

{

outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); outp (SC_INDEX+1,1<<(dc_x&3));

dest = destview + dc_yl*80 + (dc_x>>2);

}*/

// Does not work with blocky mode.

dest = ylookup[dc_yl] + columnofs[dc_x];

//Looks familiar. fracstep = dc_iscale;

frac = dc_texturemid + (dc_yl-centery)*fracstep;

//Looks like an attempt at dithering,

//using the colormap #6 (of 0-31, a bit

//brighter than average).

do

{

//Lookup framebuffer, and retrieve

//a pixel that is either one column

//left or right of the current one.

//Add index from colormap to index.

*dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];

635

// Clamp table lookup index. if (++fuzzpos == FUZZTABLE)

fuzzpos = 0;

dest += SCREENWIDTH;

frac += fracstep; } while (count--);

}

//

//R_DrawTranslatedColumn

//Used to draw player sprites

//with the green colorramp mapped to others.

//Could be used with different translation

//tables, e.g. the lighter colored version

//of the BaronOfHell, the HellKnight, uses

//identical sprites, kinda brightened up.

//

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

// WATCOM VGA specific. /* Keep for fixing.

if (detailshift)

{

if (dc_x & 1)

outp (SC_INDEX+1,12);

else

outp (SC_INDEX+1,3);

dest = destview + dc_yl*80 + (dc_x>>1);

}

else

{

outp (SC_INDEX+1,1<<(dc_x&3));

dest = destview + dc_yl*80 + (dc_x>>2);

}*/

636

// FIXME. As above.

dest = ylookup[dc_yl] + columnofs[dc_x];

//Looks familiar. fracstep = dc_iscale;

frac = dc_texturemid + (dc_yl-centery)*fracstep;

//Here we do an additional index re-mapping.

do

{

//Translation tables are used

//to map certain colorramps to other ones,

//used with PLAY sprites.

//Thus the "green" ramp of the player 0 sprite

//is mapped to gray, red, black/indigo.

*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; dest += SCREENWIDTH;

frac += fracstep; } while (count--);

}

//

//R_InitTranslationTables

//Creates the translation tables to map

//the green color ramp to gray, brown, red.

//Assumes a given structure of the PLAYPAL.

//Could be read from a lump instead.

//

void R_InitTranslationTables (void)

{

int

i;

translationtables = Z_Malloc (256*3+255, PU_STATIC, 0); translationtables = (byte *)(( (int)translationtables + 255 )& ~255);

// translate just the 16 green colors for (i=0 ; i<256 ; i++)

{

if (i >= 0x70 && i<= 0x7f)

{

// map green ramp to gray, brown, red translationtables[i] = 0x60 + (i&0xf); translationtables [i+256] = 0x40 + (i&0xf); translationtables [i+512] = 0x20 + (i&0xf);

}

else

{

// Keep all other colors as is. translationtables[i] = translationtables[i+256]

= translationtables[i+512] = i;

}

}

}

//

// R_DrawSpan

637

//With DOOM style restrictions on view orientation,

//the floors and ceilings consist of horizontal slices

//or spans with constant z depth.

//However, rotation around the world z axis is possible,

//thus this mapping, while simpler and faster than

//perspective correct texture mapping, has to traverse

//the texture at an angle in all but a few cases.

//In consequence, flats are not stored by column (like walls),

//and the inner loop has to step in texture space u and v.

//

 

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;

// start of a 64*64 tile image

byte*

ds_source;

// just for profiling

 

int

dscount;

//

 

// Draws the actual span.

 

void R_DrawSpan (void)

 

{

 

fixed_t

xfrac;

fixed_t

yfrac;

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);

}

 

//

dscount++;

#endif

 

xfrac = ds_xfrac; yfrac = ds_yfrac;

dest = ylookup[ds_y] + columnofs[ds_x1];

// We do not check for zero spans here? count = ds_x2 - ds_x1;

do

{

// Current texture index in u,v.

spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);

// Lookup pixel from flat texture tile,

638

//re-index using light/colormap. *dest++ = ds_colormap[ds_source[spot]];

//Next step in u,v.

xfrac += ds_xstep; yfrac += ds_ystep;

} while (count--);

}

//UNUSED.

//Loop unrolled by 4. #if 0

void R_DrawSpan (void)

{

unsigned

position, step;

byte*

source;

byte*

colormap;

byte*

dest;

unsigned

count;

usingned

spot;

unsigned

value;

unsigned

temp;

unsigned

xtemp;

unsigned

ytemp;

position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff); step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);

source = ds_source; colormap = ds_colormap;

dest = ylookup[ds_y] + columnofs[ds_x1]; count = ds_x2 - ds_x1 + 1;

while (count >= 4)

{

ytemp = position>>4; ytemp = ytemp & 4032; xtemp = position>>26; spot = xtemp | ytemp; position += step;

dest[0] = colormap[source[spot]];

ytemp = position>>4; ytemp = ytemp & 4032; xtemp = position>>26; spot = xtemp | ytemp; position += step;

dest[1] = colormap[source[spot]];

ytemp = position>>4; ytemp = ytemp & 4032; xtemp = position>>26; spot = xtemp | ytemp; position += step;

dest[2] = colormap[source[spot]];

ytemp = position>>4; ytemp = ytemp & 4032; xtemp = position>>26; spot = xtemp | ytemp;

639

position += step;

dest[3] = colormap[source[spot]];

count -= 4; dest += 4;

}

while (count > 0)

{

ytemp = position>>4; ytemp = ytemp & 4032; xtemp = position>>26; spot = xtemp | ytemp; position += step;

*dest++ = colormap[source[spot]]; count--;

}

}

#endif

//

 

 

// Again..

 

//

 

 

void R_DrawSpanLow (void)

 

{

 

 

 

fixed_t

xfrac;

 

fixed_t

yfrac;

 

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);

 

}

 

//

dscount++;

 

#endif

xfrac = ds_xfrac; yfrac = ds_yfrac;

// Blocky mode, need to multiply by 2. ds_x1 <<= 1;

ds_x2 <<= 1;

dest = ylookup[ds_y] + columnofs[ds_x1];

count = ds_x2 - ds_x1; do

{

spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);

//Lowres/blocky mode does it twice,

//while scale is adjusted appropriately. *dest++ = ds_colormap[ds_source[spot]]; *dest++ = ds_colormap[ds_source[spot]];

xfrac += ds_xstep; yfrac += ds_ystep;

640

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]