Annotation of doom/r_draw.c, revision 1.1.1.5

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.5 ! root        8: // This source is available for distribution and/or modification
        !             9: // only under the terms of the DOOM Source Code License as
        !            10: // published by id Software. All rights reserved.
1.1.1.3   root       11: //
1.1.1.5 ! root       12: // The source is distributed in the hope that it will be useful,
1.1.1.3   root       13: // but WITHOUT ANY WARRANTY; without even the implied warranty of
1.1.1.5 ! root       14: // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
        !            15: // for more details.
1.1.1.3   root       16: //
                     17: // $Log:$
                     18: //
                     19: // DESCRIPTION:
                     20: //     The actual span/column drawing functions.
                     21: //     Here find the main potential for optimization,
                     22: //      e.g. inline assembly, different algorithms.
                     23: //
                     24: //-----------------------------------------------------------------------------
1.1       root       25: 
                     26: 
1.1.1.3   root       27: static const char
                     28: rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
1.1       root       29: 
                     30: 
1.1.1.3   root       31: #include "doomdef.h"
1.1       root       32: 
1.1.1.3   root       33: #include "i_system.h"
                     34: #include "z_zone.h"
                     35: #include "w_wad.h"
1.1       root       36: 
1.1.1.3   root       37: #include "r_local.h"
1.1       root       38: 
1.1.1.3   root       39: // Needs access to LFB (guess what).
                     40: #include "v_video.h"
1.1       root       41: 
1.1.1.3   root       42: // State.
                     43: #include "doomstat.h"
1.1       root       44: 
1.1.1.5 ! root       45: void WriteDebug(char *);
1.1       root       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.5 ! 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]; 
1.1.1.3   root       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 
1.1.1.5 ! root      261: #define FUZZOFF        1
1.1       root      262: 
1.1.1.3   root      263: int    fuzzoffset[FUZZTABLE] =
1.1       root      264: {
1.1.1.3   root      265:     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
                    266:     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
                    267:     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
                    268:     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
                    269:     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
                    270:     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
                    271:     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF 
                    272: }; 
1.1       root      273: 
1.1.1.3   root      274: int    fuzzpos = 0; 
1.1       root      275: 
1.1.1.5 ! root      276: void R_InitFuzzTable()
        !           277:    {
        !           278:     int i;
        !           279: 
        !           280:     for (i = 0; i < FUZZTABLE; i++)
        !           281:        fuzzoffset[i] *= SCREENWIDTH;
        !           282:    }
1.1       root      283: 
1.1.1.2   root      284: //
1.1.1.3   root      285: // Framebuffer postprocessing.
                    286: // Creates a fuzzy image by copying pixels
                    287: //  from adjacent ones to left and right.
                    288: // Used with an all black colormap, this
                    289: //  could create the SHADOW effect,
                    290: //  i.e. spectres and invisible players.
