Skip to content

Commit

Permalink
Merge pull request #499 from Avalancs/alt_tab_fix
Browse files Browse the repository at this point in the history
Fix alt-tab during full screen crash
  • Loading branch information
NicholasBatesNZ authored Apr 4, 2020
2 parents 7209435 + 100b660 commit e1a96cf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 18 deletions.
11 changes: 11 additions & 0 deletions engine/src/main/java/org/destinationsol/game/SolCam.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
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;
import org.destinationsol.ui.SolInputManager;
import org.destinationsol.ui.SolUiControl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

Expand All @@ -38,15 +41,16 @@ public class ShipMixedControl implements ShipUiControl {
public final SolUiControl shoot2Ctrl;
public final SolUiControl abilityCtrl;
private final SolUiControl myDownCtrl;
private final Vector2 myMouseWorldPos;
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<SolUiControl> controls) {
GameOptions gameOptions = solApplication.getOptions();
myCursor = Assets.getAtlasRegion("engine:uiCursorTarget");
myMouseWorldPos = new Vector2();
mouseScreenPos = new Vector2();
upCtrl = new SolUiControl(null, false, gameOptions.getKeyUpMouse());
controls.add(upCtrl);
myDownCtrl = new SolUiControl(null, false, gameOptions.getKeyDownMouse());
Expand All @@ -63,22 +67,25 @@ 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);
Boolean ntt = Mover.needsToTurn(hero.getAngle(), desiredAngle, hero.getRotationSpeed(), hero.getRotationAcceleration(), Shooter.MIN_SHOOT_AAD);
if (ntt != null) {
if (ntt) {
myRight = true;
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
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(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()) {
Expand All @@ -95,14 +102,39 @@ 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)) {
throw new RuntimeException("Mouse coordinates are not valid: " + mouseCoords.x + " " + mouseCoords.y);
}

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
Expand Down Expand Up @@ -137,7 +169,7 @@ public TextureAtlas.AtlasRegion getInGameTex() {

@Override
public void blur() {
myLeft = false;
myRight = false;
turnLeft = false;
turnRight = false;
}
}

0 comments on commit e1a96cf

Please sign in to comment.