⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 command.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
// Emacs style mode select   -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: command.c,v 1.11 2001/02/24 13:35:19 bpereira Exp $//// Copyright (C) 1998-2000 by DooM Legacy Team.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.////// $Log: command.c,v $// Revision 1.11  2001/02/24 13:35:19  bpereira// no message//// Revision 1.10  2001/01/25 22:15:41  bpereira// added heretic support//// Revision 1.9  2000/11/11 13:59:45  bpereira// no message//// Revision 1.8  2000/11/02 19:49:35  bpereira// no message//// Revision 1.7  2000/10/08 13:29:59  bpereira// no message//// Revision 1.6  2000/09/28 20:57:14  bpereira// no message//// Revision 1.5  2000/08/31 14:30:54  bpereira// no message//// Revision 1.4  2000/08/03 17:57:41  bpereira// no message//// Revision 1.3  2000/02/27 00:42:10  hurdler// fix CR+LF problem//// Revision 1.2  2000/02/26 00:28:42  hurdler// Mostly bug fix (see borislog.txt 23-2-2000, 24-2-2000)////// DESCRIPTION://      parse and execute commands from console input/scripts///      and remote server.////      handles console variables, which is a simplified version//      of commands, each consvar can have a function called when//      it is modified.. thus it acts nearly as commands.////      code shamelessly inspired by the QuakeC sources, thanks Id :)////-----------------------------------------------------------------------------#include "doomdef.h"#include "doomstat.h"#include "command.h"#include "console.h"#include "z_zone.h"#include "d_clisrv.h"#include "d_netcmd.h"#include "m_misc.h"#include "m_fixed.h"#include "byteptr.h"#include "p_saveg.h"//========// protos.//========static boolean COM_Exists (char *com_name);static void    COM_ExecuteString (char *text);static void    COM_Alias_f (void);static void    COM_Echo_f (void);static void    COM_Exec_f (void);static void    COM_Wait_f (void);static void    COM_Help_f (void);static void    COM_Toggle_f (void);static boolean    CV_Command (void);static consvar_t *CV_FindVar (char *name);static char      *CV_StringValue (char *var_name);static consvar_t  *consvar_vars;       // list of registered console variablesstatic char    com_token[1024];static char    *COM_Parse (char *data);CV_PossibleValue_t CV_OnOff[] =    {{0,"Off"}, {1,"On"},    {0,NULL}};CV_PossibleValue_t CV_YesNo[] =     {{0,"No"} , {1,"Yes"},   {0,NULL}};CV_PossibleValue_t CV_Unsigned[]=   {{0,"MIN"}, {999999999,"MAX"}, {0,NULL}};#define COM_BUF_SIZE    8192   // command buffer sizeint     com_wait;       // one command per frame (for cmd sequences)// command aliases//typedef struct cmdalias_s{    struct cmdalias_s   *next;    char    *name;    char    *value;     // the command string to replace the alias} cmdalias_t;cmdalias_t  *com_alias; // aliases list// =========================================================================//                            COMMAND BUFFER// =========================================================================vsbuf_t   com_text;     // variable sized buffer//  Add text in the command buffer (for later execution)//void COM_BufAddText (char *text){    int     l;    l = strlen (text);    if (com_text.cursize + l >= com_text.maxsize)    {        CONS_Printf ("Command buffer full!\n");        return;    }    VS_Write (&com_text, text, l);}// Adds command text immediately after the current command// Adds a \n to the text//void COM_BufInsertText (char *text){    char    *temp;    int     templen;    // copy off any commands still remaining in the exec buffer    templen = com_text.cursize;    if (templen)    {        temp = ZZ_Alloc (templen);        memcpy (temp, com_text.data, templen);        VS_Clear (&com_text);    }    else        temp = NULL;    // shut up compiler    // add the entire text of the file (or alias)    COM_BufAddText (text);    // add the copied off data    if (templen)    {        VS_Write (&com_text, temp, templen);        Z_Free (temp);    }}//  Flush (execute) console commands in buffer//   does only one if com_wait//void COM_BufExecute (void){    int     i;    char    *text;    char    line[1024];    int     quotes;    if (com_wait)    {        com_wait--;        return;    }    while (com_text.cursize)    {        // find a '\n' or ; line break        text = (char *)com_text.data;        quotes = 0;        for (i=0 ; i< com_text.cursize ; i++)        {            if (text[i] == '"')                quotes++;            if ( !(quotes&1) &&  text[i] == ';')                break;  // don't break if inside a quoted string            if (text[i] == '\n' || text[i] == '\r')                break;        }        memcpy (line, text, i);        line[i] = 0;        // flush the command text from the command buffer, _BEFORE_        // executing, to avoid that 'recursive' aliases overflow the        // command text buffer, in that case, new commands are inserted        // at the beginning, in place of the actual, so it doesn't        // overflow        if (i == com_text.cursize)            // the last command was just flushed            com_text.cursize = 0;        else        {            i++;            com_text.cursize -= i;            memcpy (text, text+i, com_text.cursize);        }        // execute the command line        COM_ExecuteString (line);        // delay following commands if a wait was encountered        if (com_wait)        {            com_wait--;            break;        }    }}// =========================================================================//                            COMMAND EXECUTION// =========================================================================typedef struct xcommand_s{    char               *name;    struct xcommand_s  *next;    com_func_t         function;} xcommand_t;static  xcommand_t  *com_commands = NULL;     // current commands#define MAX_ARGS        80static int         com_argc;static char        *com_argv[MAX_ARGS];static char        *com_null_string = "";static char        *com_args = NULL;          // current command args or NULLvoid Got_NetVar(char **p,int playernum);//  Initialise command buffer and add basic commands//void COM_Init (void){    // allocate command buffer    VS_Alloc (&com_text, COM_BUF_SIZE);    // add standard commands    COM_AddCommand ("alias",COM_Alias_f);    COM_AddCommand ("echo", COM_Echo_f);    COM_AddCommand ("exec", COM_Exec_f);    COM_AddCommand ("wait", COM_Wait_f);    COM_AddCommand ("help", COM_Help_f);    COM_AddCommand ("toggle", COM_Toggle_f);    RegisterNetXCmd(XD_NETVAR,Got_NetVar);}// Returns how many args for last command//int COM_Argc (void){    return com_argc;}// Returns string pointer for given argument number//char *COM_Argv (int arg){    if ( arg >= com_argc || arg < 0 )        return com_null_string;    return com_argv[arg];}// Returns string pointer of all command args//char *COM_Args (void){    return com_args;}int COM_CheckParm (char *check){    int         i;    for (i = 1;i<com_argc;i++)    {        if ( !strcasecmp(check, com_argv[i]) )            return i;    }    return 0;}// Parses the given string into command line tokens.//// Takes a null terminated string.  Does not need to be /n terminated.// breaks the string up into arg tokens.static void COM_TokenizeString (char *text){    int     i;// clear the args from the last string    for (i=0 ; i<com_argc ; i++)        Z_Free (com_argv[i]);    com_argc = 0;    com_args = NULL;    while (1)    {// skip whitespace up to a /n        while (*text && *text <= ' ' && *text != '\n')            text++;        if (*text == '\n')        {   // a newline means end of command in buffer,            // thus end of this command's args too            text++;            break;        }        if (!*text)            return;        if (com_argc == 1)            com_args = text;        text = COM_Parse (text);        if (!text)            return;        if (com_argc < MAX_ARGS)        {            com_argv[com_argc] = ZZ_Alloc (strlen(com_token)+1);            strcpy (com_argv[com_argc], com_token);            com_argc++;        }    }}// Add a command before existing ones.//void COM_AddCommand (char *name, com_func_t func){    xcommand_t  *cmd;    // fail if the command is a variable name    if (CV_StringValue(name)[0])    {        CONS_Printf ("%s is a variable name\n", name);        return;    }    // fail if the command already exists    for (cmd=com_commands ; cmd ; cmd=cmd->next)    {        if (!strcmp (name, cmd->name))        {            CONS_Printf ("Command %s already exists\n", name);            return;        }    }    cmd = ZZ_Alloc (sizeof(xcommand_t));    cmd->name = name;    cmd->function = func;    cmd->next = com_commands;    com_commands = cmd;}//  Returns true if a command by the name given exists//static boolean COM_Exists (char *com_name){    xcommand_t  *cmd;    for (cmd=com_commands ; cmd ; cmd=cmd->next)    {        if (!strcmp (com_name,cmd->name))            return true;    }    return false;}//  Command completion using TAB key like '4dos'//  Will skip 'skips' commands//char *COM_CompleteCommand (char *partial, int skips){    xcommand_t  *cmd;    int        len;    len = strlen(partial);    if (!len)        return NULL;// check functions    for (cmd=com_commands ; cmd ; cmd=cmd->next)        if (!strncmp (partial,cmd->name, len))            if (!skips--)                return cmd->name;    return NULL;}// Parses a single line of text into arguments and tries to execute it.// The text can come from the command buffer, a remote client, or stdin.//static void COM_ExecuteString (char *text){    xcommand_t  *cmd;    cmdalias_t *a;    COM_TokenizeString (text);// execute the command line    if (!COM_Argc())        return;     // no tokens// check functions    for (cmd=com_commands ; cmd ; cmd=cmd->next)    {        if (!strcmp (com_argv[0],cmd->name))        {            cmd->function ();            return;        }    }// check aliases    for (a=com_alias ; a ; a=a->next)    {        if (!strcmp (com_argv[0], a->name))        {            COM_BufInsertText (a->value);            return;        }    }// check cvars    if (!CV_Command ())        CONS_Printf ("Unknown command '%s'\n", COM_Argv(0));}// =========================================================================//                            SCRIPT COMMANDS// =========================================================================// alias command : a command name that replaces another command//static void COM_Alias_f (void){    cmdalias_t  *a;    char        cmd[1024];    int         i, c;    if (COM_Argc()<3)    {        CONS_Printf("alias <name> <command>\n");        return;    }    a = ZZ_Alloc (sizeof(cmdalias_t));    a->next = com_alias;    com_alias = a;    a->name = Z_StrDup (COM_Argv(1));// copy the rest of the command line    cmd[0] = 0;     // start out with a null string    c = COM_Argc();    for (i=2 ; i< c ; i++)    {        strcat (cmd, COM_Argv(i));        if (i != c)            strcat (cmd, " ");    }    strcat (cmd, "\n");    a->value = Z_StrDup (cmd);}// Echo a line of text to console//static void COM_Echo_f (void){    int     i;    for (i=1 ; i<COM_Argc() ; i++)        CONS_Printf ("%s ",COM_Argv(i));    CONS_Printf ("\n");}// Execute a script file//static void COM_Exec_f (void){    int     length;    byte*   buf=NULL;    if (COM_Argc () != 2)    {        CONS_Printf ("exec <filename> : run a script file\n");        return;    }// load file    length = FIL_ReadFile (COM_Argv(1), &buf);    //CONS_Printf ("debug file length : %d\n",length);    if (!buf)    {        CONS_Printf ("couldn't execute file %s\n",COM_Argv(1));        return;    }    CONS_Printf ("executing %s\n",COM_Argv(1));// insert text file into the command buffer    COM_BufInsertText (buf);// free buffer    Z_Free(buf);}// Delay execution of the rest of the commands to the next frame,// allows sequences of commands like "jump; fire; backward"//static void COM_Wait_f (void){    if (COM_Argc()>1)        com_wait = atoi(COM_Argv(1));    else        com_wait = 1;   // 1 frame}static void COM_Help_f (void){    xcommand_t  *cmd;    consvar_t  *cvar;    int i=0;    if(COM_Argc()>1)    {        cvar = CV_FindVar (COM_Argv(1));        if( cvar )        {            CONS_Printf("Variable %s:\n",cvar->name);            CONS_Printf("  flags :");            if( cvar->flags & CV_SAVE )                CONS_Printf("AUTOSAVE ");            if( cvar->flags & CV_FLOAT )                CONS_Printf("FLOAT ");            if( cvar->flags & CV_NETVAR )                CONS_Printf("NETVAR ");            if( cvar->flags & CV_CALL )                CONS_Printf("ACTION ");            CONS_Printf("\n");            if( cvar->PossibleValue )            {                if(stricmp(cvar->PossibleValue[0].strvalue,"MIN")==0)                {                    for(i=1;cvar->PossibleValue[i].strvalue!=NULL;i++)                        if(!stricmp(cvar->PossibleValue[i].strvalue,"MAX"))                            break;                    CONS_Printf("  range from %d to %d\n",cvar->PossibleValue[0].value,cvar->PossibleValue[i].value);                }                else                {                    CONS_Printf("  possible value :\n",cvar->name);                    while(cvar->PossibleValue[i].strvalue)                    {                        CONS_Printf("    %-2d : %s\n",cvar->PossibleValue[i].value,cvar->PossibleValue[i].strvalue);                        i++;                    }                }            }        }        else            CONS_Printf("No Help for this command/variable\n");    }    else    {        // commands

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -