diff --git a/pom.xml b/pom.xml
index 9ab36367..473658a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,7 @@
org.slick2d:slick2d-core
+ org/newdawn/slick/GameContainer.*
org/newdawn/slick/Image.*
org/newdawn/slick/Music.*
org/newdawn/slick/openal/AudioInputStream*
diff --git a/res/version b/res/version
index 11f63e48..006a1cd5 100644
--- a/res/version
+++ b/res/version
@@ -1,6 +1,2 @@
-# opsu! build info
version=${pom.version}
build.date=${timestamp}
-
-# slick build
-build=237
diff --git a/src/itdelatrisu/opsu/Container.java b/src/itdelatrisu/opsu/Container.java
index 8bb87adc..b56ae1e3 100644
--- a/src/itdelatrisu/opsu/Container.java
+++ b/src/itdelatrisu/opsu/Container.java
@@ -21,6 +21,7 @@ package itdelatrisu.opsu;
import itdelatrisu.opsu.audio.MusicController;
import itdelatrisu.opsu.downloads.DownloadList;
+import org.lwjgl.opengl.Display;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.Game;
import org.newdawn.slick.SlickException;
@@ -79,6 +80,28 @@ public class Container extends AppGameContainer {
Opsu.exit();
}
+ @Override
+ protected void gameLoop() throws SlickException {
+ int delta = getDelta();
+ if (!Display.isVisible() && updateOnlyOnVisible) {
+ try { Thread.sleep(100); } catch (Exception e) {}
+ } else {
+ try {
+ updateAndRender(delta);
+ } catch (SlickException e) {
+ this.e = e; // store exception to display later
+ running = false;
+ return;
+ }
+ }
+ updateFPS();
+ Display.update();
+ if (Display.isCloseRequested()) {
+ if (game.closeRequested())
+ running = false;
+ }
+ }
+
/**
* Actions to perform before destroying the game container.
*/
@@ -102,16 +125,6 @@ public class Container extends AppGameContainer {
OsuGroupList.get().reset();
}
- @Override
- protected void updateAndRender(int delta) throws SlickException {
- try {
- super.updateAndRender(delta);
- } catch (SlickException e) {
- this.e = e; // store exception to display later
- throw e; // re-throw exception
- }
- }
-
@Override
public void exit() {
// show confirmation dialog if any downloads are active
diff --git a/src/org/newdawn/slick/GameContainer.java b/src/org/newdawn/slick/GameContainer.java
new file mode 100644
index 00000000..3c6cff2d
--- /dev/null
+++ b/src/org/newdawn/slick/GameContainer.java
@@ -0,0 +1,907 @@
+/*
+ * Copyright (c) 2013, Slick2D
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the Slick2D nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.newdawn.slick;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.lwjgl.LWJGLException;
+import org.lwjgl.Sys;
+import org.lwjgl.input.Cursor;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.Drawable;
+import org.lwjgl.opengl.Pbuffer;
+import org.lwjgl.opengl.PixelFormat;
+import org.newdawn.slick.gui.GUIContext;
+import org.newdawn.slick.openal.SoundStore;
+import org.newdawn.slick.opengl.CursorLoader;
+import org.newdawn.slick.opengl.ImageData;
+import org.newdawn.slick.opengl.renderer.Renderer;
+import org.newdawn.slick.opengl.renderer.SGL;
+import org.newdawn.slick.util.Log;
+import org.newdawn.slick.util.ResourceLoader;
+
+/**
+ * A generic game container that handles the game loop, fps recording and
+ * managing the input system
+ *
+ * @author kevin
+ */
+public abstract class GameContainer implements GUIContext {
+ /** The renderer to use for all GL operations */
+ protected static SGL GL = Renderer.get();
+ /** The shared drawable if any */
+ protected static Drawable SHARED_DRAWABLE;
+
+ /** The time the last frame was rendered */
+ protected long lastFrame;
+ /** The last time the FPS recorded */
+ protected long lastFPS;
+ /** The last recorded FPS */
+ protected int recordedFPS;
+ /** The current count of FPS */
+ protected int fps;
+ /** True if we're currently running the game loop */
+ protected boolean running = true;
+
+ /** The width of the display */
+ protected int width;
+ /** The height of the display */
+ protected int height;
+ /** The game being managed */
+ protected Game game;
+
+ /** The default font to use in the graphics context */
+ private Font defaultFont;
+ /** The graphics context to be passed to the game */
+ private Graphics graphics;
+
+ /** The input system to pass to the game */
+ protected Input input;
+ /** The FPS we want to lock to */
+ protected int targetFPS = -1;
+ /** True if we should show the fps */
+ private boolean showFPS = true;
+ /** The minimum logic update interval */
+ protected long minimumLogicInterval = 1;
+ /** The stored delta */
+ protected long storedDelta;
+ /** The maximum logic update interval */
+ protected long maximumLogicInterval = 0;
+ /** The last game started */
+ protected Game lastGame;
+ /** True if we should clear the screen each frame */
+ protected boolean clearEachFrame = true;
+
+ /** True if the game is paused */
+ protected boolean paused;
+ /** True if we should force exit */
+ protected boolean forceExit = true;
+ /** True if vsync has been requested */
+ protected boolean vsync;
+ /** Smoothed deltas requested */
+ protected boolean smoothDeltas;
+ /** The number of samples we'll attempt through hardware */
+ protected int samples;
+
+ /** True if this context supports multisample */
+ protected boolean supportsMultiSample;
+
+ /** True if we should render when not focused */
+ protected boolean alwaysRender;
+ /** True if we require stencil bits */
+ protected static boolean stencil;
+
+ /**
+ * Create a new game container wrapping a given game
+ *
+ * @param game The game to be wrapped
+ */
+ protected GameContainer(Game game) {
+ this.game = game;
+ lastFrame = getTime();
+
+ getBuildVersion();
+ Log.checkVerboseLogSetting();
+ }
+
+ public static void enableStencil() {
+ stencil = true;
+ }
+
+ /**
+ * Set the default font that will be intialised in the graphics held in this container
+ *
+ * @param font The font to use as default
+ */
+ public void setDefaultFont(Font font) {
+ if (font != null) {
+ this.defaultFont = font;
+ } else {
+ Log.warn("Please provide a non null font");
+ }
+ }
+
+ /**
+ * Indicate whether we want to try to use fullscreen multisampling. This will
+ * give antialiasing across the whole scene using a hardware feature.
+ *
+ * @param samples The number of samples to attempt (2 is safe)
+ */
+ public void setMultiSample(int samples) {
+ this.samples = samples;
+ }
+
+ /**
+ * Check if this hardware can support multi-sampling
+ *
+ * @return True if the hardware supports multi-sampling
+ */
+ public boolean supportsMultiSample() {
+ return supportsMultiSample;
+ }
+
+ /**
+ * The number of samples we're attempting to performing using
+ * hardware multisampling
+ *
+ * @return The number of samples requested
+ */
+ public int getSamples() {
+ return samples;
+ }
+
+ /**
+ * Indicate if we should force exitting the VM at the end
+ * of the game (default = true)
+ *
+ * @param forceExit True if we should force the VM exit
+ */
+ public void setForceExit(boolean forceExit) {
+ this.forceExit = forceExit;
+ }
+
+ /**
+ * Indicate if we want to smooth deltas. This feature will report
+ * a delta based on the FPS not the time passed. This works well with
+ * vsync.
+ *
+ * @param smoothDeltas True if we should report smooth deltas
+ */
+ public void setSmoothDeltas(boolean smoothDeltas) {
+ this.smoothDeltas = smoothDeltas;
+ }
+
+ /**
+ * Check if the display is in fullscreen mode
+ *
+ * @return True if the display is in fullscreen mode
+ */
+ public boolean isFullscreen() {
+ return false;
+ }
+
+ /**
+ * Get the aspect ratio of the screen
+ *
+ * @return The aspect ratio of the display
+ */
+ public float getAspectRatio() {
+ return getWidth() / getHeight();
+ }
+
+ /**
+ * Indicate whether we want to be in fullscreen mode. Note that the current
+ * display mode must be valid as a fullscreen mode for this to work
+ *
+ * @param fullscreen True if we want to be in fullscreen mode
+ * @throws SlickException Indicates we failed to change the display mode
+ */
+ public void setFullscreen(boolean fullscreen) throws SlickException {
+ }
+
+ /**
+ * Enable shared OpenGL context. After calling this all containers created
+ * will shared a single parent context
+ *
+ * @throws SlickException Indicates a failure to create the shared drawable
+ */
+ public static void enableSharedContext() throws SlickException {
+ try {
+ SHARED_DRAWABLE = new Pbuffer(64, 64, new PixelFormat(8, 0, 0), null);
+ } catch (LWJGLException e) {
+ throw new SlickException("Unable to create the pbuffer used for shard context, buffers not supported", e);
+ }
+ }
+
+ /**
+ * Get the context shared by all containers
+ *
+ * @return The context shared by all the containers or null if shared context isn't enabled
+ */
+ public static Drawable getSharedContext() {
+ return SHARED_DRAWABLE;
+ }
+
+ /**
+ * Indicate if we should clear the screen at the beginning of each frame. If you're
+ * rendering to the whole screen each frame then setting this to false can give
+ * some performance improvements
+ *
+ * @param clear True if the the screen should be cleared each frame
+ */
+ public void setClearEachFrame(boolean clear) {
+ this.clearEachFrame = clear;
+ }
+
+ /**
+ * Renitialise the game and the context in which it's being rendered
+ *
+ * @throws SlickException Indicates a failure rerun initialisation routines
+ */
+ public void reinit() throws SlickException {
+ }
+
+ /**
+ * Pause the game - i.e. suspend updates
+ */
+ public void pause()
+ {
+ setPaused(true);
+ }
+
+ /**
+ * Resumt the game - i.e. continue updates
+ */
+ public void resume()
+ {
+ setPaused(false);
+ }
+
+ /**
+ * Check if the container is currently paused.
+ *
+ * @return True if the container is paused
+ */
+ public boolean isPaused() {
+ return paused;
+ }
+
+ /**
+ * Indicates if the game should be paused, i.e. if updates
+ * should be propogated through to the game.
+ *
+ * @param paused True if the game should be paused
+ */
+ public void setPaused(boolean paused)
+ {
+ this.paused = paused;
+ }
+
+ /**
+ * True if this container should render when it has focus
+ *
+ * @return True if this container should render when it has focus
+ */
+ public boolean getAlwaysRender () {
+ return alwaysRender;
+ }
+
+ /**
+ * Indicate whether we want this container to render when it has focus
+ *
+ * @param alwaysRender True if this container should render when it has focus
+ */
+ public void setAlwaysRender (boolean alwaysRender) {
+ this.alwaysRender = alwaysRender;
+ }
+
+ /**
+ * Get the build number of slick
+ *
+ * @return The build number of slick
+ */
+ public static int getBuildVersion() {
+ try {
+ Properties props = new Properties();
+ props.load(ResourceLoader.getResourceAsStream("version"));
+
+ int build = Integer.parseInt(props.getProperty("build"));
+ Log.info("Slick Build #"+build);
+
+ return build;
+ } catch (Exception e) {
+ Log.info("Unable to determine Slick build number");
+ return -1;
+ }
+ }
+
+ /**
+ * Get the default system font
+ *
+ * @return The default system font
+ */
+ @Override
+ public Font getDefaultFont() {
+ return defaultFont;
+ }
+
+ /**
+ * Check if sound effects are enabled
+ *
+ * @return True if sound effects are enabled
+ */
+ public boolean isSoundOn() {
+ return SoundStore.get().soundsOn();
+ }
+
+ /**
+ * Check if music is enabled
+ *
+ * @return True if music is enabled
+ */
+ public boolean isMusicOn() {
+ return SoundStore.get().musicOn();
+ }
+
+ /**
+ * Indicate whether music should be enabled
+ *
+ * @param on True if music should be enabled
+ */
+ public void setMusicOn(boolean on) {
+ SoundStore.get().setMusicOn(on);
+ }
+
+ /**
+ * Indicate whether sound effects should be enabled
+ *
+ * @param on True if sound effects should be enabled
+ */
+ public void setSoundOn(boolean on) {
+ SoundStore.get().setSoundsOn(on);
+ }
+
+ /**
+ * Retrieve the current default volume for music
+ * @return the current default volume for music
+ */
+ public float getMusicVolume() {
+ return SoundStore.get().getMusicVolume();
+ }
+
+ /**
+ * Retrieve the current default volume for sound fx
+ * @return the current default volume for sound fx
+ */
+ public float getSoundVolume() {
+ return SoundStore.get().getSoundVolume();
+ }
+
+ /**
+ * Set the default volume for sound fx
+ * @param volume the new default value for sound fx volume
+ */
+ public void setSoundVolume(float volume) {
+ SoundStore.get().setSoundVolume(volume);
+ }
+
+ /**
+ * Set the default volume for music
+ * @param volume the new default value for music volume
+ */
+ public void setMusicVolume(float volume) {
+ SoundStore.get().setMusicVolume(volume);
+ }
+
+ /**
+ * Get the width of the standard screen resolution
+ *
+ * @return The screen width
+ */
+ @Override
+ public abstract int getScreenWidth();
+
+ /**
+ * Get the height of the standard screen resolution
+ *
+ * @return The screen height
+ */
+ @Override
+ public abstract int getScreenHeight();
+
+ /**
+ * Get the width of the game canvas
+ *
+ * @return The width of the game canvas
+ */
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * Get the height of the game canvas
+ *
+ * @return The height of the game canvas
+ */
+ @Override
+ public int getHeight() {
+ return height;
+ }
+
+ /**
+ * Set the icon to be displayed if possible in this type of
+ * container
+ *
+ * @param ref The reference to the icon to be displayed
+ * @throws SlickException Indicates a failure to load the icon
+ */
+ public abstract void setIcon(String ref) throws SlickException;
+
+ /**
+ * Set the icons to be used for this application. Note that the size of the icon
+ * defines how it will be used. Important ones to note
+ *
+ * Windows window icon must be 16x16
+ * Windows alt-tab icon must be 24x24 or 32x32 depending on Windows version (XP=32)
+ *
+ * @param refs The reference to the icon to be displayed
+ * @throws SlickException Indicates a failure to load the icon
+ */
+ public abstract void setIcons(String[] refs) throws SlickException;
+
+ /**
+ * Get the accurate system time
+ *
+ * @return The system time in milliseconds
+ */
+ @Override
+ public long getTime() {
+ return (Sys.getTime() * 1000) / Sys.getTimerResolution();
+ }
+
+ /**
+ * Sleep for a given period
+ *
+ * @param milliseconds The period to sleep for in milliseconds
+ */
+ public void sleep(int milliseconds) {
+ long target = getTime()+milliseconds;
+ while (getTime() < target) {
+ try { Thread.sleep(1); } catch (Exception e) {}
+ }
+ }
+
+ /**
+ * Set the mouse cursor to be displayed - this is a hardware cursor and hence
+ * shouldn't have any impact on FPS.
+ *
+ * @param ref The location of the image to be loaded for the cursor
+ * @param hotSpotX The x coordinate of the hotspot within the cursor image
+ * @param hotSpotY The y coordinate of the hotspot within the cursor image
+ * @throws SlickException Indicates a failure to load the cursor image or create the hardware cursor
+ */
+ @Override
+ public abstract void setMouseCursor(String ref, int hotSpotX, int hotSpotY) throws SlickException;
+
+ /**
+ * Set the mouse cursor to be displayed - this is a hardware cursor and hence
+ * shouldn't have any impact on FPS.
+ *
+ * @param data The image data from which the cursor can be construted
+ * @param hotSpotX The x coordinate of the hotspot within the cursor image
+ * @param hotSpotY The y coordinate of the hotspot within the cursor image
+ * @throws SlickException Indicates a failure to load the cursor image or create the hardware cursor
+ */
+ @Override
+ public abstract void setMouseCursor(ImageData data, int hotSpotX, int hotSpotY) throws SlickException;
+
+ /**
+ * Set the mouse cursor based on the contents of the image. Note that this will not take
+ * account of render state type changes to images (rotation and such). If these effects
+ * are required it is recommended that an offscreen buffer be used to produce an appropriate
+ * image. An offscreen buffer will always be used to produce the new cursor and as such
+ * this operation an be very expensive
+ *
+ * @param image The image to use as the cursor
+ * @param hotSpotX The x coordinate of the hotspot within the cursor image
+ * @param hotSpotY The y coordinate of the hotspot within the cursor image
+ * @throws SlickException Indicates a failure to load the cursor image or create the hardware cursor
+ */
+ public abstract void setMouseCursor(Image image, int hotSpotX, int hotSpotY) throws SlickException;
+
+ /**
+ * Set the mouse cursor to be displayed - this is a hardware cursor and hence
+ * shouldn't have any impact on FPS.
+ *
+ * @param cursor The cursor to use
+ * @param hotSpotX The x coordinate of the hotspot within the cursor image
+ * @param hotSpotY The y coordinate of the hotspot within the cursor image
+ * @throws SlickException Indicates a failure to load the cursor image or create the hardware cursor
+ */
+ @Override
+ public abstract void setMouseCursor(Cursor cursor, int hotSpotX, int hotSpotY) throws SlickException;
+
+ /**
+ * Get a cursor based on a image reference on the classpath. The image
+ * is assumed to be a set/strip of cursor animation frames running from top to
+ * bottom.
+ *
+ * @param ref The reference to the image to be loaded
+ * @param x The x-coordinate of the cursor hotspot (left -> right)
+ * @param y The y-coordinate of the cursor hotspot (bottom -> top)
+ * @param width The x width of the cursor
+ * @param height The y height of the cursor
+ * @param cursorDelays image delays between changing frames in animation
+ *
+ * @throws SlickException Indicates a failure to load the image or a failure to create the hardware cursor
+ */
+ public void setAnimatedMouseCursor(String ref, int x, int y, int width, int height, int[] cursorDelays) throws SlickException
+ {
+ try {
+ Cursor cursor;
+ cursor = CursorLoader.get().getAnimatedCursor(ref, x, y, width, height, cursorDelays);
+ setMouseCursor(cursor, x, y);
+ } catch (IOException e) {
+ throw new SlickException("Failed to set mouse cursor", e);
+ } catch (LWJGLException e) {
+ throw new SlickException("Failed to set mouse cursor", e);
+ }
+ }
+
+ /**
+ * Set the default mouse cursor - i.e. the original cursor before any native
+ * cursor was set
+ */
+ @Override
+ public abstract void setDefaultMouseCursor();
+
+ /**
+ * Get the input system
+ *
+ * @return The input system available to this game container
+ */
+ @Override
+ public Input getInput() {
+ return input;
+ }
+
+ /**
+ * Get the current recorded FPS (frames per second)
+ *
+ * @return The current FPS
+ */
+ public int getFPS() {
+ return recordedFPS;
+ }
+
+ /**
+ * Indicate whether mouse cursor should be grabbed or not
+ *
+ * @param grabbed True if mouse cursor should be grabbed
+ */
+ public abstract void setMouseGrabbed(boolean grabbed);
+
+ /**
+ * Check if the mouse cursor is current grabbed. This will cause it not
+ * to be seen.
+ *
+ * @return True if the mouse is currently grabbed
+ */
+ public abstract boolean isMouseGrabbed();
+
+ /**
+ * Retrieve the time taken to render the last frame, i.e. the change in time - delta.
+ *
+ * @return The time taken to render the last frame
+ */
+ protected int getDelta() {
+ long time = getTime();
+ int delta = (int) (time - lastFrame);
+ lastFrame = time;
+
+ return delta;
+ }
+
+ /**
+ * Updated the FPS counter
+ */
+ protected void updateFPS() {
+ if (getTime() - lastFPS > 1000) {
+ lastFPS = getTime();
+ recordedFPS = fps;
+ fps = 0;
+ }
+ fps++;
+ }
+
+ /**
+ * Set the minimum amount of time in milliseonds that has to
+ * pass before update() is called on the container game. This gives
+ * a way to limit logic updates compared to renders.
+ *
+ * @param interval The minimum interval between logic updates
+ */
+ public void setMinimumLogicUpdateInterval(int interval) {
+ minimumLogicInterval = interval;
+ }
+
+ /**
+ * Set the maximum amount of time in milliseconds that can passed
+ * into the update method. Useful for collision detection without
+ * sweeping.
+ *
+ * @param interval The maximum interval between logic updates
+ */
+ public void setMaximumLogicUpdateInterval(int interval) {
+ maximumLogicInterval = interval;
+ }
+
+ /**
+ * Update and render the game
+ *
+ * @param delta The change in time since last update and render
+ * @throws SlickException Indicates an internal fault to the game.
+ */
+ protected void updateAndRender(int delta) throws SlickException {
+ if (smoothDeltas) {
+ if (getFPS() != 0) {
+ delta = 1000 / getFPS();
+ }
+ }
+
+ input.poll(width, height);
+
+ Music.poll(delta);
+ if (!paused) {
+ storedDelta += delta;
+
+ if (storedDelta >= minimumLogicInterval) {
+ try {
+ if (maximumLogicInterval != 0) {
+ long cycles = storedDelta / maximumLogicInterval;
+ for (int i=0;i minimumLogicInterval) {
+ game.update(this, (int) (remainder % maximumLogicInterval));
+ storedDelta = 0;
+ } else {
+ storedDelta = remainder;
+ }
+ } else {
+ game.update(this, (int) storedDelta);
+ storedDelta = 0;
+ }
+
+ } catch (Throwable e) {
+// Log.error(e);
+ throw new SlickException("Game.update() failure.", e);
+ }
+ }
+ } else {
+ game.update(this, 0);
+ }
+
+ if (hasFocus() || getAlwaysRender()) {
+ if (clearEachFrame) {
+ GL.glClear(SGL.GL_COLOR_BUFFER_BIT | SGL.GL_DEPTH_BUFFER_BIT);
+ }
+
+ GL.glLoadIdentity();
+
+ graphics.resetTransform();
+ graphics.resetFont();
+ graphics.resetLineWidth();
+ graphics.setAntiAlias(false);
+ try {
+ game.render(this, graphics);
+ } catch (Throwable e) {
+// Log.error(e);
+ throw new SlickException("Game.render() failure.", e);
+ }
+ graphics.resetTransform();
+
+ if (showFPS) {
+ defaultFont.drawString(10, 10, "FPS: "+recordedFPS);
+ }
+
+ GL.flush();
+ }
+
+ if (targetFPS != -1) {
+ Display.sync(targetFPS);
+ }
+ }
+
+ /**
+ * Indicate if the display should update only when the game is visible
+ * (the default is true)
+ *
+ * @param updateOnlyWhenVisible True if we should updated only when the display is visible
+ */
+ public void setUpdateOnlyWhenVisible(boolean updateOnlyWhenVisible) {
+ }
+
+ /**
+ * Check if this game is only updating when visible to the user (default = true)
+ *
+ * @return True if the game is only updated when the display is visible
+ */
+ public boolean isUpdatingOnlyWhenVisible() {
+ return true;
+ }
+
+ /**
+ * Initialise the GL context
+ */
+ protected void initGL() {
+ Log.info("Starting display "+width+"x"+height);
+ GL.initDisplay(width, height);
+
+ if (input == null) {
+ input = new Input(height);
+ }
+ input.init(height);
+ // no need to remove listeners?
+ //input.removeAllListeners();
+ if (game instanceof InputListener) {
+ input.removeListener((InputListener) game);
+ input.addListener((InputListener) game);
+ }
+
+ if (graphics != null) {
+ graphics.setDimensions(getWidth(), getHeight());
+ }
+ lastGame = game;
+ }
+
+ /**
+ * Initialise the system components, OpenGL and OpenAL.
+ *
+ * @throws SlickException Indicates a failure to create a native handler
+ */
+ protected void initSystem() throws SlickException {
+ initGL();
+ setMusicVolume(1.0f);
+ setSoundVolume(1.0f);
+
+ graphics = new Graphics(width, height);
+ defaultFont = graphics.getFont();
+ }
+
+ /**
+ * Enter the orthographic mode
+ */
+ protected void enterOrtho() {
+ enterOrtho(width, height);
+ }
+
+ /**
+ * Indicate whether the container should show the FPS
+ *
+ * @param show True if the container should show the FPS
+ */
+ public void setShowFPS(boolean show) {
+ showFPS = show;
+ }
+
+ /**
+ * Check if the FPS is currently showing
+ *
+ * @return True if the FPS is showing
+ */
+ public boolean isShowingFPS() {
+ return showFPS;
+ }
+
+ /**
+ * Set the target fps we're hoping to get
+ *
+ * @param fps The target fps we're hoping to get
+ */
+ public void setTargetFrameRate(int fps) {
+ targetFPS = fps;
+ }
+
+ /**
+ * Indicate whether the display should be synced to the
+ * vertical refresh (stops tearing)
+ *
+ * @param vsync True if we want to sync to vertical refresh
+ */
+ public void setVSync(boolean vsync) {
+ this.vsync = vsync;
+ Display.setVSyncEnabled(vsync);
+ }
+
+ /**
+ * True if vsync is requested
+ *
+ * @return True if vsync is requested
+ */
+ public boolean isVSyncRequested() {
+ return vsync;
+ }
+
+ /**
+ * True if the game is running
+ *
+ * @return True if the game is running
+ */
+ protected boolean running() {
+ return running;
+ }
+
+ /**
+ * Inidcate we want verbose logging
+ *
+ * @param verbose True if we want verbose logging (INFO and DEBUG)
+ */
+ public void setVerbose(boolean verbose) {
+ Log.setVerbose(verbose);
+ }
+
+ /**
+ * Cause the game to exit and shutdown cleanly
+ */
+ public void exit() {
+ running = false;
+ }
+
+ /**
+ * Check if the game currently has focus
+ *
+ * @return True if the game currently has focus
+ */
+ public abstract boolean hasFocus();
+
+ /**
+ * Get the graphics context used by this container. Note that this
+ * value may vary over the life time of the game.
+ *
+ * @return The graphics context used by this container
+ */
+ public Graphics getGraphics() {
+ return graphics;
+ }
+
+ /**
+ * Enter the orthographic mode
+ *
+ * @param xsize The size of the panel being used
+ * @param ysize The size of the panel being used
+ */
+ protected void enterOrtho(int xsize, int ysize) {
+ GL.enterOrtho(xsize, ysize);
+ }
+}