X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_gui.pas;h=48700f74e782969b9b562b2f54250ca4d874e527;hb=921c3b45ee6dd3b39307f4d1d6c05ab1c137bd49;hp=34436a6458ed56d0239f25fb459586e591e1c41d;hpb=88ce644db1b40111bdb380f4357fa59bdb5173be;p=d2df-sdl.git diff --git a/src/game/g_gui.pas b/src/game/g_gui.pas index 34436a6..48700f7 100644 --- a/src/game/g_gui.pas +++ b/src/game/g_gui.pas @@ -1,9 +1,25 @@ +(* 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 . + *) +{$MODE DELPHI} unit g_gui; interface uses - e_graphics, e_input, g_playermodel, g_basic, MAPSTRUCT, WADEDITOR; + e_graphics, e_input, g_playermodel, g_basic, MAPSTRUCT, wadreader; const MAINMENU_HEADER_COLOR: TRGB = (R:255; G:255; B:255); @@ -65,7 +81,7 @@ type wParam: LongInt; lParam: LongInt; end; - + TFontType = (FONT_TEXTURE, FONT_CHAR); TFont = class(TObject) @@ -82,31 +98,33 @@ type end; TGUIControl = class; + TGUIWindow = class; TOnKeyDownEvent = procedure(Key: Byte); + TOnKeyDownEventEx = procedure(win: TGUIWindow; Key: Byte); TOnCloseEvent = procedure; TOnShowEvent = procedure; TOnClickEvent = procedure; TOnChangeEvent = procedure(Sender: TGUIControl); TOnEnterEvent = procedure(Sender: TGUIControl); - TGUIWindow = class; - TGUIControl = class private FX, FY: Integer; FEnabled: Boolean; FWindow : TGUIWindow; FName: string; + FUserData: Pointer; public constructor Create; procedure OnMessage(var Msg: TMessage); virtual; procedure Update; virtual; - procedure Draw; virtual; + procedure Draw; virtual; property X: Integer read FX write FX; property Y: Integer read FY write FY; property Enabled: Boolean read FEnabled write FEnabled; property Name: string read FName write FName; + property UserData: Pointer read FUserData write FUserData; end; TGUIWindow = class @@ -118,8 +136,10 @@ type FBackTexture: string; FMainWindow: Boolean; FOnKeyDown: TOnKeyDownEvent; + FOnKeyDownEx: TOnKeyDownEventEx; FOnCloseEvent: TOnCloseEvent; FOnShowEvent: TOnShowEvent; + FUserData: Pointer; public Childs: array of TGUIControl; constructor Create(Name: string); @@ -131,12 +151,14 @@ type procedure SetActive(Control: TGUIControl); function GetControl(Name: string): TGUIControl; property OnKeyDown: TOnKeyDownEvent read FOnKeyDown write FOnKeyDown; + property OnKeyDownEx: TOnKeyDownEventEx read FOnKeyDownEx write FOnKeyDownEx; property OnClose: TOnCloseEvent read FOnCloseEvent write FOnCloseEvent; property OnShow: TOnShowEvent read FOnShowEvent write FOnShowEvent; property Name: string read FName; property DefControl: string read FDefControl write FDefControl; property BackTexture: string read FBackTexture write FBackTexture; property MainWindow: Boolean read FMainWindow write FMainWindow; + property UserData: Pointer read FUserData write FUserData; end; TGUITextButton = class(TGUIControl) @@ -148,6 +170,7 @@ type FShowWindow: string; public Proc: procedure; + ProcEx: procedure (sender: TGUITextButton); constructor Create(Proc: Pointer; FontID: DWORD; Text: string); destructor Destroy(); override; procedure OnMessage(var Msg: TMessage); override; @@ -447,6 +470,7 @@ type FCounter: Byte; FAlign: Boolean; FLeft: Integer; + FYesNo: Boolean; function NewItem(): Integer; public constructor Create(HeaderFont, ItemsFont: DWORD; Header: string); @@ -472,6 +496,7 @@ type procedure UpdateIndex(); property Align: Boolean read FAlign write FAlign; property Left: Integer read FLeft write FLeft; + property YesNo: Boolean read FYesNo write FYesNo; end; var @@ -713,6 +738,7 @@ begin FActiveControl := nil; FName := Name; FOnKeyDown := nil; + FOnKeyDownEx := nil; FOnCloseEvent := nil; FOnShowEvent := nil; end; @@ -765,6 +791,7 @@ procedure TGUIWindow.OnMessage(var Msg: TMessage); begin if FActiveControl <> nil then FActiveControl.OnMessage(Msg); if @FOnKeyDown <> nil then FOnKeyDown(Msg.wParam); + if @FOnKeyDownEx <> nil then FOnKeyDownEx(self, Msg.wParam); if Msg.Msg = WM_KEYDOWN then if Msg.wParam = IK_ESCAPE then @@ -827,13 +854,12 @@ end; procedure TGUITextButton.Click(Silent: Boolean = False); begin - if (FSound <> '') and (not Silent) then - g_Sound_PlayEx(FSound); + if (FSound <> '') and (not Silent) then g_Sound_PlayEx(FSound); - if @Proc <> nil then - Proc(); - if FShowWindow <> '' then - g_GUI_ShowWindow(FShowWindow); + if @Proc <> nil then Proc(); + if @ProcEx <> nil then ProcEx(self); + + if FShowWindow <> '' then g_GUI_ShowWindow(FShowWindow); end; constructor TGUITextButton.Create(Proc: Pointer; FontID: DWORD; Text: string); @@ -841,6 +867,7 @@ begin inherited Create(); Self.Proc := Proc; + ProcEx := nil; FFont := TFont.Create(FontID, FONT_CHAR); @@ -883,7 +910,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_RETURN: Click(); + IK_RETURN, IK_KPRETURN: Click(); end; end; end; @@ -912,7 +939,7 @@ end; procedure TFont.Draw(X, Y: Integer; Text: string; R, G, B: Byte); begin if FFontType = FONT_CHAR then e_CharFont_PrintEx(ID, X, Y, Text, _RGB(R, G, B), FScale) - else e_TextureFontPrintEx(X, Y, Text, ID, R, G, B, FScale); + else e_TextureFontPrintEx(X, Y, Text, ID, R, G, B, FScale); end; procedure TFont.GetTextSize(Text: string; var w, h: Word); @@ -999,7 +1026,7 @@ begin FCounter := MAINMENU_MARKERDELAY; g_Texture_Get(MAINMENU_MARKER1, FMarkerID1); - g_Texture_Get(MAINMENU_MARKER2, FMarkerID2); + g_Texture_Get(MAINMENU_MARKER2, FMarkerID2); FHeader := TGUILabel.Create(Header, FFontID); with FHeader do @@ -1037,7 +1064,7 @@ begin if FButtons[a] <> nil then FButtons[a].Draw; if FIndex <> -1 then - e_Draw(FMarkerID1, FButtons[FIndex].FX-48, FButtons[FIndex].FY, 0, True, False); + e_Draw(FMarkerID1, FButtons[FIndex].FX-48, FButtons[FIndex].FY, 0, True, False); end; end; @@ -1097,7 +1124,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_UP: + IK_UP, IK_KPUP: begin repeat Dec(FIndex); @@ -1106,7 +1133,7 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_DOWN: + IK_DOWN, IK_KPDOWN: begin repeat Inc(FIndex); @@ -1115,7 +1142,7 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_RETURN: if (FIndex <> -1) and FButtons[FIndex].FEnabled then FButtons[FIndex].Click; + IK_RETURN, IK_KPRETURN: if (FIndex <> -1) and FButtons[FIndex].FEnabled then FButtons[FIndex].Click; end; end; end; @@ -1142,7 +1169,7 @@ constructor TGUILabel.Create(Text: string; FontID: DWORD); begin inherited Create(); - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, FONT_CHAR); FText := Text; FFixedLen := 0; @@ -1169,8 +1196,8 @@ begin if FFixedLen = 0 then FFont.GetTextSize(FText, w, h) else - w := e_CharFont_GetMaxWidth(FFont.ID)*FFixedLen; - Result := w; + w := e_CharFont_GetMaxWidth(FFont.ID)*FFixedLen; + Result := w; end; procedure TGUILabel.OnMessage(var Msg: TMessage); @@ -1182,7 +1209,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_RETURN: if @FOnClickEvent <> nil then FOnClickEvent(); + IK_RETURN, IK_KPRETURN: if @FOnClickEvent <> nil then FOnClickEvent(); end; end; end; @@ -1248,9 +1275,13 @@ begin with FItems[i] do begin Text := TGUILabel.Create(l[a], FFontID); - with Text do + if FYesNo then begin - FColor := MENU_ITEMSTEXT_COLOR; + with Text do begin FColor := _RGB(255, 0, 0); end; + end + else + begin + with Text do begin FColor := MENU_ITEMSTEXT_COLOR; end; end; Control := nil; @@ -1283,6 +1314,7 @@ begin FFontID := ItemsFont; FCounter := MENU_MARKERDELAY; FAlign := True; + FYesNo := false; FHeader := TGUILabel.Create(Header, HeaderFont); with FHeader do @@ -1343,9 +1375,9 @@ begin y := FItems[FIndex].Control.FY; end; - x := x-e_CharFont_GetMaxWidth(FFontID); + x := x-e_CharFont_GetMaxWidth(FFontID); - e_CharFont_PrintEx(FFontID, x, y, #16, _RGB(255, 0, 0)); + e_CharFont_PrintEx(FFontID, x, y, #16, _RGB(255, 0, 0)); end; end; @@ -1416,7 +1448,7 @@ begin WM_KEYDOWN: begin case Msg.wParam of - IK_UP: + IK_UP, IK_KPUP: begin c := 0; repeat @@ -1437,7 +1469,7 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_DOWN: + IK_DOWN, IK_KPDOWN: begin c := 0; repeat @@ -1458,20 +1490,35 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_LEFT, IK_RIGHT: + IK_LEFT, IK_RIGHT, IK_KPLEFT, IK_KPRIGHT: begin if FIndex <> -1 then if FItems[FIndex].Control <> nil then FItems[FIndex].Control.OnMessage(Msg); end; - IK_RETURN: + IK_RETURN, IK_KPRETURN: begin if FIndex <> -1 then - if FItems[FIndex].Control <> nil then - FItems[FIndex].Control.OnMessage(Msg); - + begin + if FItems[FIndex].Control <> nil then FItems[FIndex].Control.OnMessage(Msg); + end; g_Sound_PlayEx(MENU_CLICKSOUND); end; + // dirty hacks + IK_Y: + if FYesNo and (length(FItems) > 1) then + begin + Msg.wParam := IK_RETURN; // to register keypress + FIndex := High(FItems)-1; + if FItems[FIndex].Control <> nil then FItems[FIndex].Control.OnMessage(Msg); + end; + IK_N: + if FYesNo and (length(FItems) > 1) then + begin + Msg.wParam := IK_RETURN; // to register keypress + FIndex := High(FItems); + if FItems[FIndex].Control <> nil then FItems[FIndex].Control.OnMessage(Msg); + end; end; end; end; @@ -1520,21 +1567,22 @@ begin cx := 0; for a := 0 to High(FItems) do + begin with FItems[a] do begin if (Text <> nil) and (Control = nil) then Continue; - w := 0; if Text <> nil then w := tx+Text.GetWidth; - if w > cx then cx := w; end; + end; cx := cx+MENU_HSPACE; h := FHeader.GetHeight*2+MENU_VSPACE*(Length(FItems)-1); for a := 0 to High(FItems) do + begin with FItems[a] do begin if (ControlType = TGUIListBox) or (ControlType = TGUIFileListBox) then @@ -1542,6 +1590,7 @@ begin else h := h+e_CharFont_GetMaxHeight(FFontID); end; + end; h := (gScreenHeight div 2)-(h div 2); @@ -1583,6 +1632,30 @@ begin else Inc(h, e_CharFont_GetMaxHeight(FFontID)+MENU_VSPACE); end; + + // another ugly hack + if FYesNo and (length(FItems) > 1) then + begin + w := -1; + for a := High(FItems)-1 to High(FItems) do + begin + if (FItems[a].Control <> nil) and (FItems[a].ControlType = TGUITextButton) then + begin + cx := (FItems[a].Control as TGUITextButton).GetWidth; + if cx > w then w := cx; + end; + end; + if w > 0 then + begin + for a := High(FItems)-1 to High(FItems) do + begin + if (FItems[a].Control <> nil) and (FItems[a].ControlType = TGUITextButton) then + begin + FItems[a].Control.FX := (gScreenWidth-w) div 2; + end; + end; + end; + end; end; function TGUIMenu.AddScroll(fText: string): TGUIScroll; @@ -1903,14 +1976,14 @@ begin WM_KEYDOWN: begin case Msg.wParam of - IK_LEFT: + IK_LEFT, IK_KPLEFT: if FValue > 0 then begin Dec(FValue); g_Sound_PlayEx(SCROLL_SUBSOUND); if @FOnChangeEvent <> nil then FOnChangeEvent(Self); end; - IK_RIGHT: + IK_RIGHT, IK_KPRIGHT: if FValue < FMax then begin Inc(FValue); @@ -1987,7 +2060,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_RETURN, IK_RIGHT: + IK_RETURN, IK_RIGHT, IK_KPRETURN, IK_KPRIGHT: begin if FIndex < High(FItems) then Inc(FIndex) @@ -1998,7 +2071,7 @@ begin FOnChangeEvent(Self); end; - IK_LEFT: + IK_LEFT, IK_KPLEFT: begin if FIndex > 0 then Dec(FIndex) @@ -2097,11 +2170,11 @@ begin if FCaretPos > 0 then Dec(FCaretPos); end; IK_DELETE: Delete(FText, FCaretPos + 1, 1); - IK_END: FCaretPos := Length(FText); - IK_HOME: FCaretPos := 0; - IK_LEFT: if FCaretPos > 0 then Dec(FCaretPos); - IK_RIGHT: if FCaretPos < Length(FText) then Inc(FCaretPos); - IK_RETURN: + IK_END, IK_KPEND: FCaretPos := Length(FText); + IK_HOME, IK_KPHOME: FCaretPos := 0; + IK_LEFT, IK_KPLEFT: if FCaretPos > 0 then Dec(FCaretPos); + IK_RIGHT, IK_KPRIGHT: if FCaretPos < Length(FText) then Inc(FCaretPos); + IK_RETURN, IK_KPRETURN: with FWindow do begin if FActiveControl <> Self then @@ -2155,7 +2228,7 @@ var w, h: Word; begin Result := 0; - + for a := 0 to 255 do begin FFont.GetTextSize(e_KeyNames[a], w, h); @@ -2191,7 +2264,7 @@ begin FIsQuery := False; end; - IK_RETURN: + IK_RETURN, IK_KPRETURN: begin if not FIsQuery then begin @@ -2205,18 +2278,18 @@ begin begin FKey := IK_ENTER; // FIsQuery := False; - + with FWindow do if FDefControl <> '' then SetActive(GetControl(FDefControl)) else SetActive(nil); - end; + end; end; end; MESSAGE_DIKEY: - if FIsQuery and (wParam <> IK_ENTER) then // Not IK_ENTER) and (wParam <> IK_KPRETURN) then // Not '' then FKey := wParam; @@ -2253,7 +2326,7 @@ begin DrawBox(FX, FY, 4, 4); - if FModel <> nil then FModel.Draw(FX+4, FY+4); + if FModel <> nil then FModel.Draw(FX+4, FY+4); end; procedure TGUIModelView.NextAnim(); @@ -2286,7 +2359,7 @@ end; procedure TGUIModelView.SetColor(Red, Green, Blue: Byte); begin - if FModel <> nil then FModel.SetColor(Red, Green, Blue); + if FModel <> nil then FModel.SetColor(Red, Green, Blue); end; procedure TGUIModelView.SetModel(ModelName: string); @@ -2302,7 +2375,7 @@ begin a := not a; if a then Exit; - + if FModel <> nil then FModel.Update; end; @@ -2335,7 +2408,7 @@ begin e_DrawFillQuad(FX+4, FY+4, FX+4 + Trunc(FMapSize.X / FScale) - 1, FY+4 + Trunc(FMapSize.Y / FScale) - 1, - 32, 32, 32, 0); + 32, 32, 32, 0); if FMapData <> nil then for a := 0 to High(FMapData) do @@ -2346,7 +2419,7 @@ begin 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; @@ -2406,26 +2479,27 @@ end; procedure TGUIMapPreview.SetMap(Res: string); var - WAD: TWADEditor_1; + WAD: TWADFile; MapReader: TMapReader_1; panels: TPanelsRec1Array; header: TMapHeaderRec_1; a: Integer; - FileName, SectionName, ResName: string; + FileName: string; Data: Pointer; Len: Integer; rX, rY: Single; begin - g_ProcessResourceStr(Res, FileName, SectionName, ResName); + FileName := g_ExtractWadName(Res); - WAD := TWADEditor_1.Create(); + WAD := TWADFile.Create(); if not WAD.ReadFile(FileName) then begin WAD.Free(); Exit; end; - if not WAD.GetResource('', ResName, Data, Len) then + //k8: ignores path again + if not WAD.GetMapResource(g_ExtractFileName(Res), Data, Len) then begin WAD.Free(); Exit; @@ -2593,12 +2667,12 @@ end; function TGUIListBox.GetHeight: Word; begin - Result := 8+FHeight*16; + Result := 8+FHeight*16; end; function TGUIListBox.GetWidth: Word; begin - Result := 8+(FWidth+1)*16; + Result := 8+(FWidth+1)*16; end; procedure TGUIListBox.OnMessage(var Msg: TMessage); @@ -2615,31 +2689,31 @@ begin case Msg of WM_KEYDOWN: case wParam of - IK_HOME: + IK_HOME, IK_KPHOME: begin FIndex := 0; FStartLine := 0; end; - IK_END: + IK_END, IK_KPEND: begin FIndex := High(FItems); FStartLine := Max(High(FItems)-FHeight+1, 0); end; - IK_UP, IK_LEFT: + IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT: if FIndex > 0 then begin Dec(FIndex); if FIndex < FStartLine then Dec(FStartLine); if @FOnChangeEvent <> nil then FOnChangeEvent(Self); end; - IK_DOWN, IK_RIGHT: + IK_DOWN, IK_RIGHT, IK_KPDOWN, IK_KPRIGHT: if FIndex < High(FItems) then begin Inc(FIndex); if FIndex > FStartLine+FHeight-1 then Inc(FStartLine); if @FOnChangeEvent <> nil then FOnChangeEvent(Self); end; - IK_RETURN: + IK_RETURN, IK_KPRETURN: with FWindow do begin if FActiveControl <> Self then SetActive(Self) @@ -2675,7 +2749,7 @@ procedure TGUIListBox.FSetItems(Items: SArray); begin if FItems <> nil then FItems := nil; - + FItems := Items; FStartLine := 0; @@ -2739,7 +2813,7 @@ begin case Msg of WM_KEYDOWN: case wParam of - IK_HOME: + IK_HOME, IK_KPHOME: begin FIndex := 0; FStartLine := 0; @@ -2747,7 +2821,7 @@ begin FOnChangeEvent(Self); end; - IK_END: + IK_END, IK_KPEND: begin FIndex := High(FItems); FStartLine := Max(High(FItems)-FHeight+1, 0); @@ -2755,7 +2829,7 @@ begin FOnChangeEvent(Self); end; - IK_PAGEUP: + IK_PAGEUP, IK_KPPAGEUP: begin if FIndex > FHeight then FIndex := FIndex-FHeight @@ -2768,7 +2842,7 @@ begin FStartLine := 0; end; - IK_PAGEDN: + IK_PAGEDN, IK_KPPAGEDN: begin if FIndex < High(FItems)-FHeight then FIndex := FIndex+FHeight @@ -2781,7 +2855,7 @@ begin FStartLine := High(FItems)-FHeight+1; end; - IK_UP, IK_LEFT: + IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT: if FIndex > 0 then begin Dec(FIndex); @@ -2791,7 +2865,7 @@ begin FOnChangeEvent(Self); end; - IK_DOWN, IK_RIGHT: + IK_DOWN, IK_RIGHT, IK_KPDOWN, IK_KPRIGHT: if FIndex < High(FItems) then begin Inc(FIndex); @@ -2801,7 +2875,7 @@ begin FOnChangeEvent(Self); end; - IK_RETURN: + IK_RETURN, IK_KPRETURN: with FWindow do begin if FActiveControl <> Self then @@ -2844,13 +2918,14 @@ procedure TGUIFileListBox.OpenDir(path: String); var SR: TSearchRec; i: Integer; + sm, sc: string; begin Clear(); path := IncludeTrailingPathDelimiter(path); path := ExpandFileName(path); -// Êàòàëîãè: + // Êàòàëîãè: if FDirs then begin if FindFirst(path+'*', faDirectory, SR) = 0 then @@ -2867,13 +2942,17 @@ begin FindClose(SR); end; -// Ôàéëû: - if FindFirst(path+FFileMask, faAnyFile, SR) = 0 then - repeat - AddItem(SR.Name); - until FindNext(SR) <> 0; - - FindClose(SR); + // Ôàéëû: + sm := FFileMask; + while sm <> '' do + begin + i := Pos('|', sm); + if i = 0 then i := length(sm)+1; + sc := Copy(sm, 1, i-1); + Delete(sm, 1, i); + if FindFirst(path+sc, faAnyFile, SR) = 0 then repeat AddItem(SR.Name); until FindNext(SR) <> 0; + FindClose(SR); + end; for i := 0 to High(FItems) do if FItems[i][1] = #1 then @@ -2907,7 +2986,7 @@ var begin if (FIndex = -1) or (FItems = nil) or (FIndex > High(FItems)) or - (FItems[FIndex][1] = '/') or + (FItems[FIndex][1] = '/') or (FItems[FIndex][1] = '\') then fn := '' else @@ -2977,13 +3056,13 @@ begin case Msg of WM_KEYDOWN: case wParam of - IK_UP, IK_LEFT: + IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT: if FStartLine > 0 then Dec(FStartLine); - IK_DOWN, IK_RIGHT: + IK_DOWN, IK_RIGHT, IK_KPDOWN, IK_KPRIGHT: if FStartLine < Length(FLines)-FHeight then Inc(FStartLine); - IK_RETURN: + IK_RETURN, IK_KPRETURN: with FWindow do begin if FActiveControl <> Self then @@ -3034,7 +3113,7 @@ begin inherited; if FImageRes = '' then - begin + begin if g_Texture_Get(FDefaultRes, ID) then e_Draw(ID, FX, FY, 0, True, False); end else