Annotation of doom/r_draw.c, revision 1.1.1.4

1.1.1.3   root        1: // Emacs style mode select   -*- C++ -*- 
                      2: //-----------------------------------------------------------------------------
                      3: //
                      4: // $Id:$
                      5: //
                      6: // Copyright (C) 1993-1996 by id Software, Inc.
                      7: //
1.1.1.4 ! root        8: // This program is free software; you can redistribute it and/or
        !             9: // modify it under the terms of the GNU General Public License
        !            10: // as published by the Free Software Foundation; either version 2
        !            11: // of the License, or (at your option) any later version.
1.1.1.3   root       12: //
1.1.1.4 ! root       13: // This program is distributed in the hope that it will be useful,
1.1.1.3   root       14: // but WITHOUT ANY WARRANTY; without even the implied warranty of
1.1.1.4 ! root       15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            16: // GNU General Public License for more details.
1.1.1.3   root       17: //
                     18: // $Log:$
                     19: //
                     20: // DESCRIPTION:
                     21: //     The actual span/column drawing functions.
                     22: //     Here find the main potential for optimization,
                     23: //      e.g. inline assembly, different algorithms.
                     24: //
                     25: //-----------------------------------------------------------------------------
1.1       root       26: 
                     27: 
1.1.1.3   root       28: static const char
                     29: rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
1.1       root       30: 
                     31: 
1.1.1.3   root       32: #include "doomdef.h"
1.1       root       33: 
1.1.1.3   root       34: #include "i_system.h"
                     35: #include "z_zone.h"
                     36: #include "w_wad.h"
1.1       root       37: 
1.1.1.3   root       38: #include "r_local.h"
1.1       root       39: 
1.1.1.3   root       40: // Needs access to LFB (guess what).
                     41: #include "v_video.h"
1.1       root       42: 
1.1.1.3   root       43: // State.
                     44: #include "doomstat.h"
1.1       root       45: 
                     46: 
1.1.1.3   root       47: // ?
                     48: #define MAXWIDTH                       1120
                     49: #define MAXHEIGHT                      832
1.1       root       50: 
1.1.1.3   root       51: // status bar height at bottom of screen
                     52: #define SBARHEIGHT             32
1.1       root       53: 
1.1.1.3   root       54: //
                     55: // All drawing to the view buffer is accomplished in this file.
                     56: // The other refresh files only know about ccordinates,
                     57: //  not the architecture of the frame buffer.
                     58: // Conveniently, the frame buffer is a linear one,
                     59: //  and we need only the base address,
                     60: //  and the total size == width*height*depth/8.,
                     61: //
1.1       root       62: 
                     63: 
1.1.1.3   root       64: byte*          viewimage; 
                     65: int            viewwidth;
                     66: int            scaledviewwidth;
                     67: int            viewheight;
                     68: int            viewwindowx;
                     69: int            viewwindowy; 
                     70: byte*          ylookup[MAXHEIGHT]; 
                     71: int            columnofs[MAXWIDTH]; 
                     72: 
                     73: // Color tables for different players,
                     74: //  translate a limited part to another
                     75: //  (color ramps used for  suit colors).
                     76: //
                     77: byte           translations[3][256];   
                     78:  
                     79:  
1.1       root       80: 
1.1.1.2   root       81: 
                     82: //
1.1.1.3   root       83: // R_DrawColumn
                     84: // Source is the top of the column to scale.
1.1.1.2   root       85: //
1.1.1.3   root       86: lighttable_t*          dc_colormap; 
                     87: int                    dc_x; 
                     88: int                    dc_yl; 
                     89: int                    dc_yh; 
                     90: fixed_t                        dc_iscale; 
                     91: fixed_t                        dc_texturemid;
1.1.1.2   root       92: 
1.1.1.3   root       93: // first pixel in a column (possibly virtual) 
                     94: byte*                  dc_source;              
1.1       root       95: 
1.1.1.3   root       96: // just for profiling 
                     97: int                    dccount;
