📄 command.c
字号:
CONS_Printf("\2Commands\n"); for (cmd=com_commands ; cmd ; cmd=cmd->next) { CONS_Printf("%s ",cmd->name); i++; } // varibale CONS_Printf("\2\nVariable\n"); for (cvar=consvar_vars; cvar; cvar = cvar->next) { CONS_Printf("%s ",cvar->name); i++; } CONS_Printf("\2\nread console.txt for more or type help <command or variable>\n"); if( devparm ) CONS_Printf("\2Total : %d\n",i); }}static void COM_Toggle_f(void){ consvar_t *cvar; if(COM_Argc()!=2 && COM_Argc()!=3) { CONS_Printf("Toggle <cvar_name> [-1]\n" "Toggle the value of a cvar\n"); return; } cvar = CV_FindVar (COM_Argv(1)); if(!cvar) { CONS_Printf("%s is not a cvar\n",COM_Argv(1)); return; } // netcvar don't change imediately cvar->flags |= CV_SHOWMODIFONETIME; if( COM_Argc()==3 ) CV_AddValue(cvar,atol(COM_Argv(2))); else CV_AddValue(cvar,+1);}// =========================================================================// VARIABLE SIZE BUFFERS// =========================================================================#define VSBUFMINSIZE 256void VS_Alloc (vsbuf_t *buf, int initsize){ if (initsize < VSBUFMINSIZE) initsize = VSBUFMINSIZE; buf->data = Z_Malloc (initsize, PU_STATIC, NULL); buf->maxsize = initsize; buf->cursize = 0;}void VS_Free (vsbuf_t *buf){// Z_Free (buf->data); buf->cursize = 0;}void VS_Clear (vsbuf_t *buf){ buf->cursize = 0;}void *VS_GetSpace (vsbuf_t *buf, int length){ void *data; if (buf->cursize + length > buf->maxsize) { if (!buf->allowoverflow) I_Error ("overflow 111"); if (length > buf->maxsize) I_Error ("overflow l%i 112", length); buf->overflowed = true; CONS_Printf ("VS buffer overflow"); VS_Clear (buf); } data = buf->data + buf->cursize; buf->cursize += length; return data;}// Copy data at end of variable sized buffer//void VS_Write (vsbuf_t *buf, void *data, int length){ memcpy (VS_GetSpace(buf,length),data,length);}// Print text in variable size buffer, like VS_Write + trailing 0//void VS_Print (vsbuf_t *buf, char *data){ int len; len = strlen(data)+1; if (buf->data[buf->cursize-1]) memcpy ((byte *)VS_GetSpace(buf, len),data,len); // no trailing 0 else memcpy ((byte *)VS_GetSpace(buf, len-1)-1,data,len); // write over trailing 0}// =========================================================================//// CONSOLE VARIABLES//// console variables are a simple way of changing variables of the game// through the console or code, at run time.//// console vars acts like simplified commands, because a function can be// attached to them, and called whenever a console var is modified//// =========================================================================static char *cv_null_string = "";// Search if a variable has been registered// returns true if given variable has been registered//static consvar_t *CV_FindVar (char *name){ consvar_t *cvar; for (cvar=consvar_vars; cvar; cvar = cvar->next) if ( !strcmp(name,cvar->name) ) return cvar; return NULL;}// Build a unique Net Variable identifier number, that is used// in network packets instead of the fullname//unsigned short CV_ComputeNetid (char *s){ unsigned short ret; static int premiers[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53}; int i; ret=0; i=0; while(*s) { ret += (*s)*premiers[i]; s++; i = (i+1)%16; } return ret;}// Return the Net Variable, from it's identifier number//static consvar_t *CV_FindNetVar (unsigned short netid){ consvar_t *cvar; for (cvar=consvar_vars; cvar; cvar = cvar->next) if (cvar->netid==netid) return cvar; return NULL;}void Setvalue (consvar_t *var, char *valstr);// Register a variable, that can be used later at the console//void CV_RegisterVar (consvar_t *variable){ // first check to see if it has allready been defined if (CV_FindVar (variable->name)) { CONS_Printf ("Variable %s is already defined\n", variable->name); return; } // check for overlap with a command if (COM_Exists (variable->name)) { CONS_Printf ("%s is a command name\n", variable->name); return; } // check net variables if (variable->flags & CV_NETVAR) { variable->netid = CV_ComputeNetid (variable->name); if (CV_FindNetVar(variable->netid)) I_Error("Variable %s have same netid\n",variable->name); } // link the variable in if( !(variable->flags & CV_HIDEN) ) { variable->next = consvar_vars; consvar_vars = variable; } variable->string = NULL; // copy the value off, because future sets will Z_Free it //variable->string = Z_StrDup (variable->string);#ifdef PARANOIA if ((variable->flags & CV_NOINIT) && !(variable->flags & CV_CALL)) I_Error("variable %s have CV_NOINIT without CV_CALL\n"); if ((variable->flags & CV_CALL) && !variable->func) I_Error("variable %s have cv_call flags whitout func");#endif if (variable->flags & CV_NOINIT) variable->flags &=~CV_CALL; Setvalue(variable,variable->defaultvalue); if (variable->flags & CV_NOINIT) variable->flags |= CV_CALL; // the SetValue will set this bit variable->flags &= ~CV_MODIFIED;}// Returns the string value of a console var//static char *CV_StringValue (char *var_name){ consvar_t *var; var = CV_FindVar (var_name); if (!var) return cv_null_string; return var->string;}// Completes the name of a console var//char *CV_CompleteVar (char *partial, int skips){ consvar_t *cvar; int len; len = strlen(partial); if (!len) return NULL; // check functions for (cvar=consvar_vars ; cvar ; cvar=cvar->next) if (!strncmp (partial,cvar->name, len)) if (!skips--) return cvar->name; return NULL;}// set value to the variable, no check only for internal use//void Setvalue (consvar_t *var, char *valstr){ if(var->PossibleValue) { int v=atoi(valstr); if(!stricmp(var->PossibleValue[0].strvalue,"MIN")) { // bounded cvar int i; // search for maximum for(i=1;var->PossibleValue[i].strvalue!=NULL;i++) if(!stricmp(var->PossibleValue[i].strvalue,"MAX")) break;#ifdef PARANOIA if(var->PossibleValue[i].strvalue==NULL) I_Error("Bounded cvar \"%s\" without Maximum !",var->name);#endif if(v<var->PossibleValue[0].value) { v=var->PossibleValue[0].value; sprintf(valstr,"%d",v); } if(v>var->PossibleValue[i].value) { v=var->PossibleValue[i].value; sprintf(valstr,"%d",v); } } else { // waw spaghetti programming ! :) int i; // check first strings for(i=0;var->PossibleValue[i].strvalue!=NULL;i++) if(!stricmp(var->PossibleValue[i].strvalue,valstr)) goto found; if(!v) if(strcmp(valstr,"0")!=0) // !=0 if valstr!="0" goto error; // check int now for(i=0;var->PossibleValue[i].strvalue!=NULL;i++) if(v==var->PossibleValue[i].value) goto found;error: // not found CONS_Printf("\"%s\" is not a possible value for \"%s\"\n", valstr, var->name); if(var->defaultvalue==valstr) I_Error("Variable %s default value \"%s\" is not a possible value\n",var->name,var->defaultvalue); return;found: var->value =var->PossibleValue[i].value; var->string=var->PossibleValue[i].strvalue; goto finish; } } // free the old value string if(var->string) Z_Free (var->string); var->string = Z_StrDup (valstr); if (var->flags & CV_FLOAT) { double d; d = atof (var->string); var->value = d * FRACUNIT; } else var->value = atoi (var->string);finish: if( var->flags & CV_SHOWMODIFONETIME || var->flags & CV_SHOWMODIF) { CONS_Printf("%s set to %s\n",var->name,var->string); var->flags &= ~CV_SHOWMODIFONETIME; } DEBFILE(va("%s set to %s\n",var->name,var->string)); var->flags |= CV_MODIFIED; // raise 'on change' code if (var->flags & CV_CALL) var->func ();}//// Use XD_NETVAR argument :// 2 byte for variable identification// then the value of the variable followed with a 0 byte (like str)//void Got_NetVar(char **p,int playernum){ consvar_t *cvar; char *svalue; cvar = CV_FindNetVar (READUSHORT(*p)); svalue = *p; SKIPSTRING(*p); if(cvar==NULL) { CONS_Printf("\2Netvar not found\n"); return; } Setvalue(cvar,svalue);}// get implicit parameter save_pvoid CV_SaveNetVars( char **p ){ consvar_t *cvar; // we must send all cvar because on the other side maybe // it have a cvar modified and here not (same for true savegame) for (cvar=consvar_vars; cvar; cvar = cvar->next) if (cvar->flags & CV_NETVAR) { WRITESHORT(*p,cvar->netid); WRITESTRING(*p,cvar->string); }}// get implicit parameter save_pvoid CV_LoadNetVars( char **p ){ consvar_t *cvar; for (cvar=consvar_vars; cvar; cvar = cvar->next) if (cvar->flags & CV_NETVAR) Got_NetVar(p, 0);}// does as if "<varname> <value>" is entered at the console//void CV_Set (consvar_t *var, char *value){ //changed = strcmp(var->string, value);#ifdef PARANOIA if(!var) I_Error("CV_Set : no variable\n"); if(!var->string) I_Error("cv_Set : %s no string set ?!\n",var->name);#endif if (stricmp(var->string, value)==0) return; // no changes if (var->flags & CV_NETVAR) { // send the value of the variable char buf[128],*p; if (!server) { CONS_Printf("Only the server can change this variable\n"); return; } p=buf; WRITEUSHORT(p, var->netid); WRITESTRING(p, value); SendNetXCmd (XD_NETVAR, buf, p-buf); } else if ((var->flags & CV_NOTINNET) && netgame) { CONS_Printf("This Variable can't be changed while in netgame\n"); return; } else Setvalue(var,value);}// Expands value to string before calling CV_Set ()//void CV_SetValue (consvar_t *var, int value){ char val[32]; sprintf (val, "%d", value); CV_Set (var, val);}void CV_AddValue (consvar_t *var, int increment){ int newvalue=var->value+increment; if( var->PossibleValue ) {#define MIN 0 if( strcmp(var->PossibleValue[MIN].strvalue,"MIN")==0 ) { int max; // seach the next to last for(max=0;var->PossibleValue[max+1].strvalue!=NULL;max++) ; if( newvalue<var->PossibleValue[MIN].value ) newvalue+=var->PossibleValue[max].value-var->PossibleValue[MIN].value+1; // add the max+1 newvalue=var->PossibleValue[MIN].value + (newvalue-var->PossibleValue[MIN].value) % (var->PossibleValue[max].value - var->PossibleValue[MIN].value+1); CV_SetValue(var,newvalue); } else { int max,currentindice=-1,newindice; // this code do not support more than same value for differant PossibleValue for(max=0;var->PossibleValue[max].strvalue!=NULL;max++) if( var->PossibleValue[max].value==var->value ) currentindice=max; max--;#ifdef PARANOIA if( currentindice==-1 ) I_Error("CV_AddValue : current value %d not found in possible value\n",var->value);#endif newindice=(currentindice+increment+max+1) % (max+1); CV_Set(var,var->PossibleValue[newindice].strvalue); } } else CV_SetValue(var,newvalue);}// Allow display of variable content or change from the console//// Returns false if the passed command was not recognised as// console variable.//static boolean CV_Command (void){ consvar_t *v; // check variables v = CV_FindVar (COM_Argv(0)); if (!v) return false; // perform a variable print or set if (COM_Argc() == 1) { CONS_Printf ("\"%s\" is \"%s\" default is \"%s\"\n", v->name, v->string, v->defaultvalue); return true; } CV_Set (v, COM_Argv(1)); return true;}// Save console variables that have the CV_SAVE flag set//void CV_SaveVariables (FILE *f){ consvar_t *cvar; for (cvar = consvar_vars ; cvar ; cvar=cvar->next) if (cvar->flags & CV_SAVE) fprintf (f, "%s \"%s\"\n", cvar->name, cvar->string);}//============================================================================// SCRIPT PARSE//============================================================================// Parse a token out of a string, handles script files too// returns the data pointer after the tokenstatic char *COM_Parse (char *data){ int c; int len; len = 0; com_token[0] = 0; if (!data) return NULL;// skip whitespaceskipwhite: while ( (c = *data) <= ' ') { if (c == 0) return NULL; // end of file; data++; }// skip // comments if (c=='/' && data[1] == '/') { while (*data && *data != '\n') data++; goto skipwhite; }// handle quoted strings specially if (c == '\"') { data++; while (1) { c = *data++; if (c=='\"' || !c) { com_token[len] = 0; return data; } com_token[len] = c; len++; } }// parse single characters if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') { com_token[len] = c; len++; com_token[len] = 0; return data+1; }// parse a regular word do { com_token[len] = c; data++; len++; c = *data; if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') break; } while (c>32); com_token[len] = 0; return data;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -