DEADSOFTWARE

Fix warnings
[d2df-sdl.git] / src / game / g_gui.pas
index 2ead3bbbb06a9e0bf0bd7c8cbae0b5eb2d626919..a76a1801f560969bd0ab491f9dca790cc7565c3f 100644 (file)
@@ -1,4 +1,4 @@
-(* Copyright (C)  DooM 2D:Forever Developers
+(* 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
@@ -19,8 +19,8 @@ unit g_gui;
 interface
 
 uses
-  mempool,
-  e_graphics, e_input, e_log, g_playermodel, g_basic, MAPDEF, wadreader;
+  {$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);
@@ -83,9 +83,9 @@ type
     lParam: LongInt;
   end;
 
-  TFontType = (FONT_TEXTURE, FONT_CHAR);
+  TFontType = (Texture, Character);
 
-  TFont = class(TPoolObject)
+  TFont = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
   private
     ID: DWORD;
     FScale: Single;
@@ -109,7 +109,7 @@ type
   TOnChangeEvent = procedure(Sender: TGUIControl);
   TOnEnterEvent = procedure(Sender: TGUIControl);
 
-  TGUIControl = class(TPoolObject)
+  TGUIControl = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
   private
     FX, FY: Integer;
     FEnabled: Boolean;
@@ -134,7 +134,7 @@ type
     property RightAlign: Boolean read FRightAlign write FRightAlign; // for menu
   end;
 
-  TGUIWindow = class(TPoolObject)
+  TGUIWindow = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
   private
     FActiveControl: TGUIControl;
     FDefControl: string;
@@ -268,6 +268,7 @@ type
     FMiddleID: DWORD;
     FOnChangeEvent: TOnChangeEvent;
     FOnEnterEvent: TOnEnterEvent;
+    FInvalid: Boolean;
     procedure SetText(Text: string);
   public
     constructor Create(FontID: DWORD);
@@ -283,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)
@@ -379,7 +381,7 @@ type
 
   TGUIListBox = class(TGUIControl)
   private
-    FItems: SArray;
+    FItems: SSArray;
     FActiveColor: TRGB;
     FUnActiveColor: TRGB;
     FFont: TFont;
@@ -392,7 +394,7 @@ type
     FDrawScroll: Boolean;
     FOnChangeEvent: TOnChangeEvent;
 
-    procedure FSetItems(Items: SArray);
+    procedure FSetItems(Items: SSArray);
     procedure FSetIndex(aIndex: Integer);
 
   public
@@ -409,7 +411,7 @@ type
     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;
@@ -439,7 +441,7 @@ type
 
   TGUIMemo = class(TGUIControl)
   private
-    FLines: SArray;
+    FLines: SSArray;
     FFont: TFont;
     FStartLine: Integer;
     FWidth: Word;
@@ -533,6 +535,7 @@ type
 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;
@@ -543,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,
+  {$INCLUDE ../nogl/noGLuses.inc}
+  g_textures, g_sound, SysUtils,
   g_game, Math, StrUtils, g_player, g_options,
-  g_map, g_weapons, xdynrec;
+  g_map, g_weapons, xdynrec, wadreader;
+
 
 var
   Box: Array [0..8] of DWORD;
-  Saved_Windows: SArray;
+  Saved_Windows: SSArray;
+
 
 procedure g_GUI_Init();
 begin
@@ -807,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;
@@ -825,11 +845,15 @@ begin
   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);
@@ -915,7 +939,7 @@ begin
   Self.Proc := aProc;
   ProcEx := nil;
 
-  FFont := TFont.Create(FontID, FONT_CHAR);
+  FFont := TFont.Create(FontID, TFontType.Character);
 
   FText := Text;
 end;
@@ -956,7 +980,7 @@ begin
   case Msg.Msg of
     WM_KEYDOWN:
       case Msg.wParam of
-        IK_RETURN, IK_KPRETURN: Click();
+        IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: Click();
       end;
   end;
 end;
@@ -984,7 +1008,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)
+  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;
 
@@ -992,7 +1016,7 @@ 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);
@@ -1170,7 +1194,7 @@ begin
   case Msg.Msg of
     WM_KEYDOWN:
       case Msg.wParam of
-        IK_UP, IK_KPUP:
+        IK_UP, IK_KPUP, VK_UP, JOY0_UP, JOY1_UP, JOY2_UP, JOY3_UP:
         begin
           repeat
             Dec(FIndex);
@@ -1179,7 +1203,7 @@ begin
 
           g_Sound_PlayEx(MENU_CHANGESOUND);
         end;
-        IK_DOWN, IK_KPDOWN:
+        IK_DOWN, IK_KPDOWN, VK_DOWN, JOY0_DOWN, JOY1_DOWN, JOY2_DOWN, JOY3_DOWN:
         begin
           repeat
             Inc(FIndex);
@@ -1188,7 +1212,7 @@ begin
 
           g_Sound_PlayEx(MENU_CHANGESOUND);
         end;
-        IK_RETURN, IK_KPRETURN: 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;
@@ -1215,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;
@@ -1265,7 +1289,7 @@ begin
   case Msg.Msg of
     WM_KEYDOWN:
       case Msg.wParam of