1.1.1.2   root      291: //
1.1.1.3   root      292: void R_DrawFuzzColumn (void) 
                    293: { 
                    294:     int                        count; 
                    295:     byte*              dest; 
                    296:     fixed_t            frac;
                    297:     fixed_t            fracstep;        
                    298: 
                    299:     // Adjust borders. Low... 
                    300:     if (!dc_yl) 
                    301:        dc_yl = 1;
                    302: 
                    303:     // .. and high.
                    304:     if (dc_yh == viewheight-1) 
                    305:        dc_yh = viewheight - 2; 
                    306:                 
                    307:     count = dc_yh - dc_yl; 
                    308: 
                    309:     // Zero length.
                    310:     if (count < 0) 
                    311:        return; 
                    312: 
                    313:     
                    314: #ifdef RANGECHECK 
                    315:     if ((unsigned)dc_x >= SCREENWIDTH
                    316:        || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
                    317:     {
                    318:        I_Error ("R_DrawFuzzColumn: %i to %i at %i",
                    319:                 dc_yl, dc_yh, dc_x);
                    320:     }
1.1       root      321: #endif
                    322: 
                    323: 
1.1.1.3   root      324:     // Keep till detailshift bug in blocky mode fixed,
                    325:     //  or blocky mode removed.
                    326:     /* WATCOM code 
                    327:     if (detailshift)
                    328:     {
                    329:        if (dc_x & 1)
1.1       root      330:        {
1.1.1.3   root      331:            outpw (GC_INDEX,GC_READMAP+(2<<8) ); 
                    332:            outp (SC_INDEX+1,12); 
                    333:        }
                    334:        else
                    335:        {
                    336:            outpw (GC_INDEX,GC_READMAP); 
                    337:            outp (SC_INDEX+1,3); 
                    338:        }
                    339:        dest = destview + dc_yl*80 + (dc_x>>1); 
                    340:     }
                    341:     else
                    342:     {
                    343:        outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); 
                    344:        outp (SC_INDEX+1,1<<(dc_x&3)); 
                    345:        dest = destview + dc_yl*80 + (dc_x>>2); 
                    346:     }*/
                    347: 
                    348:     
                    349:     // Does not work with blocky mode.
                    350:     dest = ylookup[dc_yl] + columnofs[dc_x];
                    351: 
                    352:     // Looks familiar.
                    353:     fracstep = dc_iscale; 
                    354:     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
                    355: 
                    356:     // Looks like an attempt at dithering,
                    357:     //  using the colormap #6 (of 0-31, a bit
                    358:     //  brighter than average).
                    359:     do 
                    360:     {
                    361:        // Lookup framebuffer, and retrieve
                    362:        //  a pixel that is either one column
                    363:        //  left or right of the current one.
                    364:        // Add index from colormap to index.
                    365:        *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; 
                    366: 
                    367:        // Clamp table lookup index.
                    368:        if (++fuzzpos == FUZZTABLE) 
                    369:            fuzzpos = 0;
                    370:        
                    371:        dest += SCREENWIDTH;
                    372: 
                    373:        frac += fracstep; 
                    374:     } while (count--); 
                    375: } 
                    376:  
                    377:   
                    378:  
1.1       root      379: 
1.1.1.2   root      380: //
1.1.1.3   root      381: // R_DrawTranslatedColumn
                    382: // Used to draw player sprites
                    383: //  with the green colorramp mapped to others.
                    384: // Could be used with different translation
                    385: //  tables, e.g. the lighter colored version
                    386: //  of the BaronOfHell, the HellKnight, uses
                    387: //  identical sprites, kinda brightened up.
1.1.1.2   root      388: //
1.1.1.3   root      389: byte*  dc_translation;
                    390: byte*  translationtables;
1.1.1.2   root      391: 
1.1.1.3   root      392: void R_DrawTranslatedColumn (void) 
                    393: { 
                    394:     int                        count; 
                    395:     byte*              dest; 
                    396:     fixed_t            frac;
                    397:     fixed_t            fracstep;        
                    398:  
                    399:     count = dc_yh - dc_yl; 
                    400:     if (count < 0) 
                    401:        return; 
                    402:                                 
                    403: #ifdef RANGECHECK 
                    404:     if ((unsigned)dc_x >= SCREENWIDTH
                    405:        || dc_yl < 0
                    406:        || dc_yh >= SCREENHEIGHT)
                    407:     {
                    408:        I_Error ( "R_DrawColumn: %i to %i at %i",
                    409:                  dc_yl, dc_yh, dc_x);
                    410:     }
                    411:     
                    412: #endif 
                    413: 
                    414: 
                    415:     // WATCOM VGA specific.
                    416:     /* Keep for fixing.
                    417:     if (detailshift)
                    418:     {
                    419:        if (dc_x & 1)
                    420:            outp (SC_INDEX+1,12); 
                    421:        else
                    422:            outp (SC_INDEX+1,3);
1.1.1.2   root      423:        
1.1.1.3   root      424:        dest = destview + dc_yl*80 + (dc_x>>1); 
                    425:     }
                    426:     else
                    427:     {
                    428:        outp (SC_INDEX+1,1<<(dc_x&3)); 
                    429: 
                    430:        dest = destview + dc_yl*80 + (dc_x>>2); 
                    431:     }*/
                    432: 
                    433:     
                    434:     // FIXME. As above.
                    435:     dest = ylookup[dc_yl] + columnofs[dc_x]; 
                    436: 
                    437:     // Looks familiar.
                    438:     fracstep = dc_iscale; 
                    439:     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
                    440: 
                    441:     // Here we do an additional index re-mapping.
                    442:     do 
                    443:     {
                    444:        // Translation tables are used
                    445:        //  to map certain colorramps to other ones,
                    446:        //  used with PLAY sprites.
                    447:        // Thus the "green" ramp of the player 0 sprite
                    448:        //  is mapped to gray, red, black/indigo. 
                    449:        *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
                    450:        dest += SCREENWIDTH;
                    451:        
                    452:        frac += fracstep; 
                    453:     } while (count--); 
                    454: } 
                    455: 
                    456: 
1.1.1.2   root      457: 
                    458: 
1.1       root      459: //
1.1.1.3   root      460: // R_InitTranslationTables
                    461: // Creates the translation tables to map
                    462: //  the green color ramp to gray, brown, red.
                    463: // Assumes a given structure of the PLAYPAL.
                    464: // Could be read from a lump instead.
1.1       root      465: //
                    466: void R_InitTranslationTables (void)
                    467: {
1.1.1.3   root      468:     int                i;
                    469:        
                    470:     translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
                    471:     translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
                    472:     
                    473:     // translate just the 16 green colors
                    474:     for (i=0 ; i<256 ; i++)
                    475:     {
                    476:        if (i >= 0x70 && i<= 0x7f)
                    477:        {
                    478:            // map green ramp to gray, brown, red
                    479:            translationtables[i] = 0x60 + (i&0xf);
                    480:            translationtables [i+256] = 0x40 + (i&0xf);
                    481:            translationtables [i+512] = 0x20 + (i&0xf);
                    482:        }
                    483:        else
1.1.1.2   root      484:        {
1.1.1.3   root      485:            // Keep all other colors as is.
                    486:            translationtables[i] = translationtables[i+256] 
                    487:                = translationtables[i+512] = i;
1.1       root      488:        }
1.1.1.3   root      489:     }
1.1       root      490: }
                    491: 
                    492: 
                    493: 
                    494: 
1.1.1.3   root      495: //
                    496: // R_DrawSpan 
                    497: // With DOOM style restrictions on view orientation,
                    498: //  the floors and ceilings consist of horizontal slices
                    499: //  or spans with constant z depth.
                    500: // However, rotation around the world z axis is possible,
                    501: //  thus this mapping, while simpler and faster than
                    502: //  perspective correct texture mapping, has to traverse
                    503: //  the texture at an angle in all but a few cases.
                    504: // In consequence, flats are not stored by column (like walls),
                    505: //  and the inner loop has to step in texture space u and v.
                    506: //
                    507: int                    ds_y; 
                    508: int                    ds_x1; 
                    509: int                    ds_x2;
                    510: 
                    511: lighttable_t*          ds_colormap; 
                    512: 
                    513: fixed_t                        ds_xfrac; 
                    514: fixed_t                        ds_yfrac; 
                    515: fixed_t                        ds_xstep; 
                    516: fixed_t                        ds_ystep;
1.1       root      517: 
1.1.1.3   root      518: // start of a 64*64 tile image 
                    519: byte*                  ds_source;      
1.1       root      520: 
1.1.1.3   root      521: // just for profiling
                    522: int                    dscount;
1.1       root      523: 
                    524: 
1.1.1.3   root      525: //
                    526: // Draws the actual span.
                    527: void R_DrawSpan (void) 
                    528: { 
                    529:     fixed_t            xfrac;
                    530:     fixed_t            yfrac; 
                    531:     byte*              dest; 
                    532:     int                        count;
                    533:     int                        spot; 
                    534:         
                    535: #ifdef RANGECHECK 
                    536:     if (ds_x2 < ds_x1
                    537:        || ds_x1<0
                    538:        || ds_x2>=SCREENWIDTH  
                    539:        || (unsigned)ds_y>SCREENHEIGHT)
                    540:     {
                    541:        I_Error( "R_DrawSpan: %i to %i at %i",
                    542:                 ds_x1,ds_x2,ds_y);
                    543:     }
                    544: //     dscount++; 
                    545: #endif 
                    546: 
                    547:     
                    548:     xfrac = ds_xfrac; 
                    549:     yfrac = ds_yfrac; 
                    550:         
                    551:     dest = ylookup[ds_y] + columnofs[ds_x1];
                    552: 
                    553:     // We do not check for zero spans here?
1.1.1.5 ! root      554:     count = ds_x2 - ds_x1;
1.1.1.3   root      555: 
                    556:     do 
                    557:     {
                    558:        // Current texture index in u,v.
                    559:        spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
                    560: 
                    561:        // Lookup pixel from flat texture tile,
                    562:        //  re-index using light/colormap.
                    563:        *dest++ = ds_colormap[ds_source[spot]];
                    564: 
                    565:        // Next step in u,v.
                    566:        xfrac += ds_xstep; 
                    567:        yfrac += ds_ystep;
                    568:        
                    569:     } while (count--); 
                    570: } 
1.1       root      571: 
                    572: 
                    573: 
1.1.1.3   root      574: // UNUSED.
                    575: // Loop unrolled by 4.
                    576: #if 0
                    577: void R_DrawSpan (void) 
                    578: { 
                    579:     unsigned   position, step;
                    580: 
                    581:     byte*      source;
                    582:     byte*      colormap;
                    583:     byte*      dest;
                    584:     
                    585:     unsigned   count;
                    586:     usingned   spot; 
                    587:     unsigned   value;
                    588:     unsigned   temp;
                    589:     unsigned   xtemp;
                    590:     unsigned   ytemp;
                    591:                
                    592:     position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff);
                    593:     step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);
                    594:                
                    595:     source = ds_source;
                    596:     colormap = ds_colormap;
                    597:     dest = ylookup[ds_y] + columnofs[ds_x1];    
                    598:     count = ds_x2 - ds_x1 + 1; 
                    599:        
                    600:     while (count >= 4) 
                    601:     { 
                    602:        ytemp = position>>4;
                    603:        ytemp = ytemp & 4032;
                    604:        xtemp = position>>26;
                    605:        spot = xtemp | ytemp;
                    606:        position += step;
                    607:        dest[0] = colormap[source[spot]]; 
                    608: 
                    609:        ytemp = position>>4;
                    610:        ytemp = ytemp & 4032;
                    611:        xtemp = position>>26;
                    612:        spot = xtemp | ytemp;
                    613:        position += step;
                    614:        dest[1] = colormap[source[spot]];
                    615:        
                    616:        ytemp = position>>4;
                    617:        ytemp = ytemp & 4032;
                    618:        xtemp = position>>26;
                    619:        spot = xtemp | ytemp;
                    620:        position += step;
                    621:        dest[2] = colormap[source[spot]];
                    622:        
                    623:        ytemp = position>>4;
                    624:        ytemp = ytemp & 4032;
                    625:        xtemp = position>>26;
                    626:        spot = xtemp | ytemp;
                    627:        position += step;
                    628:        dest[3] = colormap[source[spot]]; 
                    629:                
                    630:        count -= 4;
                    631:        dest += 4;
                    632:     } 
                    633:     while (count > 0) 
                    634:     { 
                    635:        ytemp = position>>4;
                    636:        ytemp = ytemp & 4032;
                    637:        xtemp = position>>26;
                    638:        spot = xtemp | ytemp;
                    639:        position += step;
                    640:        *dest++ = colormap[source[spot]]; 
                    641:        count--;
                    642:     } 
                    643: } 
                    644: #endif
