DEADSOFTWARE

e_input cleanup
[d2df-sdl.git] / src / game / g_window.pas
index e57defe11cf4067a739f8f8c986dba9fef8f763b..44997de63c8046824eb8b1c762ad9fb636fe57f1 100644 (file)
@@ -55,7 +55,7 @@ uses
 {$IFDEF ENABLE_HOLMES}
   g_holmes, sdlcarcass, fui_ctls,
 {$ENDIF}
-  SysUtils, Classes, MAPDEF,
+  SysUtils, Classes, MAPDEF, Math,
   SDL2, e_graphics, e_log, e_texture, g_main,
   g_console, e_input, g_options, g_game,
   g_basic, g_textures, e_sound, g_sound, g_menu, ENet, g_net,
@@ -84,7 +84,8 @@ var
   ticksOverflow: Int64 = -1;
   lastTicks: Uint32 = 0; // to detect overflow
 {$ENDIF}
-
+  JoystickHatState: array [0..e_MaxJoys, 0..e_MaxJoyHats, HAT_LEFT..HAT_DOWN] of Boolean;
+  JoystickZeroAxes: array [0..e_MaxJoys, 0..e_MaxJoyAxes] of Integer;
 
 procedure KillGLWindow (preserveGL: Boolean);
 begin
@@ -234,7 +235,7 @@ begin
 end;
 
 
-procedure ChangeWindowSize ();
+procedure ChangeWindowSize (requested: Boolean);
 begin
   e_LogWritefln('  ChangeWindowSize: (ws=%dx%d) (ss=%dx%d)', [gWinSizeX, gWinSizeY, gScreenWidth, gScreenHeight]);
   gWinSizeX := gScreenWidth;
@@ -246,7 +247,13 @@ begin
   {$ENDIF}
   e_ResizeWindow(gScreenWidth, gScreenHeight);
   g_Game_SetupScreenSize();
-  g_Menu_Reset();
+  {$IF DEFINED(ANDROID)}
+    (* This will fix menu reset on keyboard showing *)
+    if requested then
+      g_Menu_Reset;
+  {$ELSE}
+    g_Menu_Reset;
+  {$ENDIF}
   g_Game_ClearLoading();
 {$ENDIF}
 end;
@@ -281,7 +288,7 @@ begin
   if result then
   begin
     g_Window_SetDisplay(preserve);
-    ChangeWindowSize();
+    ChangeWindowSize(true);
   end;
 {$ENDIF}
 end;
@@ -337,7 +344,7 @@ begin
         gScreenWidth := ev.data1;
         gScreenHeight := ev.data2;
       end;
-      ChangeWindowSize();
+      ChangeWindowSize(false);
       SwapBuffers();
       if g_debug_WinMsgs then
       begin
@@ -405,8 +412,7 @@ begin
     if gWinActive then
     begin
       e_WriteLog('deactivating window', TMsgType.Notify);
-      e_EnableInput := false;
-      e_ClearInputBuffer();
+      e_UnpressAllKeys;
 
       if gMuteWhenInactive then
       begin
@@ -432,7 +438,6 @@ begin
     if not gWinActive then
     begin
       //e_WriteLog('activating window', MSG_NOTIFY);
-      e_EnableInput := true;
 
       if gMuteWhenInactive then
       begin
@@ -458,9 +463,12 @@ end;
 
 function EventHandler (var ev: TSDL_Event): Boolean;
 var
-  key, keychr: Word;
+  key, keychr, minuskey: Word;
   uc: UnicodeChar;
   down: Boolean;
+  i: Integer;
+  hat: array [HAT_LEFT..HAT_DOWN] of Boolean;
+  joy: PSDL_Joystick;
 begin
   result := false;
 
@@ -499,10 +507,107 @@ begin
           exit;
         end;
         {$ENDIF}
-        e_KeyUpDown(key, down);
+        if ev.key._repeat = 0 then
+        begin
+          e_KeyUpDown(key, down);
+          g_Console_ProcessBind(key, down)
+        end;
         if down then KeyPress(key);
       end;
 