-        IK_RETURN, IK_KPRETURN: 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;
@@ -1319,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);
 
@@ -1517,7 +1541,7 @@ begin
     WM_KEYDOWN:
     begin
       case Msg.wParam of
-        IK_UP, IK_KPUP:
+        IK_UP, IK_KPUP, VK_UP,JOY0_UP, JOY1_UP, JOY2_UP, JOY3_UP:
         begin
           c := 0;
           repeat
@@ -1538,7 +1562,7 @@ begin
           g_Sound_PlayEx(MENU_CHANGESOUND);
         end;
 
-        IK_DOWN, IK_KPDOWN:
+        IK_DOWN, IK_KPDOWN, VK_DOWN, JOY0_DOWN, JOY1_DOWN, JOY2_DOWN, JOY3_DOWN:
         begin
           c := 0;
           repeat
@@ -1559,13 +1583,15 @@ begin
           g_Sound_PlayEx(MENU_CHANGESOUND);
         end;
 
-        IK_LEFT, IK_RIGHT, IK_KPLEFT, IK_KPRIGHT:
+        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_KPRETURN:
+        IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK:
         begin
           if FIndex <> -1 then
           begin
@@ -2094,14 +2120,14 @@ begin
     WM_KEYDOWN:
     begin
       case Msg.wParam of
-        IK_LEFT, IK_KPLEFT:
+        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_KPRIGHT:
+        IK_RIGHT, IK_KPRIGHT, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT:
           if FValue < FMax then
           begin
             Inc(FValue);
@@ -2135,7 +2161,7 @@ begin
 
   FIndex := -1;
 
-  FFont := TFont.Create(FontID, FONT_CHAR);
+  FFont := TFont.Create(FontID, TFontType.Character);
 end;
 
 procedure TGUISwitch.Draw;
@@ -2178,7 +2204,9 @@ begin
   case Msg.Msg of
     WM_KEYDOWN:
       case Msg.wParam of
-        IK_RETURN, IK_RIGHT, IK_KPRETURN, IK_KPRIGHT:
+        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)
@@ -2189,7 +2217,8 @@ begin
             FOnChangeEvent(Self);
         end;
 
-    IK_LEFT, IK_KPLEFT:
+    IK_LEFT, IK_KPLEFT, VK_LEFT,
+    JOY0_LEFT, JOY1_LEFT, JOY2_LEFT, JOY3_LEFT:
       begin
         if FIndex > 0 then
           Dec(FIndex)
@@ -2215,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);
@@ -2228,6 +2258,7 @@ end;
 procedure TGUIEdit.Draw;
 var
   c, w, h: Word;
+  r, g, b: Byte;
 begin
   inherited;
 
@@ -2237,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);
@@ -2290,9 +2325,9 @@ begin
           IK_DELETE: Delete(FText, FCaretPos + 1, 1);
           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:
+          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
@@ -2309,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);
@@ -2331,7 +2369,7 @@ begin
   FKey := 0;
   FIsQuery := false;
 
-  FFont := TFont.Create(FontID, FONT_CHAR);
+  FFont := TFont.Create(FontID, TFontType.Character);
 end;
 
 procedure TGUIKeyRead.Draw;
@@ -2389,12 +2427,12 @@ begin
     case Msg of
       WM_KEYDOWN:
         case wParam of
-          IK_ESCAPE:
+          VK_ESCAPE:
             begin
               if FIsQuery then actDefCtl();
               FIsQuery := False;
             end;
-          IK_RETURN, IK_KPRETURN:
+          IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK:
             begin
               if not FIsQuery then
                 begin
@@ -2404,9 +2442,10 @@ begin
 
                   FIsQuery := True;
                 end
-              else
+              else if (wParam < VK_FIRSTKEY) and (wParam > VK_LASTKEY) then
                 begin
-                  FKey := IK_ENTER; // <Enter>
+                  // FKey := IK_ENTER; // <Enter>
+                  FKey := wParam;
                   FIsQuery := False;
                   actDefCtl();
                 end;
@@ -2428,15 +2467,21 @@ begin
             FKey := 0;
             actDefCtl();
           end
-          else if FIsQuery and (wParam <> IK_ENTER) and (wParam <> IK_KPRETURN) then // Not <Enter
+          else if FIsQuery then
           begin
-            if e_KeyNames[wParam] <> '' then
-              FKey := wParam;
-            FIsQuery := False;
-            actDefCtl();
+            case wParam of
+              IK_ENTER, IK_KPRETURN, VK_FIRSTKEY..VK_LASTKEY, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: // Not <Enter
+            else
+              if e_KeyNames[wParam] <> '' then
+                FKey := wParam;
+              FIsQuery := False;
+              actDefCtl();
+            end
           end;
         end;
     end;
+
+  g_GUIGrabInput := FIsQuery
 end;
 
 { TGUIKeyRead2 }
@@ -2454,7 +2499,7 @@ begin
   FIsQuery := False;
 
   FFontID := FontID;