1.1       root      645: 
                    646: 
1.1.1.3   root      647: //
                    648: // Again..
                    649: //
                    650: void R_DrawSpanLow (void) 
                    651: { 
                    652:     fixed_t            xfrac;
                    653:     fixed_t            yfrac; 
                    654:     byte*              dest; 
                    655:     int                        count;
                    656:     int                        spot; 
                    657:         
                    658: #ifdef RANGECHECK 
                    659:     if (ds_x2 < ds_x1
                    660:        || ds_x1<0
                    661:        || ds_x2>=SCREENWIDTH  
                    662:        || (unsigned)ds_y>SCREENHEIGHT)
                    663:     {
                    664:        I_Error( "R_DrawSpan: %i to %i at %i",
                    665:                 ds_x1,ds_x2,ds_y);
                    666:     }
                    667: //     dscount++; 
                    668: #endif 
                    669:         
                    670:     xfrac = ds_xfrac; 
                    671:     yfrac = ds_yfrac; 
                    672: 
                    673:     // Blocky mode, need to multiply by 2.
                    674:     ds_x1 <<= 1;
                    675:     ds_x2 <<= 1;
                    676:     
                    677:     dest = ylookup[ds_y] + columnofs[ds_x1];
                    678:   
                    679:     
                    680:     count = ds_x2 - ds_x1; 
                    681:     do 
                    682:     { 
                    683:        spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
                    684:        // Lowres/blocky mode does it twice,
                    685:        //  while scale is adjusted appropriately.
                    686:        *dest++ = ds_colormap[ds_source[spot]]; 
                    687:        *dest++ = ds_colormap[ds_source[spot]];
1.1       root      688:        
1.1.1.3   root      689:        xfrac += ds_xstep; 
                    690:        yfrac += ds_ystep; 
                    691: 
                    692:     } while (count--); 
1.1       root      693: }
                    694: 