1.1       root       98: 
1.1.1.3   root       99: //
                    100: // A column is a vertical slice/span from a wall texture that,
                    101: //  given the DOOM style restrictions on the view orientation,
                    102: //  will always have constant z depth.
                    103: // Thus a special case loop for very fast rendering can
                    104: //  be used. It has also been used with Wolfenstein 3D.
                    105: // 
                    106: void R_DrawColumn (void) 
                    107: { 
                    108:     int                        count; 
                    109:     byte*              dest; 
                    110:     fixed_t            frac;
                    111:     fixed_t            fracstep;        
                    112:  
                    113:     count = dc_yh - dc_yl; 
                    114: 
                    115:     // Zero length, column does not exceed a pixel.
                    116:     if (count < 0) 
                    117:        return; 
                    118:                                 
                    119: #ifdef RANGECHECK 
                    120:     if ((unsigned)dc_x >= SCREENWIDTH
                    121:        || dc_yl < 0
                    122:        || dc_yh >= SCREENHEIGHT) 
                    123:        I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); 
                    124: #endif 
                    125: 
                    126:     // Framebuffer destination address.
                    127:     // Use ylookup LUT to avoid multiply with ScreenWidth.
                    128:     // Use columnofs LUT for subwindows? 
                    129:     dest = ylookup[dc_yl] + columnofs[dc_x];  
                    130: 
                    131:     // Determine scaling,
                    132:     //  which is the only mapping to be done.
                    133:     fracstep = dc_iscale; 
                    134:     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
                    135: 
                    136:     // Inner loop that does the actual texture mapping,
                    137:     //  e.g. a DDA-lile scaling.
                    138:     // This is as fast as it gets.
                    139:     do 
                    140:     {
                    141:        // Re-map color indices from wall texture column
                    142:        //  using a lighting/special effects LUT.
                    143:        *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
                    144:        
                    145:        dest += SCREENWIDTH; 
                    146:        frac += fracstep;
                    147:        
                    148:     } while (count--); 
                    149: } 
                    150: 
                    151: 
                    152: 
                    153: // UNUSED.
                    154: // Loop unrolled.
                    155: #if 0
                    156: void R_DrawColumn (void) 
                    157: { 
                    158:     int                        count; 
                    159:     byte*              source;
                    160:     byte*              dest;
                    161:     byte*              colormap;
                    162:     
                    163:     unsigned           frac;
                    164:     unsigned           fracstep;
                    165:     unsigned           fracstep2;
                    166:     unsigned           fracstep3;
                    167:     unsigned           fracstep4;       
                    168:  
                    169:     count = dc_yh - dc_yl + 1; 
                    170: 
                    171:     source = dc_source;
                    172:     colormap = dc_colormap;             
                    173:     dest = ylookup[dc_yl] + columnofs[dc_x];  
                    174:         
                    175:     fracstep = dc_iscale<<9; 
                    176:     frac = (dc_texturemid + (dc_yl-centery)*dc_iscale)<<9; 
                    177:  
                    178:     fracstep2 = fracstep+fracstep;
                    179:     fracstep3 = fracstep2+fracstep;
                    180:     fracstep4 = fracstep3+fracstep;
                    181:        
                    182:     while (count >= 8) 
                    183:     { 
                    184:        dest[0] = colormap[source[frac>>25]]; 
                    185:        dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]]; 
                    186:        dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]]; 
                    187:        dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]];
                    188:        
                    189:        frac += fracstep4; 
                    190: 
                    191:        dest[SCREENWIDTH*4] = colormap[source[frac>>25]]; 
                    192:        dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]]; 
                    193:        dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]]; 
                    194:        dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]]; 
                    195: 
                    196:        frac += fracstep4; 
                    197:        dest += SCREENWIDTH*8; 
                    198:        count -= 8;
                    199:     } 
                    200:        
                    201:     while (count > 0)
                    202:     { 
                    203:        *dest = colormap[source[frac>>25]]; 
                    204:        dest += SCREENWIDTH; 
                    205:        frac += fracstep; 
                    206:        count--;
                    207:     } 
                    208: }
                    209: #endif
                    210: 
                    211: 
                    212: void R_DrawColumnLow (void) 
                    213: { 
                    214:     int                        count; 
                    215:     byte*              dest; 
                    216:     byte*              dest2;
                    217:     fixed_t            frac;
                    218:     fixed_t            fracstep;        
                    219:  
                    220:     count = dc_yh - dc_yl; 
                    221: 
                    222:     // Zero length.
                    223:     if (count < 0) 
                    224:        return; 
                    225:                                 
                    226: #ifdef RANGECHECK 
                    227:     if ((unsigned)dc_x >= SCREENWIDTH
                    228:        || dc_yl < 0
                    229:        || dc_yh >= SCREENHEIGHT)
                    230:     {
                    231:        
                    232:        I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
                    233:     }
                    234:     // dccount++; 
                    235: #endif 
                    236:     // Blocky mode, need to multiply by 2.
                    237:     dc_x <<= 1;
                    238:     
                    239:     dest = ylookup[dc_yl] + columnofs[dc_x];
                    240:     dest2 = ylookup[dc_yl] + columnofs[dc_x+1];
                    241:     
                    242:     fracstep = dc_iscale; 
                    243:     frac = dc_texturemid + (dc_yl-centery)*fracstep;
                    244:     
                    245:     do 
                    246:     {
                    247:        // Hack. Does not work corretly.
                    248:        *dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
                    249:        dest += SCREENWIDTH;
                    250:        dest2 += SCREENWIDTH;
                    251:        frac += fracstep; 
1.1       root      252: 
1.1.1.3   root      253:     } while (count--);
1.1       root      254: }
                    255: 
                    256: 
