From eee682ab3503246896ff94bdadfdc5e75b6c58fe Mon Sep 17 00:00:00 2001 From: AvaLanCS Date: Sun, 8 Mar 2020 23:27:12 +0100 Subject: [PATCH 1/2] Fix alt-tab during full screen crash --- .../java/org/destinationsol/game/SolCam.java | 11 +++++ .../game/screens/ShipMixedControl.java | 45 ++++++++++++++++--- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/engine/src/main/java/org/destinationsol/game/SolCam.java b/engine/src/main/java/org/destinationsol/game/SolCam.java index 2da090f4b..92194319a 100644 --- a/engine/src/main/java/org/destinationsol/game/SolCam.java +++ b/engine/src/main/java/org/destinationsol/game/SolCam.java @@ -323,4 +323,15 @@ public Vector2 worldToScreen(SolShip ship) { distanceDifference.y = .5f - distanceDifference.y; return distanceDifference; } + + /** @return true if the camera matrix does not have Nan or infinite values */ + public boolean isMatrixValid() { + for(float i : myCam.combined.val) { + if(!Float.isFinite(i)) { + return false; + } + } + + return true; + } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java b/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java index a0c2f1489..6cebd121e 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java @@ -24,6 +24,7 @@ import org.destinationsol.assets.Assets; import org.destinationsol.common.SolMath; import org.destinationsol.game.Hero; +import org.destinationsol.game.SolCam; import org.destinationsol.game.SolGame; import org.destinationsol.game.input.Mover; import org.destinationsol.game.input.Shooter; @@ -38,7 +39,7 @@ public class ShipMixedControl implements ShipUiControl { public final SolUiControl shoot2Ctrl; public final SolUiControl abilityCtrl; private final SolUiControl myDownCtrl; - private final Vector2 myMouseWorldPos; + private final Vector2 myMouseScreenPos; private final TextureAtlas.AtlasRegion myCursor; private boolean myRight; private boolean myLeft; @@ -46,7 +47,7 @@ public class ShipMixedControl implements ShipUiControl { ShipMixedControl(SolApplication solApplication, List controls) { GameOptions gameOptions = solApplication.getOptions(); myCursor = Assets.getAtlasRegion("engine:uiCursorTarget"); - myMouseWorldPos = new Vector2(); + myMouseScreenPos = new Vector2(); upCtrl = new SolUiControl(null, false, gameOptions.getKeyUpMouse()); controls.add(upCtrl); myDownCtrl = new SolUiControl(null, false, gameOptions.getKeyDownMouse()); @@ -63,16 +64,19 @@ public class ShipMixedControl implements ShipUiControl { public void update(SolApplication solApplication, boolean enabled) { GameOptions gameOptions = solApplication.getOptions(); blur(); - if (!enabled) { + SolGame game = solApplication.getGame(); + if (!enabled || problemWithProjections(game.getCam())) { return; } SolInputManager im = solApplication.getInputManager(); - SolGame game = solApplication.getGame(); Hero hero = game.getHero(); if (hero.isNonTranscendent()) { - myMouseWorldPos.set(Gdx.input.getX(), Gdx.input.getY()); - game.getCam().screenToWorld(myMouseWorldPos); - float desiredAngle = SolMath.angle(hero.getPosition(), myMouseWorldPos); + myMouseScreenPos.set(Gdx.input.getX(), Gdx.input.getY()); + // project mouse coordinates [0;width] and [0;height] to screen coordinates [0,1], [0,1] by scaling down + myMouseScreenPos.scl(1.0f / Gdx.graphics.getWidth(), 1.0f / Gdx.graphics.getHeight()); + Vector2 shipOnScreen = game.getCam().worldToScreen(hero.getShip()); // unproject hero to screen coordinates + assertHeroAndMouseCoords(myMouseScreenPos, shipOnScreen); + float desiredAngle = SolMath.angle(shipOnScreen, myMouseScreenPos); Boolean ntt = Mover.needsToTurn(hero.getAngle(), desiredAngle, hero.getRotationSpeed(), hero.getRotationAcceleration(), Shooter.MIN_SHOOT_AAD); if (ntt != null) { if (ntt) { @@ -95,6 +99,33 @@ public void update(SolApplication solApplication, boolean enabled) { } } + /** + * When alt+tabbing in full screen mode, the client area can become 0 with/height, and when alt+tabbing back, + * the camera matrix can contain NaN values for the first frame + * @return true if projections should not be done this update + */ + private boolean problemWithProjections(SolCam camera) { + return Gdx.graphics.getWidth() == 0 || Gdx.graphics.getHeight() == 0 || + camera.getViewWidth() <= 0.f || camera.getViewHeight() <= 0.f || !camera.isMatrixValid(); + } + + /** + * Assert that the following vectors do not contain NaN or infinite values + * @param mouseCoords mouse coordinates in [0;1] screen space + * @param heroCoords hero coordinates projected to [0;1] screen space + */ + private void assertHeroAndMouseCoords(Vector2 mouseCoords, Vector2 heroCoords) { + if(Double.isNaN(mouseCoords.x) || Double.isNaN(mouseCoords.y)) { + System.err.println("Screen size: " + Gdx.graphics.getWidth() + " " + Gdx.graphics.getHeight()); + throw new RuntimeException("Mouse coordinates are not valid: " + mouseCoords.x + " " + mouseCoords.y); + } + + if(Double.isNaN(heroCoords.x) || Double.isNaN(heroCoords.y)) { + System.err.println("Screen size: " + Gdx.graphics.getWidth() + " " + Gdx.graphics.getHeight()); + throw new RuntimeException("Hero coordinates are not valid: " + heroCoords.x + " " + heroCoords.y); + } + } + @Override public boolean isLeft() { return myLeft; From 100b66057bc6316864dcc51fc1116356a4c65e3a Mon Sep 17 00:00:00 2001 From: AvaLanCS Date: Thu, 12 Mar 2020 00:10:56 +0100 Subject: [PATCH 2/2] fix style issues --- .../java/org/destinationsol/game/SolCam.java | 4 +- .../game/screens/ShipMixedControl.java | 43 ++++++++++--------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/engine/src/main/java/org/destinationsol/game/SolCam.java b/engine/src/main/java/org/destinationsol/game/SolCam.java index 92194319a..4e2e173b6 100644 --- a/engine/src/main/java/org/destinationsol/game/SolCam.java +++ b/engine/src/main/java/org/destinationsol/game/SolCam.java @@ -326,8 +326,8 @@ public Vector2 worldToScreen(SolShip ship) { /** @return true if the camera matrix does not have Nan or infinite values */ public boolean isMatrixValid() { - for(float i : myCam.combined.val) { - if(!Float.isFinite(i)) { + for (float i : myCam.combined.val) { + if (!Float.isFinite(i)) { return false; } } diff --git a/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java b/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java index 6cebd121e..3f10a3fb6 100644 --- a/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java +++ b/engine/src/main/java/org/destinationsol/game/screens/ShipMixedControl.java @@ -30,6 +30,8 @@ import org.destinationsol.game.input.Shooter; import org.destinationsol.ui.SolInputManager; import org.destinationsol.ui.SolUiControl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.List; @@ -39,15 +41,16 @@ public class ShipMixedControl implements ShipUiControl { public final SolUiControl shoot2Ctrl; public final SolUiControl abilityCtrl; private final SolUiControl myDownCtrl; - private final Vector2 myMouseScreenPos; + private final Vector2 mouseScreenPos; private final TextureAtlas.AtlasRegion myCursor; - private boolean myRight; - private boolean myLeft; + private boolean turnRight; + private boolean turnLeft; + private Logger logger = LoggerFactory.getLogger(ShipMixedControl.class); ShipMixedControl(SolApplication solApplication, List controls) { GameOptions gameOptions = solApplication.getOptions(); myCursor = Assets.getAtlasRegion("engine:uiCursorTarget"); - myMouseScreenPos = new Vector2(); + mouseScreenPos = new Vector2(); upCtrl = new SolUiControl(null, false, gameOptions.getKeyUpMouse()); controls.add(upCtrl); myDownCtrl = new SolUiControl(null, false, gameOptions.getKeyDownMouse()); @@ -71,18 +74,18 @@ public void update(SolApplication solApplication, boolean enabled) { SolInputManager im = solApplication.getInputManager(); Hero hero = game.getHero(); if (hero.isNonTranscendent()) { - myMouseScreenPos.set(Gdx.input.getX(), Gdx.input.getY()); + mouseScreenPos.set(Gdx.input.getX(), Gdx.input.getY()); // project mouse coordinates [0;width] and [0;height] to screen coordinates [0,1], [0,1] by scaling down - myMouseScreenPos.scl(1.0f / Gdx.graphics.getWidth(), 1.0f / Gdx.graphics.getHeight()); + mouseScreenPos.scl(1.0f / Gdx.graphics.getWidth(), 1.0f / Gdx.graphics.getHeight()); Vector2 shipOnScreen = game.getCam().worldToScreen(hero.getShip()); // unproject hero to screen coordinates - assertHeroAndMouseCoords(myMouseScreenPos, shipOnScreen); - float desiredAngle = SolMath.angle(shipOnScreen, myMouseScreenPos); - Boolean ntt = Mover.needsToTurn(hero.getAngle(), desiredAngle, hero.getRotationSpeed(), hero.getRotationAcceleration(), Shooter.MIN_SHOOT_AAD); - if (ntt != null) { - if (ntt) { - myRight = true; + assertHeroAndMouseCoords(mouseScreenPos, shipOnScreen); + float desiredAngle = SolMath.angle(shipOnScreen, mouseScreenPos); + Boolean needsToTurn = Mover.needsToTurn(hero.getAngle(), desiredAngle, hero.getRotationSpeed(), hero.getRotationAcceleration(), Shooter.MIN_SHOOT_AAD); + if (needsToTurn != null) { + if (needsToTurn) { + turnRight = true; } else { - myLeft = true; + turnLeft = true; } } if (!im.isMouseOnUi()) { @@ -115,25 +118,23 @@ private boolean problemWithProjections(SolCam camera) { * @param heroCoords hero coordinates projected to [0;1] screen space */ private void assertHeroAndMouseCoords(Vector2 mouseCoords, Vector2 heroCoords) { - if(Double.isNaN(mouseCoords.x) || Double.isNaN(mouseCoords.y)) { - System.err.println("Screen size: " + Gdx.graphics.getWidth() + " " + Gdx.graphics.getHeight()); + if (Double.isNaN(mouseCoords.x) || Double.isNaN(mouseCoords.y)) { throw new RuntimeException("Mouse coordinates are not valid: " + mouseCoords.x + " " + mouseCoords.y); } - if(Double.isNaN(heroCoords.x) || Double.isNaN(heroCoords.y)) { - System.err.println("Screen size: " + Gdx.graphics.getWidth() + " " + Gdx.graphics.getHeight()); + if (Double.isNaN(heroCoords.x) || Double.isNaN(heroCoords.y)) { throw new RuntimeException("Hero coordinates are not valid: " + heroCoords.x + " " + heroCoords.y); } } @Override public boolean isLeft() { - return myLeft; + return turnLeft; } @Override public boolean isRight() { - return myRight; + return turnRight; } @Override @@ -168,7 +169,7 @@ public TextureAtlas.AtlasRegion getInGameTex() { @Override public void blur() { - myLeft = false; - myRight = false; + turnLeft = false; + turnRight = false; } }