X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_console.pas;h=9e6f4d5de4776bd505e2499b4a384cfff3a6862a;hb=ae58c60b09a12df74e69717546235c3e5bf3c992;hp=e0f401deeade15964e5c93c103ecebfa6065088c;hpb=98ad2c936a61bb810453f3552d7ed273eeaeaef3;p=d2df-sdl.git diff --git a/src/game/g_console.pas b/src/game/g_console.pas index e0f401d..9e6f4d5 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -19,7 +19,7 @@ unit g_console; interface uses - wadreader; // for SArray + utils; // for SSArray procedure g_Console_Init (); procedure g_Console_Update (); @@ -36,12 +36,15 @@ procedure conwriteln (const s: AnsiString; show: Boolean=false); procedure conwritefln (const s: AnsiString; args: array of const; show: Boolean=false); // <0: no arg; 0/1: true/false -function conGetBoolArg (p: SArray; idx: Integer): Integer; +function conGetBoolArg (p: SSArray; idx: Integer): Integer; procedure g_Console_Chat_Switch (team: Boolean=false); -procedure conRegVar (const conname: AnsiString; pvar: PBoolean; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false); overload; -procedure conRegVar (const conname: AnsiString; pvar: PSingle; amin, amax: Single; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false); overload; +procedure conRegVar (const conname: AnsiString; pvar: PBoolean; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; +procedure conRegVar (const conname: AnsiString; pvar: PSingle; amin, amax: Single; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; + +// poor man's floating literal parser; i'm sorry, but `StrToFloat()` sux cocks +function conParseFloat (var res: Single; const s: AnsiString): Boolean; var @@ -58,14 +61,14 @@ implementation uses g_textures, g_main, e_graphics, e_input, g_game, SysUtils, g_basic, g_options, Math, - g_menu, g_language, g_net, g_netmsg, e_log, conbuf, utils; + g_menu, g_language, g_net, g_netmsg, e_log, conbuf; type PCommand = ^TCommand; - TCmdProc = procedure (p: SArray); - TCmdProcEx = procedure (me: PCommand; p: SArray); + TCmdProc = procedure (p: SSArray); + TCmdProcEx = procedure (me: PCommand; p: SSArray); TCommand = record cmd: AnsiString; @@ -80,7 +83,7 @@ type TAlias = record name: AnsiString; - commands: SArray; + commands: SSArray; end; @@ -100,9 +103,9 @@ var Cons_Shown: Boolean; // Ðèñîâàòü ëè êîíñîëü? Line: AnsiString; CPos: Word; - //ConsoleHistory: SArray; - CommandHistory: SArray; - Whitelist: SArray; + //ConsoleHistory: SSArray; + CommandHistory: SSArray; + Whitelist: SSArray; commands: Array of TCommand = nil; Aliases: Array of TAlias = nil; CmdIndex: Word; @@ -113,9 +116,48 @@ var end; +// poor man's floating literal parser; i'm sorry, but `StrToFloat()` sux cocks +function conParseFloat (var res: Single; const s: AnsiString): Boolean; +var + pos: Integer = 1; + frac: Single = 1; + slen: Integer; +begin + result := false; + res := 0; + slen := Length(s); + while (slen > 0) and (s[slen] <= ' ') do Dec(slen); + while (pos <= slen) and (s[pos] <= ' ') do Inc(pos); + if (pos > slen) then exit; + if (slen-pos = 1) and (s[pos] = '.') then exit; // single dot + // integral part + while (pos <= slen) do + begin + if (s[pos] < '0') or (s[pos] > '9') then break; + res := res*10+Byte(s[pos])-48; + Inc(pos); + end; + if (pos <= slen) then + begin + // must be a dot + if (s[pos] <> '.') then exit; + Inc(pos); + while (pos <= slen) do + begin + if (s[pos] < '0') or (s[pos] > '9') then break; + frac := frac/10; + res += frac*(Byte(s[pos])-48); + Inc(pos); + end; + end; + if (pos <= slen) then exit; // oops + result := true; +end; + + // ////////////////////////////////////////////////////////////////////////// // // <0: no arg; 0/1: true/false; 666: toggle -function conGetBoolArg (p: SArray; idx: Integer): Integer; +function conGetBoolArg (p: SSArray; idx: Integer): Integer; begin if (idx < 0) or (idx > High(p)) then begin result := -1; exit; end; result := 0; @@ -126,7 +168,7 @@ begin end; -procedure boolVarHandler (me: PCommand; p: SArray); +procedure boolVarHandler (me: PCommand; p: SSArray); procedure binaryFlag (var flag: Boolean; msg: AnsiString); begin if (Length(p) > 2) then @@ -137,11 +179,12 @@ procedure boolVarHandler (me: PCommand; p: SArray); begin case conGetBoolArg(p, 1) of -1: begin end; - 0: if conIsCheatsEnabled then flag := false else begin conwriteln('not available'); exit; end; - 1: if conIsCheatsEnabled then flag := true else begin conwriteln('not available'); exit; end; - 666: if conIsCheatsEnabled then flag := not flag else begin conwriteln('not available'); exit; end; + 0: if not me.cheat or conIsCheatsEnabled then flag := false else begin conwriteln('not available'); exit; end; + 1: if not me.cheat or conIsCheatsEnabled then flag := true else begin conwriteln('not available'); exit; end; + 666: if not me.cheat or conIsCheatsEnabled then flag := not flag else begin conwriteln('not available'); exit; end; end; - if flag then conwritefln('%s: tan', [msg]) else conwritefln('%s: ona', [msg]); + if (Length(msg) = 0) then msg := p[0] else msg += ':'; + if flag then conwritefln('%s tan', [msg]) else conwritefln('%s ona', [msg]); end; end; begin @@ -149,7 +192,7 @@ begin end; -procedure conRegVar (const conname: AnsiString; pvar: PBoolean; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false); overload; +procedure conRegVar (const conname: AnsiString; pvar: PBoolean; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; var f: Integer; cp: PCommand; @@ -161,7 +204,7 @@ begin cp.proc := nil; cp.procEx := boolVarHandler; cp.help := ahelp; - cp.hidden := false; + cp.hidden := ahidden; cp.ptr := pvar; cp.msg := amsg; cp.cheat := acheat; @@ -177,44 +220,7 @@ type end; -procedure singleVarHandler (me: PCommand; p: SArray); - // poor man's floating literal parser; i'm sorry, but `StrToFloat()` sux cocks - function parseFloat (var res: Single; const s: AnsiString): Boolean; - var - pos: Integer = 1; - frac: Single = 1; - slen: Integer; - begin - result := false; - res := 0; - slen := Length(s); - while (slen > 0) and (s[slen] <= ' ') do Dec(slen); - while (pos <= slen) and (s[pos] <= ' ') do Inc(pos); - if (pos > slen) then exit; - if (slen-pos = 1) and (s[pos] = '.') then exit; // single dot - // integral part - while (pos <= slen) do - begin - if (s[pos] < '0') or (s[pos] > '9') then break; - res := res*10+Byte(s[pos])-48; - Inc(pos); - end; - if (pos <= slen) then - begin - // must be a dot - if (s[pos] <> '.') then exit; - Inc(pos); - while (pos <= slen) do - begin - if (s[pos] < '0') or (s[pos] > '9') then break; - frac := frac/10; - res += frac*(Byte(s[pos])-48); - Inc(pos); - end; - end; - if (pos <= slen) then exit; // oops - result := true; - end; +procedure singleVarHandler (me: PCommand; p: SSArray); var pv: PVarSingle; nv: Single; @@ -222,13 +228,13 @@ var begin if (Length(p) > 2) then begin - conwritefln('too many arguments to ''%s''', [p[0]]); + conwritefln('too many arguments to ''%s''', [me.cmd]); exit; end; pv := PVarSingle(me.ptr); if (Length(p) = 2) then begin - if not conIsCheatsEnabled then begin conwriteln('not available'); exit; end; + if me.cheat and (not conIsCheatsEnabled) then begin conwriteln('not available'); exit; end; if (CompareText(p[1], 'default') = 0) or (CompareText(p[1], 'def') = 0) or (CompareText(p[1], 'd') = 0) or (CompareText(p[1], 'off') = 0) or (CompareText(p[1], 'ona') = 0) then @@ -237,9 +243,9 @@ begin end else begin - if not parseFloat(nv, p[1]) then + if not conParseFloat(nv, p[1]) then begin - conwritefln('%s: ''%s'' doesn''t look like a floating number', [p[0], p[1]]); + conwritefln('%s: ''%s'' doesn''t look like a floating number', [me.cmd, p[1]]); exit; end; if (nv < pv.min) then nv := pv.min; @@ -248,12 +254,12 @@ begin end; end; msg := me.msg; - if (Length(msg) = 0) then msg := p[0] else msg += ':'; + if (Length(msg) = 0) then msg := me.cmd else msg += ':'; conwritefln('%s %s', [msg, pv.val^]); end; -procedure conRegVar (const conname: AnsiString; pvar: PSingle; amin, amax: Single; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false); overload; +procedure conRegVar (const conname: AnsiString; pvar: PSingle; amin, amax: Single; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; var f: Integer; cp: PCommand; @@ -271,7 +277,7 @@ begin cp.proc := nil; cp.procEx := singleVarHandler; cp.help := ahelp; - cp.hidden := false; + cp.hidden := ahidden; cp.ptr := pv; cp.msg := amsg; cp.cheat := acheat; @@ -294,7 +300,7 @@ begin end; end; -function ParseAlias(Str: AnsiString): SArray; +function ParseAlias(Str: AnsiString): SSArray; begin Result := nil; @@ -310,7 +316,7 @@ begin end; end; -procedure ConsoleCommands(p: SArray); +procedure ConsoleCommands(p: SSArray); var cmd, s: AnsiString; a, b: Integer; @@ -556,6 +562,15 @@ begin cp.cheat := acheat; end; + +procedure segfault (p: SSArray); +var + pp: PByte = nil; +begin + pp^ := 0; +end; + + procedure g_Console_Init(); var a: Integer; @@ -574,6 +589,8 @@ begin Time := 0; end; + AddCommand('segfault', segfault, 'make segfault'); + AddCommand('clear', ConsoleCommands, 'clear console'); AddCommand('clearhistory', ConsoleCommands); AddCommand('showhistory', ConsoleCommands); @@ -596,6 +613,7 @@ begin AddCommand('d_health', DebugCommands); AddCommand('d_player', DebugCommands); AddCommand('d_joy', DebugCommands); + AddCommand('d_mem', DebugCommands); AddCommand('p1_name', GameCVars); AddCommand('p2_name', GameCVars); @@ -937,16 +955,15 @@ begin g_Console_Add(''); for i := 0 to High(commands) do begin - if not commands[i].hidden then + // hidden commands are hidden when cheats aren't enabled + if commands[i].hidden and not conIsCheatsEnabled then continue; + if (Length(commands[i].help) > 0) then begin - if (Length(commands[i].help) > 0) then - begin - g_Console_Add(' '+commands[i].cmd+' -- '+commands[i].help); - end - else - begin - g_Console_Add(' '+commands[i].cmd); - end; + g_Console_Add(' '+commands[i].cmd+' -- '+commands[i].help); + end + else + begin + g_Console_Add(' '+commands[i].cmd); end; end; exit; @@ -960,7 +977,8 @@ begin ll := Copy(ll, 0, Length(ll)-1); for i := 0 to High(commands) do begin - if commands[i].hidden then continue; + // hidden commands are hidden when cheats aren't enabled + if commands[i].hidden and not conIsCheatsEnabled then continue; if (commands[i].cmd = ll) then begin if (Length(commands[i].help) > 0) then @@ -976,7 +994,8 @@ begin tused := 0; for i := 0 to High(commands) do begin - if commands[i].hidden then continue; + // hidden commands are hidden when cheats aren't enabled + if commands[i].hidden and not conIsCheatsEnabled then continue; cmd := commands[i].cmd; if (Length(cmd) >= Length(ll)) and (ll = Copy(cmd, 0, Length(ll))) then begin @@ -1149,7 +1168,7 @@ begin end; end; -function ParseString(Str: AnsiString): SArray; +function ParseString(Str: AnsiString): SSArray; begin Result := nil; @@ -1300,7 +1319,7 @@ end; function g_Console_CommandBlacklisted(C: AnsiString): Boolean; var - Arr: SArray; + Arr: SSArray; i: Integer; begin Result := True; @@ -1321,7 +1340,7 @@ end; procedure g_Console_Process(L: AnsiString; quiet: Boolean = False); var - Arr: SArray; + Arr: SSArray; i: Integer; begin Arr := nil; @@ -1377,4 +1396,5 @@ begin g_Console_Add(Format(_lc[I_CONSOLE_UNKNOWN], [Arr[0]])); end; + end.