hedgewars/ArgParsers.inc
changeset 9289 6bc1df062f04
parent 9261 6e4feb4191a0
parent 9287 bb9ad6a5f625
child 9291 15f7bb217b66
equal deleted inserted replaced
9261:6e4feb4191a0 9289:6bc1df062f04
     1 (*
       
     2  * Hedgewars, a free turn based strategy game
       
     3  * Copyright (c) 2004-2013 Andrey Korotaev <unC0Rr@gmail.com>
       
     4  *
       
     5  * This program is free software; you can redistribute it and/or modify
       
     6  * it under the terms of the GNU General Public License as published by
       
     7  * the Free Software Foundation; version 2 of the License
       
     8  *
       
     9  * This program is distributed in the hope that it will be useful,
       
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12  * GNU General Public License for more details.
       
    13  *
       
    14  * You should have received a copy of the GNU General Public License
       
    15  * along with this program; if not, write to the Free Software
       
    16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
       
    17  *)
       
    18 
       
    19 procedure GciEasterEgg;
       
    20 begin
       
    21     WriteLn(stdout, '                                                                ');
       
    22     WriteLn(stdout, '      /\\\\\\\\\\\\        /\\\\\\\\\  /\\\\\\\\\\\             ');
       
    23     WriteLn(stdout, '     /\\\//////////      /\\\////////  \/////\\\///             ');
       
    24     WriteLn(stdout, '     /\\\               /\\\/               \/\\\               ');
       
    25     WriteLn(stdout, '     \/\\\    /\\\\\\\  /\\\                 \/\\\              ');
       
    26     WriteLn(stdout, '      \/\\\   \/////\\\ \/\\\                 \/\\\             ');
       
    27     WriteLn(stdout, '       \/\\\       \/\\\ \//\\\                \/\\\            ');
       
    28     WriteLn(stdout, '        \/\\\       \/\\\  \///\\\              \/\\\           ');
       
    29     WriteLn(stdout, '         \/\\\\\\\\\\\\\/     \////\\\\\\\\\  /\\\\\\\\\\\      ');
       
    30     WriteLn(stdout, '          \/////////////          \/////////  \///////////      ');
       
    31     WriteLn(stdout, '                                                                ');
       
    32     WriteLn(stdout, ' Command Line Parser Implementation by a Google Code-In Student ');
       
    33     WriteLn(stdout, '             ASCII Art easter egg idea by @sheepluva            ');
       
    34     WriteLn(stdout, '                                                                ');
       
    35 end;
       
    36 
       
    37 procedure DisplayUsage;
       
    38 begin
       
    39     WriteLn(stdout, 'Usage: hwengine <path to replay file> [options]');
       
    40     WriteLn(stdout, '');
       
    41     WriteLn(stdout, 'where [options] can be any of the following:');
       
    42     WriteLn(stdout, ' --prefix [path to folder]');
       
    43     WriteLn(stdout, ' --user-prefix [path to folder]');
       
    44     WriteLn(stdout, ' --locale [name of language file]');
       
    45     WriteLn(stdout, ' --nick [string]');
       
    46     WriteLn(stdout, ' --fullscreen-width [fullscreen width in pixels]');
       
    47     WriteLn(stdout, ' --fullscreen-height [fullscreen height in pixels]');
       
    48     WriteLn(stdout, ' --width [window width in pixels]');
       
    49     WriteLn(stdout, ' --height [window height in pixels]');
       
    50     WriteLn(stdout, ' --volume [sound level]');
       
    51     WriteLn(stdout, ' --frame-interval [milliseconds]');
       
    52     Writeln(stdout, ' --stereo [value]');
       
    53     WriteLn(stdout, ' --raw-quality [flags]');
       
    54     WriteLn(stdout, ' --low-quality');
       
    55     WriteLn(stdout, ' --nomusic');
       
    56     WriteLn(stdout, ' --nosound');
       
    57     WriteLn(stdout, ' --fullscreen');
       
    58     WriteLn(stdout, ' --showfps');
       
    59     WriteLn(stdout, ' --altdmg');
       
    60     WriteLn(stdout, ' --no-teamtag');
       
    61     WriteLn(stdout, ' --no-hogtag');
       
    62     WriteLn(stdout, ' --no-healthtag');
       
    63     WriteLn(stdout, ' --translucent-tags');
       
    64     WriteLn(stdout, ' --stats-only');
       
    65     WriteLn(stdout, ' --help');
       
    66     WriteLn(stdout, '');
       
    67     WriteLn(stdout, 'For more detailed help and examples go to:');
       
    68     WriteLn(stdout, 'http://code.google.com/p/hedgewars/wiki/CommandLineOptions');
       
    69     GameType:= gmtSyntax;
       
    70 end;
       
    71 
       
    72 procedure setDepth(var paramIndex: LongInt);
       
    73 begin
       
    74     WriteLn(stdout, 'WARNING: --depth is a deprecated command, which could be removed in a future version!');
       
    75     WriteLn(stdout, '         This option no longer does anything, please consider removing it');
       
    76     WriteLn(stdout, '');
       
    77    inc(ParamIndex);
       
    78 end;
       
    79 
       
    80 procedure statsOnlyGame;
       
    81 begin
       
    82     cOnlyStats:= true;
       
    83     cReducedQuality:= $FFFFFFFF xor rqLowRes;
       
    84     SetSound(false);
       
    85     SetMusic(false);
       
    86     SetVolume(0);
       
    87 end;
       
    88 
       
    89 procedure setIpcPort(port: LongInt; var wrongParameter:Boolean);
       
    90 begin
       
    91     if isInternal then
       
    92         ipcPort := port
       
    93     else
       
    94         begin
       
    95         WriteLn(stderr, 'ERROR: use of --port is not allowed');
       
    96         wrongParameter := true;
       
    97         end
       
    98 end;
       
    99 
       
   100 function parseNick(nick: String): String;
       
   101 begin
       
   102     if isInternal then
       
   103         parseNick:= DecodeBase64(nick)
       
   104     else
       
   105         parseNick:= nick;
       
   106 end;
       
   107 
       
   108 procedure setStereoMode(tmp: LongInt);
       
   109 begin
       
   110     GrayScale:= false;
       
   111 {$IFDEF USE_S3D_RENDERING}
       
   112     if (tmp > 6) and (tmp < 13) then
       
   113         begin
       
   114         // set the gray anaglyph rendering
       
   115         GrayScale:= true;
       
   116         cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)))
       
   117         end
       
   118     else if tmp <= 6 then
       
   119         // set the fullcolor anaglyph
       
   120         cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp)))
       
   121     else
       
   122         // any other mode
       
   123         cStereoMode:= TStereoMode(max(0, min(ord(high(TStereoMode)), tmp-6)));
       
   124 {$ELSE}
       
   125     tmp:= tmp;
       
   126     cStereoMode:= smNone;
       
   127 {$ENDIF}
       
   128 end;
       
   129 
       
   130 procedure startVideoRecording(var paramIndex: LongInt);
       
   131 begin
       
   132     // Silence the hint that appears when USE_VIDEO_RECORDING is not defined
       
   133     paramIndex:= paramIndex;
       
   134 {$IFDEF USE_VIDEO_RECORDING}
       
   135     GameType:= gmtRecord;
       
   136     inc(paramIndex);
       
   137     cVideoFramerateNum:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
       
   138     cVideoFramerateDen:= StrToInt(ParamStr(paramIndex)); inc(paramIndex);
       
   139     RecPrefix:= ParamStr(paramIndex);                    inc(paramIndex);
       
   140     cAVFormat:= ParamStr(paramIndex);                    inc(paramIndex);
       
   141     cVideoCodec:= ParamStr(paramIndex);                  inc(paramIndex);
       
   142     cVideoQuality:= StrToInt(ParamStr(paramIndex));      inc(paramIndex);
       
   143     cAudioCodec:= ParamStr(paramIndex);                  inc(paramIndex);
       
   144 {$ENDIF}
       
   145 end;
       
   146 
       
   147 function getLongIntParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): LongInt;
       
   148 var tmpInt, c: LongInt;
       
   149 begin
       
   150     inc(paramIndex);
       
   151     val(str, tmpInt, c);
       
   152     wrongParameter:= c <> 0;
       
   153     if wrongParameter then
       
   154         WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a number, you passed "'+str+'"');
       
   155     getLongIntParameter:= tmpInt;
       
   156 end;
       
   157 
       
   158 function getStringParameter(str:String; var paramIndex:LongInt; var wrongParameter:Boolean): String;
       
   159 begin
       
   160     inc(paramIndex);
       
   161     wrongParameter:= (str='') or (Copy(str,1,2) = '--');
       
   162     if wrongParameter then
       
   163          WriteLn(stderr, 'ERROR: '+ParamStr(paramIndex-1)+' expects a string, you passed "'+str+'"');
       
   164     getStringParameter:= str;
       
   165 end;
       
   166 
       
   167 
       
   168 procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt); Forward;
       
   169 
       
   170 function parseParameter(cmd:String; arg:String; var paramIndex:LongInt): Boolean;
       
   171 const videoArray: Array [1..5] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth');
       
   172       audioArray: Array [1..3] of String = ('--volume','--nomusic','--nosound');
       
   173       otherArray: Array [1..3] of String = ('--locale','--fullscreen','--showfps');
       
   174       mediaArray: Array [1..10] of String = ('--fullscreen-width', '--fullscreen-height', '--width', '--height', '--depth', '--volume','--nomusic','--nosound','--locale','--fullscreen');
       
   175       allArray: Array [1..18] of String = ('--fullscreen-width','--fullscreen-height', '--width', '--height', '--depth','--volume','--nomusic','--nosound','--locale','--fullscreen','--showfps','--altdmg','--frame-interval','--low-quality','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
       
   176       reallyAll: array[0..34] of shortstring = (
       
   177                 '--prefix', '--user-prefix', '--locale', '--fullscreen-width', '--fullscreen-height', '--width',
       
   178                 '--height', '--frame-interval', '--volume','--nomusic', '--nosound',
       
   179                 '--fullscreen', '--showfps', '--altdmg', '--low-quality', '--raw-quality', '--stereo', '--nick',
       
   180   {deprecated}  '--depth', '--set-video', '--set-audio', '--set-other', '--set-multimedia', '--set-everything',
       
   181   {internal}    '--internal', '--port', '--recorder', '--landpreview',
       
   182   {misc}        '--stats-only', '--gci', '--help','--no-teamtag','--no-hogtag','--no-healthtag','--translucent-tags');
       
   183 var cmdIndex: byte;
       
   184 begin
       
   185     parseParameter:= false;
       
   186     cmdIndex:= 0;
       
   187 
       
   188     //NOTE: Any update to the list of parameters must be reflected in the case statement below, the reallyAll array above,
       
   189     //      the the DisplayUsage() procedure, the HWForm::getDemoArguments() function, and the online wiki
       
   190 
       
   191     while (cmdIndex <= High(reallyAll)) and (cmd <> reallyAll[cmdIndex]) do inc(cmdIndex);
       
   192     case cmdIndex of
       
   193         {--prefix}               0 : PathPrefix        := getStringParameter (arg, paramIndex, parseParameter);
       
   194         {--user-prefix}          1 : UserPathPrefix    := getStringParameter (arg, paramIndex, parseParameter);
       
   195         {--locale}               2 : cLocaleFName      := getStringParameter (arg, paramIndex, parseParameter);
       
   196         {--fullscreen-width}     3 : cFullscreenWidth  := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenWidth);
       
   197         {--fullscreen-height}    4 : cFullscreenHeight := max(getLongIntParameter(arg, paramIndex, parseParameter), cMinScreenHeight);
       
   198         {--width}                5 : cWindowedWidth    := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenWidth);
       
   199         {--height}               6 : cWindowedHeight   := max(2 * (getLongIntParameter(arg, paramIndex, parseParameter) div 2), cMinScreenHeight);
       
   200         {--frame-interval}       7 : cTimerInterval    := getLongIntParameter(arg, paramIndex, parseParameter);
       
   201         {--volume}               8 : SetVolume          ( max(getLongIntParameter(arg, paramIndex, parseParameter), 0) );
       
   202         {--nomusic}              9 : SetMusic           ( false );
       
   203         {--nosound}             10 : SetSound           ( false );
       
   204         {--fullscreen}          11 : cFullScreen       := true;
       
   205         {--showfps}             12 : cShowFPS          := true;
       
   206         {--altdmg}              13 : cAltDamage        := true;
       
   207         {--low-quality}         14 : cReducedQuality   := $FFFFFFFF xor rqLowRes;
       
   208         {--raw-quality}         15 : cReducedQuality   := getLongIntParameter(arg, paramIndex, parseParameter);
       
   209         {--stereo}              16 : setStereoMode      ( getLongIntParameter(arg, paramIndex, parseParameter) );
       
   210         {--nick}                17 : UserNick          := parseNick( getStringParameter(arg, paramIndex, parseParameter) );
       
   211         {deprecated options}
       
   212         {--depth}               18 : setDepth(paramIndex);
       
   213         {--set-video}           19 : parseClassicParameter(videoArray,5,paramIndex);
       
   214         {--set-audio}           20 : parseClassicParameter(audioArray,3,paramIndex);
       
   215         {--set-other}           21 : parseClassicParameter(otherArray,3,paramIndex);
       
   216         {--set-multimedia}      22 : parseClassicParameter(mediaArray,10,paramIndex);
       
   217         {--set-everything}      23 : parseClassicParameter(allArray,14,paramIndex);
       
   218         {"internal" options}
       
   219         {--internal}            24 : {$IFDEF HWLIBRARY}isInternal:= true{$ENDIF};
       
   220         {--port}                25 : setIpcPort( getLongIntParameter(arg, paramIndex, parseParameter), parseParameter );
       
   221         {--recorder}            26 : startVideoRecording(paramIndex);
       
   222         {--landpreview}         27 : GameType := gmtLandPreview;
       
   223         {anything else}
       
   224         {--stats-only}          28 : statsOnlyGame();
       
   225         {--gci}                 29 : GciEasterEgg();
       
   226         {--help}                30 : DisplayUsage();
       
   227         {--no-teamtag}          31 : cTagsMask := cTagsMask and not htTeamName;
       
   228         {--no-hogtag}           32 : cTagsMask := cTagsMask and not htName;
       
   229         {--no-healthtag}        33 : cTagsMask := cTagsMask and not htHealth;
       
   230         {--translucent-tags}    34 : cTagsMask := cTagsMask or htTransparent 
       
   231     else
       
   232         begin
       
   233         //Asusme the first "non parameter" is the replay file, anything else is invalid
       
   234         if (recordFileName = '') and (Copy(cmd,1,2) <> '--') then
       
   235             recordFileName := cmd
       
   236         else
       
   237             begin
       
   238             WriteLn(stderr, '"'+cmd+'" is not a valid option');
       
   239             parseParameter:= true;
       
   240             end;
       
   241         end;
       
   242     end;
       
   243 end;
       
   244 
       
   245 procedure parseClassicParameter(cmdArray: Array of String; size:LongInt; var paramIndex:LongInt);
       
   246 var index, tmpInt: LongInt;
       
   247     isBool, isValid: Boolean;
       
   248     cmd, arg, newSyntax: String;
       
   249 begin
       
   250     WriteLn(stdout, 'WARNING: you are using a deprecated command, which could be removed in a future version!');
       
   251     WriteLn(stdout, '         Consider updating to the latest syntax, which is much more flexible!');
       
   252     WriteLn(stdout, '         Run `hwegine --help` to learn it!');
       
   253     WriteLn(stdout, '');
       
   254 
       
   255     index:= 0;
       
   256     tmpInt:= 1;
       
   257     while (index < size) do
       
   258         begin
       
   259         newSyntax:= '';
       
   260         inc(paramIndex);
       
   261         cmd:= cmdArray[index];
       
   262         arg:= ParamStr(paramIndex);
       
   263         isValid:= (cmd<>'--depth');
       
   264 
       
   265         // check if the parameter is a boolean one
       
   266         isBool:= (cmd = '--nomusic') or (cmd = '--nosound') or (cmd = '--fullscreen') or (cmd = '--showfps') or (cmd = '--altdmg') or (cmd = '--no-teamtag') or (cmd = '--no-hogtag') or (cmd = '--no-healthtag') or (cmd = '--translucent-tags');
       
   267         if isBool and (arg='0') then
       
   268             isValid:= false;
       
   269         if (cmd='--nomusic') or (cmd='--nosound') then
       
   270             isValid:= not isValid;
       
   271 
       
   272         if isValid then
       
   273             begin
       
   274             parseParameter(cmd, arg, tmpInt);
       
   275             newSyntax := newSyntax + cmd + ' ';
       
   276             if not isBool then
       
   277                 newSyntax := newSyntax + arg + ' ';
       
   278             end;
       
   279         inc(index);
       
   280         end;
       
   281 
       
   282     WriteLn(stdout, 'Attempted to automatically convert to the new syntax:');
       
   283     WriteLn(stdout, newSyntax);
       
   284     WriteLn(stdout, '');
       
   285 end;
       
   286 
       
   287 procedure parseCommandLine{$IFDEF HWLIBRARY}(argc: LongInt; argv: PPChar){$ENDIF};
       
   288 var paramIndex: LongInt;
       
   289     paramTotal: LongInt;
       
   290     index, nextIndex: LongInt;
       
   291     wrongParameter: boolean;
       
   292 //var tmpInt: LongInt;
       
   293 begin
       
   294     paramIndex:= {$IFDEF HWLIBRARY}0{$ELSE}1{$ENDIF};
       
   295     paramTotal:= {$IFDEF HWLIBRARY}argc-1{$ELSE}ParamCount{$ENDIF}; //-1 because pascal enumeration is inclusive
       
   296     (*
       
   297     WriteLn(stdout, 'total parameters: ' + inttostr(paramTotal));
       
   298     tmpInt:= 0;
       
   299     while (tmpInt <= paramTotal) do
       
   300         begin
       
   301         WriteLn(stdout, inttostr(tmpInt) + ': ' + {$IFDEF HWLIBRARY}argv[tmpInt]{$ELSE}paramCount(tmpInt){$ENDIF});
       
   302         inc(tmpInt);
       
   303         end;
       
   304     *)
       
   305     wrongParameter:= false;
       
   306     while (paramIndex <= paramTotal) do
       
   307         begin
       
   308         // avoid going past the number of paramTotal (esp. w/ library)
       
   309         index:= paramIndex;
       
   310         if index = paramTotal then nextIndex:= index
       
   311         else nextIndex:= index+1;
       
   312         {$IFDEF HWLIBRARY}
       
   313         wrongParameter:= parseParameter( argv[index], argv[nextIndex], paramIndex);
       
   314         {$ELSE}
       
   315         wrongParameter:= parseParameter( ParamStr(index), ParamStr(nextIndex), paramIndex);
       
   316         {$ENDIF}
       
   317         inc(paramIndex);
       
   318         end;
       
   319     if wrongParameter = true then
       
   320         GameType:= gmtSyntax;
       
   321 end;
       
   322 
       
   323 {$IFNDEF HWLIBRARY}
       
   324 procedure GetParams;
       
   325 begin
       
   326     isInternal:= (ParamStr(1) = '--internal');
       
   327 
       
   328     UserPathPrefix := '.';
       
   329     PathPrefix     := cDefaultPathPrefix;
       
   330     recordFileName := '';
       
   331     parseCommandLine();
       
   332 
       
   333     if (isInternal) and (ParamCount<=1) then
       
   334         begin
       
   335         WriteLn(stderr, '--internal should not be manually used');
       
   336         GameType := gmtSyntax;
       
   337         end;
       
   338 
       
   339     if (not isInternal) and (recordFileName = '') then
       
   340         begin
       
   341         WriteLn(stderr, 'You must specify a replay file');
       
   342         GameType := gmtSyntax;
       
   343         end
       
   344     else if (recordFileName <> '') then
       
   345         WriteLn(stdout, 'Attempting to play demo file "' + recordFilename + '"');
       
   346 
       
   347     if (GameType = gmtSyntax) then
       
   348         WriteLn(stderr, 'Please use --help to see possible arguments and their usage');
       
   349 
       
   350     (*
       
   351     WriteLn(stdout,'PathPrefix:     ' + PathPrefix);
       
   352     WriteLn(stdout,'UserPathPrefix: ' + UserPathPrefix);
       
   353     *)
       
   354 end;
       
   355 {$ENDIF}
       
   356