+    SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP:
+      if (ev.jbutton.which < e_MaxJoys) and (ev.jbutton.button < e_MaxJoyBtns) then
+      begin
+        key := e_JoyButtonToKey(ev.jbutton.which, ev.jbutton.button);
+        down := ev.type_ = SDL_JOYBUTTONDOWN;
+        e_KeyUpDown(key, down);
+        g_Console_ProcessBind(key, down);
+        if down then KeyPress(key)
+      end;
+
+    SDL_JOYAXISMOTION:
+      if (ev.jaxis.which < e_MaxJoys) and (ev.jaxis.axis < e_MaxJoyAxes) then
+      begin
+        key := e_JoyAxisToKey(ev.jaxis.which, ev.jaxis.axis, AX_PLUS);
+        minuskey := e_JoyAxisToKey(ev.jaxis.which, ev.jaxis.axis, AX_MINUS);
+
+        if ev.jaxis.value < JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis] - e_JoystickDeadzones[ev.jaxis.which] then
+        begin
+          if (e_KeyPressed(key)) then
+          begin
+            e_KeyUpDown(key, False);
+            g_Console_ProcessBind(key, False);
+          end;
+          e_KeyUpDown(minuskey, True);
+          g_Console_ProcessBind(minuskey, True);
+          KeyPress(minuskey);
+        end
+        else if ev.jaxis.value > JoystickZeroAxes[ev.jaxis.which, ev.jaxis.axis] + e_JoystickDeadzones[ev.jaxis.which] then
+        begin
+          if (e_KeyPressed(minuskey)) then
+          begin
+            e_KeyUpDown(minuskey, False);
+            g_Console_ProcessBind(minuskey, False);
+          end;
+          e_KeyUpDown(key, True);
+          g_Console_ProcessBind(key, True);
+          KeyPress(key);
+        end
+        else
+        begin
+          if (e_KeyPressed(minuskey)) then
+          begin
+            e_KeyUpDown(minuskey, False);
+            g_Console_ProcessBind(minuskey, False);
+          end;
+          if (e_KeyPressed(key)) then
+          begin
+            e_KeyUpDown(key, False);
+            g_Console_ProcessBind(key, False);
+          end;
+        end;
+      end;
+
+    SDL_JOYHATMOTION:
+      if (ev.jhat.which < e_MaxJoys) and (ev.jhat.hat < e_MaxJoyHats) then
+      begin
+        hat[HAT_UP] := LongBool(ev.jhat.value and SDL_HAT_UP);
+        hat[HAT_DOWN] := LongBool(ev.jhat.value and SDL_HAT_DOWN);
+        hat[HAT_LEFT] := LongBool(ev.jhat.value and SDL_HAT_LEFT);
+        hat[HAT_RIGHT] := LongBool(ev.jhat.value and SDL_HAT_RIGHT);
+        for i := HAT_LEFT to HAT_DOWN do
+        begin
+          if JoystickHatState[ev.jhat.which, ev.jhat.hat, i] <> hat[i] then
+          begin
+            down := hat[i];
+            key := e_JoyHatToKey(ev.jhat.which, ev.jhat.hat, i);
+            e_KeyUpDown(key, down);
+            g_Console_ProcessBind(key, down);
+            if down then KeyPress(key)
+          end
+        end;
+        JoystickHatState[ev.jhat.which, ev.jhat.hat] := hat
+      end;
+
+    SDL_JOYDEVICEADDED:
+      if (ev.jdevice.which < e_MaxJoys) then
+      begin
+        joy := SDL_JoystickOpen(ev.jdevice.which);
+        ASSERT(joy <> nil);
+        e_LogWritefln('Added Joystick %s', [ev.jdevice.which]);
+        e_JoystickAvailable[ev.jdevice.which] := True;
+        for i := 0 to Min(SDL_JoystickNumAxes(joy), e_MaxJoyAxes) do
+          JoystickZeroAxes[ev.jdevice.which, i] := SDL_JoystickGetAxis(joy, i);
+        SDL_JoystickClose(joy)
+      end;
+
+    SDL_JOYDEVICEREMOVED:
+      if (ev.jdevice.which < e_MaxJoys) then
+      begin
+        e_JoystickAvailable[ev.jdevice.which] := False;
+        e_LogWritefln('Removed Joystick %s', [ev.jdevice.which])
+      end;
+
     {$IF not DEFINED(HEADLESS) and DEFINED(ENABLE_HOLMES)}
     SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SDL_MOUSEWHEEL, SDL_MOUSEMOTION:
       fuiOnSDLEvent(ev);
@@ -653,7 +758,7 @@ begin
     EventHandler(ev);
     if (ev.type_ = SDL_QUITEV) then break;
   end;
-  e_PollJoysticks();
+  //e_PollJoysticks();
 
   if (ev.type_ = SDL_QUITEV) or (gExit = EXIT_QUIT) then
   begin
@@ -720,7 +825,7 @@ begin
     result := EventHandler(ev);
     if (ev.type_ = SDL_QUITEV) then exit;
   end;
-  e_PollJoysticks();
+  //e_PollJoysticks();
 end;
 
 
@@ -892,8 +997,10 @@ var
   {$ENDIF}
   arg: AnsiString;
   mdfo: TStream;
+  {$IFDEF ENABLE_HOLMES}
   itmp: Integer;
   valres: Word;
+  {$ENDIF}
 begin
 {$IFDEF HEADLESS}
   e_NoGraphics := true;
@@ -1011,15 +1118,16 @@ begin
   e_LogWritefln('stencil buffer size: %s', [ltmp]);
   gwin_has_stencil := (ltmp > 0);
 
-  if not glHasExtension('GL_ARB_texture_non_power_of_two') then
+  if glHasExtension('GL_ARB_texture_non_power_of_two') or
+     glHasExtension('GL_OES_texture_npot') then
   begin
-    e_WriteLog('NPOT textures: NO', TMsgType.Warning);
-    glLegacyNPOT := true;
+    e_WriteLog('NPOT textures: YES', TMsgType.Notify);
+    glLegacyNPOT := false;
   end
   else
   begin
-    e_WriteLog('NPOT textures: YES', TMsgType.Notify);
-    glLegacyNPOT := false;
+    e_WriteLog('NPOT textures: NO', TMsgType.Warning);
+    glLegacyNPOT := true;
   end;
   gwin_dump_extensions := false;
 {$ENDIF}