Minor GameContainer changes.
Added copy of GameContainer.java: - updateAndRender() no longer calls Log.error(), and re-throws the original exception as a SlickException. This prevents errors from being logged twice, and now the relevant one is shown in the error popup (instead of a useless "failure" message). - getBuildVersion() no longer calls Log.error(), and removed slick build information from "version" file. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
3df08e5357
commit
9138b70a24
1
pom.xml
1
pom.xml
|
@ -112,6 +112,7 @@
|
|||
<!-- Overwritten classes -->
|
||||
<artifact>org.slick2d:slick2d-core</artifact>
|
||||
<excludes>
|
||||
<exclude>org/newdawn/slick/GameContainer.*</exclude>
|
||||
<exclude>org/newdawn/slick/Image.*</exclude>
|
||||
<exclude>org/newdawn/slick/Music.*</exclude>
|
||||
<exclude>org/newdawn/slick/openal/AudioInputStream*</exclude>
|
||||
|
|
|
@ -1,6 +1,2 @@
|
|||
# opsu! build info
|
||||
version=${pom.version}
|
||||
build.date=${timestamp}
|
||||
|
||||
# slick build
|
||||
build=237
|
||||
|
|
|
@ -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
|
||||
|
|
907
src/org/newdawn/slick/GameContainer.java
Normal file
907
src/org/newdawn/slick/GameContainer.java
Normal file
|
@ -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<cycles;i++) {
|
||||
game.update(this, (int) maximumLogicInterval);
|
||||
}
|
||||
|
||||
int remainder = (int) (storedDelta % maximumLogicInterval);
|
||||
if (remainder > 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user