nguillaumin / slick2d-maven

Maven distribution of the Slick2D Gava game development library
BSD 3-Clause "New" or "Revised" License
66 stars 36 forks source link

Fix off-by-one bug for y-position of mouse cursor #16

Closed ghost closed 9 years ago

ghost commented 9 years ago

Hi, it's me again. I fixed a small inaccuracy in the Input class, where the y-position of the mouse cursor at the very the top position was reported as 1, and not 0.

nguillaumin commented 9 years ago

Hm, I'm not sure about this one. It sound odd to me that X is correct but not Y, and that it wasn't reported before as that sound pretty serious.

Could you post a minimal program that reproduces it so I can test on my computer? Thanks.

ghost commented 9 years ago

Hi, thanks for your quick response times.

This short program demonstrates the off-by-one bug for mouse y:

import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public final class OffByOne extends BasicGame {
  public OffByOne() {
    super("OffByOne");
  }

  @Override
  public void init(GameContainer container) {
    // empty
  }

  @Override
  public void update(GameContainer container, int delta) {
    Input input = container.getInput();
    if (input.isKeyDown(Input.KEY_ESCAPE)) {
      container.exit();
    }
  }

  @Override
  public void render(GameContainer container, Graphics g) {
    Input input = container.getInput();
    g.getFont().drawString(10, 10 + 20 * 1, "SCREEN: " + container.getWidth() + "x" + container.getHeight());
    g.getFont().drawString(10, 10 + 20 * 2, "MOUSE:  " + input.getMouseX() + "/" + input.getMouseY());
    g.getFont().drawString(10, 10 + 20 * 4, "PRESS ESCAPE TO EXIT");
  }

  public static void main(String[] args) throws SlickException {
    DisplayMode desktopDisplayMode = Display.getDesktopDisplayMode();
    AppGameContainer container = new AppGameContainer(new OffByOne(),
                                                      desktopDisplayMode.getWidth(),
                                                      desktopDisplayMode.getHeight(),
                                                      desktopDisplayMode.isFullscreenCapable());
    container.setVSync(true);
    container.start();
  }
}

The reason for being X right and Y wrong is that lwjgl/sdl/opengl coordinates have their origin at the bottom left corner, whereas java has top/left coords. So, the Y coordinate gets flipped in Input, by the following formula: mouseY = height - Mouse.getY() The lwjgl/sdl/gl y coordinate runs from 0 to height - 1, resulting in java coordinate height - 0 to height - (height -1), which is the same as from height to 1 (flipped, as intended). Still, the range must be from 0 to height - 1, so subtracting one, as in the patch, would get things right.

nguillaumin commented 9 years ago

Makes sense, thanks for taking the time to explain and provide a test program.