-  FFont := TFont.Create(FontID, FONT_CHAR);
+  FFont := TFont.Create(FontID, TFontType.Character);
 
   FMaxKeyNameWdt := 0;
   for a := 0 to 255 do
@@ -2508,11 +2553,14 @@ end;
 
 function TGUIKeyRead2.WantActivationKey (key: LongInt): Boolean;
 begin
-  result :=
-    (key = IK_BACKSPACE) or
-    (key = IK_LEFT) or (key = IK_RIGHT) or
-    (key = IK_KPLEFT) or (key = IK_KPRIGHT) or
-    false; // oops
+  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);
@@ -2535,12 +2583,12 @@ begin
     case Msg of
       WM_KEYDOWN:
         case wParam of
-          IK_ESCAPE:
+          VK_ESCAPE:
             begin
               if FIsQuery then actDefCtl();
               FIsQuery := False;
             end;
-          IK_RETURN, IK_KPRETURN:
+          IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK:
             begin
               if not FIsQuery then
                 begin
@@ -2550,9 +2598,10 @@ begin
 
                   FIsQuery := True;
                 end
-              else
+              else if (wParam < VK_FIRSTKEY) and (wParam > VK_LASTKEY) then
                 begin
-                  if (FKeyIdx = 0) then FKey0 := IK_ENTER else FKey1 := IK_ENTER; // <Enter>
+                  // if (FKeyIdx = 0) then FKey0 := IK_ENTER else FKey1 := IK_ENTER; // <Enter>
+                  if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam;
                   FIsQuery := False;
                   actDefCtl();
                 end;
@@ -2565,13 +2614,13 @@ begin
                 actDefCtl();
               end;
             end;
-          IK_LEFT, IK_KPLEFT:
+          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:
+          IK_RIGHT, IK_KPRIGHT, VK_RIGHT, JOY0_RIGHT, JOY1_RIGHT, JOY2_RIGHT, JOY3_RIGHT:
             if not FIsQuery then
             begin
               FKeyIdx := 1;
@@ -2586,17 +2635,23 @@ begin
             if (FKeyIdx = 0) then FKey0 := 0 else FKey1 := 0;
             actDefCtl();
           end
-          else if FIsQuery and (wParam <> IK_ENTER) and (wParam <> IK_KPRETURN) then // Not <Enter
+          else if FIsQuery then
           begin
-            if e_KeyNames[wParam] <> '' then
-            begin
-              if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam;
-            end;
-            FIsQuery := False;
-            actDefCtl();
+            case wParam of
+              IK_ENTER, IK_KPRETURN, VK_FIRSTKEY..VK_LASTKEY, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK: // Not <Enter
+            else
+              if e_KeyNames[wParam] <> '' then
+              begin
+                if (FKeyIdx = 0) then FKey0 := wParam else FKey1 := wParam;
+              end;
+              FIsQuery := False;
+              actDefCtl()
+            end
           end;
         end;
     end;
+
+  g_GUIGrabInput := FIsQuery
 end;
 
 
@@ -2927,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;
@@ -3003,21 +3058,21 @@ begin
             FIndex := High(FItems);
             FStartLine := Max(High(FItems)-FHeight+1, 0);
           end;
-          IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT:
+          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_KPDOWN, IK_KPRIGHT:
+          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_KPRETURN:
+          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)
@@ -3049,7 +3104,7 @@ begin
   Result := FItems[FIndex];
 end;
 
-procedure TGUIListBox.FSetItems(Items: SArray);
+procedure TGUIListBox.FSetItems(Items: SSArray);
 begin
   if FItems <> nil then
     FItems := nil;
@@ -3105,7 +3160,7 @@ end;
 
 procedure TGUIFileListBox.OnMessage(var Msg: TMessage);
 var
-  a: Integer;
+  a, b: Integer;
 begin
   if not FEnabled then
     Exit;
@@ -3159,7 +3214,7 @@ begin
                 FStartLine := High(FItems)-FHeight+1;
             end;
 
-          IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT:
+          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);
@@ -3169,7 +3224,7 @@ begin
                 FOnChangeEvent(Self);
             end;
 
-          IK_DOWN, IK_RIGHT, IK_KPDOWN, IK_KPRIGHT:
+          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);
@@ -3179,7 +3234,7 @@ begin
                 FOnChangeEvent(Self);
             end;
 
-          IK_RETURN, IK_KPRETURN:
+          IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK:
             with FWindow do
             begin
               if FActiveControl <> Self then
@@ -3202,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
@@ -3215,6 +3272,7 @@ begin
               FOnChangeEvent(Self);
             Break;
           end;
+        end;
     end;
 end;
 
@@ -3314,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;
@@ -3360,13 +3418,13 @@ begin
     case Msg of
       WM_KEYDOWN:
         case wParam of
-          IK_UP, IK_LEFT, IK_KPUP, IK_KPLEFT:
+          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_KPDOWN, IK_KPRIGHT:
+          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_KPRETURN:
+          IK_RETURN, IK_KPRETURN, VK_FIRE, VK_OPEN, JOY0_ATTACK, JOY1_ATTACK, JOY2_ATTACK, JOY3_ATTACK:
             with FWindow do
             begin
               if FActiveControl <> Self then