EventBus now using thread; +Textures; +Audio; Cleaner structure
This commit is contained in:
+120
-116
@@ -4,22 +4,21 @@ package mightypork.rogue;
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.display.Screen;
|
||||
import mightypork.rogue.display.screens.screenBouncy.TestLayeredScreen;
|
||||
import mightypork.rogue.audio.SoundSystem;
|
||||
import mightypork.rogue.bus.events.*;
|
||||
import mightypork.rogue.gui.screens.ScreenRegistry;
|
||||
import mightypork.rogue.input.InputSystem;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.rogue.sounds.SoundSystem;
|
||||
import mightypork.rogue.tasks.TaskTakeScreenshot;
|
||||
import mightypork.rogue.textures.TextureRegistry;
|
||||
import mightypork.rogue.util.Utils;
|
||||
import mightypork.rogue.render.DisplaySystem;
|
||||
import mightypork.utils.control.bus.EventBus;
|
||||
import mightypork.utils.control.bus.events.DestroyEvent;
|
||||
import mightypork.utils.control.bus.events.UpdateEvent;
|
||||
import mightypork.utils.control.timing.TimerDelta;
|
||||
import mightypork.utils.control.interf.Destroyable;
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.logging.LogInstance;
|
||||
|
||||
@@ -38,22 +37,12 @@ public class App implements AppAccess {
|
||||
|
||||
// modules
|
||||
private InputSystem inputSystem;
|
||||
private SoundSystem soundSystem;
|
||||
private DisplaySystem displaySystem;
|
||||
private static SoundSystem soundSystem;
|
||||
private EventBus eventBus;
|
||||
private TextureRegistry textureRegistry;
|
||||
private MainLoop mainLoop;
|
||||
|
||||
/** current screen */
|
||||
private Screen screen;
|
||||
|
||||
/** Flag that screenshot is scheduled to be taken next loop */
|
||||
private boolean scheduledScreenshot = false;
|
||||
|
||||
/** Log instance; accessible as static via Log. */
|
||||
private LogInstance log;
|
||||
|
||||
/** timer */
|
||||
private TimerDelta timerRender;
|
||||
public ScreenRegistry screens;
|
||||
|
||||
|
||||
/**
|
||||
@@ -82,34 +71,9 @@ public class App implements AppAccess {
|
||||
private void start()
|
||||
{
|
||||
initialize();
|
||||
mainLoop();
|
||||
shutdown();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* App main loop
|
||||
*/
|
||||
private void mainLoop()
|
||||
{
|
||||
screen = new TestLayeredScreen(this);
|
||||
|
||||
screen.setActive(true);
|
||||
|
||||
timerRender = new TimerDelta();
|
||||
|
||||
while (!displaySystem.isCloseRequested()) {
|
||||
displaySystem.beginFrame();
|
||||
|
||||
eventBus.broadcast(new UpdateEvent(timerRender.getDelta()));
|
||||
|
||||
if (scheduledScreenshot) {
|
||||
takeScreenshot();
|
||||
scheduledScreenshot = false;
|
||||
}
|
||||
|
||||
displaySystem.endFrame();
|
||||
}
|
||||
Log.i("Starting main loop...");
|
||||
mainLoop.start();
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +84,7 @@ public class App implements AppAccess {
|
||||
*/
|
||||
public static void onCrash(Throwable error)
|
||||
{
|
||||
Log.e("The game has crashed.", error);
|
||||
Log.e("The game has crashed!", error);
|
||||
|
||||
if (inst != null) inst.shutdown();
|
||||
}
|
||||
@@ -129,7 +93,11 @@ public class App implements AppAccess {
|
||||
@Override
|
||||
public void shutdown()
|
||||
{
|
||||
bus().broadcast(new DestroyEvent());
|
||||
bus().send(new DestroyEvent());
|
||||
|
||||
bus().destroy();
|
||||
|
||||
Log.i("Shutting down...");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
@@ -137,34 +105,124 @@ public class App implements AppAccess {
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
Log.i("Initializing subsystems");
|
||||
|
||||
// lock working directory
|
||||
/*
|
||||
* Lock working directory
|
||||
*/
|
||||
initLock();
|
||||
|
||||
// setup logging
|
||||
log = Log.create("runtime", Paths.LOGS, 10);
|
||||
/*
|
||||
* Setup logging
|
||||
*/
|
||||
LogInstance log = Log.create("runtime", Paths.LOGS, 10);
|
||||
log.enable(Config.LOGGING_ENABLED);
|
||||
log.enableSysout(Config.LOG_TO_STDOUT);
|
||||
|
||||
// event bus
|
||||
Log.f1("Initializing subsystems...");
|
||||
|
||||
/*
|
||||
* Event bus
|
||||
*/
|
||||
Log.f2("Initializing Event Bus...");
|
||||
eventBus = new EventBus();
|
||||
eventBus.enableLogging(Config.LOG_BUS);
|
||||
initChannels();
|
||||
|
||||
// Subsystems
|
||||
textureRegistry = new TextureRegistry(this);
|
||||
|
||||
/*
|
||||
* Display
|
||||
*/
|
||||
Log.f2("Initializing Display System...");
|
||||
displaySystem = new DisplaySystem(this);
|
||||
displaySystem.createMainWindow(Const.WINDOW_W, Const.WINDOW_H, true, Config.START_IN_FS, Const.TITLEBAR);
|
||||
displaySystem.setTargetFps(Const.FPS_RENDER);
|
||||
|
||||
/*
|
||||
* Audio
|
||||
*/
|
||||
Log.f2("Initializing Sound System...");
|
||||
soundSystem = new SoundSystem(this);
|
||||
soundSystem.setMasterVolume(1);
|
||||
|
||||
/*
|
||||
* Input
|
||||
*/
|
||||
Log.f2("Initializing Input System...");
|
||||
inputSystem = new InputSystem(this);
|
||||
setupGlobalKeystrokes();
|
||||
|
||||
// load resources
|
||||
Resources.load(this);
|
||||
/*
|
||||
* Screen registry
|
||||
*/
|
||||
Log.f2("Initializing screen registry...");
|
||||
screens = new ScreenRegistry(this);
|
||||
|
||||
/*
|
||||
* Load resources
|
||||
*/
|
||||
Log.f1("Registering resources...");
|
||||
Res.load(this);
|
||||
|
||||
/*
|
||||
* Prepare main loop
|
||||
*/
|
||||
Log.f1("Preparing main loop...");
|
||||
ArrayList<Runnable> loopTasks = new ArrayList<Runnable>();
|
||||
loopTasks.add(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
screens.render();
|
||||
}
|
||||
});
|
||||
|
||||
mainLoop = new MainLoop(this, loopTasks);
|
||||
}
|
||||
|
||||
|
||||
private void initChannels()
|
||||
{
|
||||
Log.f3("Registering channels...");
|
||||
|
||||
bus().addChannel(DestroyEvent.class, Destroyable.class);
|
||||
bus().addChannel(UpdateEvent.class, Updateable.class);
|
||||
|
||||
bus().addChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
|
||||
bus().addChannel(KeyboardEvent.class, KeyboardEvent.Listener.class);
|
||||
bus().addChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class);
|
||||
bus().addChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class);
|
||||
bus().addChannel(ScreenRequestEvent.class, ScreenRequestEvent.Listener.class);
|
||||
bus().addChannel(ActionRequest.class, ActionRequest.Listener.class);
|
||||
}
|
||||
|
||||
|
||||
private void setupGlobalKeystrokes()
|
||||
{
|
||||
input().bindKeyStroke(new KeyStroke(Keyboard.KEY_F11), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
bus().queue(new ActionRequest(RequestType.FULLSCREEN));
|
||||
}
|
||||
});
|
||||
|
||||
input().bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
bus().queue(new ActionRequest(RequestType.SCREENSHOT));
|
||||
}
|
||||
});
|
||||
|
||||
input().bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
bus().queue(new ActionRequest(RequestType.SHUTDOWN));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +231,7 @@ public class App implements AppAccess {
|
||||
if (!Config.SINGLE_INSTANCE) return;
|
||||
|
||||
if (!lockInstance()) {
|
||||
System.out.println("Working directory is locked.\nOnly one instance can run at a time.");
|
||||
System.err.println("Working directory is locked.\nOnly one instance can run at a time.");
|
||||
|
||||
//@formatter:off
|
||||
JOptionPane.showMessageDialog(
|
||||
@@ -222,53 +280,6 @@ public class App implements AppAccess {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* initialize inputs
|
||||
*/
|
||||
private void setupGlobalKeystrokes()
|
||||
{
|
||||
inputSystem.bindKeyStroke(new KeyStroke(Keyboard.KEY_F2), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Log.f3("F2, taking screenshot.");
|
||||
scheduledScreenshot = true;
|
||||
}
|
||||
});
|
||||
|
||||
inputSystem.bindKeyStroke(new KeyStroke(false, Keyboard.KEY_F11), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Log.f3("F11, toggling fullscreen.");
|
||||
displaySystem.switchFullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
inputSystem.bindKeyStroke(new KeyStroke(Keyboard.KEY_LCONTROL, Keyboard.KEY_Q), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Log.f3("CTRL+Q, shutting down.");
|
||||
shutdown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do take a screenshot
|
||||
*/
|
||||
private void takeScreenshot()
|
||||
{
|
||||
soundSystem.getEffect("gui.shutter").play(1);
|
||||
Utils.runAsThread(new TaskTakeScreenshot(displaySystem));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return sound system of the running instance
|
||||
*/
|
||||
@@ -308,11 +319,4 @@ public class App implements AppAccess {
|
||||
return eventBus;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TextureRegistry tx()
|
||||
{
|
||||
return textureRegistry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.audio.SoundSystem;
|
||||
import mightypork.rogue.input.InputSystem;
|
||||
import mightypork.rogue.sounds.SoundSystem;
|
||||
import mightypork.rogue.textures.TextureRegistry;
|
||||
import mightypork.rogue.render.DisplaySystem;
|
||||
import mightypork.utils.control.bus.EventBus;
|
||||
|
||||
|
||||
@@ -39,12 +38,6 @@ public interface AppAccess {
|
||||
abstract EventBus bus();
|
||||
|
||||
|
||||
/**
|
||||
* @return texture registry
|
||||
*/
|
||||
abstract TextureRegistry tx();
|
||||
|
||||
|
||||
/**
|
||||
* Quit to OS<br>
|
||||
* Destroy app & exit VM
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.audio.SoundSystem;
|
||||
import mightypork.rogue.input.InputSystem;
|
||||
import mightypork.rogue.sounds.SoundSystem;
|
||||
import mightypork.rogue.textures.TextureRegistry;
|
||||
import mightypork.rogue.render.DisplaySystem;
|
||||
import mightypork.utils.control.bus.EventBus;
|
||||
|
||||
|
||||
@@ -59,11 +58,4 @@ public class AppAdapter implements AppAccess {
|
||||
app.shutdown();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TextureRegistry tx()
|
||||
{
|
||||
return app.tx();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -77,5 +77,6 @@ public class Config {
|
||||
public static boolean SINGLE_INSTANCE = true;
|
||||
|
||||
public static boolean LOG_FONTS = false;
|
||||
public static boolean LOG_BUS = false;
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,7 @@ public class Const {
|
||||
public static final String TITLEBAR = APP_NAME + " v." + VERSION;
|
||||
|
||||
// AUDIO
|
||||
public static final int FPS_RENDER = 200; // max
|
||||
public static final long FPS_GUI_UPDATE = 60;
|
||||
public static final int FPS_RENDER = 80; // max
|
||||
|
||||
// INITIAL WINDOW SIZE
|
||||
public static final int WINDOW_W = 1024;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
/**
|
||||
* Deferred resource
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface Deferred {
|
||||
|
||||
/**
|
||||
* Load the actual resource if not loaded yet
|
||||
*/
|
||||
public void load();
|
||||
|
||||
|
||||
/**
|
||||
* @return true if already loaded
|
||||
*/
|
||||
public boolean isLoaded();
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.events.ActionRequest;
|
||||
import mightypork.rogue.bus.events.RequestType;
|
||||
import mightypork.rogue.bus.events.ScreenRequestEvent;
|
||||
import mightypork.rogue.tasks.TaskTakeScreenshot;
|
||||
import mightypork.rogue.util.Utils;
|
||||
import mightypork.utils.control.bus.events.UpdateEvent;
|
||||
import mightypork.utils.control.timing.TimerDelta;
|
||||
|
||||
|
||||
public class MainLoop extends Subsystem implements ActionRequest.Listener {
|
||||
|
||||
private Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<Runnable>();
|
||||
private List<Runnable> regularTasks;
|
||||
|
||||
|
||||
public MainLoop(App app, ArrayList<Runnable> loopTasks) {
|
||||
super(app);
|
||||
|
||||
this.regularTasks = loopTasks;
|
||||
}
|
||||
|
||||
/** timer */
|
||||
private TimerDelta timer;
|
||||
private boolean running = true;
|
||||
|
||||
|
||||
public void start()
|
||||
{
|
||||
bus().queue(new ScreenRequestEvent("test.texture"));
|
||||
|
||||
timer = new TimerDelta();
|
||||
|
||||
while (running) {
|
||||
disp().beginFrame();
|
||||
|
||||
bus().send(new UpdateEvent(timer.getDelta()));
|
||||
|
||||
for (Runnable r : regularTasks) {
|
||||
r.run();
|
||||
}
|
||||
|
||||
Runnable r;
|
||||
while ((r = taskQueue.poll()) != null) {
|
||||
r.run();
|
||||
}
|
||||
|
||||
disp().endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinit()
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void requestAction(RequestType request)
|
||||
{
|
||||
switch (request) {
|
||||
case FULLSCREEN:
|
||||
taskQueue.add(taskFullscreen);
|
||||
break;
|
||||
|
||||
case SCREENSHOT:
|
||||
taskQueue.add(taskScreenshot);
|
||||
break;
|
||||
|
||||
case SHUTDOWN:
|
||||
taskQueue.add(taskShutdown);
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable taskScreenshot = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Res.getEffect("gui.shutter").play(1);
|
||||
Utils.runAsThread(new TaskTakeScreenshot(disp()));
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable taskShutdown = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable taskFullscreen = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
disp().switchFullscreen();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import mightypork.rogue.audio.EffectPlayer;
|
||||
import mightypork.rogue.audio.LoopPlayer;
|
||||
import mightypork.rogue.audio.SoundBank;
|
||||
import mightypork.rogue.gui.screens.screenBouncy.ScreenTestAnim;
|
||||
import mightypork.rogue.gui.screens.screenTextures.ScreenTextureTest;
|
||||
import mightypork.rogue.render.textures.TextureBank;
|
||||
import mightypork.rogue.render.textures.TxQuad;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
public class Res {
|
||||
|
||||
private static TextureBank textures;
|
||||
private static SoundBank sounds;
|
||||
private static boolean initialized = false;
|
||||
|
||||
|
||||
public static void load(App app)
|
||||
{
|
||||
if (initialized) return;
|
||||
initialized = true;
|
||||
|
||||
textures = new TextureBank(app);
|
||||
sounds = new SoundBank(app);
|
||||
|
||||
loadSounds(app);
|
||||
loadTextures(app);
|
||||
loadFonts(app);
|
||||
loadScreens(app);
|
||||
}
|
||||
|
||||
|
||||
private static void loadFonts(App app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void loadTextures(App app)
|
||||
{
|
||||
textures.loadTexture("test.kitten", "/res/img/kitten.png");
|
||||
}
|
||||
|
||||
|
||||
private static void loadSounds(App app)
|
||||
{
|
||||
sounds.addEffect("gui.shutter", "/res/audio/shutter.ogg", 1, 1);
|
||||
|
||||
sounds.addLoop("test.wilderness", "/res/audio/wilderness.ogg", 1, 1, 3, 3);
|
||||
}
|
||||
|
||||
|
||||
private static void loadScreens(App app)
|
||||
{
|
||||
app.screens.add("test.anim", new ScreenTestAnim(app));
|
||||
app.screens.add("test.texture", new ScreenTextureTest(app));
|
||||
}
|
||||
|
||||
|
||||
public static TxQuad getTxQuad(String key)
|
||||
{
|
||||
return textures.getTxQuad(key);
|
||||
}
|
||||
|
||||
|
||||
public static Texture getTexture(String key)
|
||||
{
|
||||
return textures.getTexture(key);
|
||||
}
|
||||
|
||||
|
||||
public static LoopPlayer getLoop(String key)
|
||||
{
|
||||
return sounds.getLoop(key);
|
||||
}
|
||||
|
||||
|
||||
public static EffectPlayer getEffect(String key)
|
||||
{
|
||||
return sounds.getEffect(key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
public class Resources {
|
||||
|
||||
public static void load(AppAccess app)
|
||||
{
|
||||
|
||||
loadSounds(app);
|
||||
|
||||
loadTextures(app);
|
||||
|
||||
loadFonts(app);
|
||||
}
|
||||
|
||||
|
||||
private static void loadFonts(AppAccess app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void loadTextures(AppAccess app)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static void loadSounds(AppAccess app)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.sounds;
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import mightypork.utils.objects.Mutable;
|
||||
@@ -7,7 +7,7 @@ import mightypork.utils.objects.Mutable;
|
||||
public abstract class BaseAudioPlayer {
|
||||
|
||||
/** the track */
|
||||
private AudioX audio;
|
||||
private DeferredAudio audio;
|
||||
|
||||
/** base gain for sfx */
|
||||
private double baseGain = 1;
|
||||
@@ -19,12 +19,12 @@ public abstract class BaseAudioPlayer {
|
||||
private Mutable<Double> gainMultiplier = null;
|
||||
|
||||
|
||||
public BaseAudioPlayer(AudioX track, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
public BaseAudioPlayer(DeferredAudio track, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
this(track, 1, baseGain, gainMultiplier);
|
||||
}
|
||||
|
||||
|
||||
public BaseAudioPlayer(AudioX track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
public BaseAudioPlayer(DeferredAudio track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
this.audio = track;
|
||||
|
||||
this.baseGain = baseGain;
|
||||
@@ -43,7 +43,7 @@ public abstract class BaseAudioPlayer {
|
||||
}
|
||||
|
||||
|
||||
protected AudioX getAudio()
|
||||
protected DeferredAudio getAudio()
|
||||
{
|
||||
return audio;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public abstract class BaseAudioPlayer {
|
||||
*
|
||||
* @return is valid
|
||||
*/
|
||||
protected boolean canPlay()
|
||||
protected boolean hasAudio()
|
||||
{
|
||||
return (audio != null);
|
||||
}
|
||||
@@ -74,6 +74,6 @@ public abstract class BaseAudioPlayer {
|
||||
|
||||
public void load()
|
||||
{
|
||||
if (canPlay()) audio.load();
|
||||
if (hasAudio()) audio.load();
|
||||
}
|
||||
}
|
||||
+27
-16
@@ -1,6 +1,7 @@
|
||||
package mightypork.rogue.sounds;
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import mightypork.rogue.Deferred;
|
||||
import mightypork.utils.control.interf.Destroyable;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.logging.Log;
|
||||
@@ -15,7 +16,7 @@ import org.newdawn.slick.openal.SoundStore;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class AudioX implements Destroyable {
|
||||
public class DeferredAudio implements Destroyable, Deferred {
|
||||
|
||||
private enum PlayMode
|
||||
{
|
||||
@@ -39,7 +40,7 @@ public class AudioX implements Destroyable {
|
||||
*
|
||||
* @param resourceName resource to load when needed
|
||||
*/
|
||||
public AudioX(String resourceName) {
|
||||
public DeferredAudio(String resourceName) {
|
||||
this.audio = null;
|
||||
this.resourcePath = resourceName;
|
||||
}
|
||||
@@ -50,7 +51,7 @@ public class AudioX implements Destroyable {
|
||||
*/
|
||||
public void pauseLoop()
|
||||
{
|
||||
if (!load()) return;
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
if (isPlaying() && looping) {
|
||||
pauseLoopPosition = audio.getPosition();
|
||||
@@ -67,7 +68,7 @@ public class AudioX implements Destroyable {
|
||||
*/
|
||||
public int resumeLoop()
|
||||
{
|
||||
if (!load()) return -1;
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
int source = -1;
|
||||
if (looping && paused) {
|
||||
@@ -88,24 +89,32 @@ public class AudioX implements Destroyable {
|
||||
*
|
||||
* @return resource is loaded
|
||||
*/
|
||||
private boolean isLoaded()
|
||||
@Override
|
||||
public boolean isLoaded()
|
||||
{
|
||||
return audio != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
ensureLoaded();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to load if not loaded already
|
||||
*
|
||||
* @return is loaded
|
||||
*/
|
||||
public boolean load()
|
||||
protected boolean ensureLoaded()
|
||||
{
|
||||
if (isLoaded()) return true; // already loaded
|
||||
if (loadFailed || resourcePath == null) return false; // not loaded, but
|
||||
// can't load
|
||||
// anyway
|
||||
|
||||
if (loadFailed || resourcePath == null) return false;
|
||||
|
||||
Log.f3("Trying to load: " + resourcePath);
|
||||
|
||||
loadFailed = false;
|
||||
try {
|
||||
String ext = FileUtils.getExtension(resourcePath);
|
||||
@@ -124,6 +133,8 @@ public class AudioX implements Destroyable {
|
||||
loadFailed = true; // don't try next time
|
||||
}
|
||||
|
||||
if (!loadFailed) Log.f3("Audio loaded: " + resourcePath);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("Could not load " + resourcePath, e);
|
||||
loadFailed = true; // don't try next time
|
||||
@@ -201,7 +212,7 @@ public class AudioX implements Destroyable {
|
||||
*/
|
||||
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y, double z)
|
||||
{
|
||||
if (!load()) return -1;
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
this.lastPlayPitch = pitch;
|
||||
this.lastPlayGain = gain;
|
||||
@@ -222,7 +233,7 @@ public class AudioX implements Destroyable {
|
||||
*/
|
||||
public int playAsEffect(double pitch, double gain, boolean loop, Coord pos)
|
||||
{
|
||||
if (!load()) return -1;
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
return playAsEffect(pitch, gain, loop, pos.x, pos.y, pos.z);
|
||||
}
|
||||
@@ -239,7 +250,7 @@ public class AudioX implements Destroyable {
|
||||
*/
|
||||
public int playAsMusic(double pitch, double gain, boolean loop)
|
||||
{
|
||||
if (!load()) return -1;
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
this.lastPlayPitch = (float) pitch;
|
||||
this.lastPlayGain = (float) gain;
|
||||
@@ -274,8 +285,8 @@ public class AudioX implements Destroyable {
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof AudioX)) return false;
|
||||
AudioX other = (AudioX) obj;
|
||||
if (!(obj instanceof DeferredAudio)) return false;
|
||||
DeferredAudio other = (DeferredAudio) obj;
|
||||
if (resourcePath == null) {
|
||||
if (other.resourcePath != null) return false;
|
||||
} else if (!resourcePath.equals(other.resourcePath)) {
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.sounds;
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
@@ -7,14 +7,14 @@ import mightypork.utils.objects.Mutable;
|
||||
|
||||
public class EffectPlayer extends BaseAudioPlayer {
|
||||
|
||||
public EffectPlayer(AudioX track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
public EffectPlayer(DeferredAudio track, double basePitch, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
super(track, (float) basePitch, (float) baseGain, gainMultiplier);
|
||||
}
|
||||
|
||||
|
||||
public int play(double pitch, double gain)
|
||||
{
|
||||
if (!canPlay()) return -1;
|
||||
if (!hasAudio()) return -1;
|
||||
|
||||
return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class EffectPlayer extends BaseAudioPlayer {
|
||||
|
||||
public int play(double pitch, double gain, Coord pos)
|
||||
{
|
||||
if (!canPlay()) return -1;
|
||||
if (!hasAudio()) return -1;
|
||||
|
||||
return getAudio().playAsEffect(getPitch(pitch), getGain(gain), false, pos);
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.sounds;
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import mightypork.utils.math.Calc;
|
||||
+9
-9
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.sounds;
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
@@ -28,7 +28,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
private double outTime = 1;
|
||||
|
||||
|
||||
public LoopPlayer(AudioX track, double pitch, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
public LoopPlayer(DeferredAudio track, double pitch, double baseGain, Mutable<Double> gainMultiplier) {
|
||||
super(track, (float) pitch, (float) baseGain, gainMultiplier);
|
||||
|
||||
paused = true;
|
||||
@@ -44,7 +44,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
|
||||
private void initLoop()
|
||||
{
|
||||
if (!canPlay() && sourceID == -1) {
|
||||
if (hasAudio() && sourceID == -1) {
|
||||
sourceID = getAudio().playAsEffect(getPitch(1), getGain(1), true);
|
||||
getAudio().pauseLoop();
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
@Override
|
||||
public void pause()
|
||||
{
|
||||
if (!canPlay() || paused) return;
|
||||
if (!hasAudio() || paused) return;
|
||||
|
||||
initLoop();
|
||||
|
||||
@@ -73,7 +73,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
@Override
|
||||
public void resume()
|
||||
{
|
||||
if (!canPlay() || paused) return;
|
||||
if (!hasAudio() || !paused) return;
|
||||
|
||||
initLoop();
|
||||
|
||||
@@ -85,13 +85,13 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
if (!canPlay() || paused) return;
|
||||
if (!hasAudio() || paused) return;
|
||||
|
||||
initLoop();
|
||||
|
||||
fadeAnim.update(delta);
|
||||
|
||||
double gain = getGain(fadeAnim.getCurrentValue());
|
||||
double gain = getGain(fadeAnim.now());
|
||||
if (!paused && gain != lastUpdateGain) {
|
||||
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
|
||||
lastUpdateGain = gain;
|
||||
@@ -103,7 +103,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
|
||||
public void fadeIn(double secs)
|
||||
{
|
||||
if (!canPlay()) return;
|
||||
if (!hasAudio()) return;
|
||||
|
||||
resume();
|
||||
fadeAnim.fadeIn(secs);
|
||||
@@ -112,7 +112,7 @@ public class LoopPlayer extends BaseAudioPlayer implements Updateable, Pauseable
|
||||
|
||||
public void fadeOut(double secs)
|
||||
{
|
||||
if (!canPlay()) return;
|
||||
if (!hasAudio()) return;
|
||||
|
||||
fadeAnim.fadeOut(secs);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
public class NullAudio extends DeferredAudio {
|
||||
|
||||
public NullAudio() {
|
||||
super("");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isLoaded()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean ensureLoaded()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.AppAdapter;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
public class SoundBank extends AppAdapter {
|
||||
|
||||
private static final DeferredAudio NO_SOUND = new NullAudio();
|
||||
private static final LoopPlayer NULL_LOOP = new LoopPlayer(NO_SOUND, 0, 0, null);
|
||||
private static final EffectPlayer NULL_EFFECT = new EffectPlayer(NO_SOUND, 0, 0, null);
|
||||
|
||||
private Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>();
|
||||
private Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>();
|
||||
|
||||
|
||||
public SoundBank(AppAccess app) {
|
||||
super(app);
|
||||
if (snd() == null) throw new NullPointerException("SoundSystem cannot be null.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register effect resource
|
||||
*
|
||||
* @param key sound key
|
||||
* @param resource resource path
|
||||
* @param pitch default pitch (1 = unchanged)
|
||||
* @param gain default gain (0-1)
|
||||
*/
|
||||
public void addEffect(String key, String resource, double pitch, double gain)
|
||||
{
|
||||
effects.put(key, snd().createEffect(resource, pitch, gain));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register loop resource (music / effect loop)
|
||||
*
|
||||
* @param key sound key
|
||||
* @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
|
||||
*/
|
||||
public void addLoop(String key, String resource, double pitch, double gain, double fadeIn, double fadeOut)
|
||||
{
|
||||
loops.put(key, snd().createLoop(resource, pitch, gain, fadeIn, fadeOut));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a loop player for key
|
||||
*
|
||||
* @param key sound key
|
||||
* @return loop player
|
||||
*/
|
||||
public LoopPlayer getLoop(String key)
|
||||
{
|
||||
LoopPlayer p = loops.get(key);
|
||||
if (p == null) {
|
||||
Log.w("Requesting unknown sound loop \"" + key + "\".");
|
||||
return NULL_LOOP;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a effect player for key
|
||||
*
|
||||
* @param key sound key
|
||||
* @return effect player
|
||||
*/
|
||||
public EffectPlayer getEffect(String key)
|
||||
{
|
||||
EffectPlayer p = effects.get(key);
|
||||
if (p == null) {
|
||||
Log.w("Requesting unknown sound effect \"" + key + "\".");
|
||||
return NULL_EFFECT;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
+24
-133
@@ -1,16 +1,13 @@
|
||||
package mightypork.rogue.sounds;
|
||||
package mightypork.rogue.audio;
|
||||
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.Calc.Buffers;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.objects.Mutable;
|
||||
@@ -30,9 +27,6 @@ public class SoundSystem extends Subsystem implements Updateable {
|
||||
|
||||
private static final Coord INITIAL_LISTENER_POS = new Coord(0, 0, 0);
|
||||
private static final int MAX_SOURCES = 256;
|
||||
private static final AudioX NO_SOUND = new NullAudio();
|
||||
private static final LoopPlayer NULL_LOOP = new LoopPlayer(NO_SOUND, 0, 0, null);
|
||||
private static final EffectPlayer NULL_EFFECT = new EffectPlayer(NO_SOUND, 0, 0, null);
|
||||
|
||||
private static Coord listener = new Coord();
|
||||
|
||||
@@ -67,15 +61,20 @@ public class SoundSystem extends Subsystem implements Updateable {
|
||||
buf3 = buf6 = null;
|
||||
}
|
||||
|
||||
|
||||
public static Coord getListener()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
// -- instance --
|
||||
|
||||
public Mutable<Double> masterVolume = new Mutable<Double>(1D);
|
||||
public Mutable<Double> effectsVolume = new JointVolume(masterVolume);
|
||||
public Mutable<Double> loopsVolume = new JointVolume(masterVolume);
|
||||
|
||||
private Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>();
|
||||
private Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>();
|
||||
private Set<AudioX> resources = new HashSet<AudioX>();
|
||||
private Set<LoopPlayer> loopPlayers = new HashSet<LoopPlayer>();
|
||||
private Set<DeferredAudio> resources = new HashSet<DeferredAudio>();
|
||||
|
||||
|
||||
public SoundSystem(AppAccess app) {
|
||||
@@ -86,7 +85,7 @@ public class SoundSystem extends Subsystem implements Updateable {
|
||||
@Override
|
||||
public final void deinit()
|
||||
{
|
||||
for (AudioX r : resources) {
|
||||
for (DeferredAudio r : resources) {
|
||||
r.destroy();
|
||||
}
|
||||
|
||||
@@ -98,191 +97,83 @@ public class SoundSystem extends Subsystem implements Updateable {
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
for (LoopPlayer lp : loops.values()) {
|
||||
for (Updateable lp : loopPlayers) {
|
||||
lp.update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Coord getListener()
|
||||
{
|
||||
return listener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register effect resource
|
||||
* Create effect resource
|
||||
*
|
||||
* @param key sound key
|
||||
* @param resource resource path
|
||||
* @param pitch default pitch (1 = unchanged)
|
||||
* @param gain default gain (0-1)
|
||||
* @return player
|
||||
*/
|
||||
public void addEffect(String key, String resource, double pitch, double gain)
|
||||
public EffectPlayer createEffect(String resource, double pitch, double gain)
|
||||
{
|
||||
EffectPlayer p = new EffectPlayer(getResource(resource), pitch, gain, effectsVolume);
|
||||
effects.put(key, p);
|
||||
return new EffectPlayer(getResource(resource), pitch, gain, effectsVolume);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register loop resource (music / effect loop)
|
||||
*
|
||||
* @param key sound key
|
||||
* @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 void addLoop(String key, String resource, double pitch, double gain, double fadeIn, double fadeOut)
|
||||
public LoopPlayer createLoop(String resource, double pitch, double gain, double fadeIn, double fadeOut)
|
||||
{
|
||||
LoopPlayer p = new LoopPlayer(getResource(resource), pitch, gain, loopsVolume);
|
||||
p.setFadeTimes(fadeIn, fadeOut);
|
||||
loops.put(key, p);
|
||||
loopPlayers.add(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create {@link AudioX} 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 AudioX getResource(String res)
|
||||
private DeferredAudio getResource(String res)
|
||||
{
|
||||
AudioX a = new AudioX(res);
|
||||
DeferredAudio a = new DeferredAudio(res);
|
||||
if (resources.contains(a)) throw new IllegalArgumentException("Sound resource " + res + " is already registered.");
|
||||
resources.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a loop player for key
|
||||
*
|
||||
* @param key sound key
|
||||
* @return loop player
|
||||
*/
|
||||
public LoopPlayer getLoop(String key)
|
||||
{
|
||||
LoopPlayer p = loops.get(key);
|
||||
if (p == null) {
|
||||
Log.w("Requesting unknown sound loop \"" + key + "\".");
|
||||
return NULL_LOOP;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a effect player for key
|
||||
*
|
||||
* @param key sound key
|
||||
* @return effect player
|
||||
*/
|
||||
public EffectPlayer getEffect(String key)
|
||||
{
|
||||
EffectPlayer p = effects.get(key);
|
||||
if (p == null) {
|
||||
Log.w("Requesting unknown sound effect \"" + key + "\".");
|
||||
return NULL_EFFECT;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade out all loops (ie. for screen transitions)
|
||||
*/
|
||||
public void fadeOutAllLoops()
|
||||
{
|
||||
for (LoopPlayer p : loops.values()) {
|
||||
for (LoopPlayer p : loopPlayers) {
|
||||
p.fadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade in a loop (with default time)
|
||||
*
|
||||
* @param key sound key
|
||||
*/
|
||||
public void fadeInLoop(String key)
|
||||
{
|
||||
getLoop(key).fadeIn();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade in a loop
|
||||
*
|
||||
* @param key sound key
|
||||
* @param seconds fade-in duration
|
||||
*/
|
||||
public void fadeInLoop(String key, double seconds)
|
||||
{
|
||||
getLoop(key).fadeIn(seconds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade out a loop (with default time)
|
||||
*
|
||||
* @param key sound key
|
||||
*/
|
||||
public void fadeOutLoop(String key)
|
||||
{
|
||||
getLoop(key).fadeOut();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade out a loop
|
||||
*
|
||||
* @param key sound key
|
||||
* @param seconds fade-out duration
|
||||
*/
|
||||
public void fadeOutLoop(String key, double seconds)
|
||||
{
|
||||
getLoop(key).fadeOut(seconds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pause a loop
|
||||
*
|
||||
* @param key sound key
|
||||
*/
|
||||
public void pauseLoop(String key)
|
||||
{
|
||||
getLoop(key).pause();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pause all loops (leave volume unchanged)
|
||||
*/
|
||||
public void pauseAllLoops()
|
||||
{
|
||||
for (LoopPlayer p : loops.values()) {
|
||||
for (LoopPlayer p : loopPlayers) {
|
||||
p.pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resume a loop
|
||||
*
|
||||
* @param key sound key
|
||||
*/
|
||||
public void resumeLoop(String key)
|
||||
{
|
||||
getLoop(key).resume();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set level of master volume
|
||||
*
|
||||
@@ -10,6 +10,7 @@ import mightypork.rogue.AppAdapter;
|
||||
import mightypork.utils.control.bus.EventBus;
|
||||
import mightypork.utils.control.bus.clients.DelegatingClient;
|
||||
import mightypork.utils.control.bus.clients.ToggleableClient;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
@@ -57,8 +58,10 @@ public class ChildClient extends AppAdapter implements DelegatingClient, Togglea
|
||||
*/
|
||||
public final void addChildClient(Object client)
|
||||
{
|
||||
if (client != null) {
|
||||
if (bus().isClientValid(client)) {
|
||||
clients.add(client);
|
||||
} else {
|
||||
Log.w("Client rejected by bus: " + client.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Event;
|
||||
|
||||
|
||||
/**
|
||||
* Request for action that should be performed in the main thread.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class ActionRequest implements Event<ActionRequest.Listener> {
|
||||
|
||||
private RequestType type;
|
||||
|
||||
|
||||
public ActionRequest(RequestType request) {
|
||||
type = request;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener handler)
|
||||
{
|
||||
handler.requestAction(type);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
public void requestAction(RequestType request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.control.bus.Event;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
@@ -11,7 +11,7 @@ import org.lwjgl.input.Keyboard;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class KeyboardEvent implements Handleable<KeyboardEvent.Listener> {
|
||||
public class KeyboardEvent implements Event<KeyboardEvent.Listener> {
|
||||
|
||||
private int key;
|
||||
private boolean down;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.control.bus.Event;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import mightypork.utils.math.coord.Coord;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class MouseButtonEvent implements Handleable<MouseButtonEvent.Listener> {
|
||||
public class MouseButtonEvent implements Event<MouseButtonEvent.Listener> {
|
||||
|
||||
public static final int BUTTON_LEFT = 0;
|
||||
public static final int BUTTON_MIDDLE = 1;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.control.bus.Event;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
|
||||
public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
|
||||
public class MouseMotionEvent implements Event<MouseMotionEvent.Listener> {
|
||||
|
||||
private Coord move;
|
||||
private Coord pos;
|
||||
@@ -20,7 +20,7 @@ public class MouseMotionEvent implements Handleable<MouseMotionEvent.Listener> {
|
||||
/**
|
||||
* @return movement since last {@link MouseMotionEvent}
|
||||
*/
|
||||
public Coord getPosDelta()
|
||||
public Coord getMove()
|
||||
{
|
||||
return move;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
public enum RequestType
|
||||
{
|
||||
FULLSCREEN, SCREENSHOT, SHUTDOWN;
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Handleable;
|
||||
import mightypork.utils.control.bus.Event;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
|
||||
public class ScreenChangeEvent implements Handleable<ScreenChangeEvent.Listener> {
|
||||
public class ScreenChangeEvent implements Event<ScreenChangeEvent.Listener> {
|
||||
|
||||
private boolean fullscreen;
|
||||
private Coord screenSize;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package mightypork.rogue.bus.events;
|
||||
|
||||
|
||||
import mightypork.utils.control.bus.Event;
|
||||
|
||||
|
||||
public class ScreenRequestEvent implements Event<ScreenRequestEvent.Listener> {
|
||||
|
||||
private String scrName;
|
||||
|
||||
|
||||
public ScreenRequestEvent(String screenKey) {
|
||||
scrName = screenKey;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleBy(Listener handler)
|
||||
{
|
||||
handler.showScreen(scrName);
|
||||
}
|
||||
|
||||
public interface Listener {
|
||||
|
||||
public void showScreen(String key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package mightypork.rogue.display.screens;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
|
||||
|
||||
public class ScreenRegistry extends Subsystem {
|
||||
|
||||
public ScreenRegistry(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinit()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package mightypork.rogue.display.screens.screenTextures;
|
||||
|
||||
|
||||
public class ScreenTextureTest {
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
package mightypork.rogue.gui.constraints;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
package mightypork.rogue.gui.constraints;
|
||||
|
||||
|
||||
/**
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.display.constraints;
|
||||
package mightypork.rogue.gui.constraints;
|
||||
|
||||
|
||||
import mightypork.utils.math.constraints.ConstraintContext;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.display;
|
||||
package mightypork.rogue.gui.screens;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
+67
-54
@@ -1,13 +1,15 @@
|
||||
package mightypork.rogue.display;
|
||||
package mightypork.rogue.gui.screens;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.ChildClient;
|
||||
import mightypork.rogue.bus.events.ScreenChangeEvent;
|
||||
import mightypork.rogue.input.KeyBinder;
|
||||
import mightypork.rogue.input.KeyBindingPool;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.rogue.render.Render;
|
||||
import mightypork.utils.control.interf.Destroyable;
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
import mightypork.utils.math.constraints.ConstraintContext;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
@@ -21,11 +23,13 @@ import mightypork.utils.math.coord.Rect;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Screen extends Subsystem implements Updateable, KeyBinder, ConstraintContext, ScreenChangeEvent.Listener {
|
||||
public abstract class Screen extends ChildClient implements Destroyable, Updateable, KeyBinder, ConstraintContext, ScreenChangeEvent.Listener {
|
||||
|
||||
private final KeyBindingPool keybindings = new KeyBindingPool();
|
||||
|
||||
private boolean active;
|
||||
private boolean needSetupGraphics = false;
|
||||
private boolean needSetupViewport = false;
|
||||
|
||||
|
||||
public Screen(AppAccess app) {
|
||||
@@ -53,7 +57,7 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
|
||||
|
||||
@Override
|
||||
protected final void deinit()
|
||||
public final void destroy()
|
||||
{
|
||||
deinitScreen();
|
||||
}
|
||||
@@ -68,8 +72,9 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
{
|
||||
if (shown) {
|
||||
active = true;
|
||||
setupGraphics();
|
||||
setupViewport();
|
||||
needSetupGraphics = true;
|
||||
needSetupViewport = true;
|
||||
|
||||
onSizeChanged(getRect().getSize());
|
||||
onScreenEnter();
|
||||
|
||||
@@ -130,51 +135,12 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
protected abstract void updateScreen(double delta);
|
||||
|
||||
|
||||
private void setupGraphics()
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glClearDepth(1f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
setupViewport();
|
||||
}
|
||||
|
||||
|
||||
private void setupViewport()
|
||||
{
|
||||
// fix projection for changed size
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
Coord s = disp().getSize();
|
||||
glViewport(0, 0, s.xi(), s.yi());
|
||||
glOrtho(0, s.x, 0, s.y, -1000, 1000);
|
||||
|
||||
// back to modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render screen
|
||||
*/
|
||||
private void renderBegin()
|
||||
{
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glPushMatrix();
|
||||
Render.pushState();
|
||||
}
|
||||
|
||||
|
||||
@@ -183,8 +149,7 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
*/
|
||||
private void renderEnd()
|
||||
{
|
||||
glPopAttrib();
|
||||
glPopMatrix();
|
||||
Render.popState();
|
||||
}
|
||||
|
||||
|
||||
@@ -202,9 +167,9 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
{
|
||||
if (!isActive()) return;
|
||||
|
||||
setupViewport();
|
||||
|
||||
onSizeChanged(event.getScreenSize());
|
||||
|
||||
needSetupViewport = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,10 +180,6 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
public final void update(double delta)
|
||||
{
|
||||
updateScreen(delta);
|
||||
|
||||
renderBegin();
|
||||
renderScreen();
|
||||
renderEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -228,4 +189,56 @@ public abstract class Screen extends Subsystem implements Updateable, KeyBinder,
|
||||
return disp().getRect();
|
||||
}
|
||||
|
||||
|
||||
public final void render()
|
||||
{
|
||||
if (!isActive()) return;
|
||||
|
||||
if (needSetupGraphics) {
|
||||
setupGraphics();
|
||||
}
|
||||
|
||||
if (needSetupViewport) {
|
||||
setupViewport();
|
||||
}
|
||||
|
||||
renderBegin();
|
||||
renderScreen();
|
||||
renderEnd();
|
||||
}
|
||||
|
||||
|
||||
private void setupGraphics()
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glClearDepth(1f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
|
||||
private void setupViewport()
|
||||
{
|
||||
// fix projection for changed size
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
Coord s = disp().getSize();
|
||||
glViewport(0, 0, s.xi(), s.yi());
|
||||
glOrtho(0, s.x, s.y, 0, -1000, 1000);
|
||||
|
||||
// back to modelview
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
package mightypork.rogue.display;
|
||||
package mightypork.rogue.gui.screens;
|
||||
|
||||
|
||||
import mightypork.rogue.bus.ChildClient;
|
||||
import mightypork.rogue.display.constraints.Renderable;
|
||||
import mightypork.rogue.gui.constraints.Renderable;
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
import mightypork.utils.math.constraints.ConstraintContext;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
@@ -0,0 +1,55 @@
|
||||
package mightypork.rogue.gui.screens;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.events.ScreenRequestEvent;
|
||||
|
||||
|
||||
public class ScreenRegistry extends Subsystem implements ScreenRequestEvent.Listener {
|
||||
|
||||
private HashMap<String, Screen> screens = new HashMap<String, Screen>();
|
||||
private Screen active = null;
|
||||
|
||||
|
||||
public ScreenRegistry(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
|
||||
public void add(String key, Screen screen)
|
||||
{
|
||||
screens.put(key, screen);
|
||||
addChildClient(screen);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void showScreen(String key)
|
||||
{
|
||||
Screen toshow = screens.get(key);
|
||||
if (toshow == null) throw new RuntimeException("Screen " + key + " not defined.");
|
||||
|
||||
if (active != null) active.setActive(false);
|
||||
|
||||
toshow.setActive(true);
|
||||
|
||||
active = toshow;
|
||||
}
|
||||
|
||||
|
||||
public void render()
|
||||
{
|
||||
if (active != null) active.render();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinit()
|
||||
{
|
||||
// no impl
|
||||
}
|
||||
|
||||
}
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
package mightypork.rogue.display.screens.screenBouncy;
|
||||
package mightypork.rogue.gui.screens.screenBouncy;
|
||||
|
||||
|
||||
import static mightypork.utils.math.constraints.ConstraintFactory.*;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.rogue.display.constraints.RenderableWithContext;
|
||||
import mightypork.rogue.textures.Render;
|
||||
import mightypork.rogue.gui.constraints.RenderableWithContext;
|
||||
import mightypork.rogue.render.Render;
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
import mightypork.utils.math.animation.AnimDouble;
|
||||
import mightypork.utils.math.animation.Easing;
|
||||
@@ -55,7 +55,7 @@ public class BouncyBox implements RenderableWithContext, Updateable, ConstraintC
|
||||
@Override
|
||||
public void render()
|
||||
{
|
||||
Render.quadRect(box.getRect(), RGB.GREEN);
|
||||
Render.quad(box.getRect(), RGB.GREEN);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.display.screens.screenBouncy;
|
||||
package mightypork.rogue.gui.screens.screenBouncy;
|
||||
|
||||
|
||||
import static mightypork.utils.math.constraints.ConstraintFactory.*;
|
||||
@@ -6,9 +6,9 @@ import static mightypork.utils.math.constraints.ConstraintFactory.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import mightypork.rogue.display.Screen;
|
||||
import mightypork.rogue.display.ScreenLayer;
|
||||
import mightypork.rogue.display.constraints.ElementHolder;
|
||||
import mightypork.rogue.gui.constraints.ElementHolder;
|
||||
import mightypork.rogue.gui.screens.Screen;
|
||||
import mightypork.rogue.gui.screens.ScreenLayer;
|
||||
import mightypork.utils.math.constraints.RectConstraint;
|
||||
|
||||
|
||||
+4
-4
@@ -1,19 +1,19 @@
|
||||
package mightypork.rogue.display.screens.screenBouncy;
|
||||
package mightypork.rogue.gui.screens.screenBouncy;
|
||||
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.display.LayeredScreen;
|
||||
import mightypork.rogue.gui.screens.LayeredScreen;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
public class TestLayeredScreen extends LayeredScreen {
|
||||
public class ScreenTestAnim extends LayeredScreen {
|
||||
|
||||
private LayerBouncyBoxes layer;
|
||||
|
||||
|
||||
public TestLayeredScreen(AppAccess app) {
|
||||
public ScreenTestAnim(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
layer = new LayerBouncyBoxes(this);
|
||||
@@ -0,0 +1,104 @@
|
||||
package mightypork.rogue.gui.screens.screenTextures;
|
||||
|
||||
|
||||
import static mightypork.utils.math.constraints.ConstraintFactory.*;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.Res;
|
||||
import mightypork.rogue.bus.events.ActionRequest;
|
||||
import mightypork.rogue.bus.events.MouseButtonEvent;
|
||||
import mightypork.rogue.bus.events.RequestType;
|
||||
import mightypork.rogue.gui.screens.Screen;
|
||||
import mightypork.rogue.input.KeyStroke;
|
||||
import mightypork.rogue.render.Render;
|
||||
import mightypork.utils.math.animation.AnimDouble;
|
||||
import mightypork.utils.math.animation.Easing;
|
||||
import mightypork.utils.math.constraints.RectConstraint;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
public class ScreenTextureTest extends Screen implements MouseButtonEvent.Listener {
|
||||
|
||||
private RectConstraint kittenbox;
|
||||
|
||||
private AnimDouble s = new AnimDouble(400, Easing.SINE_BOTH);
|
||||
private AnimDouble x = new AnimDouble(200, Easing.ELASTIC_OUT);
|
||||
private AnimDouble y = new AnimDouble(200, Easing.ELASTIC_OUT);
|
||||
|
||||
private Random rand = new Random();
|
||||
|
||||
|
||||
public ScreenTextureTest(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
kittenbox = c_move(c_box_sized(this, c_n(s), c_n(s)), c_n(x), c_n(y));
|
||||
|
||||
bindKeyStroke(new KeyStroke(Keyboard.KEY_ESCAPE), new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
snd().fadeOutAllLoops();
|
||||
bus().schedule(new ActionRequest(RequestType.SHUTDOWN), 3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinitScreen()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onScreenEnter()
|
||||
{
|
||||
System.out.println("YOLO");
|
||||
Res.getLoop("test.wilderness").fadeIn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onScreenLeave()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void renderScreen()
|
||||
{
|
||||
Render.quadTextured(kittenbox.getRect(), Res.getTexture("test.kitten"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void updateScreen(double delta)
|
||||
{
|
||||
s.update(delta);
|
||||
x.update(delta);
|
||||
y.update(delta);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void receive(MouseButtonEvent event)
|
||||
{
|
||||
if (!event.isDown()) return;
|
||||
|
||||
Coord pos = event.getPos();
|
||||
|
||||
double newSize = 200 + rand.nextInt(600);
|
||||
|
||||
double t = 2;
|
||||
|
||||
s.fadeTo(newSize, t / 2D);
|
||||
x.fadeTo(pos.x - newSize / 2D, t);
|
||||
y.fadeTo(pos.y - newSize / 2D, t);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,9 +3,11 @@ package mightypork.rogue.input;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.rogue.bus.events.ActionRequest;
|
||||
import mightypork.rogue.bus.events.KeyboardEvent;
|
||||
import mightypork.rogue.bus.events.MouseButtonEvent;
|
||||
import mightypork.rogue.bus.events.MouseMotionEvent;
|
||||
import mightypork.rogue.bus.events.RequestType;
|
||||
import mightypork.utils.control.interf.Updateable;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
@@ -19,6 +21,7 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
|
||||
// listeners
|
||||
private KeyBindingPool keybindings;
|
||||
private boolean yAxisDown = true;
|
||||
|
||||
|
||||
public InputSystem(AppAccess app) {
|
||||
@@ -26,8 +29,6 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
|
||||
initDevices();
|
||||
|
||||
initChannels();
|
||||
|
||||
// global keybindings
|
||||
keybindings = new KeyBindingPool();
|
||||
addChildClient(keybindings);
|
||||
@@ -54,14 +55,6 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
}
|
||||
|
||||
|
||||
private void initChannels()
|
||||
{
|
||||
bus().createChannel(KeyboardEvent.class, KeyboardEvent.Listener.class);
|
||||
bus().createChannel(MouseMotionEvent.class, MouseMotionEvent.Listener.class);
|
||||
bus().createChannel(MouseButtonEvent.class, MouseButtonEvent.Listener.class);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void bindKeyStroke(KeyStroke stroke, Runnable task)
|
||||
{
|
||||
@@ -79,19 +72,35 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
// was destroyed
|
||||
if (!Display.isCreated()) return;
|
||||
if (!Mouse.isCreated()) return;
|
||||
if (!Keyboard.isCreated()) return;
|
||||
|
||||
Display.processMessages();
|
||||
|
||||
Coord moveSum = Coord.zero();
|
||||
Coord lastPos = Coord.zero();
|
||||
boolean wasMouse = false;
|
||||
|
||||
while (Mouse.next()) {
|
||||
onMouseEvent();
|
||||
onMouseEvent(moveSum, lastPos);
|
||||
wasMouse = true;
|
||||
}
|
||||
|
||||
if (wasMouse && !moveSum.isZero()) bus().queue(new MouseMotionEvent(lastPos, moveSum));
|
||||
|
||||
while (Keyboard.next()) {
|
||||
onKeyEvent();
|
||||
}
|
||||
|
||||
if (Display.isCloseRequested()) {
|
||||
bus().queue(new ActionRequest(RequestType.SHUTDOWN));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void onMouseEvent()
|
||||
private void onMouseEvent(Coord moveSum, Coord lastPos)
|
||||
{
|
||||
int button = Mouse.getEventButton();
|
||||
boolean down = Mouse.getEventButtonState();
|
||||
@@ -99,8 +108,17 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
Coord move = new Coord(Mouse.getEventDX(), Mouse.getEventDY());
|
||||
int wheeld = Mouse.getEventDWheel();
|
||||
|
||||
if (button != -1 || wheeld != 0) bus().broadcast(new MouseButtonEvent(pos, button, down, wheeld));
|
||||
if (!move.isZero()) bus().broadcast(new MouseMotionEvent(pos, move));
|
||||
if (yAxisDown) {
|
||||
flipScrY(pos);
|
||||
move.mul_ip(1, -1, 1);
|
||||
}
|
||||
|
||||
if (button != -1 || wheeld != 0) {
|
||||
bus().queue(new MouseButtonEvent(pos, button, down, wheeld));
|
||||
}
|
||||
|
||||
moveSum.add_ip(move);
|
||||
lastPos.setTo(pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +127,14 @@ public class InputSystem extends Subsystem implements Updateable, KeyBinder {
|
||||
int key = Keyboard.getEventKey();
|
||||
boolean down = Keyboard.getEventKeyState();
|
||||
char c = Keyboard.getEventCharacter();
|
||||
bus().broadcast(new KeyboardEvent(key, c, down));
|
||||
bus().queue(new KeyboardEvent(key, c, down));
|
||||
}
|
||||
|
||||
|
||||
private void flipScrY(Coord c)
|
||||
{
|
||||
if (disp() != null) {
|
||||
c.setY_ip(disp().getSize().y - c.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-14
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.display;
|
||||
package mightypork.rogue.render;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
@@ -27,8 +27,6 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
|
||||
|
||||
public DisplaySystem(AppAccess app) {
|
||||
super(app);
|
||||
|
||||
initChannels();
|
||||
}
|
||||
|
||||
|
||||
@@ -39,15 +37,6 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize event channels
|
||||
*/
|
||||
private void initChannels()
|
||||
{
|
||||
bus().createChannel(ScreenChangeEvent.class, ScreenChangeEvent.Listener.class);
|
||||
}
|
||||
|
||||
|
||||
public void setTargetFps(int fps)
|
||||
{
|
||||
this.targetFps = fps;
|
||||
@@ -94,7 +83,7 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
|
||||
Display.update();
|
||||
}
|
||||
|
||||
bus().broadcast(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
|
||||
bus().queue(new ScreenChangeEvent(true, Display.isFullscreen(), getSize()));
|
||||
|
||||
} catch (Throwable t) {
|
||||
Log.e("Failed to toggle fullscreen mode.", t);
|
||||
@@ -162,7 +151,7 @@ public class DisplaySystem extends Subsystem implements ConstraintContext {
|
||||
{
|
||||
// handle resize
|
||||
if (Display.wasResized()) {
|
||||
bus().broadcast(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
|
||||
bus().queue(new ScreenChangeEvent(false, Display.isFullscreen(), getSize()));
|
||||
}
|
||||
|
||||
glLoadIdentity();
|
||||
@@ -0,0 +1,349 @@
|
||||
package mightypork.rogue.render;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.rogue.render.textures.TxQuad;
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.color.RGB;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.SlickCallable;
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
import org.newdawn.slick.opengl.TextureImpl;
|
||||
import org.newdawn.slick.opengl.TextureLoader;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Render utilities
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Render {
|
||||
|
||||
private static final Coord AXIS_X = new Coord(1, 0, 0);
|
||||
private static final Coord AXIS_Y = new Coord(0, 1, 0);
|
||||
private static final Coord AXIS_Z = new Coord(0, 0, 1);
|
||||
|
||||
private static boolean inited = false;
|
||||
|
||||
|
||||
/**
|
||||
* Bind GL color
|
||||
*
|
||||
* @param color RGB color
|
||||
*/
|
||||
public static void setColor(RGB color)
|
||||
{
|
||||
if (color != null) glColor4d(color.r, color.g, color.b, color.a);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind GL color
|
||||
*
|
||||
* @param color RGB color
|
||||
* @param alpha alpha multiplier
|
||||
*/
|
||||
public static void setColor(RGB color, double alpha)
|
||||
{
|
||||
if (color != null) glColor4d(color.r, color.g, color.b, color.a * alpha);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Translate with coord
|
||||
*
|
||||
* @param coord coord
|
||||
*/
|
||||
public static void translate(Coord coord)
|
||||
{
|
||||
glTranslated(coord.x, coord.y, coord.z);
|
||||
}
|
||||
|
||||
|
||||
public static void rotateX(double angle)
|
||||
{
|
||||
rotate(angle, AXIS_X);
|
||||
}
|
||||
|
||||
|
||||
public static void rotateY(double angle)
|
||||
{
|
||||
rotate(angle, AXIS_Y);
|
||||
}
|
||||
|
||||
|
||||
public static void rotateZ(double angle)
|
||||
{
|
||||
rotate(angle, AXIS_Z);
|
||||
}
|
||||
|
||||
|
||||
public static void rotate(double angle, Coord axis)
|
||||
{
|
||||
Coord vec = axis.norm(1);
|
||||
glRotated(angle, vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
|
||||
public static void pushState()
|
||||
{
|
||||
SlickCallable.enterSafeBlock();
|
||||
}
|
||||
|
||||
|
||||
public static void popState()
|
||||
{
|
||||
SlickCallable.leaveSafeBlock();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load texture
|
||||
*
|
||||
* @param resourcePath
|
||||
* @return the loaded texture
|
||||
*/
|
||||
public static Texture loadTexture(String resourcePath)
|
||||
{
|
||||
if (!inited) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
inited = true;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
String ext = FileUtils.getExtension(resourcePath).toUpperCase();
|
||||
|
||||
Log.f3("Loading texture " + ext + " at " + resourcePath);
|
||||
|
||||
Texture texture = TextureLoader.getTexture(ext, ResourceLoader.getResourceAsStream(resourcePath));
|
||||
|
||||
if (texture == null) {
|
||||
Log.w("Texture " + resourcePath + " could not be loaded.");
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e("Loading of texture " + resourcePath + " failed.", e);
|
||||
throw new RuntimeException("Could not load texture " + resourcePath + ".", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind texture
|
||||
*
|
||||
* @param texture the texture
|
||||
* @throws RuntimeException if not loaded yet
|
||||
*/
|
||||
private static void bindTexture(Texture texture) throws RuntimeException
|
||||
{
|
||||
texture.bind();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unbind all
|
||||
*/
|
||||
private static void unbindTexture()
|
||||
{
|
||||
if (TextureImpl.getLastBind() != null) {
|
||||
TextureImpl.bindNone();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D
|
||||
*
|
||||
* @param rect rectangle
|
||||
* @param color draw color
|
||||
*/
|
||||
public static void quad(Rect rect, RGB color)
|
||||
{
|
||||
setColor(color);
|
||||
quad(rect);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad
|
||||
*
|
||||
* @param quad the quad to draw (px)
|
||||
*/
|
||||
public static void quad(Rect quad)
|
||||
{
|
||||
double left = quad.xMin();
|
||||
double bottom = quad.yMin();
|
||||
double right = quad.yMax();
|
||||
double top = quad.yMax();
|
||||
|
||||
// draw with color
|
||||
unbindTexture();
|
||||
|
||||
// quad
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(left, top);
|
||||
glVertex2d(right, top);
|
||||
glVertex2d(right, bottom);
|
||||
glVertex2d(left, bottom);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect (texture must be binded already)
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param uvs texture coords (0-1)
|
||||
*/
|
||||
private static void quadUV(Rect quad, Rect uvs)
|
||||
{
|
||||
double left = quad.xMin();
|
||||
double bottom = quad.yMin();
|
||||
double right = quad.xMax();
|
||||
double top = quad.yMax();
|
||||
|
||||
double tleft = uvs.xMin();
|
||||
double tbottom = uvs.yMin();
|
||||
double tright = uvs.xMax();
|
||||
double ttop = uvs.yMax();
|
||||
|
||||
// quad with texture
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(tleft, ttop);
|
||||
glVertex2d(left, top);
|
||||
glTexCoord2d(tright, ttop);
|
||||
glVertex2d(right, top);
|
||||
glTexCoord2d(tright, tbottom);
|
||||
glVertex2d(right, bottom);
|
||||
glTexCoord2d(tleft, tbottom);
|
||||
glVertex2d(left, bottom);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
public static void quadGradH(Rect quad, RGB colorLeft, RGB colorRight)
|
||||
{
|
||||
double left = quad.xMin();
|
||||
double bottom = quad.yMin();
|
||||
double right = quad.yMax();
|
||||
double top = quad.yMax();
|
||||
|
||||
// draw with color
|
||||
unbindTexture();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
setColor(colorLeft);
|
||||
glVertex2d(left, top);
|
||||
setColor(colorRight);
|
||||
glVertex2d(right, top);
|
||||
|
||||
setColor(colorRight);
|
||||
glVertex2d(right, bottom);
|
||||
setColor(colorLeft);
|
||||
glVertex2d(left, bottom);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
public static void quadGradV(Rect quad, RGB colorTop, RGB colorBottom)
|
||||
{
|
||||
double left = quad.xMin();
|
||||
double bottom = quad.yMin();
|
||||
double right = quad.yMax();
|
||||
double top = quad.yMax();
|
||||
|
||||
// draw with color
|
||||
unbindTexture();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
setColor(colorTop);
|
||||
glVertex2d(left, top);
|
||||
glVertex2d(right, top);
|
||||
|
||||
setColor(colorBottom);
|
||||
glVertex2d(right, bottom);
|
||||
glVertex2d(left, bottom);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param uvs texture coords rectangle (0-1)
|
||||
* @param texture texture instance
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTextured(Rect quad, Rect uvs, Texture texture, RGB tint)
|
||||
{
|
||||
bindTexture(texture);
|
||||
setColor(tint);
|
||||
quadUV(quad, uvs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param uvs texture coords rectangle (px)
|
||||
* @param texture texture instance
|
||||
*/
|
||||
public static void quadTextured(Rect quad, Rect uvs, Texture texture)
|
||||
{
|
||||
quadTextured(quad, uvs, texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param texture texture instance
|
||||
*/
|
||||
public static void quadTextured(Rect quad, Texture texture)
|
||||
{
|
||||
quadTextured(quad, Rect.one(), texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param txquad texture quad
|
||||
*/
|
||||
public static void quadTextured(Rect quad, TxQuad txquad)
|
||||
{
|
||||
quadTextured(quad, txquad, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param txquad texture instance
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTextured(Rect quad, TxQuad txquad, RGB tint)
|
||||
{
|
||||
quadTextured(quad, txquad.uvs, txquad.tx, tint);
|
||||
}
|
||||
|
||||
}
|
||||
+14
-7
@@ -1,12 +1,14 @@
|
||||
package mightypork.rogue.textures;
|
||||
package mightypork.rogue.render.textures;
|
||||
|
||||
|
||||
import mightypork.rogue.Deferred;
|
||||
import mightypork.rogue.render.Render;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
public class MultiTexture implements Texture {
|
||||
public class MultiTexture implements Texture, Deferred {
|
||||
|
||||
private Texture backingTexture;
|
||||
private String resourcePath;
|
||||
@@ -23,17 +25,22 @@ public class MultiTexture implements Texture {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to load the texture.
|
||||
*/
|
||||
private void load()
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
if (backingTexture == null) {
|
||||
if (!isLoaded()) {
|
||||
backingTexture = Render.loadTexture(resourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isLoaded()
|
||||
{
|
||||
return backingTexture != null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasAlpha()
|
||||
{
|
||||
+5
-18
@@ -1,11 +1,10 @@
|
||||
package mightypork.rogue.textures;
|
||||
package mightypork.rogue.render.textures;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import mightypork.rogue.AppAccess;
|
||||
import mightypork.rogue.bus.Subsystem;
|
||||
import mightypork.utils.control.interf.Destroyable;
|
||||
import mightypork.rogue.AppAdapter;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
@@ -16,9 +15,9 @@ import org.newdawn.slick.opengl.Texture;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TextureRegistry extends Subsystem implements Destroyable {
|
||||
public class TextureBank extends AppAdapter {
|
||||
|
||||
public TextureRegistry(AppAccess app) {
|
||||
public TextureBank(AppAccess app) {
|
||||
super(app);
|
||||
}
|
||||
|
||||
@@ -84,7 +83,7 @@ public class TextureRegistry extends Subsystem implements Destroyable {
|
||||
* @param key quad key
|
||||
* @return the quad
|
||||
*/
|
||||
public TxQuad getQuad(String key)
|
||||
public TxQuad getTxQuad(String key)
|
||||
{
|
||||
TxQuad q = quads.get(key);
|
||||
|
||||
@@ -109,16 +108,4 @@ public class TextureRegistry extends Subsystem implements Destroyable {
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void deinit()
|
||||
{
|
||||
for (Texture tx : textures.values()) {
|
||||
tx.release();
|
||||
}
|
||||
|
||||
textures.clear();
|
||||
quads.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package mightypork.rogue.render.textures;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
/**
|
||||
* Texture Quad (describing a part of a texture)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TxQuad {
|
||||
|
||||
/** The texture */
|
||||
public Texture tx;
|
||||
/** Coords in texture (0-1) */
|
||||
public Rect uvs;
|
||||
|
||||
|
||||
/**
|
||||
* TxQuad from origin and size in pixels
|
||||
*
|
||||
* @param tx texture
|
||||
* @param xPx left top X (0-1)
|
||||
* @param yPx left top Y (0-1)
|
||||
* @param widthPx area width (0-1)
|
||||
* @param heightPx area height (0-1)
|
||||
* @return new TxQuad
|
||||
*/
|
||||
public static TxQuad fromSizePx(Texture tx, double xPx, double yPx, double widthPx, double heightPx)
|
||||
{
|
||||
double w = tx.getImageWidth();
|
||||
double h = tx.getImageHeight();
|
||||
|
||||
return fromSize(tx, xPx / w, yPx / h, widthPx / w, heightPx / h);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TxQuad from origin and size 0-1
|
||||
*
|
||||
* @param tx texture
|
||||
* @param x1 left top X (0-1)
|
||||
* @param y1 left top Y (0-1)
|
||||
* @param width area width (0-1)
|
||||
* @param height area height (0-1)
|
||||
* @return new TxQuad
|
||||
*/
|
||||
public static TxQuad fromSize(Texture tx, double x1, double y1, double width, double height)
|
||||
{
|
||||
return new TxQuad(tx, x1, y1, x1 + width, y1 + height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make of coords
|
||||
*
|
||||
* @param tx texture
|
||||
* @param x1 left top X (0-1)
|
||||
* @param y1 left top Y (0-1)
|
||||
* @param x2 right bottom X (0-1)
|
||||
* @param y2 right bottom Y (0-1)
|
||||
*/
|
||||
public TxQuad(Texture tx, double x1, double y1, double x2, double y2) {
|
||||
this(tx, new Rect(x1, y1, x2, y2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param tx Texture
|
||||
* @param uvs Rect of texturwe UVs (pixels - from left top)
|
||||
*/
|
||||
public TxQuad(Texture tx, Rect uvs) {
|
||||
this.tx = tx;
|
||||
this.uvs = uvs.copy();
|
||||
}
|
||||
|
||||
|
||||
public TxQuad(TxQuad txQuad) {
|
||||
this.tx = txQuad.tx;
|
||||
this.uvs = txQuad.uvs.copy();
|
||||
}
|
||||
|
||||
|
||||
public TxQuad copy()
|
||||
{
|
||||
return new TxQuad(this);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
public class NullAudio extends AudioX {
|
||||
|
||||
public NullAudio() {
|
||||
super("");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean load()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,8 +11,8 @@ import java.util.Date;
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import mightypork.rogue.Paths;
|
||||
import mightypork.rogue.display.DisplaySystem;
|
||||
import mightypork.rogue.display.DisplaySystem.Screenshot;
|
||||
import mightypork.rogue.render.DisplaySystem;
|
||||
import mightypork.rogue.render.DisplaySystem.Screenshot;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,70 +0,0 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
/**
|
||||
* Texture Quad (describing a part of a texture)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TxQuad {
|
||||
|
||||
/** The texture */
|
||||
public Texture tx;
|
||||
/** Coords in texture (pixels) */
|
||||
public Rect uvs;
|
||||
/** Quad size */
|
||||
public Coord size;
|
||||
|
||||
|
||||
/**
|
||||
* Create TxQuad from left top coord and rect size
|
||||
*
|
||||
* @param tx texture
|
||||
* @param x1 left top X
|
||||
* @param y1 left top Y
|
||||
* @param width area width
|
||||
* @param height area height
|
||||
* @return new TxQuad
|
||||
*/
|
||||
public static TxQuad fromSize(Texture tx, int x1, int y1, int width, int height)
|
||||
{
|
||||
return new TxQuad(tx, x1, y1, x1 + width, y1 + height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make of coords
|
||||
*
|
||||
* @param tx texture
|
||||
* @param x1 x1
|
||||
* @param y1 y1
|
||||
* @param x2 x2
|
||||
* @param y2 y2
|
||||
*/
|
||||
public TxQuad(Texture tx, int x1, int y1, int x2, int y2) {
|
||||
this(tx, new Rect(x1, y1, x2, y2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param tx Texture
|
||||
* @param uvs Rect of texturwe UVs (pixels - from left top)
|
||||
*/
|
||||
public TxQuad(Texture tx, Rect uvs) {
|
||||
this.tx = tx;
|
||||
this.uvs = uvs.copy();
|
||||
this.size = uvs.getSize();
|
||||
}
|
||||
|
||||
|
||||
public TxQuad copy()
|
||||
{
|
||||
return new TxQuad(tx, uvs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user