Add a dialog when closing the settings screen asking the user if they would like to restart the game now in order to apply any settings that are only applied after restarting the game. The game is reloaded in-process by spinning up a new AppDomain in order to reset state.
191 lines
4.8 KiB
C#
191 lines
4.8 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation. For more information,
|
|
* see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System.Text;
|
|
using SDL2;
|
|
|
|
namespace OpenRA.Renderer.Sdl2
|
|
{
|
|
public class Sdl2Input
|
|
{
|
|
MouseButton lastButtonBits = (MouseButton)0;
|
|
|
|
static MouseButton MakeButton(byte b)
|
|
{
|
|
return b == SDL.SDL_BUTTON_LEFT ? MouseButton.Left
|
|
: b == SDL.SDL_BUTTON_RIGHT ? MouseButton.Right
|
|
: b == SDL.SDL_BUTTON_MIDDLE ? MouseButton.Middle
|
|
: 0;
|
|
}
|
|
|
|
static Modifiers MakeModifiers(int raw)
|
|
{
|
|
return ((raw & (int)SDL.SDL_Keymod.KMOD_ALT) != 0 ? Modifiers.Alt : 0)
|
|
| ((raw & (int)SDL.SDL_Keymod.KMOD_CTRL) != 0 ? Modifiers.Ctrl : 0)
|
|
| ((raw & (int)SDL.SDL_Keymod.KMOD_LGUI) != 0 ? Modifiers.Meta : 0)
|
|
| ((raw & (int)SDL.SDL_Keymod.KMOD_RGUI) != 0 ? Modifiers.Meta : 0)
|
|
| ((raw & (int)SDL.SDL_Keymod.KMOD_SHIFT) != 0 ? Modifiers.Shift : 0);
|
|
}
|
|
|
|
public void PumpInput(IInputHandler inputHandler)
|
|
{
|
|
var mods = MakeModifiers((int)SDL.SDL_GetModState());
|
|
var scrollDelta = 0;
|
|
inputHandler.ModifierKeys(mods);
|
|
MouseInput? pendingMotion = null;
|
|
|
|
SDL.SDL_Event e;
|
|
while (SDL.SDL_PollEvent(out e) != 0)
|
|
{
|
|
switch (e.type)
|
|
{
|
|
case SDL.SDL_EventType.SDL_QUIT:
|
|
Game.Exit();
|
|
break;
|
|
|
|
case SDL.SDL_EventType.SDL_WINDOWEVENT:
|
|
{
|
|
switch (e.window.windowEvent)
|
|
{
|
|
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_LOST:
|
|
Game.HasInputFocus = false;
|
|
break;
|
|
|
|
case SDL.SDL_WindowEventID.SDL_WINDOWEVENT_FOCUS_GAINED:
|
|
Game.HasInputFocus = true;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case SDL.SDL_EventType.SDL_MOUSEBUTTONDOWN:
|
|
{
|
|
if (pendingMotion != null)
|
|
{
|
|
inputHandler.OnMouseInput(pendingMotion.Value);
|
|
pendingMotion = null;
|
|
}
|
|
|
|
var button = MakeButton(e.button.button);
|
|
lastButtonBits |= button;
|
|
|
|
var pos = new int2(e.button.x, e.button.y);
|
|
|
|
inputHandler.OnMouseInput(new MouseInput(
|
|
MouseInputEvent.Down, button, scrollDelta, pos, mods,
|
|
MultiTapDetection.DetectFromMouse(e.button.button, pos)));
|
|
|
|
break;
|
|
}
|
|
|
|
case SDL.SDL_EventType.SDL_MOUSEBUTTONUP:
|
|
{
|
|
if (pendingMotion != null)
|
|
{
|
|
inputHandler.OnMouseInput(pendingMotion.Value);
|
|
pendingMotion = null;
|
|
}
|
|
|
|
var button = MakeButton(e.button.button);
|
|
lastButtonBits &= ~button;
|
|
|
|
var pos = new int2(e.button.x, e.button.y);
|
|
inputHandler.OnMouseInput(new MouseInput(
|
|
MouseInputEvent.Up, button, scrollDelta, pos, mods,
|
|
MultiTapDetection.InfoFromMouse(e.button.button)));
|
|
|
|
break;
|
|
}
|
|
|
|
case SDL.SDL_EventType.SDL_MOUSEMOTION:
|
|
{
|
|
pendingMotion = new MouseInput(
|
|
MouseInputEvent.Move, lastButtonBits, scrollDelta,
|
|
new int2(e.motion.x, e.motion.y), mods, 0);
|
|
|
|
break;
|
|
}
|
|
|
|
case SDL.SDL_EventType.SDL_MOUSEWHEEL:
|
|
{
|
|
int x, y;
|
|
SDL.SDL_GetMouseState(out x, out y);
|
|
scrollDelta = e.wheel.y;
|
|
inputHandler.OnMouseInput(new MouseInput(MouseInputEvent.Scroll, MouseButton.None, scrollDelta, new int2(x, y), Modifiers.None, 0));
|
|
|
|
break;
|
|
}
|
|
|
|
case SDL.SDL_EventType.SDL_TEXTINPUT:
|
|
{
|
|
string input;
|
|
unsafe
|
|
{
|
|
var data = new byte[SDL.SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
|
var i = 0;
|
|
for (; i < SDL.SDL_TEXTINPUTEVENT_TEXT_SIZE; i++)
|
|
{
|
|
var b = e.text.text[i];
|
|
if (b == '\0')
|
|
break;
|
|
|
|
data[i] = b;
|
|
}
|
|
|
|
input = Encoding.UTF8.GetString(data, 0, i);
|
|
}
|
|
|
|
inputHandler.OnTextInput(input);
|
|
break;
|
|
}
|
|
|
|
case SDL.SDL_EventType.SDL_KEYDOWN:
|
|
case SDL.SDL_EventType.SDL_KEYUP:
|
|
{
|
|
var keyCode = (Keycode)e.key.keysym.sym;
|
|
var type = e.type == SDL.SDL_EventType.SDL_KEYDOWN ?
|
|
KeyInputEvent.Down : KeyInputEvent.Up;
|
|
|
|
var tapCount = e.type == SDL.SDL_EventType.SDL_KEYDOWN ?
|
|
MultiTapDetection.DetectFromKeyboard(keyCode) :
|
|
MultiTapDetection.InfoFromKeyboard(keyCode);
|
|
|
|
var keyEvent = new KeyInput
|
|
{
|
|
Event = type,
|
|
Key = keyCode,
|
|
Modifiers = mods,
|
|
UnicodeChar = (char)e.key.keysym.sym,
|
|
MultiTapCount = tapCount
|
|
};
|
|
|
|
// Special case workaround for windows users
|
|
if (e.key.keysym.sym == SDL.SDL_Keycode.SDLK_F4 && mods.HasModifier(Modifiers.Alt) &&
|
|
Platform.CurrentPlatform == PlatformType.Windows)
|
|
Game.Exit();
|
|
else
|
|
inputHandler.OnKeyInput(keyEvent);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pendingMotion != null)
|
|
{
|
|
inputHandler.OnMouseInput(pendingMotion.Value);
|
|
pendingMotion = null;
|
|
}
|
|
|
|
ErrorHandler.CheckGlError();
|
|
}
|
|
}
|
|
} |