Annotation of doom/r_draw.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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