コード例 #1
0
ファイル: cl_input.c プロジェクト: Bad-ptr/q2pro
static void KeyDown (kbutton_t *b) {
    int k;
    char *c;
    
    c = Cmd_Argv(1);
    if (c[0])
        k = atoi(c);
    else
        k = -1;        // typed manually at the console for continuous down

    if (k == b->down[0] || k == b->down[1])
        return;        // repeating key
    
    if (!b->down[0])
        b->down[0] = k;
    else if (!b->down[1])
        b->down[1] = k;
    else {
        Com_WPrintf ("Three keys down for a button!\n");
        return;
    }
    
    if (b->state & 1)
        return;        // still down

    // save timestamp
    c = Cmd_Argv(2);
    b->downtime = atoi(c);
    if (!b->downtime) {
        b->downtime = com_eventTime - 100;
    }

    b->state |= 1 + 2;    // down + impulse down
}
コード例 #2
0
ファイル: sv_init.c プロジェクト: Bad-ptr/q2pro
static void resolve_masters( void ) {
    master_t *m;
    time_t now, delta;

    now = time( NULL );
    FOR_EACH_MASTER( m ) {
        // re-resolve valid address after one day,
        // resolve invalid address after three hours
        delta = m->adr.port ? 24*60*60 : 3*60*60;
        if( now < m->last_resolved ) {
            m->last_resolved = now;
            continue;
        }
        if( now - m->last_resolved < delta ) {
            continue;
        }
        if( NET_StringToAdr( m->name, &m->adr, PORT_MASTER ) ) {
            Com_DPrintf( "Master server at %s.\n", NET_AdrToString( &m->adr ) );
        } else {
            Com_WPrintf( "Couldn't resolve master: %s\n", m->name );
            m->adr.port = 0;
        }
        m->last_resolved = now = time( NULL );
    }
}
コード例 #3
0
ファイル: cmd.c プロジェクト: Bad-ptr/q2pro
/*
============
Cbuf_AddText

Adds command text at the end of the buffer
============
*/
void Cbuf_AddText( cmdbuf_t *buf, const char *text ) {
    size_t l = strlen( text );

    if( buf->cursize + l > buf->maxsize ) {
        Com_WPrintf( "%s: overflow\n", __func__ );
        return;
    }
    memcpy( buf->text + buf->cursize, text, l );
    buf->cursize += l;
}
コード例 #4
0
ファイル: common.c プロジェクト: jayschwa/q2pro
void Com_AddConfigFile(const char *name, unsigned flags)
{
    qerror_t ret;

    ret = Cmd_ExecuteFile(name, flags);
    if (ret == Q_ERR_SUCCESS) {
        Cbuf_Execute(&cmd_buffer);
    } else if (ret != Q_ERR_NOENT) {
        Com_WPrintf("Couldn't exec %s: %s\n", name, Q_ErrorString(ret));
    }
}
コード例 #5
0
ファイル: cmd.c プロジェクト: Bad-ptr/q2pro
/*
============
Cbuf_InsertText

Adds command text at the beginning of command buffer.
Adds a \n to the text.
============
*/
void Cbuf_InsertText( cmdbuf_t *buf, const char *text ) {
    size_t l = strlen( text );

// add the entire text of the file
    if( !l ) {
        return;
    }
    if( buf->cursize + l + 1 > buf->maxsize ) {
        Com_WPrintf( "%s: overflow\n", __func__ );
        return;
    }

    memmove( buf->text + l + 1, buf->text, buf->cursize );
    memcpy( buf->text, text, l );
    buf->text[l] = '\n';
    buf->cursize += l + 1;
}
コード例 #6
0
ファイル: zone.c プロジェクト: AndreyNazarov/q2pro
void Z_LeakTest(memtag_t tag)
{
    zhead_t *z;
    size_t numLeaks = 0, numBytes = 0;

    Z_FOR_EACH(z) {
        Z_Validate(z, __func__);
        if (z->tag == tag) {
            numLeaks++;
            numBytes += z->size;
        }
    }

    if (numLeaks) {
        Com_WPrintf("************* Z_LeakTest *************\n"
                    "%s leaked %"PRIz" bytes of memory (%"PRIz" object%s)\n"
                    "**************************************\n",
                    z_tagnames[tag < TAG_MAX ? tag : TAG_FREE],
                    numBytes, numLeaks, numLeaks == 1 ? "" : "s");
    }
}
コード例 #7
0
ファイル: world.c プロジェクト: Jenco420/q2pro
/*
====================
SV_AreaEdicts_r

====================
*/
static void SV_AreaEdicts_r(areanode_t *node)
{
    list_t      *start;
    edict_t     *check;

    // touch linked edicts
    if (area_type == AREA_SOLID)
        start = &node->solid_edicts;
    else
        start = &node->trigger_edicts;

    LIST_FOR_EACH(edict_t, check, start, area) {
        if (check->solid == SOLID_NOT)
            continue;        // deactivated
        if (check->absmin[0] > area_maxs[0]
            || check->absmin[1] > area_maxs[1]
            || check->absmin[2] > area_maxs[2]
            || check->absmax[0] < area_mins[0]
            || check->absmax[1] < area_mins[1]
            || check->absmax[2] < area_mins[2])
            continue;        // not touching

        if (area_count == area_maxcount) {
            Com_WPrintf("SV_AreaEdicts: MAXCOUNT\n");
            return;
        }

        area_list[area_count] = check;
        area_count++;
    }

    if (node->axis == -1)
        return;        // terminal node

    // recurse down both sides
    if (area_maxs[node->axis] > node->dist)
        SV_AreaEdicts_r(node->children[0]);
    if (area_mins[node->axis] < node->dist)
        SV_AreaEdicts_r(node->children[1]);
}
コード例 #8
0
ファイル: cl_input.c プロジェクト: Bad-ptr/q2pro
static void CL_SendUserinfo( void ) {
    char userinfo[MAX_INFO_STRING];
    cvar_t *var;
    int i;

    if( !cls.userinfo_modified ) {
        return;
    }

    if( cls.userinfo_modified == MAX_PACKET_USERINFOS ) {
        size_t len = Cvar_BitInfo( userinfo, CVAR_USERINFO );
        Com_DDPrintf( "%s: %u: full update\n", __func__, com_framenum );
        MSG_WriteByte( clc_userinfo );
        MSG_WriteData( userinfo, len + 1 );
        MSG_FlushTo( &cls.netchan->message );
    } else if( cls.serverProtocol == PROTOCOL_VERSION_Q2PRO ) {
        Com_DDPrintf( "%s: %u: %d updates\n", __func__, com_framenum,
            cls.userinfo_modified );
        for( i = 0; i < cls.userinfo_modified; i++ ) { 
            var = cls.userinfo_updates[i];
            MSG_WriteByte( clc_userinfo_delta );
            MSG_WriteString( var->name );
            if( var->flags & CVAR_USERINFO ) {
                MSG_WriteString( var->string );
            } else {
                // no longer in userinfo
                MSG_WriteString( NULL );
            }
        }
        MSG_FlushTo( &cls.netchan->message );
    } else {
        Com_WPrintf( "%s: update count is %d, should never happen.\n",
            __func__, cls.userinfo_modified );
    }

    cls.userinfo_modified = 0;
}
コード例 #9
0
ファイル: common.c プロジェクト: jayschwa/q2pro
/*
=============
Com_Error

Both client and server can use this, and it will
do the apropriate things.
=============
*/
void Com_Error(error_type_t code, const char *fmt, ...)
{
    char            msg[MAXERRORMSG];
    va_list         argptr;
    size_t          len;

    // may not be entered recursively
    if (com_errorEntered) {
#ifdef _DEBUG
        if (com_debug_break && com_debug_break->integer) {
            Sys_DebugBreak();
        }
#endif
        Sys_Error("recursive error after: %s", com_errorMsg);
    }

    com_errorEntered = qtrue;

    va_start(argptr, fmt);
    len = Q_vscnprintf(msg, sizeof(msg), fmt, argptr);
    va_end(argptr);

    // save error msg
    // can't print into it directly since it may
    // overlap with one of the arguments!
    memcpy(com_errorMsg, msg, len + 1);

    // fix up drity message buffers
    MSG_Init();

    // abort any console redirects
    Com_AbortRedirect();

    // reset Com_Printf recursion level
    com_printEntered = 0;

    X86_POP_FPCW;

    if (code == ERR_DISCONNECT || code == ERR_RECONNECT) {
        Com_WPrintf("%s\n", com_errorMsg);
        SV_Shutdown(va("Server was killed: %s\n", com_errorMsg), code);
        CL_Disconnect(code);
        goto abort;
    }

#ifdef _DEBUG
    if (com_debug_break && com_debug_break->integer) {
        Sys_DebugBreak();
    }
#endif

    // make otherwise non-fatal errors fatal
    if (com_fatal_error && com_fatal_error->integer) {
        code = ERR_FATAL;
    }

    if (code == ERR_DROP) {
        Com_EPrintf("********************\n"
                    "ERROR: %s\n"
                    "********************\n", com_errorMsg);
        SV_Shutdown(va("Server crashed: %s\n", com_errorMsg), ERR_DROP);
        CL_Disconnect(ERR_DROP);
        goto abort;
    }

    if (com_logFile) {
        FS_FPrintf(com_logFile, "FATAL: %s\n", com_errorMsg);
    }

    SV_Shutdown(va("Server fatal crashed: %s\n", com_errorMsg), ERR_FATAL);
    CL_Shutdown();
    NET_Shutdown();
    logfile_close();
    FS_Shutdown();

    Sys_Error("%s", com_errorMsg);
    // doesn't get there

abort:
    if (com_logFile) {
        FS_Flush(com_logFile);
    }
    com_errorEntered = qfalse;
    longjmp(abortframe, -1);
}
コード例 #10
0
ファイル: glimp.c プロジェクト: Jenco420/q2pro
static int SetupGL(int colorbits, int depthbits, int stencilbits, int multisamples)
{
    PIXELFORMATDESCRIPTOR pfd;
    int pixelformat;

    // create the main window
    Win_Init();

    if (colorbits == 0)
        colorbits = 24;

    if (depthbits == 0)
        depthbits = colorbits > 16 ? 24 : 16;

    if (depthbits < 24)
        stencilbits = 0;

    // choose pixel format
    if (qwglChoosePixelFormatARB && multisamples > 1) {
        int iAttributes[20];
        UINT numFormats;

        iAttributes[0] = WGL_DRAW_TO_WINDOW_ARB;
        iAttributes[1] = TRUE;
        iAttributes[2] = WGL_SUPPORT_OPENGL_ARB;
        iAttributes[3] = TRUE;
        iAttributes[4] = WGL_DOUBLE_BUFFER_ARB;
        iAttributes[5] = TRUE;
        iAttributes[6] = WGL_PIXEL_TYPE_ARB;
        iAttributes[7] = WGL_TYPE_RGBA_ARB;
        iAttributes[8] = WGL_COLOR_BITS_ARB;
        iAttributes[9] = colorbits;
        iAttributes[10] = WGL_DEPTH_BITS_ARB;
        iAttributes[11] = depthbits;
        iAttributes[12] = WGL_STENCIL_BITS_ARB;
        iAttributes[13] = stencilbits;
        iAttributes[14] = WGL_SAMPLE_BUFFERS_ARB;
        iAttributes[15] = 1;
        iAttributes[16] = WGL_SAMPLES_ARB;
        iAttributes[17] = multisamples;
        iAttributes[18] = 0;
        iAttributes[19] = 0;

        if (qwglChoosePixelFormatARB(win.dc, iAttributes, NULL, 1, &pixelformat, &numFormats) == FALSE) {
            ReportLastError("wglChoosePixelFormatARB");
            goto soft;
        }
        if (numFormats == 0) {
            Com_EPrintf("No suitable OpenGL pixelformat found for %d multisamples\n", multisamples);
            goto soft;
        }
    } else {
        memset(&pfd, 0, sizeof(pfd));
        pfd.nSize = sizeof(pfd);
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = colorbits;
        pfd.cDepthBits = depthbits;
        pfd.cStencilBits = stencilbits;
        pfd.iLayerType = PFD_MAIN_PLANE;

        if (glw.minidriver) {
            if ((pixelformat = qwglChoosePixelFormat(win.dc, &pfd)) == 0) {
                ReportLastError("wglChoosePixelFormat");
                goto soft;
            }
        } else {
            if ((pixelformat = ChoosePixelFormat(win.dc, &pfd)) == 0) {
                ReportLastError("ChoosePixelFormat");
                goto soft;
            }
        }
    }

    // set pixel format
    if (glw.minidriver) {
        qwglDescribePixelFormat(win.dc, pixelformat, sizeof(pfd), &pfd);
        ReportPixelFormat(pixelformat, &pfd);

        if (qwglSetPixelFormat(win.dc, pixelformat, &pfd) == FALSE) {
            ReportLastError("wglSetPixelFormat");
            goto soft;
        }
    } else {
        DescribePixelFormat(win.dc, pixelformat, sizeof(pfd), &pfd);
        ReportPixelFormat(pixelformat, &pfd);

        if (SetPixelFormat(win.dc, pixelformat, &pfd) == FALSE) {
            ReportLastError("SetPixelFormat");
            goto soft;
        }
    }

    // check for software emulation
    if (pfd.dwFlags & PFD_GENERIC_FORMAT) {
        if (!gl_allow_software->integer) {
            Com_EPrintf("No hardware OpenGL acceleration detected\n");
            goto soft;
        }
        Com_WPrintf("...using software emulation\n");
    } else if (pfd.dwFlags & PFD_GENERIC_ACCELERATED) {
        Com_DPrintf("...MCD acceleration found\n");
        win.flags |= QVF_ACCELERATED;
    } else {
        Com_DPrintf("...ICD acceleration found\n");
        win.flags |= QVF_ACCELERATED;
    }

    // startup the OpenGL subsystem by creating a context and making it current
    if ((glw.hGLRC = qwglCreateContext(win.dc)) == NULL) {
        ReportLastError("wglCreateContext");
        goto hard;
    }

    if (qwglMakeCurrent(win.dc, glw.hGLRC) == FALSE) {
        ReportLastError("wglMakeCurrent");
        qwglDeleteContext(glw.hGLRC);
        glw.hGLRC = NULL;
        goto hard;
    }

    return FAIL_OK;

soft:
    // it failed, clean up
    Win_Shutdown();
    return FAIL_SOFT;

hard:
    Win_Shutdown();
    return FAIL_HARD;
}
コード例 #11
0
ファイル: http.c プロジェクト: jayschwa/q2pro
// Validate a path supplied by a filelist.
static void check_and_queue_download(char *path)
{
    size_t      len;
    char        *ext;
    dltype_t    type;
    unsigned    flags;
    int         valid;

    len = strlen(path);
    if (len >= MAX_QPATH)
        return;

    ext = strrchr(path, '.');
    if (!ext)
        return;

    ext++;
    if (!ext[0])
        return;

    Q_strlwr(ext);

    if (!strcmp(ext, "pak") || !strcmp(ext, "pkz")) {
        Com_Printf("[HTTP] Filelist is requesting a .%s file '%s'\n", ext, path);
        type = DL_PAK;
    } else {
        type = DL_OTHER;
        if (!CL_CheckDownloadExtension(ext)) {
            Com_WPrintf("[HTTP] Illegal file type '%s' in filelist.\n", path);
            return;
        }
    }

    if (path[0] == '@') {
        if (type == DL_PAK) {
            Com_WPrintf("[HTTP] '@' prefix used on a pak file '%s' in filelist.\n", path);
            return;
        }
        flags = FS_PATH_GAME;
        path++;
        len--;
    } else if (type == DL_PAK) {
        //by definition paks are game-local
        flags = FS_PATH_GAME | FS_TYPE_REAL;
    } else {
        flags = 0;
    }

    len = FS_NormalizePath(path, path);
    if (len == 0)
        return;

    valid = FS_ValidatePath(path);

    if (valid == PATH_INVALID ||
        !Q_ispath(path[0]) ||
        !Q_ispath(path[len - 1]) ||
        strstr(path, "..") ||
        (type == DL_OTHER && !strchr(path, '/')) ||
        (type == DL_PAK && strchr(path, '/'))) {
        Com_WPrintf("[HTTP] Illegal path '%s' in filelist.\n", path);
        return;
    }

    if (FS_FileExistsEx(path, flags))
        return;

    if (valid == PATH_MIXED_CASE)
        Q_strlwr(path);

    if (CL_IgnoreDownload(path))
        return;

    CL_QueueDownload(path, type);
}
コード例 #12
0
ファイル: script.c プロジェクト: m4son/q2pro
static qboolean Parse_File(const char *path, int depth)
{
    char *raw, *data, *p, *cmd;
    int argc;
    menuFrameWork_t *menu = NULL;
    qerror_t ret;

    ret = FS_LoadFile(path, (void **)&raw);
    if (!raw) {
        if (ret != Q_ERR_NOENT || depth) {
            Com_WPrintf("Couldn't %s %s: %s\n", depth ? "include" : "load",
                        path, Q_ErrorString(ret));
        }
        return qfalse;
    }

    data = raw;
    COM_Compress(data);

    while (*data) {
        p = strchr(data, '\n');
        if (p) {
            *p = 0;
        }

        Cmd_TokenizeString(data, qtrue);

        argc = Cmd_Argc();
        if (argc) {
            cmd = Cmd_Argv(0);
            if (menu) {
                if (!strcmp(cmd, "end")) {
                    if (menu->nitems) {
                        List_Append(&ui_menus, &menu->entry);
                    } else {
                        Com_WPrintf("Menu entry without items\n");
                        menu->free(menu);
                    }
                    menu = NULL;
                } else if (!strcmp(cmd, "title")) {
                    if (menu->title) {
                        Z_Free(menu->title);
                    }
                    menu->title = UI_CopyString(Cmd_Argv(1));
                } else if (!strcmp(cmd, "plaque")) {
                    Parse_Plaque(menu);
                } else if (!strcmp(cmd, "banner")) {
                    Parse_Banner(menu);
                } else if (!strcmp(cmd, "background")) {
                    Parse_Background(menu);
                } else if (!strcmp(cmd, "style")) {
                    Parse_Style(menu);
                } else if (!strcmp(cmd, "values")) {
                    Parse_Spin(menu, MTYPE_SPINCONTROL);
                } else if (!strcmp(cmd, "strings")) {
                    Parse_Spin(menu, MTYPE_STRINGS);
                } else if (!strcmp(cmd, "pairs")) {
                    Parse_Pairs(menu);
                } else if (!strcmp(cmd, "range")) {
                    Parse_Range(menu);
                } else if (!strcmp(cmd, "action")) {
                    Parse_Action(menu);
                } else if (!strcmp(cmd, "bitmap")) {
                    Parse_Bitmap(menu);
                } else if (!strcmp(cmd, "bind")) {
                    Parse_Bind(menu);
                } else if (!strcmp(cmd, "savegame")) {
                    Parse_Savegame(menu, MTYPE_SAVEGAME);
                } else if (!strcmp(cmd, "loadgame")) {
                    Parse_Savegame(menu, MTYPE_LOADGAME);
                } else if (!strcmp(cmd, "toggle")) {
                    Parse_Toggle(menu);
                } else if (!strcmp(cmd, "field")) {
                    Parse_Field(menu);
                } else if (!strcmp(cmd, "blank")) {
                    Parse_Blank(menu);
                } else {
                    Com_WPrintf("Unknown keyword '%s'\n", cmd);
                }
            } else {
                if (!strcmp(cmd, "begin")) {
                    char *s = Cmd_Argv(1);
                    if (!*s) {
                        Com_WPrintf("Expected menu name after '%s'\n", cmd);
                        break;
                    }
                    menu = UI_FindMenu(s);
                    if (menu) {
                        if (menu->free) {
                            menu->free(menu);
                        }
                        List_Remove(&menu->entry);
                    }
                    menu = UI_Mallocz(sizeof(*menu));
                    menu->name = UI_CopyString(s);
                    menu->push = Menu_Push;
                    menu->pop = Menu_Pop;
                    menu->free = Menu_Free;
                    menu->image = uis.backgroundHandle;
                    menu->color.u32 = uis.color.background.u32;
                    menu->transparent = uis.transparent;
                } else if (!strcmp(cmd, "include")) {
                    char *s = Cmd_Argv(1);
                    if (!*s) {
                        Com_WPrintf("Expected file name after '%s'\n", cmd);
                        break;
                    }
                    if (depth == 16) {
                        Com_WPrintf("Includes too deeply nested\n");
                    } else {
                        Parse_File(s, depth + 1);
                    }
                } else if (!strcmp(cmd, "color")) {
                    Parse_Color();
                } else if (!strcmp(cmd, "background")) {
                    char *s = Cmd_Argv(1);

                    if (SCR_ParseColor(s, &uis.color.background)) {
                        uis.backgroundHandle = 0;
                        uis.transparent = uis.color.background.u8[3] != 255;
                    } else {
                        uis.backgroundHandle = R_RegisterPic(s);
                        uis.transparent = R_GetPicSize(NULL, NULL, uis.backgroundHandle);
                    }
                } else if (!strcmp(cmd, "font")) {
                    uis.fontHandle = R_RegisterFont(Cmd_Argv(1));
                } else if (!strcmp(cmd, "cursor")) {
                    uis.cursorHandle = R_RegisterPic(Cmd_Argv(1));
                    R_GetPicSize(&uis.cursorWidth,
                                 &uis.cursorHeight, uis.cursorHandle);
                } else if (!strcmp(cmd, "weapon")) {
                    Cmd_ArgvBuffer(1, uis.weaponModel, sizeof(uis.weaponModel));
                } else {
                    Com_WPrintf("Unknown keyword '%s'\n", cmd);
                    break;
                }
            }
        }

        if (!p) {
            break;
        }

        data = p + 1;
    }

    FS_FreeFile(raw);

    if (menu) {
        Com_WPrintf("Menu entry without 'end' terminator\n");
        menu->free(menu);
    }

    return qtrue;
}
コード例 #13
0
ファイル: cl_input.c プロジェクト: Bad-ptr/q2pro
/*
=================
CL_SendBatchedCmd
=================
*/
static void CL_SendBatchedCmd( void ) {
    int i, j, seq, bits;
    int numCmds, numDups;
    int totalCmds, totalMsec;
    size_t cursize;
    usercmd_t *cmd, *oldcmd;
    client_history_t *history, *oldest;
    byte *patch;

    // see if we are ready to send this packet
    if( !ready_to_send() ) {
        return;
    }

    // archive this packet
    seq = cls.netchan->outgoing_sequence;
    history = &cl.history[seq & CMD_MASK];
    history->cmdNumber = cl.cmdNumber;
    history->sent = cls.realtime;    // for ping calculation
    history->rcvd = 0;

    cl.lastTransmitTime = cls.realtime;
    cl.lastTransmitCmdNumber = cl.cmdNumber;
    cl.lastTransmitCmdNumberReal = cl.cmdNumber;

    // begin a client move command
    patch = SZ_GetSpace( &msg_write, 1 );

    // let the server know what the last frame we
    // got was, so the next message can be delta compressed
    if( cl_nodelta->integer || !cl.frame.valid /*|| cls.demowaiting*/ ) {
        *patch = clc_move_nodelta; // no compression
    } else {
        *patch = clc_move_batched;
        MSG_WriteLong( cl.frame.number );
    }

    Cvar_ClampInteger( cl_packetdup, 0, MAX_PACKET_FRAMES - 1 );
    numDups = cl_packetdup->integer;

    *patch |= numDups << SVCMD_BITS;

    // send lightlevel
    MSG_WriteByte( cl.lightlevel );

    // send this and the previous cmds in the message, so
    // if the last packet was dropped, it can be recovered
    oldcmd = NULL;
    totalCmds = 0;
    totalMsec = 0;
    for( i = seq - numDups; i <= seq; i++ ) {
        oldest = &cl.history[( i - 1 ) & CMD_MASK];
        history = &cl.history[i & CMD_MASK];

        numCmds = history->cmdNumber - oldest->cmdNumber;
        if( numCmds >= MAX_PACKET_USERCMDS ) {
            Com_WPrintf( "%s: MAX_PACKET_USERCMDS exceeded\n", __func__ );
            SZ_Clear( &msg_write );
            break;
        }
        totalCmds += numCmds;
        MSG_WriteBits( numCmds, 5 );
        for( j = oldest->cmdNumber + 1; j <= history->cmdNumber; j++ ) {
            cmd = &cl.cmds[j & CMD_MASK];
            totalMsec += cmd->msec;
            bits = MSG_WriteDeltaUsercmd_Enhanced( oldcmd, cmd, cls.protocolVersion );
#ifdef _DEBUG
            if( cl_showpackets->integer == 3 ) {
                MSG_ShowDeltaUsercmdBits_Enhanced( bits );
            }
#endif
            oldcmd = cmd;
        }
    }

    P_FRAMES++;

    //
    // deliver the message
    //
    cursize = cls.netchan->Transmit( cls.netchan, msg_write.cursize, msg_write.data, 1 );
#ifdef _DEBUG
    if( cl_showpackets->integer == 1 ) {
        Com_Printf( "%"PRIz"(%i) ", cursize, totalCmds );
    } else if( cl_showpackets->integer == 2 ) {
        Com_Printf( "%"PRIz"(%i) ", cursize, totalMsec );
    } else if( cl_showpackets->integer == 3 ) {
        Com_Printf( " | " );
    }
#endif

    SZ_Clear( &msg_write );
}