Lock mouse position

This commit is contained in:
teinarss
2019-05-01 10:53:08 +02:00
committed by abcdefg30
parent 7bbfd823d0
commit ffd3834849
11 changed files with 101 additions and 73 deletions

View File

@@ -20,12 +20,26 @@ namespace OpenRA.Graphics
{
readonly Dictionary<string, IHardwareCursor[]> hardwareCursors = new Dictionary<string, IHardwareCursor[]>();
readonly CursorProvider cursorProvider;
readonly Dictionary<string, Sprite[]> sprites = new Dictionary<string, Sprite[]>();
readonly SheetBuilder sheetBuilder;
readonly HardwarePalette hardwarePalette = new HardwarePalette();
readonly Cache<string, PaletteReference> paletteReferences;
CursorSequence cursor;
bool isLocked = false;
int2 lockedPosition;
public HardwareCursor(CursorProvider cursorProvider)
{
this.cursorProvider = cursorProvider;
paletteReferences = new Cache<string, PaletteReference>(CreatePaletteReference);
foreach (var p in cursorProvider.Palettes)
hardwarePalette.AddPalette(p.Key, p.Value, false);
hardwarePalette.Initialize();
sheetBuilder = new SheetBuilder(SheetType.Indexed);
foreach (var kv in cursorProvider.Cursors)
{
var palette = cursorProvider.Palettes[kv.Value.Palette];
@@ -34,11 +48,22 @@ namespace OpenRA.Graphics
.ToArray();
hardwareCursors.Add(kv.Key, hc);
var s = kv.Value.Frames.Select(a => sheetBuilder.Add(a)).ToArray();
sprites.Add(kv.Key, s);
}
sheetBuilder.Current.ReleaseBuffer();
Update();
}
PaletteReference CreatePaletteReference(string name)
{
var pal = hardwarePalette.GetPalette(name);
return new PaletteReference(name, hardwarePalette.GetPaletteIndex(name), pal, hardwarePalette);
}
IHardwareCursor CreateCursor(ISpriteFrame f, ImmutablePalette palette, string name, CursorSequence sequence)
{
var hotspot = sequence.Hotspot - f.Offset.ToInt2() + new int2(f.Size) / 2;
@@ -96,6 +121,7 @@ namespace OpenRA.Graphics
int frame;
int ticks;
public void Tick()
{
if (cursor == null || cursor.Length == 1)
@@ -123,9 +149,35 @@ namespace OpenRA.Graphics
}
}
public void Render(Renderer renderer) { }
public void Render(Renderer renderer)
{
if (cursor.Name == null || !isLocked)
return;
public int Frame { get { return frame; } }
var cursorSequence = cursorProvider.GetCursorSequence(cursor.Name);
var cursorSprite = sprites[cursor.Name][frame];
var cursorOffset = cursorSequence.Hotspot + (0.5f * cursorSprite.Size.XY).ToInt2();
renderer.SetPalette(hardwarePalette);
renderer.SpriteRenderer.DrawSprite(cursorSprite,
lockedPosition - cursorOffset,
paletteReferences[cursorSequence.Palette],
cursorSprite.Size);
}
public void Lock()
{
lockedPosition = Viewport.LastMousePos;
Game.Renderer.Window.SetRelativeMouseMode(true);
isLocked = true;
}
public void Unlock()
{
Game.Renderer.Window.SetRelativeMouseMode(false);
isLocked = false;
}
public void Dispose()
{
@@ -133,6 +185,7 @@ namespace OpenRA.Graphics
foreach (var cursor in cursors.Value)
cursor.Dispose();
sheetBuilder.Dispose();
hardwareCursors.Clear();
}
}

View File

@@ -52,6 +52,7 @@ namespace OpenRA
IHardwareCursor CreateHardwareCursor(string name, Size size, byte[] data, int2 hotspot);
void SetHardwareCursor(IHardwareCursor cursor);
void SetRelativeMouseMode(bool mode);
}
public interface IGraphicsContext : IDisposable

View File

