X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_console.pas;h=8ce21672eefc219b83daf63e470340afc792e893;hb=ece4a4ff27b5415a6ab561721906ab1b3c81b20e;hp=5f26b864ba8d064a5df1dcde85f9f7efa8c1fc45;hpb=70c6ae06da3e766e0303dca258b0b3f6e56a2dea;p=d2df-sdl.git diff --git a/src/game/g_console.pas b/src/game/g_console.pas index 5f26b86..8ce2167 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -1,3 +1,19 @@ +(* 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 + * the Free Software Foundation, either version 3 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, see . + *) +{$INCLUDE ../shared/a_modes.inc} unit g_console; interface @@ -27,8 +43,8 @@ implementation uses g_textures, g_main, e_graphics, e_input, g_game, - SysUtils, g_basic, g_options, WADEDITOR, Math, - g_menu, g_language, g_net, g_netmsg, e_log; + SysUtils, g_basic, g_options, wadreader, Math, + g_menu, g_language, g_net, g_netmsg, e_log, conbuf; type TCmdProc = procedure (P: SArray); @@ -36,6 +52,8 @@ type TCommand = record Cmd: String; Proc: TCmdProc; + help: String; + hidden: Boolean; end; TAlias = record @@ -59,13 +77,13 @@ var Cons_Shown: Boolean; // Ðèñîâàòü ëè êîíñîëü? Line: String; CPos: Word; - ConsoleHistory: SArray; + //ConsoleHistory: SArray; CommandHistory: SArray; Whitelist: SArray; Commands: Array of TCommand; Aliases: Array of TAlias; CmdIndex: Word; - Offset: Word; + conSkipLines: Integer = 0; MsgArray: Array [0..4] of record Msg: String; Time: Word; @@ -113,7 +131,9 @@ begin if Cmd = 'clear' then begin - ConsoleHistory := nil; + //ConsoleHistory := nil; + cbufClear(); + conSkipLines := 0; for a := 0 to High(MsgArray) do with MsgArray[a] do @@ -139,7 +159,16 @@ begin g_Console_Add(''); g_Console_Add('Commands list:'); for a := High(Commands) downto 0 do - g_Console_Add(' '+Commands[a].Cmd); + begin + if (Length(Commands[a].help) > 0) then + begin + g_Console_Add(' '+Commands[a].Cmd+' -- '+Commands[a].help); + end + else + begin + g_Console_Add(' '+Commands[a].Cmd); + end; + end; end; if Cmd = 'time' then @@ -166,6 +195,7 @@ begin if Cmd = 'dump' then begin + (* if ConsoleHistory <> nil then begin if Length(P) > 1 then @@ -190,6 +220,7 @@ begin g_Console_Add(Format(_lc[I_CONSOLE_DUMPED], [s])); {$I+} end; + *) end; if Cmd = 'exec' then @@ -314,17 +345,19 @@ var begin SetLength(Whitelist, Length(Whitelist)+1); a := High(Whitelist); - Whitelist[a] := Cmd; + Whitelist[a] := LowerCase(Cmd); end; -procedure AddCommand(Cmd: String; Proc: TCmdProc); +procedure AddCommand(Cmd: String; Proc: TCmdProc; ahelp: String=''; ahidden: Boolean=false); var a: Integer; begin SetLength(Commands, Length(Commands)+1); a := High(Commands); - Commands[a].Cmd := Cmd; + Commands[a].Cmd := LowerCase(Cmd); Commands[a].Proc := Proc; + Commands[a].hidden := ahidden; + Commands[a].help := ahelp; end; procedure g_Console_Init(); @@ -345,7 +378,7 @@ begin Time := 0; end; - AddCommand('clear', ConsoleCommands); + AddCommand('clear', ConsoleCommands, 'clear console'); AddCommand('clearhistory', ConsoleCommands); AddCommand('showhistory', ConsoleCommands); AddCommand('commands', ConsoleCommands); @@ -368,6 +401,22 @@ begin AddCommand('d_player', DebugCommands); AddCommand('d_joy', DebugCommands); + AddCommand('pf_draw_frame', ProfilerCommands, 'draw frame rendering profiles'); + //AddCommand('pf_update_frame', ProfilerCommands); + AddCommand('pf_coldet', ProfilerCommands, 'draw collision detection profiles'); + AddCommand('r_sq_draw', ProfilerCommands, 'accelerated spatial queries in rendering'); + //AddCommand('r_sq_use_grid', ProfilerCommands, 'use grid for render acceleration'); + //AddCommand('r_sq_use_tree', ProfilerCommands, 'use tree for render acceleration'); + AddCommand('cd_sq_enabled', ProfilerCommands, 'accelerated spatial queries in map coldet'); + + //AddCommand('t_dump_node_queries', ProfilerCommands); + + //AddCommand('sq_use_grid', ProfilerCommands, 'use grid for map coldet acceleration'); + //AddCommand('sq_use_tree', ProfilerCommands, 'use tree for map coldet acceleration'); + + AddCommand('mon_sq_enabled', ProfilerCommands, 'use accelerated spatial queries for monsters'); + AddCommand('wtrace_sq_enabled', ProfilerCommands, 'use accelerated weapon hitscan trace'); + AddCommand('p1_name', GameCVars); AddCommand('p2_name', GameCVars); AddCommand('p1_color', GameCVars); @@ -537,11 +586,67 @@ begin end; end; + +procedure drawConsoleText (); +var + CWidth, CHeight: Byte; + ty: Integer; + sp, ep: LongWord; + skip: Integer; + + procedure putLine (sp, ep: LongWord); + var + p: LongWord; + wdt, cw: Integer; + begin + p := sp; + wdt := 0; + while p <> ep do + begin + cw := e_TextureFontCharWidth(cbufAt(p), gStdFont); + if wdt+cw > gScreenWidth-8 then break; + //e_TextureFontPrintChar(X, Y: Integer; Ch: Char; FontID: DWORD; Shadow: Boolean = False); + Inc(wdt, cw); + cbufNext(p); + end; + if p <> ep then putLine(p, ep); // do rest of the line first + // now print our part + if skip = 0 then + begin + ep := p; + p := sp; + wdt := 2; + while p <> ep do + begin + cw := e_TextureFontCharWidth(cbufAt(p), gStdFont); + e_TextureFontPrintCharEx(wdt, ty, cbufAt(p), gStdFont); + Inc(wdt, cw); + cbufNext(p); + end; + Dec(ty, CHeight); + end + else + begin + Dec(skip); + end; + end; + +begin + e_TextureFontGetSize(gStdFont, CWidth, CHeight); + ty := (gScreenHeight div 2)-4-2*CHeight-Abs(Cons_Y); + skip := conSkipLines; + cbufLastLine(sp, ep); + repeat + putLine(sp, ep); + if ty+CHeight <= 0 then break; + until not cbufLineUp(sp, ep); +end; + procedure g_Console_Draw(); var CWidth, CHeight: Byte; mfW, mfH: Word; - a, b, c, d: Integer; + a, b: Integer; begin e_TextureFontGetSize(gStdFont, CWidth, CHeight); @@ -584,6 +689,8 @@ begin e_DrawSize(ID, 0, Cons_Y, Alpha, False, False, gScreenWidth, gScreenHeight div 2); e_TextureFontPrint(0, Cons_Y+(gScreenHeight div 2)-CHeight-4, '> '+Line, gStdFont); + drawConsoleText(); + (* if ConsoleHistory <> nil then begin b := 0; @@ -602,6 +709,7 @@ begin c := c + 1; end; end; + *) e_TextureFontPrint((CPos+1)*CWidth, Cons_Y+(gScreenHeight div 2)-21, '_', gStdFont); end; @@ -633,39 +741,122 @@ begin CPos := CPos + 1; end; -procedure Complete(); + var - i: Integer; - t: Array of String; + tcomplist: array of string = nil; + tcompidx: array of Integer = nil; + +procedure Complete (); +var + i, c: Integer; + tused: Integer; + ll, lpfx, cmd: string; begin - if Line = '' then - Exit; + if (Length(Line) = 0) then + begin + g_Console_Add(''); + for i := 0 to High(Commands) do + begin + if not Commands[i].hidden 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; + end; + end; + exit; + end; + + ll := LowerCase(Line); + lpfx := ''; - t := nil; + if (Length(ll) > 1) and (ll[Length(ll)] = ' ') then + begin + ll := Copy(ll, 0, Length(ll)-1); + for i := 0 to High(Commands) do + begin + if Commands[i].hidden then continue; + if (Commands[i].Cmd = ll) then + begin + if (Length(Commands[i].help) > 0) then + begin + g_Console_Add(' '+Commands[i].Cmd+' -- '+Commands[i].help); + end; + end; + end; + exit; + end; + // build completion list + tused := 0; for i := 0 to High(Commands) do - if LowerCase(Line) = LowerCase(Copy(Commands[i].Cmd, 0, Length(Line))) then + begin + if Commands[i].hidden then continue; + cmd := Commands[i].Cmd; + if (Length(cmd) >= Length(ll)) and (ll = Copy(cmd, 0, Length(ll))) then + begin + if (tused = Length(tcomplist)) then + begin + SetLength(tcomplist, Length(tcomplist)+128); + SetLength(tcompidx, Length(tcompidx)+128); + end; + tcomplist[tused] := cmd; + tcompidx[tused] := i; + Inc(tused); + if (Length(cmd) > Length(lpfx)) then lpfx := cmd; + end; + end; + + // get longest prefix + for i := 0 to tused-1 do + begin + cmd := tcomplist[i]; + for c := 1 to Length(lpfx) do begin - SetLength(t, Length(t) + 1); - t[Length(t)-1] := Commands[i].Cmd; + if (c > Length(cmd)) then break; + if (cmd[c] <> lpfx[c]) then begin lpfx := Copy(lpfx, 0, c-1); break; end; end; + end; - if t = nil then - Exit; + if (tused = 0) then exit; - if Length(t) = 1 then + if (tused = 1) then + begin + Line := tcomplist[0]+' '; + CPos := Length(Line)+1; + end + else + begin + // has longest prefix? + if (Length(lpfx) > Length(ll)) then begin - Line := t[0]+' '; - CPos := Length(Line)+1; + Line := lpfx; + CPos:= Length(Line)+1; end - else + else begin g_Console_Add(''); - for i := 0 to High(t) do - g_Console_Add(' '+t[i]); + for i := 0 to tused-1 do + begin + if (Length(Commands[tcompidx[i]].help) > 0) then + begin + g_Console_Add(' '+tcomplist[i]+' -- '+Commands[tcompidx[i]].help); + end + else + begin + g_Console_Add(' '+tcomplist[i]); + end; + end; end; + end; end; + procedure g_Console_Control(K: Word); begin case K of @@ -741,11 +932,9 @@ begin Cpos := Length(Line) + 1; end; IK_PAGEUP, IK_KPPAGEUP: // PgUp - if not gChatShow then - IncMax(OffSet, Length(ConsoleHistory)-1); + if not gChatShow then Inc(conSkipLines); IK_PAGEDN, IK_KPPAGEDN: // PgDown - if not gChatShow then - DecMin(OffSet, 0); + if not gChatShow and (conSkipLines > 0) then Dec(conSkipLines); IK_HOME, IK_KPHOME: CPos := 1; IK_END, IK_KPEND: @@ -796,52 +985,69 @@ begin end; end; -procedure g_Console_Add(L: String; Show: Boolean = False); -var - a: Integer; -begin - // Âûâîä ñòðîê ñ ïåðåíîñàìè ïî î÷åðåäè - while Pos(#10, L) > 0 do - begin - g_Console_Add(Copy(L, 1, Pos(#10, L) - 1), Show); - Delete(L, 1, Pos(#10, L)); - end; +procedure g_Console_Add (L: string; Show: Boolean=false); - SetLength(ConsoleHistory, Length(ConsoleHistory)+1); - ConsoleHistory[High(ConsoleHistory)] := L; - - Show := Show and gAllowConsoleMessages; - - if Show and gShowMessages then + procedure conmsg (s: AnsiString); + var + a: Integer; begin + if length(s) = 0 then exit; for a := 0 to High(MsgArray) do + begin with MsgArray[a] do + begin if Time = 0 then begin - Msg := L; + Msg := s; Time := MsgTime; - Exit; + exit; end; - - for a := 0 to High(MsgArray)-1 do - MsgArray[a] := MsgArray[a+1]; - + end; + end; + for a := 0 to High(MsgArray)-1 do MsgArray[a] := MsgArray[a+1]; with MsgArray[High(MsgArray)] do begin Msg := L; Time := MsgTime; end; end; - + +var + f: Integer; +begin + // put it to console + cbufPut(L); + if (length(L) = 0) or ((L[length(L)] <> #10) and (L[length(L)] <> #13)) then cbufPut(#10); + + // now show 'em out of console too + Show := Show and gAllowConsoleMessages; + if Show and gShowMessages then + begin + // Âûâîä ñòðîê ñ ïåðåíîñàìè ïî î÷åðåäè + while length(L) > 0 do + begin + f := Pos(#10, L); + if f <= 0 then f := length(L)+1; + conmsg(Copy(L, 1, f-1)); + Delete(L, 1, f); + end; + end; + + //SetLength(ConsoleHistory, Length(ConsoleHistory)+1); + //ConsoleHistory[High(ConsoleHistory)] := L; + + (* {$IFDEF HEADLESS} e_WriteLog('CON: ' + L, MSG_NOTIFY); {$ENDIF} + *) end; procedure g_Console_Clear(); begin - ConsoleHistory := nil; - Offset := 0; + //ConsoleHistory := nil; + cbufClear(); + conSkipLines := 0; end; procedure AddToHistory(L: String); @@ -891,6 +1097,17 @@ begin if Trim(L) = '' then Exit; + conSkipLines := 0; // "unscroll" + + if L = 'goobers' then + begin + Line := ''; + CPos := 1; + gCheats := true; + g_Console_Add('Your memory serves you well.'); + exit; + end; + if not Quiet then begin g_Console_Add('> '+L);