1.1.1.3   root      695: //
                    696: // R_InitBuffer 
                    697: // Creats lookup tables that avoid
1.1.1.5 ! root      698: //  multiplies and other hassles
1.1.1.3   root      699: //  for getting the framebuffer address
                    700: //  of a pixel to draw.
                    701: //
1.1.1.5 ! root      702: void R_InitBuffer( int width, int height )
        !           703:    { 
1.1.1.3   root      704:     int                i; 
                    705: 
                    706:     // Handle resize,
                    707:     //  e.g. smaller view windows
                    708:     //  with border and/or status bar.
                    709:     viewwindowx = (SCREENWIDTH-width) >> 1; 
                    710: 
                    711:     // Column offset. For windows.
1.1.1.5 ! root      712:     for (i = 0; i < width; i++) 
        !           713:        columnofs[i] = viewwindowx + i;
1.1.1.3   root      714: 
1.1.1.5 ! root      715:     // Same with base row offset.
1.1.1.3   root      716:     if (width == SCREENWIDTH) 
1.1.1.5 ! root      717:         viewwindowy = 0; 
1.1.1.3   root      718:     else 
1.1.1.5 ! root      719:         viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1; 
1.1.1.3   root      720: 
1.1.1.5 ! root      721:     // Precalculate all row offsets.
        !           722:     for (i = 0; i < height; i++) 
        !           723:          ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH; 
        !           724:    } 
