com.github.mathiewz.slick.AppGameContainer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modernized-slick Show documentation
Show all versions of modernized-slick Show documentation
The main purpose of this libraryis to modernize and maintain the slick2D library.
The newest version!
package com.github.mathiewz.slick;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Mouse;
import org.lwjgl.openal.AL;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.PixelFormat;
import com.github.mathiewz.slick.openal.SoundStore;
import com.github.mathiewz.slick.opengl.CursorLoader;
import com.github.mathiewz.slick.opengl.ImageData;
import com.github.mathiewz.slick.opengl.ImageIOImageData;
import com.github.mathiewz.slick.opengl.InternalTextureLoader;
import com.github.mathiewz.slick.opengl.LoadableImageData;
import com.github.mathiewz.slick.opengl.TGAImageData;
import com.github.mathiewz.slick.util.Log;
import com.github.mathiewz.slick.util.ResourceLoader;
/**
* A game container that will display the game as an stand alone
* application.
*
* @author kevin
*/
public class AppGameContainer extends GameContainer {
static {
AccessController.doPrivileged((PrivilegedAction) () -> {
try {
Display.getDisplayMode();
} catch (Exception e) {
Log.error(e);
}
return null;
});
}
/** The original display mode before we tampered with things */
protected DisplayMode originalDisplayMode;
/** The display mode we're going to try and use */
protected DisplayMode targetDisplayMode;
/** True if we should update the game only when the display is visible */
protected boolean updateOnlyOnVisible = true;
/** Alpha background supported */
protected boolean alphaSupport = false;
/**
* Create a new container wrapping a game
*
* @param game
* The game to be wrapped
*/
public AppGameContainer(Game game) {
this(game, 640, 480, false);
}
/**
* Create a new container wrapping a game
*
* @param game
* The game to be wrapped
* @param width
* The width of the display required
* @param height
* The height of the display required
* @param fullscreen
* True if we want fullscreen mode
*/
public AppGameContainer(Game game, int width, int height, boolean fullscreen) {
super(game);
originalDisplayMode = Display.getDisplayMode();
setDisplayMode(width, height, fullscreen);
}
/**
* Check if the display created supported alpha in the back buffer
*
* @return True if the back buffer supported alpha
*/
public boolean supportsAlphaInBackBuffer() {
return alphaSupport;
}
/**
* Set the title of the window
*
* @param title
* The title to set on the window
*/
public void setTitle(String title) {
Display.setTitle(title);
}
/**
* Set the display mode to be used
*
* @param width
* The width of the display required
* @param height
* The height of the display required
* @param fullscreen
* True if we want fullscreen mode
*/
public void setDisplayMode(int width, int height, boolean fullscreen) {
if (this.width == width && this.height == height && isFullscreen() == fullscreen) {
return;
}
try {
targetDisplayMode = null;
if (fullscreen) {
DisplayMode[] modes = Display.getAvailableDisplayModes();
int freq = 0;
for (DisplayMode current : modes) {
if (current.getWidth() == width && current.getHeight() == height) {
if (targetDisplayMode == null || current.getFrequency() >= freq) {
if (targetDisplayMode == null || current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel()) {
targetDisplayMode = current;
freq = targetDisplayMode.getFrequency();
}
}
// if we've found a match for bpp and frequence against the
// original display mode then it's probably best to go for this one
// since it's most likely compatible with the monitor
if (current.getBitsPerPixel() == originalDisplayMode.getBitsPerPixel() && current.getFrequency() == originalDisplayMode.getFrequency()) {
targetDisplayMode = current;
break;
}
}
}
} else {
targetDisplayMode = new DisplayMode(width, height);
}
if (targetDisplayMode == null) {
throw new SlickException("Failed to find value mode: " + width + "x" + height + " fs=" + fullscreen);
}
this.width = width;
this.height = height;
Display.setDisplayMode(targetDisplayMode);
Display.setFullscreen(fullscreen);
if (Display.isCreated()) {
initGL();
enterOrtho();
}
if (targetDisplayMode.getBitsPerPixel() == 16) {
InternalTextureLoader.get().set16BitMode();
}
} catch (LWJGLException e) {
throw new SlickException("Unable to setup mode " + width + "x" + height + " fullscreen=" + fullscreen, e);
}
getDelta();
}
/**
* Check if the display is in fullscreen mode
*
* @return True if the display is in fullscreen mode
*/
@Override
public boolean isFullscreen() {
return Display.isFullscreen();
}
/**
* 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
*/
@Override
public void setFullscreen(boolean fullscreen) {
if (isFullscreen() == fullscreen) {
return;
}
if (!fullscreen) {
try {
Display.setFullscreen(fullscreen);
} catch (LWJGLException e) {
throw new SlickException("Unable to set fullscreen=" + fullscreen, e);
}
} else {
setDisplayMode(width, height, fullscreen);
}
getDelta();
}
/**
* @see com.github.mathiewz.slick.GameContainer#setMouseCursor(java.lang.String, int, int)
*/
@Override
public void setMouseCursor(String ref, int hotSpotX, int hotSpotY) {
try {
Cursor cursor = CursorLoader.get().getCursor(ref, hotSpotX, hotSpotY);
Mouse.setNativeCursor(cursor);
} catch (Throwable e) {
Log.error("Failed to load and apply cursor.", e);
throw new SlickException("Failed to set mouse cursor", e);
}
}
/**
* @see com.github.mathiewz.slick.GameContainer#setMouseCursor(com.github.mathiewz.slick.opengl.ImageData, int, int)
*/
@Override
public void setMouseCursor(ImageData data, int hotSpotX, int hotSpotY) {
try {
Cursor cursor = CursorLoader.get().getCursor(data, hotSpotX, hotSpotY);
Mouse.setNativeCursor(cursor);
} catch (Throwable e) {
Log.error("Failed to load and apply cursor.", e);
throw new SlickException("Failed to set mouse cursor", e);
}
}
/**
* @see com.github.mathiewz.slick.GameContainer#setMouseCursor(org.lwjgl.input.Cursor, int, int)
*/
@Override
public void setMouseCursor(Cursor cursor, int hotSpotX, int hotSpotY) {
try {
Mouse.setNativeCursor(cursor);
} catch (Throwable e) {
Log.error("Failed to load and apply cursor.", e);
throw new SlickException("Failed to set mouse cursor", e);
}
}
/**
* Get the closest greater power of 2 to the fold number
*
* @param fold
* The target number
* @return The power of 2
*/
private int get2Fold(int fold) {
int ret = 2;
while (ret < fold) {
ret *= 2;
}
return ret;
}
/**
* @see com.github.mathiewz.slick.GameContainer#setMouseCursor(com.github.mathiewz.slick.Image, int, int)
*/
@Override
public void setMouseCursor(Image image, int hotSpotX, int hotSpotY) {
try {
Image temp = new Image(get2Fold(image.getWidth()), get2Fold(image.getHeight()));
Graphics g = temp.getGraphics();
ByteBuffer buffer = BufferUtils.createByteBuffer(temp.getWidth() * temp.getHeight() * 4);
g.drawImage(image.getFlippedCopy(false, true), 0, 0);
g.flush();
g.getArea(0, 0, temp.getWidth(), temp.getHeight(), buffer);
Cursor cursor = CursorLoader.get().getCursor(buffer, hotSpotX, hotSpotY, temp.getWidth(), image.getHeight());
Mouse.setNativeCursor(cursor);
} catch (Throwable e) {
Log.error("Failed to load and apply cursor.", e);
throw new SlickException("Failed to set mouse cursor", e);
}
}
/**
* @see com.github.mathiewz.slick.GameContainer#reinit()
*/
@Override
public void reinit() {
InternalTextureLoader.get().clear();
SoundStore.get().clear();
initSystem();
enterOrtho();
try {
game.init(this);
} catch (SlickException e) {
Log.error(e);
running = false;
}
}
/**
* Try creating a display with the given format
*
* @param format
* The format to attempt
* @throws LWJGLException
* Indicates a failure to support the given format
*/
private void tryCreateDisplay(PixelFormat format) throws LWJGLException {
if (SHARED_DRAWABLE == null) {
Display.create(format);
} else {
Display.create(format, SHARED_DRAWABLE);
}
}
/**
* Start running the game
*
*/
public void start() {
try {
setup();
getDelta();
while (running()) {
gameLoop();
}
} finally {
destroy();
}
if (forceExit) {
System.exit(0);
}
}
/**
* Setup the environment
*
*/
protected void setup() {
if (targetDisplayMode == null) {
setDisplayMode(640, 480, false);
}
Display.setTitle(game.getTitle());
Log.info("LWJGL Version: " + Sys.getVersion());
Log.info("OriginalDisplayMode: " + originalDisplayMode);
Log.info("TargetDisplayMode: " + targetDisplayMode);
AccessController.doPrivileged((PrivilegedAction) () -> {
try {
PixelFormat format1 = new PixelFormat(8, 8, stencil ? 8 : 0, samples);
tryCreateDisplay(format1);
supportsMultiSample = true;
} catch (Exception e) {
Display.destroy();
try {
PixelFormat format2 = new PixelFormat(8, 8, stencil ? 8 : 0);
tryCreateDisplay(format2);
alphaSupport = false;
} catch (Exception e2) {
Display.destroy();
// if we couldn't get alpha, let us know
try {
tryCreateDisplay(new PixelFormat());
} catch (Exception e3) {
Log.error(e3);
}
}
}
return null;
});
if (!Display.isCreated()) {
throw new SlickException("Failed to initialise the LWJGL display");
}
initSystem();
enterOrtho();
try {
getInput().initControllers();
} catch (SlickException e) {
Log.info("Controllers not available");
} catch (Throwable e) {
Log.info("Controllers not available");
}
try {
game.init(this);
} catch (SlickException e) {
Log.error(e);
running = false;
}
}
/**
* Strategy for overloading game loop context handling
*
*/
protected void gameLoop() {
int delta = getDelta();
if (!Display.isVisible() && updateOnlyOnVisible) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
} else {
try {
updateAndRender(delta);
} catch (SlickException e) {
Log.error(e);
running = false;
return;
}
}
updateFPS();
Display.update();
if (Display.isCloseRequested()) {
if (game.closeRequested()) {
running = false;
}
}
}
/**
* @see com.github.mathiewz.slick.GameContainer#setUpdateOnlyWhenVisible(boolean)
*/
@Override
public void setUpdateOnlyWhenVisible(boolean updateOnlyWhenVisible) {
updateOnlyOnVisible = updateOnlyWhenVisible;
}
/**
* @see com.github.mathiewz.slick.GameContainer#isUpdatingOnlyWhenVisible()
*/
@Override
public boolean isUpdatingOnlyWhenVisible() {
return updateOnlyOnVisible;
}
/**
* @see com.github.mathiewz.slick.GameContainer#setIcon(java.lang.String)
*/
@Override
public void setIcon(String ref) {
setIcons(new String[] { ref });
}
/**
* @see com.github.mathiewz.slick.GameContainer#setMouseGrabbed(boolean)
*/
@Override
public void setMouseGrabbed(boolean grabbed) {
Mouse.setGrabbed(grabbed);
}
/**
* @see com.github.mathiewz.slick.GameContainer#isMouseGrabbed()
*/
@Override
public boolean isMouseGrabbed() {
return Mouse.isGrabbed();
}
/**
* @see com.github.mathiewz.slick.GameContainer#hasFocus()
*/
@Override
public boolean hasFocus() {
// hmm, not really the right thing, talk to the LWJGL guys
return Display.isActive();
}
/**
* @see com.github.mathiewz.slick.GameContainer#getScreenHeight()
*/
@Override
public int getScreenHeight() {
return originalDisplayMode.getHeight();
}
/**
* @see com.github.mathiewz.slick.GameContainer#getScreenWidth()
*/
@Override
public int getScreenWidth() {
return originalDisplayMode.getWidth();
}
/**
* Destroy the app game container
*/
public void destroy() {
Display.destroy();
AL.destroy();
}
/**
* @see com.github.mathiewz.slick.GameContainer#setIcons(java.lang.String[])
*/
@Override
public void setIcons(String[] refs) {
ByteBuffer[] bufs = new ByteBuffer[refs.length];
for (int i = 0; i < refs.length; i++) {
LoadableImageData data;
boolean flip = true;
if (refs[i].endsWith(".tga")) {
data = new TGAImageData();
} else {
flip = false;
data = new ImageIOImageData();
}
try {
bufs[i] = data.loadImage(ResourceLoader.getResourceAsStream(refs[i]), flip, false, null);
} catch (Exception e) {
Log.error(e);
throw new SlickException("Failed to set the icon");
}
}
Display.setIcon(bufs);
}
/**
* @see com.github.mathiewz.slick.GameContainer#setDefaultMouseCursor()
*/
@Override
public void setDefaultMouseCursor() {
try {
Mouse.setNativeCursor(null);
} catch (LWJGLException e) {
Log.error("Failed to reset mouse cursor", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy