/* * Operating System Command Line Interpreter */ #include #include // MR: added #ifndef _WIN32 #include #endif #include #include "media.h" #include "oscli.h" #include "console.h" #include "ithelib.h" #include "loadfile.h" #include "cookies.h" #include "core.hpp" #include "init.h" #include "tdgui.h" // Defines #define find(xxx) OSCLI_find(ArgC,ArgV,xxx) #define found(xxx) OSCLI_found(ArgC,ArgV,xxx) // Variables: These are all controlled by commandline switches // Mapfile, filename of the current map, begins with 0xff if not defined char projectname[]=COOKIE_MapName; // belated anti-Vietnam message VMINT default_mapnumber=0; // default map number char newbootlog[256]; char oldbootlog[256]; char loadingpic[256]; int logx=0,logy=0,loglen=60; // Graphical boot log, X,Y and length in lines int conx=0,cony=0,conlen=60,conwid=80; char probeInvalidObject=0; int VideoMode=-1; char debug_nosound=0; char no_panic=0; char devpaths=0; char ire_showfuncs=0; char ire_U6partymode=0; // Ultima5 or Ultima6 style of party management? char show_vrm_calls=0; int graflog=-1; // Graphical bootlog, true or false char quickstart=0; // Prevent logging to disk char mus_chan=16; // Music channels char sfx_chan=4; // Sound channels char use_light=1; // Use lighting by default char vis_blanking=1; // Use visibility blanking by default char fixwalls=1; // Correct visibility blanking by default char skip_unk=0; // Don't skip unknown keywords in the scriptfile int EggLockout=25; int EggDistance=11; VMINT map_W=512,map_H=512; // Map size int driftlevel=20; // Frequency change in Hz times -10 to +10 char reset_stats=0; char reset_funcs=0; char enable_censorware=0; int destroyhp=-100; // When this number is reached, object is obliterated char show_imap=0; // Show a map of the tracking engine int blankercol=-1; int imapx=384,imapy=240; int ig_min,ig_hour,ig_day,ig_month,ig_year,ig_dow; int turns_min=0,min_hour=60,hour_day=24,day_week=7,day_month=30,month_year=12; VMINT speechfont=0; char DebugVM=0; char in_editor; // Which program we are in (some modules are shared) char use_hw_video=0; static char gamespec=0; char allow_breakout=0; char debug_act=0; char SkipInit=0; char ShowRanges=0; char bookview[256]; char bookview2[256]; char editarea[256]; char projectdir[256]; unsigned char dlink_r=0,dlink_g=80,dlink_b=190; // Default link colour unsigned char dtext_r=255,dtext_g=255,dtext_b=255; // Default conv. colour int StartingTag=0; int vcpu_memory=0; unsigned int FRAMERATE=12; unsigned int MouseWait=60; char path_rar[1024]; // Limits for the script editor extern long spr_alloc; extern long seq_alloc; extern long vrm_alloc; extern long chr_alloc; extern long til_alloc; extern long wav_alloc; extern long mus_alloc; extern long pef_alloc; extern long tab_alloc; extern long tli_alloc; // Functions static short OSCLI_find(short ArgC,char **ArgV,char *param); static char OSCLI_found(short ArgC,char **ArgV,char *param); void OSCLI(int ArgC,char **ArgV); extern void AddScriptConstant(char *name, int value); // Code // OSCLI, process a list of switches void OSCLI(int ArgC,char **ArgV) { int cpt,rgb; char *pos; char *value; if(found("version") || found("v")) exit(1); if(found("?") || found("h") || found("help")) { printf("\n"); puts("-list [listfile] Execute a list of commands (like @ in doom)"); puts("-game [path] Path to look for a game project in"); puts("-window Run in a window rather than fullscreen"); puts("-mapfile [number] Load a different map number"); puts("-nopanic no fancy error messages"); puts("-debugVM Allow debugging keys in the PE Virtual Machine"); puts("-debugAct Debug activity system"); puts("-videomode Set number of bpp, or 0 to ask user (recommended)"); puts("-nolight Don't do any lighting (for slow systems)"); puts("-skipunknowns Ignore unknown keywords in the script, don't stop"); puts("-show_imap Display a map of the pathfinder engine"); puts("-showfuncs Write all script function names to IREFUNCS.TXT and stop"); if(in_editor) { puts("-reset_stats Reset all objects in the editor to their default statistics"); puts("-reset_funcs Reset all objects in the editor to their default functions"); puts("-area Calculate size or area of a large object"); } else { puts("-showranges Show mouse regions in red for mouse debugging"); puts("-book View a book or conversation (for book editing)"); puts("-noinit Skip 'initproc' (to bypass startup menu)"); } // puts("-L Display license"); puts("-? This screen"); puts("\nTo cause a stack trace on a Panic, set SUPERPANIC=1 in your environment space"); // puts("\nTo send ilog_quiet to the printer set LPTDEBUG=1 in your environment space"); exit(1); } if(found("L")) { puts("The IRE game engine and editor are supplied under the terms"); puts("of the BSD license, which means you can do pretty much what"); puts("you like with them. For full details, see the 'license.txt'"); puts("file which should have been included in the package."); puts("\n"); puts("The game data and artwork may have a different license."); exit(0); } cpt=find("map"); if(cpt>=0&&!default_mapnumber) if(ArgV[cpt+1]) default_mapnumber = atoi(ArgV[cpt+1]); cpt=find("edit"); if(cpt>=0) if(ArgV[cpt+1]) default_mapnumber = atoi(ArgV[cpt+1]); cpt=find("framerate"); if(cpt>=0) if(ArgV[cpt+1]) FRAMERATE = atoi(ArgV[cpt+1]); cpt=find("mousewait"); if(cpt>=0) if(ArgV[cpt+1]) MouseWait = atoi(ArgV[cpt+1]); if(found("nopanic")) no_panic = 1; if(found("skipunknowns")) skip_unk= 1; if(found("noinit")) SkipInit = 1; if(found("debugvrm") || found("debugvrms")) show_vrm_calls= 1; if(found("debugvm")) DebugVM= 1; if(found("debugact")) debug_act = 1; if(found("nolight")) use_light = 0; if(found("noblanking")) vis_blanking = 0; if(found("nofixwalls")) fixwalls = 0; if(found("nosound")) debug_nosound = 1; if(found("break")) allow_breakout = 1; if(found("reset_stats")) reset_stats = 1; if(found("reset_funcs")) reset_funcs = 1; if(found("censorware")) enable_censorware = 1; if(found("hardware_video")) use_hw_video = 1; if(found("showranges")) ShowRanges=1; // Get the project title cpt=find("project"); if(cpt>=0) if(ArgV[cpt+1]) { SAFE_STRCPY(projectname,ArgV[cpt+1]); } if(!gamespec) { cpt=find("game"); if(cpt>=0) if(ArgV[cpt+1]) { SAFE_STRCPY(projectdir,ArgV[cpt+1]); strslash(projectdir); // There must be a slash at the end if(projectdir[strlen(projectdir)-1] != '/') strcat(projectdir,"/"); gamespec=1; } } if(VideoMode==-1) { cpt=find("VideoMode"); if(cpt>=0) if(ArgV[cpt+1]) VideoMode=atoi(ArgV[cpt+1]); } // Shorthand for emergency start (handy for GDB under X11) if(found("v0")) VideoMode=0; // Shorthand for Windowed mode (X11 or GDI only at present) if(found("vx") || found("window") || found("windowed")) VideoMode=-2; cpt=find("console_x"); if(cpt>=0) { if(ArgV[cpt+1]) conx=atoi(ArgV[cpt+1]); } cpt=find("console_y"); if(cpt>=0) { if(ArgV[cpt+1]) cony=atoi(ArgV[cpt+1]); } cpt=find("console_w"); if(cpt>=0) { if(ArgV[cpt+1]) conwid=atoi(ArgV[cpt+1]); else conwid = 900; if(conwid > 80) ithe_panic("Usage: -console_w ","Width must be in characters, 2 to 80. It is NOT in pixels."); } cpt=find("console_h"); if(cpt>=0) { if(ArgV[cpt+1]) conlen=atoi(ArgV[cpt+1])-1; else conlen = 900; // Not valid, therefore print the message below. if(conlen > 60) ithe_panic("Usage: -console_h ","Height must be in lines, 2 to 60. It is NOT in pixels."); } cpt = find("speechfont"); if(cpt>=0) speechfont = atol(ArgV[cpt+1]); cpt=find("loadfont"); if(cpt>=0) if(ArgV[cpt+1]) irecon_registerfont(ArgV[cpt+2],atoi(ArgV[cpt+1])); cpt=find("driftlevel"); if(cpt>=0) { if(ArgV[cpt+1]) driftlevel=atoi(ArgV[cpt+1]); } cpt=find("map_width"); if(cpt>=0) { if(ArgV[cpt+1]) map_W=atoi(ArgV[cpt+1]); } cpt=find("map_height"); if(cpt>=0) { if(ArgV[cpt+1]) map_H=atoi(ArgV[cpt+1]); } cpt=find("view_w"); if(cpt>=0) { if(ArgV[cpt+1]) VSW=atoi(ArgV[cpt+1]); } cpt=find("view_h"); if(cpt>=0) { if(ArgV[cpt+1]) VSH=atoi(ArgV[cpt+1]); } cpt=find("loadingpic"); if(cpt>=0 && graflog ==-1) { if(ArgV[cpt+1]) { SAFE_STRCPY(loadingpic,ArgV[cpt+1]); } else ithe_safepanic("Usage: -loadingpic MYFILE.PCX","The picture can be PCX, or JPEG"); } cpt=find("loadingpic_console"); if(cpt>=0) { if(ArgV[cpt+1]) logx=atoi(ArgV[cpt+1]); if(ArgV[cpt+2]) logy=atoi(ArgV[cpt+2]); if(ArgV[cpt+3]) loglen=atoi(ArgV[cpt+3]); if(logx>128) logx=4; if(logy+(loglen*8)>480) logy=4; if(loglen>60) loglen=8; } // Book viewer utility (game program) cpt=find("book"); if(cpt>=0 && in_editor == 0) { if(ArgV[cpt+1]) { SAFE_STRCPY(bookview,ArgV[cpt+1]); } else ithe_safepanic("Usage: -book path/bookfile.txt",NULL); if(ArgV[cpt+2]) { SAFE_STRCPY(bookview2,ArgV[cpt+2]); } } // Area calculator utility (editor program) cpt=find("area"); if(cpt>=0 && in_editor == 1) { if(ArgV[cpt+1]) strcpy(editarea,ArgV[cpt+1]); else ithe_safepanic("Usage: -area object","The object must be an entry in Section: Characters"); } if(found("quickstart")) quickstart=1; if(found("u6party") || found("newparty") || found("u6partymode") || found("newpartymode")) ire_U6partymode=1; if(found("showfuncs")) ire_showfuncs=1; if(found("show_imap")) show_imap = 1; cpt=find("imapxy"); if(cpt>=0) { if(ArgV[cpt+1]) imapx=atol(ArgV[cpt+1]); if(ArgV[cpt+2]) imapy=atol(ArgV[cpt+2]); } if(found("probe_ivo")) probeInvalidObject= 1; cpt=find("destroy_hp"); if(cpt>=0) if(ArgV[cpt+1]) destroyhp = atoi(ArgV[cpt+1]); // Set VCPU memory size cpt = find("vcpu_memory"); if(cpt>=0) vcpu_memory = atoi(ArgV[cpt+1]); // Set limits for the script editor cpt = find("max_sprites"); if(cpt>=0) spr_alloc = atol(ArgV[cpt+1]); cpt = find("max_sequences"); if(cpt>=0) seq_alloc = atol(ArgV[cpt+1]); cpt = find("max_vrms"); if(cpt>=0) vrm_alloc = atol(ArgV[cpt+1]); cpt = find("max_characters"); if(cpt>=0) chr_alloc = atol(ArgV[cpt+1]); cpt = find("max_tiles"); if(cpt>=0) til_alloc = atol(ArgV[cpt+1]); cpt = find("max_wavs"); if(cpt>=0) wav_alloc = atol(ArgV[cpt+1]); cpt = find("max_music"); if(cpt<0) cpt = find("max_mods"); if(cpt>=0) mus_alloc = atol(ArgV[cpt+1]); cpt = find("max_pe_files"); if(cpt>=0) pef_alloc = atol(ArgV[cpt+1]); cpt = find("max_tables"); if(cpt>=0) tab_alloc = atol(ArgV[cpt+1]); cpt = find("max_tilelinks"); if(cpt>=0) tli_alloc = atol(ArgV[cpt+1]); // Starting date cpt = find("start_minute"); if(cpt>=0) ig_min = atol(ArgV[cpt+1]); cpt = find("start_hour"); if(cpt>=0) ig_hour = atol(ArgV[cpt+1]); cpt = find("start_day"); if(cpt>=0) ig_day = atol(ArgV[cpt+1]); cpt = find("start_month"); if(cpt>=0) ig_month = atol(ArgV[cpt+1]); cpt = find("start_year"); if(cpt>=0) ig_year = atol(ArgV[cpt+1]); cpt = find("start_day_of_month"); if(cpt>=0) ig_year = atol(ArgV[cpt+1]); // Calendar definitions cpt = find("turns_per_minute"); if(cpt>=0) turns_min = atol(ArgV[cpt+1]); cpt = find("minutes_per_hour"); if(cpt>=0) min_hour = atol(ArgV[cpt+1]); cpt = find("hours_per_day"); if(cpt>=0) hour_day = atol(ArgV[cpt+1]); cpt = find("days_per_week"); if(cpt>=0) day_week = atol(ArgV[cpt+1]); cpt = find("days_per_month"); if(cpt>=0) day_month = atol(ArgV[cpt+1]); cpt = find("months_per_year"); if(cpt>=0) month_year = atol(ArgV[cpt+1]); cpt=find("egglockout"); if(cpt>=0) { if(ArgV[cpt+1]) EggLockout=atoi(ArgV[cpt+1]); } cpt=find("eggdistance"); if(cpt>=0) { if(ArgV[cpt+1]) EggDistance=atoi(ArgV[cpt+1]); } // Set default link colour cpt = find("linkcol"); if(cpt>=0) { pos=strchr(ArgV[cpt+1],'#'); if(pos) { pos++; sscanf(pos,"%x",&rgb); // Got it in binary. dlink_r=(rgb>>16)&0xff; // get Red dlink_g=(rgb>>8)&0xff; // get green dlink_b=rgb&0xff; // get blue } } // Set default conversation text colour cpt = find("textcol"); if(cpt>=0) { pos=strchr(ArgV[cpt+1],'#'); if(pos) { pos++; sscanf(pos,"%x",&rgb); // Got it in binary. dtext_r=(rgb>>16)&0xff; // get Red dtext_g=(rgb>>8)&0xff; // get green dtext_b=rgb&0xff; // get blue } } // Set default blanker colour cpt = find("blankcol"); if(cpt>=0) { pos=strchr(ArgV[cpt+1],'#'); if(pos) { pos++; sscanf(pos,"%x",&blankercol); // Got it in binary. } } // Set a script constant cpt = find("set"); if(cpt>=0) { value=ArgV[cpt+2]; if(value) if(value[0] == '=') value=ArgV[cpt+3]; if(value && ArgV[cpt+1]) { rgb=atol(value); AddScriptConstant(ArgV[cpt+1],rgb); } } // Find a tag and start there (handy for development) cpt = find("startingtag"); if(cpt>=0) { if(ArgV[cpt+1]) StartingTag=atol(ArgV[cpt+1]); } // It is of vital importance that -include/list comes last, or the INI parser will // fall over, when the globals ArgV and ArgC are clobbered. cpt=find("include"); if(cpt>=0) if(ArgV[cpt+1]) { INI_file(ArgV[cpt+1]); return; } cpt=find("list"); if(cpt>=0) if(ArgV[cpt+1]) INI_file(ArgV[cpt+1]); return; } short OSCLI_find(short ArgC,char **ArgV,char *param) { short ctr; char tp[1024]; strcpy(tp,"-"); strcat(tp,param); //ilog_quiet("Look for %s\n",tp); for(ctr=0;ctr= 0) return 1; return 0; } // // Parse a .INI file // int INI_file(char *ini) { int words,len,ctr; char linebuf[1024]; char *word[64]; char *line; FILE *fp; fp=fopen(ini,"r"); if(!fp) return 0; do { line=fgets(linebuf,1023,fp); if(line) if(line[0]!='#'&&line[0]!=';'&&line[0]!='%') { words=0; word[words++]=&line[0]; len=strlen(line); for(ctr=0;ctr