X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=blobdiff_plain;f=src%2Fgame%2Fg_console.pas;h=edf484f1dd8177dc59170710d0c48c6f4efeffb7;hp=9e6f4d5de4776bd505e2499b4a384cfff3a6862a;hb=bccf523c0320f1f8f33edb72caec0a67cfa2e422;hpb=cd1ca85acc0740e0f307782e2af54e5ba0a59507 diff --git a/src/game/g_console.pas b/src/game/g_console.pas index 9e6f4d5..edf484f 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -1,4 +1,4 @@ -(* Copyright (C) DooM 2D:Forever Developers +(* Copyright (C) Doom 2D: Forever Developers * * 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 @@ -21,27 +21,52 @@ interface uses utils; // for SSArray -procedure g_Console_Init (); -procedure g_Console_Update (); -procedure g_Console_Draw (); -procedure g_Console_Switch (); + const + ACTION_JUMP = 0; + ACTION_MOVELEFT = 1; + ACTION_MOVERIGHT = 2; + ACTION_LOOKDOWN = 3; + ACTION_LOOKUP = 4; + ACTION_ATTACK = 5; + ACTION_SCORES = 6; + ACTION_ACTIVATE = 7; + ACTION_STRAFE = 8; + ACTION_WEAPNEXT = 9; + ACTION_WEAPPREV = 10; + + FIRST_ACTION = ACTION_JUMP; + LAST_ACTION = ACTION_WEAPPREV; + +procedure g_Console_Init; +procedure g_Console_Update; +procedure g_Console_Draw; procedure g_Console_Char (C: AnsiChar); procedure g_Console_Control (K: Word); procedure g_Console_Process (L: AnsiString; quiet: Boolean=false); procedure g_Console_Add (L: AnsiString; show: Boolean=false); -procedure g_Console_Clear (); +procedure g_Console_Clear; function g_Console_CommandBlacklisted (C: AnsiString): Boolean; +procedure g_Console_ReadConfig (filename: String); +procedure g_Console_WriteConfig (filename: String); +procedure g_Console_WriteGameConfig; + +function g_Console_Interactive: Boolean; +function g_Console_Action (action: Integer): Boolean; +function g_Console_MatchBind (key: Integer; down: AnsiString; up: AnsiString = ''): Boolean; +function g_Console_FindBind (n: Integer; down: AnsiString; up: AnsiString = ''): Integer; +procedure g_Console_BindKey (key: Integer; down: AnsiString; up: AnsiString = ''); +procedure g_Console_ProcessBind (key: Integer; down: Boolean); +procedure g_Console_ResetBinds; 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: 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; 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; +procedure conRegVar (const conname: AnsiString; pvar: PInteger; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; + +// <0: no arg; 0/1: true/false +function conGetBoolArg (p: SSArray; idx: Integer): Integer; // poor man's floating literal parser; i'm sorry, but `StrToFloat()` sux cocks function conParseFloat (var res: Single; const s: AnsiString): Boolean; @@ -52,16 +77,16 @@ var gChatShow: Boolean = false; gChatTeam: Boolean = false; gAllowConsoleMessages: Boolean = true; - gChatEnter: Boolean = true; gJustChatted: Boolean = false; // ÷òîáû àäìèí â èíòåðå ÷àòÿñü íå ïðîìàòûâàë ñòàòèñòèêó - + gParsingBinds: Boolean = true; // íå ïåðåñîõðàíÿòü êîíôèã âî âðåìÿ ïàðñèíãà + gPlayerAction: Array [0..1, 0..LAST_ACTION] of Boolean; // [player, action] 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; + SysUtils, g_basic, g_options, Math, g_touch, + g_menu, g_gui, g_language, g_net, g_netmsg, e_log, conbuf; type @@ -79,6 +104,8 @@ type ptr: Pointer; // various data msg: AnsiString; // message for var changes cheat: Boolean; + action: Integer; // >= 0 for action commands + player: Integer; // used for action commands end; TAlias = record @@ -115,6 +142,31 @@ var Time: Word; end; + gInputBinds: Array [0..e_MaxInputKeys - 1] of record + down, up: SSArray; + end; + menu_toggled: BOOLEAN; (* hack for menu controls *) + gSkipFirstChar: Boolean; (* hack for console/chat input *) + + +procedure g_Console_Switch; +begin + gChatShow := False; + gConsoleShow := not gConsoleShow; + Cons_Shown := True; + g_Touch_ShowKeyboard(gConsoleShow or gChatShow); +end; + +procedure g_Console_Chat_Switch (Team: Boolean = False); +begin + if not g_Game_IsNet then Exit; + gConsoleShow := False; + gChatShow := not gChatShow; + gChatTeam := Team; + Line := ''; + CPos := 1; + g_Touch_ShowKeyboard(gConsoleShow or gChatShow); +end; // poor man's floating literal parser; i'm sorry, but `StrToFloat()` sux cocks function conParseFloat (var res: Single; const s: AnsiString): Boolean; @@ -170,6 +222,8 @@ end; procedure boolVarHandler (me: PCommand; p: SSArray); procedure binaryFlag (var flag: Boolean; msg: AnsiString); + var + old: Boolean; begin if (Length(p) > 2) then begin @@ -177,12 +231,15 @@ procedure boolVarHandler (me: PCommand; p: SSArray); end else begin + old := flag; case conGetBoolArg(p, 1) of -1: begin 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 <> old then + g_Console_WriteGameConfig(); if (Length(msg) = 0) then msg := p[0] else msg += ':'; if flag then conwritefln('%s tan', [msg]) else conwritefln('%s ona', [msg]); end; @@ -192,6 +249,28 @@ begin end; +procedure intVarHandler (me: PCommand; p: SSArray); +var + old: Integer; +begin + if (Length(p) <> 2) then + begin + conwritefln('%s %d', [me.cmd, PInteger(me.ptr)^]); + end + else + begin + try + old := PInteger(me.ptr)^; + PInteger(me.ptr)^ := StrToInt(p[1]); + if PInteger(me.ptr)^ <> old then + g_Console_WriteGameConfig(); + except + conwritefln('invalid integer value: "%s"', [p[1]]); + end; + end; +end; + + procedure conRegVar (const conname: AnsiString; pvar: PBoolean; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; var f: Integer; @@ -208,6 +287,29 @@ begin cp.ptr := pvar; cp.msg := amsg; cp.cheat := acheat; + cp.action := -1; + cp.player := -1; +end; + + +procedure conRegVar (const conname: AnsiString; pvar: PInteger; const ahelp: AnsiString; const amsg: AnsiString; acheat: Boolean=false; ahidden: Boolean=false); overload; +var + f: Integer; + cp: PCommand; +begin + f := Length(commands); + SetLength(commands, f+1); + cp := @commands[f]; + cp.cmd := LowerCase(conname); + cp.proc := nil; + cp.procEx := intVarHandler; + cp.help := ahelp; + cp.hidden := ahidden; + cp.ptr := pvar; + cp.msg := amsg; + cp.cheat := acheat; + cp.action := -1; + cp.player := -1; end; @@ -223,7 +325,7 @@ type procedure singleVarHandler (me: PCommand; p: SSArray); var pv: PVarSingle; - nv: Single; + nv, old: Single; msg: AnsiString; begin if (Length(p) > 2) then @@ -232,6 +334,7 @@ begin exit; end; pv := PVarSingle(me.ptr); + old := pv.val^; if (Length(p) = 2) then begin if me.cheat and (not conIsCheatsEnabled) then begin conwriteln('not available'); exit; end; @@ -253,6 +356,8 @@ begin pv.val^ := nv; end; end; + if pv.val^ <> old then + g_Console_WriteGameConfig(); msg := me.msg; if (Length(msg) = 0) then msg := me.cmd else msg += ':'; conwritefln('%s %s', [msg, pv.val^]); @@ -265,7 +370,7 @@ var cp: PCommand; pv: PVarSingle; begin - GetMem(pv, sizeof(pv^)); + GetMem(pv, sizeof(TVarSingle)); pv.val := pvar; pv.min := amin; pv.max := amax; @@ -281,6 +386,8 @@ begin cp.ptr := pv; cp.msg := amsg; cp.cheat := acheat; + cp.action := -1; + cp.player := -1; end; @@ -320,7 +427,7 @@ procedure ConsoleCommands(p: SSArray); var cmd, s: AnsiString; a, b: Integer; - F: TextFile; + (* F: TextFile; *) begin cmd := LowerCase(p[0]); s := ''; @@ -422,53 +529,28 @@ begin if cmd = 'exec' then begin // exec - if Length(p) > 1 then - begin - s := GameDir+'/'+p[1]; - - {$I-} - AssignFile(F, s); - Reset(F); - if IOResult <> 0 then - begin - g_Console_Add(Format(_lc[I_CONSOLE_ERROR_READ], [s])); - CloseFile(F); - Exit; - end; - g_Console_Add(Format(_lc[I_CONSOLE_EXEC], [s])); - - while not EOF(F) do - begin - ReadLn(F, s); - if IOResult <> 0 then - begin - g_Console_Add(Format(_lc[I_CONSOLE_ERROR_READ], [s])); - CloseFile(F); - Exit; - end; - if Pos('#', s) <> 1 then // script comment - begin - // prevents endless loops - Inc(RecursionDepth); - RecursionLimitHit := (RecursionDepth > MaxScriptRecursion) or RecursionLimitHit; - if not RecursionLimitHit then - g_Console_Process(s, True); - Dec(RecursionDepth); - end; - end; - if (RecursionDepth = 0) and RecursionLimitHit then - begin - g_Console_Add(Format(_lc[I_CONSOLE_ERROR_CALL], [s])); - RecursionLimitHit := False; - end; - - CloseFile(F); - {$I+} - end + if Length(p) = 2 then + g_Console_ReadConfig(GameDir + '/' + p[1]) else g_Console_Add('exec