2017-01-09 22:42:59 +01:00
|
|
|
/*
|
|
|
|
* opsu!dance - fork of opsu! with cursordance auto
|
|
|
|
* Copyright (C) 2017 yugecin
|
|
|
|
*
|
|
|
|
* opsu!dance 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!dance 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!dance. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
package yugecin.opsudance.core;
|
|
|
|
|
|
|
|
import com.google.inject.Inject;
|
|
|
|
import org.lwjgl.LWJGLException;
|
|
|
|
import org.lwjgl.Sys;
|
|
|
|
import org.lwjgl.openal.AL;
|
|
|
|
import org.lwjgl.opengl.Display;
|
|
|
|
import org.lwjgl.opengl.DisplayMode;
|
|
|
|
import org.newdawn.slick.Graphics;
|
2017-01-10 12:43:05 +01:00
|
|
|
import org.newdawn.slick.Input;
|
2017-01-09 22:42:59 +01:00
|
|
|
import org.newdawn.slick.opengl.InternalTextureLoader;
|
|
|
|
import org.newdawn.slick.opengl.renderer.Renderer;
|
|
|
|
import org.newdawn.slick.opengl.renderer.SGL;
|
|
|
|
import org.newdawn.slick.util.Log;
|
2017-01-10 12:43:05 +01:00
|
|
|
import yugecin.opsudance.core.state.OpsuState;
|
2017-01-09 22:42:59 +01:00
|
|
|
import yugecin.opsudance.utils.GLHelper;
|
|
|
|
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
|
2017-01-09 23:10:51 +01:00
|
|
|
import static yugecin.opsudance.kernel.Entrypoint.log;
|
|
|
|
|
2017-01-09 22:42:59 +01:00
|
|
|
/**
|
|
|
|
* based on org.newdawn.slick.AppGameContainer
|
|
|
|
*/
|
|
|
|
public class DisplayContainer {
|
|
|
|
|
|
|
|
private static SGL GL = Renderer.get();
|
|
|
|
|
|
|
|
private final Demux demux;
|
|
|
|
private final DisplayMode nativeDisplayMode;
|
|
|
|
private final List<ResolutionChangeListener> resolutionChangeListeners;
|
|
|
|
|
|
|
|
private Graphics graphics;
|
2017-01-10 12:43:05 +01:00
|
|
|
private Input input;
|
2017-01-09 22:42:59 +01:00
|
|
|
|
|
|
|
public int width;
|
|
|
|
public int height;
|
|
|
|
|
2017-01-10 13:02:40 +01:00
|
|
|
public int targetRenderInterval;
|
|
|
|
public int targetBackgroundRenderInterval;
|
|
|
|
|
|
|
|
public int realRenderInterval;
|
|
|
|
public int delta;
|
|
|
|
|
|
|
|
public int timeSinceLastRender;
|
|
|
|
|
2017-01-09 22:42:59 +01:00
|
|
|
private long lastFrame;
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
public DisplayContainer(Demux demux) {
|
|
|
|
this.demux = demux;
|
|
|
|
this.nativeDisplayMode = Display.getDisplayMode();
|
|
|
|
this.resolutionChangeListeners = new LinkedList<>();
|
2017-01-10 13:02:40 +01:00
|
|
|
targetRenderInterval = 16; // ~60 fps
|
|
|
|
targetBackgroundRenderInterval = 41; // ~24 fps
|
2017-01-09 22:42:59 +01:00
|
|
|
lastFrame = getTime();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addResolutionChangeListener(ResolutionChangeListener listener) {
|
|
|
|
resolutionChangeListeners.add(listener);
|
|
|
|
}
|
|
|
|
|
2017-01-10 12:43:05 +01:00
|
|
|
public void switchState(OpsuState newState) {
|
|
|
|
demux.switchState(newState);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void switchState(Class<? extends OpsuState> newState) {
|
|
|
|
demux.switchState(newState);
|
|
|
|
}
|
|
|
|
|
2017-01-09 22:42:59 +01:00
|
|
|
public void run() throws LWJGLException {
|
|
|
|
demux.init();
|
|
|
|
setup();
|
2017-01-10 12:43:05 +01:00
|
|
|
log("GL ready");
|
2017-01-09 22:42:59 +01:00
|
|
|
while(!(Display.isCloseRequested() && demux.onCloseRequest())) {
|
2017-01-10 13:02:40 +01:00
|
|
|
delta = getDelta();
|
|
|
|
|
|
|
|
timeSinceLastRender += delta;
|
|
|
|
|
2017-01-10 12:43:05 +01:00
|
|
|
input.poll(width, height);
|
2017-01-10 14:11:15 +01:00
|
|
|
demux.update(delta);
|
2017-01-10 13:02:40 +01:00
|
|
|
|
|
|
|
int maxRenderInterval;
|
|
|
|
if (Display.isVisible() && Display.isActive()) {
|
|
|
|
maxRenderInterval = targetRenderInterval;
|
|
|
|
} else {
|
|
|
|
maxRenderInterval = targetBackgroundRenderInterval;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timeSinceLastRender >= maxRenderInterval) {
|
|
|
|
GL.glClear(SGL.GL_COLOR_BUFFER_BIT);
|
|
|
|
|
|
|
|
/*
|
|
|
|
graphics.resetTransform();
|
|
|
|
graphics.resetFont();
|
|
|
|
graphics.resetLineWidth();
|
|
|
|
graphics.resetTransform();
|
|
|
|
*/
|
|
|
|
|
2017-01-10 14:11:15 +01:00
|
|
|
demux.preRenderUpdate(timeSinceLastRender);
|
2017-01-10 13:02:40 +01:00
|
|
|
demux.render(graphics);
|
|
|
|
|
|
|
|
realRenderInterval = timeSinceLastRender;
|
|
|
|
timeSinceLastRender = 0;
|
|
|
|
|
|
|
|
Display.update(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
Display.processMessages();
|
|
|
|
Display.sync(1000);
|
2017-01-09 22:42:59 +01:00
|
|
|
}
|
|
|
|
teardown();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setup() {
|
2017-01-10 13:16:57 +01:00
|
|
|
Input.disableControllers();
|
2017-01-09 22:42:59 +01:00
|
|
|
Display.setTitle("opsu!dance");
|
|
|
|
try {
|
|
|
|
// temp displaymode to not flash the screen with a 1ms black window
|
|
|
|
Display.setDisplayMode(new DisplayMode(100, 100));
|
|
|
|
Display.create();
|
2017-01-09 22:45:52 +01:00
|
|
|
GLHelper.setIcons(new String[] { "icon16.png", "icon32.png" });
|
2017-01-09 22:42:59 +01:00
|
|
|
setDisplayMode(640, 480, false);
|
|
|
|
} catch (LWJGLException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
// TODO errorhandler dialog here
|
|
|
|
Log.error("could not initialize GL", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void teardown() {
|
|
|
|
Display.destroy();
|
|
|
|
AL.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setDisplayMode(int width, int height, boolean fullscreen) throws LWJGLException {
|
|
|
|
if (this.width == width && this.height == height) {
|
|
|
|
Display.setFullscreen(fullscreen);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DisplayMode displayMode = null;
|
|
|
|
if (fullscreen) {
|
|
|
|
displayMode = GLHelper.findFullscreenDisplayMode(nativeDisplayMode.getBitsPerPixel(), nativeDisplayMode.getFrequency(), width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (displayMode == null) {
|
|
|
|
displayMode = new DisplayMode(width,height);
|
|
|
|
if (fullscreen) {
|
|
|
|
fullscreen = false;
|
|
|
|
Log.warn("could not find fullscreen displaymode for " + width + "x" + height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.width = displayMode.getWidth();
|
|
|
|
this.height = displayMode.getHeight();
|
|
|
|
|
|
|
|
Display.setDisplayMode(displayMode);
|
|
|
|
Display.setFullscreen(fullscreen);
|
|
|
|
|
|
|
|
initGL();
|
|
|
|
|
|
|
|
for (ResolutionChangeListener resolutionChangeListener : resolutionChangeListeners) {
|
|
|
|
resolutionChangeListener.onDisplayResolutionChanged(width, height);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (displayMode.getBitsPerPixel() == 16) {
|
|
|
|
InternalTextureLoader.get().set16BitMode();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initGL() {
|
|
|
|
GL.initDisplay(width, height);
|
|
|
|
GL.enterOrtho(width, height);
|
|
|
|
|
|
|
|
graphics = new Graphics(width, height);
|
|
|
|
graphics.setAntiAlias(false);
|
|
|
|
|
2017-01-10 12:43:05 +01:00
|
|
|
input = new Input(height);
|
|
|
|
input.addKeyListener(demux);
|
|
|
|
input.addMouseListener(demux);
|
2017-01-09 22:42:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private int getDelta() {
|
|
|
|
long time = getTime();
|
|
|
|
int delta = (int) (time - lastFrame);
|
|
|
|
lastFrame = time;
|
|
|
|
return delta;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getTime() {
|
|
|
|
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|