From 64cf710bf7eb902971736580b36bcf8ce20400d8 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sun, 12 Jun 2022 11:48:14 +0300 Subject: [PATCH] gl: draw gui controls --- src/game/Doom2DF.lpr | 2 + src/game/renders/opengl/r_common.pas | 59 +++ src/game/renders/opengl/r_gui.pas | 598 +++++++++++++++++++++++++ src/game/renders/opengl/r_map.pas | 9 +- src/game/renders/opengl/r_render.pas | 46 +- src/game/renders/opengl/r_textures.pas | 8 + 6 files changed, 692 insertions(+), 30 deletions(-) create mode 100644 src/game/renders/opengl/r_common.pas create mode 100644 src/game/renders/opengl/r_gui.pas diff --git a/src/game/Doom2DF.lpr b/src/game/Doom2DF.lpr index ba70051..5eb2229 100644 --- a/src/game/Doom2DF.lpr +++ b/src/game/Doom2DF.lpr @@ -203,6 +203,8 @@ uses r_draw in 'renders/opengl/r_draw.pas', r_map in 'renders/opengl/r_map.pas', r_fonts in 'renders/opengl/r_fonts.pas', + r_common in 'renders/opengl/r_common.pas', + r_gui in 'renders/opengl/r_gui.pas', {$ELSE} {$FATAL render driver not selected} {$ENDIF} diff --git a/src/game/renders/opengl/r_common.pas b/src/game/renders/opengl/r_common.pas new file mode 100644 index 0000000..ba934c5 --- /dev/null +++ b/src/game/renders/opengl/r_common.pas @@ -0,0 +1,59 @@ +(* 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_common; + +interface + + uses r_textures; + + var + stdfont: TGLFont; + smallfont: TGLFont; + menufont: TGLFont; + + procedure r_Common_Load; + procedure r_Common_Free; + +implementation + + uses e_log, r_fonts, g_options; + + function r_Common_LoadFont (const name: AnsiString): TGLFont; + var info: TFontInfo; skiphack: Integer; + begin + result := nil; + if name = 'STD' then skiphack := 144 else skiphack := 0; + if r_Font_LoadInfoFromFile(GameWad + ':FONTS/' + name + 'TXT', info) then + result := r_Textures_LoadFontFromFile(GameWad + ':FONTS/' + name + 'FONT', info, skiphack, true); + if result = nil then + e_logwritefln('failed to load font %s', [name]); + end; + + procedure r_Common_Load; + begin + stdfont := r_Common_LoadFont('STD'); + smallfont := r_Common_LoadFont('SMALL'); + menufont := r_Common_LoadFont('MENU'); + end; + + procedure r_Common_Free; + begin + menufont.Free; + smallfont.Free; + stdfont.Free; + end; + +end. diff --git a/src/game/renders/opengl/r_gui.pas b/src/game/renders/opengl/r_gui.pas new file mode 100644 index 0000000..7016db9 --- /dev/null +++ b/src/game/renders/opengl/r_gui.pas @@ -0,0 +1,598 @@ +(* 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_gui; + +interface + + uses g_gui; + + procedure r_GUI_Load; + procedure r_GUI_Free; + + procedure r_GUI_GetSize (ctrl: TGUIControl; out w, h: Integer); + procedure r_GUI_GetLogoSize (out w, h: Integer); + procedure r_GUI_GetMaxFontSize (BigFont: Boolean; out w, h: Integer); + procedure r_GUI_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer); + + procedure r_GUI_Draw_Window (win: TGUIWindow); + +implementation + + uses + Classes, Math, SysUtils, + MAPDEF, utils, + g_basic, g_base, e_input, g_options, + r_draw, r_textures, r_common, r_map, + g_game, g_menu + ; + + const + EDIT_CURSORLEN = 10; + + type + THereTexture = record + name: AnsiString; + id: TGLTexture; + end; + + var + Box: Array [0..8] of TGLTexture; + MarkerID: array [Boolean] of TGLTexture; + ScrollLeft, ScrollRight, ScrollMiddle, ScrollMarker: TGLTexture; + EditLeft, EditRight, EditMiddle: TGLTexture; + BScrollUp, BScrollDown: array [Boolean] of TGLTexture; + BScrollMiddle: TGLTexture; + + Font: array [boolean] of TGLFont; (* Small[FALSE] / Big[TRUE] *) + LogoTex: TGLTexture; + nopic: TGLTexture; + + Background: THereTexture; + ImageControl: THereTexture; + + procedure r_GUI_FreeThis (var here: THereTexture); + begin + here.name := ''; + if here.id <> nil then + here.id.Free; + here.id := nil; + end; + + function r_GUI_LoadThis (const name: AnsiString; var here: THereTexture): Boolean; + begin + r_GUI_FreeThis(here); + if (name <> '') and (here.name <> name) then + here.id := r_Textures_LoadFromFile(name); + result := here.id <> nil; + end; + + procedure r_GUI_Load; + var i: Integer; + begin + Font[FALSE] := smallfont; + Font[TRUE] := menufont; + + MarkerID[FALSE] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/MARKER1'); + MarkerID[TRUE] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/MARKER2'); + + for i := 0 to 8 do + Box[i] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/BOX' + IntToStr(i + 1)); + + ScrollLeft := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SLEFT'); + ScrollRight := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SRIGHT'); + ScrollMiddle := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SMIDDLE'); + ScrollMarker := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SMARKER'); + + EditLeft := r_Textures_LoadFromFile(GameWad + ':TEXTURES/ELEFT'); + EditRight := r_Textures_LoadFromFile(GameWad + ':TEXTURES/ERIGHT'); + EditMiddle := r_Textures_LoadFromFile(GameWad + ':TEXTURES/EMIDDLE'); + + BScrollUp[true] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SCROLLUPA'); + BScrollUp[false] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SCROLLUPU'); + BScrollDown[true] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SCROLLDOWNA'); + BScrollDown[false] := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SCROLLDOWNU'); + BScrollMiddle := r_Textures_LoadFromFile(GameWad + ':TEXTURES/SCROLLMIDDLE'); + + LogoTex := r_Textures_LoadFromFile(GameWad + ':TEXTURES/MAINLOGO'); + nopic := r_Textures_LoadFromFile(GameWad + ':TEXTURES/NOPIC'); + end; + + procedure r_GUI_Free; + var i: Integer; + begin + Font[FALSE] := nil; + Font[TRUE] := nil; + + MarkerID[FALSE].Free; + MarkerID[TRUE].Free; + + for i := 0 to 8 do + Box[i].Free; + + ScrollLeft.Free; + ScrollRight.Free; + ScrollMiddle.Free; + ScrollMarker.Free; + + EditLeft.Free; + EditRight.Free; + EditMiddle.Free; + + BScrollUp[true].Free; + BScrollUp[false].Free; + BScrollDown[true].Free; + BScrollDown[false].Free; + BScrollMiddle.Free; + + LogoTex.Free; + nopic.Free; + + r_GUI_FreeThis(Background); + r_GUI_FreeThis(ImageControl); + end; + + procedure r_GUI_GetMaxFontSize (BigFont: Boolean; out w, h: Integer); + var f: TGLFont; + begin + f := Font[BigFont]; + w := f.GetMaxWidth(); + h := f.GetMaxHeight(); + end; + + procedure r_GUI_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer); + begin + r_Draw_GetTextSize(str, Font[BigFont], w, h); + end; + + procedure r_GUI_GetLogoSize (out w, h: Integer); + begin + w := 0; h := 0; + if LogoTex <> nil then + begin + w := LogoTex.width; + h := LogoTex.height; + end; + end; + + procedure r_GUI_GetSize_TextButton (ctrl: TGUITextButton; out w, h: Integer); + begin + r_Draw_GetTextSize(ctrl.Caption, Font[ctrl.BigFont], w, h); + end; + + procedure r_GUI_GetSize_Label (ctrl: TGUILabel; out w, h: Integer); + var f: TGLFont; + begin + f := Font[ctrl.BigFont]; + r_Draw_GetTextSize(ctrl.Text, f, w, h); + if ctrl.FixedLength <> 0 then + w := f.GetMaxWidth() * ctrl.FixedLength; + end; + + procedure r_GUI_GetSize_Switch (ctrl: TGUISwitch; out w, h: Integer); + var i: Integer; + begin + w := 0; h := 0; + if ctrl.Items <> nil then + for i := 0 to High(ctrl.Items) do + r_Draw_GetTextSize(ctrl.Items[i], Font[ctrl.BigFont], w, h); + end; + + procedure r_GUI_GetSize_KeyRead (ctrl: TGUIKeyRead; out w, h: Integer); + var i, ww, hh: Integer; f: TGLFont; + begin + w := 0; h := 0; // ??? h always 0 + f := Font[ctrl.BigFont]; + for i := 0 to 255 do + begin + r_Draw_GetTextSize(e_KeyNames[i], f, ww, hh); + w := MAX(w, ww); + end; + r_Draw_GetTextSize(KEYREAD_QUERY, f, ww, hh); + w := MAX(w, ww); + r_Draw_GetTextSize(KEYREAD_CLEAR, f, ww, hh); + w := MAX(w, ww); + end; + + procedure r_GUI_GetSize (ctrl: TGUIControl; out w, h: Integer); + begin + w := 0; + h := 0; + if ctrl is TGUITextButton then + r_GUI_GetSize_TextButton(ctrl as TGUITextButton, w, h) + else if ctrl is TGUILabel then + r_GUI_GetSize_Label(ctrl as TGUILabel, w, h) + else if ctrl is TGUIScroll then + w := 16 + ((ctrl as TGUIScroll).Max + 1) * 8 // ??? but h = 0 + else if ctrl is TGUISwitch then + r_GUI_GetSize_Switch(ctrl as TGUISwitch, w, h) + else if ctrl is TGUIEdit then + w := 16 + (ctrl as TGUIEdit).Width * 16 // ??? but h = 0 + else if ctrl is TGUIKeyRead then + r_GUI_GetSize_KeyRead(ctrl as TGUIKeyRead, w, h) + else if ctrl is TGUIKeyRead2 then + w := (ctrl as TGUIKeyRead2).MaxKeyNameWdt * 2 + 8 + 8 + 16 // ??? but h = 0 + else if ctrl is TGUIListBox then + begin + w := 8 + ((ctrl as TGUIListBox).Width + 1) * 16; // recheck w & h + h := 8 + (ctrl as TGUIListBox).Height * 16; + end + else if ctrl is TGUIMemo then + begin + w := 8 + ((ctrl as TGUIMemo).Width + 1) * 16; + h := 8 + (ctrl as TGUIMemo).Height * 16; + end + else + begin + w := ctrl.GetWidth(); + h := ctrl.GetHeight(); + end; + end; + + procedure r_GUI_Draw_Control (ctrl: TGUIControl); forward; + + procedure r_GUI_Draw_TextButton (ctrl: TGUITextButton); + begin + r_Draw_Text(ctrl.Caption, ctrl.x, ctrl.y, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B, 255, Font[ctrl.BigFont]); + end; + + procedure r_GUI_Draw_Label (ctrl: TGUILabel); + var w, h: Integer; f: TGLFont; + begin + f := Font[ctrl.BigFont]; + if ctrl.RightAlign then + begin + r_Draw_GetTextSize(ctrl.Text, f, w, h); + r_Draw_Text(ctrl.Text, ctrl.X + ctrl.CMaxWidth - w, ctrl.Y, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B, 255, f); + end + else + r_Draw_Text(ctrl.Text, ctrl.X, ctrl.Y, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B, 255, f); + end; + + procedure r_GUI_Draw_Scroll (ctrl: TGUIScroll); + begin + r_Draw_Texture(ScrollLeft, ctrl.X, ctrl.Y, ScrollLeft.width, ScrollLeft.height, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(ScrollMiddle, ctrl.X + 8 + 0 * 8, ctrl.Y, 8 + ctrl.Max * 8, ScrollMiddle.height, false, 255, 255, 255, 255, false); + r_Draw_Texture(ScrollRight, ctrl.X + 8 + (ctrl.Max + 1) * 8, ctrl.Y, ScrollRight.width, ScrollRight.height, false, 255, 255, 255, 255, false); + r_Draw_Texture(ScrollMarker, ctrl.X + 8 + ctrl.Value * 8, ctrl.Y, ScrollMarker.width, ScrollMarker.height, false, 255, 255, 255, 255, false); + end; + + procedure r_GUI_Draw_Switch (ctrl: TGUISwitch); + begin + r_Draw_Text(ctrl.Items[ctrl.ItemIndex], ctrl.X, ctrl.Y, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B, 255, Font[ctrl.BigFont]); + end; + + procedure r_GUI_Draw_Edit (ctrl: TGUIEdit); + var w, h: Integer; r, g, b: Byte; f: TGLFont; + begin + r_Draw_Texture(EditLeft, ctrl.X, ctrl.Y, EditLeft.width, EditLeft.height, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(EditMiddle, ctrl.X + 8, ctrl.Y, 8 + (ctrl.Width - 1) * 16, EditMiddle.height, false, 255, 255, 255, 255, false); + r_Draw_Texture(EditRight, ctrl.X + 8 + ctrl.Width * 16, ctrl.Y, EditRight.width, EditRight.height, false, 255, 255, 255, 255, false); + r := ctrl.Color.R; + g := ctrl.Color.G; + b := ctrl.Color.B; + if ctrl.Invalid and (ctrl.Window.ActiveControl <> ctrl) then + begin + r := 128; + g := 128; + b := 128; + end; + f := Font[ctrl.BigFont]; + r_Draw_Text(ctrl.Text, ctrl.X + 8, ctrl.Y, r, g, b, 255, f); + if ctrl.Window.ActiveControl = ctrl then + begin + r_Draw_GetTextSize(Copy(ctrl.Text, 1, ctrl.CaretPos), f, w, h); + r_Draw_FillRect(ctrl.X + 8 + w, ctrl.Y + h - 4, ctrl.X + 8 + w + EDIT_CURSORLEN, ctrl.Y + h - 2, 200, 0, 0, 255); + end; + end; + + procedure r_GUI_Draw_KeyRead (ctrl: TGUIKeyRead); + var k: AnsiString; + begin + if ctrl.IsQuery then + k := KEYREAD_QUERY + else if ctrl.Key <> 0 then + k := e_KeyNames[ctrl.Key] + else + k := KEYREAD_CLEAR; + r_Draw_Text(k, ctrl.X, ctrl.Y, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B, 255, Font[ctrl.BigFont]); + end; + + procedure r_GUI_Draw_KeyRead2 (ctrl: TGUIKeyRead2); + + procedure drawText (idx: Integer); + var x, y: Integer; r, g, b: Byte; kk: DWORD; str: AnsiString; + begin + if idx = 0 then kk := ctrl.Key0 else kk := ctrl.Key1; + y := ctrl.Y; + if idx = 0 then x := ctrl.X + 8 else x := ctrl.X + 8 + ctrl.MaxKeyNameWdt + 16; + r := 255; g := 0; b := 0; + if ctrl.KeyIdx = idx then + begin + r := 255; g := 255; b := 255; + end; + if ctrl.IsQuery and (ctrl.KeyIdx = idx) then + str := KEYREAD_QUERY + else if kk <> 0 then + str := e_KeyNames[kk] + else + str := KEYREAD_CLEAR; + r_Draw_Text(str, x, y, r, g, b, 255, Font[ctrl.BigFont]); + end; + + begin + drawText(0); + drawText(1); + end; + + procedure DrawBox (x, y, w, h: Integer); + begin + r_Draw_Texture(Box[0], x, y, 4, 4, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(Box[1], x + 4, y, w * 16, 4, false, 255, 255, 255, 255, false); + r_Draw_Texture(Box[2], x + 4 + w * 16, y, 4, 4, false, 255, 255, 255, 255, false); + + r_Draw_TextureRepeat(Box[3], x, y + 4, 4, h * 16, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(Box[4], x + 4, y + 4, w * 16, h * 16, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(Box[5], x + 4 + w * 16, y + 4, 4, h * 16, false, 255, 255, 255, 255, false); + + r_Draw_Texture(Box[6], x, y + 4 + h * 16, 4, 4, false, 255, 255, 255, 255, false); + r_Draw_TextureRepeat(Box[7], x + 4, y + 4 + h * 16, w * 16, 4, false, 255, 255, 255, 255, false); + r_Draw_Texture(Box[8], x + 4 + w * 16, y + 4 + h * 16, 4, 4, false, 255, 255, 255, 255, false); + end; + + procedure r_GUI_Draw_ModelView (ctrl: TGUIModelView); + begin + DrawBox(ctrl.X, ctrl.Y, 4, 4); + if ctrl.Model <> nil then + r_Map_DrawPlayerModel(ctrl.Model, ctrl.X + 4, ctrl.Y + 4, 255); + end; + + procedure r_GUI_Draw_MapPreview (ctrl: TGUIMapPreview); + var a: Integer; r, g, b: Byte; + begin + DrawBox(ctrl.X, ctrl.Y, MAPPREVIEW_WIDTH, MAPPREVIEW_HEIGHT); + if (ctrl.MapSize.X <= 0) or (ctrl.MapSize.Y <= 0) then + Exit; + r_Draw_FillRect(ctrl.X + 4, ctrl.Y + 4, ctrl.X + 4 + Trunc(ctrl.MapSize.X / ctrl.Scale), ctrl.Y + 4 + Trunc(ctrl.MapSize.Y / ctrl.Scale), 32, 32, 32, 255); + if ctrl.MapData <> nil then + for a := 0 to High(ctrl.MapData) do + with ctrl.MapData[a] do + begin + if X1 > MAPPREVIEW_WIDTH * 16 then Continue; + if Y1 > MAPPREVIEW_HEIGHT * 16 then Continue; + if X2 < 0 then Continue; + if Y2 < 0 then Continue; + if X2 > MAPPREVIEW_WIDTH * 16 then X2 := MAPPREVIEW_WIDTH * 16; + if Y2 > MAPPREVIEW_HEIGHT * 16 then Y2 := MAPPREVIEW_HEIGHT * 16; + if X1 < 0 then X1 := 0; + if Y1 < 0 then Y1 := 0; + case PanelType of + PANEL_WALL: + begin + r := 255; g := 255; b := 255; + end; + PANEL_CLOSEDOOR: + begin + r := 255; g := 255; b := 0; + end; + PANEL_WATER: + begin + r := 0; g := 0; b := 192; + end; + PANEL_ACID1: + begin + r := 0; g := 176; b := 0; + end; + PANEL_ACID2: + begin + r := 176; g := 0; b := 0; + end; + else + r := 128; g := 128; b := 128; + end; + if ((X2 - X1) > 0) and ((Y2 - Y1) > 0) then + r_Draw_FillRect(ctrl.X + 4 + X1, ctrl.Y + 4 + Y1, ctrl.X + 4 + X2, ctrl.Y + 4 + Y2, r, g, b, 255); + end; + end; + + procedure r_GUI_Draw_Image (ctrl: TGUIImage); + var pic: TGLTexture; + begin + pic := nopic; + if ctrl.ImageRes <> '' then + if r_GUI_LoadThis(ctrl.ImageRes, ImageControl) then + pic := ImageControl.id; + if pic <> nil then + r_Draw_Texture(pic, ctrl.x, ctrl.y, pic.width, pic.height, false, 255, 255, 255, 255, false); + end; + + procedure DrawScroll(x, y, h: Integer; Up, Down: Boolean); + var t: TGLTexture; + begin + if h >= 3 then + begin + t := BScrollUp[Up]; + r_Draw_Texture(t, x, y, t.width, t.height, false, 255, 255, 255, 255, false); + t := BScrollDown[Down]; + r_Draw_Texture(t, x, y + (h - 1) * 16, t.width, t.height, false, 255, 255, 255, 255, false); + t := BScrollMiddle; + r_Draw_TextureRepeat(t, x, y + 16, t.width, (h - 2) * 16, false, 255, 255, 255, 255, false); + end; + end; + + procedure r_GUI_Draw_ListBox (ctrl: TGUIListBox); // + TGUIFileListBox + var a, w2, h2: Integer; s: string; col: TRGB; f: TGLFont; + begin + if ctrl.DrawBack then + DrawBox(ctrl.X, ctrl.Y, ctrl.Width + 1, ctrl.Height); + if ctrl.DrawScrollBar then + DrawScroll(ctrl.X + 4 + ctrl.Width * 16, ctrl.Y + 4, ctrl.Height, (ctrl.StartLine > 0) and (ctrl.Items <> nil), (ctrl.StartLine + ctrl.Height - 1 < High(ctrl.Items)) and (ctrl.Items <> nil)); + if ctrl.Items <> nil then + begin + f := Font[ctrl.BigFont]; + for a := ctrl.StartLine to Min(High(ctrl.Items), ctrl.StartLine + ctrl.Height - 1) do + begin + s := ctrl.Items[a]; + r_Draw_GetTextSize(s, f, w2, h2); + while (Length(s) > 0) and (w2 > ctrl.Width * 16) do + begin + SetLength(s, Length(s) - 1); + r_Draw_GetTextSize(s, f, w2, h2); + end; + if a = ctrl.ItemIndex then col := ctrl.ActiveColor else col := ctrl.UnActiveColor; + r_Draw_Text(s, ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, col.r, col.g, col.b, 255, f); + end; + end; + end; + + procedure r_GUI_Draw_Memo (ctrl: TGUIMemo); + var i: Integer; + begin + if ctrl.DrawBack then + DrawBox(ctrl.X, ctrl.Y, ctrl.Width + 1, ctrl.Height); + if ctrl.DrawScrollBar then + DrawScroll(ctrl.X + 4 + ctrl.Width * 16, ctrl.Y + 4, ctrl.Height, (ctrl.StartLine > 0) and (ctrl.Lines <> nil), (ctrl.StartLine + ctrl.Height - 1 < High(ctrl.Lines)) and (ctrl.Lines <> nil)); + if ctrl.Lines <> nil then + for i := ctrl.StartLine to Min(High(ctrl.Lines), ctrl.StartLine + ctrl.Height - 1) do + r_Draw_Text(ctrl.Lines[i], ctrl.X + 4, ctrl.Y + 4 + (i - ctrl.StartLine) * 16, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B, 255, Font[ctrl.BigFont]); + end; + + procedure r_GUI_Draw_MainMenu (ctrl: TGUIMainMenu); + var i, w, h: Integer; ID: TGLTexture; + begin + if ctrl.Header <> nil then + begin + r_GUI_Draw_Label(ctrl.Header) + end + else if LogoTex <> nil then + begin + r_GUI_GetLogoSize(w, h); + r_Draw_Texture(LogoTex, ((gScreenWidth div 2) - (w div 2)), ctrl.Buttons[0].Y - ctrl.Buttons[0].GetHeight - h, w, h, false, 255, 255, 255, 255, false); + end; + if ctrl.Buttons <> nil then + begin + for i := 0 to High(ctrl.Buttons) do + if ctrl.Buttons[i] <> nil then + r_GUI_Draw_TextButton(ctrl.Buttons[i]); + if ctrl.Index <> -1 then + begin + ID := MarkerID[ctrl.Counter DIV MAINMENU_MARKERDELAY MOD 2 <> 0]; + r_Draw_Texture(ID, ctrl.Buttons[ctrl.Index].X - 48, ctrl.Buttons[ctrl.Index].Y, ID.width, ID.height, false, 255, 255, 255, 255, false); + end + end; + end; + + procedure r_GUI_Draw_Menu (ctrl: TGUIMenu); + var a, locx, locy: Integer; f: TGLFont; + begin + if ctrl.Header <> nil then + r_GUI_Draw_Label(ctrl.Header); + if ctrl.Items <> nil then + begin + for a := 0 to High(ctrl.Items) do + begin + if ctrl.Items[a].Text <> nil then + r_GUI_Draw_Control(ctrl.Items[a].Text); + if ctrl.Items[a].Control <> nil then + r_GUI_Draw_Control(ctrl.Items[a].Control); + end; + end; + if (ctrl.Index <> -1) and (ctrl.Counter > MENU_MARKERDELAY div 2) then + begin + locx := 0; + locy := 0; + if ctrl.Items[ctrl.Index].Text <> nil then + begin + locx := ctrl.Items[ctrl.Index].Text.X; + locy := ctrl.Items[ctrl.Index].Text.Y; + //HACK! + if ctrl.Items[ctrl.Index].Text.RightAlign then + begin + locx := locx + ctrl.Items[ctrl.Index].Text.CMaxWidth - ctrl.Items[ctrl.Index].Text.GetWidth; + end; + end + else if ctrl.Items[ctrl.Index].Control <> nil then + begin + locx := ctrl.Items[ctrl.Index].Control.X; + locy := ctrl.Items[ctrl.Index].Control.Y; + end; + f := Font[ctrl.BigFont]; + locx := locx - f.GetMaxWidth(); + r_Draw_Text(#16, locx, locy, 255, 0, 0, 255, f); + end; + end; + + procedure r_GUI_Draw_Control (ctrl: TGUIControl); + begin + if ctrl is TGUITextButton then + r_GUI_Draw_TextButton(TGUITextButton(ctrl)) + else if ctrl is TGUILabel then + r_GUI_Draw_Label(TGUILabel(ctrl)) + else if ctrl is TGUIScroll then + r_GUI_Draw_Scroll(TGUIScroll(ctrl)) + else if ctrl is TGUISwitch then + r_GUI_Draw_Switch(TGUISwitch(ctrl)) + else if ctrl is TGUIEdit then + r_GUI_Draw_Edit(TGUIEdit(ctrl)) + else if ctrl is TGUIKeyRead then + r_GUI_Draw_KeyRead(TGUIKeyRead(ctrl)) + else if ctrl is TGUIKeyRead2 then + r_GUI_Draw_KeyRead2(TGUIKeyRead2(ctrl)) + else if ctrl is TGUIModelView then + r_GUI_Draw_ModelView(TGUIModelView(ctrl)) + else if ctrl is TGUIMapPreview then + r_GUI_Draw_MapPreview(TGUIMapPreview(ctrl)) + else if ctrl is TGUIImage then + r_GUI_Draw_Image(TGUIImage(ctrl)) + else if ctrl is TGUIListBox then + r_GUI_Draw_ListBox(TGUIListBox(ctrl)) // + TGUIFileListBox + else if ctrl is TGUIMemo then + r_GUI_Draw_Memo(TGUIMemo(ctrl)) + else if ctrl is TGUIMainMenu then + r_GUI_Draw_MainMenu(TGUIMainMenu(ctrl)) + else if ctrl is TGUIMenu then + r_GUI_Draw_Menu(TGUIMenu(ctrl)) + else + Assert(False) + end; + + procedure r_GUI_Draw_Window (win: TGUIWindow); + var i, tw, th: Integer; + begin + // Here goes code duplication from g_game.pas:DrawMenuBackground() + if win.BackTexture <> '' then + if r_GUI_LoadThis(win.BackTexture, Background) then + begin + r_Draw_FillRect(0, 0, gScreenWidth - 1, gScreenHeight - 1, 0, 0, 0, 255); + tw := Background.id.width; + th := Background.id.height; + if tw = th then + tw := round(tw * 1.333 * (gScreenHeight / th)) + else + tw := trunc(tw * (gScreenHeight / th)); + r_Draw_Texture(Background.id, (gScreenWidth - tw) div 2, 0, tw, gScreenHeight, false, 255, 255, 255, 255, false); + end + else + r_Draw_FillRect(0, 0, gScreenWidth - 1, gScreenHeight - 1, 127, 127, 127, 255); + + // small hack here + if win.Name = 'AuthorsMenu' then + r_Draw_FillRect(0, 0, gScreenWidth - 1, gScreenHeight - 1, 0, 0, 0, 105); + for i := 0 to High(win.Childs) do + if win.Childs[i] <> nil then + r_GUI_Draw_Control(win.Childs[i]); + end; + +end. diff --git a/src/game/renders/opengl/r_map.pas b/src/game/renders/opengl/r_map.pas index 11be032..4f0621d 100644 --- a/src/game/renders/opengl/r_map.pas +++ b/src/game/renders/opengl/r_map.pas @@ -17,7 +17,7 @@ unit r_map; interface - uses g_base, g_player; // TRectWH, TPlayer + uses g_base, g_player, g_playermodel; // TRectWH, TPlayer, TPlayerModel procedure r_Map_Initialize; procedure r_Map_Finalize; @@ -34,6 +34,10 @@ interface {$IFDEF ENABLE_GIBS} function r_Map_GetGibSize (m, i: Integer): TRectWH; {$ENDIF} +{$IFDEF ENABLE_MENU} + procedure r_Map_DrawPlayerModel (pm: TPlayerModel; x, y: Integer; alpha: Byte); +{$ENDIF} + procedure r_Map_Update; @@ -51,7 +55,7 @@ implementation e_log, binheap, MAPDEF, utils, g_options, g_textures, g_basic, g_phys, - g_game, g_map, g_panel, g_items, g_monsters, g_playermodel, g_weapons, + g_game, g_map, g_panel, g_items, g_monsters, g_weapons, {$IFDEF ENABLE_CORPSES} g_corpses, {$ENDIF} @@ -1221,7 +1225,6 @@ implementation end; procedure r_Map_DrawScreenEffects (x, y, w, h: Integer; p: TPlayer); - var i: Integer; begin if p <> nil then begin diff --git a/src/game/renders/opengl/r_render.pas b/src/game/renders/opengl/r_render.pas index be9192d..6e9b96c 100644 --- a/src/game/renders/opengl/r_render.pas +++ b/src/game/renders/opengl/r_render.pas @@ -74,6 +74,9 @@ implementation {$ELSE} GL, GLEXT, {$ENDIF} + {$IFDEF ENABLE_MENU} + r_gui, + {$ENDIF} {$IFDEF ENABLE_SYSTEM} g_system, {$ENDIF} @@ -81,7 +84,7 @@ implementation e_log, utils, g_game, g_options, g_console, g_player, g_weapons, g_language, g_net, - r_draw, r_textures, r_fonts, r_map + r_draw, r_textures, r_fonts, r_common, r_map ; type @@ -94,10 +97,6 @@ implementation var menuBG: TGLTexture; - stdfont: TGLFont; - smallfont: TGLFont; - menufont: TGLFont; - hud, hudbg: TGLTexture; hudhp: array [Boolean] of TGLTexture; hudap: TGLTexture; @@ -116,27 +115,14 @@ implementation r_Map_FreeTextures; end; - function r_Render_LoadFont (const name: AnsiString): TGLFont; - var info: TFontInfo; skiphack: Integer; - begin - result := nil; - if name = 'STD' then skiphack := 144 else skiphack := 0; - if r_Font_LoadInfoFromFile(GameWad + ':FONTS/' + name + 'TXT', info) then - result := r_Textures_LoadFontFromFile(GameWad + ':FONTS/' + name + 'FONT', info, skiphack, true); - if result = nil then - e_logwritefln('failed to load font %s', [name]); - end; - procedure r_Render_Load; const WeapName: array [0..WP_LAST] of AnsiString = ('KASTET', 'SAW', 'PISTOL', 'SHOTGUN1', 'SHOTGUN2', 'MGUN', 'RLAUNCHER', 'PGUN', 'BFG', 'SPULEMET', 'FLAMETHROWER'); var i: Integer; begin + r_Common_Load; menuBG := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/TITLE'); - stdfont := r_Render_LoadFont('STD'); - smallfont := r_Render_LoadFont('SMALL'); - menufont := r_Render_LoadFont('MENU'); hud := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/HUD'); hudbg := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/HUDBG'); hudhp[false] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/MED2'); @@ -150,11 +136,17 @@ implementation hudair := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/AIRBAR'); hudjet := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/JETBAR'); r_Map_Load; + {$IFDEF ENABLE_MENU} + r_GUI_Load; + {$ENDIF} end; procedure r_Render_Free; var i: Integer; begin + {$IFDEF ENABLE_MENU} + r_GUI_Free; + {$ENDIF} r_Map_Free; hudjet.Free; hudair.Free; @@ -172,10 +164,8 @@ implementation hudhp[false].Free; hudbg.Free; hud.Free; - menufont.Free; - smallfont.Free; - stdfont.Free; menuBG.Free; + r_Common_Free; end; {$IFDEF ENABLE_SYSTEM} @@ -407,7 +397,9 @@ implementation {$IFDEF ENABLE_MENU} if g_ActiveWindow <> nil then begin - // TODO draw menu widgets + if gGameOn then + r_Draw_FillRect(0, 0, gScreenWidth - 1, gScreenHeight - 1, 0, 0, 0, 105); + r_GUI_Draw_Window(g_ActiveWindow); end; {$ENDIF} @@ -470,22 +462,22 @@ implementation {$IFDEF ENABLE_MENU} procedure r_Render_GetControlSize (ctrl: TGUIControl; out w, h: Integer); begin - w := 0; h := 0; + r_GUI_GetSize(ctrl, w, h); end; procedure r_Render_GetLogoSize (out w, h: Integer); begin - w := 0; h := 0; + r_GUI_GetLogoSize(w, h); end; procedure r_Render_GetMaxFontSize (BigFont: Boolean; out w, h: Integer); begin - w := 0; h := 0; + r_GUI_GetMaxFontSize(BigFont, w, h); end; procedure r_Render_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer); begin - w := 0; h := 0; + r_GUI_GetStringSize(BigFont, str, w, h); end; {$ENDIF} diff --git a/src/game/renders/opengl/r_textures.pas b/src/game/renders/opengl/r_textures.pas index b51afd2..8df881a 100644 --- a/src/game/renders/opengl/r_textures.pas +++ b/src/game/renders/opengl/r_textures.pas @@ -111,6 +111,7 @@ interface destructor Destroy; override; function GetChar (c: AnsiChar): TGLTexture; function GetWidth (c: AnsiChar): Integer; + function GetMaxWidth (): Integer; function GetMaxHeight (): Integer; function GetSpace (): Integer; end; @@ -780,6 +781,13 @@ implementation result := self.info.w; end; + function TGLFont.GetMaxWidth (): Integer; + begin + result := self.info.w; + if self.info.kern < 0 then + result := result + self.info.kern; + end; + function TGLFont.GetMaxHeight (): Integer; begin result := self.info.h; -- 2.29.2