Unfinished huge refactoring towards backend modules system.
Done: Audio, Graphics. Tbd: Input, cleanup Config, cleanup old BaseApp etc
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
package mightypork.gamecore.backend;
|
||||
|
||||
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
import mightypork.utils.eventbus.clients.RootBusNode;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
import mightypork.gamecore.resources.audio.AudioModule;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
|
||||
|
||||
/**
|
||||
@@ -13,8 +13,7 @@ import mightypork.utils.eventbus.clients.RootBusNode;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Backend extends RootBusNode {
|
||||
|
||||
public abstract class Backend extends BusNode {
|
||||
|
||||
/**
|
||||
* Initialize backend modules, add them to event bus.<br>
|
||||
@@ -28,5 +27,13 @@ public abstract class Backend extends RootBusNode {
|
||||
*
|
||||
* @return graphics module
|
||||
*/
|
||||
public abstract RenderModule getRenderer();
|
||||
public abstract GraphicsModule getGraphics();
|
||||
|
||||
|
||||
/**
|
||||
* Get graphics module (renderer)
|
||||
*
|
||||
* @return graphics module
|
||||
*/
|
||||
public abstract AudioModule getAudio();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package mightypork.gamecore.backend;
|
||||
|
||||
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
|
||||
@@ -14,20 +13,9 @@ import mightypork.utils.interfaces.Destroyable;
|
||||
*/
|
||||
public abstract class BackendModule extends BusNode implements Destroyable {
|
||||
|
||||
/**
|
||||
* Create a module with bus access
|
||||
*
|
||||
* @param busAccess
|
||||
*/
|
||||
public BackendModule(BusAccess busAccess) {
|
||||
super(busAccess);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Stub
|
||||
public void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package mightypork.gamecore.backend.lwjgl;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.gamecore.util.SlickLogRedirector;
|
||||
import mightypork.utils.logging.writers.LogWriter;
|
||||
|
||||
|
||||
/**
|
||||
* Initializer that redirects slick logging to main logger.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskRedirectSlickLog extends InitTask {
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
LogWriter ml = mightypork.utils.logging.Log.getMainLogger();
|
||||
SlickLogRedirector slr = new SlickLogRedirector(ml);
|
||||
org.newdawn.slick.util.Log.setLogSystem(slr);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "slick_log";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String[] getDependencies()
|
||||
{
|
||||
return new String[] { "log" };
|
||||
}
|
||||
}
|
||||
@@ -2,31 +2,39 @@ package mightypork.gamecore.backend.lwjgl;
|
||||
|
||||
|
||||
import mightypork.gamecore.backend.Backend;
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
import mightypork.gamecore.resources.audio.AudioModule;
|
||||
|
||||
|
||||
/**
|
||||
* Game backend using LWJGL
|
||||
* Game backend using LWJGL and SlickUtil
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class LwjglBackend extends Backend {
|
||||
|
||||
private LwjglRenderModule renderer;
|
||||
private LwjglGraphicsModule graphics;
|
||||
private SlickAudioModule audio;
|
||||
|
||||
|
||||
@Override
|
||||
public void initialize()
|
||||
{
|
||||
addChildClient(renderer = new LwjglRenderModule(this));
|
||||
addChildClient(graphics = new LwjglGraphicsModule());
|
||||
addChildClient(audio = new SlickAudioModule());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RenderModule getRenderer()
|
||||
public GraphicsModule getGraphics()
|
||||
{
|
||||
return renderer;
|
||||
return graphics;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AudioModule getAudio()
|
||||
{
|
||||
return audio;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-18
@@ -6,15 +6,14 @@ import static org.lwjgl.opengl.GL11.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Stack;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.render.Grad;
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
import mightypork.gamecore.render.Screenshot;
|
||||
import mightypork.gamecore.render.events.DisplayReadyEvent;
|
||||
import mightypork.gamecore.render.events.ViewportChangeEvent;
|
||||
import mightypork.gamecore.resources.textures.ITexture;
|
||||
import mightypork.gamecore.resources.textures.LazyTexture;
|
||||
import mightypork.gamecore.resources.textures.DeferredTexture;
|
||||
import mightypork.gamecore.resources.textures.TxQuad;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.color.Color;
|
||||
import mightypork.utils.math.color.pal.RGB;
|
||||
@@ -35,11 +34,7 @@ import org.lwjgl.opengl.GL11;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class LwjglRenderModule extends RenderModule {
|
||||
|
||||
public LwjglRenderModule(BusAccess busAccess) {
|
||||
super(busAccess);
|
||||
}
|
||||
public class LwjglGraphicsModule extends GraphicsModule {
|
||||
|
||||
/** Currently binded color */
|
||||
private Color activeColor = null;
|
||||
@@ -48,7 +43,7 @@ public class LwjglRenderModule extends RenderModule {
|
||||
/** Stack of pushed colors */
|
||||
private Stack<Color> colorPushStack = new Stack<>();
|
||||
/** Currently binded texture */
|
||||
private ITexture activeTexture;
|
||||
private SlickTexture activeTexture;
|
||||
|
||||
/** Display mode used currently for the window */
|
||||
private DisplayMode windowDisplayMode;
|
||||
@@ -328,7 +323,7 @@ public class LwjglRenderModule extends RenderModule {
|
||||
// texture is loaded uniquely -> can compare with ==
|
||||
if (activeTexture != txquad.tx) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
activeTexture = txquad.tx;
|
||||
activeTexture = (SlickTexture) txquad.tx;
|
||||
activeTexture.bind();
|
||||
}
|
||||
|
||||
@@ -355,8 +350,8 @@ public class LwjglRenderModule extends RenderModule {
|
||||
tR = swap;
|
||||
}
|
||||
|
||||
final double w = txquad.tx.getWidth01();
|
||||
final double h = txquad.tx.getHeight01();
|
||||
final double w = activeTexture.getWidth01();
|
||||
final double h = activeTexture.getHeight01();
|
||||
|
||||
// quad with texture
|
||||
glTexCoord2d(tL * w, tB * h);
|
||||
@@ -409,9 +404,9 @@ public class LwjglRenderModule extends RenderModule {
|
||||
|
||||
|
||||
@Override
|
||||
public LazyTexture getLazyTexture(String path)
|
||||
public DeferredTexture getLazyTexture(String path)
|
||||
{
|
||||
return new SlickLazyTexture(path);
|
||||
return new SlickTexture(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -444,7 +439,7 @@ public class LwjglRenderModule extends RenderModule {
|
||||
fullscreenSetRequested = false;
|
||||
}
|
||||
|
||||
getEventBus().send(new DisplayReadyEvent());
|
||||
App.bus().send(new DisplayReadyEvent());
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Could not initialize display.", e);
|
||||
@@ -500,7 +495,7 @@ public class LwjglRenderModule extends RenderModule {
|
||||
Display.update();
|
||||
}
|
||||
|
||||
getEventBus().send(new ViewportChangeEvent(getSize()));
|
||||
App.bus().send(new ViewportChangeEvent(getSize()));
|
||||
|
||||
} catch (final Throwable t) {
|
||||
Log.e("Failed to change fullscreen mode.", t);
|
||||
@@ -542,7 +537,7 @@ public class LwjglRenderModule extends RenderModule {
|
||||
{
|
||||
// handle resize
|
||||
if (Display.wasResized()) {
|
||||
getEventBus().send(new ViewportChangeEvent(getSize()));
|
||||
App.bus().send(new ViewportChangeEvent(getSize()));
|
||||
}
|
||||
|
||||
if (fullscreenToggleRequested) {
|
||||
@@ -0,0 +1,171 @@
|
||||
package mightypork.gamecore.backend.lwjgl;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.newdawn.slick.openal.Audio;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
|
||||
/**
|
||||
* SlickUtil-based deferred audio resource.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class SlickAudio extends DeferredAudio {
|
||||
|
||||
private double pauseLoopPosition = 0;
|
||||
private boolean looping = false;
|
||||
private boolean paused = false;
|
||||
private double lastPlayPitch = 1;
|
||||
private double lastPlayGain = 1;
|
||||
|
||||
/** Audio resource */
|
||||
private Audio backingAudio = null;
|
||||
private int sourceID;
|
||||
|
||||
|
||||
public SlickAudio(String resourceName) {
|
||||
super(resourceName);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void loadResource(String resource) throws IOException
|
||||
{
|
||||
final String ext = FileUtils.getExtension(resource);
|
||||
|
||||
try (final InputStream stream = FileUtils.getResource(resource)) {
|
||||
|
||||
if (ext.equalsIgnoreCase("ogg")) {
|
||||
backingAudio = SoundStore.get().getOgg(resource, stream);
|
||||
|
||||
} else if (ext.equalsIgnoreCase("wav")) {
|
||||
backingAudio = SoundStore.get().getWAV(resource, stream);
|
||||
|
||||
} else if (ext.equalsIgnoreCase("aif")) {
|
||||
backingAudio = SoundStore.get().getAIF(resource, stream);
|
||||
|
||||
} else if (ext.equalsIgnoreCase("mod")) {
|
||||
backingAudio = SoundStore.get().getMOD(resource, stream);
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Invalid audio file extension.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pauseLoop()
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
if (isPlaying() && looping) {
|
||||
pauseLoopPosition = backingAudio.getPosition();
|
||||
stop();
|
||||
paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resumeLoop()
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
if (looping && paused) {
|
||||
sourceID = backingAudio.playAsSoundEffect((float) lastPlayPitch, (float) lastPlayGain, true);
|
||||
backingAudio.setPosition((float) pauseLoopPosition);
|
||||
paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void adjustGain(double gain)
|
||||
{
|
||||
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
if (!isLoaded()) return;
|
||||
|
||||
backingAudio.stop();
|
||||
paused = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPlaying()
|
||||
{
|
||||
if (!isLoaded()) return false;
|
||||
|
||||
return backingAudio.isPlaying();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPaused()
|
||||
{
|
||||
if (!isLoaded()) return false;
|
||||
|
||||
return backingAudio.isPaused();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop)
|
||||
{
|
||||
play(pitch, gain, loop, SoundSystem.getListener());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, double x, double y)
|
||||
{
|
||||
play(pitch, gain, loop, x, y, SoundSystem.getListener().z());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, double x, double y, double z)
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
this.lastPlayPitch = pitch;
|
||||
this.lastPlayGain = gain;
|
||||
looping = loop;
|
||||
|
||||
sourceID = backingAudio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(double pitch, double gain, boolean loop, Vect pos)
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
play(pitch, gain, loop, pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if (!isLoaded() || backingAudio == null) return;
|
||||
|
||||
backingAudio.release();
|
||||
backingAudio = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package mightypork.gamecore.backend.lwjgl;
|
||||
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.audio.AudioModule;
|
||||
import mightypork.gamecore.resources.audio.AudioReadyEvent;
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.util.BufferHelper;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
import mightypork.utils.math.constraints.vect.var.VectVar;
|
||||
|
||||
|
||||
/**
|
||||
* SlickUtil-based audio module
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class SlickAudioModule extends AudioModule {
|
||||
|
||||
private static final Vect INITIAL_LISTENER_POS = Vect.ZERO;
|
||||
private static final int MAX_SOURCES = 256;
|
||||
|
||||
private VectVar listener = Vect.makeVar();
|
||||
private static boolean soundSystemInited = false;
|
||||
|
||||
|
||||
public SlickAudioModule() {
|
||||
|
||||
if (!soundSystemInited) {
|
||||
soundSystemInited = true;
|
||||
|
||||
try {
|
||||
SoundStore.get().setMaxSources(MAX_SOURCES);
|
||||
SoundStore.get().init();
|
||||
setListenerPos(INITIAL_LISTENER_POS);
|
||||
|
||||
App.bus().send(new AudioReadyEvent());
|
||||
} catch (final Throwable t) {
|
||||
Log.e("Error initializing sound system.", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setListenerPos(Vect pos)
|
||||
{
|
||||
listener.setTo(pos);
|
||||
final FloatBuffer buf3 = BufferHelper.alloc(3);
|
||||
final FloatBuffer buf6 = BufferHelper.alloc(6);
|
||||
buf3.clear();
|
||||
BufferHelper.fill(buf3, (float) pos.x(), (float) pos.y(), (float) pos.z());
|
||||
AL10.alListener(AL10.AL_POSITION, buf3);
|
||||
buf3.clear();
|
||||
BufferHelper.fill(buf3, 0, 0, 0);
|
||||
AL10.alListener(AL10.AL_VELOCITY, buf3);
|
||||
buf6.clear();
|
||||
BufferHelper.fill(buf6, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
|
||||
AL10.alListener(AL10.AL_ORIENTATION, buf6);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect getListenerPos()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinitSoundSystem()
|
||||
{
|
||||
SoundStore.get().clear();
|
||||
AL.destroy();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected DeferredAudio doCreateResource(String res)
|
||||
{
|
||||
return new SlickAudio(res);
|
||||
}
|
||||
|
||||
}
|
||||
+79
-30
@@ -3,9 +3,10 @@ package mightypork.gamecore.backend.lwjgl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.resources.TextureBasedResource;
|
||||
import mightypork.gamecore.resources.textures.LazyTexture;
|
||||
import mightypork.gamecore.resources.MustLoadInRenderingContext;
|
||||
import mightypork.gamecore.resources.textures.DeferredTexture;
|
||||
import mightypork.utils.annotations.Alias;
|
||||
import mightypork.utils.exceptions.IllegalValueException;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
@@ -20,8 +21,8 @@ import org.newdawn.slick.opengl.TextureLoader;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@Alias(name = "Texture")
|
||||
@TextureBasedResource
|
||||
public class SlickLazyTexture extends LazyTexture {
|
||||
@MustLoadInRenderingContext
|
||||
public class SlickTexture extends DeferredTexture {
|
||||
|
||||
private org.newdawn.slick.opengl.Texture backingTexture;
|
||||
private boolean alpha;
|
||||
@@ -31,7 +32,7 @@ public class SlickLazyTexture extends LazyTexture {
|
||||
/**
|
||||
* @param resourcePath resource path
|
||||
*/
|
||||
public SlickLazyTexture(String resourcePath) {
|
||||
public SlickTexture(String resourcePath) {
|
||||
super(resourcePath);
|
||||
}
|
||||
|
||||
@@ -42,7 +43,19 @@ public class SlickLazyTexture extends LazyTexture {
|
||||
try {
|
||||
final String ext = FileUtils.getExtension(path).toUpperCase();
|
||||
|
||||
final Texture texture = TextureLoader.getTexture(ext, FileUtils.getResource(path), false, filter.num);
|
||||
final int filtering;
|
||||
switch (filter) {
|
||||
case NEAREST:
|
||||
filtering = GL11.GL_NEAREST;
|
||||
break;
|
||||
case LINEAR:
|
||||
filtering = GL11.GL_LINEAR;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalValueException("Unsupported filtering mode.");
|
||||
}
|
||||
|
||||
final Texture texture = TextureLoader.getTexture(ext, FileUtils.getResource(path), false, filtering);
|
||||
|
||||
if (texture == null) {
|
||||
Log.w("Texture " + path + " could not be loaded.");
|
||||
@@ -71,7 +84,9 @@ public class SlickLazyTexture extends LazyTexture {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Bind to GL context, applying the filters prescribed.
|
||||
*/
|
||||
public void bind()
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
@@ -82,11 +97,35 @@ public class SlickLazyTexture extends LazyTexture {
|
||||
|
||||
GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
|
||||
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrap.num);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrap.num);
|
||||
final int wrapping;
|
||||
switch (wrap) {
|
||||
case CLAMP:
|
||||
wrapping = GL11.GL_CLAMP;
|
||||
break;
|
||||
case REPEAT:
|
||||
wrapping = GL11.GL_REPEAT;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalValueException("Unsupported wrapping mode.");
|
||||
}
|
||||
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter.num);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filter.num);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrapping);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrapping);
|
||||
|
||||
final int filtering;
|
||||
switch (filter) {
|
||||
case NEAREST:
|
||||
filtering = GL11.GL_NEAREST;
|
||||
break;
|
||||
case LINEAR:
|
||||
filtering = GL11.GL_LINEAR;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalValueException("Unsupported filtering mode.");
|
||||
}
|
||||
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filtering);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filtering);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,24 +147,6 @@ public class SlickLazyTexture extends LazyTexture {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float getHeight01()
|
||||
{
|
||||
if (!ensureLoaded()) return 0;
|
||||
|
||||
return backingTexture.getHeight();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float getWidth01()
|
||||
{
|
||||
if (!ensureLoaded()) return 0;
|
||||
|
||||
return backingTexture.getWidth();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
@@ -135,7 +156,35 @@ public class SlickLazyTexture extends LazyTexture {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Get the height of the texture, 0..1.<br>
|
||||
*
|
||||
* @return height 0..1
|
||||
*/
|
||||
public float getHeight01()
|
||||
{
|
||||
if (!ensureLoaded()) return 0;
|
||||
|
||||
return backingTexture.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the width of the texture, 0..1.<br>
|
||||
*
|
||||
* @return width 0..1
|
||||
*/
|
||||
public float getWidth01()
|
||||
{
|
||||
if (!ensureLoaded()) return 0;
|
||||
|
||||
return backingTexture.getWidth();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return OpenGL texture ID
|
||||
*/
|
||||
public int getTextureID()
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
@@ -15,26 +15,6 @@ import mightypork.utils.logging.Log;
|
||||
*/
|
||||
public class WorkDir {
|
||||
|
||||
/**
|
||||
* Route configurator.
|
||||
*/
|
||||
public static interface RouteSetup {
|
||||
|
||||
public void addRoutes(RouteOpts routeOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route configurator access
|
||||
*/
|
||||
public static class RouteOpts {
|
||||
|
||||
public void addPath(String alias, String path)
|
||||
{
|
||||
WorkDir.addPath(alias, path);
|
||||
}
|
||||
}
|
||||
|
||||
public static RouteOpts routeOpts = new RouteOpts();
|
||||
private static File workdir;
|
||||
private static Map<String, String> namedPaths = new HashMap<>();
|
||||
|
||||
@@ -46,7 +26,7 @@ public class WorkDir {
|
||||
|
||||
|
||||
/**
|
||||
* Add a path alias (dir or file)
|
||||
* Add a path alias (dir or file), relative to the workdir.
|
||||
*
|
||||
* @param alias path alias
|
||||
* @param path path relative to workdir
|
||||
@@ -57,12 +37,6 @@ public class WorkDir {
|
||||
}
|
||||
|
||||
|
||||
public static void registerRoutes(RouteSetup rs)
|
||||
{
|
||||
rs.addRoutes(routeOpts);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get workdir folder, create if not exists.
|
||||
*
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
import mightypork.utils.files.config.Property;
|
||||
import mightypork.utils.files.config.PropertyManager;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
@@ -17,45 +18,101 @@ import mightypork.utils.logging.Log;
|
||||
*/
|
||||
public class Config {
|
||||
|
||||
public static KeyOpts keyOpts = new KeyOpts();
|
||||
public static Map<String, KeyProperty> strokes = new HashMap<>();
|
||||
private static Map<String, KeyProperty> strokes = new HashMap<>();
|
||||
|
||||
static PropertyManager cfg;
|
||||
private static PropertyManager propertyManager;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize property manger for a file
|
||||
*
|
||||
* @param file config file
|
||||
* @param comment file comment
|
||||
* @param headComment file comment
|
||||
*/
|
||||
public static void init(File file, String comment)
|
||||
public static void init(File file, String headComment)
|
||||
{
|
||||
cfg = new PropertyManager(file, comment);
|
||||
cfg.cfgNewlineBeforeComments(true);
|
||||
cfg.cfgSeparateSections(true);
|
||||
propertyManager = new PropertyManager(file, headComment);
|
||||
|
||||
propertyManager.cfgNewlineBeforeComments(true);
|
||||
propertyManager.cfgSeparateSections(true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* populate config with keys from a key setup
|
||||
* Add a keystroke property
|
||||
*
|
||||
* @param keys key setup to add
|
||||
* @param key key in config file
|
||||
* @param defval default value (keystroke datastring)
|
||||
* @param comment optional comment, can be null
|
||||
*/
|
||||
public static void registerKeys(KeySetup keys)
|
||||
public void addKeyProperty(String key, String defval, String comment)
|
||||
{
|
||||
keys.addKeys(Config.keyOpts);
|
||||
final KeyProperty kprop = new KeyProperty(Config.prefixKey(key), KeyStroke.createFromDataString(defval), comment);
|
||||
strokes.put(Config.prefixKey(key), kprop);
|
||||
propertyManager.putProperty(kprop);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Populate config with options from a config setup
|
||||
* Add a boolean property (flag)
|
||||
*
|
||||
* @param conf config setup to add
|
||||
* @param key key in config file
|
||||
* @param defval default value
|
||||
* @param comment optional comment, can be null
|
||||
*/
|
||||
public static void registerOptions(ConfigSetup conf)
|
||||
public void addBooleanProperty(String key, boolean defval, String comment)
|
||||
{
|
||||
conf.addOptions(Config.cfg);
|
||||
propertyManager.putBoolean(key, defval, comment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an integer property
|
||||
*
|
||||
* @param key key in config file
|
||||
* @param defval default value
|
||||
* @param comment optional comment, can be null
|
||||
*/
|
||||
public void addIntegerProperty(String key, int defval, String comment)
|
||||
{
|
||||
propertyManager.putInteger(key, defval, comment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a double property
|
||||
*
|
||||
* @param key key in config file
|
||||
* @param defval default value
|
||||
* @param comment optional comment, can be null
|
||||
*/
|
||||
public void addDoubleProperty(String key, double defval, String comment)
|
||||
{
|
||||
propertyManager.putDouble(key, defval, comment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a string property
|
||||
*
|
||||
* @param key key in config file
|
||||
* @param defval default value
|
||||
* @param comment optional comment, can be null
|
||||
*/
|
||||
public void addStringProperty(String key, String defval, String comment)
|
||||
{
|
||||
propertyManager.putString(key, defval, comment);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an arbitrary property (can be custom type)
|
||||
*
|
||||
* @param prop the property to add
|
||||
*/
|
||||
public <T> void addProperty(Property<T> prop)
|
||||
{
|
||||
propertyManager.putProperty(prop);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +121,7 @@ public class Config {
|
||||
*/
|
||||
public static void load()
|
||||
{
|
||||
cfg.load();
|
||||
propertyManager.load();
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +131,7 @@ public class Config {
|
||||
public static void save()
|
||||
{
|
||||
Log.f3("Saving config.");
|
||||
cfg.save();
|
||||
propertyManager.save();
|
||||
}
|
||||
|
||||
|
||||
@@ -87,11 +144,11 @@ public class Config {
|
||||
public static <T> T getValue(String key)
|
||||
{
|
||||
try {
|
||||
if (cfg.getProperty(key) == null) {
|
||||
if (propertyManager.getProperty(key) == null) {
|
||||
throw new IllegalArgumentException("No such property: " + key);
|
||||
}
|
||||
|
||||
return cfg.getValue(key);
|
||||
return propertyManager.getValue(key);
|
||||
} catch (final ClassCastException cce) {
|
||||
throw new RuntimeException("Property of incompatible type: " + key);
|
||||
}
|
||||
@@ -99,18 +156,19 @@ public class Config {
|
||||
|
||||
|
||||
/**
|
||||
* Set option to a value
|
||||
* Set option to a value. Call the save() method to make the change
|
||||
* permanent.
|
||||
*
|
||||
* @param key option key
|
||||
* @param value value to set
|
||||
*/
|
||||
public static <T> void setValue(String key, T value)
|
||||
{
|
||||
if (cfg.getProperty(key) == null) {
|
||||
if (propertyManager.getProperty(key) == null) {
|
||||
throw new IllegalArgumentException("No such property: " + key);
|
||||
}
|
||||
|
||||
cfg.setValue(key, value);
|
||||
propertyManager.setValue(key, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +178,7 @@ public class Config {
|
||||
* @param cfgKey config key
|
||||
* @return key. + cfgKey
|
||||
*/
|
||||
static String prefixKey(String cfgKey)
|
||||
private static String prefixKey(String cfgKey)
|
||||
{
|
||||
return "key." + cfgKey;
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package mightypork.gamecore.core.config;
|
||||
|
||||
|
||||
import mightypork.utils.files.config.PropertyManager;
|
||||
|
||||
|
||||
/**
|
||||
* Config setup, class used to populate the config file.
|
||||
*/
|
||||
public interface ConfigSetup {
|
||||
|
||||
void addOptions(PropertyManager prop);
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package mightypork.gamecore.core.config;
|
||||
|
||||
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
|
||||
|
||||
/**
|
||||
* Key options - restricted access to {@link Config} for keys
|
||||
*/
|
||||
public class KeyOpts {
|
||||
|
||||
public void add(String cfgKey, String dataString)
|
||||
{
|
||||
add(cfgKey, dataString, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param cfgKey key in config file
|
||||
* @param dataString string representing the keystroke (format for
|
||||
* {@link KeyStroke})
|
||||
* @param comment optional comment
|
||||
*/
|
||||
public void add(String cfgKey, String dataString, String comment)
|
||||
{
|
||||
final KeyProperty kprop = new KeyProperty(Config.prefixKey(cfgKey), KeyStroke.createFromDataString(dataString), comment);
|
||||
Config.strokes.put(Config.prefixKey(cfgKey), kprop);
|
||||
Config.cfg.putProperty(kprop);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package mightypork.gamecore.core.config;
|
||||
|
||||
|
||||
/**
|
||||
* Key configurator. Config access restricted to key options.
|
||||
*/
|
||||
public interface KeySetup {
|
||||
|
||||
public void addKeys(KeyOpts keys);
|
||||
}
|
||||
@@ -18,6 +18,14 @@ public class MainLoopRequest extends BusEvent<MainLoop> {
|
||||
private final boolean priority;
|
||||
|
||||
|
||||
/**
|
||||
* @param task task to run on main thread in rendering context
|
||||
*/
|
||||
public MainLoopRequest(Runnable task) {
|
||||
this(task, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param task task to run on main thread in rendering context
|
||||
* @param priority if true, skip other tasks in queue
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mightypork.gamecore.core.events;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.core.modules.MainLoop;
|
||||
import mightypork.utils.eventbus.BusEvent;
|
||||
import mightypork.utils.eventbus.events.flags.NonConsumableEvent;
|
||||
@@ -25,7 +26,7 @@ public class ShudownRequest extends BusEvent<MainLoop> {
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
handler.shutdown();
|
||||
App.shutdown();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
package mightypork.gamecore.core.modules;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.gamecore.backend.Backend;
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.gamecore.initializers.InitTaskResolver;
|
||||
import mightypork.gamecore.plugins.AppPlugin;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
import mightypork.gamecore.resources.audio.AudioModule;
|
||||
import mightypork.utils.MapSort;
|
||||
import mightypork.utils.Support;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.EventBus;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.eventbus.clients.DelegatingList;
|
||||
import mightypork.utils.eventbus.events.DestroyEvent;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
@@ -10,53 +28,78 @@ import mightypork.gamecore.render.RenderModule;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class App {
|
||||
public class App extends BusNode {
|
||||
|
||||
private static App runningInstance;
|
||||
private static Backend backend;
|
||||
|
||||
protected final Backend backend;
|
||||
protected final EventBus eventBus;
|
||||
protected boolean started = false;
|
||||
|
||||
protected final DelegatingList plugins;
|
||||
protected final List<InitTask> initializers = new ArrayList<>();
|
||||
|
||||
|
||||
public App() {
|
||||
if (App.isInitialized()) throw new IllegalStateException("App already initialized");
|
||||
/**
|
||||
* Create an app with given backend.
|
||||
*
|
||||
* @param backend
|
||||
*/
|
||||
public App(Backend backend) {
|
||||
if (App.runningInstance != null) {
|
||||
throw new IllegalStateException("App already initialized");
|
||||
}
|
||||
|
||||
// store current instance in static field
|
||||
App.runningInstance = this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create app with given backend.
|
||||
*
|
||||
* @param backend backend to use
|
||||
*/
|
||||
public void setBackend(Backend backend)
|
||||
{
|
||||
// store used backend in static field
|
||||
App.backend = backend;
|
||||
|
||||
// initialize the backend
|
||||
App.backend.initialize();
|
||||
// create an event bus
|
||||
this.eventBus = new EventBus();
|
||||
|
||||
// join the bus
|
||||
this.eventBus.subscribe(this);
|
||||
|
||||
// create plugin registry attached to bus
|
||||
this.plugins = new DelegatingList();
|
||||
this.eventBus.subscribe(this.plugins);
|
||||
|
||||
// initialize and use backend
|
||||
this.backend = backend;
|
||||
this.eventBus.subscribe(backend);
|
||||
this.backend.initialize();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Throw error if app is not initialized
|
||||
*/
|
||||
protected static void assertInitialized()
|
||||
{
|
||||
if (!App.isInitialized()) throw new IllegalStateException("App is not initialized.");
|
||||
if (backend == null) throw new IllegalStateException("No backend set!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the app is initialized (backend assigned).
|
||||
* Add a plugin to the app. Plugins can eg. listen to bus events and react
|
||||
* to them.
|
||||
*
|
||||
* @return is initialized
|
||||
* @param plugin the added plugin.
|
||||
*/
|
||||
public static boolean isInitialized()
|
||||
public void addPlugin(AppPlugin plugin)
|
||||
{
|
||||
return runningInstance != null;
|
||||
if (started) {
|
||||
throw new IllegalStateException("App already started, cannot add plugins.");
|
||||
}
|
||||
|
||||
plugin.initialize(this);
|
||||
plugins.add(plugin);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an initializer to the app.
|
||||
*
|
||||
* @param order
|
||||
* @param initializer
|
||||
*/
|
||||
public void addInitializer(InitTask initializer)
|
||||
{
|
||||
if (started) {
|
||||
throw new IllegalStateException("App already started, cannot add initializers.");
|
||||
}
|
||||
|
||||
initializers.add(initializer);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,21 +108,115 @@ public class App {
|
||||
*
|
||||
* @return the backend
|
||||
*/
|
||||
public static Backend getBackend()
|
||||
public Backend getBackend()
|
||||
{
|
||||
assertInitialized();
|
||||
return backend;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get renderer instance from the backend
|
||||
* Initialize the App and start operating.<br>
|
||||
* This method should be called after adding all required initializers and
|
||||
* plugins.
|
||||
*/
|
||||
public final void start()
|
||||
{
|
||||
if (started) {
|
||||
throw new IllegalStateException("Already started.");
|
||||
}
|
||||
started = true;
|
||||
|
||||
// pre-init hook, just in case anyone wanted to have one.
|
||||
Log.f2("Calling pre-init hook...");
|
||||
preInit();
|
||||
|
||||
Log.i("=== Starting initialization sequence ===");
|
||||
|
||||
// sort initializers by order.
|
||||
List<InitTask> orderedInitializers = InitTaskResolver.order(initializers);
|
||||
|
||||
for (InitTask initializer : orderedInitializers) {
|
||||
Log.f1("Running init task \"" + initializer.getName() + "\"...");
|
||||
initializer.run(this);
|
||||
}
|
||||
|
||||
Log.i("=== Initialization sequence completed ===");
|
||||
|
||||
// user can now start the main loop etc.
|
||||
Log.f2("Calling post-init hook...");
|
||||
postInit();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook called before the initialization sequence starts.
|
||||
*/
|
||||
@Stub
|
||||
protected void preInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook called after the initialization sequence is finished.
|
||||
*/
|
||||
@Stub
|
||||
protected void postInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public static void shutdown()
|
||||
{
|
||||
if (runningInstance == null) throw new IllegalStateException("App is not running.");
|
||||
|
||||
Log.i("Shutting down subsystems...");
|
||||
|
||||
// TODO send some shutdown notify event
|
||||
|
||||
try {
|
||||
if (bus() != null) {
|
||||
bus().send(new DestroyEvent());
|
||||
bus().destroy();
|
||||
}
|
||||
} catch (final Throwable e) {
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
Log.i("App terminated.");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get graphics module from the backend
|
||||
*
|
||||
* @return backend
|
||||
*/
|
||||
public static RenderModule gfx()
|
||||
public static GraphicsModule gfx()
|
||||
{
|
||||
assertInitialized();
|
||||
return backend.getRenderer();
|
||||
return runningInstance.backend.getGraphics();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get audio module from the backend
|
||||
*
|
||||
* @return backend
|
||||
*/
|
||||
public static AudioModule audio()
|
||||
{
|
||||
return runningInstance.backend.getAudio();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get event bus instance.
|
||||
*
|
||||
* @return event bus
|
||||
*/
|
||||
public static EventBus bus()
|
||||
{
|
||||
return runningInstance.eventBus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package mightypork.gamecore.core.modules;
|
||||
|
||||
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
|
||||
|
||||
/**
|
||||
* App interface visible to subsystems
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface AppAccess extends BusAccess {
|
||||
|
||||
/**
|
||||
* @return sound system
|
||||
*/
|
||||
abstract SoundSystem getSoundSystem();
|
||||
|
||||
|
||||
/**
|
||||
* @return input system
|
||||
*/
|
||||
abstract InputSystem getInput();
|
||||
|
||||
|
||||
/**
|
||||
* Quit to OS<br>
|
||||
* Destroy app & exit VM
|
||||
*/
|
||||
abstract void shutdown();
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package mightypork.gamecore.core.modules;
|
||||
|
||||
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.eventbus.EventBus;
|
||||
|
||||
|
||||
/**
|
||||
* App access adapter (defualt {@link AppAccess} implementation)
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class AppAccessAdapter implements AppAccess {
|
||||
|
||||
private final AppAccess app;
|
||||
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public AppAccessAdapter(AppAccess app) {
|
||||
if (app == null) throw new NullPointerException("AppAccess instance cannot be null.");
|
||||
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final SoundSystem getSoundSystem()
|
||||
{
|
||||
return app.getSoundSystem();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final InputSystem getInput()
|
||||
{
|
||||
return app.getInput();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final EventBus getEventBus()
|
||||
{
|
||||
return app.getEventBus();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void shutdown()
|
||||
{
|
||||
app.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import mightypork.gamecore.backend.Backend;
|
||||
import mightypork.gamecore.core.WorkDir.RouteSetup;
|
||||
import mightypork.gamecore.core.config.ConfigSetup;
|
||||
import mightypork.gamecore.core.config.KeySetup;
|
||||
import mightypork.gamecore.resources.AsyncResourceLoader;
|
||||
@@ -20,28 +19,19 @@ import mightypork.gamecore.resources.ResourceSetup;
|
||||
*/
|
||||
public class AppInitOptions {
|
||||
|
||||
boolean singleInstance = false;
|
||||
|
||||
Backend backend = null;
|
||||
File workdir = null;
|
||||
|
||||
String logDir = "log";
|
||||
String logFilePrefix = "runtime";
|
||||
|
||||
String screenshotDir = "screenshots";
|
||||
|
||||
int logArchiveCount = 0;
|
||||
boolean busLogging = false;
|
||||
|
||||
String configFile = "settings.cfg";
|
||||
String configComment = "Main config file";
|
||||
|
||||
public String lockFile = ".lock";
|
||||
|
||||
final List<ResourceSetup> resourceLists = new ArrayList<>();
|
||||
final List<KeySetup> keyLists = new ArrayList<>();
|
||||
final List<ConfigSetup> configLists = new ArrayList<>();
|
||||
final List<RouteSetup> routeLists = new ArrayList<>();
|
||||
|
||||
ResourceLoader resourceLoader = new AsyncResourceLoader();
|
||||
Level logLevel = Level.ALL;
|
||||
@@ -68,12 +58,6 @@ public class AppInitOptions {
|
||||
}
|
||||
|
||||
|
||||
public void addRoutes(RouteSetup keys)
|
||||
{
|
||||
routeLists.add(keys);
|
||||
}
|
||||
|
||||
|
||||
public void addResources(ResourceSetup res)
|
||||
{
|
||||
resourceLists.add(res);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package mightypork.gamecore.core.modules;
|
||||
|
||||
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.eventbus.clients.RootBusNode;
|
||||
|
||||
|
||||
/**
|
||||
* App event bus client, to be used for subsystems, screens and anything that
|
||||
* needs access to the eventbus and other systems; Attached directly to bus.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class AppModule extends RootBusNode implements AppAccess {
|
||||
|
||||
private final AppAccess app;
|
||||
|
||||
|
||||
/**
|
||||
* Create a module
|
||||
*
|
||||
* @param app access to app systems
|
||||
*/
|
||||
public AppModule(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final SoundSystem getSoundSystem()
|
||||
{
|
||||
return app.getSoundSystem();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final InputSystem getInput()
|
||||
{
|
||||
return app.getInput();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void shutdown()
|
||||
{
|
||||
app.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package mightypork.gamecore.core.modules;
|
||||
|
||||
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.eventbus.clients.DelegatingClient;
|
||||
import mightypork.utils.eventbus.clients.RootBusNode;
|
||||
|
||||
|
||||
/**
|
||||
* Delegating bus client, to be attached to any {@link DelegatingClient}, such
|
||||
* as a {@link RootBusNode}.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class AppSubModule extends BusNode implements AppAccess {
|
||||
|
||||
private final AppAccess app;
|
||||
|
||||
|
||||
/**
|
||||
* Create submodule
|
||||
*
|
||||
* @param app access to app systems
|
||||
*/
|
||||
public AppSubModule(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final SoundSystem getSoundSystem()
|
||||
{
|
||||
return app.getSoundSystem();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final InputSystem getInput()
|
||||
{
|
||||
return app.getInput();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void shutdown()
|
||||
{
|
||||
app.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
package mightypork.gamecore.core.modules;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import mightypork.gamecore.backend.Backend;
|
||||
import mightypork.gamecore.core.WorkDir;
|
||||
import mightypork.gamecore.core.WorkDir.RouteSetup;
|
||||
@@ -16,23 +12,10 @@ import mightypork.gamecore.core.config.KeySetup;
|
||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||
import mightypork.gamecore.gui.screens.impl.CrossfadeOverlay;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.ResourceSetup;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.gamecore.util.SlickLogRedirector;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.EventBus;
|
||||
import mightypork.utils.eventbus.events.DestroyEvent;
|
||||
import mightypork.utils.files.InstanceLock;
|
||||
import mightypork.utils.ion.Ion;
|
||||
import mightypork.utils.ion.IonInput;
|
||||
import mightypork.utils.ion.IonOutput;
|
||||
import mightypork.utils.ion.IonizerBinary;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.logging.writers.LogWriter;
|
||||
import mightypork.utils.math.algo.Coord;
|
||||
import mightypork.utils.math.algo.Move;
|
||||
|
||||
|
||||
/**
|
||||
@@ -41,14 +24,12 @@ import mightypork.utils.math.algo.Move;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class BaseApp extends App implements AppAccess, UncaughtExceptionHandler {
|
||||
public abstract class BaseApp extends App implements UncaughtExceptionHandler {
|
||||
|
||||
// modules
|
||||
private InputSystem inputSystem;
|
||||
private SoundSystem soundSystem;
|
||||
private EventBus eventBus;
|
||||
private MainLoop gameLoop;
|
||||
private ScreenRegistry screenRegistry;
|
||||
|
||||
private boolean started = false;
|
||||
private boolean lockObtained = false;
|
||||
|
||||
@@ -72,25 +53,21 @@ public abstract class BaseApp extends App implements AppAccess, UncaughtExceptio
|
||||
|
||||
|
||||
public BaseApp(Backend backend) {
|
||||
|
||||
eventBus = new EventBus();
|
||||
setBackend(backend);
|
||||
backend.setBusAccess(this);
|
||||
super(backend);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the application
|
||||
*/
|
||||
@Override
|
||||
public final void start()
|
||||
{
|
||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||
|
||||
initialize();
|
||||
|
||||
Log.i("Starting main loop...");
|
||||
|
||||
// open first screen
|
||||
// open first screen !!!
|
||||
started = true;
|
||||
gameLoop.start();
|
||||
}
|
||||
@@ -125,38 +102,6 @@ public abstract class BaseApp extends App implements AppAccess, UncaughtExceptio
|
||||
}
|
||||
Config.load();
|
||||
|
||||
/*
|
||||
* Setup logging
|
||||
*/
|
||||
final LogWriter log = Log.create(opt.logFilePrefix, new File(WorkDir.getDir(opt.logDir), opt.logFilePrefix + ".log"), opt.logArchiveCount);
|
||||
Log.setMainLogger(log);
|
||||
Log.setLevel(opt.logLevel);
|
||||
Log.setSysoutLevel(opt.logSoutLevel);
|
||||
|
||||
// connect slickutil to the logger
|
||||
org.newdawn.slick.util.Log.setLogSystem(new SlickLogRedirector(log));
|
||||
writeLogHeader();
|
||||
|
||||
Log.i("=== Starting initialization sequence ===");
|
||||
|
||||
// pre-init hook
|
||||
Log.f2("Calling pre-init hook...");
|
||||
preInit();
|
||||
|
||||
/*
|
||||
* Event bus
|
||||
*/
|
||||
Log.f2("Starting Event Bus...");
|
||||
eventBus = new EventBus();
|
||||
eventBus.subscribe(this);
|
||||
eventBus.detailedLogging = opt.busLogging;
|
||||
|
||||
/*
|
||||
* Ionizables
|
||||
*/
|
||||
Log.f3("Initializing ION save system...");
|
||||
registerIonizables();
|
||||
|
||||
/*
|
||||
* Display
|
||||
*/
|
||||
@@ -208,126 +153,6 @@ public abstract class BaseApp extends App implements AppAccess, UncaughtExceptio
|
||||
*/
|
||||
Log.f2("Registering screens...");
|
||||
initScreens(screenRegistry);
|
||||
|
||||
postInit();
|
||||
Log.i("=== Initialization sequence completed ===");
|
||||
}
|
||||
|
||||
|
||||
protected void writeLogHeader()
|
||||
{
|
||||
logSystemInfo();
|
||||
}
|
||||
|
||||
|
||||
protected void logSystemInfo()
|
||||
{
|
||||
String txt = "";
|
||||
|
||||
txt += "\n### SYSTEM INFO ###\n\n";
|
||||
txt += " Platform ...... " + System.getProperty("os.name") + "\n";
|
||||
txt += " Runtime ....... " + System.getProperty("java.runtime.name") + "\n";
|
||||
txt += " Java .......... " + System.getProperty("java.version") + "\n";
|
||||
txt += " Launch path ... " + System.getProperty("user.dir") + "\n";
|
||||
|
||||
try {
|
||||
txt += " Workdir ....... " + WorkDir.getWorkDir().getCanonicalPath() + "\n";
|
||||
} catch (final IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
Log.i(txt);
|
||||
}
|
||||
|
||||
|
||||
protected void registerIonizables()
|
||||
{
|
||||
Ion.registerIndirect(255, new IonizerBinary<Coord>() {
|
||||
|
||||
@Override
|
||||
public void save(Coord object, IonOutput out) throws IOException
|
||||
{
|
||||
out.writeInt(object.x);
|
||||
out.writeInt(object.y);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Coord load(IonInput in) throws IOException
|
||||
{
|
||||
final int x = in.readInt();
|
||||
final int y = in.readInt();
|
||||
return new Coord(x, y);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Ion.registerIndirect(254, new IonizerBinary<Move>() {
|
||||
|
||||
@Override
|
||||
public void save(Move object, IonOutput out) throws IOException
|
||||
{
|
||||
out.writeInt(object.x());
|
||||
out.writeInt(object.y());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Move load(IonInput in) throws IOException
|
||||
{
|
||||
final int x = in.readInt();
|
||||
final int y = in.readInt();
|
||||
return new Move(x, y);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called at the beginning of the initialization sequence, right after lock
|
||||
* was obtained.
|
||||
*/
|
||||
@Stub
|
||||
protected void preInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called at the end of init sequence, before main loop starts.
|
||||
*/
|
||||
@Stub
|
||||
protected void postInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create window and configure rendering system
|
||||
*
|
||||
* @param gfx Graphics module
|
||||
*/
|
||||
@Stub
|
||||
protected void initDisplay(RenderModule gfx)
|
||||
{
|
||||
gfx.setSize(800, 600);
|
||||
gfx.setResizable(true);
|
||||
gfx.setTitle("New Game");
|
||||
gfx.setTargetFps(60);
|
||||
|
||||
gfx.createDisplay();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure sound system (ie. adjust volume)
|
||||
*
|
||||
* @param audio
|
||||
*/
|
||||
@Stub
|
||||
protected void initSoundSystem(SoundSystem audio)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -353,104 +178,9 @@ public abstract class BaseApp extends App implements AppAccess, UncaughtExceptio
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to obtain lock.
|
||||
*/
|
||||
private void initLock()
|
||||
{
|
||||
final File lock = WorkDir.getFile(opt.lockFile);
|
||||
if (!InstanceLock.onFile(lock)) {
|
||||
onLockError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Stub
|
||||
protected void initInputSystem(InputSystem input)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Triggered when lock cannot be obtained.<br>
|
||||
* App should terminate gracefully.
|
||||
*/
|
||||
protected void onLockError()
|
||||
{
|
||||
Log.e("Could not obtain lock file.\nOnly one instance can run at a time.");
|
||||
|
||||
//@formatter:off
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Another instance is already running.\n(Delete the "+opt.lockFile +" file in the working directory to override)",
|
||||
"Lock Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final SoundSystem getSoundSystem()
|
||||
{
|
||||
return soundSystem;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final InputSystem getInput()
|
||||
{
|
||||
return inputSystem;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final EventBus getEventBus()
|
||||
{
|
||||
return eventBus;
|
||||
}
|
||||
|
||||
|
||||
protected void beforeShutdown()
|
||||
{
|
||||
// ???
|
||||
if (lockObtained) Config.save();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void uncaughtException(Thread t, Throwable e)
|
||||
{
|
||||
onCrash(e);
|
||||
}
|
||||
|
||||
|
||||
protected void onCrash(Throwable e)
|
||||
{
|
||||
Log.e("The game has crashed.", e);
|
||||
shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void shutdown()
|
||||
{
|
||||
beforeShutdown();
|
||||
|
||||
Log.i("Shutting down subsystems...");
|
||||
|
||||
try {
|
||||
if (getEventBus() != null) {
|
||||
getEventBus().send(new DestroyEvent());
|
||||
getEventBus().destroy();
|
||||
}
|
||||
} catch (final Throwable e) {
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
Log.i("Terminating...");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,14 @@ import java.util.Deque;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||
import mightypork.gamecore.plugins.screenshot.TaskTakeScreenshot;
|
||||
import mightypork.gamecore.render.Renderable;
|
||||
import mightypork.gamecore.render.TaskTakeScreenshot;
|
||||
import mightypork.gamecore.render.events.ScreenshotRequestListener;
|
||||
import mightypork.utils.Support;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.eventbus.events.UpdateEvent;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.timing.Profiler;
|
||||
import mightypork.utils.math.timing.TimerDelta;
|
||||
@@ -21,7 +23,7 @@ import mightypork.utils.math.timing.TimerDelta;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class MainLoop extends AppModule implements ScreenshotRequestListener {
|
||||
public class MainLoop extends BusNode implements Destroyable {
|
||||
|
||||
private static final double MAX_TIME_TASKS = 1 / 30D; // (avoid queue from hogging timing)
|
||||
private static final double MAX_DELTA = 1 / 20D; // (skip huge gaps caused by loading resources etc)
|
||||
@@ -29,16 +31,7 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
|
||||
private final Deque<Runnable> tasks = new ConcurrentLinkedDeque<>();
|
||||
private TimerDelta timer;
|
||||
private Renderable rootRenderable;
|
||||
private volatile boolean running = true;
|
||||
|
||||
|
||||
/**
|
||||
* @param app {@link AppAccess} instance
|
||||
*/
|
||||
public MainLoop(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
private volatile boolean running = true;
|
||||
|
||||
/**
|
||||
* Set primary renderable
|
||||
@@ -68,7 +61,7 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
|
||||
delta = MAX_DELTA;
|
||||
}
|
||||
|
||||
getEventBus().sendDirect(new UpdateEvent(delta));
|
||||
App.bus().sendDirect(new UpdateEvent(delta));
|
||||
|
||||
Runnable r;
|
||||
final long t = Profiler.begin();
|
||||
@@ -115,7 +108,7 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinit()
|
||||
public void destroy()
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
@@ -136,19 +129,4 @@ public class MainLoop extends AppModule implements ScreenshotRequestListener {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onScreenshotRequest()
|
||||
{
|
||||
// ensure it's started in main thread
|
||||
queueTask(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Support.runAsThread(new TaskTakeScreenshot());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ package mightypork.gamecore.gui.components;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppSubModule;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.resources.audio.SoundSystem;
|
||||
import mightypork.utils.eventbus.EventBus;
|
||||
|
||||
@@ -5,7 +5,7 @@ import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.DynamicWidthComponent;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.utils.math.color.Color;
|
||||
import mightypork.utils.math.color.pal.RGB;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
@@ -32,7 +32,7 @@ public class TextButton extends ClickableComponent implements DynamicWidthCompon
|
||||
private boolean hoverMove = true;
|
||||
|
||||
|
||||
public TextButton(GLFont font, String text, Color color) {
|
||||
public TextButton(IFont font, String text, Color color) {
|
||||
this.color = color;
|
||||
|
||||
this.textPainter = new TextPainter(font, AlignX.CENTER, this.color, text);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.components.Component;
|
||||
import mightypork.utils.math.constraints.rect.RectBound;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.components.Component;
|
||||
import mightypork.gamecore.gui.components.LayoutComponent;
|
||||
import mightypork.utils.math.constraints.rect.RectBound;
|
||||
@@ -14,12 +13,11 @@ import mightypork.utils.math.constraints.rect.RectBound;
|
||||
*/
|
||||
public class ConstraintLayout extends LayoutComponent {
|
||||
|
||||
public ConstraintLayout(AppAccess app) {
|
||||
super(app);
|
||||
public ConstraintLayout() {
|
||||
}
|
||||
|
||||
|
||||
public ConstraintLayout(AppAccess app, RectBound context) {
|
||||
public ConstraintLayout(RectBound context) {
|
||||
super(app, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.Component;
|
||||
import mightypork.gamecore.gui.components.LayoutComponent;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.AlignY;
|
||||
import mightypork.gamecore.gui.components.Component;
|
||||
import mightypork.gamecore.gui.components.LayoutComponent;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.components.Component;
|
||||
import mightypork.gamecore.gui.components.LayoutComponent;
|
||||
import mightypork.utils.math.constraints.rect.RectBound;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.components.Component;
|
||||
import mightypork.utils.math.constraints.rect.RectBound;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.gui.components.layout.linear;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.DynamicWidthComponent;
|
||||
import mightypork.gamecore.gui.components.LayoutComponent;
|
||||
|
||||
@@ -6,7 +6,7 @@ import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.BaseComponent;
|
||||
import mightypork.gamecore.gui.components.DynamicWidthComponent;
|
||||
import mightypork.gamecore.resources.fonts.FontRenderer;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.utils.math.color.Color;
|
||||
import mightypork.utils.math.color.pal.RGB;
|
||||
import mightypork.utils.math.constraints.num.Num;
|
||||
@@ -39,32 +39,32 @@ public class TextPainter extends BaseComponent implements DynamicWidthComponent
|
||||
/**
|
||||
* @param font font to use
|
||||
*/
|
||||
public TextPainter(GLFont font) {
|
||||
public TextPainter(IFont font) {
|
||||
this(font, AlignX.LEFT, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
public TextPainter(GLFont font, Color color, String text) {
|
||||
public TextPainter(IFont font, Color color, String text) {
|
||||
this(font, AlignX.LEFT, color, new StringWrapper(text));
|
||||
}
|
||||
|
||||
|
||||
public TextPainter(GLFont font, Color color, StringProvider text) {
|
||||
public TextPainter(IFont font, Color color, StringProvider text) {
|
||||
this(font, AlignX.LEFT, color, text);
|
||||
}
|
||||
|
||||
|
||||
public TextPainter(GLFont font, Color color) {
|
||||
public TextPainter(IFont font, Color color) {
|
||||
this(font, AlignX.LEFT, color, (StringProvider) null);
|
||||
}
|
||||
|
||||
|
||||
public TextPainter(GLFont font, AlignX align, Color color, String text) {
|
||||
public TextPainter(IFont font, AlignX align, Color color, String text) {
|
||||
this(font, align, color, new StringWrapper(text));
|
||||
}
|
||||
|
||||
|
||||
public TextPainter(GLFont font, AlignX align, Color color, StringProvider text) {
|
||||
public TextPainter(IFont font, AlignX align, Color color, StringProvider text) {
|
||||
this.font = new FontRenderer(font);
|
||||
this.color = color;
|
||||
this.align = align;
|
||||
@@ -72,7 +72,7 @@ public class TextPainter extends BaseComponent implements DynamicWidthComponent
|
||||
}
|
||||
|
||||
|
||||
public TextPainter(GLFont font, AlignX align, Color color) {
|
||||
public TextPainter(IFont font, AlignX align, Color color) {
|
||||
this(font, align, color, (StringProvider) null);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.utils.eventbus.clients.DelegatingClient;
|
||||
|
||||
|
||||
@@ -47,11 +46,7 @@ public abstract class LayeredScreen extends Screen {
|
||||
private final LayersClient layersClient = new LayersClient();
|
||||
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public LayeredScreen(AppAccess app) {
|
||||
super(app);
|
||||
public LayeredScreen() {
|
||||
addChildClient(layersClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,17 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppSubModule;
|
||||
import mightypork.gamecore.gui.Hideable;
|
||||
import mightypork.gamecore.gui.components.layout.ConstraintLayout;
|
||||
import mightypork.gamecore.gui.events.LayoutChangeListener;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.input.KeyBinder;
|
||||
import mightypork.gamecore.input.KeyBindingPool;
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.render.Renderable;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.interfaces.Enableable;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
import mightypork.utils.math.color.Color;
|
||||
@@ -30,7 +29,7 @@ import mightypork.utils.math.constraints.vect.Vect;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class Overlay extends AppSubModule implements Comparable<Overlay>, Updateable, Renderable, KeyBinder, Hideable, Enableable, LayoutChangeListener {
|
||||
public abstract class Overlay extends BusNode implements Comparable<Overlay>, Updateable, Renderable, KeyBinder, Hideable, Enableable, LayoutChangeListener {
|
||||
|
||||
private boolean visible = true;
|
||||
private boolean enabled = true;
|
||||
@@ -51,13 +50,11 @@ public abstract class Overlay extends AppSubModule implements Comparable<Overlay
|
||||
private Num alphaMul = Num.ONE;
|
||||
|
||||
|
||||
public Overlay(AppAccess app) {
|
||||
super(app);
|
||||
public Overlay() {
|
||||
|
||||
getInput();
|
||||
this.mouse = InputSystem.getMousePos();
|
||||
|
||||
this.root = new ConstraintLayout(app, App.gfx().getRect());
|
||||
this.root = new ConstraintLayout(App.gfx().getRect());
|
||||
addChildClient(root);
|
||||
addChildClient(keybindings);
|
||||
|
||||
|
||||
@@ -2,16 +2,15 @@ package mightypork.gamecore.gui.screens;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppSubModule;
|
||||
import mightypork.gamecore.gui.events.LayoutChangeEvent;
|
||||
import mightypork.gamecore.gui.events.LayoutChangeListener;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.input.KeyBinder;
|
||||
import mightypork.gamecore.input.KeyBindingPool;
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.render.Renderable;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.math.constraints.rect.Rect;
|
||||
import mightypork.utils.math.constraints.rect.RectBound;
|
||||
|
||||
@@ -21,7 +20,7 @@ import mightypork.utils.math.constraints.rect.RectBound;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class Screen extends AppSubModule implements Renderable, RectBound, KeyBinder, LayoutChangeListener {
|
||||
public abstract class Screen extends BusNode implements Renderable, RectBound, KeyBinder, LayoutChangeListener {
|
||||
|
||||
private final KeyBindingPool keybindings = new KeyBindingPool();
|
||||
|
||||
@@ -32,8 +31,7 @@ public abstract class Screen extends AppSubModule implements Renderable, RectBou
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public Screen(AppAccess app) {
|
||||
super(app);
|
||||
public Screen() {
|
||||
|
||||
// disable events initially
|
||||
setListening(false);
|
||||
@@ -44,7 +42,7 @@ public abstract class Screen extends AppSubModule implements Renderable, RectBou
|
||||
|
||||
private void fireLayoutChangeEvent()
|
||||
{
|
||||
getEventBus().sendDirectToChildren(this, new LayoutChangeEvent());
|
||||
App.bus().sendDirectToChildren(this, new LayoutChangeEvent());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ public abstract class ScreenLayer extends Overlay {
|
||||
* @param screen parent screen
|
||||
*/
|
||||
public ScreenLayer(Screen screen) {
|
||||
super(screen); // screen as AppAccess
|
||||
|
||||
this.screen = screen;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,14 +6,13 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppModule;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.gui.events.LayoutChangeEvent;
|
||||
import mightypork.gamecore.gui.events.ScreenRequestListener;
|
||||
import mightypork.gamecore.render.Renderable;
|
||||
import mightypork.gamecore.render.events.ViewportChangeEvent;
|
||||
import mightypork.gamecore.render.events.ViewportChangeListener;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
@@ -22,21 +21,13 @@ import mightypork.utils.logging.Log;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class ScreenRegistry extends AppModule implements ScreenRequestListener, ViewportChangeListener, Renderable {
|
||||
public class ScreenRegistry extends BusNode implements ScreenRequestListener, ViewportChangeListener, Renderable {
|
||||
|
||||
private final Map<String, Screen> screens = new HashMap<>();
|
||||
private final Collection<Overlay> overlays = new TreeSet<>();
|
||||
private volatile Screen active = null;
|
||||
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public ScreenRegistry(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a screen
|
||||
*
|
||||
@@ -100,14 +91,6 @@ public class ScreenRegistry extends AppModule implements ScreenRequestListener,
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Stub
|
||||
protected void deinit()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onViewportChanged(ViewportChangeEvent event)
|
||||
{
|
||||
@@ -117,7 +100,7 @@ public class ScreenRegistry extends AppModule implements ScreenRequestListener,
|
||||
|
||||
private void fireLayoutUpdateEvent()
|
||||
{
|
||||
getEventBus().sendDirectToChildren(this, new LayoutChangeEvent());
|
||||
App.bus().sendDirectToChildren(this, new LayoutChangeEvent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package mightypork.gamecore.gui.screens.impl;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.events.ShudownRequest;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.events.ScreenRequest;
|
||||
import mightypork.gamecore.gui.screens.Overlay;
|
||||
@@ -31,9 +31,9 @@ public class CrossfadeOverlay extends Overlay {
|
||||
public void run()
|
||||
{
|
||||
if (requestedScreenName == null) {
|
||||
getEventBus().send(new ShudownRequest());
|
||||
App.bus().send(new ShudownRequest());
|
||||
} else {
|
||||
getEventBus().send(new ScreenRequest(requestedScreenName));
|
||||
App.bus().send(new ScreenRequest(requestedScreenName));
|
||||
}
|
||||
alpha.setEasing(Easing.SINE_OUT);
|
||||
alpha.fadeOut(T_OUT);
|
||||
@@ -41,9 +41,7 @@ public class CrossfadeOverlay extends Overlay {
|
||||
};
|
||||
|
||||
|
||||
public CrossfadeOverlay(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
public CrossfadeOverlay() {
|
||||
final QuadPainter qp = new QuadPainter(RGB.BLACK); // TODO allow custom colors
|
||||
qp.setRect(root);
|
||||
root.add(qp);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package mightypork.gamecore.initializers;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
|
||||
|
||||
/**
|
||||
* App initializer. A sequence of initializers is executed once the start()
|
||||
* method on App is called. Adding initializers is one way to customize the App
|
||||
* behavior and features.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class InitTask {
|
||||
|
||||
/**
|
||||
* Run the initalizer on app.
|
||||
*
|
||||
* @param app the app instance.
|
||||
*/
|
||||
public abstract void run(App app);
|
||||
|
||||
|
||||
/**
|
||||
* Get name of this initializer (for dependency resolver).<br>
|
||||
* The name should be short, snake_case and precise.
|
||||
*
|
||||
* @return name
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
|
||||
/**
|
||||
* Get what other initializers must be already loaded before this can load.<br>
|
||||
* Depending on itself or creating a circular dependency will cause error.<br>
|
||||
* If the dependencies cannot be satisfied, the initialization sequence will
|
||||
* be aborted.
|
||||
*
|
||||
* @return array of names of required initializers.
|
||||
*/
|
||||
@Stub
|
||||
public String[] getDependencies()
|
||||
{
|
||||
return new String[] {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package mightypork.gamecore.initializers;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
public class InitTaskResolver {
|
||||
|
||||
/**
|
||||
* Order init tasks so that all dependencies are loaded before thye are
|
||||
* needed by the tasks.
|
||||
*
|
||||
* @param tasks task list
|
||||
* @return task list ordered
|
||||
*/
|
||||
public static List<InitTask> order(List<InitTask> tasks)
|
||||
{
|
||||
List<InitTask> remaining = new ArrayList<>(tasks);
|
||||
|
||||
List<InitTask> ordered = new ArrayList<>();
|
||||
Set<String> loaded = new HashSet<>();
|
||||
|
||||
// resolve task order
|
||||
int addedThisIteration = 0;
|
||||
do {
|
||||
for (Iterator<InitTask> i = remaining.iterator(); i.hasNext();) {
|
||||
InitTask task = i.next();
|
||||
|
||||
String[] deps = task.getDependencies();
|
||||
if (deps == null) deps = new String[] {};
|
||||
|
||||
int unmetDepsCount = deps.length;
|
||||
|
||||
for (String d : deps) {
|
||||
if (loaded.contains(d)) unmetDepsCount--;
|
||||
}
|
||||
|
||||
if (unmetDepsCount == 0) {
|
||||
ordered.add(task);
|
||||
loaded.add(task.getName());
|
||||
i.remove();
|
||||
addedThisIteration++;
|
||||
}
|
||||
}
|
||||
} while (addedThisIteration > 0);
|
||||
|
||||
// check if any tasks are left out
|
||||
if (remaining.size() > 0) {
|
||||
|
||||
// build error message for each bad task
|
||||
for (InitTask task : remaining) {
|
||||
String notSatisfied = "";
|
||||
|
||||
for (String d : task.getDependencies()) {
|
||||
if (!loaded.contains(d)) {
|
||||
|
||||
if (!notSatisfied.isEmpty()) {
|
||||
notSatisfied += ", ";
|
||||
}
|
||||
|
||||
notSatisfied += d;
|
||||
}
|
||||
}
|
||||
|
||||
Log.w("InitTask \"" + task.getName() + "\" - missing dependencies: " + notSatisfied);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Some InitTask dependencies could not be satisfied.");
|
||||
}
|
||||
|
||||
return ordered;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package mightypork.gamecore.initializers.tasks;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.utils.ion.Ion;
|
||||
import mightypork.utils.ion.IonInput;
|
||||
import mightypork.utils.ion.IonOutput;
|
||||
import mightypork.utils.ion.IonizerBinary;
|
||||
import mightypork.utils.math.algo.Coord;
|
||||
import mightypork.utils.math.algo.Move;
|
||||
|
||||
|
||||
/**
|
||||
* Register extra ionizables added by the game library (non-native ION types).<br>
|
||||
* This initializer can be called anywhere in the initialization sequence.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskRegisterIonizables extends InitTask {
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
Ion.registerIndirect(255, new IonizerBinary<Coord>() {
|
||||
|
||||
@Override
|
||||
public void save(Coord object, IonOutput out) throws IOException
|
||||
{
|
||||
out.writeInt(object.x);
|
||||
out.writeInt(object.y);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Coord load(IonInput in) throws IOException
|
||||
{
|
||||
final int x = in.readInt();
|
||||
final int y = in.readInt();
|
||||
return new Coord(x, y);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Ion.registerIndirect(254, new IonizerBinary<Move>() {
|
||||
|
||||
@Override
|
||||
public void save(Move object, IonOutput out) throws IOException
|
||||
{
|
||||
out.writeInt(object.x());
|
||||
out.writeInt(object.y());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Move load(IonInput in) throws IOException
|
||||
{
|
||||
final int x = in.readInt();
|
||||
final int y = in.readInt();
|
||||
return new Move(x, y);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "ion";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package mightypork.gamecore.initializers.tasks;
|
||||
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Add a crash handler to the app.<br>
|
||||
* For customized crash message / crash dialog etc, override the
|
||||
* uncaughtException() method.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskSetupCrashHandler extends InitTask implements UncaughtExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Stub
|
||||
public void uncaughtException(Thread thread, Throwable throwable)
|
||||
{
|
||||
Log.e("The game has crashed.", throwable);
|
||||
App.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "crash_handler";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package mightypork.gamecore.initializers.tasks;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
|
||||
|
||||
/**
|
||||
* Setup main window.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskSetupDisplay extends InitTask {
|
||||
|
||||
private int width = 800, height = 600, fps = 60;
|
||||
private boolean resizable, fullscreen;
|
||||
private String title = "Game";
|
||||
|
||||
|
||||
/**
|
||||
* Set initial window size
|
||||
*
|
||||
* @param width width (px)
|
||||
* @param height height (px)
|
||||
*/
|
||||
public void setSize(int width, int height)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether the window should be resizable
|
||||
*
|
||||
* @param resizable true for resizable
|
||||
*/
|
||||
public void setResizable(boolean resizable)
|
||||
{
|
||||
this.resizable = resizable;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set window title
|
||||
*
|
||||
* @param title title text
|
||||
*/
|
||||
public void setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set desired framerate.
|
||||
*
|
||||
* @param fps FPS
|
||||
*/
|
||||
public void setTargetFps(int fps)
|
||||
{
|
||||
this.fps = fps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether the window should start in fullscreen
|
||||
*
|
||||
* @param fullscreen true for fullscreen
|
||||
*/
|
||||
public void setFullscreen(boolean fullscreen)
|
||||
{
|
||||
this.fullscreen = fullscreen;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
GraphicsModule gfx = app.getBackend().getGraphics();
|
||||
|
||||
gfx.setSize(width, height);
|
||||
gfx.setResizable(resizable);
|
||||
gfx.setTitle(title);
|
||||
gfx.setTargetFps(fps);
|
||||
|
||||
if (fullscreen) gfx.setFullscreen(true);
|
||||
|
||||
gfx.createDisplay();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "display";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package mightypork.gamecore.initializers.tasks;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import mightypork.gamecore.core.WorkDir;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.logging.writers.LogWriter;
|
||||
|
||||
|
||||
/**
|
||||
* Init main logger and console log printing.<br>
|
||||
* Must be called after workdir is initialized.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskSetupLog extends InitTask {
|
||||
|
||||
private String logDir = "log";
|
||||
private String logName = "runtime";
|
||||
private int archiveCount = 5;
|
||||
|
||||
private Level levelWrite = Level.ALL;
|
||||
private Level levelPrint = Level.ALL;
|
||||
|
||||
|
||||
/**
|
||||
* Set log directory (relative to workdir).<br>
|
||||
* Defaults to "log".
|
||||
*
|
||||
* @param logDir log directory.
|
||||
*/
|
||||
public void setLogDir(String logDir)
|
||||
{
|
||||
this.logDir = logDir;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set log name. This name is used as a prefix for archived log files.<br>
|
||||
* Should contain only valid filename characters.<br>
|
||||
* Defaults to "runtime".
|
||||
*
|
||||
* @param logName log name
|
||||
*/
|
||||
public void setLogName(String logName)
|
||||
{
|
||||
// TODO validate characters
|
||||
this.logName = logName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set number of logs to keep in the logs directory.<br>
|
||||
* Set to 0 to keep just the last log, -1 to keep unlimited number of logs.<br>
|
||||
* Defaults to 5.
|
||||
*
|
||||
* @param archiveCount logs to keep
|
||||
*/
|
||||
public void setArchiveCount(int archiveCount)
|
||||
{
|
||||
this.archiveCount = archiveCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set logging levels (minimal level of message to be accepted)<br>
|
||||
* Defaults to ALL, ALL.
|
||||
*
|
||||
* @param levelWrite level for writing to file
|
||||
* @param levelPrint level for writing to stdout / stderr
|
||||
*/
|
||||
public void setLevels(Level levelWrite, Level levelPrint)
|
||||
{
|
||||
this.levelWrite = levelWrite;
|
||||
this.levelPrint = levelPrint;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
final LogWriter log = Log.create(logName, new File(WorkDir.getDir(logDir), logName + ".log"), archiveCount);
|
||||
Log.setMainLogger(log);
|
||||
Log.setLevel(levelWrite);
|
||||
Log.setSysoutLevel(levelPrint);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "log";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String[] getDependencies()
|
||||
{
|
||||
return new String[] { "workdir" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package mightypork.gamecore.initializers.tasks;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import mightypork.gamecore.core.WorkDir;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.files.InstanceLock;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Initializer that takes care of setting up the proper workdir.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskSetupWorkdir extends InitTask {
|
||||
|
||||
private final File workdirPath;
|
||||
private boolean doLock;
|
||||
private String lockFile = ".lock";
|
||||
private Map<String, String> namedPaths = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* @param workdir path to the working directory
|
||||
* @param lock whether to lock the directory (single instance mode)
|
||||
*/
|
||||
public InitTaskSetupWorkdir(File workdir, boolean lock) {
|
||||
this.workdirPath = workdir;
|
||||
this.doLock = lock;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set name of the lock file.
|
||||
*
|
||||
* @param lockFile
|
||||
*/
|
||||
public void setLockFileName(String lockFile)
|
||||
{
|
||||
this.lockFile = lockFile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a named path
|
||||
*
|
||||
* @param alias path alias (snake_case)
|
||||
* @param path path (relative to the workdir)
|
||||
*/
|
||||
public void addPath(String alias, String path)
|
||||
{
|
||||
namedPaths.put(alias, path);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
WorkDir.init(workdirPath);
|
||||
|
||||
// lock working directory
|
||||
if (doLock) {
|
||||
final File lock = WorkDir.getFile(lockFile);
|
||||
if (!InstanceLock.onFile(lock)) {
|
||||
onLockError();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> e : namedPaths.entrySet()) {
|
||||
WorkDir.addPath(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when the lock file could not be obtained (cannot write or already
|
||||
* exists).<br>
|
||||
* Feel free to override this method to define custom behavior.
|
||||
*/
|
||||
@Stub
|
||||
protected void onLockError()
|
||||
{
|
||||
Log.e("Could not obtain lock file.\nOnly one instance can run at a time.");
|
||||
|
||||
//@formatter:off
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"Another instance is already running.\n(Delete the "+lockFile +" file in the working directory to override)",
|
||||
"Lock Error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
App.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "workdir";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package mightypork.gamecore.initializers.tasks;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.core.WorkDir;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.initializers.InitTask;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* initializer task that writes a system info header to the log file.<br>
|
||||
* Must be called after log is initialized.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InitTaskWriteLogHeader extends InitTask {
|
||||
|
||||
@Override
|
||||
public void run(App app)
|
||||
{
|
||||
String txt = "";
|
||||
|
||||
txt += "\n### SYSTEM INFO ###\n\n";
|
||||
txt += " Platform ...... " + System.getProperty("os.name") + "\n";
|
||||
txt += " Runtime ....... " + System.getProperty("java.runtime.name") + "\n";
|
||||
txt += " Java .......... " + System.getProperty("java.version") + "\n";
|
||||
txt += " Launch path ... " + System.getProperty("user.dir") + "\n";
|
||||
|
||||
try {
|
||||
txt += " Workdir ....... " + WorkDir.getWorkDir().getCanonicalPath() + "\n";
|
||||
} catch (final IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
|
||||
Log.i(txt);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "log_header";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String[] getDependencies()
|
||||
{
|
||||
return new String[] { "log", "workdir" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package mightypork.gamecore.input;
|
||||
|
||||
/**
|
||||
* Type of keystroke (falling / rising edge)
|
||||
*/
|
||||
public enum Edge
|
||||
{
|
||||
/** Activated by falling edge (press) */
|
||||
FALLING,
|
||||
/** Activated by rising edge (release) */
|
||||
RISING;
|
||||
}
|
||||
@@ -2,13 +2,13 @@ package mightypork.gamecore.input;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.events.UserQuitRequest;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.input.events.InputReadyEvent;
|
||||
import mightypork.gamecore.input.events.KeyEvent;
|
||||
import mightypork.gamecore.input.events.MouseButtonEvent;
|
||||
import mightypork.gamecore.input.events.MouseMotionEvent;
|
||||
import mightypork.utils.eventbus.clients.RootBusNode;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
import mightypork.utils.math.constraints.vect.var.VectVar;
|
||||
@@ -24,7 +24,7 @@ import org.lwjgl.opengl.Display;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
public class InputSystem extends BusNode implements Updateable, KeyBinder, Destroyable {
|
||||
|
||||
private static boolean inited = false;
|
||||
|
||||
@@ -58,8 +58,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public InputSystem(AppAccess app) {
|
||||
super(app);
|
||||
public InputSystem() {
|
||||
|
||||
initDevices();
|
||||
|
||||
@@ -67,12 +66,12 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
keybindings = new KeyBindingPool();
|
||||
addChildClient(keybindings);
|
||||
|
||||
getEventBus().send(new InputReadyEvent());
|
||||
App.bus().send(new InputReadyEvent());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void deinit()
|
||||
public final void destroy()
|
||||
{
|
||||
Mouse.destroy();
|
||||
Keyboard.destroy();
|
||||
@@ -128,7 +127,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
}
|
||||
|
||||
if (wasMouse && !mouseMove.isZero()) {
|
||||
getEventBus().send(new MouseMotionEvent(mouseLastPos, mouseMove));
|
||||
App.bus().send(new MouseMotionEvent(mouseLastPos, mouseMove));
|
||||
}
|
||||
|
||||
while (Keyboard.next()) {
|
||||
@@ -136,7 +135,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
}
|
||||
|
||||
if (Display.isCloseRequested()) {
|
||||
getEventBus().send(new UserQuitRequest());
|
||||
App.bus().send(new UserQuitRequest());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +154,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
pos.setY(Display.getHeight() - pos.y());
|
||||
|
||||
if (button != -1 || wheeld != 0) {
|
||||
getEventBus().send(new MouseButtonEvent(pos.freeze(), button, down, wheeld));
|
||||
App.bus().send(new MouseButtonEvent(pos.freeze(), button, down, wheeld));
|
||||
}
|
||||
|
||||
moveSum.setTo(moveSum.add(move));
|
||||
@@ -169,7 +168,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
|
||||
final boolean down = Keyboard.getEventKeyState();
|
||||
final char c = Keyboard.getEventCharacter();
|
||||
|
||||
getEventBus().send(new KeyEvent(key, c, down));
|
||||
App.bus().send(new KeyEvent(key, c, down));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package mightypork.gamecore.input;
|
||||
|
||||
|
||||
import mightypork.gamecore.gui.Action;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.input;
|
||||
|
||||
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.input.events.InputReadyListener;
|
||||
import mightypork.gamecore.input.events.KeyEvent;
|
||||
import mightypork.gamecore.input.events.KeyEventHandler;
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.input.events.KeyEvent;
|
||||
import mightypork.gamecore.input.events.KeyEventHandler;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
@@ -7,34 +7,43 @@ import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
/**
|
||||
* Key stroke trigger
|
||||
* Key stroke description
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class KeyStroke { //implements Pollable
|
||||
|
||||
public static enum Edge
|
||||
{
|
||||
FALLING, RISING;
|
||||
}
|
||||
public class KeyStroke {
|
||||
|
||||
private int mod;
|
||||
private int key;
|
||||
|
||||
|
||||
/**
|
||||
* KeyStroke
|
||||
* Create a Key Stroke
|
||||
*
|
||||
* @param key key code
|
||||
* @param mod_mask mods mask
|
||||
* @param modmask modifiers
|
||||
*/
|
||||
public KeyStroke(int key, int mod_mask) {
|
||||
setTo(key, mod_mask);
|
||||
public KeyStroke(int key, int modmask) {
|
||||
setTo(key, modmask);
|
||||
}
|
||||
|
||||
|
||||
// FIXME TODO can probably be immutable!
|
||||
/**
|
||||
* Change to...
|
||||
*
|
||||
* @param key key code
|
||||
* @param modmask modifiers
|
||||
*/
|
||||
public void setTo(int key, int modmask)
|
||||
{
|
||||
this.key = key;
|
||||
this.mod = modmask | Keys.keyToMod(key); // for mods alone
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rising edge keystroke
|
||||
* Create a new keystroke without modifiers
|
||||
*
|
||||
* @param key key code
|
||||
*/
|
||||
@@ -55,13 +64,6 @@ public class KeyStroke { //implements Pollable
|
||||
}
|
||||
|
||||
|
||||
public void setTo(int key, int mod_mask)
|
||||
{
|
||||
this.key = key;
|
||||
this.mod = mod_mask | Keys.keyToMod(key); // for mods alone
|
||||
}
|
||||
|
||||
|
||||
public String toDataString()
|
||||
{
|
||||
String s = "";
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package mightypork.gamecore.plugins;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.utils.annotations.Stub;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
|
||||
|
||||
/**
|
||||
* App plugin. Plugins are an easy way to extend app functionality.<br>
|
||||
* Typically, a plugin waits for trigger event(s) and performs some action upon
|
||||
* receiving them.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class AppPlugin extends BusNode {
|
||||
|
||||
/**
|
||||
* Initialize the plugin for the given App.<br>
|
||||
* The plugin is already attached to the event bus.
|
||||
*
|
||||
* @param app
|
||||
*/
|
||||
@Stub
|
||||
public void initialize(App app)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package mightypork.gamecore.plugins.screenshot;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.events.MainLoopRequest;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.plugins.AppPlugin;
|
||||
import mightypork.utils.Support;
|
||||
|
||||
|
||||
/**
|
||||
* This plugin waits for a {@link ScreenshotRequest} event.<br>
|
||||
* Upon receiving it, a screenshot is captured and written to file
|
||||
* asynchronously.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class ScreenshotPlugin extends AppPlugin {
|
||||
|
||||
/**
|
||||
* Take screenshot. Called by the trigger event.
|
||||
*/
|
||||
void takeScreenshot()
|
||||
{
|
||||
App.bus().send(new MainLoopRequest(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Runnable tts = new TaskTakeScreenshot();
|
||||
Support.runAsThread(tts);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package mightypork.gamecore.plugins.screenshot;
|
||||
|
||||
|
||||
import mightypork.utils.eventbus.BusEvent;
|
||||
import mightypork.utils.eventbus.events.flags.SingleReceiverEvent;
|
||||
|
||||
|
||||
/**
|
||||
* Event used to request screenshot capture.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
@SingleReceiverEvent
|
||||
public class ScreenshotRequest extends BusEvent<ScreenshotPlugin> {
|
||||
|
||||
@Override
|
||||
protected void handleBy(ScreenshotPlugin handler)
|
||||
{
|
||||
handler.takeScreenshot();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package mightypork.gamecore.plugins.screenshot;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.core.WorkDir;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.render.Screenshot;
|
||||
import mightypork.utils.Support;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Task that takes screenshot and asynchronously saves it to a file.<br>
|
||||
* Can be run in a separate thread, but must be instantiated in the render
|
||||
* thread.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TaskTakeScreenshot implements Runnable {
|
||||
|
||||
private final Screenshot scr;
|
||||
|
||||
|
||||
/**
|
||||
* Take screenshot. Must be called in render thread.
|
||||
*/
|
||||
public TaskTakeScreenshot() {
|
||||
scr = App.gfx().takeScreenshot();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
// generate unique filename
|
||||
final File file = getScreenshotFile();
|
||||
|
||||
Log.f3("Saving screenshot to file: " + file);
|
||||
|
||||
// save to disk
|
||||
try {
|
||||
scr.save(file);
|
||||
} catch (final IOException e) {
|
||||
Log.e("Failed to save screenshot.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return File to save the screenshot to.
|
||||
*/
|
||||
protected File getScreenshotFile()
|
||||
{
|
||||
final String fname = getBaseFilename();
|
||||
return findFreeFile(fname);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return directory for screenshots
|
||||
*/
|
||||
protected File getScreenshotDirectory()
|
||||
{
|
||||
return WorkDir.getDir("_screenshot_dir");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get base filename for the screenshot, without extension.
|
||||
*
|
||||
* @return filename
|
||||
*/
|
||||
protected String getBaseFilename()
|
||||
{
|
||||
return Support.getTime("yyyy-MM-dd_HH-mm-ss");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find first free filename for the screenshot, by adding -NUMBER after the
|
||||
* base filename and before extension.
|
||||
*
|
||||
* @param base_name base filename
|
||||
* @return full path to screenshot file
|
||||
*/
|
||||
protected File findFreeFile(String base_name)
|
||||
{
|
||||
File file;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
file = new File(getScreenshotDirectory(), base_name + (index > 0 ? "-" + index : "") + ".png");
|
||||
if (!file.exists()) break;
|
||||
index++;
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
}
|
||||
+3
-8
@@ -2,9 +2,8 @@ package mightypork.gamecore.render;
|
||||
|
||||
|
||||
import mightypork.gamecore.backend.BackendModule;
|
||||
import mightypork.gamecore.resources.textures.LazyTexture;
|
||||
import mightypork.gamecore.resources.textures.DeferredTexture;
|
||||
import mightypork.gamecore.resources.textures.TxQuad;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
import mightypork.utils.math.color.Color;
|
||||
import mightypork.utils.math.constraints.rect.Rect;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
@@ -19,11 +18,7 @@ import mightypork.utils.math.timing.FpsMeter;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class RenderModule extends BackendModule {
|
||||
|
||||
public RenderModule(BusAccess busAccess) {
|
||||
super(busAccess);
|
||||
}
|
||||
public abstract class GraphicsModule extends BackendModule {
|
||||
|
||||
protected static final VectConst AXIS_X = Vect.make(1, 0, 0);
|
||||
protected static final VectConst AXIS_Y = Vect.make(0, 1, 0);
|
||||
@@ -271,7 +266,7 @@ public abstract class RenderModule extends BackendModule {
|
||||
* @param path path to texture
|
||||
* @return the lazy texture
|
||||
*/
|
||||
public abstract LazyTexture getLazyTexture(String path);
|
||||
public abstract DeferredTexture getLazyTexture(String path);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1,57 +0,0 @@
|
||||
package mightypork.gamecore.render;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.gamecore.core.WorkDir;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.utils.Support;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
import org.newdawn.slick.opengl.GLUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Task that takes screenshot and asynchronously saves it to a file.<br>
|
||||
* Can be run in a separate thread, but must be instantiated in the render
|
||||
* thread.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TaskTakeScreenshot implements Runnable {
|
||||
|
||||
private final Screenshot scr;
|
||||
|
||||
|
||||
public TaskTakeScreenshot() {
|
||||
GLUtils.checkGLContext();
|
||||
scr = App.gfx().takeScreenshot();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final String fname = Support.getTime("yyyy-MM-dd_HH-mm-ss");
|
||||
|
||||
// generate unique filename
|
||||
File file;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
file = new File(WorkDir.getDir("_screenshot_dir"), fname + (index > 0 ? "-" + index : "") + ".png");
|
||||
if (!file.exists()) break;
|
||||
index++;
|
||||
}
|
||||
|
||||
Log.f3("Saving screenshot to file: " + file);
|
||||
|
||||
// save to disk
|
||||
try {
|
||||
scr.save(file);
|
||||
} catch (final IOException e) {
|
||||
Log.e("Failed to save screenshot.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
package mightypork.gamecore.render.events;
|
||||
|
||||
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
import mightypork.utils.eventbus.BusEvent;
|
||||
import mightypork.utils.eventbus.events.flags.SingleReceiverEvent;
|
||||
|
||||
|
||||
@SingleReceiverEvent
|
||||
public class FullscreenToggleRequest extends BusEvent<RenderModule> {
|
||||
public class FullscreenToggleRequest extends BusEvent<GraphicsModule> {
|
||||
|
||||
@Override
|
||||
protected void handleBy(RenderModule handler)
|
||||
protected void handleBy(GraphicsModule handler)
|
||||
{
|
||||
handler.switchFullscreen();
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package mightypork.gamecore.render.events;
|
||||
|
||||
|
||||
import mightypork.utils.eventbus.BusEvent;
|
||||
|
||||
|
||||
public class ScreenshotRequest extends BusEvent<ScreenshotRequestListener> {
|
||||
|
||||
@Override
|
||||
protected void handleBy(ScreenshotRequestListener handler)
|
||||
{
|
||||
handler.onScreenshotRequest();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package mightypork.gamecore.render.events;
|
||||
|
||||
|
||||
public interface ScreenshotRequestListener {
|
||||
|
||||
public void onScreenshotRequest();
|
||||
}
|
||||
@@ -6,8 +6,9 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import mightypork.gamecore.core.events.MainLoopRequest;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.utils.Reflect;
|
||||
import mightypork.utils.Support;
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
@@ -21,17 +22,15 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
|
||||
|
||||
private final ExecutorService exs = Executors.newFixedThreadPool(2);
|
||||
|
||||
private final LinkedBlockingQueue<LazyResource> toLoad = new LinkedBlockingQueue<>();
|
||||
private final LinkedBlockingQueue<DeferredResource> toLoad = new LinkedBlockingQueue<>();
|
||||
private volatile boolean stopped;
|
||||
private BusAccess app;
|
||||
private volatile boolean mainLoopQueuing = true;
|
||||
|
||||
|
||||
@Override
|
||||
public synchronized void init(BusAccess app)
|
||||
public synchronized void init()
|
||||
{
|
||||
this.app = app;
|
||||
app.getEventBus().subscribe(this);
|
||||
App.bus().subscribe(this); // FIXME bad
|
||||
setDaemon(true);
|
||||
super.start();
|
||||
}
|
||||
@@ -49,19 +48,19 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
|
||||
|
||||
|
||||
@Override
|
||||
public void loadResource(final LazyResource resource)
|
||||
public void loadResource(final DeferredResource resource)
|
||||
{
|
||||
if (resource.isLoaded()) return;
|
||||
|
||||
// textures & fonts needs to be loaded in main thread
|
||||
if (resource.getClass().isAnnotationPresent(TextureBasedResource.class)) {
|
||||
if (Reflect.hasAnnotation(resource, MustLoadInRenderingContext.class)) {
|
||||
|
||||
if (!mainLoopQueuing) {
|
||||
// just let it be
|
||||
} else {
|
||||
Log.f3("(loader) Delegating to main thread: " + Support.str(resource));
|
||||
|
||||
app.getEventBus().send(new MainLoopRequest(new Runnable() {
|
||||
App.bus().send(new MainLoopRequest(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
@@ -86,7 +85,7 @@ public class AsyncResourceLoader extends Thread implements ResourceLoader, Destr
|
||||
while (!stopped) {
|
||||
|
||||
try {
|
||||
final LazyResource def = toLoad.take();
|
||||
final DeferredResource def = toLoad.take();
|
||||
if (def == null) continue;
|
||||
|
||||
if (!def.isLoaded()) {
|
||||
|
||||
+4
-4
@@ -16,7 +16,7 @@ import mightypork.utils.string.StringUtil;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@Alias(name = "Resource")
|
||||
public abstract class BaseLazyResource implements LazyResource, Destroyable {
|
||||
public abstract class BaseDeferredResource implements DeferredResource, Destroyable {
|
||||
|
||||
private final String resource;
|
||||
private volatile boolean loadFailed = false;
|
||||
@@ -27,7 +27,7 @@ public abstract class BaseLazyResource implements LazyResource, Destroyable {
|
||||
* @param resource resource path / name; this string is later used in
|
||||
* loadResource()
|
||||
*/
|
||||
public BaseLazyResource(String resource) {
|
||||
public BaseDeferredResource(String resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
@@ -125,8 +125,8 @@ public abstract class BaseLazyResource implements LazyResource, Destroyable {
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof BaseLazyResource)) return false;
|
||||
final BaseLazyResource other = (BaseLazyResource) obj;
|
||||
if (!(obj instanceof BaseDeferredResource)) return false;
|
||||
final BaseDeferredResource other = (BaseDeferredResource) obj;
|
||||
if (resource == null) {
|
||||
if (other.resource != null) return false;
|
||||
} else if (!resource.equals(other.resource)) return false;
|
||||
+1
-1
@@ -6,7 +6,7 @@ package mightypork.gamecore.resources;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface LazyResource {
|
||||
public interface DeferredResource {
|
||||
|
||||
/**
|
||||
* Load the actual resource, if not loaded yet.
|
||||
+1
-1
@@ -15,4 +15,4 @@ import java.lang.annotation.*;
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface TextureBasedResource {}
|
||||
public @interface MustLoadInRenderingContext {}
|
||||
@@ -1,12 +1,11 @@
|
||||
package mightypork.gamecore.resources;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.resources.audio.SoundRegistry;
|
||||
import mightypork.gamecore.resources.audio.players.EffectPlayer;
|
||||
import mightypork.gamecore.resources.audio.players.LoopPlayer;
|
||||
import mightypork.gamecore.resources.fonts.FontRegistry;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.gamecore.resources.textures.ITexture;
|
||||
import mightypork.gamecore.resources.textures.TextureRegistry;
|
||||
import mightypork.gamecore.resources.textures.TxQuad;
|
||||
@@ -32,14 +31,14 @@ public final class Res {
|
||||
*
|
||||
* @param app app access
|
||||
*/
|
||||
public static void init(AppAccess app)
|
||||
public static void init()
|
||||
{
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
textures = new TextureRegistry(app);
|
||||
sounds = new SoundRegistry(app);
|
||||
fonts = new FontRegistry(app);
|
||||
textures = new TextureRegistry();
|
||||
sounds = new SoundRegistry();
|
||||
fonts = new FontRegistry();
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +84,7 @@ public final class Res {
|
||||
}
|
||||
|
||||
|
||||
public static GLFont getFont(String key)
|
||||
public static IFont getFont(String key)
|
||||
{
|
||||
return fonts.getFont(key);
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@ import mightypork.utils.eventbus.events.flags.SingleReceiverEvent;
|
||||
@SingleReceiverEvent
|
||||
public class ResourceLoadRequest extends BusEvent<ResourceLoader> {
|
||||
|
||||
private final LazyResource resource;
|
||||
private final DeferredResource resource;
|
||||
|
||||
|
||||
/**
|
||||
* @param resource resource to load
|
||||
*/
|
||||
public ResourceLoadRequest(LazyResource resource) {
|
||||
public ResourceLoadRequest(DeferredResource resource) {
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.gamecore.resources;
|
||||
|
||||
|
||||
import mightypork.utils.eventbus.BusAccess;
|
||||
|
||||
|
||||
/**
|
||||
@@ -16,7 +15,7 @@ public interface ResourceLoader {
|
||||
*
|
||||
* @param resource
|
||||
*/
|
||||
void loadResource(LazyResource resource);
|
||||
void loadResource(DeferredResource resource);
|
||||
|
||||
|
||||
/**
|
||||
@@ -25,5 +24,5 @@ public interface ResourceLoader {
|
||||
* @param app app the loader works for. The event bus must already be
|
||||
* initialized.
|
||||
*/
|
||||
void init(BusAccess app);
|
||||
void init();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
import mightypork.gamecore.backend.BackendModule;
|
||||
import mightypork.gamecore.backend.lwjgl.SlickAudio;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.ResourceLoadRequest;
|
||||
import mightypork.gamecore.resources.audio.players.EffectPlayer;
|
||||
import mightypork.gamecore.resources.audio.players.LoopPlayer;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract audio backend module
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public abstract class AudioModule extends BackendModule implements Updateable {
|
||||
|
||||
/**
|
||||
* Set listener position
|
||||
*
|
||||
* @param pos listener position
|
||||
*/
|
||||
public abstract void setListenerPos(Vect pos);
|
||||
|
||||
|
||||
/**
|
||||
* Get current listener position
|
||||
*
|
||||
* @return listener position
|
||||
*/
|
||||
public abstract Vect getListenerPos();
|
||||
|
||||
// -- instance --
|
||||
|
||||
private final Volume masterVolume = new Volume(1D);
|
||||
private final Volume effectsVolume = new JointVolume(masterVolume);
|
||||
private final Volume loopsVolume = new JointVolume(masterVolume);
|
||||
|
||||
private final List<LoopPlayer> loopPlayers = new ArrayList<>();
|
||||
private final List<DeferredAudio> resources = new ArrayList<>();
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
for (final DeferredAudio r : resources) {
|
||||
r.destroy();
|
||||
}
|
||||
|
||||
deinitSoundSystem();
|
||||
}
|
||||
|
||||
|
||||
protected abstract void deinitSoundSystem();
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
for (final Updateable lp : loopPlayers) {
|
||||
lp.update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create effect resource
|
||||
*
|
||||
* @param resource resource path
|
||||
* @param pitch default pitch (1 = unchanged)
|
||||
* @param gain default gain (0-1)
|
||||
* @return player
|
||||
*/
|
||||
public EffectPlayer createEffect(String resource, double pitch, double gain)
|
||||
{
|
||||
return new EffectPlayer(createResource(resource), pitch, gain, effectsVolume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register loop resource (music / effect loop)
|
||||
*
|
||||
* @param resource resource path
|
||||
* @param pitch default pitch (1 = unchanged)
|
||||
* @param gain default gain (0-1)
|
||||
* @param fadeIn default time for fadeIn
|
||||
* @param fadeOut default time for fadeOut
|
||||
* @return player
|
||||
*/
|
||||
public LoopPlayer createLoop(String resource, double pitch, double gain, double fadeIn, double fadeOut)
|
||||
{
|
||||
final LoopPlayer p = new LoopPlayer(createResource(resource), pitch, gain, loopsVolume);
|
||||
p.setFadeTimes(fadeIn, fadeOut);
|
||||
loopPlayers.add(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create {@link DeferredAudio} for a resource
|
||||
*
|
||||
* @param res a resource name
|
||||
* @return the resource
|
||||
* @throws IllegalArgumentException if resource is already registered
|
||||
*/
|
||||
protected DeferredAudio createResource(String res)
|
||||
{
|
||||
final DeferredAudio a = doCreateResource(res);;
|
||||
App.bus().send(new ResourceLoadRequest(a));
|
||||
resources.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a backend-specific deferred audio resource instance.
|
||||
*
|
||||
* @param res resource path
|
||||
* @return Deferred Audio
|
||||
*/
|
||||
protected abstract DeferredAudio doCreateResource(String res);
|
||||
|
||||
|
||||
/**
|
||||
* Fade out all loops (ie. for screen transitions)
|
||||
*/
|
||||
public void fadeOutAllLoops()
|
||||
{
|
||||
for (final LoopPlayer p : loopPlayers) {
|
||||
p.fadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pause all loops (leave volume unchanged)
|
||||
*/
|
||||
public void pauseAllLoops()
|
||||
{
|
||||
for (final LoopPlayer p : loopPlayers) {
|
||||
p.pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of master volume
|
||||
*
|
||||
* @param d level
|
||||
*/
|
||||
public void setMasterVolume(double d)
|
||||
{
|
||||
masterVolume.set(d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of effects volume
|
||||
*
|
||||
* @param d level
|
||||
*/
|
||||
public void setEffectsVolume(double d)
|
||||
{
|
||||
effectsVolume.set(d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of music volume
|
||||
*
|
||||
* @param d level
|
||||
*/
|
||||
public void setMusicVolume(double d)
|
||||
{
|
||||
loopsVolume.set(d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of master volume
|
||||
*
|
||||
* @return level
|
||||
*/
|
||||
public double getMasterVolume()
|
||||
{
|
||||
return masterVolume.get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of effects volume
|
||||
*
|
||||
* @return level
|
||||
*/
|
||||
public double getEffectsVolume()
|
||||
{
|
||||
return effectsVolume.get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get level of music volume
|
||||
*
|
||||
* @return level
|
||||
*/
|
||||
public double getMusicVolume()
|
||||
{
|
||||
return loopsVolume.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.BaseDeferredResource;
|
||||
import mightypork.utils.annotations.Alias;
|
||||
|
||||
|
||||
/**
|
||||
* Base deferred audio
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@Alias(name = "Audio")
|
||||
public abstract class DeferredAudio extends BaseDeferredResource implements IAudio {
|
||||
|
||||
/**
|
||||
* Create deferred primitive audio player
|
||||
*
|
||||
* @param resourceName resource to load when needed
|
||||
*/
|
||||
public DeferredAudio(String resourceName) {
|
||||
super(resourceName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Audio resource interface (backend independent)
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface IAudio extends Destroyable {
|
||||
|
||||
/**
|
||||
* Pause loop (remember position and stop playing) - if was looping
|
||||
*/
|
||||
void pauseLoop();
|
||||
|
||||
|
||||
/**
|
||||
* Resume loop (if was paused)
|
||||
*/
|
||||
void resumeLoop();
|
||||
|
||||
|
||||
/**
|
||||
* Adjust gain for the currently playing effect (can be used for fading
|
||||
* music)
|
||||
*
|
||||
* @param gain gain to set 0..1
|
||||
*/
|
||||
void adjustGain(double gain);
|
||||
|
||||
|
||||
/**
|
||||
* Stop audio playback
|
||||
*/
|
||||
void stop();
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the audio is playing
|
||||
*/
|
||||
boolean isPlaying();
|
||||
|
||||
|
||||
/**
|
||||
* @return trie if the audio is paused
|
||||
*/
|
||||
boolean isPaused();
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at listener position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
*/
|
||||
void play(double pitch, double gain, boolean loop);
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at given X-Y position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
void play(double pitch, double gain, boolean loop, double x, double y);
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at given position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*/
|
||||
void play(double pitch, double gain, boolean loop, double x, double y, double z);
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at given position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @param pos coord
|
||||
*/
|
||||
void play(double pitch, double gain, boolean loop, Vect pos);
|
||||
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
package mightypork.gamecore.resources.audio;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import mightypork.gamecore.resources.BaseLazyResource;
|
||||
import mightypork.utils.annotations.Alias;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
import org.newdawn.slick.openal.Audio;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper class for slick audio
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@Alias(name = "Audio")
|
||||
public class LazyAudio extends BaseLazyResource {
|
||||
|
||||
private enum PlayMode
|
||||
{
|
||||
EFFECT, MUSIC;
|
||||
}
|
||||
|
||||
/** Audio resource */
|
||||
private Audio backingAudio = null;
|
||||
|
||||
// last play options
|
||||
private PlayMode mode = PlayMode.EFFECT;
|
||||
private double pauseLoopPosition = 0;
|
||||
private boolean looping = false;
|
||||
private boolean paused = false;
|
||||
private double lastPlayPitch = 1;
|
||||
private double lastPlayGain = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Create deferred primitive audio player
|
||||
*
|
||||
* @param resourceName resource to load when needed
|
||||
*/
|
||||
public LazyAudio(String resourceName) {
|
||||
super(resourceName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pause loop (remember position and stop playing) - if was looping
|
||||
*/
|
||||
public void pauseLoop()
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
if (isPlaying() && looping) {
|
||||
pauseLoopPosition = backingAudio.getPosition();
|
||||
stop();
|
||||
paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resume loop (if was paused)
|
||||
*
|
||||
* @return source ID
|
||||
*/
|
||||
public int resumeLoop()
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
int source = -1;
|
||||
if (looping && paused) {
|
||||
if (mode == PlayMode.MUSIC) {
|
||||
source = backingAudio.playAsMusic((float) lastPlayPitch, (float) lastPlayGain, true);
|
||||
} else {
|
||||
source = backingAudio.playAsSoundEffect((float) lastPlayPitch, (float) lastPlayGain, true);
|
||||
}
|
||||
backingAudio.setPosition((float) pauseLoopPosition);
|
||||
paused = false;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void loadResource(String resource) throws IOException
|
||||
{
|
||||
final String ext = FileUtils.getExtension(resource);
|
||||
|
||||
try (final InputStream stream = FileUtils.getResource(resource)) {
|
||||
|
||||
if (ext.equalsIgnoreCase("ogg")) {
|
||||
backingAudio = SoundStore.get().getOgg(resource, stream);
|
||||
|
||||
} else if (ext.equalsIgnoreCase("wav")) {
|
||||
backingAudio = SoundStore.get().getWAV(resource, stream);
|
||||
|
||||
} else if (ext.equalsIgnoreCase("aif")) {
|
||||
backingAudio = SoundStore.get().getAIF(resource, stream);
|
||||
|
||||
} else if (ext.equalsIgnoreCase("mod")) {
|
||||
backingAudio = SoundStore.get().getMOD(resource, stream);
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("Invalid audio file extension.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop playing
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
if (!isLoaded()) return;
|
||||
|
||||
backingAudio.stop();
|
||||
paused = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the audio is playing
|
||||
*/
|
||||
public boolean isPlaying()
|
||||
{
|
||||
if (!isLoaded()) return false;
|
||||
|
||||
return backingAudio.isPlaying();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return trie if the audio is paused
|
||||
*/
|
||||
public boolean isPaused()
|
||||
{
|
||||
if (!isLoaded()) return false;
|
||||
|
||||
return backingAudio.isPaused();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at listener position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @return source id
|
||||
*/
|
||||
public int playAsEffect(double pitch, double gain, boolean loop)
|
||||
{
|
||||
return playAsEffect(pitch, gain, loop, SoundSystem.getListener());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at given X-Y position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @param x
|
||||
* @param y
|
||||
* @return source id
|
||||
*/
|
||||
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y)
|
||||
{
|
||||
return playAsEffect(pitch, gain, loop, x, y, SoundSystem.getListener().z());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at given position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return source id
|
||||
*/
|
||||
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y, double z)
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
this.lastPlayPitch = pitch;
|
||||
this.lastPlayGain = gain;
|
||||
looping = loop;
|
||||
mode = PlayMode.EFFECT;
|
||||
return backingAudio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Play as sound effect at given position
|
||||
*
|
||||
* @param pitch pitch (1 = default)
|
||||
* @param gain gain (0-1)
|
||||
* @param loop looping
|
||||
* @param pos coord
|
||||
* @return source id
|
||||
*/
|
||||
public int playAsEffect(double pitch, double gain, boolean loop, Vect pos)
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
return playAsEffect(pitch, gain, loop, pos.x(), pos.y(), pos.z());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Play as music using source 0.<br>
|
||||
* Discouraged, since this does not allow cross-fading.
|
||||
*
|
||||
* @param pitch play pitch
|
||||
* @param gain play gain
|
||||
* @param loop looping
|
||||
* @return source
|
||||
*/
|
||||
public int playAsMusic(double pitch, double gain, boolean loop)
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
this.lastPlayPitch = (float) pitch;
|
||||
this.lastPlayGain = (float) gain;
|
||||
looping = loop;
|
||||
mode = PlayMode.MUSIC;
|
||||
return backingAudio.playAsMusic((float) pitch, (float) gain, loop);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
if (!isLoaded() || backingAudio == null) return;
|
||||
|
||||
backingAudio.release();
|
||||
backingAudio = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,8 +4,7 @@ package mightypork.gamecore.resources.audio;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppAccessAdapter;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.audio.players.EffectPlayer;
|
||||
import mightypork.gamecore.resources.audio.players.LoopPlayer;
|
||||
|
||||
@@ -15,21 +14,12 @@ import mightypork.gamecore.resources.audio.players.LoopPlayer;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class SoundRegistry extends AppAccessAdapter {
|
||||
public class SoundRegistry {
|
||||
|
||||
private final Map<String, EffectPlayer> effects = new HashMap<>();
|
||||
private final Map<String, LoopPlayer> loops = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public SoundRegistry(AppAccess app) {
|
||||
super(app);
|
||||
if (getSoundSystem() == null) throw new NullPointerException("SoundSystem cannot be null.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register effect resource
|
||||
*
|
||||
@@ -40,7 +30,7 @@ public class SoundRegistry extends AppAccessAdapter {
|
||||
*/
|
||||
public void addEffect(String key, String resource, double pitch, double gain)
|
||||
{
|
||||
effects.put(key, getSoundSystem().createEffect(resource, pitch, gain));
|
||||
effects.put(key, App.audio().createEffect(resource, pitch, gain));
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +46,7 @@ public class SoundRegistry extends AppAccessAdapter {
|
||||
*/
|
||||
public void addLoop(String key, String resource, double pitch, double gain, double fadeIn, double fadeOut)
|
||||
{
|
||||
loops.put(key, getSoundSystem().createLoop(resource, pitch, gain, fadeIn, fadeOut));
|
||||
loops.put(key, App.audio().createLoop(resource, pitch, gain, fadeIn, fadeOut));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,12 +5,14 @@ import java.nio.FloatBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.backend.lwjgl.SlickAudio;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.ResourceLoadRequest;
|
||||
import mightypork.gamecore.resources.audio.players.EffectPlayer;
|
||||
import mightypork.gamecore.resources.audio.players.LoopPlayer;
|
||||
import mightypork.gamecore.util.BufferHelper;
|
||||
import mightypork.utils.eventbus.clients.RootBusNode;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
@@ -26,7 +28,7 @@ import org.newdawn.slick.openal.SoundStore;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class SoundSystem extends RootBusNode implements Updateable {
|
||||
public class SoundSystem extends BusNode implements Updateable, Destroyable {
|
||||
|
||||
private static final Vect INITIAL_LISTENER_POS = Vect.ZERO;
|
||||
private static final int MAX_SOURCES = 256;
|
||||
@@ -72,14 +74,13 @@ public class SoundSystem extends RootBusNode implements Updateable {
|
||||
private final Volume loopsVolume = new JointVolume(masterVolume);
|
||||
|
||||
private final List<LoopPlayer> loopPlayers = new ArrayList<>();
|
||||
private final List<LazyAudio> resources = new ArrayList<>();
|
||||
private final List<DeferredAudio> resources = new ArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
* @param busAccess app access
|
||||
*/
|
||||
public SoundSystem(AppAccess app) {
|
||||
super(app);
|
||||
public SoundSystem() {
|
||||
|
||||
if (!soundSystemInited) {
|
||||
soundSystemInited = true;
|
||||
@@ -89,7 +90,7 @@ public class SoundSystem extends RootBusNode implements Updateable {
|
||||
SoundStore.get().init();
|
||||
setListener(INITIAL_LISTENER_POS);
|
||||
|
||||
getEventBus().send(new AudioReadyEvent());
|
||||
App.bus().send(new AudioReadyEvent());
|
||||
} catch (final Throwable t) {
|
||||
Log.e("Error initializing sound system.", t);
|
||||
}
|
||||
@@ -98,9 +99,9 @@ public class SoundSystem extends RootBusNode implements Updateable {
|
||||
|
||||
|
||||
@Override
|
||||
public void deinit()
|
||||
public void destroy()
|
||||
{
|
||||
for (final LazyAudio r : resources) {
|
||||
for (final DeferredAudio r : resources) {
|
||||
r.destroy();
|
||||
}
|
||||
|
||||
@@ -152,16 +153,16 @@ public class SoundSystem extends RootBusNode implements Updateable {
|
||||
|
||||
|
||||
/**
|
||||
* Create {@link LazyAudio} for a resource
|
||||
* Create {@link DeferredAudio} for a resource
|
||||
*
|
||||
* @param res a resource name
|
||||
* @return the resource
|
||||
* @throws IllegalArgumentException if resource is already registered
|
||||
*/
|
||||
private LazyAudio createResource(String res)
|
||||
private DeferredAudio createResource(String res)
|
||||
{
|
||||
final LazyAudio a = new LazyAudio(res);
|
||||
getEventBus().send(new ResourceLoadRequest(a));
|
||||
final DeferredAudio a = new SlickAudio(res);
|
||||
App.bus().send(new ResourceLoadRequest(a));
|
||||
resources.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.gamecore.resources.audio.players;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.audio.LazyAudio;
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.resources.audio.Volume;
|
||||
import mightypork.utils.interfaces.Destroyable;
|
||||
|
||||
@@ -14,7 +14,7 @@ import mightypork.utils.interfaces.Destroyable;
|
||||
public abstract class BaseAudioPlayer implements Destroyable {
|
||||
|
||||
/** the track */
|
||||
private final LazyAudio audio;
|
||||
private final DeferredAudio audio;
|
||||
|
||||
/** base gain for sfx */
|
||||
private final double baseGain;
|
||||
@@ -32,7 +32,7 @@ public abstract class BaseAudioPlayer implements Destroyable {
|
||||
* @param baseGain base gain (volume multiplier)
|
||||
* @param volume colume control
|
||||
*/
|
||||
public BaseAudioPlayer(LazyAudio track, double basePitch, double baseGain, Volume volume) {
|
||||
public BaseAudioPlayer(DeferredAudio track, double basePitch, double baseGain, Volume volume) {
|
||||
this.audio = track;
|
||||
|
||||
this.baseGain = baseGain;
|
||||
@@ -54,7 +54,7 @@ public abstract class BaseAudioPlayer implements Destroyable {
|
||||
/**
|
||||
* @return audio resource
|
||||
*/
|
||||
protected LazyAudio getAudio()
|
||||
protected DeferredAudio getAudio()
|
||||
{
|
||||
return audio;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public abstract class BaseAudioPlayer implements Destroyable {
|
||||
* @param multiplier extra volume adjustment
|
||||
* @return computed gain
|
||||
*/
|
||||
protected double getGain(double multiplier)
|
||||
protected double computeGain(double multiplier)
|
||||
{
|
||||
return baseGain * gainMultiplier.get() * multiplier;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public abstract class BaseAudioPlayer implements Destroyable {
|
||||
* @param multiplier pitch adjustment
|
||||
* @return computed pitch
|
||||
*/
|
||||
protected double getPitch(double multiplier)
|
||||
protected double computePitch(double multiplier)
|
||||
{
|
||||
return basePitch * multiplier;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.gamecore.resources.audio.players;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.audio.LazyAudio;
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.resources.audio.Volume;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class EffectPlayer extends BaseAudioPlayer {
|
||||
* @param baseGain base gain (volume multiplier)
|
||||
* @param volume volume control
|
||||
*/
|
||||
public EffectPlayer(LazyAudio track, double basePitch, double baseGain, Volume volume) {
|
||||
public EffectPlayer(DeferredAudio track, double basePitch, double baseGain, Volume volume) {
|
||||
super(track, (float) basePitch, (float) baseGain, volume);
|
||||
}
|
||||
|
||||
@@ -29,13 +29,12 @@ public class EffectPlayer extends BaseAudioPlayer {
|
||||
*
|
||||
* @param pitch play pitch
|
||||
* @param gain play gain
|
||||
* @return source id
|
||||
*/
|
||||
public int play(double pitch, double gain)
|
||||
public void play(double pitch, double gain)
|
||||
{
|
||||
if (!hasAudio()) return -1;
|
||||
if (!hasAudio()) return;
|
||||
|
||||
return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false);
|
||||
getAudio().play(computePitch(pitch), computeGain(gain), false);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,11 +42,10 @@ public class EffectPlayer extends BaseAudioPlayer {
|
||||
* Play at listener
|
||||
*
|
||||
* @param gain play gain
|
||||
* @return source id
|
||||
*/
|
||||
public int play(double gain)
|
||||
public void play(double gain)
|
||||
{
|
||||
return play(1, gain);
|
||||
play(1, gain);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,13 +55,12 @@ public class EffectPlayer extends BaseAudioPlayer {
|
||||
* @param pitch play pitch
|
||||
* @param gain play gain
|
||||
* @param pos play position
|
||||
* @return source id
|
||||
*/
|
||||
public int play(double pitch, double gain, Vect pos)
|
||||
public void play(double pitch, double gain, Vect pos)
|
||||
{
|
||||
if (!hasAudio()) return -1;
|
||||
if (!hasAudio()) return;
|
||||
|
||||
return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false, pos);
|
||||
getAudio().play(computePitch(pitch), computeGain(gain), false, pos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.gamecore.resources.audio.players;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.audio.LazyAudio;
|
||||
import mightypork.gamecore.resources.audio.DeferredAudio;
|
||||
import mightypork.gamecore.resources.audio.Volume;
|
||||
import mightypork.utils.interfaces.Pauseable;
|
||||
import mightypork.utils.interfaces.Updateable;
|
||||
@@ -40,7 +40,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
* @param baseGain base gain (volume multiplier)
|
||||
* @param volume volume control
|
||||
*/
|
||||
public LoopPlayer(LazyAudio track, double basePitch, double baseGain, Volume volume) {
|
||||
public LoopPlayer(DeferredAudio track, double basePitch, double baseGain, Volume volume) {
|
||||
super(track, (float) basePitch, (float) baseGain, volume);
|
||||
|
||||
paused = true;
|
||||
@@ -63,7 +63,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
private void initLoop()
|
||||
{
|
||||
if (hasAudio() && sourceID == -1) {
|
||||
sourceID = getAudio().playAsEffect(getPitch(1), getGain(1), true);
|
||||
getAudio().play(computePitch(1), computeGain(1), true);
|
||||
getAudio().pauseLoop();
|
||||
}
|
||||
}
|
||||
@@ -95,10 +95,9 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
|
||||
initLoop();
|
||||
|
||||
sourceID = getAudio().resumeLoop();
|
||||
paused = false;
|
||||
|
||||
adjustGain(getGain(fadeAnim.value()));
|
||||
getAudio().adjustGain(computeGain(fadeAnim.value()));
|
||||
}
|
||||
|
||||
|
||||
@@ -111,9 +110,9 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
|
||||
fadeAnim.update(delta);
|
||||
|
||||
final double gain = getGain(fadeAnim.value());
|
||||
final double gain = computeGain(fadeAnim.value());
|
||||
if (!paused && gain != lastUpdateGain) {
|
||||
adjustGain(gain);
|
||||
getAudio().adjustGain(gain);
|
||||
lastUpdateGain = gain;
|
||||
}
|
||||
|
||||
@@ -121,12 +120,6 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
}
|
||||
|
||||
|
||||
private void adjustGain(double gain)
|
||||
{
|
||||
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resume if paused, and fade in (pick up from current volume).
|
||||
*
|
||||
|
||||
@@ -3,10 +3,10 @@ package mightypork.gamecore.resources.fonts;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppAccessAdapter;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.resources.ResourceLoadRequest;
|
||||
import mightypork.gamecore.resources.fonts.impl.LazyFont;
|
||||
import mightypork.utils.eventbus.clients.BusNode;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
@@ -16,16 +16,9 @@ import org.newdawn.slick.opengl.Texture;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class FontRegistry extends AppAccessAdapter {
|
||||
public class FontRegistry extends BusNode {
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public FontRegistry(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
private final HashMap<String, GLFont> fonts = new HashMap<>();
|
||||
private final HashMap<String, IFont> fonts = new HashMap<>();
|
||||
private final HashMap<String, String> aliases = new HashMap<>();
|
||||
|
||||
|
||||
@@ -37,19 +30,19 @@ public class FontRegistry extends AppAccessAdapter {
|
||||
*/
|
||||
public void addFont(String key, LazyFont font)
|
||||
{
|
||||
getEventBus().send(new ResourceLoadRequest(font));
|
||||
App.bus().send(new ResourceLoadRequest(font));
|
||||
|
||||
fonts.put(key, font);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a {@link GLFont} to the bank.
|
||||
* Add a {@link IFont} to the bank.
|
||||
*
|
||||
* @param key font key
|
||||
* @param font font instance
|
||||
*/
|
||||
public void addFont(String key, GLFont font)
|
||||
public void addFont(String key, IFont font)
|
||||
{
|
||||
fonts.put(key, font);
|
||||
}
|
||||
@@ -73,9 +66,9 @@ public class FontRegistry extends AppAccessAdapter {
|
||||
* @param key texture key
|
||||
* @return the texture
|
||||
*/
|
||||
public GLFont getFont(String key)
|
||||
public IFont getFont(String key)
|
||||
{
|
||||
GLFont f = fonts.get(key);
|
||||
IFont f = fonts.get(key);
|
||||
|
||||
if (f == null) f = fonts.get(aliases.get(key));
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import mightypork.utils.math.constraints.vect.Vect;
|
||||
*/
|
||||
public class FontRenderer {
|
||||
|
||||
private GLFont font;
|
||||
private IFont font;
|
||||
|
||||
private Color color;
|
||||
|
||||
@@ -24,7 +24,7 @@ public class FontRenderer {
|
||||
/**
|
||||
* @param font used font
|
||||
*/
|
||||
public FontRenderer(GLFont font) {
|
||||
public FontRenderer(IFont font) {
|
||||
this(font, RGB.WHITE);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class FontRenderer {
|
||||
* @param font used font
|
||||
* @param color drawing color
|
||||
*/
|
||||
public FontRenderer(GLFont font, Color color) {
|
||||
public FontRenderer(IFont font, Color color) {
|
||||
this.font = font;
|
||||
this.color = color;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class FontRenderer {
|
||||
*
|
||||
* @param font font to use for drawing
|
||||
*/
|
||||
public void setFont(GLFont font)
|
||||
public void setFont(IFont font)
|
||||
{
|
||||
this.font = font;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package mightypork.gamecore.resources.fonts;
|
||||
|
||||
|
||||
/**
|
||||
* Glyph tables.
|
||||
* Glyph tables, can be used for font loading.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import mightypork.utils.math.constraints.vect.Vect;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface GLFont {
|
||||
public interface IFont {
|
||||
|
||||
/**
|
||||
* Draw without scaling at (0, 0) in given color.
|
||||
@@ -6,9 +6,9 @@ import java.awt.FontFormatException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import mightypork.gamecore.resources.BaseLazyResource;
|
||||
import mightypork.gamecore.resources.TextureBasedResource;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.BaseDeferredResource;
|
||||
import mightypork.gamecore.resources.MustLoadInRenderingContext;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.gamecore.resources.textures.FilterMode;
|
||||
import mightypork.utils.annotations.Alias;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
@@ -21,9 +21,9 @@ import mightypork.utils.math.constraints.vect.Vect;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@TextureBasedResource
|
||||
@MustLoadInRenderingContext
|
||||
@Alias(name = "Font")
|
||||
public class LazyFont extends BaseLazyResource implements GLFont {
|
||||
public class LazyFont extends BaseDeferredResource implements IFont {
|
||||
|
||||
public static enum FontStyle
|
||||
{
|
||||
@@ -37,7 +37,7 @@ public class LazyFont extends BaseLazyResource implements GLFont {
|
||||
}
|
||||
}
|
||||
|
||||
private GLFont font = null;
|
||||
private IFont font = null;
|
||||
private double size;
|
||||
private FontStyle style;
|
||||
private String chars;
|
||||
@@ -140,7 +140,7 @@ public class LazyFont extends BaseLazyResource implements GLFont {
|
||||
|
||||
return awtFont;
|
||||
} catch (final FontFormatException e) {
|
||||
throw new IOException("Could not load font, bad format.", e);
|
||||
throw new IOException("Could not load font, bad format.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,9 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.gamecore.resources.textures.FilterMode;
|
||||
import mightypork.utils.exceptions.IllegalValueException;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.color.Color;
|
||||
import mightypork.utils.math.constraints.vect.Vect;
|
||||
@@ -40,7 +41,7 @@ import org.newdawn.slick.opengl.GLUtils;
|
||||
* @author David Aaron Muhar (bobjob)
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class TextureBackedFont implements GLFont {
|
||||
public class TextureBackedFont implements IFont {
|
||||
|
||||
private class CharTile {
|
||||
|
||||
@@ -313,9 +314,21 @@ public class TextureBackedFont implements GLFont {
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
|
||||
final int filtering;
|
||||
switch (filter) {
|
||||
case NEAREST:
|
||||
filtering = GL_NEAREST;
|
||||
break;
|
||||
case LINEAR:
|
||||
filtering = GL_LINEAR;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalValueException("Unsupported filtering mode.");
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter.num);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter.num);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
|
||||
GLU.gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, width, height, format, GL_UNSIGNED_BYTE, byteBuffer);
|
||||
return textureId.get(0);
|
||||
@@ -385,9 +398,21 @@ public class TextureBackedFont implements GLFont {
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
|
||||
final int filtering;
|
||||
switch (filter) {
|
||||
case NEAREST:
|
||||
filtering = GL_NEAREST;
|
||||
break;
|
||||
case LINEAR:
|
||||
filtering = GL_LINEAR;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalValueException("Unsupported filtering mode.");
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter.num);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter.num);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering);
|
||||
|
||||
glColor4d(color.r(), color.g(), color.b(), color.a());
|
||||
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
package mightypork.gamecore.resources.textures;
|
||||
|
||||
|
||||
import mightypork.gamecore.resources.BaseLazyResource;
|
||||
import mightypork.gamecore.resources.TextureBasedResource;
|
||||
import mightypork.gamecore.resources.BaseDeferredResource;
|
||||
import mightypork.gamecore.resources.MustLoadInRenderingContext;
|
||||
import mightypork.utils.annotations.Alias;
|
||||
import mightypork.utils.math.constraints.rect.Rect;
|
||||
|
||||
@@ -13,8 +13,8 @@ import mightypork.utils.math.constraints.rect.Rect;
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@Alias(name = "Texture")
|
||||
@TextureBasedResource
|
||||
public abstract class LazyTexture extends BaseLazyResource implements ITexture {
|
||||
@MustLoadInRenderingContext
|
||||
public abstract class DeferredTexture extends BaseDeferredResource implements ITexture {
|
||||
|
||||
protected FilterMode filter = FilterMode.NEAREST;
|
||||
protected WrapMode wrap = WrapMode.CLAMP;
|
||||
@@ -23,7 +23,7 @@ public abstract class LazyTexture extends BaseLazyResource implements ITexture {
|
||||
/**
|
||||
* @param resourcePath resource path
|
||||
*/
|
||||
public LazyTexture(String resourcePath) {
|
||||
public DeferredTexture(String resourcePath) {
|
||||
super(resourcePath);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package mightypork.gamecore.resources.textures;
|
||||
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
|
||||
/**
|
||||
* Texture filtering mode
|
||||
*
|
||||
@@ -11,12 +8,5 @@ import org.lwjgl.opengl.GL11;
|
||||
*/
|
||||
public enum FilterMode
|
||||
{
|
||||
LINEAR(GL11.GL_LINEAR), NEAREST(GL11.GL_NEAREST);
|
||||
|
||||
public final int num;
|
||||
|
||||
|
||||
private FilterMode(int gl) {
|
||||
this.num = gl;
|
||||
}
|
||||
LINEAR, NEAREST;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import mightypork.utils.math.constraints.rect.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Texture with filter and wrap mode
|
||||
* Texture interface, backend independent
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
@@ -45,28 +45,6 @@ public interface ITexture extends Destroyable {
|
||||
QuadGrid grid(int x, int y);
|
||||
|
||||
|
||||
/**
|
||||
* @return OpenGL texture ID
|
||||
*/
|
||||
int getTextureID();
|
||||
|
||||
|
||||
/**
|
||||
* Get the height of the texture, 0..1.<br>
|
||||
*
|
||||
* @return height 0..1
|
||||
*/
|
||||
float getHeight01();
|
||||
|
||||
|
||||
/**
|
||||
* Get the width of the texture, 0..1.<br>
|
||||
*
|
||||
* @return width 0..1
|
||||
*/
|
||||
float getWidth01();
|
||||
|
||||
|
||||
/**
|
||||
* @return source image width (corresponding to width01)
|
||||
*/
|
||||
@@ -79,12 +57,6 @@ public interface ITexture extends Destroyable {
|
||||
int getImageHeight();
|
||||
|
||||
|
||||
/**
|
||||
* Bind to GL context, applying the filters prescribed.
|
||||
*/
|
||||
void bind();
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the image is RGBA
|
||||
*/
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppAccessAdapter;
|
||||
import mightypork.gamecore.resources.ResourceLoadRequest;
|
||||
import mightypork.utils.exceptions.KeyAlreadyExistsException;
|
||||
import mightypork.utils.math.constraints.rect.Rect;
|
||||
@@ -18,20 +16,12 @@ import mightypork.utils.math.constraints.rect.Rect;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class TextureRegistry extends AppAccessAdapter {
|
||||
public class TextureRegistry {
|
||||
|
||||
private final Map<String, ITexture> textures = new HashMap<>();
|
||||
private final Map<String, TxSheet> sheets = new HashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
* @param app app access
|
||||
*/
|
||||
public TextureRegistry(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load a texture from resource, without a key. This texture will not be
|
||||
* added to the bank.
|
||||
@@ -61,11 +51,11 @@ public class TextureRegistry extends AppAccessAdapter {
|
||||
{
|
||||
if (key != null) if (textures.containsKey(key)) throw new KeyAlreadyExistsException();
|
||||
|
||||
final LazyTexture texture = App.gfx().getLazyTexture(resourcePath);
|
||||
final DeferredTexture texture = App.gfx().getLazyTexture(resourcePath);
|
||||
texture.setFilter(filter);
|
||||
texture.setWrap(wrap);
|
||||
|
||||
getEventBus().send(new ResourceLoadRequest(texture));
|
||||
App.bus().send(new ResourceLoadRequest(texture));
|
||||
|
||||
if (key != null) {
|
||||
textures.put(key, texture);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package mightypork.gamecore.resources.textures;
|
||||
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
|
||||
/**
|
||||
* Texture wrap mode
|
||||
*
|
||||
@@ -11,12 +8,5 @@ import org.lwjgl.opengl.GL11;
|
||||
*/
|
||||
public enum WrapMode
|
||||
{
|
||||
CLAMP(GL11.GL_CLAMP), REPEAT(GL11.GL_REPEAT);
|
||||
|
||||
public final int num;
|
||||
|
||||
|
||||
private WrapMode(int gl) {
|
||||
this.num = gl;
|
||||
}
|
||||
CLAMP, REPEAT;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import mightypork.gamecore.backend.lwjgl.LwjglBackend;
|
||||
import mightypork.gamecore.core.config.Config;
|
||||
import mightypork.gamecore.core.events.MainLoopRequest;
|
||||
@@ -11,9 +9,9 @@ import mightypork.gamecore.core.events.UserQuitRequest;
|
||||
import mightypork.gamecore.core.modules.AppInitOptions;
|
||||
import mightypork.gamecore.core.modules.BaseApp;
|
||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.render.RenderModule;
|
||||
import mightypork.gamecore.render.GraphicsModule;
|
||||
import mightypork.gamecore.render.events.FullscreenToggleRequest;
|
||||
import mightypork.gamecore.render.events.ScreenshotRequest;
|
||||
import mightypork.gamecore.render.events.ScreenshotRequestListener;
|
||||
@@ -70,7 +68,7 @@ public final class RogueApp extends BaseApp implements ViewportChangeListener, S
|
||||
|
||||
|
||||
@Override
|
||||
protected void initDisplay(RenderModule gfx)
|
||||
protected void initDisplay(GraphicsModule gfx)
|
||||
{
|
||||
// init based on config
|
||||
final int w = Config.getValue("display.width");
|
||||
|
||||
@@ -10,41 +10,41 @@ public class RogueKeys implements KeySetup {
|
||||
@Override
|
||||
public void addKeys(KeyOpts keys)
|
||||
{
|
||||
keys.add("global.quit", "CTRL+Q", "Quit the game");
|
||||
keys.add("global.quit_force", "CTRL+SHIFT+Q", "Quit the game without asking, low-level");
|
||||
keys.addKey("global.quit", "CTRL+Q", "Quit the game");
|
||||
keys.addKey("global.quit_force", "CTRL+SHIFT+Q", "Quit the game without asking, low-level");
|
||||
|
||||
keys.add("global.screenshot", "F2", "Take screenshot (save into working directory)");
|
||||
keys.add("global.fullscreen", "F11", "Toggle fullscreen");
|
||||
keys.add("global.fps_meter", "F3", "Toggle FPS meter overlay");
|
||||
keys.addKey("global.screenshot", "F2", "Take screenshot (save into working directory)");
|
||||
keys.addKey("global.fullscreen", "F11", "Toggle fullscreen");
|
||||
keys.addKey("global.fps_meter", "F3", "Toggle FPS meter overlay");
|
||||
|
||||
keys.add("general.close", "ESC", "Leave a dialog or screen");
|
||||
keys.add("general.cancel", "ESC", "\"Cancel\" option in dialogs");
|
||||
keys.add("general.confirm", "ENTER", "\"Confirm\" option in dialogs");
|
||||
keys.add("general.yes", "Y", "\"Yes\" option in dialogs");
|
||||
keys.add("general.no", "N", "\"No\" option in dialogs");
|
||||
keys.addKey("general.close", "ESC", "Leave a dialog or screen");
|
||||
keys.addKey("general.cancel", "ESC", "\"Cancel\" option in dialogs");
|
||||
keys.addKey("general.confirm", "ENTER", "\"Confirm\" option in dialogs");
|
||||
keys.addKey("general.yes", "Y", "\"Yes\" option in dialogs");
|
||||
keys.addKey("general.no", "N", "\"No\" option in dialogs");
|
||||
|
||||
keys.add("game.quit", "ESC", "Quit to menu");
|
||||
keys.add("game.save", "CTRL+S", "Save to file");
|
||||
keys.add("game.load", "CTRL+L", "Load from file");
|
||||
keys.add("game.zoom", "Z", "Toggle zoom");
|
||||
keys.add("game.minimap", "M", "Toggle minimap");
|
||||
keys.add("game.eat", "E", "Eat smallest food item");
|
||||
keys.add("game.drop", "D", "Drop last picked item");
|
||||
keys.add("game.inventory", "I", "Toggle inventory view");
|
||||
keys.add("game.pause", "P", "Pause the game");
|
||||
keys.addKey("game.quit", "ESC", "Quit to menu");
|
||||
keys.addKey("game.save", "CTRL+S", "Save to file");
|
||||
keys.addKey("game.load", "CTRL+L", "Load from file");
|
||||
keys.addKey("game.zoom", "Z", "Toggle zoom");
|
||||
keys.addKey("game.minimap", "M", "Toggle minimap");
|
||||
keys.addKey("game.eat", "E", "Eat smallest food item");
|
||||
keys.addKey("game.drop", "D", "Drop last picked item");
|
||||
keys.addKey("game.inventory", "I", "Toggle inventory view");
|
||||
keys.addKey("game.pause", "P", "Pause the game");
|
||||
|
||||
keys.add("game.walk.up", "UP", "Walk north");
|
||||
keys.add("game.walk.down", "DOWN", "Walk south");
|
||||
keys.add("game.walk.left", "LEFT", "Walk west");
|
||||
keys.add("game.walk.right", "RIGHT", "Walk east");
|
||||
keys.addKey("game.walk.up", "UP", "Walk north");
|
||||
keys.addKey("game.walk.down", "DOWN", "Walk south");
|
||||
keys.addKey("game.walk.left", "LEFT", "Walk west");
|
||||
keys.addKey("game.walk.right", "RIGHT", "Walk east");
|
||||
|
||||
keys.add("game.cheat.xray", "CTRL+SHIFT+X", "Cheat to see unexplored tiles");
|
||||
keys.addKey("game.cheat.xray", "CTRL+SHIFT+X", "Cheat to see unexplored tiles");
|
||||
|
||||
keys.add("game.inv.use", "E", "Use (eat or equip) the selected item");
|
||||
keys.add("game.inv.drop", "D", "Drop the selected item");
|
||||
keys.add("game.inv.move.left", "LEFT", "Move inventory cursor left");
|
||||
keys.add("game.inv.move.right", "RIGHT", "Move inventory cursor right");
|
||||
keys.add("game.inv.move.up", "UP", "Move inventory cursor up");
|
||||
keys.add("game.inv.move.down", "DOWN", "Move inventory cursor down");
|
||||
keys.addKey("game.inv.use", "E", "Use (eat or equip) the selected item");
|
||||
keys.addKey("game.inv.drop", "D", "Drop the selected item");
|
||||
keys.addKey("game.inv.move.left", "LEFT", "Move inventory cursor left");
|
||||
keys.addKey("game.inv.move.right", "RIGHT", "Move inventory cursor right");
|
||||
keys.addKey("game.inv.move.up", "UP", "Move inventory cursor up");
|
||||
keys.addKey("game.inv.move.down", "DOWN", "Move inventory cursor down");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.core.modules.AppModule;
|
||||
import mightypork.gamecore.gui.screens.impl.CrossfadeRequest;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
@@ -3,14 +3,13 @@ package mightypork.rogue.screens;
|
||||
|
||||
import mightypork.gamecore.core.config.Config;
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.Action;
|
||||
import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.screens.Overlay;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.utils.math.color.pal.RGB;
|
||||
import mightypork.utils.math.constraints.num.Num;
|
||||
import mightypork.utils.math.constraints.rect.RectBound;
|
||||
@@ -43,7 +42,7 @@ public class FpsOverlay extends Overlay {
|
||||
}
|
||||
});
|
||||
|
||||
final GLFont font = Res.getFont("thin");
|
||||
final IFont font = Res.getFont("thin");
|
||||
|
||||
final Num h = root.height();
|
||||
final RectBound constraint = root.shrink(h.perc(3)).topRight().startRect().growDown(h.perc(5).max(16));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mightypork.rogue.screens;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
|
||||
@@ -3,7 +3,6 @@ package mightypork.rogue.screens;
|
||||
|
||||
import mightypork.gamecore.core.events.UserQuitRequest;
|
||||
import mightypork.gamecore.core.events.UserQuitRequestListener;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.screens.LayeredScreen;
|
||||
import mightypork.rogue.RogueStateManager.RogueState;
|
||||
import mightypork.rogue.events.RogueStateRequest;
|
||||
|
||||
@@ -2,7 +2,6 @@ package mightypork.rogue.screens.game;
|
||||
|
||||
|
||||
import mightypork.gamecore.core.modules.App;
|
||||
import mightypork.gamecore.core.modules.AppAccess;
|
||||
import mightypork.gamecore.gui.AlignX;
|
||||
import mightypork.gamecore.gui.components.LayoutComponent;
|
||||
import mightypork.gamecore.gui.components.layout.FlowColumnLayout;
|
||||
|
||||
@@ -12,9 +12,9 @@ import mightypork.gamecore.gui.components.layout.linear.LinearLayout;
|
||||
import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.screens.impl.FadingLayer;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.rogue.screens.game.ScreenGame.GScrState;
|
||||
import mightypork.rogue.world.WorldProvider;
|
||||
import mightypork.utils.logging.Log;
|
||||
@@ -53,7 +53,7 @@ public class LayerAskSave extends FadingLayer {
|
||||
qp.setRect(root);
|
||||
root.add(qp);
|
||||
|
||||
final GLFont thick_font = Res.getFont("thick");
|
||||
final IFont thick_font = Res.getFont("thick");
|
||||
|
||||
final RowLayout rl = new RowLayout(root, 2);
|
||||
rl.setRect(root.shrink(Num.ZERO, root.height().perc(40)).moveY(root.height().perc(-10)));
|
||||
|
||||
@@ -14,9 +14,9 @@ import mightypork.gamecore.gui.components.painters.ImagePainter;
|
||||
import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.screens.impl.FadingLayer;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.rogue.RogueStateManager.RogueState;
|
||||
import mightypork.rogue.events.RogueStateRequest;
|
||||
import mightypork.rogue.screens.game.ScreenGame.GScrState;
|
||||
@@ -36,7 +36,7 @@ public class LayerDeath extends FadingLayer {
|
||||
qp.setRect(root);
|
||||
root.add(qp);
|
||||
|
||||
final GLFont thick_font = Res.getFont("thick");
|
||||
final IFont thick_font = Res.getFont("thick");
|
||||
|
||||
final RowLayout rl = new RowLayout(root, 5);
|
||||
rl.setRect(root.shrink(Num.ZERO, root.height().perc(15)));
|
||||
|
||||
@@ -9,8 +9,8 @@ import mightypork.gamecore.gui.components.layout.GridLayout;
|
||||
import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.screens.impl.FadingLayer;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.rogue.screens.game.ScreenGame.GScrState;
|
||||
import mightypork.rogue.world.PlayerFacade;
|
||||
|
||||
@@ -13,9 +13,9 @@ import mightypork.gamecore.gui.components.painters.ImagePainter;
|
||||
import mightypork.gamecore.gui.components.painters.QuadPainter;
|
||||
import mightypork.gamecore.gui.components.painters.TextPainter;
|
||||
import mightypork.gamecore.gui.screens.impl.FadingLayer;
|
||||
import mightypork.gamecore.input.KeyStroke.Edge;
|
||||
import mightypork.gamecore.input.Edge;
|
||||
import mightypork.gamecore.resources.Res;
|
||||
import mightypork.gamecore.resources.fonts.GLFont;
|
||||
import mightypork.gamecore.resources.fonts.IFont;
|
||||
import mightypork.rogue.RogueStateManager.RogueState;
|
||||
import mightypork.rogue.events.RogueStateRequest;
|
||||
import mightypork.rogue.world.WorldProvider;
|
||||
@@ -33,7 +33,7 @@ public class LayerWin extends FadingLayer {
|
||||
qp.setRect(root);
|
||||
root.add(qp);
|
||||
|
||||
final GLFont thick_font = Res.getFont("thick");
|
||||
final IFont thick_font = Res.getFont("thick");
|
||||
|
||||
final RowLayout rl = new RowLayout(root, 5);
|
||||
rl.setRect(root.shrink(Num.ZERO, root.height().perc(15)));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user