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

📄 t_vari.c

📁 The source code of Doom legacy for windows
💻 C
字号:
// Emacs style mode select -*- C++ -*-//----------------------------------------------------------------------------//// $Id: t_vari.c,v 1.1 2000/11/02 17:57:28 stroggonmeth Exp $//// Copyright(C) 2000 Simon Howard//// 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.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//// $Log: t_vari.c,v $// Revision 1.1  2000/11/02 17:57:28  stroggonmeth// FraggleScript files...//////--------------------------------------------------------------------------//// Variables.//// Variable code: create new variables, look up variables, get value,// set value//// variables are stored inside the individual scripts, to allow for// 'local' and 'global' variables. This way, individual scripts cannot// access variables in other scripts. However, 'global' variables can// be made which can be accessed by all scripts. These are stored inside// a dedicated script_t which exists only to hold all of these global// variables.//// functions are also stored as variables, these are kept in the global// script so they can be accessed by all scripts. function variables// cannot be set or changed inside the scripts themselves.////---------------------------------------------------------------------------/* includes ************************/#include <stdio.h>#include <string.h>#include "z_zone.h"#include "t_script.h"#include "t_parse.h"#include "t_vari.h"#include "t_func.h"// the global script just holds all// the global variablesscript_t global_script;// the hub script holds all the variables// shared between levels in a hubscript_t hub_script;// initialise the global script: clear all the variablesvoid init_variables(){  int i;    global_script.parent = NULL;    // globalscript is the root script  hub_script.parent = &global_script; // hub_script is the next level down    for(i=0; i<VARIABLESLOTS; i++)    global_script.variables[i] = hub_script.variables[i] = NULL;    // any hardcoded global variables can be added here}void T_ClearHubScript(){  int i;  for(i=0; i<VARIABLESLOTS; i++)    {      while(hub_script.variables[i])	{	  svariable_t *next = hub_script.variables[i]->next;	  if(hub_script.variables[i]->type == svt_string)	    Z_Free(hub_script.variables[i]->value.s);	  Z_Free(hub_script.variables[i]);	  hub_script.variables[i] = next;	}    }}// find_variable checks through the current script, level script// and global script to try to find the variable of the name wantedsvariable_t *find_variable(char *name){  svariable_t *var;  script_t *current;    current = current_script;    while(current)    {      // check this script      if((var = variableforname(current, name)))	return var;      current = current->parent;    // try the parent of this one    }  return NULL;    // no variable}// create a new variable in a particular script.// returns a pointer to the new variable.svariable_t *new_variable(script_t *script, char *name, int vtype){  int n;  svariable_t *newvar;  int tagtype =    script==&global_script || script==&hub_script ? PU_STATIC : PU_LEVEL;    // find an empty slot first  newvar = Z_Malloc(sizeof(svariable_t), tagtype, 0);  newvar->name = (char*)Z_Strdup(name, tagtype, 0);  newvar->type = vtype;    if(vtype == svt_string)    {      // 256 bytes for string      newvar->value.s = Z_Malloc(256, tagtype, 0);      newvar->value.s[0] = 0;    }  else    newvar->value.i = 0;    // now hook it into the hashchain    n = variable_hash(name);  newvar->next = script->variables[n];  script->variables[n] = newvar;    return script->variables[n];}// search a particular script for a variable, which// is returned if it existssvariable_t *variableforname(script_t *script, char *name){  int n;  svariable_t *current;    n = variable_hash(name);    current = script->variables[n];    while(current)    {      if(!strcmp(name, current->name))        // found it?	return current;               current = current->next;        // check next in chain    }    return NULL;}        // free all the variables in a given scriptvoid clear_variables(script_t *script){  int i;  svariable_t *current, *next;    for(i=0; i<VARIABLESLOTS; i++)    {      current = script->variables[i];            // go thru this chain      while(current)	{	  // labels are added before variables, during	  // preprocessing, so will be at the end of the chain	  // we can be sure there are no more variables to free	  if(current->type == svt_label)	    break;	  	  next = current->next; // save for after freeing	  	  // if a string, free string data	  if(current->type == svt_string)	    Z_Free(current->value.s);	  	  current = next; // go to next in chain	}      // start of labels or NULL      script->variables[i] = current;    }}// returns an svalue_t holding the current// value of a particular variable.svalue_t getvariablevalue(svariable_t *v){  svalue_t returnvar;    if(!v) return nullvar;    if(v->type == svt_pString)    {      returnvar.type = svt_string;      returnvar.value.s = *v->value.pS;    }  else if(v->type == svt_pInt)    {      returnvar.type = svt_int;      returnvar.value.i = *v->value.pI;    }  else if(v->type == svt_pFixed)    {      returnvar.type = svt_fixed;      returnvar.value.f = *v->value.pFixed;    }  else if(v->type == svt_pMobj)    {      returnvar.type = svt_mobj;      returnvar.value.mobj = *v->value.pMobj;    }  else    {      returnvar.type = v->type;      // copy the value      returnvar.value.i = v->value.i;    }    return returnvar;}// set a variable to a value from an svalue_tvoid setvariablevalue(svariable_t *v, svalue_t newvalue){  if(killscript) return;  // protect the variables when killing script    if(!v) return;    if(v->type == svt_const)    {      // const adapts to the value it is set to      v->type = newvalue.type;      // alloc memory for string      if(v->type == svt_string)   // static incase a global_script var	v->value.s = Z_Malloc(256, PU_STATIC, 0);    }    if(v->type == svt_int)      v->value.i = intvalue(newvalue);  if(v->type == svt_string)    strcpy(v->value.s, stringvalue(newvalue));  if(v->type == svt_fixed)    v->value.fixed = fixedvalue(newvalue);  if(v->type == svt_mobj)      v->value.mobj = MobjForSvalue(newvalue);  if(v->type == svt_pInt)      *v->value.pI = intvalue(newvalue);  if(v->type == svt_pString)    {      // free old value      free(*v->value.pS);            // dup new string      *v->value.pS = strdup(stringvalue(newvalue));    }  if(v->type == svt_pFixed)    *v->value.pFixed = fixedvalue(newvalue);  if(v->type == svt_pMobj)      *v->value.pMobj = MobjForSvalue(newvalue);    if(v->type == svt_function)    script_error("attempt to set function to a value\n");}svariable_t *add_game_int(char *name, int *var){  svariable_t* newvar;  newvar = new_variable(&global_script, name, svt_pInt);  newvar->value.pI = var;  return newvar;}svariable_t *add_game_fixed(char *name, fixed_t *fixed){  svariable_t *newvar;  newvar = new_variable(&global_script, name, svt_pFixed);  newvar->value.pFixed = fixed;  return newvar;}svariable_t *add_game_string(char *name, char **var){  svariable_t* newvar;  newvar = new_variable(&global_script, name, svt_pString);  newvar->value.pS = var;  return newvar;}svariable_t *add_game_mobj(char *name, mobj_t **mo){  svariable_t* newvar;  newvar = new_variable(&global_script, name, svt_pMobj);  newvar->value.pMobj = mo;  return newvar;}/********************************                     FUNCTIONS ********************************/// functions are really just variables// of type svt_function. there are two// functions to control functions (heh)// new_function: just creates a new variable//      of type svt_function. give it the//      handler function to be called, and it//      will be stored as a pointer appropriately.// evaluate_function: once parse.c is pretty//      sure it has a function to run it calls//      this. evaluate_function makes sure that//      it is a function call first, then evaluates all//      the arguments given to the function.//      these are built into an argc/argv-style//      list. the function 'handler' is then called.// the basic handler functions are in func.cint t_argc;                     // number of argumentssvalue_t *t_argv;               // argumentssvalue_t t_return;              // returned valuesvalue_t evaluate_function(int start, int stop){  svariable_t *func = NULL;  int startpoint, endpoint;  // the arguments need to be built locally in case of  // function returns as function arguments eg  // print("here is a random number: ", rnd() );    int argc;  svalue_t argv[MAXARGS];  if(tokentype[start] != function || tokentype[stop] != operator     || tokens[stop][0] != ')' )    script_error("misplaced closing bracket\n");  // all the functions are stored in the global script  else if( !(func = variableforname(&global_script, tokens[start]))  )    script_error("no such function: '%s'\n",tokens[start]);  else if(func->type != svt_function)    script_error("'%s' not a function\n", tokens[start]);  if(killscript) return nullvar; // one of the above errors occurred  // build the argument list  // use a C command-line style system rather than  // a system using a fixed length list  argc = 0;  endpoint = start + 2;   // ignore the function name and first bracket    while(endpoint < stop)    {      startpoint = endpoint;      endpoint = find_operator(startpoint, stop-1, ",");            // check for -1: no more ','s       if(endpoint == -1)	{               // evaluate the last expression	  endpoint = stop;	}      if(endpoint-1 < startpoint)	break;            argv[argc] = evaluate_expression(startpoint, endpoint-1);      endpoint++;    // skip the ','      argc++;    }  // store the arguments in the global arglist  t_argc = argc;  t_argv = argv;  if(killscript) return nullvar;    // now run the function  func->value.handler();    // return the returned value  return t_return;}// structure dot (.) operator// there are not really any structs in FraggleScript, it's// just a different way of calling a function that looks// nicer. ie//      a.b()  = a.b   =  b(a)//      a.b(c) = b(a,c)// this function is just based on the one abovesvalue_t OPstructure(int start, int n, int stop){  svariable_t *func = NULL;    // the arguments need to be built locally in case of  // function returns as function arguments eg  // print("here is a random number: ", rnd() );    int argc;  svalue_t argv[MAXARGS];  // all the functions are stored in the global script  if( !(func = variableforname(&global_script, tokens[n+1]))  )    script_error("no such function: '%s'\n",tokens[n+1]);    else if(func->type != svt_function)    script_error("'%s' not a function\n", tokens[n+1]);  if(killscript) return nullvar; // one of the above errors occurred    // build the argument list  // add the left part as first arg  argv[0] = evaluate_expression(start, n-1);  argc = 1; // start on second argv  if(stop != n+1)         // can be a.b not a.b()    {      int startpoint, endpoint;      // ignore the function name and first bracket      endpoint = n + 3;            while(endpoint < stop)	{	  startpoint = endpoint;	  endpoint = find_operator(startpoint, stop-1, ",");	  	  // check for -1: no more ','s 	  if(endpoint == -1)	    {               // evaluate the last expression	      endpoint = stop;	    }	  if(endpoint-1 < startpoint)	    break;	  	  argv[argc] = evaluate_expression(startpoint, endpoint-1);	  endpoint++;    // skip the ','	  argc++;	}    }  // store the arguments in the global arglist  t_argc = argc;  t_argv = argv;    if(killscript) return nullvar;    // now run the function  func->value.handler();    // return the returned value  return t_return;}// create a new function. returns the function numbersvariable_t *new_function(char *name, void (*handler)() ){  svariable_t *newvar;  // create the new variable for the function  // add to the global script    newvar = new_variable(&global_script, name, svt_function);    // add neccesary info    newvar->value.handler = handler;  return newvar;}//---------------------------------------------------------------------------//// $Log: t_vari.c,v $// Revision 1.1  2000/11/02 17:57:28  stroggonmeth// FraggleScript files...//// Revision 1.1.1.1  2000/04/30 19:12:08  fraggle// initial import//////---------------------------------------------------------------------------

⌨️ 快捷键说明

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