Annotation of quakeworld/client/screen.c, revision 1.1

1.1     ! root        1: /*
        !             2: Copyright (C) 1996-1997 Id Software, Inc.
        !             3: 
        !             4: This program is free software; you can redistribute it and/or
        !             5: modify it under the terms of the GNU General Public License
        !             6: as published by the Free Software Foundation; either version 2
        !             7: of the License, or (at your option) any later version.
        !             8: 
        !             9: This program is distributed in the hope that it will be useful,
        !            10: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
        !            12: 
        !            13: See the GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with this program; if not, write to the Free Software
        !            17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
        !            18: 
        !            19: */
        !            20: // screen.c -- master for refresh, status bar, console, chat, notify, etc
        !            21: 
        !            22: #include "quakedef.h"
        !            23: #include "r_local.h"
        !            24: 
        !            25: #include <time.h>
        !            26: 
        !            27: /*
        !            28: 
        !            29: background clear
        !            30: rendering
        !            31: turtle/net/ram icons
        !            32: sbar
        !            33: centerprint / slow centerprint
        !            34: notify lines
        !            35: intermission / finale overlay
        !            36: loading plaque
        !            37: console
        !            38: menu
        !            39: 
        !            40: required background clears
        !            41: required update regions
        !            42: 
        !            43: 
        !            44: syncronous draw mode or async
        !            45: One off screen buffer, with updates either copied or xblited
        !            46: Need to double buffer?
        !            47: 
        !            48: 
        !            49: async draw will require the refresh area to be cleared, because it will be
        !            50: xblited, but sync draw can just ignore it.
        !            51: 
        !            52: sync
        !            53: draw
        !            54: 
        !            55: CenterPrint ()
        !            56: SlowPrint ()
        !            57: Screen_Update ();
        !            58: Con_Printf ();
        !            59: 
        !            60: net 
        !            61: turn off messages option
        !            62: 
        !            63: the refresh is allways rendered, unless the console is full screen
        !            64: 
        !            65: 
        !            66: console is:
        !            67:        notify lines
        !            68:        half
        !            69:        full
        !            70:        
        !            71: 
        !            72: */
        !            73: 
        !            74: 
        !            75: // only the refresh window will be updated unless these variables are flagged 
        !            76: int                    scr_copytop;
        !            77: int                    scr_copyeverything;
        !            78: 
        !            79: float          scr_con_current;
        !            80: float          scr_conlines;           // lines of console to display
        !            81: 
        !            82: float          oldscreensize, oldfov;
        !            83: float          oldsbar;
        !            84: cvar_t         scr_viewsize = {"viewsize","100", true};
        !            85: cvar_t         scr_fov = {"fov","90"}; // 10 - 170
        !            86: cvar_t         scr_conspeed = {"scr_conspeed","300"};
        !            87: cvar_t         scr_centertime = {"scr_centertime","2"};
        !            88: cvar_t         scr_showram = {"showram","1"};
        !            89: cvar_t         scr_showturtle = {"showturtle","0"};
        !            90: cvar_t         scr_showpause = {"showpause","1"};
        !            91: cvar_t         scr_printspeed = {"scr_printspeed","8"};
        !            92: cvar_t         scr_allowsnap = {"scr_allowsnap", "1"};
        !            93: 
        !            94: qboolean       scr_initialized;                // ready to draw
        !            95: 
        !            96: qpic_t         *scr_ram;
        !            97: qpic_t         *scr_net;
        !            98: qpic_t         *scr_turtle;
        !            99: 
        !           100: int                    scr_fullupdate;
        !           101: 
        !           102: int                    clearconsole;
        !           103: int                    clearnotify;
        !           104: 
        !           105: int                    sb_lines;
        !           106: 
        !           107: viddef_t       vid;                            // global video state
        !           108: 
        !           109: vrect_t                *pconupdate;
        !           110: vrect_t                scr_vrect;
        !           111: 
        !           112: qboolean       scr_disabled_for_loading;
        !           113: 
        !           114: qboolean       scr_skipupdate;
        !           115: 
        !           116: qboolean       block_drawing;
        !           117: 
        !           118: void SCR_ScreenShot_f (void);
        !           119: void SCR_RSShot_f (void);
        !           120: 
        !           121: /*
        !           122: ===============================================================================
        !           123: 
        !           124: CENTER PRINTING
        !           125: 
        !           126: ===============================================================================
        !           127: */
        !           128: 
        !           129: char           scr_centerstring[1024];
        !           130: float          scr_centertime_start;   // for slow victory printing
        !           131: float          scr_centertime_off;
        !           132: int                    scr_center_lines;
        !           133: int                    scr_erase_lines;
        !           134: int                    scr_erase_center;
        !           135: 
        !           136: /*
        !           137: ==============
        !           138: SCR_CenterPrint
        !           139: 
        !           140: Called for important messages that should stay in the center of the screen
        !           141: for a few moments
        !           142: ==============
        !           143: */
        !           144: void SCR_CenterPrint (char *str)
        !           145: {
        !           146:        strncpy (scr_centerstring, str, sizeof(scr_centerstring)-1);
        !           147:        scr_centertime_off = scr_centertime.value;
        !           148:        scr_centertime_start = cl.time;
        !           149: 
        !           150: // count the number of lines for centering
        !           151:        scr_center_lines = 1;
        !           152:        while (*str)
        !           153:        {
        !           154:                if (*str == '\n')
        !           155:                        scr_center_lines++;
        !           156:                str++;
        !           157:        }
        !           158: }
        !           159: 
        !           160: void SCR_EraseCenterString (void)
        !           161: {
        !           162:        int             y;
        !           163: 
        !           164:        if (scr_erase_center++ > vid.numpages)
        !           165:        {
        !           166:                scr_erase_lines = 0;
        !           167:                return;
        !           168:        }
        !           169: 
        !           170:        if (scr_center_lines <= 4)
        !           171:                y = vid.height*0.35;
        !           172:        else
        !           173:                y = 48;
        !           174: 
        !           175:        scr_copytop = 1;
        !           176:        Draw_TileClear (0, y, vid.width, min(8*scr_erase_lines, vid.height - y - 1));
        !           177: }
        !           178: 
        !           179: void SCR_DrawCenterString (void)
        !           180: {
        !           181:        char    *start;
        !           182:        int             l;
        !           183:        int             j;
        !           184:        int             x, y;
        !           185:        int             remaining;
        !           186: 
        !           187: // the finale prints the characters one at a time
        !           188:        if (cl.intermission)
        !           189:                remaining = scr_printspeed.value * (cl.time - scr_centertime_start);
        !           190:        else
        !           191:                remaining = 9999;
        !           192: 
        !           193:        scr_erase_center = 0;
        !           194:        start = scr_centerstring;
        !           195: 
        !           196:        if (scr_center_lines <= 4)
        !           197:                y = vid.height*0.35;
        !           198:        else
        !           199:                y = 48;
        !           200: 
        !           201:        do      
        !           202:        {
        !           203:        // scan the width of the line
        !           204:                for (l=0 ; l<40 ; l++)
        !           205:                        if (start[l] == '\n' || !start[l])
        !           206:                                break;
        !           207:                x = (vid.width - l*8)/2;
        !           208:                for (j=0 ; j<l ; j++, x+=8)
        !           209:                {
        !           210:                        Draw_Character (x, y, start[j]);        
        !           211:                        if (!remaining--)
        !           212:                                return;
        !           213:                }
        !           214:                        
        !           215:                y += 8;
        !           216: 
        !           217:                while (*start && *start != '\n')
        !           218:                        start++;
        !           219: 
        !           220:                if (!*start)
        !           221:                        break;
        !           222:                start++;                // skip the \n
        !           223:        } while (1);
        !           224: }
        !           225: 
        !           226: void SCR_CheckDrawCenterString (void)
        !           227: {
        !           228:        scr_copytop = 1;
        !           229:        if (scr_center_lines > scr_erase_lines)
        !           230:                scr_erase_lines = scr_center_lines;
        !           231: 
        !           232:        scr_centertime_off -= host_frametime;
        !           233:        
        !           234:        if (scr_centertime_off <= 0 && !cl.intermission)
        !           235:                return;
        !           236:        if (key_dest != key_game)
        !           237:                return;
        !           238: 
        !           239:        SCR_DrawCenterString ();
        !           240: }
        !           241: 
        !           242: //=============================================================================
        !           243: 
        !           244: /*
        !           245: ====================
        !           246: CalcFov
        !           247: ====================
        !           248: */
        !           249: float CalcFov (float fov_x, float width, float height)
        !           250: {
        !           251:         float   a;
        !           252:         float   x;
        !           253: 
        !           254:         if (fov_x < 1 || fov_x > 179)
        !           255:                 Sys_Error ("Bad fov: %f", fov_x);
        !           256: 
        !           257:         x = width/tan(fov_x/360*M_PI);
        !           258: 
        !           259:         a = atan (height/x);
        !           260: 
        !           261:         a = a*360/M_PI;
        !           262: 
        !           263:         return a;
        !           264: }
        !           265: 
        !           266: /*
        !           267: =================
        !           268: SCR_CalcRefdef
        !           269: 
        !           270: Must be called whenever vid changes
        !           271: Internal use only
        !           272: =================
        !           273: */
        !           274: static void SCR_CalcRefdef (void)
        !           275: {
        !           276:        vrect_t         vrect;
        !           277:        float           size;
        !           278: 
        !           279:        scr_fullupdate = 0;             // force a background redraw
        !           280:        vid.recalc_refdef = 0;
        !           281: 
        !           282: // force the status bar to redraw
        !           283:        Sbar_Changed ();
        !           284: 
        !           285: //========================================
        !           286:        
        !           287: // bound viewsize
        !           288:        if (scr_viewsize.value < 30)
        !           289:                Cvar_Set ("viewsize","30");
        !           290:        if (scr_viewsize.value > 120)
        !           291:                Cvar_Set ("viewsize","120");
        !           292: 
        !           293: // bound field of view
        !           294:        if (scr_fov.value < 10)
        !           295:                Cvar_Set ("fov","10");
        !           296:        if (scr_fov.value > 170)
        !           297:                Cvar_Set ("fov","170");
        !           298: 
        !           299:        r_refdef.fov_x = scr_fov.value;
        !           300:        r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height);
        !           301: 
        !           302: // intermission is always full screen  
        !           303:        if (cl.intermission)
        !           304:                size = 120;
        !           305:        else
        !           306:                size = scr_viewsize.value;
        !           307: 
        !           308:        if (size >= 120)
        !           309:                sb_lines = 0;           // no status bar at all
        !           310:        else if (size >= 110)
        !           311:                sb_lines = 24;          // no inventory
        !           312:        else
        !           313:                sb_lines = 24+16+8;
        !           314: 
        !           315: // these calculations mirror those in R_Init() for r_refdef, but take no
        !           316: // account of water warping
        !           317:        vrect.x = 0;
        !           318:        vrect.y = 0;
        !           319:        vrect.width = vid.width;
        !           320:        vrect.height = vid.height;
        !           321: 
        !           322:        R_SetVrect (&vrect, &scr_vrect, sb_lines);
        !           323: 
        !           324: // guard against going from one mode to another that's less than half the
        !           325: // vertical resolution
        !           326:        if (scr_con_current > vid.height)
        !           327:                scr_con_current = vid.height;
        !           328: 
        !           329: // notify the refresh of the change
        !           330:        R_ViewChanged (&vrect, sb_lines, vid.aspect);
        !           331: }
        !           332: 
        !           333: 
        !           334: /*
        !           335: =================
        !           336: SCR_SizeUp_f
        !           337: 
        !           338: Keybinding command
        !           339: =================
        !           340: */
        !           341: void SCR_SizeUp_f (void)
        !           342: {
        !           343:        if (scr_viewsize.value < 120) {
        !           344:        Cvar_SetValue ("viewsize",scr_viewsize.value+10);
        !           345:        vid.recalc_refdef = 1;
        !           346:        }
        !           347: }
        !           348: 
        !           349: 
        !           350: /*
        !           351: =================
        !           352: SCR_SizeDown_f
        !           353: 
        !           354: Keybinding command
        !           355: =================
        !           356: */
        !           357: void SCR_SizeDown_f (void)
        !           358: {
        !           359:        Cvar_SetValue ("viewsize",scr_viewsize.value-10);
        !           360:        vid.recalc_refdef = 1;
        !           361: }
        !           362: 
        !           363: //============================================================================
        !           364: 
        !           365: /*
        !           366: ==================
        !           367: SCR_Init
        !           368: ==================
        !           369: */
        !           370: void SCR_Init (void)
        !           371: {
        !           372:        Cvar_RegisterVariable (&scr_fov);
        !           373:        Cvar_RegisterVariable (&scr_viewsize);
        !           374:        Cvar_RegisterVariable (&scr_conspeed);
        !           375:        Cvar_RegisterVariable (&scr_showram);
        !           376:        Cvar_RegisterVariable (&scr_showturtle);
        !           377:        Cvar_RegisterVariable (&scr_showpause);
        !           378:        Cvar_RegisterVariable (&scr_centertime);
        !           379:        Cvar_RegisterVariable (&scr_printspeed);
        !           380:        Cvar_RegisterVariable (&scr_allowsnap);
        !           381: 
        !           382: //
        !           383: // register our commands
        !           384: //
        !           385:        Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
        !           386:        Cmd_AddCommand ("snap",SCR_RSShot_f);
        !           387:        Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
        !           388:        Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
        !           389: 
        !           390:        scr_ram = W_GetLumpName ("ram");
        !           391:        scr_net = W_GetLumpName ("net");
        !           392:        scr_turtle = W_GetLumpName ("turtle");
        !           393: 
        !           394:        scr_initialized = true;
        !           395: }
        !           396: 
        !           397: 
        !           398: 
        !           399: /*
        !           400: ==============
        !           401: SCR_DrawRam
        !           402: ==============
        !           403: */
        !           404: void SCR_DrawRam (void)
        !           405: {
        !           406:        if (!scr_showram.value)
        !           407:                return;
        !           408: 
        !           409:        if (!r_cache_thrash)
        !           410:                return;
        !           411: 
        !           412:        Draw_Pic (scr_vrect.x+32, scr_vrect.y, scr_ram);
        !           413: }
        !           414: 
        !           415: /*
        !           416: ==============
        !           417: SCR_DrawTurtle
        !           418: ==============
        !           419: */
        !           420: void SCR_DrawTurtle (void)
        !           421: {
        !           422:        static int      count;
        !           423:        
        !           424:        if (!scr_showturtle.value)
        !           425:                return;
        !           426: 
        !           427:        if (host_frametime < 0.1)
        !           428:        {
        !           429:                count = 0;
        !           430:                return;
        !           431:        }
        !           432: 
        !           433:        count++;
        !           434:        if (count < 3)
        !           435:                return;
        !           436: 
        !           437:        Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle);
        !           438: }
        !           439: 
        !           440: /*
        !           441: ==============
        !           442: SCR_DrawNet
        !           443: ==============
        !           444: */
        !           445: void SCR_DrawNet (void)
        !           446: {
        !           447:        if (cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged < UPDATE_BACKUP-1)
        !           448:                return;
        !           449:        if (cls.demoplayback)
        !           450:                return;
        !           451: 
        !           452:        Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net);
        !           453: }
        !           454: 
        !           455: void SCR_DrawFPS (void)
        !           456: {
        !           457:        extern cvar_t show_fps;
        !           458:        static double lastframetime;
        !           459:        double t;
        !           460:        extern int fps_count;
        !           461:        static lastfps;
        !           462:        int x, y;
        !           463:        char st[80];
        !           464: 
        !           465:        if (!show_fps.value)
        !           466:                return;
        !           467: 
        !           468:        t = Sys_DoubleTime();
        !           469:        if ((t - lastframetime) >= 1.0) {
        !           470:                lastfps = fps_count;
        !           471:                fps_count = 0;
        !           472:                lastframetime = t;
        !           473:        }
        !           474: 
        !           475:        sprintf(st, "%3d FPS", lastfps);
        !           476:        x = vid.width - strlen(st) * 8 - 8;
        !           477:        y = vid.height - sb_lines - 8;
        !           478: //     Draw_TileClear(x, y, strlen(st) * 8, 8);
        !           479:        Draw_String(x, y, st);
        !           480: }
        !           481: 
        !           482: /*
        !           483: ==============
        !           484: DrawPause
        !           485: ==============
        !           486: */
        !           487: void SCR_DrawPause (void)
        !           488: {
        !           489:        qpic_t  *pic;
        !           490: 
        !           491:        if (!scr_showpause.value)               // turn off for screenshots
        !           492:                return;
        !           493: 
        !           494:        if (!cl.paused)
        !           495:                return;
        !           496: 
        !           497:        pic = Draw_CachePic ("gfx/pause.lmp");
        !           498:        Draw_Pic ( (vid.width - pic->width)/2, 
        !           499:                (vid.height - 48 - pic->height)/2, pic);
        !           500: }
        !           501: 
        !           502: 
        !           503: //=============================================================================
        !           504: 
        !           505: 
        !           506: /*
        !           507: ==================
        !           508: SCR_SetUpToDrawConsole
        !           509: ==================
        !           510: */
        !           511: void SCR_SetUpToDrawConsole (void)
        !           512: {
        !           513:        Con_CheckResize ();
        !           514:        
        !           515: // decide on the height of the console
        !           516:        if (cls.state != ca_active)
        !           517:        {
        !           518:                scr_conlines = vid.height;              // full screen
        !           519:                scr_con_current = scr_conlines;
        !           520:        }
        !           521:        else if (key_dest == key_console)
        !           522:                scr_conlines = vid.height/2;    // half screen
        !           523:        else
        !           524:                scr_conlines = 0;                               // none visible
        !           525:        
        !           526:        if (scr_conlines < scr_con_current)
        !           527:        {
        !           528:                scr_con_current -= scr_conspeed.value*host_frametime;
        !           529:                if (scr_conlines > scr_con_current)
        !           530:                        scr_con_current = scr_conlines;
        !           531: 
        !           532:        }
        !           533:        else if (scr_conlines > scr_con_current)
        !           534:        {
        !           535:                scr_con_current += scr_conspeed.value*host_frametime;
        !           536:                if (scr_conlines < scr_con_current)
        !           537:                        scr_con_current = scr_conlines;
        !           538:        }
        !           539: 
        !           540:        if (clearconsole++ < vid.numpages)
        !           541:        {
        !           542:                scr_copytop = 1;
        !           543:                Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current);
        !           544:                Sbar_Changed ();
        !           545:        }
        !           546:        else if (clearnotify++ < vid.numpages)
        !           547:        {
        !           548:                scr_copytop = 1;
        !           549:                Draw_TileClear (0,0,vid.width, con_notifylines);
        !           550:        }
        !           551:        else
        !           552:                con_notifylines = 0;
        !           553: }
        !           554:        
        !           555: /*
        !           556: ==================
        !           557: SCR_DrawConsole
        !           558: ==================
        !           559: */
        !           560: void SCR_DrawConsole (void)
        !           561: {
        !           562:        if (scr_con_current)
        !           563:        {
        !           564:                scr_copyeverything = 1;
        !           565:                Con_DrawConsole (scr_con_current);
        !           566:                clearconsole = 0;
        !           567:        }
        !           568:        else
        !           569:        {
        !           570:                if (key_dest == key_game || key_dest == key_message)
        !           571:                        Con_DrawNotify ();      // only draw notify in game
        !           572:        }
        !           573: }
        !           574: 
        !           575: 
        !           576: /* 
        !           577: ============================================================================== 
        !           578:  
        !           579:                                                SCREEN SHOTS 
        !           580:  
        !           581: ============================================================================== 
        !           582: */ 
        !           583: 
        !           584: 
        !           585: /* 
        !           586: ============== 
        !           587: WritePCXfile 
        !           588: ============== 
        !           589: */ 
        !           590: void WritePCXfile (char *filename, byte *data, int width, int height,
        !           591:        int rowbytes, byte *palette, qboolean upload) 
        !           592: {
        !           593:        int             i, j, length;
        !           594:        pcx_t   *pcx;
        !           595:        byte            *pack;
        !           596:          
        !           597:        pcx = Hunk_TempAlloc (width*height*2+1000);
        !           598:        if (pcx == NULL)
        !           599:        {
        !           600:                Con_Printf("SCR_ScreenShot_f: not enough memory\n");
        !           601:                return;
        !           602:        } 
        !           603:  
        !           604:        pcx->manufacturer = 0x0a;       // PCX id
        !           605:        pcx->version = 5;                       // 256 color
        !           606:        pcx->encoding = 1;              // uncompressed
        !           607:        pcx->bits_per_pixel = 8;                // 256 color
        !           608:        pcx->xmin = 0;
        !           609:        pcx->ymin = 0;
        !           610:        pcx->xmax = LittleShort((short)(width-1));
        !           611:        pcx->ymax = LittleShort((short)(height-1));
        !           612:        pcx->hres = LittleShort((short)width);
        !           613:        pcx->vres = LittleShort((short)height);
        !           614:        Q_memset (pcx->palette,0,sizeof(pcx->palette));
        !           615:        pcx->color_planes = 1;          // chunky image
        !           616:        pcx->bytes_per_line = LittleShort((short)width);
        !           617:        pcx->palette_type = LittleShort(2);             // not a grey scale
        !           618:        Q_memset (pcx->filler,0,sizeof(pcx->filler));
        !           619: 
        !           620: // pack the image
        !           621:        pack = &pcx->data;
        !           622:        
        !           623:        for (i=0 ; i<height ; i++)
        !           624:        {
        !           625:                for (j=0 ; j<width ; j++)
        !           626:                {
        !           627:                        if ( (*data & 0xc0) != 0xc0)
        !           628:                                *pack++ = *data++;
        !           629:                        else
        !           630:                        {
        !           631:                                *pack++ = 0xc1;
        !           632:                                *pack++ = *data++;
        !           633:                        }
        !           634:                }
        !           635: 
        !           636:                data += rowbytes - width;
        !           637:        }
        !           638:                        
        !           639: // write the palette
        !           640:        *pack++ = 0x0c; // palette ID byte
        !           641:        for (i=0 ; i<768 ; i++)
        !           642:                *pack++ = *palette++;
        !           643:                
        !           644: // write output file 
        !           645:        length = pack - (byte *)pcx;
        !           646:        if (upload)
        !           647:                CL_StartUpload((void *)pcx, length);
        !           648:        else
        !           649:                COM_WriteFile (filename, pcx, length);
        !           650: } 
        !           651:  
        !           652: 
        !           653: 
        !           654: /* 
        !           655: ================== 
        !           656: SCR_ScreenShot_f
        !           657: ================== 
        !           658: */  
        !           659: void SCR_ScreenShot_f (void) 
        !           660: { 
        !           661:        int     i; 
        !           662:        char            pcxname[80]; 
        !           663:        char            checkname[MAX_OSPATH];
        !           664: 
        !           665: // 
        !           666: // find a file name to save it to 
        !           667: // 
        !           668:        strcpy(pcxname,"quake00.pcx");
        !           669:                
        !           670:        for (i=0 ; i<=99 ; i++) 
        !           671:        { 
        !           672:                pcxname[5] = i/10 + '0'; 
        !           673:                pcxname[6] = i%10 + '0'; 
        !           674:                sprintf (checkname, "%s/%s", com_gamedir, pcxname);
        !           675:                if (Sys_FileTime(checkname) == -1)
        !           676:                        break;  // file doesn't exist
        !           677:        } 
        !           678:        if (i==100) 
        !           679:        {
        !           680:                Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX"); 
        !           681:                return;
        !           682:        }
        !           683:  
        !           684: // 
        !           685: // save the pcx file 
        !           686: // 
        !           687:        D_EnableBackBufferAccess ();    // enable direct drawing of console to back
        !           688:                                                                        //  buffer
        !           689: 
        !           690:        WritePCXfile (pcxname, vid.buffer, vid.width, vid.height, vid.rowbytes,
        !           691:                                  host_basepal, false);
        !           692: 
        !           693:        D_DisableBackBufferAccess ();   // for adapters that can't stay mapped in
        !           694:                                                                        //  for linear writes all the time
        !           695: 
        !           696:        Con_Printf ("Wrote %s\n", pcxname);
        !           697: } 
        !           698: 
        !           699: /*
        !           700: Find closest color in the palette for named color
        !           701: */
        !           702: int MipColor(int r, int g, int b)
        !           703: {
        !           704:        int i;
        !           705:        float dist;
        !           706:        int best;
        !           707:        float bestdist;
        !           708:        int r1, g1, b1;
        !           709:        static int lr = -1, lg = -1, lb = -1;
        !           710:        static int lastbest;
        !           711: 
        !           712:        if (r == lr && g == lg && b == lb)
        !           713:                return lastbest;
        !           714: 
        !           715:        bestdist = 256*256*3;
        !           716: 
        !           717:        for (i = 0; i < 256; i++) {
        !           718:                r1 = host_basepal[i*3] - r;
        !           719:                g1 = host_basepal[i*3+1] - g;
        !           720:                b1 = host_basepal[i*3+2] - b;
        !           721:                dist = r1*r1 + g1*g1 + b1*b1;
        !           722:                if (dist < bestdist) {
        !           723:                        bestdist = dist;
        !           724:                        best = i;
        !           725:                }
        !           726:        }
        !           727:        lr = r; lg = g; lb = b;
        !           728:        lastbest = best;
        !           729:        return best;
        !           730: }
        !           731: 
        !           732: // in draw.c
        !           733: extern byte            *draw_chars;                            // 8*8 graphic characters
        !           734: 
        !           735: void SCR_DrawCharToSnap (int num, byte *dest, int width)
        !           736: {
        !           737:        int             row, col;
        !           738:        byte    *source;
        !           739:        int             drawline;
        !           740:        int             x;
        !           741: 
        !           742:        row = num>>4;
        !           743:        col = num&15;
        !           744:        source = draw_chars + (row<<10) + (col<<3);
        !           745: 
        !           746:        drawline = 8;
        !           747: 
        !           748:        while (drawline--)
        !           749:        {
        !           750:                for (x=0 ; x<8 ; x++)
        !           751:                        if (source[x])
        !           752:                                dest[x] = source[x];
        !           753:                        else
        !           754:                                dest[x] = 98;
        !           755:                source += 128;
        !           756:                dest += width;
        !           757:        }
        !           758: 
        !           759: }
        !           760: 
        !           761: void SCR_DrawStringToSnap (const char *s, byte *buf, int x, int y, int width)
        !           762: {
        !           763:        byte *dest;
        !           764:        const unsigned char *p;
        !           765: 
        !           766:        dest = buf + ((y * width) + x);
        !           767: 
        !           768:        p = (const unsigned char *)s;
        !           769:        while (*p) {
        !           770:                SCR_DrawCharToSnap(*p++, dest, width);
        !           771:                dest += 8;
        !           772:        }
        !           773: }
        !           774: 
        !           775: 
        !           776: /* 
        !           777: ================== 
        !           778: SCR_RSShot_f
        !           779: ================== 
        !           780: */  
        !           781: void SCR_RSShot_f (void) 
        !           782: { 
        !           783:        int     i, x, y;
        !           784:        unsigned char           *src, *dest;
        !           785:        char            pcxname[80]; 
        !           786:        char            checkname[MAX_OSPATH];
        !           787:        unsigned char           *newbuf, *srcbuf;
        !           788:        int srcrowbytes;
        !           789:        int w, h;
        !           790:        int dx, dy, dex, dey, nx;
        !           791:        int r, b, g;
        !           792:        int count;
        !           793:        float fracw, frach;
        !           794:        char st[80];
        !           795:        time_t now;
        !           796: 
        !           797:        if (CL_IsUploading())
        !           798:                return; // already one pending
        !           799: 
        !           800:        if (cls.state < ca_onserver)
        !           801:                return; // gotta be connected
        !           802: 
        !           803:        if (!scr_allowsnap.value) {
        !           804:                MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
        !           805:                SZ_Print (&cls.netchan.message, "snap\n");
        !           806:                Con_Printf("Refusing remote screen shot request.\n");
        !           807:                return;
        !           808:        }
        !           809: 
        !           810:        Con_Printf("Remote screen shot requested.\n");
        !           811: 
        !           812: #if 0
        !           813: // 
        !           814: // find a file name to save it to 
        !           815: // 
        !           816:        strcpy(pcxname,"mquake00.pcx");
        !           817:                
        !           818:        for (i=0 ; i<=99 ; i++) 
        !           819:        { 
        !           820:                pcxname[6] = i/10 + '0'; 
        !           821:                pcxname[7] = i%10 + '0'; 
        !           822:                sprintf (checkname, "%s/%s", com_gamedir, pcxname);
        !           823:                if (Sys_FileTime(checkname) == -1)
        !           824:                        break;  // file doesn't exist
        !           825:        } 
        !           826:        if (i==100) 
        !           827:        {
        !           828:                Con_Printf ("SCR_ScreenShot_f: Couldn't create a PCX"); 
        !           829:                return;
        !           830:        }
        !           831: #endif
        !           832:  
        !           833: // 
        !           834: // save the pcx file 
        !           835: // 
        !           836:        D_EnableBackBufferAccess ();    // enable direct drawing of console to back
        !           837:                                                                        //  buffer
        !           838: 
        !           839:        w = (vid.width < RSSHOT_WIDTH) ? vid.width : RSSHOT_WIDTH;
        !           840:        h = (vid.height < RSSHOT_HEIGHT) ? vid.height : RSSHOT_HEIGHT;
        !           841: 
        !           842:        fracw = (float)vid.width / (float)w;
        !           843:        frach = (float)vid.height / (float)h;
        !           844: 
        !           845:        newbuf = malloc(w*h);
        !           846: 
        !           847:        for (y = 0; y < h; y++) {
        !           848:                dest = newbuf + (w * y);
        !           849: 
        !           850:                for (x = 0; x < w; x++) {
        !           851:                        r = g = b = 0;
        !           852: 
        !           853:                        dx = x * fracw;
        !           854:                        dex = (x + 1) * fracw;
        !           855:                        if (dex == dx) dex++; // at least one
        !           856:                        dy = y * frach;
        !           857:                        dey = (y + 1) * frach;
        !           858:                        if (dey == dy) dey++; // at least one
        !           859: 
        !           860:                        count = 0;
        !           861:                        for (/* */; dy < dey; dy++) {
        !           862:                                src = vid.buffer + (vid.rowbytes * dy) + dx;
        !           863:                                for (nx = dx; nx < dex; nx++) {
        !           864:                                        r += host_basepal[*src * 3];
        !           865:                                        g += host_basepal[*src * 3+1];
        !           866:                                        b += host_basepal[*src * 3+2];
        !           867:                                        src++;
        !           868:                                        count++;
        !           869:                                }
        !           870:                        }
        !           871:                        r /= count;
        !           872:                        g /= count;
        !           873:                        b /= count;
        !           874:                        *dest++ = MipColor(r, g, b);
        !           875:                }
        !           876:        }
        !           877: 
        !           878:        time(&now);
        !           879:        strcpy(st, ctime(&now));
        !           880:        st[strlen(st) - 1] = 0;
        !           881:        SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, 0, w);
        !           882: 
        !           883:        strncpy(st, cls.servername, sizeof(st));
        !           884:        st[sizeof(st) - 1] = 0;
        !           885:        SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, 10, w);
        !           886: 
        !           887:        strncpy(st, name.string, sizeof(st));
        !           888:        st[sizeof(st) - 1] = 0;
        !           889:        SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, 20, w);
        !           890: 
        !           891:        WritePCXfile (pcxname, newbuf, w, h, w, host_basepal, true);
        !           892: 
        !           893:        free(newbuf);
        !           894: 
        !           895:        D_DisableBackBufferAccess ();   // for adapters that can't stay mapped in
        !           896:                                                                        //  for linear writes all the time
        !           897: 
        !           898: //     Con_Printf ("Wrote %s\n", pcxname);
        !           899:        Con_Printf ("Sending shot to server...\n");
        !           900: } 
        !           901: 
        !           902: 
        !           903: //=============================================================================
        !           904: 
        !           905: char   *scr_notifystring;
        !           906: qboolean       scr_drawdialog;
        !           907: 
        !           908: void SCR_DrawNotifyString (void)
        !           909: {
        !           910:        char    *start;
        !           911:        int             l;
        !           912:        int             j;
        !           913:        int             x, y;
        !           914: 
        !           915:        start = scr_notifystring;
        !           916: 
        !           917:        y = vid.height*0.35;
        !           918: 
        !           919:        do      
        !           920:        {
        !           921:        // scan the width of the line
        !           922:                for (l=0 ; l<40 ; l++)
        !           923:                        if (start[l] == '\n' || !start[l])
        !           924:                                break;
        !           925:                x = (vid.width - l*8)/2;
        !           926:                for (j=0 ; j<l ; j++, x+=8)
        !           927:                        Draw_Character (x, y, start[j]);        
        !           928:                        
        !           929:                y += 8;
        !           930: 
        !           931:                while (*start && *start != '\n')
        !           932:                        start++;
        !           933: 
        !           934:                if (!*start)
        !           935:                        break;
        !           936:                start++;                // skip the \n
        !           937:        } while (1);
        !           938: }
        !           939: 
        !           940: /*
        !           941: ==================
        !           942: SCR_ModalMessage
        !           943: 
        !           944: Displays a text string in the center of the screen and waits for a Y or N
        !           945: keypress.  
        !           946: ==================
        !           947: */
        !           948: int SCR_ModalMessage (char *text)
        !           949: {
        !           950:        scr_notifystring = text;
        !           951:  
        !           952: // draw a fresh screen
        !           953:        scr_fullupdate = 0;
        !           954:        scr_drawdialog = true;
        !           955:        SCR_UpdateScreen ();
        !           956:        scr_drawdialog = false;
        !           957:        
        !           958:        S_ClearBuffer ();               // so dma doesn't loop current sound
        !           959: 
        !           960:        do
        !           961:        {
        !           962:                key_count = -1;         // wait for a key down and up
        !           963:                Sys_SendKeyEvents ();
        !           964:        } while (key_lastpress != 'y' && key_lastpress != 'n' && key_lastpress != K_ESCAPE);
        !           965: 
        !           966:        scr_fullupdate = 0;
        !           967:        SCR_UpdateScreen ();
        !           968: 
        !           969:        return key_lastpress == 'y';
        !           970: }
        !           971: 
        !           972: 
        !           973: //=============================================================================
        !           974: 
        !           975: /*
        !           976: ===============
        !           977: SCR_BringDownConsole
        !           978: 
        !           979: Brings the console down and fades the palettes back to normal
        !           980: ================
        !           981: */
        !           982: void SCR_BringDownConsole (void)
        !           983: {
        !           984:        int             i;
        !           985:        
        !           986:        scr_centertime_off = 0;
        !           987:        
        !           988:        for (i=0 ; i<20 && scr_conlines != scr_con_current ; i++)
        !           989:                SCR_UpdateScreen ();
        !           990: 
        !           991:        cl.cshifts[0].percent = 0;              // no area contents palette on next frame
        !           992:        VID_SetPalette (host_basepal);
        !           993: }
        !           994: 
        !           995: 
        !           996: /*
        !           997: ==================
        !           998: SCR_UpdateScreen
        !           999: 
        !          1000: This is called every frame, and can also be called explicitly to flush
        !          1001: text to the screen.
        !          1002: 
        !          1003: WARNING: be very careful calling this from elsewhere, because the refresh
        !          1004: needs almost the entire 256k of stack space!
        !          1005: ==================
        !          1006: */
        !          1007: void SCR_UpdateScreen (void)
        !          1008: {
        !          1009:        static float    oldscr_viewsize;
        !          1010:        vrect_t         vrect;
        !          1011: 
        !          1012:        if (scr_skipupdate || block_drawing)
        !          1013:                return;
        !          1014: 
        !          1015:        if (scr_disabled_for_loading)
        !          1016:                return;
        !          1017: 
        !          1018: #ifdef _WIN32
        !          1019:        {       // don't suck up any cpu if minimized
        !          1020:                extern int Minimized;
        !          1021: 
        !          1022:                if (Minimized)
        !          1023:                        return;
        !          1024:        }
        !          1025: #endif
        !          1026: 
        !          1027:        scr_copytop = 0;
        !          1028:        scr_copyeverything = 0;
        !          1029: 
        !          1030:        if (!scr_initialized || !con_initialized)
        !          1031:                return;                         // not initialized yet
        !          1032: 
        !          1033:        if (scr_viewsize.value != oldscr_viewsize)
        !          1034:        {
        !          1035:                oldscr_viewsize = scr_viewsize.value;
        !          1036:                vid.recalc_refdef = 1;
        !          1037:        }
        !          1038:        
        !          1039: //
        !          1040: // check for vid changes
        !          1041: //
        !          1042:        if (oldfov != scr_fov.value)
        !          1043:        {
        !          1044:                oldfov = scr_fov.value;
        !          1045:                vid.recalc_refdef = true;
        !          1046:        }
        !          1047:        
        !          1048:        if (oldscreensize != scr_viewsize.value)
        !          1049:        {
        !          1050:                oldscreensize = scr_viewsize.value;
        !          1051:                vid.recalc_refdef = true;
        !          1052:        }
        !          1053: 
        !          1054:        if (oldsbar != cl_sbar.value)
        !          1055:        {
        !          1056:                oldsbar = cl_sbar.value;
        !          1057:                vid.recalc_refdef = true;
        !          1058:        }
        !          1059:        
        !          1060:        if (vid.recalc_refdef)
        !          1061:        {
        !          1062:                // something changed, so reorder the screen
        !          1063:                SCR_CalcRefdef ();
        !          1064:        }
        !          1065: 
        !          1066: //
        !          1067: // do 3D refresh drawing, and then update the screen
        !          1068: //
        !          1069:        D_EnableBackBufferAccess ();    // of all overlay stuff if drawing directly
        !          1070: 
        !          1071:        if (scr_fullupdate++ < vid.numpages)
        !          1072:        {       // clear the entire screen
        !          1073:                scr_copyeverything = 1;
        !          1074:                Draw_TileClear (0,0,vid.width,vid.height);
        !          1075:                Sbar_Changed ();
        !          1076:        }
        !          1077: 
        !          1078:        pconupdate = NULL;
        !          1079: 
        !          1080: 
        !          1081:        SCR_SetUpToDrawConsole ();
        !          1082:        SCR_EraseCenterString ();
        !          1083:        
        !          1084:        D_DisableBackBufferAccess ();   // for adapters that can't stay mapped in
        !          1085:                                                                        //  for linear writes all the time
        !          1086: 
        !          1087:        VID_LockBuffer ();
        !          1088:        V_RenderView ();
        !          1089:        VID_UnlockBuffer ();
        !          1090: 
        !          1091:        D_EnableBackBufferAccess ();    // of all overlay stuff if drawing directly
        !          1092: 
        !          1093:        if (scr_drawdialog)
        !          1094:        {
        !          1095:                Sbar_Draw ();
        !          1096:                Draw_FadeScreen ();
        !          1097:                SCR_DrawNotifyString ();
        !          1098:                scr_copyeverything = true;
        !          1099:        }
        !          1100:        else if (cl.intermission == 1 && key_dest == key_game)
        !          1101:        {
        !          1102:                Sbar_IntermissionOverlay ();
        !          1103:        }
        !          1104:        else if (cl.intermission == 2 && key_dest == key_game)
        !          1105:        {
        !          1106:                Sbar_FinaleOverlay ();
        !          1107:                SCR_CheckDrawCenterString ();
        !          1108:        }
        !          1109:        else
        !          1110:        {
        !          1111:                SCR_DrawRam ();
        !          1112:                SCR_DrawNet ();
        !          1113:                SCR_DrawTurtle ();
        !          1114:                SCR_DrawPause ();
        !          1115:                SCR_DrawFPS ();
        !          1116:                SCR_CheckDrawCenterString ();
        !          1117:                Sbar_Draw ();
        !          1118:                SCR_DrawConsole ();     
        !          1119:                M_Draw ();
        !          1120:        }
        !          1121: 
        !          1122: 
        !          1123:        D_DisableBackBufferAccess ();   // for adapters that can't stay mapped in
        !          1124:                                                                        //  for linear writes all the time
        !          1125:        if (pconupdate)
        !          1126:        {
        !          1127:                D_UpdateRects (pconupdate);
        !          1128:        }
        !          1129: 
        !          1130:        V_UpdatePalette ();
        !          1131: 
        !          1132: //
        !          1133: // update one of three areas
        !          1134: //
        !          1135:        if (scr_copyeverything)
        !          1136:        {
        !          1137:                vrect.x = 0;
        !          1138:                vrect.y = 0;
        !          1139:                vrect.width = vid.width;
        !          1140:                vrect.height = vid.height;
        !          1141:                vrect.pnext = 0;
        !          1142:        
        !          1143:                VID_Update (&vrect);
        !          1144:        }
        !          1145:        else if (scr_copytop)
        !          1146:        {
        !          1147:                vrect.x = 0;
        !          1148:                vrect.y = 0;
        !          1149:                vrect.width = vid.width;
        !          1150:                vrect.height = vid.height - sb_lines;
        !          1151:                vrect.pnext = 0;
        !          1152:        
        !          1153:                VID_Update (&vrect);
        !          1154:        }       
        !          1155:        else
        !          1156:        {
        !          1157:                vrect.x = scr_vrect.x;
        !          1158:                vrect.y = scr_vrect.y;
        !          1159:                vrect.width = scr_vrect.width;
        !          1160:                vrect.height = scr_vrect.height;
        !          1161:                vrect.pnext = 0;
        !          1162:        
        !          1163:                VID_Update (&vrect);
        !          1164:        }       
        !          1165: }
        !          1166: 
        !          1167: /*
        !          1168: ==================
        !          1169: SCR_UpdateWholeScreen
        !          1170: ==================
        !          1171: */
        !          1172: void SCR_UpdateWholeScreen (void)
        !          1173: {
        !          1174:        scr_fullupdate = 0;
        !          1175:        SCR_UpdateScreen ();
        !          1176: }

unix.superglobalmegacorp.com

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