1.1.1.3   root      257: //
                    258: // Spectre/Invisibility.
                    259: //
                    260: #define FUZZTABLE              50 
                    261: #define FUZZOFF        (SCREENWIDTH)
                    262: 
1.1       root      263: 
1.1.1.3   root      264: int    fuzzoffset[FUZZTABLE] =
1.1       root      265: {
1.1.1.3   root      266:     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
                    267:     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
                    268:     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
                    269:     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
                    270:     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
                    271:     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
                    272:     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF 
                    273: }; 
1.1       root      274: 
1.1.1.3   root      275: int    fuzzpos = 0; 
1.1       root      276: 
                    277: 
1.1.1.2   root      278: //
1.1.1.3   root      279: // Framebuffer postprocessing.
                    280: // Creates a fuzzy image by copying pixels
                    281: //  from adjacent ones to left and right.
                    282: // Used with an all black colormap, this
                    283: //  could create the SHADOW effect,
                    284: //  i.e. spectres and invisible players.
1.1.1.2   root      285: //
1.1.1.3   root      286: void R_DrawFuzzColumn (void) 
                    287: { 
                    288:     int                        count; 
                    289:     byte*              dest; 
                    290:     fixed_t            frac;
                    291:     fixed_t            fracstep;        
                    292: 
                    293:     // Adjust borders. Low... 
                    294:     if (!dc_yl) 
                    295:        dc_yl = 1;
                    296: 
                    297:     // .. and high.
                    298:     if (dc_yh == viewheight-1) 
                    299:        dc_yh = viewheight - 2; 
                    300:                 
                    301:     count = dc_yh - dc_yl; 
                    302: 
                    303:     // Zero length.
                    304:     if (count < 0) 
                    305:        return; 
                    306: 
                    307:     
                    308: #ifdef RANGECHECK 
                    309:     if ((unsigned)dc_x >= SCREENWIDTH
                    310:        || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
                    311:     {
                    312:        I_Error ("R_DrawFuzzColumn: %i to %i at %i",
                    313:                 dc_yl, dc_yh, dc_x);
                    314:     }
1.1       root      315: #endif
                    316: 
                    317: 
1.1.1.3   root      318:     // Keep till detailshift bug in blocky mode fixed,
                    319:     //  or blocky mode removed.
                    320:     /* WATCOM code 
                    321:     if (detailshift)
                    322:     {
                    323:        if (dc_x & 1)
1.1       root      324:        {
1.1.1.3   root      325:            outpw (GC_INDEX,GC_READMAP+(2<<8) ); 
                    326:            outp (SC_INDEX+1,12); 
                    327:        }
                    328:        else
                    329:        {
                    330:            outpw (GC_INDEX,GC_READMAP); 
                    331:            outp (SC_INDEX+1,3); 
                    332:        }
                    333:        dest = destview + dc_yl*80 + (dc_x>>1); 
                    334:     }
                    335:     else
                    336:     {
                    337:        outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); 
                    338:        outp (SC_INDEX+1,1<<(dc_x&3)); 
                    339:        dest = destview + dc_yl*80 + (dc_x>>2); 
                    340:     }*/
                    341: 
                    342:     
                    343:     // Does not work with blocky mode.
                    344:     dest = ylookup[dc_yl] + columnofs[dc_x];
                    345: 
                    346:     // Looks familiar.
                    347:     fracstep = dc_iscale; 
                    348:     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
                    349: 
                    350:     // Looks like an attempt at dithering,
                    351:     //  using the colormap #6 (of 0-31, a bit
                    352:     //  brighter than average).
                    353:     do 
                    354:     {
                    355:        // Lookup framebuffer, and retrieve
                    356:        //  a pixel that is either one column
                    357:        //  left or right of the current one.
                    358:        // Add index from colormap to index.
                    359:        *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; 
                    360: 
                    361:        // Clamp table lookup index.
                    362:        if (++fuzzpos == FUZZTABLE) 
                    363:            fuzzpos = 0;
                    364:        
                    365:        dest += SCREENWIDTH;
                    366: 
                    367:        frac += fracstep; 
                    368:     } while (count--); 
                    369: } 
                    370:  
                    371:   
                    372:  
1.1       root      373: 
1.1.1.2   root      374: //
1.1.1.3   root      375: // R_DrawTranslatedColumn
                    376: // Used to draw player sprites
                    377: //  with the green colorramp mapped to others.
                    378: // Could be used with different translation
                    379: //  tables, e.g. the lighter colored version
                    380: //  of the BaronOfHell, the HellKnight, uses
                    381: //  identical sprites, kinda brightened up.
1.1.1.2   root      382: //
1.1.1.3   root      383: byte*  dc_translation;
                    384: byte*  translationtables;
1.1.1.2   root      385: 
1.1.1.3   root      386: void R_DrawTranslatedColumn (void) 
                    387: { 
                    388:     int                        count; 
                    389:     byte*              dest; 
                    390:     fixed_t            frac;
                    391:     fixed_t            fracstep;        
                    392:  
                    393:     count = dc_yh - dc_yl; 
                    394:     if (count < 0) 
                    395:        return; 
                    396:                                 
                    397: #ifdef RANGECHECK 
                    398:     if ((unsigned)dc_x >= SCREENWIDTH
                    399:        || dc_yl < 0
                    400:        || dc_yh >= SCREENHEIGHT)
                    401:     {
                    402:        I_Error ( "R_DrawColumn: %i to %i at %i",
                    403:                  dc_yl, dc_yh, dc_x);
                    404:     }
                    405:     
                    406: #endif 
                    407: 
                    408: 
                    409:     // WATCOM VGA specific.
                    410:     /* Keep for fixing.
                    411:     if (detailshift)
                    412:     {
                    413:        if (dc_x & 1)
                    414:            outp (SC_INDEX+1,12); 
                    415:        else
                    416:            outp (SC_INDEX+1,3);
1.1.1.2   root      417:        
1.1.1.3   root      418:        dest = destview + dc_yl*80 + (dc_x>>1); 
                    419:     }
                    420:     else
                    421:     {
                    422:        outp (SC_INDEX+1,1<<(dc_x&3)); 
                    423: 
                    424:        dest = destview + dc_yl*80 + (dc_x>>2); 
                    425:     }*/
                    426: 
                    427:     
                    428:     // FIXME. As above.
                    429:     dest = ylookup[dc_yl] + columnofs[dc_x]; 
                    430: 
                    431:     // Looks familiar.
                    432:     fracstep = dc_iscale; 
                    433:     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
                    434: 
                    435:     // Here we do an additional index re-mapping.
                    436:     do 
                    437:     {
                    438:        // Translation tables are used
                    439:        //  to map certain colorramps to other ones,
                    440:        //  used with PLAY sprites.
                    441:        // Thus the "green" ramp of the player 0 sprite
                    442:        //  is mapped to gray, red, black/indigo. 
                    443:        *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
                    444:        dest += SCREENWIDTH;
                    445:        
                    446:        frac += fracstep; 
                    447:     } while (count--); 
                    448: } 
                    449: 
                    450: 
1.1.1.2   root      451: 
                    452: 
1.1       root      453: //
1.1.1.3   root      454: // R_InitTranslationTables
                    455: // Creates the translation tables to map
                    456: //  the green color ramp to gray, brown, red.
                    457: // Assumes a given structure of the PLAYPAL.
                    458: // Could be read from a lump instead.
1.1       root      459: //
                    460: void R_InitTranslationTables (void)
                    461: {
1.1.1.3   root      462:     int                i;
                    463:        
                    464:     translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
                    465:     translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
                    466:     
                    467:     // translate just the 16 green colors
                    468:     for (i=0 ; i<256 ; i++)
                    469:     {
                    470:        if (i >= 0x70 && i<= 0x7f)
                    471:        {
                    472:            // map green ramp to gray, brown, red
                    473:            translationtables[i] = 0x60 + (i&0xf);
                    474:            translationtables [i+256] = 0x40 + (i&0xf);
                    475:            translationtables [i+512] = 0x20 + (i&0xf);
                    476:        }
                    477:        else
1.1.1.2   root      478:        {
1.1.1.3   root      479:            // Keep all other colors as is.
                    480:            translationtables[i] = translationtables[i+256] 
                    481:                = translationtables[i+512] = i;
1.1       root      482:        }
1.1.1.3   root      483:     }
1.1       root      484: }
                    485: 
                    486: 
                    487: 
                    488: 
1.1.1.3   root      489: //
                    490: // R_DrawSpan 
                    491: // With DOOM style restrictions on view orientation,
                    492: //  the floors and ceilings consist of horizontal slices
                    493: //  or spans with constant z depth.
                    494: // However, rotation around the world z axis is possible,
                    495: //  thus this mapping, while simpler and faster than
                    496: //  perspective correct texture mapping, has to traverse
                    497: //  the texture at an angle in all but a few cases.
                    498: // In consequence, flats are not stored by column (like walls),
                    499: //  and the inner loop has to step in texture space u and v.
                    500: //
                    501: int                    ds_y; 
                    502: int                    ds_x1; 
                    503: int                    ds_x2;
                    504: 
                    505: lighttable_t*          ds_colormap; 
                    506: 
                    507: fixed_t                        ds_xfrac; 
                    508: fixed_t                        ds_yfrac; 
                    509: fixed_t                        ds_xstep; 
                    510: fixed_t                        ds_ystep;
1.1       root      511: 
1.1.1.3   root      512: // start of a 64*64 tile image 
                    513: byte*                  ds_source;      
1.1       root      514: 
1.1.1.3   root      515: // just for profiling
                    516: int                    dscount;
1.1       root      517: 
                    518: 
1.1.1.3   root      519: //
                    520: // Draws the actual span.
                    521: void R_DrawSpan (void) 
                    522: { 
                    523:     fixed_t            xfrac;
                    524:     fixed_t            yfrac; 
                    525:     byte*              dest; 
                    526:     int                        count;
                    527:     int                        spot; 
                    528:         
                    529: #ifdef RANGECHECK 
                    530:     if (ds_x2 < ds_x1
                    531:        || ds_x1<0
                    532:        || ds_x2>=SCREENWIDTH  
                    533:        || (unsigned)ds_y>SCREENHEIGHT)
                    534:     {
                    535:        I_Error( "R_DrawSpan: %i to %i at %i",
                    536:                 ds_x1,ds_x2,ds_y);
                    537:     }
                    538: //     dscount++; 
                    539: #endif 
                    540: 
                    541:     
                    542:     xfrac = ds_xfrac; 
                    543:     yfrac = ds_yfrac; 
                    544:         
                    545:     dest = ylookup[ds_y] + columnofs[ds_x1];
                    546: 
                    547:     // We do not check for zero spans here?
                    548:     count = ds_x2 - ds_x1; 
                    549: 
                    550:     do 
                    551:     {
                    552:        // Current texture index in u,v.
                    553:        spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
                    554: 
                    555:        // Lookup pixel from flat texture tile,
                    556:        //  re-index using light/colormap.
                    557:        *dest++ = ds_colormap[ds_source[spot]];
                    558: 
                    559:        // Next step in u,v.
                    560:        xfrac += ds_xstep; 
                    561:        yfrac += ds_ystep;
                    562:        
                    563:     } while (count--); 
                    564: } 
1.1       root      565: 
                    566: 
                    567: 
1.1.1.3   root      568: // UNUSED.
                    569: // Loop unrolled by 4.
                    570: #if 0
                    571: void R_DrawSpan (void) 
                    572: { 
                    573:     unsigned   position, step;
                    574: 
                    575:     byte*      source;
                    576:     byte*      colormap;
                    577:     byte*      dest;
                    578:     
                    579:     unsigned   count;
                    580:     usingned   spot; 
                    581:     unsigned   value;
                    582:     unsigned   temp;
                    583:     unsigned   xtemp;
                    584:     unsigned   ytemp;
                    585:                
                    586:     position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff);
                    587:     step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);
                    588:                
                    589:     source = ds_source;
                    590:     colormap = ds_colormap;
                    591:     dest = ylookup[ds_y] + columnofs[ds_x1];    
                    592:     count = ds_x2 - ds_x1 + 1; 
                    593:        
                    594:     while (count >= 4) 
                    595:     { 
                    596:        ytemp = position>>4;
                    597:        ytemp = ytemp & 4032;
                    598:        xtemp = position>>26;
                    599:        spot = xtemp | ytemp;
                    600:        position += step;
                    601:        dest[0] = colormap[source[spot]]; 
                    602: 
                    603:        ytemp = position>>4;
                    604:        ytemp = ytemp & 4032;
                    605:        xtemp = position>>26;
                    606:        spot = xtemp | ytemp;
                    607:        position += step;
                    608:        dest[1] = colormap[source[spot]];
                    609:        
                    610:        ytemp = position>>4;
                    611:        ytemp = ytemp & 4032;
                    612:        xtemp = position>>26;
                    613:        spot = xtemp | ytemp;
                    614:        position += step;
                    615:        dest[2] = colormap[source[spot]];
                    616:        
                    617:        ytemp = position>>4;
                    618:        ytemp = ytemp & 4032;
                    619:        xtemp = position>>26;
                    620:        spot = xtemp | ytemp;
                    621:        position += step;
                    622:        dest[3] = colormap[source[spot]]; 
                    623:                
                    624:        count -= 4;
                    625:        dest += 4;
                    626:     } 
                    627:     while (count > 0) 
                    628:     { 
                    629:        ytemp = position>>4;
                    630:        ytemp = ytemp & 4032;
                    631:        xtemp = position>>26;
                    632:        spot = xtemp | ytemp;
                    633:        position += step;
                    634:        *dest++ = colormap[source[spot]]; 
                    635:        count--;
                    636:     } 
                    637: } 
                    638: #endif
