mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-10 13:51:53 +09:00
added sources for Slick
Former-commit-id: 1647fa32ef6894bd7db44f741f07c2f4dcdf9054 Former-commit-id: 0e5810dcfbe1fd59b13e7cabe9f1e93c5542da2d
This commit is contained in:
576
lib/slick-source/org/newdawn/slick/AppletGameContainer.java
Normal file
576
lib/slick-source/org/newdawn/slick/AppletGameContainer.java
Normal file
@@ -0,0 +1,576 @@
|
||||
package org.newdawn.slick;
|
||||
|
||||
import java.applet.Applet;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.Label;
|
||||
import java.awt.Panel;
|
||||
import java.awt.TextArea;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.input.Cursor;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.PixelFormat;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
import org.newdawn.slick.opengl.CursorLoader;
|
||||
import org.newdawn.slick.opengl.ImageData;
|
||||
import org.newdawn.slick.opengl.InternalTextureLoader;
|
||||
import org.newdawn.slick.util.Log;
|
||||
|
||||
/**
|
||||
* A game container that displays the game as an applet. Note however that the
|
||||
* actual game container implementation is an internal class which can be
|
||||
* obtained with the getContainer() method - this is due to the Applet being a
|
||||
* class wrap than an interface.
|
||||
*
|
||||
* @author kevin
|
||||
*/
|
||||
public class AppletGameContainer extends Applet {
|
||||
/** The GL Canvas used for this container */
|
||||
protected ContainerPanel canvas;
|
||||
/** The actual container implementation */
|
||||
protected Container container;
|
||||
/** The parent of the display */
|
||||
protected Canvas displayParent;
|
||||
/** The thread that is looping for the game */
|
||||
protected Thread gameThread;
|
||||
/** Alpha background supported */
|
||||
protected boolean alphaSupport = true;
|
||||
|
||||
/**
|
||||
* @see java.applet.Applet#destroy()
|
||||
*/
|
||||
public void destroy() {
|
||||
if (displayParent != null) {
|
||||
remove(displayParent);
|
||||
}
|
||||
super.destroy();
|
||||
|
||||
Log.info("Clear up");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the LWJGL resources
|
||||
*/
|
||||
private void destroyLWJGL() {
|
||||
container.stopApplet();
|
||||
|
||||
try {
|
||||
gameThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
Log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.applet.Applet#start()
|
||||
*/
|
||||
public void start() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a thread to run LWJGL in
|
||||
*/
|
||||
public void startLWJGL() {
|
||||
if (gameThread != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
gameThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
canvas.start();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (Display.isCreated()) {
|
||||
Display.destroy();
|
||||
}
|
||||
displayParent.setVisible(false);//removeAll();
|
||||
add(new ConsolePanel(e));
|
||||
validate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
gameThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.applet.Applet#stop()
|
||||
*/
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.applet.Applet#init()
|
||||
*/
|
||||
public void init() {
|
||||
removeAll();
|
||||
setLayout(new BorderLayout());
|
||||
setIgnoreRepaint(true);
|
||||
|
||||
try {
|
||||
Game game = (Game) Class.forName(getParameter("game")).newInstance();
|
||||
|
||||
container = new Container(game);
|
||||
canvas = new ContainerPanel(container);
|
||||
displayParent = new Canvas() {
|
||||
public final void addNotify() {
|
||||
super.addNotify();
|
||||
startLWJGL();
|
||||
}
|
||||
public final void removeNotify() {
|
||||
destroyLWJGL();
|
||||
super.removeNotify();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
displayParent.setSize(getWidth(), getHeight());
|
||||
add(displayParent);
|
||||
displayParent.setFocusable(true);
|
||||
displayParent.requestFocus();
|
||||
displayParent.setIgnoreRepaint(true);
|
||||
setVisible(true);
|
||||
} catch (Exception e) {
|
||||
Log.error(e);
|
||||
throw new RuntimeException("Unable to create game container");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GameContainer providing this applet
|
||||
*
|
||||
* @return The game container providing this applet
|
||||
*/
|
||||
public GameContainer getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new panel to display the GL context
|
||||
*
|
||||
* @author kevin
|
||||
*/
|
||||
public class ContainerPanel {
|
||||
/** The container being displayed on this canvas */
|
||||
private Container container;
|
||||
|
||||
/**
|
||||
* Create a new panel
|
||||
*
|
||||
* @param container The container we're running
|
||||
*/
|
||||
public ContainerPanel(Container container) {
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the LWJGL display
|
||||
*
|
||||
* @throws Exception Failure to create display
|
||||
*/
|
||||
private void createDisplay() throws Exception {
|
||||
try {
|
||||
// create display with alpha
|
||||
Display.create(new PixelFormat(8,8,GameContainer.stencil ? 8 : 0));
|
||||
alphaSupport = true;
|
||||
} catch (Exception e) {
|
||||
// if we couldn't get alpha, let us know
|
||||
alphaSupport = false;
|
||||
Display.destroy();
|
||||
// create display without alpha
|
||||
Display.create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the game container
|
||||
*
|
||||
* @throws Exception Failure to create display
|
||||
*/
|
||||
public void start() throws Exception {
|
||||
Display.setParent(displayParent);
|
||||
Display.setVSyncEnabled(true);
|
||||
|
||||
try {
|
||||
createDisplay();
|
||||
} catch (LWJGLException e) {
|
||||
e.printStackTrace();
|
||||
// failed to create Display, apply workaround (sleep for 1 second) and try again
|
||||
Thread.sleep(1000);
|
||||
createDisplay();
|
||||
}
|
||||
|
||||
initGL();
|
||||
displayParent.requestFocus();
|
||||
container.runloop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise GL state
|
||||
*/
|
||||
protected void initGL() {
|
||||
try {
|
||||
InternalTextureLoader.get().clear();
|
||||
SoundStore.get().clear();
|
||||
|
||||
container.initApplet();
|
||||
} catch (Exception e) {
|
||||
Log.error(e);
|
||||
container.stopApplet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A game container to provide the applet context
|
||||
*
|
||||
* @author kevin
|
||||
*/
|
||||
public class Container extends GameContainer {
|
||||
/**
|
||||
* Create a new container wrapped round the game
|
||||
*
|
||||
* @param game The game to be held in this container
|
||||
*/
|
||||
public Container(Game game) {
|
||||
super(game);
|
||||
|
||||
width = AppletGameContainer.this.getWidth();
|
||||
height = AppletGameContainer.this.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiliase based on Applet init
|
||||
*
|
||||
* @throws SlickException Indicates a failure to inialise the basic framework
|
||||
*/
|
||||
public void initApplet() throws SlickException {
|
||||
initSystem();
|
||||
enterOrtho();
|
||||
|
||||
try {
|
||||
getInput().initControllers();
|
||||
} catch (SlickException e) {
|
||||
Log.info("Controllers not available");
|
||||
} catch (Throwable e) {
|
||||
Log.info("Controllers not available");
|
||||
}
|
||||
|
||||
game.init(this);
|
||||
getDelta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the applet is currently running
|
||||
*
|
||||
* @return True if the applet is running
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the applet play back
|
||||
*/
|
||||
public void stopApplet() {
|
||||
running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#getScreenHeight()
|
||||
*/
|
||||
public int getScreenHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#getScreenWidth()
|
||||
*/
|
||||
public int getScreenWidth() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the display created supported alpha in the back buffer
|
||||
*
|
||||
* @return True if the back buffer supported alpha
|
||||
*/
|
||||
public boolean supportsAlphaInBackBuffer() {
|
||||
return alphaSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#hasFocus()
|
||||
*/
|
||||
public boolean hasFocus() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Applet Object
|
||||
* @return Applet Object
|
||||
*/
|
||||
public Applet getApplet() {
|
||||
return AppletGameContainer.this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#setIcon(java.lang.String)
|
||||
*/
|
||||
public void setIcon(String ref) throws SlickException {
|
||||
// unsupported in an applet
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#setMouseGrabbed(boolean)
|
||||
*/
|
||||
public void setMouseGrabbed(boolean grabbed) {
|
||||
Mouse.setGrabbed(grabbed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#isMouseGrabbed()
|
||||
*/
|
||||
public boolean isMouseGrabbed() {
|
||||
return Mouse.isGrabbed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#setMouseCursor(java.lang.String,
|
||||
* int, int)
|
||||
*/
|
||||
public void setMouseCursor(String ref, int hotSpotX, int hotSpotY) throws SlickException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void setMouseCursor(Image image, int hotSpotX, int hotSpotY) throws SlickException {
|
||||
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(),temp.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 org.newdawn.slick.GameContainer#setIcons(java.lang.String[])
|
||||
*/
|
||||
public void setIcons(String[] refs) throws SlickException {
|
||||
// unsupported in an applet
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#setMouseCursor(org.newdawn.slick.opengl.ImageData, int, int)
|
||||
*/
|
||||
public void setMouseCursor(ImageData data, int hotSpotX, int hotSpotY) throws SlickException {
|
||||
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 org.newdawn.slick.GameContainer#setMouseCursor(org.lwjgl.input.Cursor, int, int)
|
||||
*/
|
||||
public void setMouseCursor(Cursor cursor, int hotSpotX, int hotSpotY) throws SlickException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.newdawn.slick.GameContainer#setDefaultMouseCursor()
|
||||
*/
|
||||
public void setDefaultMouseCursor() {
|
||||
}
|
||||
|
||||
public boolean isFullscreen() {
|
||||
return Display.isFullscreen();
|
||||
}
|
||||
|
||||
public void setFullscreen(boolean fullscreen) throws SlickException {
|
||||
if (fullscreen == isFullscreen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (fullscreen) {
|
||||
// get current screen resolution
|
||||
int screenWidth = Display.getDisplayMode().getWidth();
|
||||
int screenHeight = Display.getDisplayMode().getHeight();
|
||||
|
||||
// calculate aspect ratio
|
||||
float gameAspectRatio = (float) width / height;
|
||||
float screenAspectRatio = (float) screenWidth
|
||||
/ screenHeight;
|
||||
|
||||
int newWidth;
|
||||
int newHeight;
|
||||
|
||||
// get new screen resolution to match aspect ratio
|
||||
|
||||
if (gameAspectRatio >= screenAspectRatio) {
|
||||
newWidth = screenWidth;
|
||||
newHeight = (int) (height / ((float) width / screenWidth));
|
||||
} else {
|
||||
newWidth = (int) (width / ((float) height / screenHeight));
|
||||
newHeight = screenHeight;
|
||||
}
|
||||
|
||||
// center new screen
|
||||
int xoffset = (screenWidth - newWidth) / 2;
|
||||
int yoffset = (screenHeight - newHeight) / 2;
|
||||
|
||||
// scale game to match new resolution
|
||||
GL11.glViewport(xoffset, yoffset, newWidth, newHeight);
|
||||
|
||||
enterOrtho();
|
||||
|
||||
// fix input to match new resolution
|
||||
this.getInput().setOffset(
|
||||
-xoffset * (float) width / newWidth,
|
||||
-yoffset * (float) height / newHeight);
|
||||
|
||||
this.getInput().setScale((float) width / newWidth,
|
||||
(float) height / newHeight);
|
||||
|
||||
width = screenWidth;
|
||||
height = screenHeight;
|
||||
Display.setFullscreen(true);
|
||||
} else {
|
||||
// restore input
|
||||
this.getInput().setOffset(0, 0);
|
||||
this.getInput().setScale(1, 1);
|
||||
width = AppletGameContainer.this.getWidth();
|
||||
height = AppletGameContainer.this.getHeight();
|
||||
GL11.glViewport(0, 0, width, height);
|
||||
|
||||
enterOrtho();
|
||||
|
||||
Display.setFullscreen(false);
|
||||
}
|
||||
} catch (LWJGLException e) {
|
||||
Log.error(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The running game loop
|
||||
*
|
||||
* @throws Exception Indicates a failure within the game's loop rather than the framework
|
||||
*/
|
||||
public void runloop() throws Exception {
|
||||
while (running) {
|
||||
int delta = getDelta();
|
||||
|
||||
updateAndRender(delta);
|
||||
|
||||
updateFPS();
|
||||
Display.update();
|
||||
}
|
||||
|
||||
Display.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic console to display an error message if the applet crashes.
|
||||
* This will prevent the applet from just freezing in the browser
|
||||
* and give the end user an a nice gui where the error message can easily
|
||||
* be viewed and copied.
|
||||
*/
|
||||
public class ConsolePanel extends Panel {
|
||||
/** The area display the console output */
|
||||
TextArea textArea = new TextArea();
|
||||
|
||||
/**
|
||||
* Create a new panel to display the console output
|
||||
*
|
||||
* @param e The exception causing the console to be displayed
|
||||
*/
|
||||
public ConsolePanel(Exception e) {
|
||||
setLayout(new BorderLayout());
|
||||
setBackground(Color.black);
|
||||
setForeground(Color.white);
|
||||
|
||||
Font consoleFont = new Font("Arial", Font.BOLD, 14);
|
||||
|
||||
Label slickLabel = new Label("SLICK CONSOLE", Label.CENTER);
|
||||
slickLabel.setFont(consoleFont);
|
||||
add(slickLabel, BorderLayout.PAGE_START);
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
|
||||
textArea.setText(sw.toString());
|
||||
textArea.setEditable(false);
|
||||
add(textArea, BorderLayout.CENTER);
|
||||
|
||||
// add a border on both sides of the console
|
||||
add(new Panel(), BorderLayout.LINE_START);
|
||||
add(new Panel(), BorderLayout.LINE_END);
|
||||
|
||||
Panel bottomPanel = new Panel();
|
||||
bottomPanel.setLayout(new GridLayout(0, 1));
|
||||
Label infoLabel1 = new Label("An error occured while running the applet.", Label.CENTER);
|
||||
Label infoLabel2 = new Label("Plese contact support to resolve this issue.", Label.CENTER);
|
||||
infoLabel1.setFont(consoleFont);
|
||||
infoLabel2.setFont(consoleFont);
|
||||
bottomPanel.add(infoLabel1);
|
||||
bottomPanel.add(infoLabel2);
|
||||
add(bottomPanel, BorderLayout.PAGE_END);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user