@@ -21,7 +21,8 @@ namespace OpenRA.Graphics
void Render(Renderer renderer);
void SetCursor(string cursor);
void Tick();
int Frame { get; }
void Lock();
void Unlock();
}
public sealed class SoftwareCursor : ICursor
@@ -32,6 +33,9 @@ namespace OpenRA.Graphics
readonly CursorProvider cursorProvider;
readonly SheetBuilder sheetBuilder;
bool isLocked = false;
int2 lockedPosition;
public SoftwareCursor(CursorProvider cursorProvider)
{
this.cursorProvider = cursorProvider;
@@ -78,7 +82,7 @@ namespace OpenRA.Graphics
return;
var cursorSequence = cursorProvider.GetCursorSequence(cursorName);
var cursorSprite = sprites[cursorName][Frame];
var cursorSprite = sprites[cursorName][(int)cursorFrame % cursorSequence.Length];
var cursorSize = CursorProvider.CursorViewportZoomed ? 2.0f * cursorSprite.Size : cursorSprite.Size;
var cursorOffset = CursorProvider.CursorViewportZoomed ?
@@ -86,19 +90,24 @@ namespace OpenRA.Graphics
cursorSequence.Hotspot + (0.5f * cursorSprite.Size.XY).ToInt2();
renderer.SetPalette(palette);
var mousePos = isLocked ? lockedPosition : Viewport.LastMousePos;
renderer.SpriteRenderer.DrawSprite(cursorSprite,
Viewport.LastMousePos - cursorOffset,
mousePos - cursorOffset,
paletteReferences[cursorSequence.Palette],
cursorSize);
}
public int Frame
public void Lock()
{
get
{
var cursorSequence = cursorProvider.GetCursorSequence(cursorName);
return (int)cursorFrame % cursorSequence.Length;
}
Game.Renderer.Window.SetRelativeMouseMode(true);
lockedPosition = Viewport.LastMousePos;
isLocked = true;
}
public void Unlock()
{
Game.Renderer.Window.SetRelativeMouseMode(false);
isLocked = false;
}
public void Dispose()

View File

@@ -39,12 +39,6 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Enables the player directional targeting")]
public readonly bool UseDirectionalTarget = false;
[Desc("Placeholder cursor animation for the target cursor when using directional targeting.")]
public readonly string TargetPlaceholderCursorAnimation = null;
[Desc("Palette for placeholder cursor animation.")]
public readonly string TargetPlaceholderCursorPalette = "chrome";
[Desc("Animation used to render the direction arrows.")]
public readonly string DirectionArrowAnimation = null;
@@ -75,8 +69,7 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
Info.SelectTargetSpeechNotification, self.Owner.Faction.InternalName);
self.World.OrderGenerator = new SelectDirectionalTarget(self.World, order, manager, Info.Cursor,
info.TargetPlaceholderCursorAnimation, info.DirectionArrowAnimation, info.TargetPlaceholderCursorPalette, info.DirectionArrowPalette);
self.World.OrderGenerator = new SelectDirectionalTarget(self.World, order, manager, Info.Cursor, info.DirectionArrowAnimation, info.DirectionArrowPalette);
}
else
base.SelectTarget(self, order, manager);

View File

@@ -53,12 +53,6 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Enables the player directional targeting")]
public readonly bool UseDirectionalTarget = false;
[Desc("Placeholder cursor animation for the target cursor when using directional targeting.")]
public readonly string TargetPlaceholderCursorAnimation = null;
[Desc("Palette for placeholder cursor animation.")]
public readonly string TargetPlaceholderCursorPalette = "chrome";
[Desc("Animation used to render the direction arrows.")]
public readonly string DirectionArrowAnimation = null;
@@ -89,8 +83,7 @@ namespace OpenRA.Mods.Common.Traits
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech",
Info.SelectTargetSpeechNotification, self.Owner.Faction.InternalName);
self.World.OrderGenerator = new SelectDirectionalTarget(self.World, order, manager, Info.Cursor,
info.TargetPlaceholderCursorAnimation, info.DirectionArrowAnimation, info.TargetPlaceholderCursorPalette, info.DirectionArrowPalette);
self.World.OrderGenerator = new SelectDirectionalTarget(self.World, order, manager, Info.Cursor, info.DirectionArrowAnimation, info.DirectionArrowPalette);
}
else
base.SelectTarget(self, order, manager);

View File