1.1       root      639: 
                    640: 
1.1.1.3   root      641: //
                    642: // Again..
                    643: //
                    644: void R_DrawSpanLow (void) 
                    645: { 
                    646:     fixed_t            xfrac;
                    647:     fixed_t            yfrac; 
                    648:     byte*              dest; 
                    649:     int                        count;
                    650:     int                        spot; 
                    651:         
                    652: #ifdef RANGECHECK 
                    653:     if (ds_x2 < ds_x1
                    654:        || ds_x1<0
                    655:        || ds_x2>=SCREENWIDTH  
                    656:        || (unsigned)ds_y>SCREENHEIGHT)
                    657:     {
                    658:        I_Error( "R_DrawSpan: %i to %i at %i",
                    659:                 ds_x1,ds_x2,ds_y);
                    660:     }
                    661: //     dscount++; 
                    662: #endif 
                    663:         
                    664:     xfrac = ds_xfrac; 
                    665:     yfrac = ds_yfrac; 
                    666: 
                    667:     // Blocky mode, need to multiply by 2.
                    668:     ds_x1 <<= 1;
                    669:     ds_x2 <<= 1;
                    670:     
                    671:     dest = ylookup[ds_y] + columnofs[ds_x1];
                    672:   
                    673:     
                    674:     count = ds_x2 - ds_x1; 
                    675:     do 
                    676:     { 
                    677:        spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
                    678:        // Lowres/blocky mode does it twice,
                    679:        //  while scale is adjusted appropriately.
                    680:        *dest++ = ds_colormap[ds_source[spot]]; 
                    681:        *dest++ = ds_colormap[ds_source[spot]];
1.1       root      682:        
1.1.1.3   root      683:        xfrac += ds_xstep; 
                    684:        yfrac += ds_ystep; 
                    685: 
                    686:     } while (count--); 
1.1       root      687: }
                    688: 