1.1.1.3   root      725:  
                    726:  
1.1       root      727: 
                    728: 
1.1.1.3   root      729: //
                    730: // R_FillBackScreen
1.1.1.5 ! root      731: // Fills the back screen with a pattern for variable screen sizes
1.1.1.3   root      732: // Also draws a beveled edge.
                    733: //
1.1.1.5 ! root      734: void R_FillBackScreen(void)
        !           735: {
        !           736:        byte*   src;
1.1.1.3   root      737:     byte*      dest; 
                    738:     int                x;
                    739:     int                y; 
                    740:     patch_t*   patch;
                    741: 
                    742:     // DOOM border patch.
                    743:     char       name1[] = "FLOOR7_2";
                    744: 
                    745:     // DOOM II border patch.
                    746:     char       name2[] = "GRNROCK";    
                    747: 
                    748:     char*      name;
1.1.1.5 ! root      749: 
        !           750:     if ((scaledviewwidth == SCREENWIDTH)&&(viewheight == SCREENHEIGHT))
        !           751:         return;
1.1.1.3   root      752:        
1.1.1.5 ! root      753:     if (gamemode == commercial)
        !           754:         name = name2;
1.1.1.3   root      755:     else
1.1.1.5 ! root      756:         name = name1;
1.1.1.3   root      757:     
1.1.1.5 ! root      758:     src = W_CacheLumpName(name, PU_CACHE); 
        !           759:     dest = screens[1];
1.1.1.3   root      760: 
1.1.1.5 ! root      761:     //for (y = 0; y < SCREENHEIGHT-SBARHEIGHT; y++) 
        !           762:     for (y = 0; y < SCREENHEIGHT; y++)
1.1.1.3   root      763:        { 
1.1.1.5 ! root      764:         for (x = 0; x < SCREENWIDTH/64; x++)
        !           765:                { 
        !           766:             memcpy (dest, src+((y&63)<<6), 64);
        !           767:             dest += 64; 
        !           768:                } 
        !           769:         if (SCREENWIDTH & 63) 
        !           770:                { 
        !           771:             memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63); 
        !           772:             dest += (SCREENWIDTH&63); 
        !           773:                } 
1.1.1.3   root      774:        } 
                    775:        
1.1.1.5 ! root      776:     if (scaledviewwidth == SCREENWIDTH)
        !           777:         return;
        !           778: 
