X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_gui.pas;h=a76a1801f560969bd0ab491f9dca790cc7565c3f;hb=cabbec9701799f82a1d1bde30cb6e235fe7a74a4;hp=34436a6458ed56d0239f25fb459586e591e1c41d;hpb=88ce644db1b40111bdb380f4357fa59bdb5173be;p=d2df-sdl.git diff --git a/src/game/g_gui.pas b/src/game/g_gui.pas index 34436a6..a76a180 100644 --- a/src/game/g_gui.pas +++ b/src/game/g_gui.pas @@ -1,9 +1,26 @@ +(* 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_gui; interface uses - e_graphics, e_input, g_playermodel, g_basic, MAPSTRUCT, WADEDITOR; + {$IFDEF USE_MEMPOOL}mempool,{$ENDIF} + e_graphics, e_input, e_log, g_playermodel, g_basic, g_touch, MAPDEF, utils; const MAINMENU_HEADER_COLOR: TRGB = (R:255; G:255; B:255); @@ -65,10 +82,10 @@ type wParam: LongInt; lParam: LongInt; end; - - TFontType = (FONT_TEXTURE, FONT_CHAR); - TFont = class(TObject) + TFontType = (Texture, Character); + + TFont = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private ID: DWORD; FScale: Single; @@ -82,34 +99,42 @@ 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 + TGUIControl = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private FX, FY: Integer; FEnabled: Boolean; FWindow : TGUIWindow; FName: string; + FUserData: Pointer; + FRightAlign: Boolean; //HACK! this works only for "normal" menus, only for menu text labels, and generally sux. sorry. + FMaxWidth: Integer; //HACK! used for right-aligning labels public constructor Create; procedure OnMessage(var Msg: TMessage); virtual; procedure Update; virtual; - procedure Draw; virtual; + procedure Draw; virtual; + function GetWidth(): Integer; virtual; + function GetHeight(): Integer; virtual; + function WantActivationKey (key: LongInt): Boolean; 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; + property RightAlign: Boolean read FRightAlign write FRightAlign; // for menu end; - TGUIWindow = class + TGUIWindow = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF} private FActiveControl: TGUIControl; FDefControl: string; @@ -118,8 +143,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 +158,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,13 +177,14 @@ type FShowWindow: string; public Proc: procedure; - constructor Create(Proc: Pointer; FontID: DWORD; Text: string); + ProcEx: procedure (sender: TGUITextButton); + constructor Create(aProc: Pointer; FontID: DWORD; Text: string); destructor Destroy(); override; procedure OnMessage(var Msg: TMessage); override; procedure Update(); override; procedure Draw(); override; - function GetWidth(): Integer; - function GetHeight(): Integer; + function GetWidth(): Integer; override; + function GetHeight(): Integer; override; procedure Click(Silent: Boolean = False); property Caption: string read FText write FText; property Color: TRGB read FColor write FColor; @@ -173,8 +203,8 @@ type constructor Create(Text: string; FontID: DWORD); procedure OnMessage(var Msg: TMessage); override; procedure Draw; override; - function GetWidth: Integer; - function GetHeight: Integer; + function GetWidth: Integer; override; + function GetHeight: Integer; override; property OnClick: TOnClickEvent read FOnClickEvent write FOnClickEvent; property FixedLength: Word read FFixedLen write FFixedLen; property Text: string read FText write FText; @@ -197,7 +227,7 @@ type procedure OnMessage(var Msg: TMessage); override; procedure Update; override; procedure Draw; override; - function GetWidth(): Word; + function GetWidth(): Integer; override; property OnChange: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent; property Max: Word read FMax write FMax; property Value: Integer read FValue write FSetValue; @@ -216,7 +246,7 @@ type procedure AddItem(Item: string); procedure Update; override; procedure Draw; override; - function GetWidth(): Word; + function GetWidth(): Integer; override; function GetText: string; property ItemIndex: Integer read FIndex write FIndex; property Color: TRGB read FColor write FColor; @@ -238,13 +268,14 @@ type FMiddleID: DWORD; FOnChangeEvent: TOnChangeEvent; FOnEnterEvent: TOnEnterEvent; + FInvalid: Boolean; procedure SetText(Text: string); public constructor Create(FontID: DWORD); procedure OnMessage(var Msg: TMessage); override; procedure Update; override; procedure Draw; override; - function GetWidth(): Word; + function GetWidth(): Integer; override; property OnChange: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent; property OnEnter: TOnEnterEvent read FOnEnterEvent write FOnEnterEvent; property Width: Word read FWidth write FWidth; @@ -253,6 +284,7 @@ type property Text: string read FText write SetText; property Color: TRGB read FColor write FColor; property Font: TFont read FFont write FFont; + property Invalid: Boolean read FInvalid write FInvalid; end; TGUIKeyRead = class(TGUIControl) @@ -265,12 +297,35 @@ type constructor Create(FontID: DWORD); procedure OnMessage(var Msg: TMessage); override; procedure Draw; override; - function GetWidth(): Word; + function GetWidth(): Integer; override; + function WantActivationKey (key: LongInt): Boolean; override; property Key: Word read FKey write FKey; property Color: TRGB read FColor write FColor; property Font: TFont read FFont write FFont; end; + // can hold two keys + TGUIKeyRead2 = class(TGUIControl) + private + FFont: TFont; + FFontID: DWORD; + FColor: TRGB; + FKey0, FKey1: Word; // this should be an array. sorry. + FKeyIdx: Integer; + FIsQuery: Boolean; + FMaxKeyNameWdt: Integer; + public + constructor Create(FontID: DWORD); + procedure OnMessage(var Msg: TMessage); override; + procedure Draw; override; + function GetWidth(): Integer; override; + function WantActivationKey (key: LongInt): Boolean; override; + property Key0: Word read FKey0 write FKey0; + property Key1: Word read FKey1 write FKey1; + property Color: TRGB read FColor write FColor; + property Font: TFont read FFont write FFont; + end; + TGUIModelView = class(TGUIControl) private FModel: TPlayerModel; @@ -296,7 +351,7 @@ type TGUIMapPreview = class(TGUIControl) private FMapData: array of TPreviewPanel; - FMapSize: TPoint; + FMapSize: TDFPoint; FScale: Single; public constructor Create(); @@ -326,7 +381,7 @@ type TGUIListBox = class(TGUIControl) private - FItems: SArray; + FItems: SSArray; FActiveColor: TRGB; FUnActiveColor: TRGB; FFont: TFont; @@ -339,7 +394,7 @@ type FDrawScroll: Boolean; FOnChangeEvent: TOnChangeEvent; - procedure FSetItems(Items: SArray); + procedure FSetItems(Items: SSArray); procedure FSetIndex(aIndex: Integer); public @@ -349,14 +404,14 @@ type procedure AddItem(Item: String); procedure SelectItem(Item: String); procedure Clear(); - function GetWidth(): Word; - function GetHeight(): Word; + function GetWidth(): Integer; override; + function GetHeight(): Integer; override; function SelectedItem(): String; property OnChange: TOnChangeEvent read FOnChangeEvent write FOnChangeEvent; property Sort: Boolean read FSort write FSort; property ItemIndex: Integer read FIndex write FSetIndex; - property Items: SArray read FItems write FSetItems; + property Items: SSArray read FItems write FSetItems; property DrawBack: Boolean read FDrawBack write FDrawBack; property DrawScrollBar: Boolean read FDrawScroll write FDrawScroll; property ActiveColor: TRGB read FActiveColor write FActiveColor; @@ -364,7 +419,7 @@ type property Font: TFont read FFont write FFont; end; - TGUIFileListBox = class (TGUIListBox) + TGUIFileListBox = class(TGUIListBox) private FBasePath: String; FPath: String; @@ -386,7 +441,7 @@ type TGUIMemo = class(TGUIControl) private - FLines: SArray; + FLines: SSArray; FFont: TFont; FStartLine: Integer; FWidth: Word; @@ -399,8 +454,8 @@ type procedure OnMessage(var Msg: TMessage); override; procedure Draw; override; procedure Clear; - function GetWidth(): Word; - function GetHeight(): Word; + function GetWidth(): Integer; override; + function GetHeight(): Integer; override; procedure SetText(Text: string); property DrawBack: Boolean read FDrawBack write FDrawBack; property DrawScrollBar: Boolean read FDrawScroll write FDrawScroll; @@ -422,8 +477,8 @@ type destructor Destroy; override; procedure OnMessage(var Msg: TMessage); override; function AddButton(fProc: Pointer; Caption: string; ShowWindow: string = ''): TGUITextButton; - function GetButton(Name: string): TGUITextButton; - procedure EnableButton(Name: string; e: Boolean); + function GetButton(aName: string): TGUITextButton; + procedure EnableButton(aName: string; e: Boolean); procedure AddSpace(); procedure Update; override; procedure Draw; override; @@ -447,6 +502,7 @@ type FCounter: Byte; FAlign: Boolean; FLeft: Integer; + FYesNo: Boolean; function NewItem(): Integer; public constructor Create(HeaderFont, ItemsFont: DWORD; Header: string); @@ -461,22 +517,25 @@ type function AddSwitch(fText: string): TGUISwitch; function AddEdit(fText: string): TGUIEdit; function AddKeyRead(fText: string): TGUIKeyRead; + function AddKeyRead2(fText: string): TGUIKeyRead2; function AddList(fText: string; Width, Height: Word): TGUIListBox; function AddFileList(fText: string; Width, Height: Word): TGUIFileListBox; function AddMemo(fText: string; Width, Height: Word): TGUIMemo; procedure ReAlign(); - function GetControl(Name: string): TGUIControl; - function GetControlsText(Name: string): TGUILabel; + function GetControl(aName: string): TGUIControl; + function GetControlsText(aName: string): TGUILabel; procedure Draw; override; procedure Update; override; 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 g_GUIWindows: array of TGUIWindow; g_ActiveWindow: TGUIWindow = nil; + g_GUIGrabInput: Boolean = False; procedure g_GUI_Init(); function g_GUI_AddWindow(Window: TGUIWindow): TGUIWindow; @@ -487,16 +546,20 @@ function g_GUI_Destroy(): Boolean; procedure g_GUI_SaveMenuPos(); procedure g_GUI_LoadMenuPos(); + implementation uses - GL, GLExt, g_textures, g_sound, SysUtils, - g_game, Math, StrUtils, g_player, g_options, MAPREADER, - g_map, MAPDEF, g_weapons; + {$INCLUDE ../nogl/noGLuses.inc} + g_textures, g_sound, SysUtils, + g_game, Math, StrUtils, g_player, g_options, + g_map, g_weapons, xdynrec, wadreader; + var Box: Array [0..8] of DWORD; - Saved_Windows: SArray; + Saved_Windows: SSArray; + procedure g_GUI_Init(); begin @@ -713,6 +776,7 @@ begin FActiveControl := nil; FName := Name; FOnKeyDown := nil; + FOnKeyDownEx := nil; FOnCloseEvent := nil; FOnShowEvent := nil; end; @@ -750,13 +814,26 @@ procedure TGUIWindow.Draw; var i: Integer; ID: DWORD; + tw, th: Word; begin - if FBackTexture <> '' then + if FBackTexture <> '' then // Here goes code duplication from g_game.pas:DrawMenuBackground() if g_Texture_Get(FBackTexture, ID) then - e_DrawSize(ID, 0, 0, 0, False, False, gScreenWidth, gScreenHeight) + begin + e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); + e_GetTextureSize(ID, @tw, @th); + if tw = th then + tw := round(tw * 1.333 * (gScreenHeight / th)) + else + tw := trunc(tw * (gScreenHeight / th)); + e_DrawSize(ID, (gScreenWidth - tw) div 2, 0, 0, False, False, tw, gScreenHeight); + end else e_Clear(GL_COLOR_BUFFER_BIT, 0.5, 0.5, 0.5); + // small hack here + if FName = 'AuthorsMenu' then + e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150); + for i := 0 to High(Childs) do if Childs[i] <> nil then Childs[i].Draw; end; @@ -765,13 +842,18 @@ 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 - begin - g_GUI_HideWindow; - Exit; - end; + begin + case Msg.wParam of + VK_ESCAPE: + begin + g_GUI_HideWindow; + Exit + end + end + end end; procedure TGUIWindow.SetActive(Control: TGUIControl); @@ -805,6 +887,8 @@ begin FY := 0; FEnabled := True; + FRightAlign := false; + FMaxWidth := -1; end; procedure TGUIControl.OnMessage(var Msg: TMessage); @@ -815,34 +899,47 @@ end; procedure TGUIControl.Update(); begin - end; procedure TGUIControl.Draw(); begin +end; +function TGUIControl.WantActivationKey (key: LongInt): Boolean; +begin + result := false; +end; + +function TGUIControl.GetWidth(): Integer; +begin + result := 0; +end; + +function TGUIControl.GetHeight(): Integer; +begin + result := 0; end; { TGUITextButton } 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 @ProcEx <> nil then ProcEx(self); - if @Proc <> nil then - Proc(); - if FShowWindow <> '' then - g_GUI_ShowWindow(FShowWindow); + if FShowWindow <> '' then g_GUI_ShowWindow(FShowWindow); end; -constructor TGUITextButton.Create(Proc: Pointer; FontID: DWORD; Text: string); +constructor TGUITextButton.Create(aProc: Pointer; FontID: DWORD; Text: string); begin inherited Create(); - Self.Proc := Proc; + Self.Proc := aProc; + ProcEx := nil; - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); FText := Text; end; @@ -883,7 +980,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_RETURN: Click(); + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: Click(); end; end; end; @@ -911,15 +1008,15 @@ 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); + if FFontType = TFontType.Character then e_CharFont_PrintEx(ID, X, Y, Text, _RGB(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); var cw, ch: Byte; begin - if FFontType = FONT_CHAR then e_CharFont_GetSize(ID, Text, w, h) + if FFontType = TFontType.Character then e_CharFont_GetSize(ID, Text, w, h) else begin e_TextureFontGetSize(ID, cw, ch); @@ -999,7 +1096,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,18 +1134,18 @@ 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; -procedure TGUIMainMenu.EnableButton(Name: string; e: Boolean); +procedure TGUIMainMenu.EnableButton(aName: string; e: Boolean); var a: Integer; begin if FButtons = nil then Exit; for a := 0 to High(FButtons) do - if (FButtons[a] <> nil) and (FButtons[a].Name = Name) then + if (FButtons[a] <> nil) and (FButtons[a].Name = aName) then begin if e then FButtons[a].FColor := MAINMENU_ITEMS_COLOR else FButtons[a].FColor := MAINMENU_UNACTIVEITEMS_COLOR; @@ -1057,7 +1154,7 @@ begin end; end; -function TGUIMainMenu.GetButton(Name: string): TGUITextButton; +function TGUIMainMenu.GetButton(aName: string): TGUITextButton; var a: Integer; begin @@ -1066,7 +1163,7 @@ begin if FButtons = nil then Exit; for a := 0 to High(FButtons) do - if (FButtons[a] <> nil) and (FButtons[a].Name = Name) then + if (FButtons[a] <> nil) and (FButtons[a].Name = aName) then begin Result := FButtons[a]; Break; @@ -1097,7 +1194,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_UP: + IK_UP, IK_KPUP, VK_UP, JOY0_UP, JOY1_UP, JOY2_UP, JOY3_UP: begin repeat Dec(FIndex); @@ -1106,7 +1203,7 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_DOWN: + IK_DOWN, IK_KPDOWN, VK_DOWN, JOY0_DOWN, JOY1_DOWN, JOY2_DOWN, JOY3_DOWN: begin repeat Inc(FIndex); @@ -1115,7 +1212,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, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: if (FIndex <> -1) and FButtons[FIndex].FEnabled then FButtons[FIndex].Click; end; end; end; @@ -1142,7 +1239,7 @@ constructor TGUILabel.Create(Text: string; FontID: DWORD); begin inherited Create(); - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); FText := Text; FFixedLen := 0; @@ -1150,8 +1247,18 @@ begin end; procedure TGUILabel.Draw; +var + w, h: Word; begin - FFont.Draw(FX, FY, FText, FColor.R, FColor.G, FColor.B); + if RightAlign then + begin + FFont.GetTextSize(FText, w, h); + FFont.Draw(FX+FMaxWidth-w, FY, FText, FColor.R, FColor.G, FColor.B); + end + else + begin + FFont.Draw(FX, FY, FText, FColor.R, FColor.G, FColor.B); + end; end; function TGUILabel.GetHeight: Integer; @@ -1169,8 +1276,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 +1289,7 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_RETURN: if @FOnClickEvent <> nil then FOnClickEvent(); + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: if @FOnClickEvent <> nil then FOnClickEvent(); end; end; end; @@ -1236,7 +1343,7 @@ end; procedure TGUIMenu.AddText(fText: string; MaxWidth: Word); var a, i: Integer; - l: SArray; + l: SSArray; begin l := GetLines(fText, FFontID, MaxWidth); @@ -1248,9 +1355,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 +1394,7 @@ begin FFontID := ItemsFont; FCounter := MENU_MARKERDELAY; FAlign := True; + FYesNo := false; FHeader := TGUILabel.Create(Header, HeaderFont); with FHeader do @@ -1314,7 +1426,7 @@ end; procedure TGUIMenu.Draw; var - a, x, y: Integer; + a, locx, locy: Integer; begin inherited; @@ -1329,27 +1441,32 @@ begin if (FIndex <> -1) and (FCounter > MENU_MARKERDELAY div 2) then begin - x := 0; - y := 0; + locx := 0; + locy := 0; if FItems[FIndex].Text <> nil then begin - x := FItems[FIndex].Text.FX; - y := FItems[FIndex].Text.FY; + locx := FItems[FIndex].Text.FX; + locy := FItems[FIndex].Text.FY; + //HACK! + if FItems[FIndex].Text.RightAlign then + begin + locx := locx+FItems[FIndex].Text.FMaxWidth-FItems[FIndex].Text.GetWidth; + end; end else if FItems[FIndex].Control <> nil then begin - x := FItems[FIndex].Control.FX; - y := FItems[FIndex].Control.FY; + locx := FItems[FIndex].Control.FX; + locy := FItems[FIndex].Control.FY; end; - x := x-e_CharFont_GetMaxWidth(FFontID); + locx := locx-e_CharFont_GetMaxWidth(FFontID); - e_CharFont_PrintEx(FFontID, x, y, #16, _RGB(255, 0, 0)); + e_CharFont_PrintEx(FFontID, locx, locy, #16, _RGB(255, 0, 0)); end; end; -function TGUIMenu.GetControl(Name: String): TGUIControl; +function TGUIMenu.GetControl(aName: String): TGUIControl; var a: Integer; begin @@ -1358,16 +1475,16 @@ begin if FItems <> nil then for a := 0 to High(FItems) do if FItems[a].Control <> nil then - if LowerCase(FItems[a].Control.Name) = LowerCase(Name) then + if LowerCase(FItems[a].Control.Name) = LowerCase(aName) then begin Result := FItems[a].Control; Break; end; - Assert(Result <> nil, 'GUI control "'+Name+'" not found!'); + Assert(Result <> nil, 'GUI control "'+aName+'" not found!'); end; -function TGUIMenu.GetControlsText(Name: String): TGUILabel; +function TGUIMenu.GetControlsText(aName: String): TGUILabel; var a: Integer; begin @@ -1376,13 +1493,13 @@ begin if FItems <> nil then for a := 0 to High(FItems) do if FItems[a].Control <> nil then - if LowerCase(FItems[a].Control.Name) = LowerCase(Name) then + if LowerCase(FItems[a].Control.Name) = LowerCase(aName) then begin Result := FItems[a].Text; Break; end; - Assert(Result <> nil, 'GUI control''s text "'+Name+'" not found!'); + Assert(Result <> nil, 'GUI control''s text "'+aName+'" not found!'); end; function TGUIMenu.NewItem: Integer; @@ -1412,11 +1529,19 @@ begin if not ok then Exit; + if (Msg.Msg = WM_KEYDOWN) and (FIndex <> -1) and (FItems[FIndex].Control <> nil) and + (FItems[FIndex].Control.WantActivationKey(Msg.wParam)) then + begin + FItems[FIndex].Control.OnMessage(Msg); + g_Sound_PlayEx(MENU_CLICKSOUND); + exit; + end; + case Msg.Msg of WM_KEYDOWN: begin case Msg.wParam of - IK_UP: + IK_UP, IK_KPUP, VK_UP,JOY0_UP, JOY1_UP, JOY2_UP, JOY3_UP: begin c := 0; repeat @@ -1437,7 +1562,7 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_DOWN: + IK_DOWN, IK_KPDOWN, VK_DOWN, JOY0_DOWN, JOY1_DOWN, JOY2_DOWN, JOY3_DOWN: begin c := 0; repeat @@ -1458,20 +1583,37 @@ begin g_Sound_PlayEx(MENU_CHANGESOUND); end; - IK_LEFT, IK_RIGHT: + IK_LEFT, IK_RIGHT, IK_KPLEFT, IK_KPRIGHT, VK_LEFT, VK_RIGHT, + JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT, + JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: begin if FIndex <> -1 then if FItems[FIndex].Control <> nil then FItems[FIndex].Control.OnMessage(Msg); end; - IK_RETURN: + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: 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; @@ -1480,10 +1622,27 @@ end; procedure TGUIMenu.ReAlign(); var a, tx, cx, w, h: Integer; + cww: array of Integer; // cached widths + maxcww: Integer; begin if FItems = nil then Exit; - if not FAlign then tx := FLeft else + SetLength(cww, length(FItems)); + maxcww := 0; + for a := 0 to High(FItems) do + begin + if FItems[a].Text <> nil then + begin + cww[a] := FItems[a].Text.GetWidth; + if maxcww < cww[a] then maxcww := cww[a]; + end; + end; + + if not FAlign then + begin + tx := FLeft; + end + else begin tx := gScreenWidth; for a := 0 to High(FItems) do @@ -1493,48 +1652,39 @@ begin if FItems[a].Control <> nil then begin w := w+MENU_HSPACE; - - if FItems[a].ControlType = TGUILabel then - w := w+(FItems[a].Control as TGUILabel).GetWidth - else if FItems[a].ControlType = TGUITextButton then - w := w+(FItems[a].Control as TGUITextButton).GetWidth - else if FItems[a].ControlType = TGUIScroll then - w := w+(FItems[a].Control as TGUIScroll).GetWidth - else if FItems[a].ControlType = TGUISwitch then - w := w+(FItems[a].Control as TGUISwitch).GetWidth - else if FItems[a].ControlType = TGUIEdit then - w := w+(FItems[a].Control as TGUIEdit).GetWidth - else if FItems[a].ControlType = TGUIKeyRead then - w := w+(FItems[a].Control as TGUIKeyRead).GetWidth - else if (FItems[a].ControlType = TGUIListBox) then - w := w+(FItems[a].Control as TGUIListBox).GetWidth - else if (FItems[a].ControlType = TGUIFileListBox) then - w := w+(FItems[a].Control as TGUIFileListBox).GetWidth - else if FItems[a].ControlType = TGUIMemo then - w := w+(FItems[a].Control as TGUIMemo).GetWidth; + if FItems[a].ControlType = TGUILabel then w := w+(FItems[a].Control as TGUILabel).GetWidth + else if FItems[a].ControlType = TGUITextButton then w := w+(FItems[a].Control as TGUITextButton).GetWidth + else if FItems[a].ControlType = TGUIScroll then w := w+(FItems[a].Control as TGUIScroll).GetWidth + else if FItems[a].ControlType = TGUISwitch then w := w+(FItems[a].Control as TGUISwitch).GetWidth + else if FItems[a].ControlType = TGUIEdit then w := w+(FItems[a].Control as TGUIEdit).GetWidth + else if FItems[a].ControlType = TGUIKeyRead then w := w+(FItems[a].Control as TGUIKeyRead).GetWidth + else if FItems[a].ControlType = TGUIKeyRead2 then w := w+(FItems[a].Control as TGUIKeyRead2).GetWidth + else if FItems[a].ControlType = TGUIListBox then w := w+(FItems[a].Control as TGUIListBox).GetWidth + else if FItems[a].ControlType = TGUIFileListBox then w := w+(FItems[a].Control as TGUIFileListBox).GetWidth + else if FItems[a].ControlType = TGUIMemo then w := w+(FItems[a].Control as TGUIMemo).GetWidth; end; - tx := Min(tx, (gScreenWidth div 2)-(w div 2)); end; end; 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 +1692,7 @@ begin else h := h+e_CharFont_GetMaxHeight(FFontID); end; + end; h := (gScreenHeight div 2)-(h div 2); @@ -1554,35 +1705,70 @@ begin end; for a := 0 to High(FItems) do + begin with FItems[a] do begin if Text <> nil then + begin with Text do begin FX := tx; FY := h; end; + //HACK! + if Text.RightAlign and (length(cww) > a) then + begin + //Text.FX := Text.FX+maxcww; + Text.FMaxWidth := maxcww; + end; + end; - if Control <> nil then - with Control do - if Text <> nil then - begin - FX := cx; - FY := h; - end - else - begin - FX := tx; - FY := h; - end; + if Control <> nil then + begin + with Control do + begin + if Text <> nil then + begin + FX := cx; + FY := h; + end + else + begin + FX := tx; + FY := h; + end; + end; + end; - if (ControlType = TGUIListBox) or (ControlType = TGUIFileListBox) then - Inc(h, (Control as TGUIListBox).GetHeight+MENU_VSPACE) - else if ControlType = TGUIMemo then - Inc(h, (Control as TGUIMemo).GetHeight+MENU_VSPACE) - else - Inc(h, e_CharFont_GetMaxHeight(FFontID)+MENU_VSPACE); + if (ControlType = TGUIListBox) or (ControlType = TGUIFileListBox) then Inc(h, (Control as TGUIListBox).GetHeight+MENU_VSPACE) + else if ControlType = TGUIMemo then Inc(h, (Control as TGUIMemo).GetHeight+MENU_VSPACE) + else Inc(h, e_CharFont_GetMaxHeight(FFontID)+MENU_VSPACE); end; + 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; @@ -1710,6 +1896,37 @@ begin ReAlign(); end; +function TGUIMenu.AddKeyRead2(fText: string): TGUIKeyRead2; +var + i: Integer; +begin + i := NewItem(); + with FItems[i] do + begin + Control := TGUIKeyRead2.Create(FFontID); + with Control as TGUIKeyRead2 do + begin + FWindow := Self.FWindow; + FColor := MENU_ITEMSCTRL_COLOR; + end; + + Text := TGUILabel.Create(fText, FFontID); + with Text do + begin + FColor := MENU_ITEMSCTRL_COLOR; //MENU_ITEMSTEXT_COLOR; + RightAlign := true; + end; + + ControlType := TGUIKeyRead2; + + Result := (Control as TGUIKeyRead2); + end; + + if FIndex = -1 then FIndex := i; + + ReAlign(); +end; + function TGUIMenu.AddList(fText: string; Width, Height: Word): TGUIListBox; var i: Integer; @@ -1888,7 +2105,7 @@ begin if a > FMax then FValue := FMax else FValue := a; end; -function TGUIScroll.GetWidth: Word; +function TGUIScroll.GetWidth: Integer; begin Result := 16+(FMax+1)*8; end; @@ -1903,14 +2120,14 @@ begin WM_KEYDOWN: begin case Msg.wParam of - IK_LEFT: + IK_LEFT, IK_KPLEFT, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: 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, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: if FValue < FMax then begin Inc(FValue); @@ -1944,7 +2161,7 @@ begin FIndex := -1; - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); end; procedure TGUISwitch.Draw; @@ -1960,7 +2177,7 @@ begin else Result := ''; end; -function TGUISwitch.GetWidth: Word; +function TGUISwitch.GetWidth: Integer; var a: Integer; w, h: Word; @@ -1987,7 +2204,9 @@ begin case Msg.Msg of WM_KEYDOWN: case Msg.wParam of - IK_RETURN, IK_RIGHT: + IK_RETURN, IK_RIGHT, IK_KPRETURN, IK_KPRIGHT, VK_FIRE, VK_OPEN, VK_RIGHT, + JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT, + JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: begin if FIndex < High(FItems) then Inc(FIndex) @@ -1998,7 +2217,8 @@ begin FOnChangeEvent(Self); end; - IK_LEFT: + IK_LEFT, IK_KPLEFT, VK_LEFT, + JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: begin if FIndex > 0 then Dec(FIndex) @@ -2024,10 +2244,11 @@ constructor TGUIEdit.Create(FontID: DWORD); begin inherited Create(); - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); FMaxLength := 0; FWidth := 0; + FInvalid := false; g_Texture_Get(EDIT_LEFT, FLeftID); g_Texture_Get(EDIT_RIGHT, FRightID); @@ -2037,6 +2258,7 @@ end; procedure TGUIEdit.Draw; var c, w, h: Word; + r, g, b: Byte; begin inherited; @@ -2046,9 +2268,13 @@ begin for c := 0 to FWidth-1 do e_Draw(FMiddleID, FX+8+c*16, FY, 0, True, False); - FFont.Draw(FX+8, FY, FText, FColor.R, FColor.G, FColor.B); + r := FColor.R; + g := FColor.G; + b := FColor.B; + if FInvalid and (FWindow.FActiveControl <> self) then begin r := 128; g := 128; b := 128; end; + FFont.Draw(FX+8, FY, FText, r, g, b); - if FWindow.FActiveControl = Self then + if (FWindow.FActiveControl = self) then begin FFont.GetTextSize(Copy(FText, 1, FCaretPos), w, h); h := e_CharFont_GetMaxHeight(FFont.ID); @@ -2057,7 +2283,7 @@ begin end; end; -function TGUIEdit.GetWidth: Word; +function TGUIEdit.GetWidth: Integer; begin Result := 16+FWidth*16; end; @@ -2097,11 +2323,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, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: if FCaretPos > 0 then Dec(FCaretPos); + IK_RIGHT, IK_KPRIGHT, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: if FCaretPos < Length(FText) then Inc(FCaretPos); + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: with FWindow do begin if FActiveControl <> Self then @@ -2118,6 +2344,9 @@ begin end; end; end; + + g_GUIGrabInput := (@FOnEnterEvent = nil) and (FWindow.FActiveControl = Self); + g_Touch_ShowKeyboard(g_GUIGrabInput) end; procedure TGUIEdit.SetText(Text: string); @@ -2137,8 +2366,10 @@ end; constructor TGUIKeyRead.Create(FontID: DWORD); begin inherited Create(); + FKey := 0; + FIsQuery := false; - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); end; procedure TGUIKeyRead.Draw; @@ -2149,13 +2380,13 @@ begin FColor.R, FColor.G, FColor.B); end; -function TGUIKeyRead.GetWidth: Word; +function TGUIKeyRead.GetWidth: Integer; var a: Byte; w, h: Word; begin Result := 0; - + for a := 0 to 255 do begin FFont.GetTextSize(e_KeyNames[a], w, h); @@ -2169,7 +2400,23 @@ begin if w > Result then Result := w; end; +function TGUIKeyRead.WantActivationKey (key: LongInt): Boolean; +begin + result := + (key = IK_BACKSPACE) or + false; // oops +end; + procedure TGUIKeyRead.OnMessage(var Msg: TMessage); + procedure actDefCtl (); + begin + with FWindow do + if FDefControl <> '' then + SetActive(GetControl(FDefControl)) + else + SetActive(nil); + end; + begin inherited; @@ -2180,18 +2427,12 @@ begin case Msg of WM_KEYDOWN: case wParam of - IK_ESCAPE: + VK_ESCAPE: begin - if FIsQuery then - with FWindow do - if FDefControl <> '' then - SetActive(GetControl(FDefControl)) - else - SetActive(nil); - + if FIsQuery then actDefCtl(); FIsQuery := False; end; - IK_RETURN: + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: begin if not FIsQuery then begin @@ -2201,36 +2442,219 @@ begin FIsQuery := True; end - else + else if (wParam < VK_FIRSTKEY) and (wParam > VK_LASTKEY) then begin - FKey := IK_ENTER; // + // FKey := IK_ENTER; // + FKey := wParam; FIsQuery := False; - - with FWindow do - if FDefControl <> '' then - SetActive(GetControl(FDefControl)) - else - SetActive(nil); - end; + actDefCtl(); + end; + end; + IK_BACKSPACE: // clear keybinding if we aren't waiting for a key + begin + if not FIsQuery then + begin + FKey := 0; + actDefCtl(); + end; end; end; MESSAGE_DIKEY: - if FIsQuery and (wParam <> IK_ENTER) then // Not '' then - FKey := wParam; - FIsQuery := False; + if not FIsQuery and (wParam = IK_BACKSPACE) then + begin + FKey := 0; + actDefCtl(); + end + else if FIsQuery then + begin + case wParam of + IK_ENTER, IK_KPRETURN, VK_FIRSTKEY..VK_LASTKEY, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: // Not '' then + FKey := wParam; + FIsQuery := False; + actDefCtl(); + end + end; + end; + end; + + g_GUIGrabInput := FIsQuery +end; + +{ TGUIKeyRead2 } + +constructor TGUIKeyRead2.Create(FontID: DWORD); +var + a: Byte; + w, h: Word; +begin + inherited Create(); + + FKey0 := 0; + FKey1 := 0; + FKeyIdx := 0; + FIsQuery := False; + + FFontID := FontID; + FFont := TFont.Create(FontID, TFontType.Character); + + FMaxKeyNameWdt := 0; + for a := 0 to 255 do + begin + FFont.GetTextSize(e_KeyNames[a], w, h); + FMaxKeyNameWdt := Max(FMaxKeyNameWdt, w); + end; + + FMaxKeyNameWdt := FMaxKeyNameWdt-(FMaxKeyNameWdt div 3); + + FFont.GetTextSize(KEYREAD_QUERY, w, h); + if w > FMaxKeyNameWdt then FMaxKeyNameWdt := w; - with FWindow do - if FDefControl <> '' then - SetActive(GetControl(FDefControl)) + FFont.GetTextSize(KEYREAD_CLEAR, w, h); + if w > FMaxKeyNameWdt then FMaxKeyNameWdt := w; +end; + +procedure TGUIKeyRead2.Draw; + procedure drawText (idx: Integer); + var + x, y: Integer; + r, g, b: Byte; + kk: DWORD; + begin + if idx = 0 then kk := FKey0 else kk := FKey1; + y := FY; + if idx = 0 then x := FX+8 else x := FX+8+FMaxKeyNameWdt+16; + r := 255; + g := 0; + b := 0; + if FKeyIdx = idx then begin r := 255; g := 255; b := 255; end; + if FIsQuery and (FKeyIdx = idx) then + FFont.Draw(x, y, KEYREAD_QUERY, r, g, b) + else + FFont.Draw(x, y, IfThen(kk <> 0, e_KeyNames[kk], KEYREAD_CLEAR), r, g, b); + end; + +begin + inherited; + + //FFont.Draw(FX+8, FY, IfThen(FIsQuery and (FKeyIdx = 0), KEYREAD_QUERY, IfThen(FKey0 <> 0, e_KeyNames[FKey0], KEYREAD_CLEAR)), FColor.R, FColor.G, FColor.B); + //FFont.Draw(FX+8+FMaxKeyNameWdt+16, FY, IfThen(FIsQuery and (FKeyIdx = 1), KEYREAD_QUERY, IfThen(FKey1 <> 0, e_KeyNames[FKey1], KEYREAD_CLEAR)), FColor.R, FColor.G, FColor.B); + drawText(0); + drawText(1); +end; + +function TGUIKeyRead2.GetWidth: Integer; +begin + Result := FMaxKeyNameWdt*2+8+8+16; +end; + +function TGUIKeyRead2.WantActivationKey (key: LongInt): Boolean; +begin + case key of + IK_BACKSPACE, IK_LEFT, IK_RIGHT, IK_KPLEFT, IK_KPRIGHT, VK_LEFT, VK_RIGHT, + JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT, + JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: + result := True + else + result := False + end +end; + +procedure TGUIKeyRead2.OnMessage(var Msg: TMessage); + procedure actDefCtl (); + begin + with FWindow do + if FDefControl <> '' then + SetActive(GetControl(FDefControl)) + else + SetActive(nil); + end; + +begin + inherited; + + if not FEnabled then + Exit; + + with Msg do + case Msg of + WM_KEYDOWN: + case wParam of + VK_ESCAPE: + begin + if FIsQuery then actDefCtl(); + FIsQuery := False; + end; + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: + begin + if not FIsQuery then + begin + with FWindow do + if FActiveControl <> Self then + SetActive(Self); + + FIsQuery := True; + end + else if (wParam < VK_FIRSTKEY) and (wParam > VK_LASTKEY) then + begin + // if (FKeyIdx = 0) then FKey0 := IK_ENTER else FKey1 := IK_ENTER; // + if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam; + FIsQuery := False; + actDefCtl(); + end; + end; + IK_BACKSPACE: // clear keybinding if we aren't waiting for a key + begin + if not FIsQuery then + begin + if (FKeyIdx = 0) then FKey0 := 0 else FKey1 := 0; + actDefCtl(); + end; + end; + IK_LEFT, IK_KPLEFT, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: + if not FIsQuery then + begin + FKeyIdx := 0; + actDefCtl(); + end; + IK_RIGHT, IK_KPRIGHT, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: + if not FIsQuery then + begin + FKeyIdx := 1; + actDefCtl(); + end; + end; + + MESSAGE_DIKEY: + begin + if not FIsQuery and (wParam = IK_BACKSPACE) then + begin + if (FKeyIdx = 0) then FKey0 := 0 else FKey1 := 0; + actDefCtl(); + end + else if FIsQuery then + begin + case wParam of + IK_ENTER, IK_KPRETURN, VK_FIRSTKEY..VK_LASTKEY, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: // Not '' then + begin + if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam; + end; + FIsQuery := False; + actDefCtl() + end + end; end; end; + + g_GUIGrabInput := FIsQuery end; + { TGUIModelView } constructor TGUIModelView.Create; @@ -2253,7 +2677,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(); @@ -2272,7 +2696,7 @@ begin if FModel = nil then Exit; - if FModel.Weapon < WEAPON_SUPERPULEMET then + if FModel.Weapon < WP_LAST then FModel.SetWeapon(FModel.Weapon+1) else FModel.SetWeapon(WEAPON_KASTET); @@ -2286,7 +2710,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 +2726,7 @@ begin a := not a; if a then Exit; - + if FModel <> nil then FModel.Update; end; @@ -2335,7 +2759,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 +2770,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 +2830,32 @@ end; procedure TGUIMapPreview.SetMap(Res: string); var - WAD: TWADEditor_1; - MapReader: TMapReader_1; - panels: TPanelsRec1Array; - header: TMapHeaderRec_1; - a: Integer; - FileName, SectionName, ResName: string; + WAD: TWADFile; + panlist: TDynField; + pan: TDynRecord; + //header: TMapHeaderRec_1; + FileName: string; Data: Pointer; Len: Integer; rX, rY: Single; + map: TDynRecord = nil; begin - g_ProcessResourceStr(Res, FileName, SectionName, ResName); + FMapSize.X := 0; + FMapSize.Y := 0; + FScale := 0.0; + FMapData := nil; - WAD := TWADEditor_1.Create(); + FileName := g_ExtractWadName(Res); + + 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; @@ -2433,68 +2863,71 @@ begin WAD.Free(); - MapReader := TMapReader_1.Create(); - - if not MapReader.LoadMap(Data) then - begin + try + map := g_Map_ParseMap(Data, Len); + except FreeMem(Data); - MapReader.Free(); - FMapSize.X := 0; - FMapSize.Y := 0; - FScale := 0.0; - FMapData := nil; - Exit; + map.Free(); + //raise; + exit; end; FreeMem(Data); - panels := MapReader.GetPanels(); - header := MapReader.GetMapHeader(); + if (map = nil) then exit; - FMapSize.X := header.Width div 16; - FMapSize.Y := header.Height div 16; + try + panlist := map.field['panel']; + //header := GetMapHeader(map); - rX := Ceil(header.Width / (MAPPREVIEW_WIDTH*256.0)); - rY := Ceil(header.Height / (MAPPREVIEW_HEIGHT*256.0)); - FScale := max(rX, rY); + FMapSize.X := map.Width div 16; + FMapSize.Y := map.Height div 16; - FMapData := nil; + rX := Ceil(map.Width / (MAPPREVIEW_WIDTH*256.0)); + rY := Ceil(map.Height / (MAPPREVIEW_HEIGHT*256.0)); + FScale := max(rX, rY); - if panels <> nil then - for a := 0 to High(panels) do - if WordBool(panels[a].PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or - PANEL_STEP or PANEL_WATER or - PANEL_ACID1 or PANEL_ACID2)) then + FMapData := nil; + + if (panlist <> nil) then + begin + for pan in panlist do begin - SetLength(FMapData, Length(FMapData)+1); - with FMapData[High(FMapData)] do + if (pan.PanelType and (PANEL_WALL or PANEL_CLOSEDOOR or + PANEL_STEP or PANEL_WATER or + PANEL_ACID1 or PANEL_ACID2)) <> 0 then begin - X1 := panels[a].X div 16; - Y1 := panels[a].Y div 16; + SetLength(FMapData, Length(FMapData)+1); + with FMapData[High(FMapData)] do + begin + X1 := pan.X div 16; + Y1 := pan.Y div 16; - X2 := (panels[a].X + panels[a].Width) div 16; - Y2 := (panels[a].Y + panels[a].Height) div 16; + X2 := (pan.X + pan.Width) div 16; + Y2 := (pan.Y + pan.Height) div 16; - X1 := Trunc(X1/FScale + 0.5); - Y1 := Trunc(Y1/FScale + 0.5); - X2 := Trunc(X2/FScale + 0.5); - Y2 := Trunc(Y2/FScale + 0.5); + X1 := Trunc(X1/FScale + 0.5); + Y1 := Trunc(Y1/FScale + 0.5); + X2 := Trunc(X2/FScale + 0.5); + Y2 := Trunc(Y2/FScale + 0.5); - if (X1 <> X2) or (Y1 <> Y2) then - begin - if X1 = X2 then - X2 := X2 + 1; - if Y1 = Y2 then - Y2 := Y2 + 1; - end; + if (X1 <> X2) or (Y1 <> Y2) then + begin + if X1 = X2 then + X2 := X2 + 1; + if Y1 = Y2 then + Y2 := Y2 + 1; + end; - PanelType := panels[a].PanelType; + PanelType := pan.PanelType; + end; + end; end; - end; - - panels := nil; - - MapReader.Free(); + end; + finally + //writeln('freeing map'); + map.Free(); + end; end; procedure TGUIMapPreview.ClearMap(); @@ -2549,7 +2982,7 @@ constructor TGUIListBox.Create(FontID: DWORD; Width, Height: Word); begin inherited Create(); - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); FWidth := Width; FHeight := Height; @@ -2591,14 +3024,14 @@ begin end; end; -function TGUIListBox.GetHeight: Word; +function TGUIListBox.GetHeight: Integer; begin - Result := 8+FHeight*16; + Result := 8+FHeight*16; end; -function TGUIListBox.GetWidth: Word; +function TGUIListBox.GetWidth: Integer; begin - Result := 8+(FWidth+1)*16; + Result := 8+(FWidth+1)*16; end; procedure TGUIListBox.OnMessage(var Msg: TMessage); @@ -2615,31 +3048,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, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: 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, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: 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, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: with FWindow do begin if FActiveControl <> Self then SetActive(Self) @@ -2671,11 +3104,11 @@ begin Result := FItems[FIndex]; end; -procedure TGUIListBox.FSetItems(Items: SArray); +procedure TGUIListBox.FSetItems(Items: SSArray); begin if FItems <> nil then FItems := nil; - + FItems := Items; FStartLine := 0; @@ -2727,7 +3160,7 @@ end; procedure TGUIFileListBox.OnMessage(var Msg: TMessage); var - a: Integer; + a, b: Integer; begin if not FEnabled then Exit; @@ -2739,7 +3172,7 @@ begin case Msg of WM_KEYDOWN: case wParam of - IK_HOME: + IK_HOME, IK_KPHOME: begin FIndex := 0; FStartLine := 0; @@ -2747,7 +3180,7 @@ begin FOnChangeEvent(Self); end; - IK_END: + IK_END, IK_KPEND: begin FIndex := High(FItems); FStartLine := Max(High(FItems)-FHeight+1, 0); @@ -2755,7 +3188,7 @@ begin FOnChangeEvent(Self); end; - IK_PAGEUP: + IK_PAGEUP, IK_KPPAGEUP: begin if FIndex > FHeight then FIndex := FIndex-FHeight @@ -2768,7 +3201,7 @@ begin FStartLine := 0; end; - IK_PAGEDN: + IK_PAGEDN, IK_KPPAGEDN: begin if FIndex < High(FItems)-FHeight then FIndex := FIndex+FHeight @@ -2781,7 +3214,7 @@ begin FStartLine := High(FItems)-FHeight+1; end; - IK_UP, IK_LEFT: + IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT, VK_UP, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: if FIndex > 0 then begin Dec(FIndex); @@ -2791,7 +3224,7 @@ begin FOnChangeEvent(Self); end; - IK_DOWN, IK_RIGHT: + IK_DOWN, IK_RIGHT, IK_KPDOWN, IK_KPRIGHT, VK_DOWN, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: if FIndex < High(FItems) then begin Inc(FIndex); @@ -2801,7 +3234,7 @@ begin FOnChangeEvent(Self); end; - IK_RETURN: + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: with FWindow do begin if FActiveControl <> Self then @@ -2824,7 +3257,9 @@ begin end; WM_CHAR: - for a := 0 to High(FItems) do + for b := FIndex + 1 to High(FItems) + FIndex do + begin + a := b mod Length(FItems); if ( (Length(FItems[a]) > 0) and (LowerCase(FItems[a][1]) = LowerCase(Chr(wParam))) ) or ( (Length(FItems[a]) > 1) and @@ -2837,6 +3272,7 @@ begin FOnChangeEvent(Self); Break; end; + end; end; end; @@ -2844,13 +3280,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 +3304,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 +3348,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 @@ -2931,7 +3372,7 @@ constructor TGUIMemo.Create(FontID: DWORD; Width, Height: Word); begin inherited Create(); - FFont := TFont.Create(FontID, FONT_CHAR); + FFont := TFont.Create(FontID, TFontType.Character); FWidth := Width; FHeight := Height; @@ -2955,12 +3396,12 @@ begin FFont.Draw(FX+4, FY+4+(a-FStartLine)*16, FLines[a], FColor.R, FColor.G, FColor.B); end; -function TGUIMemo.GetHeight: Word; +function TGUIMemo.GetHeight: Integer; begin Result := 8+FHeight*16; end; -function TGUIMemo.GetWidth: Word; +function TGUIMemo.GetWidth: Integer; begin Result := 8+(FWidth+1)*16; end; @@ -2977,13 +3418,13 @@ begin case Msg of WM_KEYDOWN: case wParam of - IK_UP, IK_LEFT: + IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT, VK_UP, VK_LEFT, JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT: if FStartLine > 0 then Dec(FStartLine); - IK_DOWN, IK_RIGHT: + IK_DOWN, IK_RIGHT, IK_KPDOWN, IK_KPRIGHT, VK_DOWN, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT: if FStartLine < Length(FLines)-FHeight then Inc(FStartLine); - IK_RETURN: + IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: with FWindow do begin if FActiveControl <> Self then @@ -3034,7 +3475,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