Removed bad libraries, added LWJGL and Slick-Util, added
mightypork.utils, some work on the framework.
This commit is contained in:
@@ -0,0 +1,417 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileLock;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import mightypork.rogue.input.Keys;
|
||||
import mightypork.rogue.screens.ScreenSplash;
|
||||
import mightypork.rogue.sounds.SoundManager;
|
||||
import mightypork.rogue.threads.ThreadSaveScreenshot;
|
||||
import mightypork.rogue.threads.ThreadScreenshotTrigger;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.logging.LogInstance;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.time.TimerDelta;
|
||||
import mightypork.utils.time.TimerInterpolating;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.LWJGLException;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.lwjgl.opengl.DisplayMode;
|
||||
|
||||
|
||||
public class App {
|
||||
|
||||
/** instance */
|
||||
public static App inst;
|
||||
/** Current delta time (secs since last render) */
|
||||
public static double currentDelta = 0;
|
||||
|
||||
private static DisplayMode windowDisplayMode = null;
|
||||
|
||||
/** current screen */
|
||||
public static Screen screen = null;
|
||||
|
||||
/** Flag that screenshot is scheduled to be taken next loop */
|
||||
public static boolean scheduledScreenshot = false;
|
||||
|
||||
|
||||
private static boolean lockInstance()
|
||||
{
|
||||
if (Config.SINGLE_INSTANCE == false) return true; // bypass lock
|
||||
|
||||
final File lockFile = new File(Paths.WORKDIR, ".lock");
|
||||
try {
|
||||
final RandomAccessFile randomAccessFile = new RandomAccessFile(lockFile, "rw");
|
||||
final FileLock fileLock = randomAccessFile.getChannel().tryLock();
|
||||
if (fileLock != null) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
fileLock.release();
|
||||
randomAccessFile.close();
|
||||
lockFile.delete();
|
||||
} catch (Exception e) {
|
||||
System.out.println("Unable to remove lock file.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Unable to create and/or lock file.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is if FS
|
||||
*
|
||||
* @return is in fs
|
||||
*/
|
||||
public static boolean isFullscreen()
|
||||
{
|
||||
return Display.isFullscreen();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler());
|
||||
|
||||
inst = new App();
|
||||
|
||||
try {
|
||||
inst.start();
|
||||
} catch (Throwable t) {
|
||||
onCrash(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show crash report dialog with error stack trace.
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
public static void onCrash(Throwable error)
|
||||
{
|
||||
Log.e("The game has crashed.");
|
||||
|
||||
Log.e(error);
|
||||
|
||||
try {
|
||||
inst.deinit();
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Quit to OS
|
||||
*/
|
||||
public void exit()
|
||||
{
|
||||
deinit();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get current screen
|
||||
*
|
||||
* @return screen
|
||||
*/
|
||||
public Screen getScreen()
|
||||
{
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get screen size
|
||||
*
|
||||
* @return size
|
||||
*/
|
||||
public Coord getSize()
|
||||
{
|
||||
return new Coord(Display.getWidth(), Display.getHeight());
|
||||
}
|
||||
|
||||
|
||||
private void init() throws LWJGLException
|
||||
{
|
||||
// initialize main logger
|
||||
LogInstance li = Log.create("runtime", Paths.LOGS, 10);
|
||||
li.enable(Config.LOGGING_ENABLED);
|
||||
li.enableSysout(Config.LOG_TO_STDOUT);
|
||||
|
||||
// initialize display
|
||||
Display.setDisplayMode(windowDisplayMode = new DisplayMode(Const.WINDOW_SIZE_X, Const.WINDOW_SIZE_Y));
|
||||
Display.setResizable(true);
|
||||
Display.setVSyncEnabled(true);
|
||||
Display.setTitle(Const.TITLEBAR);
|
||||
Display.create();
|
||||
|
||||
if (Config.START_IN_FS) {
|
||||
switchFullscreen();
|
||||
Display.update();
|
||||
}
|
||||
|
||||
// initialize inputs
|
||||
Mouse.create();
|
||||
Keyboard.create();
|
||||
Keyboard.enableRepeatEvents(false);
|
||||
|
||||
// initialize sound system
|
||||
SoundManager.get().setListener(Const.LISTENER_POS);
|
||||
SoundManager.get().setMasterVolume(1F);
|
||||
|
||||
// start async screenshot trigger listener
|
||||
(new ThreadScreenshotTrigger()).start();
|
||||
}
|
||||
|
||||
|
||||
private void start() throws LWJGLException
|
||||
{
|
||||
|
||||
if (!lockInstance()) {
|
||||
System.out.println("Working directory is locked.\nOnly one instance can run at a time.");
|
||||
|
||||
//@formatter:off
|
||||
JOptionPane.showMessageDialog(
|
||||
null,
|
||||
"The game is already running.",
|
||||
"Instance error",
|
||||
JOptionPane.ERROR_MESSAGE
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
exit();
|
||||
return;
|
||||
}
|
||||
|
||||
init();
|
||||
mainLoop();
|
||||
deinit();
|
||||
}
|
||||
|
||||
|
||||
private void deinit()
|
||||
{
|
||||
Display.destroy();
|
||||
Mouse.destroy();
|
||||
Keyboard.destroy();
|
||||
SoundManager.get().destroy();
|
||||
AL.destroy();
|
||||
}
|
||||
|
||||
/** timer */
|
||||
private TimerDelta timerRender;
|
||||
private TimerInterpolating timerGui;
|
||||
|
||||
private int timerAfterResize = 0;
|
||||
|
||||
|
||||
private void mainLoop()
|
||||
{
|
||||
screen = new ScreenSplash();
|
||||
|
||||
screen.init();
|
||||
|
||||
timerRender = new TimerDelta();
|
||||
timerGui = new TimerInterpolating(Const.FPS_GUI_UPDATE);
|
||||
|
||||
while (!Display.isCloseRequested()) {
|
||||
glLoadIdentity();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
timerGui.sync();
|
||||
|
||||
int ticks = timerGui.getSkipped();
|
||||
|
||||
if (ticks >= 1) {
|
||||
screen.updateGui();
|
||||
timerGui.startNewFrame();
|
||||
}
|
||||
|
||||
currentDelta = timerRender.getDelta();
|
||||
|
||||
// RENDER
|
||||
screen.render(currentDelta);
|
||||
SoundManager.get().update(currentDelta);
|
||||
|
||||
Display.update();
|
||||
|
||||
if (scheduledScreenshot) {
|
||||
takeScreenshot();
|
||||
scheduledScreenshot = false;
|
||||
}
|
||||
|
||||
if (Keys.justPressed(Keyboard.KEY_F11)) {
|
||||
Log.f2("F11, toggle fullscreen.");
|
||||
switchFullscreen();
|
||||
screen.onFullscreenChange();
|
||||
Keys.destroyChangeState(Keyboard.KEY_F11);
|
||||
}
|
||||
|
||||
if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) {
|
||||
if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
|
||||
Log.f2("Ctrl+Q, force quit.");
|
||||
Keys.destroyChangeState(Keyboard.KEY_Q);
|
||||
exit();
|
||||
return;
|
||||
}
|
||||
|
||||
// if (Keyboard.isKeyDown(Keyboard.KEY_M)) {
|
||||
// Log.f2("Ctrl+M, go to main menu.");
|
||||
// Keys.destroyChangeState(Keyboard.KEY_M);
|
||||
// replaceScreen(new ScreenMenuMain());
|
||||
// }
|
||||
|
||||
if (Keyboard.isKeyDown(Keyboard.KEY_F)) {
|
||||
Log.f2("Ctrl+F, switch fullscreen.");
|
||||
Keys.destroyChangeState(Keyboard.KEY_F);
|
||||
switchFullscreen();
|
||||
screen.onFullscreenChange();
|
||||
}
|
||||
}
|
||||
|
||||
if (Display.wasResized()) {
|
||||
screen.onWindowResize();
|
||||
timerAfterResize = 0;
|
||||
} else { // ensure screen has even size
|
||||
timerAfterResize++;
|
||||
if (timerAfterResize > Const.FPS_GUI_UPDATE * 0.3) {
|
||||
timerAfterResize = 0;
|
||||
int x = Display.getX();
|
||||
int y = Display.getY();
|
||||
|
||||
int w = Display.getWidth();
|
||||
int h = Display.getHeight();
|
||||
if (w % 2 != 0 || h % 2 != 0) {
|
||||
try {
|
||||
Display.setDisplayMode(windowDisplayMode = new DisplayMode(w - w % 2, h - h % 2));
|
||||
screen.onWindowResize();
|
||||
Display.setLocation(x, y);
|
||||
} catch (LWJGLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Display.sync(Const.FPS_RENDER);
|
||||
} catch (Throwable t) {
|
||||
Log.e("Your graphics card driver does not support fullscreen properly.", t);
|
||||
|
||||
try {
|
||||
Display.setDisplayMode(windowDisplayMode);
|
||||
} catch (LWJGLException e) {
|
||||
Log.e("Error going back from corrupted fullscreen.");
|
||||
onCrash(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// UPDATE LOOP END
|
||||
|
||||
/**
|
||||
* Do take a screenshot
|
||||
*/
|
||||
public void takeScreenshot()
|
||||
{
|
||||
//Effects.play("gui.screenshot");
|
||||
|
||||
glReadBuffer(GL_FRONT);
|
||||
int width = Display.getDisplayMode().getWidth();
|
||||
int height = Display.getDisplayMode().getHeight();
|
||||
int bpp = 4; // Assuming a 32-bit display with a byte each for red, green, blue, and alpha.
|
||||
ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
(new ThreadSaveScreenshot(buffer, width, height, bpp)).start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace screen
|
||||
*
|
||||
* @param newScreen new screen
|
||||
*/
|
||||
public void replaceScreen(Screen newScreen)
|
||||
{
|
||||
screen = newScreen;
|
||||
screen.init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replace screen, don't init it
|
||||
*
|
||||
* @param newScreen new screen
|
||||
*/
|
||||
public void replaceScreenNoInit(Screen newScreen)
|
||||
{
|
||||
screen = newScreen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggle FS if possible
|
||||
*/
|
||||
public void switchFullscreen()
|
||||
{
|
||||
try {
|
||||
if (!Display.isFullscreen()) {
|
||||
Log.f3("Entering fullscreen.");
|
||||
// save window resize
|
||||
windowDisplayMode = new DisplayMode(Display.getWidth(), Display.getHeight());
|
||||
|
||||
Display.setDisplayMode(Display.getDesktopDisplayMode());
|
||||
Display.setFullscreen(true);
|
||||
Display.update();
|
||||
//
|
||||
//
|
||||
// DisplayMode mode = Display.getDesktopDisplayMode(); //findDisplayMode(WIDTH, HEIGHT);
|
||||
// Display.setDisplayModeAndFullscreen(mode);
|
||||
} else {
|
||||
Log.f3("Leaving fullscreen.");
|
||||
Display.setDisplayMode(windowDisplayMode);
|
||||
Display.update();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.e("Failed to toggle fullscreen mode.", t);
|
||||
try {
|
||||
Display.setDisplayMode(windowDisplayMode);
|
||||
Display.update();
|
||||
} catch (Throwable t1) {
|
||||
onCrash(t1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import mightypork.utils.files.PropertyManager;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Main Config class
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Config {
|
||||
|
||||
private static PropertyManager mgr;
|
||||
|
||||
// opts
|
||||
public static final int def_LAST_RUN_VERSION = 0;
|
||||
public static int LAST_RUN_VERSION;
|
||||
|
||||
public static final boolean def_START_IN_FS = false;
|
||||
public static boolean START_IN_FS;
|
||||
|
||||
// property keys
|
||||
private static final String PK_LAST_RUN_VERSION = "status.last_run_version";
|
||||
private static final String PK_START_IN_FS = "cfg.start_in_fullscreen";
|
||||
|
||||
|
||||
/**
|
||||
* Prepare config manager and load user settings
|
||||
*/
|
||||
public static void init()
|
||||
{
|
||||
Log.f2("Initializing configuration manager.");
|
||||
|
||||
String comment = Const.APP_NAME + " config file";
|
||||
|
||||
mgr = new PropertyManager(Paths.CONFIG, comment);
|
||||
|
||||
mgr.cfgNewlineBeforeComments(true);
|
||||
mgr.cfgSeparateSections(true);
|
||||
|
||||
mgr.putInteger(PK_LAST_RUN_VERSION, def_LAST_RUN_VERSION);
|
||||
mgr.putBoolean(PK_START_IN_FS, def_START_IN_FS);
|
||||
|
||||
load(); // load what has been "put"
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save changed fields to config file
|
||||
*/
|
||||
public static void save()
|
||||
{
|
||||
mgr.setValue(PK_LAST_RUN_VERSION, Const.VERSION);
|
||||
mgr.setValue(PK_START_IN_FS, START_IN_FS);
|
||||
|
||||
mgr.apply();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load config file and assign values to fields
|
||||
*/
|
||||
public static void load()
|
||||
{
|
||||
mgr.apply();
|
||||
|
||||
LAST_RUN_VERSION = mgr.getInteger(PK_LAST_RUN_VERSION);
|
||||
START_IN_FS = mgr.getBoolean(PK_START_IN_FS);
|
||||
}
|
||||
|
||||
// options that can't be configured via config file
|
||||
|
||||
public static boolean LOGGING_ENABLED = true;
|
||||
public static boolean LOG_TO_STDOUT = true;
|
||||
public static boolean SINGLE_INSTANCE = true;
|
||||
|
||||
public static boolean LOG_FONTS = false;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
|
||||
/**
|
||||
* Application constants
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Const {
|
||||
|
||||
// STRINGS
|
||||
public static final int VERSION = 1;
|
||||
|
||||
public static final String APP_NAME = "Rogue";
|
||||
public static final String TITLEBAR = APP_NAME + " v." + VERSION;
|
||||
|
||||
// AUDIO
|
||||
public static final Coord LISTENER_POS = Coord.ZERO;
|
||||
|
||||
public static final int FPS_RENDER = 200; // max
|
||||
public static final long FPS_GUI_UPDATE = 60;
|
||||
|
||||
// INITIAL WINDOW SIZE
|
||||
public static final int WINDOW_SIZE_X = 1024;
|
||||
public static final int WINDOW_SIZE_Y = 768;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
|
||||
public class CrashHandler implements UncaughtExceptionHandler {
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e)
|
||||
{
|
||||
App.onCrash(e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import mightypork.utils.files.OsUtils;
|
||||
|
||||
|
||||
public class Paths {
|
||||
|
||||
private static final String APPDIR_NAME = "rogue";
|
||||
|
||||
public static final File WORKDIR = OsUtils.getWorkDir(APPDIR_NAME);
|
||||
public static final File LOGS = OsUtils.getWorkDir(APPDIR_NAME, "logs");
|
||||
public static final File SCREENSHOTS = OsUtils.getWorkDir(APPDIR_NAME, "screenshots");
|
||||
public static final File CONFIG = new File(WORKDIR, "config.ini");
|
||||
|
||||
public static final String DIR_EFFECTS = "res/sounds/effects/";
|
||||
public static final String DIR_MUSIC = "res/sounds/music/";
|
||||
public static final String DIR_LOOPS = "res/sounds/loops/";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package mightypork.rogue;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.rogue.animations.GUIRenderer;
|
||||
import mightypork.rogue.input.InputHandler;
|
||||
import mightypork.rogue.input.Keys;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Vec;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.input.Mouse;
|
||||
|
||||
|
||||
/**
|
||||
* Screen class.<br>
|
||||
* Screen animates 3D world, while contained panels render 2D overlays, process
|
||||
* inputs and run the game logic.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Screen implements GUIRenderer, InputHandler {
|
||||
|
||||
/** RNG */
|
||||
protected static Random rand = new Random();
|
||||
|
||||
|
||||
/**
|
||||
* handle fullscreen change
|
||||
*/
|
||||
@Override
|
||||
public final void onFullscreenChange()
|
||||
{
|
||||
onWindowResize();
|
||||
onViewportChanged();
|
||||
}
|
||||
|
||||
|
||||
protected abstract void onViewportChanged();
|
||||
|
||||
|
||||
/**
|
||||
* handle window resize.
|
||||
*/
|
||||
public final void onWindowResize()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
Coord s = App.inst.getSize();
|
||||
|
||||
glViewport(0, 0, s.xi(), s.yi());
|
||||
|
||||
glOrtho(0, s.x, 0, s.y, -1000, 1000);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glLoadIdentity();
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize screen
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
onWindowResize();
|
||||
|
||||
initScreen();
|
||||
|
||||
// SETUP LIGHTS
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
// OTHER SETTINGS
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glClearDepth(1f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Here you can initialize the screen.
|
||||
*/
|
||||
public abstract void initScreen();
|
||||
|
||||
|
||||
/**
|
||||
* Update tick
|
||||
*/
|
||||
@Override
|
||||
public final void updateGui()
|
||||
{
|
||||
Mouse.poll();
|
||||
Keyboard.poll();
|
||||
checkInputEvents();
|
||||
|
||||
onGuiUpdate();
|
||||
}
|
||||
|
||||
|
||||
protected abstract void onGuiUpdate();
|
||||
|
||||
|
||||
/**
|
||||
* Render screen
|
||||
*
|
||||
* @param delta delta time (position between two update ticks, to allow
|
||||
* super-smooth animations)
|
||||
*/
|
||||
@Override
|
||||
public final void render(double delta)
|
||||
{
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
|
||||
// draw the directly rendered 3D stuff
|
||||
render3D();
|
||||
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
protected abstract void render3D();
|
||||
|
||||
|
||||
/**
|
||||
* Check input events and process them.
|
||||
*/
|
||||
private final void checkInputEvents()
|
||||
{
|
||||
while (Keyboard.next()) {
|
||||
int key = Keyboard.getEventKey();
|
||||
boolean down = Keyboard.getEventKeyState();
|
||||
char c = Keyboard.getEventCharacter();
|
||||
Keys.onKey(key, down);
|
||||
onKey(key, c, down);
|
||||
}
|
||||
while (Mouse.next()) {
|
||||
int button = Mouse.getEventButton();
|
||||
boolean down = Mouse.getEventButtonState();
|
||||
Coord delta = new Coord(Mouse.getEventDX(), Mouse.getEventDY());
|
||||
Coord pos = new Coord(Mouse.getEventX(), Mouse.getEventY());
|
||||
int wheeld = Mouse.getEventDWheel();
|
||||
|
||||
onMouseButton(button, down, wheeld, pos, delta);
|
||||
}
|
||||
|
||||
int xc = Mouse.getX();
|
||||
int yc = Mouse.getY();
|
||||
int xd = Mouse.getDX();
|
||||
int yd = Mouse.getDY();
|
||||
int wd = Mouse.getDWheel();
|
||||
|
||||
if (Math.abs(xd) > 0 || Math.abs(yd) > 0 || Math.abs(wd) > 0) {
|
||||
onMouseMove(new Coord(xc, yc), new Vec(xd, yd), wd);
|
||||
}
|
||||
|
||||
handleKeyStates();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void onKey(int key, char c, boolean down);
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void onMouseButton(int button, boolean down, int wheeld, Coord pos, Coord delta);
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void handleKeyStates();
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void onMouseMove(Coord coord, Vec vec, int wd);
|
||||
|
||||
|
||||
/**
|
||||
* Render background 2D (all is ready for rendering)
|
||||
*
|
||||
* @param delta delta time
|
||||
*/
|
||||
protected abstract void render2D(double delta);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package mightypork.rogue.animations;
|
||||
|
||||
|
||||
/**
|
||||
* Empty animation (no effect)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class EmptyAnimator implements GUIRenderer {
|
||||
|
||||
/**
|
||||
* New empty animation
|
||||
*/
|
||||
public EmptyAnimator() {}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateGui()
|
||||
{}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(double delta)
|
||||
{}
|
||||
|
||||
|
||||
@Override
|
||||
public void onFullscreenChange()
|
||||
{}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package mightypork.rogue.animations;
|
||||
|
||||
|
||||
public interface GUIRenderer {
|
||||
|
||||
public void updateGui();
|
||||
|
||||
|
||||
public void render(double delta);
|
||||
|
||||
|
||||
public void onFullscreenChange();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package mightypork.rogue.fonts;
|
||||
|
||||
|
||||
/**
|
||||
* Alignment
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public class Align {
|
||||
|
||||
public static final int LEFT = -1;
|
||||
public static final int RIGHT = 1;
|
||||
public static final int TOP = 1;
|
||||
public static final int BOTTOM = -1;
|
||||
public static final int UP = 1;
|
||||
public static final int DOWN = -1;
|
||||
public static final int CENTER = 0;
|
||||
public static final int MIDDLE = 0;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
package mightypork.rogue.fonts;
|
||||
|
||||
|
||||
import java.awt.Font;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import mightypork.rogue.Config;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Remade universal font manager for Sector.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class FontManager {
|
||||
|
||||
private static final boolean DEBUG = Config.LOG_FONTS;
|
||||
|
||||
/**
|
||||
* Glyph tables.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public static class Glyphs {
|
||||
|
||||
//@formatter:off
|
||||
/** all glyphs */
|
||||
public static final String all =
|
||||
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]" +
|
||||
"^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£¤" +
|
||||
"¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäå" +
|
||||
"æçèéêëìíîïðñòóôõö÷øùúûüýþÿ";
|
||||
|
||||
/** letters and numbers, sufficient for basic messages etc. NO SPACE */
|
||||
public static final String alnum_nospace =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
/** letters and numbers, sufficient for basic messages etc. */
|
||||
public static final String alnum =
|
||||
" "+alnum_nospace;
|
||||
|
||||
/** letters and numbers with the most basic punctuation signs */
|
||||
public static final String basic_text =
|
||||
" .-,.?!:;_"+alnum_nospace;
|
||||
|
||||
/** letters */
|
||||
public static final String alpha =
|
||||
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
/** numbers */
|
||||
public static final String numbers =
|
||||
" 0123456789.-,:";
|
||||
|
||||
/** non-standard variants of alnum */
|
||||
public static final String alnum_extra =
|
||||
" ŒÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜŸÝßàáâãäåæçèéêëìíîïðñòóôõöøùúû" +
|
||||
"üýþÿĚŠČŘŽŤŇĎŮěščřžťňďůŁłđ";
|
||||
|
||||
/** signs and punctuation */
|
||||
public static final String signs =
|
||||
" !\"#$%&§'()*+,-./:;<=>?@[\\]^_{|}~";
|
||||
|
||||
/** extra signs and punctuation */
|
||||
public static final String signs_extra =
|
||||
" ¥€£¢`ƒ„…†‡ˆ‰‹‘’“”•›¡¤¦¨ª«¬¯°±²³´µ¶·¸¹º»¼½¾¿÷™©®→↓←↑";
|
||||
|
||||
|
||||
/** basic character set. */
|
||||
public static final String basic = alnum + signs;
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* Font style
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public static enum Style
|
||||
{
|
||||
/** Normal */
|
||||
NORMAL,
|
||||
/** Italic */
|
||||
ITALIC,
|
||||
/** Stronger italic to left. */
|
||||
LEFT,
|
||||
/** Stronger italic to right */
|
||||
RIGHT,
|
||||
/** Monospace type */
|
||||
MONO,
|
||||
/** Bold */
|
||||
BOLD,
|
||||
/** Bold & Italic */
|
||||
BOLD_I,
|
||||
/** Bold & Left */
|
||||
BOLD_L,
|
||||
/** Bold & Right */
|
||||
BOLD_R,
|
||||
/** Heavy style, stronger than bold. */
|
||||
HEAVY,
|
||||
/** Light (lighter than normal) */
|
||||
LIGHT,
|
||||
/** narrow style, similar to Light */
|
||||
NARROW,
|
||||
/** Wide style, like Bold but with thinner lines */
|
||||
WIDE,
|
||||
/** Outline variant of normal */
|
||||
OUTLINE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preloaded font identifier [name, size, style]
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public static class FontId {
|
||||
|
||||
/** font size (pt) */
|
||||
public float size = 24;
|
||||
/** font name, registered with registerFile */
|
||||
public String name = "";
|
||||
/** font style. The given style must be in a file. */
|
||||
public Style style;
|
||||
|
||||
/** Set of glyphs in this ID */
|
||||
public String glyphs = "";
|
||||
|
||||
/** Index for faster comparision of glyph ids. */
|
||||
public int glyphset_id = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Preloaded font identifier
|
||||
*
|
||||
* @param name font name (registerFile)
|
||||
* @param size font size (pt)
|
||||
* @param style font style
|
||||
* @param glyphs glyphs to load
|
||||
*/
|
||||
public FontId(String name, double size, Style style, String glyphs) {
|
||||
this.name = name;
|
||||
this.size = (float) size;
|
||||
this.style = style;
|
||||
|
||||
if (glyphs.equals(Glyphs.basic)) {
|
||||
glyphset_id = 1;
|
||||
} else if (glyphs.equals(Glyphs.alnum)) {
|
||||
glyphset_id = 2;
|
||||
} else if (glyphs.equals(Glyphs.basic_text)) {
|
||||
glyphset_id = 3;
|
||||
} else if (glyphs.equals(Glyphs.numbers)) {
|
||||
glyphset_id = 4;
|
||||
} else if (glyphs.equals(Glyphs.alpha)) {
|
||||
glyphset_id = 5;
|
||||
} else if (glyphs.equals(Glyphs.all)) {
|
||||
glyphset_id = 6;
|
||||
} else if (glyphs.equals(Glyphs.alnum_extra)) {
|
||||
glyphset_id = 7;
|
||||
} else if (glyphs.equals(Glyphs.signs)) {
|
||||
glyphset_id = 8;
|
||||
} else if (glyphs.equals(Glyphs.signs_extra)) {
|
||||
glyphset_id = 9;
|
||||
} else {
|
||||
this.glyphs = glyphs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (!(obj.getClass().isAssignableFrom(getClass()))) return false;
|
||||
if (obj instanceof FontId) {
|
||||
if (obj == this) return true;
|
||||
FontId id2 = ((FontId) obj);
|
||||
boolean flag = true;
|
||||
flag &= id2.size == size;
|
||||
flag &= id2.name.equals(name);
|
||||
flag &= id2.style == style;
|
||||
flag &= ((id2.glyphset_id != -1 && id2.glyphset_id == glyphset_id) || id2.glyphs.equals(glyphs));
|
||||
return flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return (new Float(size).hashCode()) ^ name.hashCode() ^ style.hashCode() ^ glyphset_id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "[" + name + ", " + size + ", " + style + (glyphset_id > 0 ? ", g=" + glyphset_id : ", g=custom") + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group of styles of one font.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public static class FontFamily extends HashMap<Style, String> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Table of font files. name → {style:file,style:file,style:file...}
|
||||
*/
|
||||
private static HashMap<String, FontFamily> fontFiles = new HashMap<String, FontFamily>();
|
||||
|
||||
|
||||
/**
|
||||
* Register font file.
|
||||
*
|
||||
* @param path resource path (res/fonts/...)
|
||||
* @param name font name (for binding)
|
||||
* @param style font style in this file
|
||||
*/
|
||||
public static void registerFile(String path, String name, Style style)
|
||||
{
|
||||
if (fontFiles.containsKey(name)) {
|
||||
if (fontFiles.get(name) != null) {
|
||||
fontFiles.get(name).put(style, path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// insert new table of styles to font name.
|
||||
FontFamily family = new FontFamily();
|
||||
family.put(style, path);
|
||||
fontFiles.put(name, family);
|
||||
}
|
||||
|
||||
/** Counter of loaded fonts */
|
||||
public static int loadedFontCounter = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Preload font if needed, get preloaded font.<br>
|
||||
* If needed file is not available, throws runtime exception.
|
||||
*
|
||||
* @param name font name (registerFile)
|
||||
* @param size font size (pt)
|
||||
* @param style font style
|
||||
* @param glyphs glyphs needed
|
||||
* @return the loaded font.
|
||||
*/
|
||||
public static LoadedFont loadFont(String name, double size, Style style, String glyphs)
|
||||
{
|
||||
return loadFont(name, size, style, glyphs, 9, 8, Coord.ONE, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Preload font if needed, get preloaded font.<br>
|
||||
* If needed file is not available, throws runtime exception.
|
||||
*
|
||||
* @param name font name (registerFile)
|
||||
* @param size font size (pt)
|
||||
* @param style font style
|
||||
* @param glyphs glyphs needed
|
||||
* @param correctLeft left horizontal correction
|
||||
* @param correctRight right horizontal correction
|
||||
* @param scale font scale (changing aspect ratio)
|
||||
* @param clipTop top clip (0-1) - top part of the font to be cut off
|
||||
* @param clipBottom bottom clip (0-1) - bottom part of the font to be cut
|
||||
* off
|
||||
* @return the loaded font.
|
||||
*/
|
||||
public static LoadedFont loadFont(String name, double size, Style style, String glyphs, int correctLeft, int correctRight, Coord scale, double clipTop, double clipBottom)
|
||||
{
|
||||
String resourcePath;
|
||||
try {
|
||||
resourcePath = fontFiles.get(name).get(style);
|
||||
if (resourcePath == null) {
|
||||
Log.w("Font [" + name + "] does not have variant " + style + ".\nUsing NORMAL instead.");
|
||||
resourcePath = fontFiles.get(name).get(Style.NORMAL);
|
||||
if (resourcePath == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException npe) {
|
||||
throw new RuntimeException("Font loading failed: no font file registered for name \"" + name + "\".");
|
||||
}
|
||||
|
||||
InputStream in = ResourceLoader.getResourceAsStream(resourcePath);
|
||||
|
||||
Font awtFont;
|
||||
try {
|
||||
awtFont = Font.createFont(Font.TRUETYPE_FONT, in);
|
||||
} catch (Exception e) {
|
||||
Log.e("Loading of font " + resourcePath + " failed.", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
awtFont = awtFont.deriveFont((float) size); // set font size
|
||||
LoadedFont font = new LoadedFont(awtFont, true, glyphs);
|
||||
|
||||
font.setCorrection(correctLeft, correctRight);
|
||||
font.setClip(clipTop, clipBottom);
|
||||
font.setScale(scale.x, scale.y);
|
||||
|
||||
loadedFontCounter++;
|
||||
|
||||
if (DEBUG) Log.f3("Font from file \"" + resourcePath + "\" preloaded.");
|
||||
|
||||
return font;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package mightypork.rogue.fonts;
|
||||
|
||||
|
||||
import static mightypork.rogue.fonts.FontManager.Style.*;
|
||||
import mightypork.rogue.fonts.FontManager.Glyphs;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Global font preloader
|
||||
*
|
||||
* @author Rapus
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public class Fonts {
|
||||
|
||||
public static LoadedFont splash_info;
|
||||
|
||||
public static LoadedFont tooltip;
|
||||
public static LoadedFont gui;
|
||||
public static LoadedFont gui_title;
|
||||
public static LoadedFont program_number;
|
||||
public static LoadedFont menu_button;
|
||||
public static LoadedFont menu_title;
|
||||
public static LoadedFont tiny;
|
||||
|
||||
|
||||
private static void registerFileNames()
|
||||
{
|
||||
FontManager.registerFile("res/fonts/4feb.ttf", "4feb", NORMAL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load fonts needed for splash.
|
||||
*/
|
||||
public static void loadForSplash()
|
||||
{
|
||||
registerFileNames();
|
||||
|
||||
gui = FontManager.loadFont("4feb", 24, NORMAL, Glyphs.basic).setCorrection(8, 7);
|
||||
splash_info = FontManager.loadFont("4feb", 42, NORMAL, "Loading.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Preload all fonts we will use in the game
|
||||
*/
|
||||
public static void load()
|
||||
{
|
||||
tooltip = FontManager.loadFont("4feb", 24, NORMAL, Glyphs.basic_text).setCorrection(8, 7);
|
||||
gui_title = FontManager.loadFont("4feb", 30, NORMAL, Glyphs.basic_text);
|
||||
menu_button = FontManager.loadFont("4feb", 36, NORMAL, Glyphs.basic_text);
|
||||
menu_title = FontManager.loadFont("4feb", 34, NORMAL, Glyphs.basic_text);
|
||||
program_number = FontManager.loadFont("4feb", 28, NORMAL, Glyphs.numbers);
|
||||
tiny = FontManager.loadFont("4feb", 20, NORMAL, Glyphs.basic_text);
|
||||
|
||||
Log.i("Fonts loaded = " + FontManager.loadedFontCounter);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,665 @@
|
||||
package mightypork.rogue.fonts;
|
||||
|
||||
|
||||
import static mightypork.rogue.fonts.Align.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.rogue.Config;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.color.RGB;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.CoordI;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.util.glu.GLU;
|
||||
|
||||
|
||||
/**
|
||||
* A TrueType font implementation originally for Slick, edited for Bobjob's
|
||||
* Engine
|
||||
*
|
||||
* @original author James Chambers (Jimmy)
|
||||
* @original author Jeremy Adams (elias4444)
|
||||
* @original author Kevin Glass (kevglass)
|
||||
* @original author Peter Korzuszek (genail)
|
||||
* @new version edited by David Aaron Muhar (bobjob)
|
||||
* @new version edited by MightyPork
|
||||
*/
|
||||
public class LoadedFont {
|
||||
|
||||
private static final boolean DEBUG = Config.LOG_FONTS;
|
||||
|
||||
/** Map of user defined font characters (Character <-> IntObject) */
|
||||
private Map<Character, CharStorageEntry> chars = new HashMap<Character, CharStorageEntry>(100);
|
||||
|
||||
/** Boolean flag on whether AntiAliasing is enabled or not */
|
||||
private boolean antiAlias;
|
||||
|
||||
/** Font's size */
|
||||
private int fontSize = 0;
|
||||
|
||||
/** Font's height */
|
||||
private int fontHeight = 0;
|
||||
|
||||
/** Texture used to cache the font 0-255 characters */
|
||||
private int fontTextureID;
|
||||
|
||||
/** Default font texture width */
|
||||
private int textureWidth = 2048;
|
||||
|
||||
/** Default font texture height */
|
||||
private int textureHeight = 2048;
|
||||
|
||||
/** A reference to Java's AWT Font that we create our font texture from */
|
||||
private Font font;
|
||||
|
||||
/** The font metrics for our Java AWT font */
|
||||
private FontMetrics fontMetrics;
|
||||
|
||||
private int correctL = 9, correctR = 8;
|
||||
|
||||
private double defScaleX = 1, defScaleY = 1;
|
||||
private double clipVerticalT = 0;
|
||||
private double clipVerticalB = 0;
|
||||
|
||||
private class CharStorageEntry {
|
||||
|
||||
/** Character's width */
|
||||
public int width;
|
||||
|
||||
/** Character's height */
|
||||
public int height;
|
||||
|
||||
/** Character's stored x position */
|
||||
public int texPosX;
|
||||
|
||||
/** Character's stored y position */
|
||||
public int texPosY;
|
||||
}
|
||||
|
||||
|
||||
public LoadedFont(Font font, boolean antiAlias, String charsNeeded) {
|
||||
this.font = font;
|
||||
this.fontSize = font.getSize() + 3;
|
||||
this.antiAlias = antiAlias;
|
||||
|
||||
createSet(charsNeeded.toCharArray());
|
||||
|
||||
fontHeight -= 1;
|
||||
if (fontHeight <= 0) fontHeight = 1;
|
||||
}
|
||||
|
||||
|
||||
public void setCorrection(boolean on)
|
||||
{
|
||||
if (on) {
|
||||
correctL = 9;//2
|
||||
correctR = 8;//1
|
||||
} else {
|
||||
correctL = 0;
|
||||
correctR = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private BufferedImage getFontImage(char ch)
|
||||
{
|
||||
// Create a temporary image to extract the character's size
|
||||
BufferedImage tempfontImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) tempfontImage.getGraphics();
|
||||
if (antiAlias == true) {
|
||||
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
}
|
||||
g.setFont(font);
|
||||
fontMetrics = g.getFontMetrics();
|
||||
int charwidth = fontMetrics.charWidth(ch) + 8;
|
||||
|
||||
if (charwidth <= 0) {
|
||||
charwidth = 7;
|
||||
}
|
||||
int charheight = fontMetrics.getHeight() + 3;
|
||||
if (charheight <= 0) {
|
||||
charheight = fontSize;
|
||||
}
|
||||
|
||||
// Create another image holding the character we are creating
|
||||
BufferedImage fontImage;
|
||||
fontImage = new BufferedImage(charwidth, charheight, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D gt = (Graphics2D) fontImage.getGraphics();
|
||||
if (antiAlias == true) {
|
||||
gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
}
|
||||
gt.setFont(font);
|
||||
|
||||
gt.setColor(Color.WHITE);
|
||||
int charx = 3;
|
||||
int chary = 1;
|
||||
gt.drawString(String.valueOf(ch), (charx), (chary) + fontMetrics.getAscent());
|
||||
|
||||
return fontImage;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createSet(char[] charsToLoad)
|
||||
{
|
||||
try {
|
||||
class LoadedGlyph {
|
||||
|
||||
public char c;
|
||||
public BufferedImage image;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
|
||||
public LoadedGlyph(char c, BufferedImage image) {
|
||||
this.image = image;
|
||||
this.c = c;
|
||||
this.width = image.getWidth();
|
||||
this.height = image.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
List<LoadedGlyph> glyphs = new ArrayList<LoadedGlyph>();
|
||||
List<Character> loaded = new ArrayList<Character>();
|
||||
for (char ch : charsToLoad) {
|
||||
if (!loaded.contains(ch)) {
|
||||
glyphs.add(new LoadedGlyph(ch, getFontImage(ch)));
|
||||
loaded.add(ch);
|
||||
}
|
||||
}
|
||||
|
||||
Coord canvas = new Coord(128, 128);
|
||||
double lineHeight = 0;
|
||||
Coord begin = new Coord(0, 0);
|
||||
boolean needsLarger = false;
|
||||
|
||||
while (true) {
|
||||
needsLarger = false;
|
||||
|
||||
for (LoadedGlyph glyph : glyphs) {
|
||||
if (begin.x + glyph.width > canvas.x) {
|
||||
begin.y += lineHeight;
|
||||
lineHeight = 0;
|
||||
begin.x = 0;
|
||||
}
|
||||
|
||||
if (lineHeight < glyph.height) {
|
||||
lineHeight = glyph.height;
|
||||
}
|
||||
|
||||
if (begin.y + lineHeight > canvas.y) {
|
||||
needsLarger = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// draw.
|
||||
begin.x += glyph.width;
|
||||
}
|
||||
|
||||
if (needsLarger) {
|
||||
canvas.x *= 2;
|
||||
canvas.y *= 2;
|
||||
begin.setTo(0, 0);
|
||||
lineHeight = 0;
|
||||
} else {
|
||||
if (DEBUG) Log.f3("Preparing texture " + canvas.x + "x" + canvas.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
textureWidth = (int) canvas.x;
|
||||
textureHeight = (int) canvas.y;
|
||||
|
||||
BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) imgTemp.getGraphics();
|
||||
|
||||
g.setColor(new Color(0, 0, 0, 1));
|
||||
g.fillRect(0, 0, textureWidth, textureHeight);
|
||||
|
||||
int rowHeight = 0;
|
||||
int positionX = 0;
|
||||
int positionY = 0;
|
||||
|
||||
for (LoadedGlyph glyph : glyphs) {
|
||||
CharStorageEntry storedChar = new CharStorageEntry();
|
||||
|
||||
storedChar.width = glyph.width;
|
||||
storedChar.height = glyph.height;
|
||||
|
||||
if (positionX + storedChar.width >= textureWidth) {
|
||||
positionX = 0;
|
||||
positionY += rowHeight;
|
||||
rowHeight = 0;
|
||||
}
|
||||
|
||||
storedChar.texPosX = positionX;
|
||||
storedChar.texPosY = positionY;
|
||||
|
||||
if (storedChar.height > fontHeight) {
|
||||
fontHeight = storedChar.height;
|
||||
}
|
||||
|
||||
if (storedChar.height > rowHeight) {
|
||||
rowHeight = storedChar.height;
|
||||
}
|
||||
|
||||
// Draw it here
|
||||
g.drawImage(glyph.image, positionX, positionY, null);
|
||||
|
||||
positionX += storedChar.width;
|
||||
|
||||
chars.put(glyph.c, storedChar);
|
||||
}
|
||||
|
||||
fontTextureID = loadImage(imgTemp);
|
||||
|
||||
imgTemp = null;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to create font.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void drawQuad(double drawX, double drawY, double drawX2, double drawY2, CharStorageEntry charObj)
|
||||
{
|
||||
double srcX = charObj.texPosX + charObj.width;
|
||||
double srcY = charObj.texPosY + charObj.height;
|
||||
double srcX2 = charObj.texPosX;
|
||||
double srcY2 = charObj.texPosY;
|
||||
double DrawWidth = drawX2 - drawX;
|
||||
double DrawHeight = drawY2 - drawY;
|
||||
double TextureSrcX = srcX / textureWidth;
|
||||
double TextureSrcY = srcY / textureHeight;
|
||||
double SrcWidth = srcX2 - srcX;
|
||||
double SrcHeight = srcY2 - srcY;
|
||||
double RenderWidth = (SrcWidth / textureWidth);
|
||||
double RenderHeight = (SrcHeight / textureHeight);
|
||||
|
||||
drawY -= DrawHeight * clipVerticalB;
|
||||
|
||||
GL11.glTexCoord2d(TextureSrcX, TextureSrcY);
|
||||
GL11.glVertex2d(drawX, drawY);
|
||||
GL11.glTexCoord2d(TextureSrcX, TextureSrcY + RenderHeight);
|
||||
GL11.glVertex2d(drawX, drawY + DrawHeight);
|
||||
GL11.glTexCoord2d(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
|
||||
GL11.glVertex2d(drawX + DrawWidth, drawY + DrawHeight);
|
||||
GL11.glTexCoord2d(TextureSrcX + RenderWidth, TextureSrcY);
|
||||
GL11.glVertex2d(drawX + DrawWidth, drawY);
|
||||
}
|
||||
|
||||
|
||||
public int getWidth(String whatchars)
|
||||
{
|
||||
if (whatchars == null) whatchars = "";
|
||||
int totalwidth = 0;
|
||||
CharStorageEntry charStorage = null;
|
||||
char currentChar = 0;
|
||||
for (int i = 0; i < whatchars.length(); i++) {
|
||||
currentChar = whatchars.charAt(i);
|
||||
|
||||
charStorage = chars.get(currentChar);
|
||||
|
||||
if (charStorage != null) {
|
||||
totalwidth += charStorage.width - correctL;
|
||||
}
|
||||
}
|
||||
return (int) (totalwidth * defScaleX);
|
||||
}
|
||||
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
return (int) (fontHeight * defScaleY * (1 - clipVerticalT - clipVerticalB));
|
||||
}
|
||||
|
||||
|
||||
public int getLineHeight()
|
||||
{
|
||||
return getHeight();
|
||||
}
|
||||
|
||||
|
||||
public void drawString(double x, double y, String text, double scaleX, double scaleY, RGB color)
|
||||
{
|
||||
drawString(x, y, text, 0, text.length() - 1, scaleX, scaleY, color, LEFT);
|
||||
}
|
||||
|
||||
|
||||
public void drawString(double x, double y, String text, double scaleX, double scaleY, RGB color, int align)
|
||||
{
|
||||
drawString(x, y, text, 0, text.length() - 1, scaleX, scaleY, color, align);
|
||||
}
|
||||
|
||||
|
||||
private void drawString(double x, double y, String text, int startIndex, int endIndex, double scaleX, double scaleY, RGB color, int align)
|
||||
{
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
|
||||
scaleX *= defScaleX;
|
||||
scaleY *= defScaleY;
|
||||
|
||||
CharStorageEntry charStorage = null;
|
||||
int charCurrent;
|
||||
|
||||
int totalwidth = 0;
|
||||
int i = startIndex, d = 1, c = correctL;
|
||||
float startY = 0;
|
||||
|
||||
switch (align) {
|
||||
case RIGHT: {
|
||||
d = -1;
|
||||
c = correctR;
|
||||
|
||||
while (i < endIndex) {
|
||||
if (text.charAt(i) == '\n') startY -= getHeight();
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CENTER: {
|
||||
for (int l = startIndex; l <= endIndex; l++) {
|
||||
charCurrent = text.charAt(l);
|
||||
if (charCurrent == '\n') break;
|
||||
|
||||
charStorage = chars.get((char) charCurrent);
|
||||
if (charStorage != null) {
|
||||
totalwidth += charStorage.width - correctL;
|
||||
}
|
||||
}
|
||||
totalwidth /= -2;
|
||||
break;
|
||||
}
|
||||
case LEFT:
|
||||
default: {
|
||||
d = 1;
|
||||
c = correctL;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GL11.glPushAttrib(GL_ENABLE_BIT);
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID);
|
||||
GL11.glColor4d(color.r, color.g, color.b, color.a);
|
||||
GL11.glBegin(GL11.GL_QUADS);
|
||||
|
||||
while (i >= startIndex && i <= endIndex) {
|
||||
charCurrent = text.charAt(i);
|
||||
|
||||
charStorage = chars.get(new Character((char) charCurrent));
|
||||
|
||||
if (charStorage != null) {
|
||||
if (d < 0) totalwidth += (charStorage.width - c) * d;
|
||||
if (charCurrent == '\n') {
|
||||
startY -= getHeight() * d;
|
||||
totalwidth = 0;
|
||||
if (align == CENTER) {
|
||||
for (int l = i + 1; l <= endIndex; l++) {
|
||||
charCurrent = text.charAt(l);
|
||||
if (charCurrent == '\n') break;
|
||||
|
||||
charStorage = chars.get((char) charCurrent);
|
||||
|
||||
totalwidth += charStorage.width - correctL;
|
||||
}
|
||||
totalwidth /= -2;
|
||||
}
|
||||
//if center get next lines total width/2;
|
||||
} else {
|
||||
//@formatter:off
|
||||
drawQuad(
|
||||
(totalwidth + charStorage.width) * scaleX + x,
|
||||
startY * scaleY + y, totalwidth * scaleX + x,
|
||||
(startY + charStorage.height) * scaleY + y,
|
||||
charStorage
|
||||
);
|
||||
//@formatter:on
|
||||
|
||||
if (d > 0) totalwidth += (charStorage.width - c) * d;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
i += d;
|
||||
}
|
||||
GL11.glEnd();
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
public static int loadImage(BufferedImage bufferedImage)
|
||||
{
|
||||
try {
|
||||
short width = (short) bufferedImage.getWidth();
|
||||
short height = (short) bufferedImage.getHeight();
|
||||
//textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ? (byte)32 : (byte)24;
|
||||
int bpp = (byte) bufferedImage.getColorModel().getPixelSize();
|
||||
ByteBuffer byteBuffer;
|
||||
DataBuffer db = bufferedImage.getData().getDataBuffer();
|
||||
if (db instanceof DataBufferInt) {
|
||||
int intI[] = ((DataBufferInt) (bufferedImage.getData().getDataBuffer())).getData();
|
||||
byte newI[] = new byte[intI.length * 4];
|
||||
for (int i = 0; i < intI.length; i++) {
|
||||
byte b[] = intToByteArray(intI[i]);
|
||||
int newIndex = i * 4;
|
||||
|
||||
newI[newIndex] = b[1];
|
||||
newI[newIndex + 1] = b[2];
|
||||
newI[newIndex + 2] = b[3];
|
||||
newI[newIndex + 3] = b[0];
|
||||
}
|
||||
|
||||
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(newI);
|
||||
} else {
|
||||
byteBuffer = ByteBuffer.allocateDirect(width * height * (bpp / 8)).order(ByteOrder.nativeOrder()).put(((DataBufferByte) (bufferedImage.getData().getDataBuffer())).getData());
|
||||
}
|
||||
byteBuffer.flip();
|
||||
|
||||
int internalFormat = GL11.GL_RGBA8, format = GL11.GL_RGBA;
|
||||
IntBuffer textureId = BufferUtils.createIntBuffer(1);
|
||||
|
||||
GL11.glGenTextures(textureId);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0));
|
||||
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
|
||||
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
|
||||
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
|
||||
|
||||
GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
|
||||
|
||||
GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, internalFormat, width, height, format, GL11.GL_UNSIGNED_BYTE, byteBuffer);
|
||||
return textureId.get(0);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public static boolean isSupported(String fontname)
|
||||
{
|
||||
Font font[] = getFonts();
|
||||
for (int i = font.length - 1; i >= 0; i--) {
|
||||
if (font[i].getName().equalsIgnoreCase(fontname)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static Font[] getFonts()
|
||||
{
|
||||
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
|
||||
}
|
||||
|
||||
|
||||
public static Font getFont(String fontname, int style, float size)
|
||||
{
|
||||
Font result = null;
|
||||
GraphicsEnvironment graphicsenvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
for (Font font : graphicsenvironment.getAllFonts()) {
|
||||
if (font.getName().equalsIgnoreCase(fontname)) {
|
||||
result = font.deriveFont(style, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static byte[] intToByteArray(int value)
|
||||
{
|
||||
return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), (byte) value };
|
||||
}
|
||||
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
IntBuffer scratch = BufferUtils.createIntBuffer(1);
|
||||
scratch.put(0, fontTextureID);
|
||||
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
|
||||
GL11.glDeleteTextures(scratch);
|
||||
}
|
||||
|
||||
|
||||
public LoadedFont setScale(double x, double y)
|
||||
{
|
||||
defScaleX = x;
|
||||
defScaleY = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public LoadedFont setClip(double clipRatioTop, double clipRatioBottom)
|
||||
{
|
||||
clipVerticalT = clipRatioTop;
|
||||
clipVerticalB = clipRatioBottom;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public LoadedFont setCorrection(int correctionLeft, int correctionRight)
|
||||
{
|
||||
correctL = correctionLeft;
|
||||
correctR = correctionRight;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw string with font.
|
||||
*
|
||||
* @param x x coord
|
||||
* @param y y coord
|
||||
* @param text text to draw
|
||||
* @param color render color
|
||||
* @param align (-1,0,1)
|
||||
*/
|
||||
public void draw(double x, double y, String text, RGB color, int align)
|
||||
{
|
||||
drawString(x, y, text, 1, 1, color, align);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw string with font.
|
||||
*
|
||||
* @param pos coord
|
||||
* @param text text to draw
|
||||
* @param color render color
|
||||
* @param align (-1,0,1)
|
||||
*/
|
||||
public void draw(Coord pos, String text, RGB color, int align)
|
||||
{
|
||||
drawString(pos.x, pos.y, text, 1, 1, color, align);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw string with font.
|
||||
*
|
||||
* @param pos coord
|
||||
* @param text text to draw
|
||||
* @param color render color
|
||||
* @param align (-1,0,1)
|
||||
*/
|
||||
public void draw(CoordI pos, String text, RGB color, int align)
|
||||
{
|
||||
drawString(pos.x, pos.y, text, 1, 1, color, align);
|
||||
}
|
||||
|
||||
|
||||
public void drawFuzzy(Coord pos, String text, int align, RGB textColor, RGB blurColor, int blurSize)
|
||||
{
|
||||
drawFuzzy(pos, text, align, textColor, blurColor, blurSize, true);
|
||||
}
|
||||
|
||||
|
||||
public void drawFuzzy(CoordI pos, String text, int align, RGB textColor, RGB blurColor, int blurSize)
|
||||
{
|
||||
drawFuzzy(pos.toCoord(), text, align, textColor, blurColor, blurSize, true);
|
||||
}
|
||||
|
||||
|
||||
public void drawFuzzy(CoordI pos, String text, int align, RGB textColor, RGB blurColor, int blurSize, boolean smooth)
|
||||
{
|
||||
drawFuzzy(pos.toCoord(), text, align, textColor, blurColor, blurSize, smooth);
|
||||
}
|
||||
|
||||
|
||||
public void drawFuzzy(Coord pos, String text, int align, RGB textColor, RGB blurColor, int blurSize, boolean smooth)
|
||||
{
|
||||
glPushMatrix();
|
||||
|
||||
glTranslated(pos.x, pos.y, pos.z);
|
||||
|
||||
//shadow
|
||||
int sh = blurSize;
|
||||
|
||||
int l = glGenLists(1);
|
||||
|
||||
glNewList(l, GL_COMPILE);
|
||||
draw(0, 0, text, blurColor, align);
|
||||
glEndList();
|
||||
|
||||
for (int xx = -sh; xx <= sh; xx += (smooth ? 1 : sh)) {
|
||||
for (int yy = -sh; yy <= sh; yy += (smooth ? 1 : sh)) {
|
||||
if (xx == 0 && yy == 0) continue;
|
||||
glPushMatrix();
|
||||
glTranslated(xx, yy, 0);
|
||||
glCallList(l);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
glDeleteLists(l, 1);
|
||||
|
||||
draw(0, 0, text, textColor, align);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Vec;
|
||||
|
||||
|
||||
/**
|
||||
* Input event handler
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface InputHandler {
|
||||
|
||||
/**
|
||||
* Called each update tick, if the mouse position was changed.
|
||||
*
|
||||
* @param pos mouse position
|
||||
* @param move mouse motion
|
||||
* @param wheelDelta mouse wheel delta
|
||||
*/
|
||||
public void onMouseMove(Coord pos, Vec move, int wheelDelta);
|
||||
|
||||
|
||||
/**
|
||||
* Mouse event handler.
|
||||
*
|
||||
* @param button button which caused this event
|
||||
* @param down true = down, false = up
|
||||
* @param wheelDelta number of steps the wheel turned since last event
|
||||
* @param pos mouse position
|
||||
* @param deltaPos delta mouse position
|
||||
*/
|
||||
public void onMouseButton(int button, boolean down, int wheelDelta, Coord pos, Coord deltaPos);
|
||||
|
||||
|
||||
/**
|
||||
* Key event handler.
|
||||
*
|
||||
* @param key key index, constant Keyboard.KEY_???
|
||||
* @param c character typed, if any
|
||||
* @param down true = down, false = up
|
||||
*/
|
||||
public void onKey(int key, char c, boolean down);
|
||||
|
||||
|
||||
/**
|
||||
* In this method screen can handle static inputs, that is:
|
||||
* Keyboard.isKeyDown, Mouse.isButtonDown etc.
|
||||
*/
|
||||
public void handleKeyStates();
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package mightypork.rogue.input;
|
||||
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
/**
|
||||
* Key state handler
|
||||
*/
|
||||
public class Keys {
|
||||
|
||||
private static boolean[] prevKeys;
|
||||
private static boolean[] keys;
|
||||
|
||||
|
||||
/**
|
||||
* initialize key state handler
|
||||
*/
|
||||
private static void init()
|
||||
{
|
||||
|
||||
if (keys == null) {
|
||||
keys = new boolean[Keyboard.KEYBOARD_SIZE];
|
||||
}
|
||||
|
||||
if (prevKeys == null) {
|
||||
prevKeys = new boolean[Keyboard.KEYBOARD_SIZE];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* method called when key event was detected in Screen class.
|
||||
*
|
||||
* @param key
|
||||
* @param down
|
||||
*/
|
||||
public static void onKey(int key, boolean down)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
prevKeys[key] = keys[key];
|
||||
keys[key] = down;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key is down
|
||||
*
|
||||
* @param key key index
|
||||
* @return is down
|
||||
*/
|
||||
public static boolean isDown(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key is up
|
||||
*
|
||||
* @param key key index
|
||||
* @return is up
|
||||
*/
|
||||
public static boolean isUp(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return !keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key was just pressed (changed state since last event on this
|
||||
* key)
|
||||
*
|
||||
* @param key key index
|
||||
* @return true if changed state to DOWN
|
||||
*/
|
||||
public static boolean justPressed(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return !prevKeys[key] && keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if key was just released (changed state since last event on this
|
||||
* key)
|
||||
*
|
||||
* @param key key index
|
||||
* @return true if changed state to UP
|
||||
*/
|
||||
public static boolean justReleased(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
return prevKeys[key] && !keys[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy "just" flag for a key.
|
||||
*
|
||||
* @param key key index
|
||||
*/
|
||||
public static void destroyChangeState(int key)
|
||||
{
|
||||
|
||||
init();
|
||||
|
||||
prevKeys[key] = keys[key];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package mightypork.rogue.screens;
|
||||
|
||||
|
||||
import mightypork.rogue.Screen;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Vec;
|
||||
|
||||
|
||||
public class ScreenSplash extends Screen {
|
||||
|
||||
@Override
|
||||
protected void onViewportChanged()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void initScreen()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onGuiUpdate()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void render3D()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onKey(int key, char c, boolean down)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMouseButton(int button, boolean down, int wheeld, Coord pos, Coord delta)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleKeyStates()
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMouseMove(Coord coord, Vec vec, int wd)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void render2D(double delta)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.objects.Mutable;
|
||||
|
||||
|
||||
public abstract class AudioPlayer {
|
||||
|
||||
/** base gain for sfx */
|
||||
private double baseGain = 1;
|
||||
|
||||
/** the track */
|
||||
private AudioX track;
|
||||
|
||||
/** base pitch for sfx */
|
||||
private double basePitch = 1;
|
||||
|
||||
/** dedicated volume control */
|
||||
private Mutable<Float> gainMultiplier = null;
|
||||
|
||||
|
||||
public AudioPlayer(AudioX track, double baseGain, Mutable<Float> gainMultiplier) {
|
||||
this(track, 1, baseGain, gainMultiplier);
|
||||
}
|
||||
|
||||
|
||||
public AudioPlayer(AudioX track, double basePitch, double baseGain, Mutable<Float> gainMultiplier) {
|
||||
this.track = track;
|
||||
|
||||
this.baseGain = baseGain;
|
||||
this.basePitch = basePitch;
|
||||
|
||||
this.gainMultiplier = gainMultiplier;
|
||||
}
|
||||
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
track.release();
|
||||
track = null;
|
||||
}
|
||||
|
||||
|
||||
protected AudioX getAudio()
|
||||
{
|
||||
return track;
|
||||
}
|
||||
|
||||
|
||||
protected float getGain(double multiplier)
|
||||
{
|
||||
return (float) (baseGain * gainMultiplier.get() * multiplier);
|
||||
}
|
||||
|
||||
|
||||
protected float getPitch(double multiplier)
|
||||
{
|
||||
return (float) (basePitch * multiplier);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get if audio is valid
|
||||
*
|
||||
* @return is valid
|
||||
*/
|
||||
protected boolean canPlay()
|
||||
{
|
||||
return (track != null);
|
||||
}
|
||||
|
||||
|
||||
public void load()
|
||||
{
|
||||
if (canPlay()) track.load();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.files.FileUtils;
|
||||
import mightypork.utils.logging.Log;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
|
||||
import org.newdawn.slick.openal.Audio;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper class for slick audio
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class AudioX implements Audio {
|
||||
|
||||
private enum PlayMode
|
||||
{
|
||||
EFFECT, MUSIC;
|
||||
};
|
||||
|
||||
private Audio audio = null;
|
||||
private float pauseLoopPosition = 0;
|
||||
private boolean looping = false;
|
||||
private boolean paused = false;
|
||||
private PlayMode mode = PlayMode.EFFECT;
|
||||
private float pitch = 1;
|
||||
private float gain = 1;
|
||||
|
||||
private String resourcePath;
|
||||
|
||||
|
||||
/**
|
||||
* Pause loop (remember position and stop playing) - if was looping
|
||||
*/
|
||||
public void pauseLoop()
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
if (isPlaying() && looping) {
|
||||
pauseLoopPosition = audio.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 = audio.playAsMusic(pitch, gain, true);
|
||||
} else {
|
||||
source = audio.playAsSoundEffect(pitch, gain, true);
|
||||
}
|
||||
audio.setPosition(pauseLoopPosition);
|
||||
paused = false;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create deferred primitive audio player
|
||||
*
|
||||
* @param resourceName resource to load when needed
|
||||
*/
|
||||
public AudioX(String resourceName) {
|
||||
this.audio = null;
|
||||
this.resourcePath = resourceName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if can play, if not, try to load sound.
|
||||
*
|
||||
* @return can now play
|
||||
*/
|
||||
private boolean ensureLoaded()
|
||||
{
|
||||
load();
|
||||
|
||||
return audio != null;
|
||||
}
|
||||
|
||||
|
||||
public void load()
|
||||
{
|
||||
if (audio != null) return; // already loaded
|
||||
if (resourcePath == null) return; // not loaded, but can't load anyway
|
||||
|
||||
try {
|
||||
String ext = FileUtils.getExtension(resourcePath);
|
||||
|
||||
// java 6 can't use String switch :(
|
||||
if (ext.equalsIgnoreCase("ogg")) {
|
||||
audio = SoundStore.get().getOgg(resourcePath);
|
||||
} else if (ext.equalsIgnoreCase("wav")) {
|
||||
audio = SoundStore.get().getWAV(resourcePath);
|
||||
} else if (ext.equalsIgnoreCase("aif")) {
|
||||
audio = SoundStore.get().getAIF(resourcePath);
|
||||
} else if (ext.equalsIgnoreCase("mod")) {
|
||||
audio = SoundStore.get().getMOD(resourcePath);
|
||||
} else {
|
||||
resourcePath = null; // don't try next time
|
||||
Log.e("Invalid audio file extension: " + resourcePath);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("Could not load " + resourcePath, e);
|
||||
resourcePath = null; // don't try next time
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
if (!ensureLoaded()) return;
|
||||
|
||||
audio.stop();
|
||||
paused = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getBufferID()
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
return audio.getBufferID();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPlaying()
|
||||
{
|
||||
if (!ensureLoaded()) return false;
|
||||
|
||||
return audio.isPlaying();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPaused()
|
||||
{
|
||||
if (!ensureLoaded()) return false;
|
||||
|
||||
return audio.isPaused();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int playAsSoundEffect(float pitch, float gain, boolean loop)
|
||||
{
|
||||
return playAsSoundEffect(pitch, gain, loop, SoundManager.get().listener);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int playAsSoundEffect(float pitch, float gain, boolean loop, float x, float y, float z)
|
||||
{
|
||||
if (!ensureLoaded()) return -1;
|
||||
|
||||
this.pitch = pitch;
|
||||
this.gain = gain;
|
||||
looping = loop;
|
||||
mode = PlayMode.EFFECT;
|
||||
return audio.playAsSoundEffect(pitch, gain, loop, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Play this sound as a sound effect
|
||||
*
|
||||
* @param pitch The pitch of the play back
|
||||
* @param gain The gain of the play back
|
||||
* @param loop True if we should loop
|
||||
* @param pos The position of the sound
|
||||
* @return The ID of the source playing the sound
|
||||
*/
|
||||
public int playAsSoundEffect(float pitch, float gain, boolean loop, Coord pos)
|
||||
{
|
||||
return playAsSoundEffect(pitch, gain, loop, (float) pos.x, (float) pos.y, (float) pos.z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int playAsMusic(float pitch, float gain, boolean loop)
|
||||
{
|
||||
this.pitch = pitch;
|
||||
this.gain = gain;
|
||||
looping = loop;
|
||||
mode = PlayMode.MUSIC;
|
||||
return audio.playAsMusic(pitch, gain, loop);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setPosition(float position)
|
||||
{
|
||||
return audio.setPosition(position);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float getPosition()
|
||||
{
|
||||
return audio.getPosition();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void release()
|
||||
{
|
||||
audio.release();
|
||||
audio = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.objects.Mutable;
|
||||
|
||||
|
||||
public class EffectPlayer extends AudioPlayer {
|
||||
|
||||
public EffectPlayer(AudioX track, double basePitch, double baseGain, Mutable<Float> gainMultiplier) {
|
||||
super(track, (float) basePitch, (float) baseGain, gainMultiplier);
|
||||
}
|
||||
|
||||
|
||||
public int play(double pitch, double gain)
|
||||
{
|
||||
if (!canPlay()) return -1;
|
||||
|
||||
return getAudio().playAsSoundEffect(getPitch(pitch), getGain(gain), false);
|
||||
}
|
||||
|
||||
|
||||
public int play(double gain)
|
||||
{
|
||||
return play(1, gain);
|
||||
}
|
||||
|
||||
|
||||
public int play(double pitch, double gain, Coord pos)
|
||||
{
|
||||
if (!canPlay()) return -1;
|
||||
|
||||
return getAudio().playAsSoundEffect(getPitch(pitch), getGain(gain), false, pos);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.math.Calc;
|
||||
import mightypork.utils.objects.Mutable;
|
||||
|
||||
|
||||
/**
|
||||
* Volume multiplex
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class JointVolume extends Mutable<Float> {
|
||||
|
||||
private Mutable<Float>[] volumes;
|
||||
|
||||
|
||||
/**
|
||||
* CReate joint volume with master gain of 1
|
||||
*
|
||||
* @param volumes individual volumes to join
|
||||
*/
|
||||
public JointVolume(Mutable<Float>... volumes) {
|
||||
super(1F);
|
||||
this.volumes = volumes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get combined gain (multiplied)
|
||||
*/
|
||||
@Override
|
||||
public Float get()
|
||||
{
|
||||
float f = super.get();
|
||||
for (Mutable<Float> v : volumes)
|
||||
f *= v.get();
|
||||
|
||||
return Calc.clampf(f, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set master gain
|
||||
*/
|
||||
@Override
|
||||
public void set(Float o)
|
||||
{
|
||||
super.set(o);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import mightypork.utils.objects.Mutable;
|
||||
import mightypork.utils.time.AnimDouble;
|
||||
import mightypork.utils.time.Pauseable;
|
||||
import mightypork.utils.time.Updateable;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
|
||||
|
||||
public class LoopPlayer extends AudioPlayer implements Updateable, Pauseable {
|
||||
|
||||
private int sourceID = -1;
|
||||
|
||||
/** animator for fade in and fade out */
|
||||
private AnimDouble fadeAnim = new AnimDouble(0);
|
||||
|
||||
private double lastUpdateGain = 0;
|
||||
|
||||
/** flag that track is paused */
|
||||
private boolean paused = true;
|
||||
|
||||
/** Default fadeIn time */
|
||||
private double inTime = 1;
|
||||
|
||||
/** Default fadeOut time */
|
||||
private double outTime = 1;
|
||||
|
||||
|
||||
public LoopPlayer(AudioX track, double pitch, double baseGain, Mutable<Float> gainMultiplier) {
|
||||
super(track, (float) pitch, (float) baseGain, gainMultiplier);
|
||||
|
||||
paused = true;
|
||||
}
|
||||
|
||||
|
||||
public void setFadeTimes(double in, double out)
|
||||
{
|
||||
inTime = in;
|
||||
outTime = out;
|
||||
}
|
||||
|
||||
|
||||
private void initLoop()
|
||||
{
|
||||
if (!canPlay() && sourceID == -1) {
|
||||
sourceID = getAudio().playAsSoundEffect(getPitch(1), getGain(1), true);
|
||||
getAudio().pauseLoop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pause()
|
||||
{
|
||||
if (!canPlay() || paused) return;
|
||||
|
||||
initLoop();
|
||||
|
||||
getAudio().pauseLoop();
|
||||
paused = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPaused()
|
||||
{
|
||||
return paused;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resume()
|
||||
{
|
||||
if (!canPlay() || paused) return;
|
||||
|
||||
initLoop();
|
||||
|
||||
sourceID = getAudio().resumeLoop();
|
||||
paused = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
if (!canPlay() || paused) return;
|
||||
|
||||
initLoop();
|
||||
|
||||
fadeAnim.update(delta);
|
||||
|
||||
double gain = getGain(fadeAnim.getCurrentValue());
|
||||
if (!paused && gain != lastUpdateGain) {
|
||||
AL10.alSourcef(sourceID, AL10.AL_GAIN, (float) gain);
|
||||
lastUpdateGain = gain;
|
||||
}
|
||||
|
||||
if (gain == 0 && !paused) pause(); // pause on zero volume
|
||||
}
|
||||
|
||||
|
||||
public void fadeIn(double secs)
|
||||
{
|
||||
if (!canPlay()) return;
|
||||
|
||||
resume();
|
||||
fadeAnim.fadeIn(secs);
|
||||
}
|
||||
|
||||
|
||||
public void fadeOut(double secs)
|
||||
{
|
||||
if (!canPlay()) return;
|
||||
|
||||
fadeAnim.fadeOut(secs);
|
||||
}
|
||||
|
||||
|
||||
public void fadeIn()
|
||||
{
|
||||
fadeIn(inTime);
|
||||
}
|
||||
|
||||
|
||||
public void fadeOut()
|
||||
{
|
||||
fadeOut(outTime);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
package mightypork.rogue.sounds;
|
||||
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import mightypork.utils.math.Calc.Buffers;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.objects.Mutable;
|
||||
import mightypork.utils.time.Updateable;
|
||||
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.newdawn.slick.openal.SoundStore;
|
||||
|
||||
|
||||
/**
|
||||
* Preloaded sounds.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class SoundManager implements Updateable {
|
||||
|
||||
private static SoundManager inst = new SoundManager();
|
||||
public Mutable<Float> masterVolume = new Mutable<Float>(1F);
|
||||
@SuppressWarnings("unchecked")
|
||||
public Mutable<Float> effectsVolume = new JointVolume(masterVolume);
|
||||
@SuppressWarnings("unchecked")
|
||||
public Mutable<Float> loopsVolume = new JointVolume(masterVolume);
|
||||
public Coord listener = new Coord(Coord.ZERO);
|
||||
private Map<String, EffectPlayer> effects = new HashMap<String, EffectPlayer>();
|
||||
private Map<String, LoopPlayer> loops = new HashMap<String, LoopPlayer>();
|
||||
|
||||
|
||||
/**
|
||||
* Singleton constructor
|
||||
*/
|
||||
private SoundManager() {
|
||||
SoundStore.get().setMaxSources(256);
|
||||
SoundStore.get().init();
|
||||
}
|
||||
|
||||
|
||||
public static SoundManager get()
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
public void addEffect(String key, String resource, float pitch, float gain)
|
||||
{
|
||||
EffectPlayer p = new EffectPlayer(new AudioX(resource), pitch, gain, effectsVolume);
|
||||
effects.put(key, p);
|
||||
}
|
||||
|
||||
|
||||
public void addLoop(String key, String resource, float pitch, float gain, double fadeIn, double fadeOut)
|
||||
{
|
||||
LoopPlayer p = new LoopPlayer(new AudioX(resource), pitch, gain, loopsVolume);
|
||||
p.setFadeTimes(fadeIn, fadeOut);
|
||||
loops.put(key, p);
|
||||
}
|
||||
|
||||
|
||||
public LoopPlayer getLoop(String key)
|
||||
{
|
||||
LoopPlayer p = loops.get(key);
|
||||
if (p == null) {
|
||||
throw new IllegalArgumentException("Requesting unknown sound loop \"" + key + "\".");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
public EffectPlayer getEffect(String key)
|
||||
{
|
||||
EffectPlayer p = effects.get(key);
|
||||
if (p == null) {
|
||||
throw new IllegalArgumentException("Requesting unknown sound effect \"" + key + "\".");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
public void fadeOutAllLoops()
|
||||
{
|
||||
for (LoopPlayer p : loops.values()) {
|
||||
p.fadeOut();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void fadeInLoop(String key)
|
||||
{
|
||||
getLoop(key).fadeIn();
|
||||
}
|
||||
|
||||
|
||||
public void fadeInLoop(String key, double seconds)
|
||||
{
|
||||
getLoop(key).fadeIn(seconds);
|
||||
}
|
||||
|
||||
|
||||
public void pauseLoop(String key)
|
||||
{
|
||||
getLoop(key).pause();
|
||||
}
|
||||
|
||||
|
||||
public void pauseAllLoops()
|
||||
{
|
||||
for (LoopPlayer p : loops.values()) {
|
||||
p.pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void resumeLoop(String key)
|
||||
{
|
||||
getLoop(key).resume();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set listener pos
|
||||
*
|
||||
* @param pos
|
||||
*/
|
||||
public void setListener(Coord pos)
|
||||
{
|
||||
listener.setTo(pos);
|
||||
FloatBuffer buf3 = Buffers.alloc(3);
|
||||
FloatBuffer buf6 = Buffers.alloc(6);
|
||||
buf3.clear();
|
||||
Buffers.fill(buf3, (float) pos.x, (float) pos.y, (float) pos.z);
|
||||
AL10.alListener(AL10.AL_POSITION, buf3);
|
||||
buf3.clear();
|
||||
Buffers.fill(buf3, 0, 0, 0);
|
||||
AL10.alListener(AL10.AL_VELOCITY, buf3);
|
||||
buf6.clear();
|
||||
Buffers.fill(buf6, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
|
||||
AL10.alListener(AL10.AL_ORIENTATION, buf6);
|
||||
buf3 = buf6 = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
for (LoopPlayer lp : loops.values()) {
|
||||
lp.update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setMasterVolume(float f)
|
||||
{
|
||||
masterVolume.set(f);
|
||||
}
|
||||
|
||||
|
||||
public void setEffectsVolume(float f)
|
||||
{
|
||||
effectsVolume.set(f);
|
||||
}
|
||||
|
||||
|
||||
public void setMusicVolume(float f)
|
||||
{
|
||||
loopsVolume.set(f);
|
||||
}
|
||||
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
SoundStore.get().clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
import org.newdawn.slick.opengl.TextureLoader;
|
||||
import org.newdawn.slick.util.ResourceLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Texture manager
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TextureManager {
|
||||
|
||||
private static Texture lastBinded = null;
|
||||
|
||||
|
||||
/**
|
||||
* Load texture
|
||||
*
|
||||
* @param resourcePath
|
||||
* @return the loaded texture
|
||||
*/
|
||||
public static Texture load(String resourcePath)
|
||||
{
|
||||
try {
|
||||
String ext = resourcePath.substring(resourcePath.length() - 4);
|
||||
|
||||
Texture texture = TextureLoader.getTexture(ext.toUpperCase(), ResourceLoader.getResourceAsStream(resourcePath));
|
||||
|
||||
if (texture != null) {
|
||||
return texture;
|
||||
}
|
||||
|
||||
Log.w("Texture " + resourcePath + " could not be loaded.");
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
Log.e("Loading of texture " + resourcePath + " failed.", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Bind texture
|
||||
*
|
||||
* @param texture the texture
|
||||
* @throws RuntimeException if not loaded yet
|
||||
*/
|
||||
public static void bind(Texture texture) throws RuntimeException
|
||||
{
|
||||
if (texture != lastBinded) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
|
||||
lastBinded = texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unbind all
|
||||
*/
|
||||
public static void unbind()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
lastBinded = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
/**
|
||||
* Texture loading class
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
// unrelevant
|
||||
public class Textures {
|
||||
|
||||
protected static Texture buttons_menu;
|
||||
protected static Texture buttons_small;
|
||||
|
||||
// patterns need raw access (are repeated)
|
||||
public static Texture steel_small_dk;
|
||||
public static Texture steel_small_lt;
|
||||
public static Texture steel_big_dk;
|
||||
public static Texture steel_big_lt;
|
||||
public static Texture steel_big_scratched;
|
||||
public static Texture steel_brushed;
|
||||
public static Texture steel_rivet_belts;
|
||||
public static Texture water;
|
||||
|
||||
// particles need direct access
|
||||
public static Texture snow;
|
||||
public static Texture leaves;
|
||||
public static Texture rain;
|
||||
public static Texture circle;
|
||||
|
||||
protected static Texture logo;
|
||||
protected static Texture widgets;
|
||||
public static Texture program;
|
||||
protected static Texture icons;
|
||||
|
||||
public static Texture map_tiles;
|
||||
public static Texture map_shading;
|
||||
|
||||
// spotted
|
||||
public static Texture turtle_blue;
|
||||
public static Texture turtle_green;
|
||||
public static Texture turtle_purple;
|
||||
public static Texture turtle_yellow;
|
||||
|
||||
// misc
|
||||
public static Texture turtle_red;
|
||||
public static Texture turtle_brown_dk;
|
||||
public static Texture turtle_brown_lt;
|
||||
public static Texture turtle_brown_orn;
|
||||
// a shadow sheet
|
||||
public static Texture turtle_shadows;
|
||||
|
||||
public static Texture food;
|
||||
public static Texture food_shadows;
|
||||
|
||||
private static final String GUI = "res/images/gui/";
|
||||
private static final String PATTERNS = "res/images/patterns/";
|
||||
private static final String PROGRAM = "res/images/program/";
|
||||
private static final String TILES = "res/images/tiles/";
|
||||
private static final String SPRITES = "res/images/sprites/";
|
||||
private static final String PARTICLES = "res/images/particles/";
|
||||
|
||||
|
||||
/**
|
||||
* Load what's needed for splash
|
||||
*/
|
||||
public static void loadForSplash()
|
||||
{
|
||||
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);
|
||||
|
||||
logo = TextureManager.load(GUI + "logo.png");
|
||||
steel_small_dk = TextureManager.load(PATTERNS + "steel.png");
|
||||
|
||||
Tx.initForSplash();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load textures
|
||||
*/
|
||||
public static void load()
|
||||
{
|
||||
// gui
|
||||
buttons_menu = TextureManager.load(GUI + "buttons_menu.png");
|
||||
buttons_small = TextureManager.load(GUI + "buttons_small.png");
|
||||
widgets = TextureManager.load(GUI + "widgets.png");
|
||||
icons = TextureManager.load(GUI + "icons.png");
|
||||
|
||||
// patterns
|
||||
|
||||
steel_small_lt = TextureManager.load(PATTERNS + "steel_light.png"); // XXX Unused texture
|
||||
steel_big_dk = TextureManager.load(PATTERNS + "steel_big.png");
|
||||
steel_big_lt = TextureManager.load(PATTERNS + "steel_big_light.png");
|
||||
steel_big_scratched = TextureManager.load(PATTERNS + "steel_big_scratched.png");
|
||||
steel_brushed = TextureManager.load(PATTERNS + "steel_brushed.png");
|
||||
steel_rivet_belts = TextureManager.load(PATTERNS + "rivet_belts.png");
|
||||
water = TextureManager.load(PATTERNS + "water.png");
|
||||
|
||||
// particles
|
||||
snow = TextureManager.load(PARTICLES + "snow.png");
|
||||
leaves = TextureManager.load(PARTICLES + "leaves.png");
|
||||
rain = TextureManager.load(PARTICLES + "rain.png");
|
||||
circle = TextureManager.load(PARTICLES + "circle.png");
|
||||
|
||||
// program tiles
|
||||
program = TextureManager.load(PROGRAM + "program.png");
|
||||
|
||||
// map tiles
|
||||
map_tiles = TextureManager.load(TILES + "tiles.png");
|
||||
map_shading = TextureManager.load(TILES + "shading.png");
|
||||
|
||||
// turtle
|
||||
turtle_blue = TextureManager.load(SPRITES + "HD-blue.png");
|
||||
turtle_yellow = TextureManager.load(SPRITES + "HD-yellow.png");
|
||||
turtle_green = TextureManager.load(SPRITES + "HD-green.png");
|
||||
turtle_purple = TextureManager.load(SPRITES + "HD-purple.png");
|
||||
turtle_red = TextureManager.load(SPRITES + "HD-red.png");
|
||||
|
||||
turtle_brown_dk = TextureManager.load(SPRITES + "HD-brown-dk.png");
|
||||
turtle_brown_lt = TextureManager.load(SPRITES + "HD-brown-lt.png");
|
||||
turtle_brown_orn = TextureManager.load(SPRITES + "HD-brown-ornamental.png");
|
||||
turtle_shadows = TextureManager.load(SPRITES + "HD-shadow.png");
|
||||
|
||||
food = TextureManager.load(SPRITES + "food.png");
|
||||
food_shadows = TextureManager.load(SPRITES + "food-shadow.png");
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
Tx.init();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package mightypork.rogue.textures;
|
||||
|
||||
|
||||
/**
|
||||
* List of texture quads for GUIs
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public class Tx {
|
||||
|
||||
// logo
|
||||
public static TxQuad LOGO;
|
||||
|
||||
|
||||
public static void initForSplash()
|
||||
{
|
||||
// splash logo
|
||||
LOGO = TxQuad.fromSize(Textures.logo, 15, 9, 226, 132);
|
||||
}
|
||||
|
||||
|
||||
public static void init()
|
||||
{
|
||||
// title image (word art)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 = tx;
|
||||
this.uvs = new Rect(x1, y1, x2, y2);
|
||||
this.size = uvs.getSize();
|
||||
}
|
||||
|
||||
|
||||
public TxQuad copy()
|
||||
{
|
||||
return new TxQuad(tx, uvs);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package mightypork.rogue.threads;
|
||||
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import mightypork.rogue.Paths;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
|
||||
/**
|
||||
* Thread for saving screenshot
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class ThreadSaveScreenshot extends Thread {
|
||||
|
||||
private ByteBuffer buffer;
|
||||
private int width;
|
||||
private int height;
|
||||
private int bpp;
|
||||
|
||||
|
||||
/**
|
||||
* Save screenshot thread
|
||||
*
|
||||
* @param buffer byte buffer with image data
|
||||
* @param width screen width
|
||||
* @param height screen height
|
||||
* @param bpp bits per pixel
|
||||
*/
|
||||
public ThreadSaveScreenshot(ByteBuffer buffer, int width, int height, int bpp) {
|
||||
this.buffer = buffer;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.bpp = bpp;
|
||||
}
|
||||
|
||||
|
||||
private String getUniqueScreenshotName()
|
||||
{
|
||||
DateFormat df = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
String fname = getUniqueScreenshotName();
|
||||
|
||||
// generate unique filename
|
||||
File file;
|
||||
int index = 0;
|
||||
while (true) {
|
||||
file = new File(Paths.SCREENSHOTS, fname + (index > 0 ? "-" + index : "") + ".png");
|
||||
if (!file.exists()) break;
|
||||
index++;
|
||||
}
|
||||
|
||||
Log.f3("Saving screenshot to file: " + file);
|
||||
|
||||
String format = "PNG";
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
// convert to a buffered image
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int i = (x + (width * y)) * bpp;
|
||||
int r = buffer.get(i) & 0xFF;
|
||||
int g = buffer.get(i + 1) & 0xFF;
|
||||
int b = buffer.get(i + 2) & 0xFF;
|
||||
image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
}
|
||||
|
||||
// save to disk
|
||||
try {
|
||||
ImageIO.write(image, format, file);
|
||||
} catch (IOException e) {
|
||||
Log.e("Failed to save screenshot.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package mightypork.rogue.threads;
|
||||
|
||||
|
||||
import mightypork.rogue.App;
|
||||
import mightypork.rogue.input.Keys;
|
||||
import mightypork.utils.logging.Log;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
|
||||
/**
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class ThreadScreenshotTrigger extends Thread {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
while (true) {
|
||||
if (Keys.justPressed(Keyboard.KEY_F2)) {
|
||||
Log.f2("F2, taking screenshot.");
|
||||
App.scheduledScreenshot = true;
|
||||
Keys.destroyChangeState(Keyboard.KEY_F2);
|
||||
}
|
||||
try {
|
||||
sleep(2);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,919 @@
|
||||
package mightypork.rogue.util;
|
||||
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import mightypork.rogue.textures.TextureManager;
|
||||
import mightypork.rogue.textures.TxQuad;
|
||||
import mightypork.utils.math.color.HSV;
|
||||
import mightypork.utils.math.color.RGB;
|
||||
import mightypork.utils.math.coord.Coord;
|
||||
import mightypork.utils.math.coord.Rect;
|
||||
|
||||
import org.newdawn.slick.opengl.Texture;
|
||||
|
||||
|
||||
/**
|
||||
* Render utilities
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class RenderUtils {
|
||||
|
||||
/**
|
||||
* Render quad 2D
|
||||
*
|
||||
* @param min min coord
|
||||
* @param max max coord
|
||||
*/
|
||||
public static void quadCoord(Coord min, Coord max)
|
||||
{
|
||||
quadCoord(min.x, min.y, max.x, max.y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with absolute coords (from screen bottom)
|
||||
*
|
||||
* @param left left x
|
||||
* @param bottom bottom y
|
||||
* @param right right x
|
||||
* @param top top y
|
||||
*/
|
||||
public static void quadCoord(double left, double bottom, double right, double top)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(left, top);
|
||||
glVertex2d(right, top);
|
||||
glVertex2d(right, bottom);
|
||||
glVertex2d(left, bottom);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with coloured border
|
||||
*
|
||||
* @param min min
|
||||
* @param max max
|
||||
* @param border border width
|
||||
* @param borderColor border color
|
||||
* @param insideColor filling color
|
||||
*/
|
||||
public static void quadCoordBorder(Coord min, Coord max, double border, RGB borderColor, RGB insideColor)
|
||||
{
|
||||
quadCoordBorder(min.x, min.y, max.x, max.y, border, borderColor, insideColor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with coloured border
|
||||
*
|
||||
* @param minX min x
|
||||
* @param minY min y
|
||||
* @param maxX max x
|
||||
* @param maxY max y
|
||||
* @param border border width
|
||||
* @param borderColor border color
|
||||
* @param insideColor filling color
|
||||
*/
|
||||
public static void quadCoordBorder(double minX, double minY, double maxX, double maxY, double border, RGB borderColor, RGB insideColor)
|
||||
{
|
||||
double bdr = border;
|
||||
|
||||
RenderUtils.setColor(borderColor);
|
||||
|
||||
//@formatter:off
|
||||
RenderUtils.quadCoord(minX, minY, minX + bdr, maxY);
|
||||
RenderUtils.quadCoord(maxX - bdr, minY, maxX, maxY);
|
||||
RenderUtils.quadCoord(minX + bdr, maxY - bdr, maxX - bdr, maxY);
|
||||
RenderUtils.quadCoord(minX + bdr, minY, maxX - bdr, minY + bdr);
|
||||
//@formatter:on
|
||||
|
||||
if (insideColor != null) {
|
||||
RenderUtils.setColor(insideColor);
|
||||
RenderUtils.quadCoord(minX + bdr, minY + bdr, maxX - bdr, maxY - bdr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient horizontal
|
||||
*
|
||||
* @param min min coord
|
||||
* @param max max coord
|
||||
* @param colorLeft color left
|
||||
* @param colorRight color right
|
||||
*/
|
||||
public static void quadCoordGradH(Coord min, Coord max, RGB colorLeft, RGB colorRight)
|
||||
{
|
||||
quadCoordGradH(min.x, min.y, max.x, max.y, colorLeft, colorRight);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient horizontal
|
||||
*
|
||||
* @param minX units from left
|
||||
* @param minY units from bottom
|
||||
* @param maxX quad width
|
||||
* @param maxY quad height
|
||||
* @param colorLeft color left
|
||||
* @param colorRight color right
|
||||
*/
|
||||
public static void quadCoordGradH(double minX, double minY, double maxX, double maxY, RGB colorLeft, RGB colorRight)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
setColor(colorLeft);
|
||||
glVertex2d(minX, maxY);
|
||||
setColor(colorRight);
|
||||
glVertex2d(maxX, maxY);
|
||||
|
||||
setColor(colorRight);
|
||||
glVertex2d(maxX, minY);
|
||||
setColor(colorLeft);
|
||||
glVertex2d(minX, minY);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient horizontal
|
||||
*
|
||||
* @param min min coord
|
||||
* @param max max coord
|
||||
* @param colorOuter color outer
|
||||
* @param colorMiddle color inner
|
||||
*/
|
||||
public static void quadCoordGradHBilinear(Coord min, Coord max, RGB colorOuter, RGB colorMiddle)
|
||||
{
|
||||
quadCoordGradHBilinear(min.x, min.y, max.x, max.y, colorOuter, colorMiddle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient horizontal
|
||||
*
|
||||
* @param minX min x
|
||||
* @param minY min y
|
||||
* @param maxX max x
|
||||
* @param maxY max y
|
||||
* @param colorOuter color outer
|
||||
* @param colorMiddle color inner
|
||||
*/
|
||||
public static void quadCoordGradHBilinear(double minX, double minY, double maxX, double maxY, RGB colorOuter, RGB colorMiddle)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
setColor(colorOuter);
|
||||
glVertex2d(minX, maxY);
|
||||
setColor(colorMiddle);
|
||||
glVertex2d((minX + maxX) / 2, maxY);
|
||||
|
||||
setColor(colorMiddle);
|
||||
glVertex2d((minX + maxX) / 2, minY);
|
||||
setColor(colorOuter);
|
||||
glVertex2d(minX, minY);
|
||||
|
||||
setColor(colorMiddle);
|
||||
glVertex2d((minX + maxX) / 2, maxY);
|
||||
setColor(colorOuter);
|
||||
glVertex2d(maxX, maxY);
|
||||
|
||||
setColor(colorOuter);
|
||||
glVertex2d(maxX, minY);
|
||||
setColor(colorMiddle);
|
||||
glVertex2d((minX + maxX) / 2, minY);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient vertical
|
||||
*
|
||||
* @param min min coord
|
||||
* @param max max coord
|
||||
* @param colorTop top color
|
||||
* @param colorBottom bottom color
|
||||
*/
|
||||
public static void quadCoordGradV(Coord min, Coord max, RGB colorTop, RGB colorBottom)
|
||||
{
|
||||
quadCoordGradV(min.x, min.y, max.x, max.y, colorTop, colorBottom);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient vertical
|
||||
*
|
||||
* @param minX min X
|
||||
* @param minY min Y
|
||||
* @param maxX max X
|
||||
* @param maxY max Y
|
||||
* @param colorTop top color
|
||||
* @param colorBottom bottom color
|
||||
*/
|
||||
public static void quadCoordGradV(double minX, double minY, double maxX, double maxY, RGB colorTop, RGB colorBottom)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
setColor(colorTop);
|
||||
glVertex2d(minX, maxY);
|
||||
glVertex2d(maxX, maxY);
|
||||
|
||||
setColor(colorBottom);
|
||||
glVertex2d(maxX, minY);
|
||||
glVertex2d(minX, minY);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient vertical
|
||||
*
|
||||
* @param min min coord
|
||||
* @param max max coord
|
||||
* @param colorOuter outer color
|
||||
* @param colorMiddle middle color
|
||||
*/
|
||||
public static void quadCoordGradVBilinear(Coord min, Coord max, RGB colorOuter, RGB colorMiddle)
|
||||
{
|
||||
quadCoordGradVBilinear(min.x, min.y, max.x, max.y, colorOuter, colorMiddle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient vertical
|
||||
*
|
||||
* @param minX min X
|
||||
* @param minY min Y
|
||||
* @param maxX max X
|
||||
* @param maxY max Y
|
||||
* @param colorOuter outer color
|
||||
* @param colorMiddle middle color
|
||||
*/
|
||||
public static void quadCoordGradVBilinear(double minX, double minY, double maxX, double maxY, RGB colorOuter, RGB colorMiddle)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
setColor(colorOuter);
|
||||
glVertex2d(minX, maxY);
|
||||
glVertex2d(maxX, maxY);
|
||||
|
||||
setColor(colorMiddle);
|
||||
glVertex2d(maxX, (maxY + minY) / 2);
|
||||
glVertex2d(minX, (maxY + minY) / 2);
|
||||
|
||||
setColor(colorMiddle);
|
||||
glVertex2d(minX, (maxY + minY) / 2);
|
||||
glVertex2d(maxX, (maxY + minY) / 2);
|
||||
|
||||
setColor(colorOuter);
|
||||
glVertex2d(maxX, minY);
|
||||
glVertex2d(minX, minY);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with coloured border with outset effect
|
||||
*
|
||||
* @param min min coord
|
||||
* @param max max coord
|
||||
* @param border border width
|
||||
* @param fill fill color
|
||||
* @param inset true for inset, false for outset
|
||||
*/
|
||||
public static void quadCoordOutset(Coord min, Coord max, double border, RGB fill, boolean inset)
|
||||
{
|
||||
quadCoordOutset(min.x, min.y, max.x, max.y, border, fill, inset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with coloured border with outset effect
|
||||
*
|
||||
* @param minX left X
|
||||
* @param minY bottom Y
|
||||
* @param maxX right X
|
||||
* @param maxY top Y
|
||||
* @param border border width
|
||||
* @param fill fill color
|
||||
* @param inset true for inset, false for outset
|
||||
*/
|
||||
public static void quadCoordOutset(double minX, double minY, double maxX, double maxY, double border, RGB fill, boolean inset)
|
||||
{
|
||||
HSV hsv = fill.toHSV();
|
||||
HSV h;
|
||||
|
||||
h = hsv.copy();
|
||||
h.s *= 0.6;
|
||||
RGB a = h.toRGB();
|
||||
|
||||
h = fill.toHSV();
|
||||
h.v *= 0.6;
|
||||
RGB b = h.toRGB();
|
||||
|
||||
RGB leftTopC, rightBottomC;
|
||||
|
||||
if (!inset) {
|
||||
leftTopC = a;
|
||||
rightBottomC = b;
|
||||
} else {
|
||||
leftTopC = b;
|
||||
rightBottomC = a;
|
||||
}
|
||||
|
||||
double bdr = border;
|
||||
|
||||
RenderUtils.setColor(leftTopC);
|
||||
|
||||
// left + top
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(minX, minY);
|
||||
glVertex2d(minX + bdr, minY + bdr);
|
||||
glVertex2d(minX + bdr, maxY - bdr);
|
||||
glVertex2d(minX, maxY);
|
||||
|
||||
glVertex2d(minX, maxY);
|
||||
glVertex2d(minX + bdr, maxY - bdr);
|
||||
glVertex2d(maxX - bdr, maxY - bdr);
|
||||
glVertex2d(maxX, maxY);
|
||||
glEnd();
|
||||
|
||||
RenderUtils.setColor(rightBottomC);
|
||||
|
||||
// right + bottom
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(maxX, minY);
|
||||
glVertex2d(maxX, maxY);
|
||||
glVertex2d(maxX - bdr, maxY - bdr);
|
||||
glVertex2d(maxX - bdr, minY + bdr);
|
||||
|
||||
glVertex2d(minX, minY);
|
||||
glVertex2d(maxX, minY);
|
||||
glVertex2d(maxX - bdr, minY + bdr);
|
||||
glVertex2d(minX + bdr, minY + bdr);
|
||||
glEnd();
|
||||
|
||||
RenderUtils.setColor(fill);
|
||||
RenderUtils.quadCoord(minX + bdr, minY + bdr, maxX - bdr, maxY - bdr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D
|
||||
*
|
||||
* @param rect rectangle
|
||||
*/
|
||||
public static void quadRect(Rect rect)
|
||||
{
|
||||
quadCoord(rect.getMin(), rect.getMax());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D
|
||||
*
|
||||
* @param rect rectangle
|
||||
* @param color draw color
|
||||
*/
|
||||
public static void quadRect(Rect rect, RGB color)
|
||||
{
|
||||
setColor(color);
|
||||
quadCoord(rect.getMin(), rect.getMax());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with coloured border
|
||||
*
|
||||
* @param rect rect
|
||||
* @param border border width
|
||||
* @param borderColor border color
|
||||
* @param insideColor filling color
|
||||
*/
|
||||
public static void quadBorder(Rect rect, double border, RGB borderColor, RGB insideColor)
|
||||
{
|
||||
quadCoordBorder(rect.getMin(), rect.getMax(), border, borderColor, insideColor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient horizontal
|
||||
*
|
||||
* @param rect rect
|
||||
* @param colorLeft color left
|
||||
* @param colorRight color right
|
||||
*/
|
||||
public static void quadGradH(Rect rect, RGB colorLeft, RGB colorRight)
|
||||
{
|
||||
quadCoordGradH(rect.getMin(), rect.getMax(), colorLeft, colorRight);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient horizontal
|
||||
*
|
||||
* @param rect rect
|
||||
* @param colorOuter color outer
|
||||
* @param colorMiddle color inner
|
||||
*/
|
||||
public static void quadGradHBilinear(Rect rect, RGB colorOuter, RGB colorMiddle)
|
||||
{
|
||||
quadCoordGradHBilinear(rect.getMin(), rect.getMax(), colorOuter, colorMiddle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient vertical
|
||||
*
|
||||
* @param rect rect
|
||||
* @param colorTop top color
|
||||
* @param colorBottom bottom color
|
||||
*/
|
||||
public static void quadGradV(Rect rect, RGB colorTop, RGB colorBottom)
|
||||
{
|
||||
quadCoordGradV(rect.getMin(), rect.getMax(), colorTop, colorBottom);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D with gradient vertical
|
||||
*
|
||||
* @param rect rect
|
||||
* @param colorOuter outer color
|
||||
* @param colorMiddle middle color
|
||||
*/
|
||||
public static void quadGradVBilinear(Rect rect, RGB colorOuter, RGB colorMiddle)
|
||||
{
|
||||
quadCoordGradVBilinear(rect.getMin(), rect.getMax(), colorOuter, colorMiddle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad with coloured border with outset effect
|
||||
*
|
||||
* @param rect rectangle
|
||||
* @param border border width
|
||||
* @param fill fill color
|
||||
* @param inset true for inset, false for outset
|
||||
*/
|
||||
public static void quadRectOutset(Rect rect, double border, RGB fill, boolean inset)
|
||||
{
|
||||
quadCoordOutset(rect.getMin(), rect.getMax(), border, fill, inset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect (texture must be binded already)
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param textureCoords texture coords (0-1)
|
||||
*/
|
||||
public static void quadTexturedAbs(Rect quad, Rect textureCoords)
|
||||
{
|
||||
double left = quad.x1();
|
||||
double bottom = quad.y2();
|
||||
double right = quad.x2();
|
||||
double top = quad.y1();
|
||||
|
||||
double tleft = textureCoords.x1();
|
||||
double tbottom = textureCoords.y1();
|
||||
double tright = textureCoords.x2();
|
||||
double ttop = textureCoords.y2();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param txCoords texture coords rectangle (px)
|
||||
* @param texture texture instance
|
||||
*/
|
||||
public static void quadTextured(Rect quad, Rect txCoords, Texture texture)
|
||||
{
|
||||
quadTextured(quad, txCoords, texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured rect
|
||||
*
|
||||
* @param quad rectangle (px)
|
||||
* @param txCoords texture coords rectangle (px)
|
||||
* @param texture texture instance
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTextured(Rect quad, Rect txCoords, Texture texture, RGB tint)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
setColor(tint);
|
||||
TextureManager.bind(texture);
|
||||
|
||||
quadTexturedAbs(quad, txCoords.div(texture.getImageHeight()));
|
||||
|
||||
TextureManager.unbind();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame with borders
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param yOffsetTimes offset count (move frame down n times)
|
||||
* @param texture the texture
|
||||
*/
|
||||
public static void quadTexturedFrame(Rect quadRect, Rect textureRect, int yOffsetTimes, Texture texture)
|
||||
{
|
||||
quadTexturedFrame(quadRect, textureRect, yOffsetTimes, texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame with borders
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param yOffsetTimes offset count (move frame down n times)
|
||||
* @param texture the texture
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTexturedFrame(Rect quadRect, Rect textureRect, int yOffsetTimes, Texture texture, RGB tint)
|
||||
{
|
||||
Texture tx = texture;
|
||||
|
||||
int frameHeight = (int) textureRect.getSize().y;
|
||||
|
||||
int yOffset = yOffsetTimes * frameHeight;
|
||||
|
||||
double x1 = quadRect.x1();
|
||||
double y1 = quadRect.y1();
|
||||
double x2 = quadRect.x2();
|
||||
double y2 = quadRect.y2();
|
||||
|
||||
double w = x2 - x1;
|
||||
double h = y2 - y1;
|
||||
|
||||
double tx1 = textureRect.x1();
|
||||
double ty1 = textureRect.y1();
|
||||
double tx2 = textureRect.x2();
|
||||
double ty2 = textureRect.y2();
|
||||
|
||||
double halfY = h / 2D;
|
||||
double halfX = w / 2D;
|
||||
|
||||
// lt, rt
|
||||
// lb, rb
|
||||
|
||||
Rect verts, uvs;
|
||||
|
||||
// lt
|
||||
verts = new Rect(x1, y2, x1 + halfX, y2 - halfY);
|
||||
uvs = new Rect(tx1, ty1, tx1 + halfX, ty1 + halfY);
|
||||
uvs.add_ip(0, yOffset);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// lb
|
||||
verts = new Rect(x1, y2 - halfY, x1 + halfX, y1);
|
||||
uvs = new Rect(tx1, ty2 - halfY, tx1 + halfX, ty2);
|
||||
uvs.add_ip(0, yOffset);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// rt
|
||||
verts = new Rect(x1 + halfX, y2, x2, y2 - halfY);
|
||||
uvs = new Rect(tx2 - halfX, ty1, tx2, ty1 + halfY);
|
||||
uvs.add_ip(0, yOffset);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// rb
|
||||
verts = new Rect(x1 + halfX, y2 - halfY, x2, y1);
|
||||
uvs = new Rect(tx2 - halfX, ty2 - halfY, tx2, ty2);
|
||||
uvs.add_ip(0, yOffset);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame with borders
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param texture the texture
|
||||
*/
|
||||
public static void quadTexturedFrame(Rect quadRect, Rect textureRect, Texture texture)
|
||||
{
|
||||
quadTexturedFrame(quadRect, textureRect, 0, texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame with borders
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
*/
|
||||
public static void quadTexturedFrame(Rect quadRect, TxQuad txquad)
|
||||
{
|
||||
quadTexturedFrame(quadRect, txquad, 0, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame with borders
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
* @param yOffsetTimes offset count (move frame down n times)
|
||||
*/
|
||||
public static void quadTexturedFrame(Rect quadRect, TxQuad txquad, int yOffsetTimes)
|
||||
{
|
||||
quadTexturedFrame(quadRect, txquad, yOffsetTimes, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame with borders
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
* @param yOffsetTimes offset count (move frame down n times)
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTexturedFrame(Rect quadRect, TxQuad txquad, int yOffsetTimes, RGB tint)
|
||||
{
|
||||
quadTexturedFrame(quadRect, txquad.uvs, yOffsetTimes, txquad.tx, tint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching horizontally (rect height = texture rect
|
||||
* height)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
* @param texture the texture
|
||||
*/
|
||||
public static void quadTexturedStretchH(Rect quadRect, Rect textureRect, int borderSize, Texture texture)
|
||||
{
|
||||
quadTexturedStretchH(quadRect, textureRect, borderSize, texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching horizontally (rect height = texture rect
|
||||
* height)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
* @param texture the texture
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTexturedStretchH(Rect quadRect, Rect textureRect, int borderSize, Texture texture, RGB tint)
|
||||
{
|
||||
Texture tx = texture;
|
||||
|
||||
double x1 = quadRect.x1();
|
||||
double y1 = quadRect.y1();
|
||||
double x2 = quadRect.x2();
|
||||
double y2 = quadRect.y2();
|
||||
|
||||
double tx1 = textureRect.x1();
|
||||
double ty1 = textureRect.y1();
|
||||
double tx2 = textureRect.x2();
|
||||
double ty2 = textureRect.y2();
|
||||
|
||||
// lt, mi, rt
|
||||
|
||||
Rect verts, uvs;
|
||||
|
||||
// lt
|
||||
verts = new Rect(x1, y2, x1 + borderSize, y1);
|
||||
uvs = new Rect(tx1, ty1, tx1 + borderSize, ty2);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// // mi
|
||||
verts = new Rect(x1 + borderSize, y2, x2 - borderSize, y1);
|
||||
uvs = new Rect(tx1 + borderSize, ty1, tx2 - borderSize, ty2);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// rt
|
||||
verts = new Rect(x2 - borderSize, y2, x2, y1);
|
||||
uvs = new Rect(tx2 - borderSize, ty1, tx2, ty2);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching horizontally (rect height = texture rect
|
||||
* height)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
*/
|
||||
public static void quadTexturedStretchH(Rect quadRect, TxQuad txquad, int borderSize)
|
||||
{
|
||||
quadTexturedStretchH(quadRect, txquad, borderSize, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching horizontally (rect height = texture rect
|
||||
* height)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTexturedStretchH(Rect quadRect, TxQuad txquad, int borderSize, RGB tint)
|
||||
{
|
||||
quadTexturedStretchH(quadRect, txquad.uvs, borderSize, txquad.tx, tint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching vertically (rect width = texture rect
|
||||
* width)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
* @param texture the texture
|
||||
*/
|
||||
public static void quadTexturedStretchV(Rect quadRect, Rect textureRect, int borderSize, Texture texture)
|
||||
{
|
||||
quadTexturedStretchV(quadRect, textureRect, borderSize, texture, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching vertically (rect width = texture rect
|
||||
* width)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param textureRect rectangle in texture with the basic frame (px)
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
* @param texture the texture
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTexturedStretchV(Rect quadRect, Rect textureRect, int borderSize, Texture texture, RGB tint)
|
||||
{
|
||||
Texture tx = texture;
|
||||
|
||||
double x1 = quadRect.x1();
|
||||
double y1 = quadRect.y1();
|
||||
double x2 = quadRect.x2();
|
||||
double y2 = quadRect.y2();
|
||||
|
||||
double tx1 = textureRect.x1();
|
||||
double ty1 = textureRect.y1();
|
||||
double tx2 = textureRect.x2();
|
||||
double ty2 = textureRect.y2();
|
||||
|
||||
// tp
|
||||
// mi
|
||||
// bn
|
||||
|
||||
Rect verts, uvs;
|
||||
|
||||
// tp
|
||||
verts = new Rect(x1, y2, x2, y2 - borderSize);
|
||||
uvs = new Rect(tx1, ty1, tx2, ty1 + borderSize);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// mi
|
||||
verts = new Rect(x1, y2 - borderSize, x2, y1 + borderSize);
|
||||
uvs = new Rect(tx1, ty1 + borderSize, tx2, ty2 - borderSize);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
|
||||
// rt
|
||||
verts = new Rect(x1, y1 + borderSize, x2, y1);
|
||||
uvs = new Rect(tx1, ty2 - borderSize, tx2, ty2);
|
||||
quadTextured(verts, uvs, tx, tint);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching vertically (rect width = texture rect
|
||||
* width)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
*/
|
||||
public static void quadTexturedStretchV(Rect quadRect, TxQuad txquad, int borderSize)
|
||||
{
|
||||
quadTexturedStretchV(quadRect, txquad, borderSize, RGB.WHITE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render textured frame stretching vertically (rect width = texture rect
|
||||
* width)
|
||||
*
|
||||
* @param quadRect drawn rectangle (px)
|
||||
* @param txquad texture quad
|
||||
* @param borderSize size of the unstretched horizontal border
|
||||
* @param tint color tint
|
||||
*/
|
||||
public static void quadTexturedStretchV(Rect quadRect, TxQuad txquad, int borderSize, RGB tint)
|
||||
{
|
||||
quadTexturedStretchV(quadRect, txquad.uvs, borderSize, txquad.tx, tint);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render quad 2D
|
||||
*
|
||||
* @param left units from left
|
||||
* @param bottom units from bottom
|
||||
* @param width quad width
|
||||
* @param height quad height
|
||||
*/
|
||||
public static void quadSize(double left, double bottom, double width, double height)
|
||||
{
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(left, bottom + height);
|
||||
glVertex2d(left + width, bottom + height);
|
||||
glVertex2d(left + width, bottom);
|
||||
glVertex2d(left, bottom);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package mightypork.rogue.util;
|
||||
|
||||
|
||||
/**
|
||||
* Utils class
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Utils {
|
||||
}
|
||||
Reference in New Issue
Block a user