From: DeaDDooMER Date: Mon, 7 Jun 2021 13:22:53 +0000 (+0300) Subject: render: separate console logic and drawing X-Git-Url: http://deadsoftware.ru/gitweb?p=d2df-sdl.git;a=commitdiff_plain;h=83ba12ea2028427bb2e8c1c362294e04c1d55008 render: separate console logic and drawing --- diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr index 53d54fc..e928742 100644 --- a/src/game/Doom2DF.lpr +++ b/src/game/Doom2DF.lpr @@ -153,6 +153,8 @@ uses g_touch in 'sdl2/g_touch.pas', {$ENDIF} + r_console in 'opengl/r_console.pas', + {$IFDEF USE_FMOD} fmod in '../lib/FMOD/fmod.pas', fmoderrors in '../lib/FMOD/fmoderrors.pas', diff --git a/src/game/g_console.pas b/src/game/g_console.pas index 15497d9..9db9e79 100644 --- a/src/game/g_console.pas +++ b/src/game/g_console.pas @@ -36,10 +36,18 @@ uses FIRST_ACTION = ACTION_JUMP; LAST_ACTION = ACTION_WEAPPREV; + var (* private state *) + Line: AnsiString; + CPos: Word; + conSkipLines: Integer; + MsgArray: Array [0..4] of record + Msg: AnsiString; + Time: Word; + end; + procedure g_Console_Init; procedure g_Console_SysInit; procedure g_Console_Update; -procedure g_Console_Draw (MessagesOnly: Boolean = False); procedure g_Console_Char (C: AnsiChar); procedure g_Console_Control (K: Word); procedure g_Console_Process (L: AnsiString; quiet: Boolean=false); @@ -91,7 +99,7 @@ var implementation uses - g_textures, g_main, e_graphics, e_input, g_game, g_gfx, g_player, g_items, + g_textures, g_main, e_input, g_game, g_gfx, g_player, g_items, SysUtils, g_basic, g_options, Math, g_touch, e_res, g_menu, g_gui, g_language, g_net, g_netmsg, e_log, conbuf; @@ -128,48 +136,27 @@ const MsgTime = 144; MaxScriptRecursion = 16; - DEBUG_STRING = 'DEBUG MODE'; - var - ID: DWORD; RecursionDepth: Word = 0; RecursionLimitHit: Boolean = False; - Cons_Y: SmallInt; - ConsoleHeight: Single; - Cons_Shown: Boolean; // draw console InputReady: Boolean; // allow text input in console/chat - Line: AnsiString; - CPos: Word; //ConsoleHistory: SSArray; CommandHistory: SSArray; Whitelist: SSArray; commands: Array of TCommand = nil; Aliases: Array of TAlias = nil; CmdIndex: Word; - conSkipLines: Integer = 0; - MsgArray: Array [0..4] of record - Msg: AnsiString; - Time: Word; - end; gInputBinds: Array [0..e_MaxInputKeys - 1] of record rep: Boolean; down, up: SSArray; end; menu_toggled: BOOLEAN; (* hack for menu controls *) - ChatTop: BOOLEAN; - ConsoleStep: Single; - ConsoleTrans: Single; - procedure g_Console_Switch; begin - Cons_Y := Min(0, Max(Cons_Y, -Floor(gScreenHeight * ConsoleHeight))); - if Cons_Shown = False then - Cons_Y := -Floor(gScreenHeight * ConsoleHeight); gChatShow := False; gConsoleShow := not gConsoleShow; - Cons_Shown := True; InputReady := False; g_Touch_ShowKeyboard(gConsoleShow or gChatShow); end; @@ -177,13 +164,9 @@ end; procedure g_Console_Chat_Switch (Team: Boolean = False); begin if not g_Game_IsNet then Exit; - Cons_Y := Min(0, Max(Cons_Y, -Floor(gScreenHeight * ConsoleHeight))); - if Cons_Shown = False then - Cons_Y := -Floor(gScreenHeight * ConsoleHeight); gConsoleShow := False; gChatShow := not gChatShow; gChatTeam := Team; - Cons_Shown := True; InputReady := False; Line := ''; CPos := 1; @@ -964,10 +947,8 @@ end; procedure g_Console_SysInit; var a: Integer; begin - Cons_Y := -Floor(gScreenHeight * ConsoleHeight); gConsoleShow := False; gChatShow := False; - Cons_Shown := False; InputReady := False; CPos := 1; @@ -1183,35 +1164,15 @@ end; procedure g_Console_Init; begin - g_Texture_CreateWAD(ID, GameWAD+':TEXTURES\CONSOLE'); g_Console_Add(Format(_lc[I_CONSOLE_WELCOME], [GAME_VERSION])); g_Console_Add(''); end; procedure g_Console_Update; var - a, b, Step: Integer; + a, b: Integer; begin - if Cons_Shown then - begin - Step := Max(1, Round(Floor(gScreenHeight * ConsoleHeight) * ConsoleStep)); - if gConsoleShow then - begin - (* Open animation *) - Cons_Y := Min(Cons_Y + Step, 0); - InputReady := True - end - else - begin - (* Close animation *) - Cons_Y := Max(Cons_Y - Step, -Floor(gScreenHeight * ConsoleHeight)); - Cons_Shown := Cons_Y > -Floor(gScreenHeight * ConsoleHeight); - InputReady := False - end; - - if gChatShow then - InputReady := True - end; + InputReady := gConsoleShow or gChatShow; a := 0; while a <= High(MsgArray) do @@ -1238,138 +1199,6 @@ 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 := Floor(gScreenHeight * ConsoleHeight) - 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(MessagesOnly: Boolean = False); -var - CWidth, CHeight: Byte; - mfW, mfH: Word; - a, b, offset_y: Integer; -begin - e_TextureFontGetSize(gStdFont, CWidth, CHeight); - - if ChatTop and gChatShow then - offset_y := CHeight - else - offset_y := 0; - - for a := 0 to High(MsgArray) do - if MsgArray[a].Time > 0 then - e_TextureFontPrintFmt(0, offset_y + CHeight * a, MsgArray[a].Msg, gStdFont, True); - - if MessagesOnly then Exit; - - if gChatShow then - begin - if ChatTop then - offset_y := 0 - else - offset_y := gScreenHeight - CHeight - 1; - if gChatTeam then - begin - e_TextureFontPrintEx(0, offset_y, 'say team> ' + Line, gStdFont, 255, 255, 255, 1, True); - e_TextureFontPrintEx((CPos + 9) * CWidth, offset_y, '_', gStdFont, 255, 255, 255, 1, True); - end - else - begin - e_TextureFontPrintEx(0, offset_y, 'say> ' + Line, gStdFont, 255, 255, 255, 1, True); - e_TextureFontPrintEx((CPos + 4) * CWidth, offset_y, '_', gStdFont, 255, 255, 255, 1, True); - end - end; - - if not Cons_Shown then - Exit; - - if gDebugMode then - begin - e_CharFont_GetSize(gMenuFont, DEBUG_STRING, mfW, mfH); - a := (gScreenWidth - 2*mfW) div 2; - b := Cons_Y + (Floor(gScreenHeight * ConsoleHeight) - 2 * mfH) div 2; - e_CharFont_PrintEx(gMenuFont, a div 2, b div 2, DEBUG_STRING, - _RGB(128, 0, 0), 2.0); - end; - - e_DrawSize(ID, 0, Cons_Y, Round(ConsoleTrans * 255), False, False, gScreenWidth, Floor(gScreenHeight * ConsoleHeight)); - e_TextureFontPrint(0, Cons_Y + Floor(gScreenHeight * ConsoleHeight) - CHeight - 4, '> ' + Line, gStdFont); - - drawConsoleText(); - (* - if ConsoleHistory <> nil then - begin - b := 0; - if CHeight > 0 then - if Length(ConsoleHistory) > (Floor(gScreenHeight * ConsoleHeight) div CHeight) - 1 then - b := Length(ConsoleHistory) - (Floor(gScreenHeight * ConsoleHeight) div CHeight) + 1; - - b := Max(b-Offset, 0); - d := Max(High(ConsoleHistory)-Offset, 0); - - c := 2; - for a := d downto b do - begin - e_TextureFontPrintFmt(0, Floor(gScreenHeight * ConsoleHeight) - 4 - c * CHeight - Abs(Cons_Y), ConsoleHistory[a], gStdFont, True); - c := c + 1; - end; - end; - *) - - e_TextureFontPrint((CPos + 1) * CWidth, Cons_Y + Floor(gScreenHeight * ConsoleHeight) - 21, '_', gStdFont); -end; - procedure g_Console_Char(C: AnsiChar); begin if InputReady and (gConsoleShow or gChatShow) then @@ -2227,19 +2056,6 @@ end; procedure Init; var i: Integer; begin - conRegVar('chat_at_top', @ChatTop, 'draw chat at top border', 'draw chat at top border'); - conRegVar('console_height', @ConsoleHeight, 0.0, 1.0, 'set console size', 'set console size'); - conRegVar('console_trans', @ConsoleTrans, 0.0, 1.0, 'set console transparency', 'set console transparency'); - conRegVar('console_step', @ConsoleStep, 0.0, 1.0, 'set console animation speed', 'set console animation speed'); -{$IFDEF ANDROID} - ChatTop := True; - ConsoleHeight := 0.35; -{$ELSE} - ChatTop := False; - ConsoleHeight := 0.5; -{$ENDIF} - ConsoleTrans := 0.1; - ConsoleStep := 0.07; conRegVar('d_eres', @debug_e_res, '', ''); for i := 1 to e_MaxJoys do conRegVar('joy' + IntToStr(i) + '_deadzone', @e_JoystickDeadzones[i - 1], '', '') diff --git a/src/game/g_game.pas b/src/game/g_game.pas index a2dacb9..6f70992 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -388,7 +388,7 @@ uses g_holmes, {$ENDIF} e_texture, e_res, g_textures, g_window, g_menu, - e_input, e_log, g_console, g_items, g_map, g_panel, + e_input, e_log, g_console, r_console, g_items, g_map, g_panel, g_playermodel, g_gfx, g_options, Math, g_triggers, g_monsters, e_sound, CONFIG, g_language, g_net, g_main, g_phys, @@ -1399,6 +1399,7 @@ begin g_Game_SetLoadingText('', 0, False); g_Game_SetLoadingText(_lc[I_LOAD_CONSOLE], 0, False); + r_Console_Init; g_Console_Init(); g_Game_SetLoadingText(_lc[I_LOAD_MODELS], 0, False); @@ -1795,6 +1796,7 @@ begin // no need to, as we'll do it in event handler // Îáíîâëÿåì êîíñîëü (äâèæåíèå è ñîîáùåíèÿ): + r_Console_Update; g_Console_Update(); if (NetMode = NET_NONE) and (g_Game_IsNet) and (gGameOn or (gState in [STATE_FOLD, STATE_INTERCUSTOM])) then @@ -4171,7 +4173,7 @@ begin end; {$IFNDEF HEADLESS} - g_Console_Draw(); + r_Console_Draw(); {$ENDIF} if g_debug_Sounds and gGameOn then diff --git a/src/game/g_window.pas b/src/game/g_window.pas index 37d9791..954790b 100644 --- a/src/game/g_window.pas +++ b/src/game/g_window.pas @@ -41,7 +41,7 @@ uses {$INCLUDE ../nogl/noGLuses.inc} SysUtils, Classes, MAPDEF, Math, e_graphics, e_log, e_texture, g_main, - g_console, e_input, g_options, g_game, + g_console, r_console, e_input, g_options, g_game, g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net, g_map, g_gfx, g_monsters, xprofiler, g_touch, g_gui, g_system, g_netmaster; @@ -94,7 +94,7 @@ begin DrawMenuBackground('INTER'); e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); DrawLoadingStat(); - g_Console_Draw(True); + r_Console_Draw(True); e_SetRendertarget(False); e_SetViewPort(0, 0, gWinSizeX, gWinSizeY); diff --git a/src/game/opengl/r_console.pas b/src/game/opengl/r_console.pas new file mode 100644 index 0000000..194efe1 --- /dev/null +++ b/src/game/opengl/r_console.pas @@ -0,0 +1,214 @@ +(* 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, version 3 of the License ONLY. + * + * 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 r_console; + +interface + + procedure r_Console_Init; + procedure r_Console_Update; + procedure r_Console_Draw (MessagesOnly: Boolean = False); + +implementation + + uses + SysUtils, Classes, Math, + e_log, e_graphics, + conbuf, + g_main, g_console, g_game, g_menu, g_textures + ; + +(* ====== Console ====== *) + +const + DEBUG_STRING = 'DEBUG MODE'; + +var + ID: DWORD; + ConsoleTrans: Single; + ChatTop: BOOLEAN; + + Cons_Y: SmallInt; + ConsoleHeight: Single; + ConsoleStep: Single; + Cons_Shown: Boolean; // draw console + +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 := Floor(gScreenHeight * ConsoleHeight) - 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 r_Console_Draw (MessagesOnly: Boolean = False); +var + CWidth, CHeight: Byte; + mfW, mfH: Word; + a, b, offset_y: Integer; +begin + e_TextureFontGetSize(gStdFont, CWidth, CHeight); + + if ChatTop and gChatShow then + offset_y := CHeight + else + offset_y := 0; + + for a := 0 to High(MsgArray) do + if MsgArray[a].Time > 0 then + e_TextureFontPrintFmt(0, offset_y + CHeight * a, MsgArray[a].Msg, gStdFont, True); + + if MessagesOnly then Exit; + + if gChatShow then + begin + if ChatTop then + offset_y := 0 + else + offset_y := gScreenHeight - CHeight - 1; + if gChatTeam then + begin + e_TextureFontPrintEx(0, offset_y, 'say team> ' + Line, gStdFont, 255, 255, 255, 1, True); + e_TextureFontPrintEx((CPos + 9) * CWidth, offset_y, '_', gStdFont, 255, 255, 255, 1, True); + end + else + begin + e_TextureFontPrintEx(0, offset_y, 'say> ' + Line, gStdFont, 255, 255, 255, 1, True); + e_TextureFontPrintEx((CPos + 4) * CWidth, offset_y, '_', gStdFont, 255, 255, 255, 1, True); + end + end; + + if not Cons_Shown then + Exit; + + if gDebugMode then + begin + e_CharFont_GetSize(gMenuFont, DEBUG_STRING, mfW, mfH); + a := (gScreenWidth - 2*mfW) div 2; + b := Cons_Y + (Floor(gScreenHeight * ConsoleHeight) - 2 * mfH) div 2; + e_CharFont_PrintEx(gMenuFont, a div 2, b div 2, DEBUG_STRING, + _RGB(128, 0, 0), 2.0); + end; + + e_DrawSize(ID, 0, Cons_Y, Round(ConsoleTrans * 255), False, False, gScreenWidth, Floor(gScreenHeight * ConsoleHeight)); + e_TextureFontPrint(0, Cons_Y + Floor(gScreenHeight * ConsoleHeight) - CHeight - 4, '> ' + Line, gStdFont); + + drawConsoleText(); + (* + if ConsoleHistory <> nil then + begin + b := 0; + if CHeight > 0 then + if Length(ConsoleHistory) > (Floor(gScreenHeight * ConsoleHeight) div CHeight) - 1 then + b := Length(ConsoleHistory) - (Floor(gScreenHeight * ConsoleHeight) div CHeight) + 1; + + b := Max(b-Offset, 0); + d := Max(High(ConsoleHistory)-Offset, 0); + + c := 2; + for a := d downto b do + begin + e_TextureFontPrintFmt(0, Floor(gScreenHeight * ConsoleHeight) - 4 - c * CHeight - Abs(Cons_Y), ConsoleHistory[a], gStdFont, True); + c := c + 1; + end; + end; + *) + + e_TextureFontPrint((CPos + 1) * CWidth, Cons_Y + Floor(gScreenHeight * ConsoleHeight) - 21, '_', gStdFont); +end; + + procedure r_Console_Update; + var step, miny: Integer; + begin + step := Max(1, Round(Floor(gScreenHeight * ConsoleHeight) * ConsoleStep)); + miny := Round(-Floor(gScreenHeight * ConsoleHeight)); + if gConsoleShow then + Cons_Y := Cons_Y + step + else + Cons_Y := Cons_Y - step; + Cons_Y := Min(Max(Cons_Y, miny), 0); + Cons_Shown := Cons_Y > miny; + end; + + procedure r_Console_Init; + var miny: Integer; + begin + g_Texture_CreateWAD(ID, GameWAD + ':TEXTURES\CONSOLE'); + miny := Round(-Floor(gScreenHeight * ConsoleHeight)); + Cons_Y := miny; + end; + +initialization + conRegVar('chat_at_top', @ChatTop, 'draw chat at top border', 'draw chat at top border'); + conRegVar('console_height', @ConsoleHeight, 0.0, 1.0, 'set console size', 'set console size'); + conRegVar('console_step', @ConsoleStep, 0.0, 1.0, 'set console animation speed', 'set console animation speed'); + conRegVar('console_trans', @ConsoleTrans, 0.0, 1.0, 'set console transparency', 'set console transparency'); +{$IFDEF ANDROID} + ChatTop := True; + ConsoleHeight := 0.35; +{$ELSE} + ChatTop := False; + ConsoleHeight := 0.5; +{$ENDIF} + ConsoleStep := 0.07; + ConsoleTrans := 0.1; +end.