1.1.1.3   root      689: //
                    690: // R_InitBuffer 
                    691: // Creats lookup tables that avoid
                    692: //  multiplies and other hazzles
                    693: //  for getting the framebuffer address
                    694: //  of a pixel to draw.
                    695: //
                    696: void
                    697: R_InitBuffer
                    698: ( int          width,
                    699:   int          height ) 
                    700: { 
                    701:     int                i; 
                    702: 
                    703:     // Handle resize,
                    704:     //  e.g. smaller view windows
                    705:     //  with border and/or status bar.
                    706:     viewwindowx = (SCREENWIDTH-width) >> 1; 
                    707: 
                    708:     // Column offset. For windows.
                    709:     for (i=0 ; i<width ; i++) 
                    710:        columnofs[i] = viewwindowx + i;
                    711: 
                    712:     // Samw with base row offset.
                    713:     if (width == SCREENWIDTH) 
                    714:        viewwindowy = 0; 
                    715:     else 
                    716:        viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1; 
                    717: 
                    718:     // Preclaculate all row offsets.
                    719:     for (i=0 ; i<height ; i++) 
                    720:        ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH; 
                    721: } 
                    722:  
                    723:  
1.1       root      724: 
                    725: 
1.1.1.3   root      726: //
                    727: // R_FillBackScreen
                    728: // Fills the back screen with a pattern
                    729: //  for variable screen sizes
                    730: // Also draws a beveled edge.
                    731: //
                    732: void R_FillBackScreen (void) 
                    733: { 
                    734:     byte*      src;
                    735:     byte*      dest; 
                    736:     int                x;
                    737:     int                y; 
                    738:     patch_t*   patch;
                    739: 
                    740:     // DOOM border patch.
                    741:     char       name1[] = "FLOOR7_2";
                    742: 
                    743:     // DOOM II border patch.
                    744:     char       name2[] = "GRNROCK";    
                    745: 
                    746:     char*      name;
                    747:        
                    748:     if (scaledviewwidth == 320)
                    749:        return;
                    750:        
                    751:     if ( gamemode == commercial)
                    752:        name = name2;
                    753:     else
                    754:        name = name1;
                    755:     
                    756:     src = W_CacheLumpName (name, PU_CACHE); 
                    757:     dest = screens[1]; 
                    758:         
                    759:     for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) 
                    760:     { 
                    761:        for (x=0 ; x<SCREENWIDTH/64 ; x++) 
                    762:        { 
                    763:            memcpy (dest, src+((y&63)<<6), 64); 
                    764:            dest += 64; 
                    765:        } 
                    766: 
                    767:        if (SCREENWIDTH&63) 
                    768:        { 
                    769:            memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63); 
                    770:            dest += (SCREENWIDTH&63); 
                    771:        } 
                    772:     } 
                    773:        
                    774:     patch = W_CacheLumpName ("brdr_t",PU_CACHE);
                    775: 
                    776:     for (x=0 ; x<scaledviewwidth ; x+=8)
                    777:        V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch);
                    778:     patch = W_CacheLumpName ("brdr_b",PU_CACHE);
                    779: 
                    780:     for (x=0 ; x<scaledviewwidth ; x+=8)
                    781:        V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch);
                    782:     patch = W_CacheLumpName ("brdr_l",PU_CACHE);
                    783: 
                    784:     for (y=0 ; y<viewheight ; y+=8)
                    785:        V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch);
                    786:     patch = W_CacheLumpName ("brdr_r",PU_CACHE);
                    787: 
                    788:     for (y=0 ; y<viewheight ; y+=8)
                    789:        V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
                    790: 
                    791: 
                    792:     // Draw beveled edge. 
                    793:     V_DrawPatch (viewwindowx-8,
                    794:                 viewwindowy-8,
                    795:                 1,
                    796:                 W_CacheLumpName ("brdr_tl",PU_CACHE));
                    797:     
                    798:     V_DrawPatch (viewwindowx+scaledviewwidth,
                    799:                 viewwindowy-8,
                    800:                 1,
                    801:                 W_CacheLumpName ("brdr_tr",PU_CACHE));
                    802:     
                    803:     V_DrawPatch (viewwindowx-8,
                    804:                 viewwindowy+viewheight,
                    805:                 1,
                    806:                 W_CacheLumpName ("brdr_bl",PU_CACHE));
                    807:     
                    808:     V_DrawPatch (viewwindowx+scaledviewwidth,
                    809:                 viewwindowy+viewheight,
                    810:                 1,
                    811:                 W_CacheLumpName ("brdr_br",PU_CACHE));
                    812: } 
                    813:  