@@ -22,9 +22,7 @@ namespace OpenRA.Mods.Common.Traits
readonly string order;
readonly SupportPowerManager manager;
readonly string cursor;
readonly string targetPlaceholderCursorPalette;
readonly string directionArrowPalette;
readonly Animation targetCursor;
readonly string[] arrows = { "arrow-t", "arrow-tl", "arrow-l", "arrow-bl", "arrow-b", "arrow-br", "arrow-r", "arrow-tr" };
readonly Arrow[] directionArrows;
@@ -34,24 +32,17 @@ namespace OpenRA.Mods.Common.Traits
int2 dragLocation;
bool activated;
bool dragStarted;
bool hideMouse = true;
Arrow currentArrow;
public SelectDirectionalTarget(World world, string order, SupportPowerManager manager, string cursor, string targetPlaceholderCursorAnimation,
string directionArrowAnimation, string targetPlaceholderCursorPalette, string directionArrowPalette)
public SelectDirectionalTarget(World world, string order, SupportPowerManager manager, string cursor,
string directionArrowAnimation, string directionArrowPalette)
{
this.order = order;
this.manager = manager;
this.cursor = cursor;
this.targetPlaceholderCursorPalette = targetPlaceholderCursorPalette;
this.directionArrowPalette = directionArrowPalette;
targetCursor = new Animation(world, targetPlaceholderCursorAnimation);
targetCursor.PlayRepeating("cursor");
for (var i = 0; i < Game.Cursor.Frame; i++)
targetCursor.Tick();
directionArrows = LoadArrows(directionArrowAnimation, world, arrows.Length);
}
@@ -70,6 +61,7 @@ namespace OpenRA.Mods.Common.Traits
targetCell = cell;
targetLocation = mi.Location;
activated = true;
Game.Cursor.Lock();
}
yield break;
@@ -101,8 +93,6 @@ namespace OpenRA.Mods.Common.Traits
void IOrderGenerator.Tick(World world)
{
targetCursor.Tick();
// Cancel the OG if we can't use the power
if (!manager.Powers.ContainsKey(order))
world.CancelInputMode();
@@ -118,28 +108,16 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<IRenderable> IOrderGenerator.RenderAboveShroud(WorldRenderer wr, World world)
{
if (!activated)
return Enumerable.Empty<IRenderable>();
yield break;
var targetPalette = wr.Palette(targetPlaceholderCursorPalette);
var location = activated ? targetLocation : Viewport.LastMousePos;
var worldPx = wr.Viewport.ViewToWorldPx(location);
var worldPx = wr.Viewport.ViewToWorldPx(targetLocation);
var worldPos = wr.ProjectedPosition(worldPx);
var renderables = new List<IRenderable>(targetCursor.Render(worldPos, WVec.Zero, -511, targetPalette, 1 / wr.Viewport.Zoom));
if (IsOutsideDragZone)
{
var directionPalette = wr.Palette(directionArrowPalette);
renderables.Add(new SpriteRenderable(currentArrow.Sprite, worldPos, WVec.Zero, -511, directionPalette, 1 / wr.Viewport.Zoom, true));
yield return new SpriteRenderable(currentArrow.Sprite, worldPos, WVec.Zero, -511, directionPalette, 1 / wr.Viewport.Zoom, true);
}
if (hideMouse)
{
hideMouse = false;
Game.RunAfterTick(() => Game.HideCursor = true);
}
return renderables;
}
string IOrderGenerator.GetCursor(World world, CPos cell, int2 worldPixel, MouseInput mi) { return cursor; }
@@ -149,7 +127,7 @@ namespace OpenRA.Mods.Common.Traits
void IOrderGenerator.Deactivate()
{
if (activated)
Game.HideCursor = false;
Game.Cursor.Unlock();
}
// Starting at (0, -1) and rotating in CCW

View File

@@ -30,6 +30,7 @@ namespace OpenRA.Platforms.Default
Size windowSize;
Size surfaceSize;
float windowScale;
int2 mousePosition;
internal IntPtr Window
{
@@ -276,6 +277,22 @@ namespace OpenRA.Platforms.Default
}
}
public void SetRelativeMouseMode(bool mode)
{
if (mode)
{
int x, y;
SDL.SDL_GetMouseState(out x, out y);
mousePosition = new int2(x, y);
SDL.SDL_SetRelativeMouseMode(SDL.SDL_bool.SDL_TRUE);
}
else
{
SDL.SDL_SetRelativeMouseMode(SDL.SDL_bool.SDL_FALSE);
SDL.SDL_WarpMouseInWindow(window, mousePosition.X, mousePosition.Y);
}
}
internal void WindowSizeChanged()
{
// The ratio between pixels and points can change when moving between displays in OSX

View File

@@ -655,7 +655,6 @@ HQ:
ClockSequence: clock
CircleSequence: circles
UseDirectionalTarget: True
TargetPlaceholderCursorAnimation: airstriketarget
DirectionArrowAnimation: airstrikedirection
SupportPowerPaletteOrder: 10
SupportPowerChargeBar:

View File

@@ -430,12 +430,6 @@ smokland:
Tick: 120
ZOffset: 1023
airstriketarget:
cursor: mouse2
Start: 88
Length: 8
Tick: 80
airstrikedirection:
arrow-t: mouse2
Start: 1

View File

@@ -1487,7 +1487,6 @@ AFLD:
ClockSequence: clock
CircleSequence: circles
UseDirectionalTarget: True
TargetPlaceholderCursorAnimation: paratarget
DirectionArrowAnimation: paradirection
SupportPowerPaletteOrder: 60
ParatroopersPower@paratroopers:
@@ -1509,7 +1508,6 @@ AFLD:
ClockSequence: clock
CircleSequence: circles
UseDirectionalTarget: True
TargetPlaceholderCursorAnimation: paratarget
DirectionArrowAnimation: paradirection
SupportPowerPaletteOrder: 50
AirstrikePower@parabombs:
@@ -1532,7 +1530,6 @@ AFLD:
ClockSequence: clock
CircleSequence: circles
UseDirectionalTarget: True
TargetPlaceholderCursorAnimation: paratarget
DirectionArrowAnimation: paradirection
SupportPowerPaletteOrder: 40
ProductionBar:

View File

@@ -623,12 +623,6 @@ ctflag:
Length: *
UseTilesetExtension: true
paratarget:
cursor: mouse
Start: 82
Length: 8
Tick: 80
paradirection:
arrow-t: mouse
Start: 1