Annotation of quake2/client/console.c, revision 1.1

1.1     ! root        1: // console.c
        !             2: 
        !             3: #include "client.h"
        !             4: 
        !             5: console_t      con;
        !             6: 
        !             7: cvar_t         *con_notifytime;
        !             8: 
        !             9: 
        !            10: #define                MAXCMDLINE      256
        !            11: extern char    key_lines[32][MAXCMDLINE];
        !            12: extern int             edit_line;
        !            13: extern int             key_linepos;
        !            14:                
        !            15: 
        !            16: void DrawString (int x, int y, char *s)
        !            17: {
        !            18:        while (*s)
        !            19:        {
        !            20:                re.DrawChar (x, y, *s);
        !            21:                x+=8;
        !            22:                s++;
        !            23:        }
        !            24: }
        !            25: 
        !            26: void DrawAltString (int x, int y, char *s)
        !            27: {
        !            28:        while (*s)
        !            29:        {
        !            30:                re.DrawChar (x, y, *s ^ 0x80);
        !            31:                x+=8;
        !            32:                s++;
        !            33:        }
        !            34: }
        !            35: 
        !            36: 
        !            37: void Key_ClearTyping (void)
        !            38: {
        !            39:        key_lines[edit_line][1] = 0;    // clear any typing
        !            40:        key_linepos = 1;
        !            41: }
        !            42: 
        !            43: /*
        !            44: ================
        !            45: Con_ToggleConsole_f
        !            46: ================
        !            47: */
        !            48: void Con_ToggleConsole_f (void)
        !            49: {
        !            50:        SCR_EndLoadingPlaque ();        // get rid of loading plaque
        !            51: 
        !            52:        if (cl.attractloop)
        !            53:        {
        !            54:                Cbuf_AddText ("killserver\n");
        !            55:                return;
        !            56:        }
        !            57: 
        !            58:        if (cls.state == ca_disconnected)
        !            59:        {       // start the demo loop again
        !            60:                Cbuf_AddText ("d1\n");
        !            61:                return;
        !            62:        }
        !            63: 
        !            64:        Key_ClearTyping ();
        !            65:        Con_ClearNotify ();
        !            66: 
        !            67:        if (cls.key_dest == key_console)
        !            68:        {
        !            69:                M_ForceMenuOff ();
        !            70:                Cvar_Set ("paused", "0");
        !            71:        }
        !            72:        else
        !            73:        {
        !            74:                M_ForceMenuOff ();
        !            75:                cls.key_dest = key_console;     
        !            76: 
        !            77:                if (Cvar_VariableValue ("maxclients") == 1 
        !            78:                        && Com_ServerState ())
        !            79:                        Cvar_Set ("paused", "1");
        !            80:        }
        !            81: }
        !            82: 
        !            83: /*
        !            84: ================
        !            85: Con_ToggleChat_f
        !            86: ================
        !            87: */
        !            88: void Con_ToggleChat_f (void)
        !            89: {
        !            90:        Key_ClearTyping ();
        !            91: 
        !            92:        if (cls.key_dest == key_console)
        !            93:        {
        !            94:                if (cls.state == ca_active)
        !            95:                {
        !            96:                        M_ForceMenuOff ();
        !            97:                        cls.key_dest = key_game;
        !            98:                }
        !            99:        }
        !           100:        else
        !           101:                cls.key_dest = key_console;
        !           102:        
        !           103:        Con_ClearNotify ();
        !           104: }
        !           105: 
        !           106: /*
        !           107: ================
        !           108: Con_Clear_f
        !           109: ================
        !           110: */
        !           111: void Con_Clear_f (void)
        !           112: {
        !           113:        memset (con.text, ' ', CON_TEXTSIZE);
        !           114: }
        !           115: 
        !           116:                                                
        !           117: /*
        !           118: ================
        !           119: Con_Dump_f
        !           120: 
        !           121: Save the console contents out to a file
        !           122: ================
        !           123: */
        !           124: void Con_Dump_f (void)
        !           125: {
        !           126:        int             l, x;
        !           127:        char    *line;
        !           128:        FILE    *f;
        !           129:        char    buffer[1024];
        !           130:        char    name[MAX_OSPATH];
        !           131: 
        !           132:        if (Cmd_Argc() != 2)
        !           133:        {
        !           134:                Com_Printf ("usage: condump <filename>\n");
        !           135:                return;
        !           136:        }
        !           137: 
        !           138:        Com_sprintf (name, sizeof(name), "%s/%s.txt", FS_Gamedir(), Cmd_Argv(1));
        !           139: 
        !           140:        Com_Printf ("Dumped console text to %s.\n", name);
        !           141:        FS_CreatePath (name);
        !           142:        f = fopen (name, "w");
        !           143:        if (!f)
        !           144:        {
        !           145:                Com_Printf ("ERROR: couldn't open.\n");
        !           146:                return;
        !           147:        }
        !           148: 
        !           149:        // skip empty lines
        !           150:        for (l = con.current - con.totallines + 1 ; l <= con.current ; l++)
        !           151:        {
        !           152:                line = con.text + (l%con.totallines)*con.linewidth;
        !           153:                for (x=0 ; x<con.linewidth ; x++)
        !           154:                        if (line[x] != ' ')
        !           155:                                break;
        !           156:                if (x != con.linewidth)
        !           157:                        break;
        !           158:        }
        !           159: 
        !           160:        // write the remaining lines
        !           161:        buffer[con.linewidth] = 0;
        !           162:        for ( ; l <= con.current ; l++)
        !           163:        {
        !           164:                line = con.text + (l%con.totallines)*con.linewidth;
        !           165:                strncpy (buffer, line, con.linewidth);
        !           166:                for (x=con.linewidth-1 ; x>=0 ; x--)
        !           167:                {
        !           168:                        if (buffer[x] == ' ')
        !           169:                                buffer[x] = 0;
        !           170:                        else
        !           171:                                break;
        !           172:                }
        !           173: 
        !           174:                fprintf (f, "%s\n", buffer);
        !           175:        }
        !           176: 
        !           177:        fclose (f);
        !           178: }
        !           179: 
        !           180:                                                
        !           181: /*
        !           182: ================
        !           183: Con_ClearNotify
        !           184: ================
        !           185: */
        !           186: void Con_ClearNotify (void)
        !           187: {
        !           188:        int             i;
        !           189:        
        !           190:        for (i=0 ; i<NUM_CON_TIMES ; i++)
        !           191:                con.times[i] = 0;
        !           192: }
        !           193: 
        !           194:                                                
        !           195: /*
        !           196: ================
        !           197: Con_MessageMode_f
        !           198: ================
        !           199: */
        !           200: void Con_MessageMode_f (void)
        !           201: {
        !           202:        chat_team = false;
        !           203:        cls.key_dest = key_message;
        !           204: }
        !           205: 
        !           206: /*
        !           207: ================
        !           208: Con_MessageMode2_f
        !           209: ================
        !           210: */
        !           211: void Con_MessageMode2_f (void)
        !           212: {
        !           213:        chat_team = true;
        !           214:        cls.key_dest = key_message;
        !           215: }
        !           216: 
        !           217: /*
        !           218: ================
        !           219: Con_CheckResize
        !           220: 
        !           221: If the line width has changed, reformat the buffer.
        !           222: ================
        !           223: */
        !           224: void Con_CheckResize (void)
        !           225: {
        !           226:        int             i, j, width, oldwidth, oldtotallines, numlines, numchars;
        !           227:        char    tbuf[CON_TEXTSIZE];
        !           228: 
        !           229:        width = (viddef.width >> 3) - 2;
        !           230: 
        !           231:        if (width == con.linewidth)
        !           232:                return;
        !           233: 
        !           234:        if (width < 1)                  // video hasn't been initialized yet
        !           235:        {
        !           236:                width = 38;
        !           237:                con.linewidth = width;
        !           238:                con.totallines = CON_TEXTSIZE / con.linewidth;
        !           239:                memset (con.text, ' ', CON_TEXTSIZE);
        !           240:        }
        !           241:        else
        !           242:        {
        !           243:                oldwidth = con.linewidth;
        !           244:                con.linewidth = width;
        !           245:                oldtotallines = con.totallines;
        !           246:                con.totallines = CON_TEXTSIZE / con.linewidth;
        !           247:                numlines = oldtotallines;
        !           248: 
        !           249:                if (con.totallines < numlines)
        !           250:                        numlines = con.totallines;
        !           251: 
        !           252:                numchars = oldwidth;
        !           253:        
        !           254:                if (con.linewidth < numchars)
        !           255:                        numchars = con.linewidth;
        !           256: 
        !           257:                memcpy (tbuf, con.text, CON_TEXTSIZE);
        !           258:                memset (con.text, ' ', CON_TEXTSIZE);
        !           259: 
        !           260:                for (i=0 ; i<numlines ; i++)
        !           261:                {
        !           262:                        for (j=0 ; j<numchars ; j++)
        !           263:                        {
        !           264:                                con.text[(con.totallines - 1 - i) * con.linewidth + j] =
        !           265:                                                tbuf[((con.current - i + oldtotallines) %
        !           266:                                                          oldtotallines) * oldwidth + j];
        !           267:                        }
        !           268:                }
        !           269: 
        !           270:                Con_ClearNotify ();
        !           271:        }
        !           272: 
        !           273:        con.current = con.totallines - 1;
        !           274:        con.display = con.current;
        !           275: }
        !           276: 
        !           277: 
        !           278: /*
        !           279: ================
        !           280: Con_Init
        !           281: ================
        !           282: */
        !           283: void Con_Init (void)
        !           284: {
        !           285:        con.linewidth = -1;
        !           286: 
        !           287:        Con_CheckResize ();
        !           288:        
        !           289:        Com_Printf ("Console initialized.\n");
        !           290: 
        !           291: //
        !           292: // register our commands
        !           293: //
        !           294:        con_notifytime = Cvar_Get ("con_notifytime", "3", 0);
        !           295: 
        !           296:        Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
        !           297:        Cmd_AddCommand ("togglechat", Con_ToggleChat_f);
        !           298:        Cmd_AddCommand ("messagemode", Con_MessageMode_f);
        !           299:        Cmd_AddCommand ("messagemode2", Con_MessageMode2_f);
        !           300:        Cmd_AddCommand ("clear", Con_Clear_f);
        !           301:        Cmd_AddCommand ("condump", Con_Dump_f);
        !           302:        con.initialized = true;
        !           303: }
        !           304: 
        !           305: 
        !           306: /*
        !           307: ===============
        !           308: Con_Linefeed
        !           309: ===============
        !           310: */
        !           311: void Con_Linefeed (void)
        !           312: {
        !           313:        con.x = 0;
        !           314:        if (con.display == con.current)
        !           315:                con.display++;
        !           316:        con.current++;
        !           317:        memset (&con.text[(con.current%con.totallines)*con.linewidth]
        !           318:        , ' ', con.linewidth);
        !           319: }
        !           320: 
        !           321: /*
        !           322: ================
        !           323: Con_Print
        !           324: 
        !           325: Handles cursor positioning, line wrapping, etc
        !           326: All console printing must go through this in order to be logged to disk
        !           327: If no console is visible, the text will appear at the top of the game window
        !           328: ================
        !           329: */
        !           330: void Con_Print (char *txt)
        !           331: {
        !           332:        int             y;
        !           333:        int             c, l;
        !           334:        static int      cr;
        !           335:        int             mask;
        !           336: 
        !           337:        if (!con.initialized)
        !           338:                return;
        !           339: 
        !           340:        if (txt[0] == 1 || txt[0] == 2)
        !           341:        {
        !           342:                mask = 128;             // go to colored text
        !           343:                txt++;
        !           344:        }
        !           345:        else
        !           346:                mask = 0;
        !           347: 
        !           348: 
        !           349:        while ( (c = *txt) )
        !           350:        {
        !           351:        // count word length
        !           352:                for (l=0 ; l< con.linewidth ; l++)
        !           353:                        if ( txt[l] <= ' ')
        !           354:                                break;
        !           355: 
        !           356:        // word wrap
        !           357:                if (l != con.linewidth && (con.x + l > con.linewidth) )
        !           358:                        con.x = 0;
        !           359: 
        !           360:                txt++;
        !           361: 
        !           362:                if (cr)
        !           363:                {
        !           364:                        con.current--;
        !           365:                        cr = false;
        !           366:                }
        !           367: 
        !           368:                
        !           369:                if (!con.x)
        !           370:                {
        !           371:                        Con_Linefeed ();
        !           372:                // mark time for transparent overlay
        !           373:                        if (con.current >= 0)
        !           374:                                con.times[con.current % NUM_CON_TIMES] = cls.realtime;
        !           375:                }
        !           376: 
        !           377:                switch (c)
        !           378:                {
        !           379:                case '\n':
        !           380:                        con.x = 0;
        !           381:                        break;
        !           382: 
        !           383:                case '\r':
        !           384:                        con.x = 0;
        !           385:                        cr = 1;
        !           386:                        break;
        !           387: 
        !           388:                default:        // display character and advance
        !           389:                        y = con.current % con.totallines;
        !           390:                        con.text[y*con.linewidth+con.x] = c | mask | con.ormask;
        !           391:                        con.x++;
        !           392:                        if (con.x >= con.linewidth)
        !           393:                                con.x = 0;
        !           394:                        break;
        !           395:                }
        !           396:                
        !           397:        }
        !           398: }
        !           399: 
        !           400: 
        !           401: /*
        !           402: ==============
        !           403: Con_CenteredPrint
        !           404: ==============
        !           405: */
        !           406: void Con_CenteredPrint (char *text)
        !           407: {
        !           408:        int             l;
        !           409:        char    buffer[1024];
        !           410: 
        !           411:        l = strlen(text);
        !           412:        l = (con.linewidth-l)/2;
        !           413:        if (l < 0)
        !           414:                l = 0;
        !           415:        memset (buffer, ' ', l);
        !           416:        strcpy (buffer+l, text);
        !           417:        strcat (buffer, "\n");
        !           418:        Con_Print (buffer);
        !           419: }
        !           420: 
        !           421: /*
        !           422: ==============================================================================
        !           423: 
        !           424: DRAWING
        !           425: 
        !           426: ==============================================================================
        !           427: */
        !           428: 
        !           429: 
        !           430: /*
        !           431: ================
        !           432: Con_DrawInput
        !           433: 
        !           434: The input line scrolls horizontally if typing goes beyond the right edge
        !           435: ================
        !           436: */
        !           437: void Con_DrawInput (void)
        !           438: {
        !           439:        int             y;
        !           440:        int             i;
        !           441:        char    *text;
        !           442: 
        !           443:        if (cls.key_dest == key_menu)
        !           444:                return;
        !           445:        if (cls.key_dest != key_console && cls.state == ca_active)
        !           446:                return;         // don't draw anything (always draw if not active)
        !           447: 
        !           448:        text = key_lines[edit_line];
        !           449:        
        !           450: // add the cursor frame
        !           451:        text[key_linepos] = 10+((int)(cls.realtime>>8)&1);
        !           452:        
        !           453: // fill out remainder with spaces
        !           454:        for (i=key_linepos+1 ; i< con.linewidth ; i++)
        !           455:                text[i] = ' ';
        !           456:                
        !           457: //     prestep if horizontally scrolling
        !           458:        if (key_linepos >= con.linewidth)
        !           459:                text += 1 + key_linepos - con.linewidth;
        !           460:                
        !           461: // draw it
        !           462:        y = con.vislines-16;
        !           463: 
        !           464:        for (i=0 ; i<con.linewidth ; i++)
        !           465:                re.DrawChar ( (i+1)<<3, con.vislines - 16, text[i]);
        !           466: 
        !           467: // remove cursor
        !           468:        key_lines[edit_line][key_linepos] = 0;
        !           469: }
        !           470: 
        !           471: 
        !           472: /*
        !           473: ================
        !           474: Con_DrawNotify
        !           475: 
        !           476: Draws the last few lines of output transparently over the game top
        !           477: ================
        !           478: */
        !           479: void Con_DrawNotify (void)
        !           480: {
        !           481:        int             x, v;
        !           482:        char    *text;
        !           483:        int             i;
        !           484:        int             time;
        !           485:        char    *s;
        !           486:        int             skip;
        !           487: 
        !           488:        v = 0;
        !           489:        for (i= con.current-NUM_CON_TIMES+1 ; i<=con.current ; i++)
        !           490:        {
        !           491:                if (i < 0)
        !           492:                        continue;
        !           493:                time = con.times[i % NUM_CON_TIMES];
        !           494:                if (time == 0)
        !           495:                        continue;
        !           496:                time = cls.realtime - time;
        !           497:                if (time > con_notifytime->value*1000)
        !           498:                        continue;
        !           499:                text = con.text + (i % con.totallines)*con.linewidth;
        !           500:                
        !           501:                for (x = 0 ; x < con.linewidth ; x++)
        !           502:                        re.DrawChar ( (x+1)<<3, v, text[x]);
        !           503: 
        !           504:                v += 8;
        !           505:        }
        !           506: 
        !           507: 
        !           508:        if (cls.key_dest == key_message)
        !           509:        {
        !           510:                if (chat_team)
        !           511:                {
        !           512:                        DrawString (8, v, "say_team:");
        !           513:                        skip = 11;
        !           514:                }
        !           515:                else
        !           516:                {
        !           517:                        DrawString (8, v, "say:");
        !           518:                        skip = 5;
        !           519:                }
        !           520: 
        !           521:                s = chat_buffer;
        !           522:                if (chat_bufferlen > (viddef.width>>3)-(skip+1))
        !           523:                        s += chat_bufferlen - ((viddef.width>>3)-(skip+1));
        !           524:                x = 0;
        !           525:                while(s[x])
        !           526:                {
        !           527:                        re.DrawChar ( (x+skip)<<3, v, s[x]);
        !           528:                        x++;
        !           529:                }
        !           530:                re.DrawChar ( (x+skip)<<3, v, 10+((cls.realtime>>8)&1));
        !           531:                v += 8;
        !           532:        }
        !           533:        
        !           534:        if (v)
        !           535:        {
        !           536:                SCR_AddDirtyPoint (0,0);
        !           537:                SCR_AddDirtyPoint (viddef.width-1, v);
        !           538:        }
        !           539: }
        !           540: 
        !           541: /*
        !           542: ================
        !           543: Con_DrawConsole
        !           544: 
        !           545: Draws the console with the solid background
        !           546: ================
        !           547: */
        !           548: void Con_DrawConsole (float frac)
        !           549: {
        !           550:        int                             i, x, y;
        !           551:        int                             rows;
        !           552:        char                    *text;
        !           553:        int                             row;
        !           554:        int                             lines;
        !           555:        char                    version[64];
        !           556: 
        !           557:        lines = viddef.height * frac;
        !           558:        if (lines <= 0)
        !           559:                return;
        !           560: 
        !           561:        if (lines > viddef.height)
        !           562:                lines = viddef.height;
        !           563: 
        !           564: // draw the background
        !           565:        re.DrawStretchPic (0, -viddef.height+lines, viddef.width, viddef.height, "conback");
        !           566:        SCR_AddDirtyPoint (0,0);
        !           567:        SCR_AddDirtyPoint (viddef.width-1,lines-1);
        !           568: 
        !           569:        Com_sprintf (version, sizeof(version), "v%4.2f", VERSION);
        !           570:        for (x=0 ; x<5 ; x++)
        !           571:                re.DrawChar (viddef.width-44+x*8, lines-12, 128 + version[x] );
        !           572: 
        !           573: // draw the text
        !           574:        con.vislines = lines;
        !           575:        
        !           576:        rows = (lines-8)>>3;            // rows of text to draw
        !           577: 
        !           578:        y = lines - 24;
        !           579: 
        !           580: // draw from the bottom up
        !           581:        if (con.display != con.current)
        !           582:        {
        !           583:        // draw arrows to show the buffer is backscrolled
        !           584:                for (x=0 ; x<con.linewidth ; x+=4)
        !           585:                        re.DrawChar ( (x+1)<<3, y, '^');
        !           586:        
        !           587:                y -= 8;
        !           588:                rows--;
        !           589:        }
        !           590:        
        !           591:        row = con.display;
        !           592:        for (i=0 ; i<rows ; i++, y-=8, row--)
        !           593:        {
        !           594:                if (row < 0)
        !           595:                        break;
        !           596:                if (con.current - row >= con.totallines)
        !           597:                        break;          // past scrollback wrap point
        !           598:                        
        !           599:                text = con.text + (row % con.totallines)*con.linewidth;
        !           600: 
        !           601:                for (x=0 ; x<con.linewidth ; x++)
        !           602:                        re.DrawChar ( (x+1)<<3, y, text[x]);
        !           603:        }
        !           604: 
        !           605: // draw the input prompt, user text, and cursor if desired
        !           606:        Con_DrawInput ();
        !           607: }
        !           608: 
        !           609: 

unix.superglobalmegacorp.com

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