1.1       root      814: 
1.1.1.3   root      815: //
                    816: // Copy a screen buffer.
                    817: //
                    818: void
                    819: R_VideoErase
                    820: ( unsigned     ofs,
                    821:   int          count ) 
                    822: { 
                    823:   // LFB copy.
                    824:   // This might not be a good idea if memcpy
                    825:   //  is not optiomal, e.g. byte by byte on
                    826:   //  a 32bit CPU, as GNU GCC/Linux libc did
                    827:   //  at one point.
                    828:     memcpy (screens[0]+ofs, screens[1]+ofs, count); 
                    829: } 
1.1       root      830: 
                    831: 
1.1.1.3   root      832: //
                    833: // R_DrawViewBorder
                    834: // Draws the border around the view
                    835: //  for different size windows?
                    836: //
                    837: void
                    838: V_MarkRect
                    839: ( int          x,
                    840:   int          y,
                    841:   int          width,
                    842:   int          height ); 
                    843:  
                    844: void R_DrawViewBorder (void) 
                    845: { 
                    846:     int                top;
                    847:     int                side;
                    848:     int                ofs;
                    849:     int                i; 
                    850:  
                    851:     if (scaledviewwidth == SCREENWIDTH) 
                    852:        return; 
                    853:   
                    854:     top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2; 
                    855:     side = (SCREENWIDTH-scaledviewwidth)/2; 
                    856:  
                    857:     // copy top and one line of left side 
                    858:     R_VideoErase (0, top*SCREENWIDTH+side); 
                    859:  
                    860:     // copy one line of right side and bottom 
                    861:     ofs = (viewheight+top)*SCREENWIDTH-side; 
                    862:     R_VideoErase (ofs, top*SCREENWIDTH+side); 
                    863:  
                    864:     // copy sides using wraparound 
                    865:     ofs = top*SCREENWIDTH + SCREENWIDTH-side; 
                    866:     side <<= 1;
                    867:     
                    868:     for (i=1 ; i<viewheight ; i++) 
                    869:     { 
                    870:        R_VideoErase (ofs, side); 
                    871:        ofs += SCREENWIDTH; 
                    872:     } 
                    873: 
                    874:     // ? 
                    875:     V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT); 
                    876: } 
                    877:  
                    878:  

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.