removing now unused classes
This commit is contained in:
parent
f730935622
commit
95a466f92f
|
@ -1,184 +0,0 @@
|
|||
/*
|
||||
* opsu! - an open-source osu! client
|
||||
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||
*
|
||||
* opsu! is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu! is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package itdelatrisu.opsu;
|
||||
|
||||
import itdelatrisu.opsu.audio.MusicController;
|
||||
import itdelatrisu.opsu.audio.SoundController;
|
||||
import itdelatrisu.opsu.beatmap.Beatmap;
|
||||
import itdelatrisu.opsu.beatmap.BeatmapGroup;
|
||||
import itdelatrisu.opsu.beatmap.BeatmapSetList;
|
||||
import itdelatrisu.opsu.beatmap.BeatmapSortOrder;
|
||||
import itdelatrisu.opsu.beatmap.BeatmapWatchService;
|
||||
import itdelatrisu.opsu.downloads.DownloadList;
|
||||
import itdelatrisu.opsu.downloads.Updater;
|
||||
import itdelatrisu.opsu.render.CurveRenderState;
|
||||
import itdelatrisu.opsu.ui.UI;
|
||||
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.newdawn.slick.AppGameContainer;
|
||||
import org.newdawn.slick.Game;
|
||||
import org.newdawn.slick.SlickException;
|
||||
import org.newdawn.slick.opengl.InternalTextureLoader;
|
||||
|
||||
/**
|
||||
* AppGameContainer extension that sends critical errors to ErrorHandler.
|
||||
*/
|
||||
public class Container extends AppGameContainer {
|
||||
/** Exception causing game failure. */
|
||||
protected Exception e = null;
|
||||
|
||||
public static Container instance;
|
||||
|
||||
/**
|
||||
* Create a new container wrapping a game
|
||||
*
|
||||
* @param game The game to be wrapped
|
||||
* @throws SlickException Indicates a failure to initialise the display
|
||||
*/
|
||||
public Container(Game game) throws SlickException {
|
||||
super(game);
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws SlickException Indicates a failure to initialise the display
|
||||
*/
|
||||
public Container(Game game, int width, int height, boolean fullscreen) throws SlickException {
|
||||
super(game, width, height, fullscreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws SlickException {
|
||||
try {
|
||||
setup();
|
||||
ErrorHandler.setGlString();
|
||||
getDelta();
|
||||
while (running())
|
||||
gameLoop();
|
||||
} catch (Exception e) {
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
// destroy the game container
|
||||
try {
|
||||
close_sub();
|
||||
} catch (Exception e) {
|
||||
if (this.e == null) // suppress if caused by a previous exception
|
||||
this.e = e;
|
||||
}
|
||||
destroy();
|
||||
|
||||
// report any critical errors
|
||||
if (e != null) {
|
||||
ErrorHandler.error(null, e, true);
|
||||
e = null;
|
||||
forceExit = true;
|
||||
}
|
||||
|
||||
if (forceExit) {
|
||||
Opsu.close();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@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.
|
||||
*/
|
||||
private void close_sub() {
|
||||
// save user options
|
||||
Options.saveOptions();
|
||||
|
||||
// reset cursor
|
||||
UI.getCursor().reset();
|
||||
|
||||
// destroy images
|
||||
InternalTextureLoader.get().clear();
|
||||
|
||||
// reset image references
|
||||
GameImage.clearReferences();
|
||||
GameData.Grade.clearReferences();
|
||||
Beatmap.clearBackgroundImageCache();
|
||||
|
||||
// prevent loading tracks from re-initializing OpenAL
|
||||
MusicController.reset();
|
||||
|
||||
// stop any playing track
|
||||
SoundController.stopTrack();
|
||||
|
||||
// reset BeatmapSetList data
|
||||
BeatmapGroup.set(BeatmapGroup.ALL);
|
||||
BeatmapSortOrder.set(BeatmapSortOrder.TITLE);
|
||||
if (BeatmapSetList.get() != null)
|
||||
BeatmapSetList.get().reset();
|
||||
|
||||
// delete OpenGL objects involved in the Curve rendering
|
||||
CurveRenderState.shutdown();
|
||||
|
||||
// destroy watch service
|
||||
if (!Options.isWatchServiceEnabled())
|
||||
BeatmapWatchService.destroy();
|
||||
BeatmapWatchService.removeListeners();
|
||||
|
||||
// delete temporary directory
|
||||
Utils.deleteDirectory(Options.TEMP_DIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() {
|
||||
// show confirmation dialog if any downloads are active
|
||||
if (forceExit) {
|
||||
if (DownloadList.get().hasActiveDownloads() &&
|
||||
UI.showExitConfirmation(DownloadList.EXIT_CONFIRMATION))
|
||||
return;
|
||||
if (Updater.get().getStatus() == Updater.Status.UPDATE_DOWNLOADING &&
|
||||
UI.showExitConfirmation(Updater.EXIT_CONFIRMATION))
|
||||
return;
|
||||
}
|
||||
|
||||
super.exit();
|
||||
}
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
/*
|
||||
* opsu! - an open-source osu! client
|
||||
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||
*
|
||||
* opsu! is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu! is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package itdelatrisu.opsu;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Desktop;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.newdawn.slick.util.Log;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
* Error handler to log and display errors.
|
||||
*/
|
||||
public class ErrorHandler {
|
||||
/** Error popup title. */
|
||||
private static final String title = "Error";
|
||||
|
||||
/** Error popup description text. */
|
||||
private static final String
|
||||
desc = "opsu! has encountered an error.",
|
||||
descReport = "opsu! has encountered an error. Please report this!";
|
||||
|
||||
/** Error popup button options. */
|
||||
private static final String[]
|
||||
optionsLog = {"View Error Log", "Close"},
|
||||
optionsReport = {"Send Report", "Close"},
|
||||
optionsLogReport = {"Send Report", "View Error Log", "Close"};
|
||||
|
||||
/** Text area for Exception. */
|
||||
private static final JTextArea textArea = new JTextArea(15, 100);
|
||||
static {
|
||||
textArea.setEditable(false);
|
||||
textArea.setBackground(UIManager.getColor("Panel.background"));
|
||||
textArea.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
|
||||
textArea.setTabSize(2);
|
||||
textArea.setLineWrap(false);
|
||||
textArea.setWrapStyleWord(true);
|
||||
}
|
||||
|
||||
/** Scroll pane holding JTextArea. */
|
||||
private static final JScrollPane scroll = new JScrollPane(textArea);
|
||||
|
||||
/** Error popup objects. */
|
||||
private static final Object[]
|
||||
message = { desc, scroll },
|
||||
messageReport = { descReport, scroll };
|
||||
|
||||
/** OpenGL string (if any). */
|
||||
private static String glString = null;
|
||||
|
||||
// This class should not be instantiated.
|
||||
private ErrorHandler() {}
|
||||
|
||||
/**
|
||||
* Sets the OpenGL version string.
|
||||
*/
|
||||
public static void setGlString() {
|
||||
try {
|
||||
String glVersion = GL11.glGetString(GL11.GL_VERSION);
|
||||
String glVendor = GL11.glGetString(GL11.GL_VENDOR);
|
||||
glString = String.format("%s (%s)", glVersion, glVendor);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an error popup and logs the given error.
|
||||
* @param error a description of the error
|
||||
* @param e the exception causing the error
|
||||
* @param report whether to ask to report the error
|
||||
*/
|
||||
public static void error(String error, Throwable e, boolean report) {
|
||||
if (error == null && e == null)
|
||||
return;
|
||||
|
||||
// log the error
|
||||
if (error == null)
|
||||
Log.error(e);
|
||||
else if (e == null)
|
||||
Log.error(error);
|
||||
else
|
||||
Log.error(error, e);
|
||||
|
||||
// set the textArea to the error message
|
||||
textArea.setText(null);
|
||||
if (error != null) {
|
||||
textArea.append(error);
|
||||
textArea.append("\n");
|
||||
}
|
||||
String trace = null;
|
||||
if (e != null) {
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
trace = sw.toString();
|
||||
textArea.append(trace);
|
||||
}
|
||||
|
||||
// display popup
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
Desktop desktop = null;
|
||||
boolean isBrowseSupported = false, isOpenSupported = false;
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
desktop = Desktop.getDesktop();
|
||||
isBrowseSupported = desktop.isSupported(Desktop.Action.BROWSE);
|
||||
isOpenSupported = desktop.isSupported(Desktop.Action.OPEN);
|
||||
}
|
||||
if (desktop != null && (isOpenSupported || (report && isBrowseSupported))) { // try to open the log file and/or issues webpage
|
||||
if (report && isBrowseSupported) { // ask to report the error
|
||||
if (isOpenSupported) { // also ask to open the log
|
||||
int n = JOptionPane.showOptionDialog(null, messageReport, title,
|
||||
JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE,
|
||||
null, optionsLogReport, optionsLogReport[2]);
|
||||
if (n == 0)
|
||||
desktop.browse(getIssueURI(error, e, trace));
|
||||
else if (n == 1)
|
||||
desktop.open(Options.LOG_FILE);
|
||||
} else { // only ask to report the error
|
||||
int n = JOptionPane.showOptionDialog(null, message, title,
|
||||
JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE,
|
||||
null, optionsReport, optionsReport[1]);
|
||||
if (n == 0)
|
||||
desktop.browse(getIssueURI(error, e, trace));
|
||||
}
|
||||
} else { // don't report the error
|
||||
int n = JOptionPane.showOptionDialog(null, message, title,
|
||||
JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE,
|
||||
null, optionsLog, optionsLog[1]);
|
||||
if (n == 0)
|
||||
desktop.open(Options.LOG_FILE);
|
||||
}
|
||||
} else { // display error only
|
||||
JOptionPane.showMessageDialog(null, report ? messageReport : message,
|
||||
title, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
Log.error("An error occurred in the crash popup.", e1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the issue reporting URI.
|
||||
* This will auto-fill the report with the relevant information if possible.
|
||||
* @param error a description of the error
|
||||
* @param e the exception causing the error
|
||||
* @param trace the stack trace
|
||||
* @return the created URI
|
||||
*/
|
||||
private static URI getIssueURI(String error, Throwable e, String trace) {
|
||||
// generate report information
|
||||
String issueTitle = (error != null) ? error : e.getMessage();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
// read version and build date from version file, if possible
|
||||
Properties props = new Properties();
|
||||
props.load(ResourceLoader.getResourceAsStream(Options.VERSION_FILE));
|
||||
String version = props.getProperty("version");
|
||||
if (version != null && !version.equals("${pom.version}")) {
|
||||
sb.append("**Version:** ");
|
||||
sb.append(version);
|
||||
String hash = Utils.getGitHash();
|
||||
if (hash != null) {
|
||||
sb.append(" (");
|
||||
sb.append(hash.substring(0, 12));
|
||||
sb.append(')');
|
||||
}
|
||||
sb.append('\n');
|
||||
}
|
||||
String timestamp = props.getProperty("build.date");
|
||||
if (timestamp != null &&
|
||||
!timestamp.equals("${maven.build.timestamp}") && !timestamp.equals("${timestamp}")) {
|
||||
sb.append("**Build date:** ");
|
||||
sb.append(timestamp);
|
||||
sb.append('\n');
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
Log.warn("Could not read version file.", e1);
|
||||
}
|
||||
sb.append("**OS:** ");
|
||||
sb.append(System.getProperty("os.name"));
|
||||
sb.append(" (");
|
||||
sb.append(System.getProperty("os.arch"));
|
||||
sb.append(")\n");
|
||||
sb.append("**JRE:** ");
|
||||
sb.append(System.getProperty("java.version"));
|
||||
sb.append('\n');
|
||||
if (glString != null) {
|
||||
sb.append("**OpenGL Version:** ");
|
||||
sb.append(glString);
|
||||
sb.append('\n');
|
||||
}
|
||||
if (error != null) {
|
||||
sb.append("**Error:** `");
|
||||
sb.append(error);
|
||||
sb.append("`\n");
|
||||
}
|
||||
if (trace != null) {
|
||||
sb.append("**Stack trace:**");
|
||||
sb.append("\n```\n");
|
||||
sb.append(trace);
|
||||
sb.append("```");
|
||||
}
|
||||
|
||||
// return auto-filled URI
|
||||
try {
|
||||
return URI.create(String.format(Options.ISSUES_URL,
|
||||
URLEncoder.encode(issueTitle, "UTF-8"),
|
||||
URLEncoder.encode(sb.toString(), "UTF-8")));
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
Log.warn("URLEncoder failed to encode the auto-filled issue report URL.");
|
||||
return URI.create(String.format(Options.ISSUES_URL, "", ""));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,309 +0,0 @@
|
|||
/*
|
||||
* opsu! - an open-source osu! client
|
||||
* Copyright (C) 2014, 2015 Jeffrey Han
|
||||
*
|
||||
* opsu! is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* opsu! is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package itdelatrisu.opsu;
|
||||
|
||||
import itdelatrisu.opsu.audio.MusicController;
|
||||
import itdelatrisu.opsu.db.DBController;
|
||||
import itdelatrisu.opsu.downloads.DownloadList;
|
||||
import itdelatrisu.opsu.downloads.Updater;
|
||||
import itdelatrisu.opsu.states.ButtonMenu;
|
||||
import itdelatrisu.opsu.states.DownloadsMenu;
|
||||
import itdelatrisu.opsu.states.Game;
|
||||
import itdelatrisu.opsu.states.GamePauseMenu;
|
||||
import itdelatrisu.opsu.states.GameRanking;
|
||||
import itdelatrisu.opsu.states.MainMenu;
|
||||
import itdelatrisu.opsu.states.OptionsMenu;
|
||||
import itdelatrisu.opsu.states.SongMenu;
|
||||
import itdelatrisu.opsu.states.Splash;
|
||||
import itdelatrisu.opsu.ui.UI;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.newdawn.slick.GameContainer;
|
||||
import org.newdawn.slick.Input;
|
||||
import org.newdawn.slick.SlickException;
|
||||
import org.newdawn.slick.state.StateBasedGame;
|
||||
import org.newdawn.slick.state.transition.FadeInTransition;
|
||||
import org.newdawn.slick.state.transition.EasedFadeOutTransition;
|
||||
import org.newdawn.slick.util.DefaultLogSystem;
|
||||
import org.newdawn.slick.util.FileSystemLocation;
|
||||
import org.newdawn.slick.util.Log;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
/**
|
||||
* Main class.
|
||||
* <p>
|
||||
* Creates game container, adds all other states, and initializes song data.
|
||||
*/
|
||||
public class Opsu extends StateBasedGame {
|
||||
/** Game states. */
|
||||
public static final int
|
||||
STATE_SPLASH = 0,
|
||||
STATE_MAINMENU = 1,
|
||||
STATE_BUTTONMENU = 2,
|
||||
STATE_SONGMENU = 3,
|
||||
STATE_GAME = 4,
|
||||
STATE_GAMEPAUSEMENU = 5,
|
||||
STATE_GAMERANKING = 6,
|
||||
STATE_OPTIONSMENU = 7,
|
||||
STATE_DOWNLOADSMENU = 8;
|
||||
|
||||
/** Server socket for restricting the program to a single instance. */
|
||||
private static ServerSocket SERVER_SOCKET;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param name the program name
|
||||
*/
|
||||
public Opsu(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initStatesList(GameContainer container) throws SlickException {
|
||||
//addState(new Splash(STATE_SPLASH));
|
||||
//addState(new MainMenu(STATE_MAINMENU));
|
||||
//addState(new ButtonMenu(STATE_BUTTONMENU));
|
||||
//addState(new SongMenu(STATE_SONGMENU));
|
||||
//addState(new Game(STATE_GAME));
|
||||
//addState(new GamePauseMenu(STATE_GAMEPAUSEMENU));
|
||||
//addState(new GameRanking(STATE_GAMERANKING));
|
||||
//addState(new OptionsMenu(STATE_OPTIONSMENU));
|
||||
//addState(new DownloadsMenu(STATE_DOWNLOADSMENU));
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches opsu!.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// log all errors to a file
|
||||
Log.setVerbose(false);
|
||||
try {
|
||||
DefaultLogSystem.out = new PrintStream(new FileOutputStream(Options.LOG_FILE, true));
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.error(e);
|
||||
}
|
||||
|
||||
// set default exception handler
|
||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
ErrorHandler.error("** Uncaught Exception! **", e, true);
|
||||
System.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
// parse configuration file
|
||||
Options.parseOptions();
|
||||
|
||||
// only allow a single instance
|
||||
if (!Options.noSingleInstance()) {
|
||||
try {
|
||||
SERVER_SOCKET = new ServerSocket(Options.getPort(), 1, InetAddress.getLocalHost());
|
||||
} catch (UnknownHostException e) {
|
||||
// shouldn't happen
|
||||
} catch (IOException e) {
|
||||
errorAndExit(
|
||||
null,
|
||||
String.format(
|
||||
"opsu! could not be launched for one of these reasons:\n" +
|
||||
"- An instance of opsu! is already running.\n" +
|
||||
"- Another program is bound to port %d. " +
|
||||
"You can change the port opsu! uses by editing the \"Port\" field in the configuration file.",
|
||||
Options.getPort()
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// load natives
|
||||
File nativeDir;
|
||||
if (!Utils.isJarRunning() && (
|
||||
(nativeDir = new File("./target/natives/")).isDirectory() ||
|
||||
(nativeDir = new File("./build/natives/")).isDirectory()))
|
||||
;
|
||||
else {
|
||||
nativeDir = Options.NATIVE_DIR;
|
||||
try {
|
||||
new NativeLoader(nativeDir).loadNatives();
|
||||
} catch (IOException e) {
|
||||
Log.error("Error loading natives.", e);
|
||||
}
|
||||
}
|
||||
System.setProperty("org.lwjgl.librarypath", nativeDir.getAbsolutePath());
|
||||
System.setProperty("java.library.path", nativeDir.getAbsolutePath());
|
||||
try {
|
||||
// Workaround for "java.library.path" property being read-only.
|
||||
// http://stackoverflow.com/a/24988095
|
||||
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
|
||||
fieldSysPath.setAccessible(true);
|
||||
fieldSysPath.set(null, null);
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
Log.warn("Failed to set 'sys_paths' field.", e);
|
||||
}
|
||||
|
||||
// set the resource paths
|
||||
ResourceLoader.addResourceLocation(new FileSystemLocation(new File("./res/")));
|
||||
|
||||
// initialize databases
|
||||
try {
|
||||
DBController.init();
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
errorAndExit(e, "The databases could not be initialized.", true);
|
||||
}
|
||||
|
||||
// check if just updated
|
||||
if (args.length >= 2)
|
||||
Updater.get().setUpdateInfo(args[0], args[1]);
|
||||
|
||||
// check for updates
|
||||
if (!Options.isUpdaterDisabled()) {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Updater.get().checkForUpdates();
|
||||
} catch (IOException e) {
|
||||
Log.warn("Check for updates failed.", e);
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
// disable jinput
|
||||
Input.disableControllers();
|
||||
|
||||
// start the game
|
||||
try {
|
||||
// loop until force exit
|
||||
while (true) {
|
||||
Opsu opsu = new Opsu("opsu!");
|
||||
Container app = new Container(opsu);
|
||||
|
||||
// basic game settings
|
||||
//Options.setDisplayMode(app);
|
||||
String[] icons = { "icon16.png", "icon32.png" };
|
||||
try {
|
||||
app.setIcons(icons);
|
||||
} catch (Exception e) {
|
||||
Log.error("could not set icon");
|
||||
}
|
||||
app.setForceExit(true);
|
||||
|
||||
app.start();
|
||||
|
||||
// run update if available
|
||||
if (Updater.get().getStatus() == Updater.Status.UPDATE_FINAL) {
|
||||
close();
|
||||
Updater.get().runUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (SlickException e) {
|
||||
errorAndExit(e, "An error occurred while creating the game container.", true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean closeRequested() {
|
||||
int id = this.getCurrentStateID();
|
||||
|
||||
// intercept close requests in game-related states and return to song menu
|
||||
if (id == STATE_GAME || id == STATE_GAMEPAUSEMENU || id == STATE_GAMERANKING) {
|
||||
// start playing track at preview position
|
||||
SongMenu songMenu = (SongMenu) this.getState(Opsu.STATE_SONGMENU);
|
||||
if (id == STATE_GAMERANKING) {
|
||||
GameData data = ((GameRanking) this.getState(Opsu.STATE_GAMERANKING)).getGameData();
|
||||
if (data != null && data.isGameplay())
|
||||
songMenu.resetTrackOnLoad();
|
||||
} else {
|
||||
if (id == STATE_GAME) {
|
||||
MusicController.pause();
|
||||
MusicController.setPitch(1.0f);
|
||||
MusicController.resume();
|
||||
} else
|
||||
songMenu.resetTrackOnLoad();
|
||||
}
|
||||
|
||||
// reset game data
|
||||
if (UI.getCursor().isBeatmapSkinned())
|
||||
UI.getCursor().reset();
|
||||
songMenu.resetGameDataOnLoad();
|
||||
|
||||
this.enterState(Opsu.STATE_SONGMENU, new EasedFadeOutTransition(), new FadeInTransition());
|
||||
return false;
|
||||
}
|
||||
|
||||
// show confirmation dialog if any downloads are active
|
||||
if (DownloadList.get().hasActiveDownloads() &&
|
||||
UI.showExitConfirmation(DownloadList.EXIT_CONFIRMATION))
|
||||
return false;
|
||||
if (Updater.get().getStatus() == Updater.Status.UPDATE_DOWNLOADING &&
|
||||
UI.showExitConfirmation(Updater.EXIT_CONFIRMATION))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all resources.
|
||||
*/
|
||||
public static void close() {
|
||||
// close databases
|
||||
DBController.closeConnections();
|
||||
|
||||
// cancel all downloads
|
||||
DownloadList.get().cancelAllDownloads();
|
||||
|
||||
// close server socket
|
||||
if (SERVER_SOCKET != null) {
|
||||
try {
|
||||
SERVER_SOCKET.close();
|
||||
} catch (IOException e) {
|
||||
ErrorHandler.error("Failed to close server socket.", e, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error and exits the application with the given message.
|
||||
* @param e the exception that caused the crash
|
||||
* @param message the message to display
|
||||
* @param report whether to ask to report the error
|
||||
*/
|
||||
private static void errorAndExit(Throwable e, String message, boolean report) {
|
||||
// JARs will not run properly inside directories containing '!'
|
||||
// http://bugs.java.com/view_bug.do?bug_id=4523159
|
||||
if (Utils.isJarRunning() && Utils.getRunningDirectory() != null &&
|
||||
Utils.getRunningDirectory().getAbsolutePath().indexOf('!') != -1)
|
||||
ErrorHandler.error("JARs cannot be run from some paths containing '!'. Please move or rename the file and try again.", null, false);
|
||||
else
|
||||
ErrorHandler.error(message, e, report);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
|
@ -1,907 +0,0 @@
|
|||
/*
|
||||
* 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 {@literal ->} right)
|
||||
* @param y The y-coordinate of the cursor hotspot (bottom {@literal ->} 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