1.1.1.3   root      779:     patch = W_CacheLumpName ("brdr_t",PU_CACHE);
                    780: 
                    781:     for (x=0 ; x<scaledviewwidth ; x+=8)
                    782:        V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch);
                    783:     patch = W_CacheLumpName ("brdr_b",PU_CACHE);
                    784: 
                    785:     for (x=0 ; x<scaledviewwidth ; x+=8)
                    786:        V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch);
                    787:     patch = W_CacheLumpName ("brdr_l",PU_CACHE);
                    788: 
                    789:     for (y=0 ; y<viewheight ; y+=8)
                    790:        V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch);
                    791:     patch = W_CacheLumpName ("brdr_r",PU_CACHE);
                    792: 
                    793:     for (y=0 ; y<viewheight ; y+=8)
                    794:        V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
                    795: 
                    796: 
                    797:     // Draw beveled edge. 
                    798:     V_DrawPatch (viewwindowx-8,
                    799:                 viewwindowy-8,
                    800:                 1,
                    801:                 W_CacheLumpName ("brdr_tl",PU_CACHE));
                    802:     
                    803:     V_DrawPatch (viewwindowx+scaledviewwidth,
                    804:                 viewwindowy-8,
                    805:                 1,
                    806:                 W_CacheLumpName ("brdr_tr",PU_CACHE));
                    807:     
                    808:     V_DrawPatch (viewwindowx-8,
                    809:                 viewwindowy+viewheight,
                    810:                 1,
                    811:                 W_CacheLumpName ("brdr_bl",PU_CACHE));
                    812:     
                    813:     V_DrawPatch (viewwindowx+scaledviewwidth,
                    814:                 viewwindowy+viewheight,
                    815:                 1,
                    816:                 W_CacheLumpName ("brdr_br",PU_CACHE));
                    817: } 
                    818:  
1.1       root      819: 
1.1.1.3   root      820: //
                    821: // Copy a screen buffer.
                    822: //
1.1.1.5 ! root      823: void R_VideoErase( unsigned    ofs, int count ) 
        !           824:    { 
        !           825:     // LFB copy.
        !           826:     // This might not be a good idea if memcpy is not optimal, e.g. byte by byte on
        !           827:     // a 32bit CPU, as GNU GCC/Linux libc did 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) 
1.1.1.5 ! root      845:    { 
1.1.1.3   root      846:     int                top;
1.1.1.5 ! root      847:     int                side, side2;
1.1.1.3   root      848:     int                ofs;
                    849:     int                i; 
1.1.1.5 ! root      850: 
        !           851:     if ((SCREENWIDTH > 320) && (SCREENHEIGHT != viewheight))
        !           852:        {
        !           853:         ofs = (SCREENHEIGHT-SBARHEIGHT) * SCREENWIDTH;
        !           854:         side = ((SCREENWIDTH - 320) / 2);
        !           855:         side2 = side * 2;
        !           856: 
        !           857:         R_VideoErase(ofs, side);
        !           858:         ofs += (SCREENWIDTH - side);
        !           859:         for (i = 1;i < SBARHEIGHT;i++)
        !           860:            {
        !           861:             R_VideoErase(ofs, side2);
        !           862:             ofs += SCREENWIDTH;
        !           863:            }
        !           864:         R_VideoErase(ofs, side);
        !           865:        }
        !           866: 
1.1.1.3   root      867:     if (scaledviewwidth == SCREENWIDTH) 
1.1.1.5 ! root      868:         return;
        !           869: 
        !           870:     top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2;
        !           871:     side = (SCREENWIDTH-scaledviewwidth)/2;
1.1.1.3   root      872:  
                    873:     // copy top and one line of left side 
1.1.1.5 ! root      874:     R_VideoErase(0, top*SCREENWIDTH+side);
1.1.1.3   root      875:  
                    876:     // copy one line of right side and bottom 
1.1.1.5 ! root      877:     ofs = (viewheight+top)*SCREENWIDTH-side;
        !           878:     R_VideoErase (ofs, top*SCREENWIDTH+side);
1.1.1.3   root      879:  
                    880:     // copy sides using wraparound 
                    881:     ofs = top*SCREENWIDTH + SCREENWIDTH-side; 
                    882:     side <<= 1;
                    883:     
1.1.1.5 ! root      884:     for (i = 1; i < viewheight; i++) 
        !           885:        { 
        !           886:            R_VideoErase (ofs, side); 
        !           887:            ofs += SCREENWIDTH; 
        !           888:        } 
1.1.1.3   root      889: 
                    890:     // ? 
                    891:     V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT); 
1.1.1.5 ! root      892:    } 
1.1.1.3   root      893:  
                    894:  

unix.superglobalmegacorp.com

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