Restructuring starting from the launcher up to obtaining PCM data from
the audio backend is complete but untested.
This commit is contained in:
parent
7782a6a44b
commit
0dce05050a
45
core/src/zero1hd/rhythmbullet/AssetPack.java
Executable file
45
core/src/zero1hd/rhythmbullet/AssetPack.java
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
package zero1hd.rhythmbullet;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.assets.AssetManager;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
|
public interface AssetPack extends Disposable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called right after the game instance is created and passed to LWJGL. This method is called once for you to instantiate things for later use but require Libgdx functions.
|
||||||
|
*/
|
||||||
|
public void initiateResources();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game manager calls this when it needs to load textures.
|
||||||
|
*/
|
||||||
|
public void queueTextures(AssetManager assetManager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game manager calls this when it needs to load sound effects.
|
||||||
|
*/
|
||||||
|
public void queueSFX(AssetManager assetManager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game manager calls this when it needs to load particles.
|
||||||
|
*/
|
||||||
|
public void queueParticles(AssetManager assetManager);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game manager calls when it needs to load particles. Usually called after textures are loaded since the skin requires the other assets.
|
||||||
|
* @param skin the skin object to set up.
|
||||||
|
*/
|
||||||
|
public void setupSkin(Skin skin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game manager calls when it needs the fonts to be generated. Usually called right before setting up the skin itself since items in the skin need fonts.
|
||||||
|
*/
|
||||||
|
public void generateFonts(Skin skin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game manager calls this once all assets are loaded. This function should be used to make some in-code adjustments to assets that will be consistent throughout the game for that run.
|
||||||
|
* @param assetManager gives you access to the assets to modify.
|
||||||
|
*/
|
||||||
|
public void complete(AssetManager assetManager);
|
||||||
|
}
|
7
core/src/zero1hd/rhythmbullet/InitialScreen.java
Executable file
7
core/src/zero1hd/rhythmbullet/InitialScreen.java
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
package zero1hd.rhythmbullet;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Screen;
|
||||||
|
|
||||||
|
public interface InitialScreen {
|
||||||
|
public Screen createMainScreen(RhythmBullet game);
|
||||||
|
}
|
@ -13,28 +13,14 @@ import com.badlogic.gdx.assets.loaders.TextureLoader;
|
|||||||
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
|
import com.badlogic.gdx.assets.loaders.resolvers.InternalFileHandleResolver;
|
||||||
import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.Resolution;
|
import com.badlogic.gdx.assets.loaders.resolvers.ResolutionFileResolver.Resolution;
|
||||||
import com.badlogic.gdx.audio.Sound;
|
import com.badlogic.gdx.audio.Sound;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
|
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.List.ListStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane.ScrollPaneStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox.SelectBoxStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Slider.SliderStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldStyle;
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Window.WindowStyle;
|
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.util.GenericFileTypeHandler;
|
import zero1hd.rhythmbullet.util.GenericFileTypeHandler;
|
||||||
import zero1hd.rhythmbullet.util.RoundingResolutionHandler;
|
import zero1hd.rhythmbullet.util.RoundingResolutionHandler;
|
||||||
import zero1hd.rhythmbullet.util.AdvancedResizeScreen;
|
import zero1hd.rhythmbullet.util.ResizeReadyScreen;
|
||||||
|
|
||||||
|
|
||||||
public class RhythmBullet extends Game {
|
public class RhythmBullet extends Game {
|
||||||
@ -42,34 +28,37 @@ public class RhythmBullet extends Game {
|
|||||||
public static final int WORLD_HEIGHT = 48;
|
public static final int WORLD_HEIGHT = 48;
|
||||||
public static final int SPAWN_CIRCLE_RADIUS = 6;
|
public static final int SPAWN_CIRCLE_RADIUS = 6;
|
||||||
public static int pixels_per_unit;
|
public static int pixels_per_unit;
|
||||||
private boolean initComplete = false;
|
private boolean initiated;
|
||||||
private boolean resizing;
|
private boolean resizing;
|
||||||
private int screenWidth, screenHeight;
|
private int screenWidth, screenHeight;
|
||||||
public static final String VERSION = "(0.1)R1-PreAlpha";
|
public static final String VERSION = "(0.1)R1-PreAlpha";
|
||||||
|
|
||||||
private AssetManager assetManager = new AssetManager();
|
private AssetManager assetManager = new AssetManager();
|
||||||
private Skin defaultSkin = new Skin();
|
private Skin skin;
|
||||||
private FreeTypeFontGenerator default_fontGenerator;
|
|
||||||
private FreeTypeFontGenerator darktech_ldr_fontGenerator;
|
|
||||||
TextureAtlas skinAtlas;
|
TextureAtlas skinAtlas;
|
||||||
private Preferences prefs;
|
private Preferences prefs;
|
||||||
private RoundingResolutionHandler rRHandler;
|
private RoundingResolutionHandler rRHandler;
|
||||||
private Screen initialScreen;
|
private Screen initialScreen;
|
||||||
|
private AssetPack assetPack;
|
||||||
|
|
||||||
public void setInitialScreen(Screen initialScreen) {
|
/**
|
||||||
|
* This should be called before passed to LWJGL. Setup for system-dependent items such as UI and assets.
|
||||||
|
* @param initialScreen the first screen to go to.
|
||||||
|
* @param assetPack the asset package to be used.
|
||||||
|
*/
|
||||||
|
public void setup(Screen initialScreen, AssetPack assetPack) {
|
||||||
this.initialScreen = initialScreen;
|
this.initialScreen = initialScreen;
|
||||||
|
this.assetPack = assetPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create() {
|
public void create() {
|
||||||
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||||
prefs = Gdx.app.getPreferences("RhythmBullet Preferences");
|
setScreen(initialScreen);
|
||||||
|
|
||||||
if (getPrefs().getBoolean("fullscreen", true)) {
|
assetPack.initiateResources();
|
||||||
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
|
|
||||||
} else {
|
prefs = Gdx.app.getPreferences("RhythmBullet Preferences");
|
||||||
Gdx.graphics.setWindowedMode(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Resolution[] resolution = {
|
Resolution[] resolution = {
|
||||||
new Resolution(1280, 720, "1280x720"),
|
new Resolution(1280, 720, "1280x720"),
|
||||||
@ -88,57 +77,68 @@ public class RhythmBullet extends Game {
|
|||||||
assetManager.setLoader(Texture.class, new TextureLoader(rRHandler));
|
assetManager.setLoader(Texture.class, new TextureLoader(rRHandler));
|
||||||
assetManager.setLoader(ParticleEffect.class, new ParticleEffectLoader(genericFileFinder));
|
assetManager.setLoader(ParticleEffect.class, new ParticleEffectLoader(genericFileFinder));
|
||||||
assetManager.setLoader(Sound.class, new SoundLoader(genericFileFinder));
|
assetManager.setLoader(Sound.class, new SoundLoader(genericFileFinder));
|
||||||
default_fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Gasalt-Regular.ttf"));
|
|
||||||
darktech_ldr_fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/darktech_ldr.ttf"));
|
|
||||||
|
|
||||||
getrRHandler().setResolution(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
|
rRHandler.setResolution(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
|
||||||
|
|
||||||
queueAssets();
|
|
||||||
setScreen(initialScreen);
|
|
||||||
|
|
||||||
screenWidth = Gdx.graphics.getWidth();
|
screenWidth = Gdx.graphics.getWidth();
|
||||||
screenHeight = Gdx.graphics.getHeight();
|
screenHeight = Gdx.graphics.getHeight();
|
||||||
|
|
||||||
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
|
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
|
||||||
}
|
|
||||||
|
|
||||||
public void checkAssetQueue() {
|
if (getPrefs().getBoolean("fullscreen", true)) {
|
||||||
if (!initComplete) {
|
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
|
||||||
if (assetManager.update()) {
|
} else {
|
||||||
generateFonts(Gdx.graphics.getHeight());
|
Gdx.graphics.setWindowedMode(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
|
||||||
defineSkinStyles();
|
|
||||||
setInitComplete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkResize() {
|
|
||||||
if (resizing) {
|
|
||||||
if (assetManager.update()) {
|
|
||||||
Gdx.app.debug("Resize", "Post transition is happening");
|
|
||||||
resizing = false;
|
|
||||||
generateFonts(Gdx.graphics.getHeight());
|
|
||||||
defineSkinStyles();
|
|
||||||
assetManager.get("standard_thrust.p", ParticleEffect.class).flipY();
|
|
||||||
((AdvancedResizeScreen) getScreen()).postAssetLoad();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
checkResize();
|
|
||||||
checkAssetQueue();
|
checkAssetQueue();
|
||||||
super.render();
|
super.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean checkAssetQueue() {
|
||||||
|
if (assetManager.update()) {
|
||||||
|
if (skin != null) skin.dispose();
|
||||||
|
skin = new Skin();
|
||||||
|
skinAtlas = assetManager.get("uiskin.atlas", TextureAtlas.class);
|
||||||
|
getSkinSkin().addRegions(skinAtlas);
|
||||||
|
|
||||||
|
assetPack.generateFonts(skin);
|
||||||
|
assetPack.setupSkin(skin);
|
||||||
|
assetPack.complete(assetManager);
|
||||||
|
|
||||||
|
if (resizing) {
|
||||||
|
Gdx.app.debug("Resize", "Post resize is starting...");
|
||||||
|
if (getScreen() instanceof ResizeReadyScreen) {
|
||||||
|
((ResizeReadyScreen) getScreen()).postAssetLoad();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Cannot perform window resize on a screen that isn't using a resize ready screen.");
|
||||||
|
}
|
||||||
|
Gdx.app.debug("Resize", "Post resize has ended.");
|
||||||
|
|
||||||
|
if (!initiated) {
|
||||||
|
setScreen(((InitialScreen) initialScreen).createMainScreen(this));
|
||||||
|
initiated = true;
|
||||||
|
}
|
||||||
|
resizing = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setScreen(Screen screen) {
|
public void setScreen(Screen screen) {
|
||||||
if (screen instanceof AdvancedResizeScreen) {
|
if (screen instanceof ResizeReadyScreen) {
|
||||||
AdvancedResizeScreen advancedResizeScreen = (AdvancedResizeScreen) screen;
|
ResizeReadyScreen advancedResizeScreen = (ResizeReadyScreen) screen;
|
||||||
try {
|
try {
|
||||||
advancedResizeScreen.preAssetLoad();
|
advancedResizeScreen.preAssetLoad();
|
||||||
} catch (NullPointerException cleanScreen) {
|
} catch (NullPointerException cleanScreen) {
|
||||||
|
//Tried to perform pre-asset reload, but had uninitialized objects, meaning this is a new screen, or "clean" screen.
|
||||||
} finally {
|
} finally {
|
||||||
advancedResizeScreen.postAssetLoad();
|
advancedResizeScreen.postAssetLoad();
|
||||||
}
|
}
|
||||||
@ -146,235 +146,61 @@ public class RhythmBullet extends Game {
|
|||||||
super.setScreen(screen);
|
super.setScreen(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
Gdx.app.debug("Core", "disposing...");
|
|
||||||
if (initComplete) {
|
|
||||||
skinAtlas.dispose();
|
|
||||||
getDefaultSkin().dispose();
|
|
||||||
default_fontGenerator.dispose();
|
|
||||||
darktech_ldr_fontGenerator.dispose();
|
|
||||||
assetManager.dispose();
|
|
||||||
getScreen().dispose();
|
|
||||||
}
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resize(int width, int height) {
|
public void resize(int width, int height) {
|
||||||
Gdx.app.debug("RhythmBullet/resize", "Previous size:" + screenWidth + "x" + screenHeight + " new size: " + width + "x" + height);
|
Gdx.app.debug("RhythmBullet/resize", "Current size:" + screenWidth + "x" + screenHeight + " new size: " + width + "x" + height);
|
||||||
if (width != screenWidth || height != screenHeight) {
|
if (width != screenWidth || height != screenHeight) {
|
||||||
screenWidth = Gdx.graphics.getWidth();
|
screenWidth = Gdx.graphics.getWidth();
|
||||||
screenHeight = Gdx.graphics.getHeight();
|
screenHeight = Gdx.graphics.getHeight();
|
||||||
|
|
||||||
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
|
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
|
||||||
|
Gdx.app.debug("Resize", "Pre-resize is happening. Resizing to " + width + "x" + height);
|
||||||
if (initComplete) {
|
|
||||||
Gdx.app.debug("Resize", "Pre-transition is happening. Using resolution " + width + "x" + height);
|
|
||||||
rRHandler.setResolution(width, height);
|
rRHandler.setResolution(width, height);
|
||||||
((AdvancedResizeScreen) getScreen()).preAssetLoad();
|
if (getScreen() instanceof ResizeReadyScreen) {
|
||||||
assetManager.clear();
|
((ResizeReadyScreen) getScreen()).preAssetLoad();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Cannot perform window resize on a screen that isn't using a resize ready screen.");
|
||||||
|
}
|
||||||
prefs.putInteger("screen-width", width);
|
prefs.putInteger("screen-width", width);
|
||||||
prefs.putInteger("screen-height", height);
|
prefs.putInteger("screen-height", height);
|
||||||
prefs.flush();
|
prefs.flush();
|
||||||
resizing = true;
|
resizing = true;
|
||||||
|
assetManager.clear();
|
||||||
queueAssets();
|
queueAssets();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
super.resize(width, height);
|
super.resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int fontScale(float fontSize, int height) {
|
public void queueAssets() {
|
||||||
int size = MathUtils.round(Gdx.graphics.getDensity()*(fontSize*height));
|
assetPack.queueTextures(assetManager);
|
||||||
if (size >= 200) {
|
assetPack.queueSFX(assetManager);
|
||||||
size = 200;
|
assetPack.queueParticles(assetManager);
|
||||||
}
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetManager getAssetManager() {
|
public AssetManager getAssetManager() {
|
||||||
return assetManager;
|
return assetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Skin getDefaultSkin() {
|
public Skin getSkinSkin() {
|
||||||
return defaultSkin;
|
return skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Preferences getPrefs() {
|
public Preferences getPrefs() {
|
||||||
return prefs;
|
return prefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInitComplete() {
|
@Override
|
||||||
initComplete = true;
|
public void dispose() {
|
||||||
|
Gdx.app.debug("Core", "disposing...");
|
||||||
|
try {
|
||||||
|
skinAtlas.dispose();
|
||||||
|
getSkinSkin().dispose();
|
||||||
|
assetManager.dispose();
|
||||||
|
getScreen().dispose();
|
||||||
|
assetPack.dispose();
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
//Means the game was closed before everything was initiated.
|
||||||
}
|
}
|
||||||
|
super.dispose();
|
||||||
public boolean isInitComplete() {
|
|
||||||
return initComplete;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoundingResolutionHandler getrRHandler() {
|
|
||||||
return rRHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void queueAssets() {
|
|
||||||
assetManager.load("uiskin.atlas", TextureAtlas.class);
|
|
||||||
assetManager.load("Tech-Circle1.png", Texture.class);
|
|
||||||
assetManager.load("polyjet-standard.png", Texture.class);
|
|
||||||
assetManager.load("standard_thrust.p", ParticleEffect.class);
|
|
||||||
assetManager.load("keyboard.atlas", TextureAtlas.class);
|
|
||||||
assetManager.load("cybercircle3B.png", Texture.class);
|
|
||||||
assetManager.load("title.png", Texture.class);
|
|
||||||
assetManager.load("cybercircle1.png", Texture.class);
|
|
||||||
assetManager.load("defaultCover.png", Texture.class);
|
|
||||||
assetManager.load("teleport-cloak.p", ParticleEffect.class);
|
|
||||||
assetManager.load("pop_open.ogg", Sound.class);
|
|
||||||
assetManager.load("pop_close.ogg", Sound.class);
|
|
||||||
assetManager.load("laser.png", Texture.class);
|
|
||||||
assetManager.load("pellet.png", Texture.class);
|
|
||||||
assetManager.load("shard.png", Texture.class);
|
|
||||||
assetManager.load("bar.png", Texture.class);
|
|
||||||
assetManager.load("flake.png", Texture.class);
|
|
||||||
assetManager.load("void_circle.png", Texture.class);
|
|
||||||
assetManager.load("laser.ogg", Sound.class);
|
|
||||||
assetManager.load("explosion.ogg", Sound.class);
|
|
||||||
assetManager.load("disintegrate.ogg", Sound.class);
|
|
||||||
assetManager.load("explosion-s.p", ParticleEffect.class);
|
|
||||||
assetManager.load("beateffect.p", ParticleEffect.class);
|
|
||||||
assetManager.load("tpSelector.png", Texture.class);
|
|
||||||
assetManager.load("magic1.png", Texture.class);
|
|
||||||
assetManager.load("backgrounds/mainBG.png", Texture.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateFonts(final int height) {
|
|
||||||
defaultSkin = new Skin();
|
|
||||||
Gdx.app.debug("Prelaunch Debug Info", "Generating fonts with screen height of " + height);
|
|
||||||
skinAtlas = assetManager.get("uiskin.atlas", TextureAtlas.class);
|
|
||||||
getDefaultSkin().addRegions(skinAtlas);
|
|
||||||
|
|
||||||
getDefaultSkin().add("window-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
|
||||||
{
|
|
||||||
size = 18;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
getDefaultSkin().add("sub-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
|
||||||
{
|
|
||||||
size = fontScale(0.05f, height);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
getDefaultSkin().add("default-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
|
||||||
{
|
|
||||||
size = fontScale(0.07f, height);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
getDefaultSkin().add("large-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
|
||||||
{
|
|
||||||
size = fontScale(0.085f, height);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
getDefaultSkin().add("special-font", darktech_ldr_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
|
||||||
{
|
|
||||||
size = fontScale(0.075f, height);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void defineSkinStyles() {
|
|
||||||
getDefaultSkin().add("default", Color.WHITE);
|
|
||||||
getDefaultSkin().add("inverse", Color.BLACK);
|
|
||||||
|
|
||||||
TextButtonStyle defaultTextButton = new TextButtonStyle();
|
|
||||||
defaultTextButton.up = getDefaultSkin().getDrawable("rect");
|
|
||||||
defaultTextButton.down = getDefaultSkin().getDrawable("rect-down");
|
|
||||||
defaultTextButton.font = getDefaultSkin().getFont("default-font");
|
|
||||||
defaultTextButton.fontColor = getDefaultSkin().getColor("default");
|
|
||||||
defaultTextButton.disabled = getDefaultSkin().getDrawable("rect-disabled");
|
|
||||||
getDefaultSkin().add("default", defaultTextButton);
|
|
||||||
|
|
||||||
TextButtonStyle subTextbutton = new TextButtonStyle(defaultTextButton);
|
|
||||||
subTextbutton.font = getDefaultSkin().getFont("sub-font");
|
|
||||||
getDefaultSkin().add("sub", subTextbutton);
|
|
||||||
|
|
||||||
TextButtonStyle windowTextButton = new TextButtonStyle(defaultTextButton);
|
|
||||||
windowTextButton.font = getDefaultSkin().getFont("window-font");
|
|
||||||
getDefaultSkin().add("window", windowTextButton);
|
|
||||||
|
|
||||||
TextButtonStyle textButtonLeft = new TextButtonStyle();
|
|
||||||
textButtonLeft.up = getDefaultSkin().getDrawable("left-button");
|
|
||||||
textButtonLeft.down = getDefaultSkin().getDrawable("left-button-down");
|
|
||||||
textButtonLeft.font = getDefaultSkin().getFont("default-font");
|
|
||||||
textButtonLeft.fontColor = getDefaultSkin().getColor("default");
|
|
||||||
getDefaultSkin().add("left", textButtonLeft);
|
|
||||||
|
|
||||||
SliderStyle defaultSlider = new SliderStyle(getDefaultSkin().getDrawable("default-slider"), getDefaultSkin().getDrawable("default-slider-knob"));
|
|
||||||
getDefaultSkin().add("default-horizontal", defaultSlider);
|
|
||||||
|
|
||||||
SliderStyle vertSlider = new SliderStyle(defaultSlider);
|
|
||||||
vertSlider.knob = getDefaultSkin().getDrawable("vertical-slider-knob");
|
|
||||||
getDefaultSkin().add("default-vertical", vertSlider);
|
|
||||||
|
|
||||||
LabelStyle defaultLabel = new LabelStyle();
|
|
||||||
defaultLabel.font = getDefaultSkin().getFont("default-font");
|
|
||||||
defaultLabel.fontColor = getDefaultSkin().getColor("default");
|
|
||||||
getDefaultSkin().add("default", defaultLabel);
|
|
||||||
|
|
||||||
TextFieldStyle defaultTextField = new TextFieldStyle(getDefaultSkin().getFont("sub-font"), getDefaultSkin().getColor("default"), getDefaultSkin().getDrawable("cursor"), getDefaultSkin().getDrawable("selection"), getDefaultSkin().getDrawable("textfield"));
|
|
||||||
getDefaultSkin().add("default", defaultTextField);
|
|
||||||
|
|
||||||
TextFieldStyle uiTextField = new TextFieldStyle(defaultTextField);
|
|
||||||
uiTextField.font = getDefaultSkin().getFont("window-font");
|
|
||||||
getDefaultSkin().add("ui", uiTextField);
|
|
||||||
|
|
||||||
WindowStyle defaultWindow = new WindowStyle(getDefaultSkin().getFont("window-font"), getDefaultSkin().getColor("default"), getDefaultSkin().getDrawable("default-window"));
|
|
||||||
getDefaultSkin().add("default", defaultWindow);
|
|
||||||
|
|
||||||
WindowStyle tintedWindow = new WindowStyle(defaultWindow);
|
|
||||||
tintedWindow.titleFontColor = getDefaultSkin().getColor("inverse");
|
|
||||||
tintedWindow.background = getDefaultSkin().getDrawable("tinted-window");
|
|
||||||
getDefaultSkin().add("tinted", tintedWindow);
|
|
||||||
|
|
||||||
ListStyle defaultList = new ListStyle(getDefaultSkin().getFont("window-font"), getDefaultSkin().getColor("inverse"), getDefaultSkin().getColor("default"), getDefaultSkin().getDrawable("selection"));
|
|
||||||
getDefaultSkin().add("default", defaultList);
|
|
||||||
|
|
||||||
ScrollPaneStyle defaultScrollPane = new ScrollPaneStyle();
|
|
||||||
defaultScrollPane.vScroll = getDefaultSkin().getDrawable("default-scroll");
|
|
||||||
defaultScrollPane.hScrollKnob = getDefaultSkin().getDrawable("default-round-large");
|
|
||||||
defaultScrollPane.hScroll = getDefaultSkin().getDrawable("default-scroll");
|
|
||||||
defaultScrollPane.vScrollKnob = getDefaultSkin().getDrawable("default-round-large");
|
|
||||||
getDefaultSkin().add("default", defaultScrollPane);
|
|
||||||
|
|
||||||
CheckBoxStyle defaultCheckBox = new CheckBoxStyle(getDefaultSkin().getDrawable("check-off"), getDefaultSkin().getDrawable("check-on"), getDefaultSkin().getFont("window-font"), getDefaultSkin().getColor("default"));
|
|
||||||
defaultCheckBox.checkboxOffDisabled = getDefaultSkin().getDrawable("check-disabled");
|
|
||||||
getDefaultSkin().add("default", defaultCheckBox);
|
|
||||||
|
|
||||||
SelectBoxStyle defaultSelectBox = new SelectBoxStyle(getDefaultSkin().getFont("default-font"), getDefaultSkin().getColor("default"), getDefaultSkin().getDrawable("default-select"), defaultScrollPane, defaultList);
|
|
||||||
getDefaultSkin().add("default", defaultSelectBox);
|
|
||||||
|
|
||||||
Gdx.app.debug("Prelaunch Debug Info", "UI Skin has been defined.");
|
|
||||||
|
|
||||||
CheckBoxStyle playButtonStyle = new CheckBoxStyle(defaultCheckBox);
|
|
||||||
playButtonStyle.checkboxOn = getDefaultSkin().getDrawable("play-down");
|
|
||||||
playButtonStyle.checkboxOff = getDefaultSkin().getDrawable("play");
|
|
||||||
getDefaultSkin().add("play-button", playButtonStyle);
|
|
||||||
|
|
||||||
ImageButtonStyle pauseButtonStyle = new ImageButtonStyle();
|
|
||||||
pauseButtonStyle.down = getDefaultSkin().getDrawable("pause-down");
|
|
||||||
pauseButtonStyle.up = getDefaultSkin().getDrawable("pause");
|
|
||||||
getDefaultSkin().add("pause-button", pauseButtonStyle);
|
|
||||||
|
|
||||||
ImageButtonStyle fastForwardButtonStyle = new ImageButtonStyle();
|
|
||||||
fastForwardButtonStyle.down = getDefaultSkin().getDrawable("fast-forward-down");
|
|
||||||
fastForwardButtonStyle.up = getDefaultSkin().getDrawable("fast-forward");
|
|
||||||
getDefaultSkin().add("fast-forward-button", fastForwardButtonStyle);
|
|
||||||
|
|
||||||
ImageButtonStyle reverseButtonStyle = new ImageButtonStyle();
|
|
||||||
reverseButtonStyle.down = getDefaultSkin().getDrawable("rewind-down");
|
|
||||||
reverseButtonStyle.up = getDefaultSkin().getDrawable("rewind");
|
|
||||||
getDefaultSkin().add("rewind-button", reverseButtonStyle);
|
|
||||||
|
|
||||||
CheckBoxStyle shuffleButtonStyle = new CheckBoxStyle(defaultCheckBox);
|
|
||||||
shuffleButtonStyle.checkboxOff = getDefaultSkin().getDrawable("shuffle");
|
|
||||||
shuffleButtonStyle.checkboxOn = getDefaultSkin().getDrawable("shuffle-down");
|
|
||||||
getDefaultSkin().add("shuffle-button", shuffleButtonStyle);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
core/src/zero1hd/rhythmbullet/audio/AudioProcessorFactory.java
Executable file
12
core/src/zero1hd/rhythmbullet/audio/AudioProcessorFactory.java
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
package zero1hd.rhythmbullet.audio;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
|
import zero1hd.rhythmbullet.audio.processor.AudioProcessor;
|
||||||
|
|
||||||
|
public interface AudioProcessorFactory {
|
||||||
|
/**
|
||||||
|
* @return a new {@link #zero1hd.rhythmbullet.audio.processor.AudioProcessor()} from the appropriate platform.
|
||||||
|
*/
|
||||||
|
public AudioProcessor newMP3AudioProcessor(FileHandle fileHandle);
|
||||||
|
}
|
37
core/src/zero1hd/rhythmbullet/audio/MinimalAudioHeader.java
Executable file
37
core/src/zero1hd/rhythmbullet/audio/MinimalAudioHeader.java
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
package zero1hd.rhythmbullet.audio;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jaudiotagger.audio.AudioFile;
|
||||||
|
import org.jaudiotagger.audio.AudioFileIO;
|
||||||
|
import org.jaudiotagger.audio.AudioHeader;
|
||||||
|
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||||
|
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||||
|
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||||
|
import org.jaudiotagger.tag.TagException;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
|
public class MinimalAudioHeader {
|
||||||
|
private int sampleRate, channelCount;
|
||||||
|
|
||||||
|
public MinimalAudioHeader(FileHandle musicFile) {
|
||||||
|
try {
|
||||||
|
AudioFile file = AudioFileIO.read(musicFile.file());
|
||||||
|
AudioHeader header = file.getAudioHeader();
|
||||||
|
sampleRate = header.getSampleRateAsNumber();
|
||||||
|
channelCount = (header.getChannels().equals("Mono") ? 1 : 2);
|
||||||
|
} catch (CannotReadException | IOException | TagException | ReadOnlyFileException
|
||||||
|
| InvalidAudioFrameException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSampleRate() {
|
||||||
|
return sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChannelCount() {
|
||||||
|
return channelCount;
|
||||||
|
}
|
||||||
|
}
|
223
core/src/zero1hd/rhythmbullet/audio/MusicController.java
Executable file
223
core/src/zero1hd/rhythmbullet/audio/MusicController.java
Executable file
@ -0,0 +1,223 @@
|
|||||||
|
package zero1hd.rhythmbullet.audio;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Preferences;
|
||||||
|
import com.badlogic.gdx.audio.Music;
|
||||||
|
import com.badlogic.gdx.audio.Music.OnCompletionListener;
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages current games music playback and does this in tandem with the {@link MusicList} by asking to retrieve files and then feeding it to LibGDX.
|
||||||
|
* Notifies observers when a new song is loaded.
|
||||||
|
* The loading model is like taking a disk and loading it into a player. It doesn't necessarily mean it'll play right away, but its ready and the only track that has a stream opened.
|
||||||
|
* @author yunya
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MusicController extends Observable implements OnCompletionListener, Observer {
|
||||||
|
public enum States {
|
||||||
|
Loaded, Playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MusicList musicList;
|
||||||
|
private MinimalAudioHeader musicHeader;
|
||||||
|
private Music music;
|
||||||
|
private int currentPlaybackIndex;
|
||||||
|
private boolean autoPlay;
|
||||||
|
private boolean shuffle;
|
||||||
|
private Random rand;
|
||||||
|
private Preferences prefs;
|
||||||
|
|
||||||
|
public MusicController(MusicList musicList, Preferences prefs) {
|
||||||
|
if (prefs == null) throw new NullPointerException("preferences can't be null...");
|
||||||
|
if (musicList == null) throw new NullPointerException("music list can't be null...");
|
||||||
|
musicList.addObserver(this);
|
||||||
|
this.prefs = prefs;
|
||||||
|
this.musicList = musicList;
|
||||||
|
rand = new Random();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This play method automatically sets the volume.
|
||||||
|
*/
|
||||||
|
public void play() {
|
||||||
|
if (music != null) {
|
||||||
|
Gdx.app.debug("MusicListController", "Playing from MLC.");
|
||||||
|
music.play();
|
||||||
|
music.setVolume(prefs.getFloat("music vol", 1f));
|
||||||
|
notifyObservers(States.Playing);
|
||||||
|
} else {
|
||||||
|
Gdx.app.debug("MusicListController", "failed to begin playing. Load the music!!!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to pause current song. Does nothing if no song is playing or loaded.
|
||||||
|
*/
|
||||||
|
public void pause() {
|
||||||
|
if (music != null) {
|
||||||
|
music.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads music based on the index in the {@link MusicList}.
|
||||||
|
* @param index of music to play
|
||||||
|
*/
|
||||||
|
public void setMusicByIndex(int index) {
|
||||||
|
this.currentPlaybackIndex = index;
|
||||||
|
loadMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Goes to the next track
|
||||||
|
*/
|
||||||
|
public void skip() {
|
||||||
|
currentPlaybackIndex++;
|
||||||
|
if (shuffle) {
|
||||||
|
shuffle(false);
|
||||||
|
}
|
||||||
|
loadMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Goes to the previous track
|
||||||
|
*/
|
||||||
|
public void previous() {
|
||||||
|
currentPlaybackIndex--;
|
||||||
|
if (shuffle) {
|
||||||
|
shuffle(false);
|
||||||
|
}
|
||||||
|
loadMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompletion(Music music) {
|
||||||
|
if (autoPlay) {
|
||||||
|
if (shuffle) {
|
||||||
|
shuffle(false);
|
||||||
|
} else {
|
||||||
|
currentPlaybackIndex++;
|
||||||
|
}
|
||||||
|
loadMusic();
|
||||||
|
play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuffles the controller whether the shuffle boolean is true or false.
|
||||||
|
* @param load whether this method should also make sure to load the music, dispose of the last one, etc. Normally called unless you plan to manually call it elsewhere.
|
||||||
|
*/
|
||||||
|
public void shuffle(boolean load) {
|
||||||
|
Gdx.app.debug("MusicListController", "shuffled.");
|
||||||
|
if (musicList.getTotal() == 0) {
|
||||||
|
currentPlaybackIndex = 0;
|
||||||
|
} else {
|
||||||
|
currentPlaybackIndex = rand.nextInt(musicList.getTotal());
|
||||||
|
}
|
||||||
|
if (load) {
|
||||||
|
loadMusic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAutoPlay(boolean autoPlay) {
|
||||||
|
this.autoPlay = autoPlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShuffle(boolean shuffle) {
|
||||||
|
this.shuffle = shuffle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShuffle() {
|
||||||
|
return shuffle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAutoPlay() {
|
||||||
|
return autoPlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the current selected song.
|
||||||
|
*/
|
||||||
|
public void loadMusic() {
|
||||||
|
Gdx.app.debug("MusicListController", "music is being loaded and listeners are being notified.");
|
||||||
|
musicHeader = null;
|
||||||
|
if (music != null) {
|
||||||
|
music.dispose();
|
||||||
|
}
|
||||||
|
if (currentPlaybackIndex < 0) {
|
||||||
|
currentPlaybackIndex = musicList.getTotal()-1;
|
||||||
|
}
|
||||||
|
if (currentPlaybackIndex >= musicList.getTotal()) {
|
||||||
|
currentPlaybackIndex = 0;
|
||||||
|
}
|
||||||
|
this.music = Gdx.audio.newMusic(musicList.getMusicArray().get(currentPlaybackIndex));
|
||||||
|
music.setOnCompletionListener(this);
|
||||||
|
|
||||||
|
setChanged();
|
||||||
|
|
||||||
|
if (autoPlay) {
|
||||||
|
play();
|
||||||
|
}
|
||||||
|
notifyObservers(States.Loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MusicList getMusicList() {
|
||||||
|
return musicList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileHandle getCurrentMusicFileHandle() {
|
||||||
|
return musicList.getSongFileHandleFromIndex(currentPlaybackIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MinimalAudioHeader getCurrentMusicHeader() {
|
||||||
|
if (musicHeader != null) {
|
||||||
|
return musicHeader;
|
||||||
|
} else {
|
||||||
|
return musicList.newMinimalAudioHeader(getCurrentMusicFileHandle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
if (o == musicList) {
|
||||||
|
loadMusic();
|
||||||
|
if (autoPlay) {
|
||||||
|
play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCurrentSongName() {
|
||||||
|
return getCurrentMusicFileHandle().nameWithoutExtension();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getCurrentPosition() {
|
||||||
|
if (music != null) {
|
||||||
|
return music.getPosition();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMusicPosition(float position) {
|
||||||
|
if (music != null) {
|
||||||
|
music.setPosition(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPlaying() {
|
||||||
|
return music.isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current music. In no circumstances should this be used to begin playing or it would be playing independent of the controller.
|
||||||
|
* Doing otherwise would mean you are playing the music separately of the controller.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Music getCurrentMusic() {
|
||||||
|
return music;
|
||||||
|
}
|
||||||
|
}
|
135
core/src/zero1hd/rhythmbullet/audio/MusicList.java
Executable file
135
core/src/zero1hd/rhythmbullet/audio/MusicList.java
Executable file
@ -0,0 +1,135 @@
|
|||||||
|
package zero1hd.rhythmbullet.audio;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
|
import zero1hd.rhythmbullet.audio.processor.AudioProcessor;
|
||||||
|
import zero1hd.rhythmbullet.audio.processor.WAVAudioProcessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A music list made to store paths to all the songs within a given directory. Can activate the music calling {@link #newAudioProcessor(FileHandle)} and its derivatives.
|
||||||
|
* Is observable, meaning, given there are observers, will notify when the list completes a refresh.
|
||||||
|
* @author yunya
|
||||||
|
*/
|
||||||
|
public class MusicList extends Observable {
|
||||||
|
private Array<FileHandle> musicList;
|
||||||
|
private RecursiveMusicSearchThread searchThread;
|
||||||
|
private AudioProcessorFactory audioProcFactory;
|
||||||
|
private boolean searched;
|
||||||
|
|
||||||
|
public MusicList(AudioProcessorFactory audioProcessorFactory) {
|
||||||
|
this.audioProcFactory = audioProcessorFactory;
|
||||||
|
musicList = new Array<>();
|
||||||
|
searchThread = new RecursiveMusicSearchThread("Music Search Thread");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper method that uses async refresh.
|
||||||
|
* Also notifies listeners that are on the main thread.
|
||||||
|
*/
|
||||||
|
public void asyncSearch() {
|
||||||
|
searchThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchPath(String searchPath) {
|
||||||
|
searchThread.setSearchDirectory(Gdx.files.absolute(searchPath));
|
||||||
|
setChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param file
|
||||||
|
* @return a {@link #zero1hd.rhythmbullet.audio.processor.AudioProcessor()} of the given music file. Will return null if theres a format error.
|
||||||
|
*/
|
||||||
|
public AudioProcessor newAudioProcessor(FileHandle file) {
|
||||||
|
if (file.extension().equalsIgnoreCase("wav")) {
|
||||||
|
return new WAVAudioProcessor(file);
|
||||||
|
} else if (file.extension().equalsIgnoreCase("mp3")) {
|
||||||
|
return audioProcFactory.newMP3AudioProcessor(file);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param file the music file that you need the header for.
|
||||||
|
* @return the header containing minimal info of the song.
|
||||||
|
*/
|
||||||
|
public MinimalAudioHeader newMinimalAudioHeader(FileHandle file) {
|
||||||
|
return new MinimalAudioHeader(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioProcessor newAudioProcessorFromIndex(int index) {
|
||||||
|
if (!searched) Gdx.app.debug("SongList", "Warning, this list hasn't even searched yet...");
|
||||||
|
return newAudioProcessor(musicList.get(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public FileHandle getSongFileHandleFromIndex(int index) {
|
||||||
|
if (!searched) Gdx.app.debug("SongList", "Warning, this list hasn't even searched yet...");
|
||||||
|
return musicList.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Array<FileHandle> getMusicArray() {
|
||||||
|
return musicList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSearched() {
|
||||||
|
return searched;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void searchComplete() {
|
||||||
|
notifyObservers();
|
||||||
|
searched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTotal() {
|
||||||
|
return musicList.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RecursiveMusicSearchThread implements Runnable {
|
||||||
|
private Thread thread;
|
||||||
|
private String threadName;
|
||||||
|
private FileHandle directory;
|
||||||
|
|
||||||
|
public RecursiveMusicSearchThread(String name) {
|
||||||
|
this.threadName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSearchDirectory(FileHandle directory) {
|
||||||
|
this.directory = directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
musicList = recursiveMusicSearch(directory);
|
||||||
|
searchComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if (thread == null && !thread.isAlive()) {
|
||||||
|
thread = new Thread(this, threadName);
|
||||||
|
thread.start();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Two " + threadName + " instances (threads) were created. This is not allowed for optimization as there is no reason to have two running.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Array<FileHandle> recursiveMusicSearch(FileHandle fileHandle) {
|
||||||
|
Array<FileHandle> musicFiles = new Array<>();
|
||||||
|
FileHandle[] files = fileHandle.list();
|
||||||
|
for (int i = 0; i < files.length; i++) {
|
||||||
|
if (files[i].isDirectory()) {
|
||||||
|
musicFiles.addAll(recursiveMusicSearch(files[i]));
|
||||||
|
} else {
|
||||||
|
if (files[i].extension().equalsIgnoreCase("wav") || files[i].extension().equalsIgnoreCase("mp3")) {
|
||||||
|
musicFiles.add(files[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return musicFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
core/src/zero1hd/rhythmbullet/audio/MusicMetadataController.java
Executable file
102
core/src/zero1hd/rhythmbullet/audio/MusicMetadataController.java
Executable file
@ -0,0 +1,102 @@
|
|||||||
|
package zero1hd.rhythmbullet.audio;
|
||||||
|
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
|
import zero1hd.rhythmbullet.audio.metadata.AudioMetadata;
|
||||||
|
import zero1hd.rhythmbullet.audio.metadata.MP3Metadata;
|
||||||
|
import zero1hd.rhythmbullet.audio.metadata.WAVMetadata;
|
||||||
|
|
||||||
|
public class MusicMetadataController implements Disposable, Observer {
|
||||||
|
private MusicList musicList;
|
||||||
|
private Array<AudioMetadata> metadataArray;
|
||||||
|
private MetadataLoadingThread loadingThread;
|
||||||
|
private volatile boolean searching;
|
||||||
|
|
||||||
|
public MusicMetadataController(MusicList musicList) {
|
||||||
|
this.musicList = musicList;
|
||||||
|
metadataArray = new Array<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MusicList getMusicList() {
|
||||||
|
return musicList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-blocking, loads on separate thread.
|
||||||
|
*/
|
||||||
|
public void loadSongInfo() {
|
||||||
|
loadingThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDone() {
|
||||||
|
return (metadataArray.size == musicList.getMusicArray().size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
for (int i = 0; i < metadataArray.size; i++) {
|
||||||
|
metadataArray.get(i).dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return metadataArray.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AudioMetadata getMetadata(int index) {
|
||||||
|
synchronized (loadingThread) {
|
||||||
|
return metadataArray.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AudioMetadata getInfo(FileHandle filehandle) {
|
||||||
|
return metadataArray.get(musicList.getMusicArray().indexOf(filehandle, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSearching() {
|
||||||
|
return searching;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MetadataLoadingThread implements Runnable {
|
||||||
|
private Thread thread;
|
||||||
|
private String name = "Metadata-Load";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
searching = true;
|
||||||
|
for (int i = 0; i < metadataArray.size; i++) {
|
||||||
|
metadataArray.get(i).dispose();
|
||||||
|
}
|
||||||
|
metadataArray.clear();
|
||||||
|
for (int i = 0; i < musicList.getTotal(); i++) {
|
||||||
|
FileHandle musicFile = musicList.getMusicArray().get(i);
|
||||||
|
synchronized (this) {
|
||||||
|
if (musicFile.extension().equalsIgnoreCase("wav")) {
|
||||||
|
metadataArray.add(new WAVMetadata(musicFile));
|
||||||
|
} else if (musicFile.extension().equalsIgnoreCase("mp3")) {
|
||||||
|
metadataArray.add(new MP3Metadata(musicFile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
searching = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if (thread != null && !thread.isAlive()) {
|
||||||
|
thread = new Thread(this, name);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
package zero1hd.rhythmbullet.audio;
|
|
||||||
|
|
||||||
public class RhythmBulletMetadata {
|
|
||||||
private String highScore = "0", lastPlayed = "N/A", difficulty = "N/A";
|
|
||||||
|
|
||||||
public void setHighScore(String highScore) {
|
|
||||||
this.highScore = highScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastPlayed(String lastPlayed) {
|
|
||||||
this.lastPlayed = lastPlayed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDifficulty(String difficulty) {
|
|
||||||
this.difficulty = difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHighScore() {
|
|
||||||
return highScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDifficulty() {
|
|
||||||
return difficulty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastPlayed() {
|
|
||||||
return lastPlayed;
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package zero1hd.rhythmbullet.audio;
|
package zero1hd.rhythmbullet.audio.metadata;
|
||||||
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
@ -1,4 +1,4 @@
|
|||||||
package zero1hd.rhythmbullet.audio;
|
package zero1hd.rhythmbullet.audio.metadata;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package zero1hd.rhythmbullet.audio;
|
package zero1hd.rhythmbullet.audio.metadata;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -7,6 +7,7 @@ import javax.sound.sampled.AudioInputStream;
|
|||||||
import javax.sound.sampled.AudioSystem;
|
import javax.sound.sampled.AudioSystem;
|
||||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
public class WAVAudioProcessor implements AudioProcessor {
|
public class WAVAudioProcessor implements AudioProcessor {
|
||||||
@ -17,11 +18,18 @@ public class WAVAudioProcessor implements AudioProcessor {
|
|||||||
private AudioInputStream audioInputStream;
|
private AudioInputStream audioInputStream;
|
||||||
private boolean initiated;
|
private boolean initiated;
|
||||||
|
|
||||||
public WAVAudioProcessor(FileHandle fileHandle, int windowSize) throws IOException, UnsupportedAudioFileException {
|
public WAVAudioProcessor(FileHandle fileHandle) {
|
||||||
this.fileHandle = fileHandle;
|
this.fileHandle = fileHandle;
|
||||||
AudioFormat format = AudioSystem.getAudioFileFormat(fileHandle.file()).getFormat();
|
AudioFormat format;
|
||||||
|
try {
|
||||||
|
format = AudioSystem.getAudioFileFormat(fileHandle.file()).getFormat();
|
||||||
stereo = format.getChannels() > 1 ? true : false;
|
stereo = format.getChannels() > 1 ? true : false;
|
||||||
sampleRate = (int) format.getSampleRate();
|
sampleRate = (int) format.getSampleRate();
|
||||||
|
} catch (UnsupportedAudioFileException | IOException e) {
|
||||||
|
Gdx.app.debug("WAVAudioProcessor", "Couldn't instantiate WAVAUdioProcessor due to error.");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -12,7 +12,6 @@ import com.badlogic.gdx.math.Vector2;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
|
||||||
|
|
||||||
public class HorizontalVisualizer implements Disposable {
|
public class HorizontalVisualizer implements Disposable {
|
||||||
private Pixmap pixmap;
|
private Pixmap pixmap;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package zero1hd.rhythmbullet.util;
|
package zero1hd.rhythmbullet.util;
|
||||||
|
|
||||||
public interface AdvancedResizeScreen {
|
public interface ResizeReadyScreen {
|
||||||
/**
|
/**
|
||||||
* called before assets are cleared from memory.
|
* called before assets are cleared from memory.
|
||||||
*/
|
*/
|
224
desktop/src/zero1hd/rhythmbullet/desktop/DesktopAssetPack.java
Executable file
224
desktop/src/zero1hd/rhythmbullet/desktop/DesktopAssetPack.java
Executable file
@ -0,0 +1,224 @@
|
|||||||
|
package zero1hd.rhythmbullet.desktop;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.assets.AssetManager;
|
||||||
|
import com.badlogic.gdx.audio.Sound;
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator.FreeTypeFontParameter;
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox.CheckBoxStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.List.ListStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane.ScrollPaneStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox.SelectBoxStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Slider.SliderStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.TextField.TextFieldStyle;
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Window.WindowStyle;
|
||||||
|
|
||||||
|
import zero1hd.rhythmbullet.AssetPack;
|
||||||
|
|
||||||
|
public class DesktopAssetPack implements AssetPack {
|
||||||
|
private FreeTypeFontGenerator default_fontGenerator;
|
||||||
|
private FreeTypeFontGenerator darktech_ldr_fontGenerator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initiateResources() {
|
||||||
|
default_fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/Gasalt-Regular.ttf"));
|
||||||
|
darktech_ldr_fontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/darktech_ldr.ttf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueTextures(AssetManager assetManager) {
|
||||||
|
assetManager.load("uiskin.atlas", TextureAtlas.class);
|
||||||
|
assetManager.load("Tech-Circle1.png", Texture.class);
|
||||||
|
assetManager.load("polyjet-standard.png", Texture.class);
|
||||||
|
assetManager.load("keyboard.atlas", TextureAtlas.class);
|
||||||
|
assetManager.load("cybercircle3B.png", Texture.class);
|
||||||
|
assetManager.load("title.png", Texture.class);
|
||||||
|
assetManager.load("cybercircle1.png", Texture.class);
|
||||||
|
assetManager.load("defaultCover.png", Texture.class);
|
||||||
|
assetManager.load("laser.png", Texture.class);
|
||||||
|
assetManager.load("pellet.png", Texture.class);
|
||||||
|
assetManager.load("shard.png", Texture.class);
|
||||||
|
assetManager.load("bar.png", Texture.class);
|
||||||
|
assetManager.load("flake.png", Texture.class);
|
||||||
|
assetManager.load("void_circle.png", Texture.class);
|
||||||
|
assetManager.load("tpSelector.png", Texture.class);
|
||||||
|
assetManager.load("backgrounds/mainBG.png", Texture.class);
|
||||||
|
assetManager.load("magic1.png", Texture.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueSFX(AssetManager assetManager) {
|
||||||
|
assetManager.load("pop_open.ogg", Sound.class);
|
||||||
|
assetManager.load("pop_close.ogg", Sound.class);
|
||||||
|
assetManager.load("laser.ogg", Sound.class);
|
||||||
|
assetManager.load("explosion.ogg", Sound.class);
|
||||||
|
assetManager.load("disintegrate.ogg", Sound.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queueParticles(AssetManager assetManager) {
|
||||||
|
assetManager.load("standard_thrust.p", ParticleEffect.class);
|
||||||
|
assetManager.load("teleport-cloak.p", ParticleEffect.class);
|
||||||
|
assetManager.load("explosion-s.p", ParticleEffect.class);
|
||||||
|
assetManager.load("beateffect.p", ParticleEffect.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setupSkin(Skin skin) {
|
||||||
|
skin.add("default", Color.WHITE);
|
||||||
|
skin.add("inverse", Color.BLACK);
|
||||||
|
|
||||||
|
TextButtonStyle defaultTextButton = new TextButtonStyle();
|
||||||
|
defaultTextButton.up = skin.getDrawable("rect");
|
||||||
|
defaultTextButton.down = skin.getDrawable("rect-down");
|
||||||
|
defaultTextButton.font = skin.getFont("default-font");
|
||||||
|
defaultTextButton.fontColor = skin.getColor("default");
|
||||||
|
defaultTextButton.disabled = skin.getDrawable("rect-disabled");
|
||||||
|
skin.add("default", defaultTextButton);
|
||||||
|
|
||||||
|
TextButtonStyle subTextbutton = new TextButtonStyle(defaultTextButton);
|
||||||
|
subTextbutton.font = skin.getFont("sub-font");
|
||||||
|
skin.add("sub", subTextbutton);
|
||||||
|
|
||||||
|
TextButtonStyle windowTextButton = new TextButtonStyle(defaultTextButton);
|
||||||
|
windowTextButton.font = skin.getFont("window-font");
|
||||||
|
skin.add("window", windowTextButton);
|
||||||
|
|
||||||
|
TextButtonStyle textButtonLeft = new TextButtonStyle();
|
||||||
|
textButtonLeft.up = skin.getDrawable("left-button");
|
||||||
|
textButtonLeft.down = skin.getDrawable("left-button-down");
|
||||||
|
textButtonLeft.font = skin.getFont("default-font");
|
||||||
|
textButtonLeft.fontColor = skin.getColor("default");
|
||||||
|
skin.add("left", textButtonLeft);
|
||||||
|
|
||||||
|
SliderStyle defaultSlider = new SliderStyle(skin.getDrawable("default-slider"), skin.getDrawable("default-slider-knob"));
|
||||||
|
skin.add("default-horizontal", defaultSlider);
|
||||||
|
|
||||||
|
SliderStyle vertSlider = new SliderStyle(defaultSlider);
|
||||||
|
vertSlider.knob = skin.getDrawable("vertical-slider-knob");
|
||||||
|
skin.add("default-vertical", vertSlider);
|
||||||
|
|
||||||
|
LabelStyle defaultLabel = new LabelStyle();
|
||||||
|
defaultLabel.font = skin.getFont("default-font");
|
||||||
|
defaultLabel.fontColor = skin.getColor("default");
|
||||||
|
skin.add("default", defaultLabel);
|
||||||
|
|
||||||
|
TextFieldStyle defaultTextField = new TextFieldStyle(skin.getFont("sub-font"), skin.getColor("default"), skin.getDrawable("cursor"), skin.getDrawable("selection"), skin.getDrawable("textfield"));
|
||||||
|
skin.add("default", defaultTextField);
|
||||||
|
|
||||||
|
TextFieldStyle uiTextField = new TextFieldStyle(defaultTextField);
|
||||||
|
uiTextField.font = skin.getFont("window-font");
|
||||||
|
skin.add("ui", uiTextField);
|
||||||
|
|
||||||
|
WindowStyle defaultWindow = new WindowStyle(skin.getFont("window-font"), skin.getColor("default"), skin.getDrawable("default-window"));
|
||||||
|
skin.add("default", defaultWindow);
|
||||||
|
|
||||||
|
WindowStyle tintedWindow = new WindowStyle(defaultWindow);
|
||||||
|
tintedWindow.titleFontColor = skin.getColor("inverse");
|
||||||
|
tintedWindow.background = skin.getDrawable("tinted-window");
|
||||||
|
skin.add("tinted", tintedWindow);
|
||||||
|
|
||||||
|
ListStyle defaultList = new ListStyle(skin.getFont("window-font"), skin.getColor("inverse"), skin.getColor("default"), skin.getDrawable("selection"));
|
||||||
|
skin.add("default", defaultList);
|
||||||
|
|
||||||
|
ScrollPaneStyle defaultScrollPane = new ScrollPaneStyle();
|
||||||
|
defaultScrollPane.vScroll = skin.getDrawable("default-scroll");
|
||||||
|
defaultScrollPane.hScrollKnob = skin.getDrawable("default-round-large");
|
||||||
|
defaultScrollPane.hScroll = skin.getDrawable("default-scroll");
|
||||||
|
defaultScrollPane.vScrollKnob = skin.getDrawable("default-round-large");
|
||||||
|
skin.add("default", defaultScrollPane);
|
||||||
|
|
||||||
|
CheckBoxStyle defaultCheckBox = new CheckBoxStyle(skin.getDrawable("check-off"), skin.getDrawable("check-on"), skin.getFont("window-font"), skin.getColor("default"));
|
||||||
|
defaultCheckBox.checkboxOffDisabled = skin.getDrawable("check-disabled");
|
||||||
|
skin.add("default", defaultCheckBox);
|
||||||
|
|
||||||
|
SelectBoxStyle defaultSelectBox = new SelectBoxStyle(skin.getFont("default-font"), skin.getColor("default"), skin.getDrawable("default-select"), defaultScrollPane, defaultList);
|
||||||
|
skin.add("default", defaultSelectBox);
|
||||||
|
|
||||||
|
Gdx.app.debug("Prelaunch Debug Info", "UI Skin has been defined.");
|
||||||
|
|
||||||
|
CheckBoxStyle playButtonStyle = new CheckBoxStyle(defaultCheckBox);
|
||||||
|
playButtonStyle.checkboxOn = skin.getDrawable("play-down");
|
||||||
|
playButtonStyle.checkboxOff = skin.getDrawable("play");
|
||||||
|
skin.add("play-button", playButtonStyle);
|
||||||
|
|
||||||
|
ImageButtonStyle pauseButtonStyle = new ImageButtonStyle();
|
||||||
|
pauseButtonStyle.down = skin.getDrawable("pause-down");
|
||||||
|
pauseButtonStyle.up = skin.getDrawable("pause");
|
||||||
|
skin.add("pause-button", pauseButtonStyle);
|
||||||
|
|
||||||
|
ImageButtonStyle fastForwardButtonStyle = new ImageButtonStyle();
|
||||||
|
fastForwardButtonStyle.down = skin.getDrawable("fast-forward-down");
|
||||||
|
fastForwardButtonStyle.up = skin.getDrawable("fast-forward");
|
||||||
|
skin.add("fast-forward-button", fastForwardButtonStyle);
|
||||||
|
|
||||||
|
ImageButtonStyle reverseButtonStyle = new ImageButtonStyle();
|
||||||
|
reverseButtonStyle.down = skin.getDrawable("rewind-down");
|
||||||
|
reverseButtonStyle.up = skin.getDrawable("rewind");
|
||||||
|
skin.add("rewind-button", reverseButtonStyle);
|
||||||
|
|
||||||
|
CheckBoxStyle shuffleButtonStyle = new CheckBoxStyle(defaultCheckBox);
|
||||||
|
shuffleButtonStyle.checkboxOff = skin.getDrawable("shuffle");
|
||||||
|
shuffleButtonStyle.checkboxOn = skin.getDrawable("shuffle-down");
|
||||||
|
skin.add("shuffle-button", shuffleButtonStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateFonts(Skin skin) {
|
||||||
|
int height = Gdx.graphics.getHeight();
|
||||||
|
|
||||||
|
skin.add("window-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
||||||
|
{
|
||||||
|
size = 18;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
skin.add("sub-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
||||||
|
{
|
||||||
|
size = fontScale(0.05f, height);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
skin.add("default-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
||||||
|
{
|
||||||
|
size = fontScale(0.07f, height);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
skin.add("large-font", default_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
||||||
|
{
|
||||||
|
size = fontScale(0.085f, height);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
skin.add("special-font", darktech_ldr_fontGenerator.generateFont(new FreeTypeFontParameter() {
|
||||||
|
{
|
||||||
|
size = fontScale(0.075f, height);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int fontScale(float fontSize, int height) {
|
||||||
|
int size = MathUtils.round(Gdx.graphics.getDensity()*(fontSize*height));
|
||||||
|
if (size >= 200) {
|
||||||
|
size = 200;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void complete(AssetManager assetManager) {
|
||||||
|
assetManager.get("standard_thrust.p", ParticleEffect.class).flipY();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
darktech_ldr_fontGenerator.dispose();
|
||||||
|
default_fontGenerator.dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,5 @@
|
|||||||
package zero1hd.rhythmbullet.desktop;
|
package zero1hd.rhythmbullet.desktop;
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||||
|
|
||||||
@ -11,16 +8,15 @@ import zero1hd.rhythmbullet.desktop.screens.SplashScreen;
|
|||||||
|
|
||||||
public class DesktopLauncher {
|
public class DesktopLauncher {
|
||||||
public static void main (String[] arg) {
|
public static void main (String[] arg) {
|
||||||
Logger.getLogger("org.jaudiotagger").setLevel(Level.OFF);
|
|
||||||
|
|
||||||
RhythmBullet core;
|
RhythmBullet core;
|
||||||
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
|
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
|
||||||
config.title = "Rhythm Bullet";
|
config.title = "Rhythm Bullet";
|
||||||
config.resizable = false;
|
config.resizable = false;
|
||||||
config.allowSoftwareMode = true;
|
config.allowSoftwareMode = true;
|
||||||
config.useHDPI = true;
|
config.useHDPI = true;
|
||||||
|
|
||||||
core = new RhythmBullet();
|
core = new RhythmBullet();
|
||||||
core.setInitialScreen(new SplashScreen(core));
|
core.setup(new SplashScreen(), new DesktopAssetPack());
|
||||||
new LwjglApplication(core, config);
|
new LwjglApplication(core, config);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,64 +0,0 @@
|
|||||||
package zero1hd.rhythmbullet.desktop.audio;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.Preferences;
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicInfo;
|
|
||||||
|
|
||||||
public class MusicInfoController implements Disposable {
|
|
||||||
private MusicList musicList;
|
|
||||||
private ExecutorService exec;
|
|
||||||
private Array<MusicInfo> songInfoArray;
|
|
||||||
private Preferences musicAnnotation;
|
|
||||||
|
|
||||||
public MusicInfoController(MusicList musicList) {
|
|
||||||
this.musicList = musicList;
|
|
||||||
songInfoArray = new Array<>();
|
|
||||||
exec = Executors.newSingleThreadExecutor();
|
|
||||||
musicAnnotation = Gdx.app.getPreferences("MusicAnnotation");
|
|
||||||
}
|
|
||||||
|
|
||||||
public MusicList getMusicList() {
|
|
||||||
return musicList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Non-blocking, loads on separate thread.
|
|
||||||
*/
|
|
||||||
public void loadSongInfo() {
|
|
||||||
for (int i = 0; i < songInfoArray.size; i++) {
|
|
||||||
songInfoArray.get(i).dispose();
|
|
||||||
}
|
|
||||||
songInfoArray.clear();
|
|
||||||
exec.submit(() -> {
|
|
||||||
for (int i = 0; i < musicList.getTotal(); i++) {
|
|
||||||
MusicInfo musicInfo = new MusicInfo(musicList.getMusicArray().get(i), musicAnnotation);
|
|
||||||
musicInfo.loadInfo();
|
|
||||||
songInfoArray.add(musicInfo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDone() {
|
|
||||||
return (songInfoArray.size == musicList.getMusicArray().size);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
exec.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Array<MusicInfo> getSongInfoArray() {
|
|
||||||
return songInfoArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MusicInfo getInfo(FileHandle filehandle) {
|
|
||||||
return songInfoArray.get(musicList.getMusicArray().indexOf(filehandle, true));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,129 +0,0 @@
|
|||||||
package zero1hd.rhythmbullet.desktop.audio;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.Observable;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.badlogic.gdx.utils.Sort;
|
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
|
||||||
import zero1hd.rhythmbullet.desktop.audio.processor.MP3AudioProcessor;
|
|
||||||
|
|
||||||
public class MusicList extends Observable {
|
|
||||||
private Array<FileHandle> musicArray;
|
|
||||||
private String searchPath;
|
|
||||||
private boolean searched;
|
|
||||||
private ExecutorService exec;
|
|
||||||
|
|
||||||
public MusicList() {
|
|
||||||
musicArray = new Array<>();
|
|
||||||
exec = Executors.newSingleThreadExecutor();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Array<FileHandle> recursiveMusicFileList(FileHandle fileHandle) {
|
|
||||||
Array<FileHandle> musicFiles = new Array<>();
|
|
||||||
FileHandle[] files = fileHandle.list();
|
|
||||||
for (int i = 0; i < files.length; i++) {
|
|
||||||
if (files[i].isDirectory()) {
|
|
||||||
musicFiles.addAll(recursiveMusicFileList(files[i]));
|
|
||||||
} else {
|
|
||||||
if (files[i].extension().equalsIgnoreCase("wav") || files[i].extension().equalsIgnoreCase("mp3")) {
|
|
||||||
musicFiles.add(files[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return musicFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* refreshes song list, notifies any observers of the refresh while passing no argument to the notifier.
|
|
||||||
* Blocking.
|
|
||||||
*/
|
|
||||||
public void refresh(boolean notifyOnCompletion) {
|
|
||||||
searched = false;
|
|
||||||
musicArray.clear();
|
|
||||||
Gdx.app.debug("SongController", "Searching path: " + searchPath);
|
|
||||||
if (Gdx.files.absolute(searchPath).exists() && Gdx.files.absolute(searchPath).isDirectory()) {
|
|
||||||
musicArray.addAll(recursiveMusicFileList(Gdx.files.absolute(searchPath)));
|
|
||||||
}
|
|
||||||
if (!Gdx.files.external("RhythmBullet/Alan Walker - Spectre.mp3").exists()) {
|
|
||||||
Gdx.files.internal("music/Alan Walker - Spectre.mp3").copyTo(Gdx.files.external("RhythmBullet/Alan Walker - Spectre.mp3"));
|
|
||||||
}
|
|
||||||
musicArray.add(Gdx.files.external("RhythmBullet/Alan Walker - Spectre.mp3"));
|
|
||||||
setChanged();
|
|
||||||
Sort.instance().sort(musicArray, new Comparator<FileHandle>() {
|
|
||||||
@Override
|
|
||||||
public int compare(FileHandle o1, FileHandle o2) {
|
|
||||||
return o1.nameWithoutExtension().compareTo(o2.nameWithoutExtension());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
searched = true;
|
|
||||||
|
|
||||||
if (notifyOnCompletion) {
|
|
||||||
notifyObservers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper method that uses asynch refresh.
|
|
||||||
* Also notifies listeners that are on the main thread.
|
|
||||||
*/
|
|
||||||
public void asynchRefresh() {
|
|
||||||
searched = false;
|
|
||||||
exec.submit(() -> {
|
|
||||||
refresh(false);
|
|
||||||
Gdx.app.debug("Asynch-MusicList", "Async refresh done. Notification has been sent.");
|
|
||||||
Gdx.app.postRunnable(() -> {
|
|
||||||
notifyObservers();
|
|
||||||
searched = true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSearchPath(String searchPath) {
|
|
||||||
this.searchPath = searchPath;
|
|
||||||
setChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* creates an audio manager for the given music file.
|
|
||||||
* @param file
|
|
||||||
* @return a music manager of the given music file.
|
|
||||||
*/
|
|
||||||
public MusicManager getAudioData(FileHandle file) {
|
|
||||||
if (file.extension().equalsIgnoreCase("wav")) {
|
|
||||||
return new WAVManager(file);
|
|
||||||
} else if (file.extension().equalsIgnoreCase("mp3")) {
|
|
||||||
return new MP3AudioProcessor(file);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MusicManager getMusicManagerFromIndex(int index) {
|
|
||||||
if (!searched) Gdx.app.debug("SongList", "Warning, this list hasn't even searched yet...");
|
|
||||||
return getAudioData(musicArray.get(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotal() {
|
|
||||||
return musicArray.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileHandle getSongFileHandleFromIndex(int index) {
|
|
||||||
if (!searched) Gdx.app.debug("SongList", "Warning, this list hasn't even searched yet...");
|
|
||||||
return musicArray.get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Array<FileHandle> getMusicArray() {
|
|
||||||
return musicArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSearched() {
|
|
||||||
return searched;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
package zero1hd.rhythmbullet.desktop.audio;
|
|
||||||
|
|
||||||
import java.util.Observable;
|
|
||||||
import java.util.Observer;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.Preferences;
|
|
||||||
import com.badlogic.gdx.audio.Music;
|
|
||||||
import com.badlogic.gdx.audio.Music.OnCompletionListener;
|
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
|
||||||
|
|
||||||
public class MusicListController extends Observable implements OnCompletionListener, Observer {
|
|
||||||
private MusicList musicList;
|
|
||||||
private MusicManager mm;
|
|
||||||
private int currentPlaybackID;
|
|
||||||
private boolean autoPlay;
|
|
||||||
private boolean shuffle;
|
|
||||||
private Random rand;
|
|
||||||
|
|
||||||
private Preferences prefs;
|
|
||||||
public MusicListController(MusicList musicList, Preferences prefs) {
|
|
||||||
if (prefs == null) throw new NullPointerException("preferences can't be null...");
|
|
||||||
if (musicList == null) throw new NullPointerException("music list can't be null...");
|
|
||||||
musicList.addObserver(this);
|
|
||||||
this.prefs = prefs;
|
|
||||||
this.musicList = musicList;
|
|
||||||
rand = new Random();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This play method automatically sets the volume.
|
|
||||||
*/
|
|
||||||
public void play() {
|
|
||||||
if (mm != null) {
|
|
||||||
Gdx.app.debug("MusicListController", "Playing from MLC.");
|
|
||||||
mm.play();
|
|
||||||
mm.setVolume(prefs.getFloat("music vol", 1f));
|
|
||||||
} else {
|
|
||||||
Gdx.app.debug("MusicListController", "failed to begin playing. Load the music!!!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pause() {
|
|
||||||
if (mm != null) {
|
|
||||||
mm.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMusicByIndex(int index) {
|
|
||||||
this.currentPlaybackID = index;
|
|
||||||
loadMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void skip() {
|
|
||||||
currentPlaybackID++;
|
|
||||||
if (shuffle) {
|
|
||||||
shuffle(false);
|
|
||||||
}
|
|
||||||
loadMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void previous() {
|
|
||||||
currentPlaybackID--;
|
|
||||||
if (shuffle) {
|
|
||||||
shuffle(false);
|
|
||||||
}
|
|
||||||
loadMusic();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCompletion(Music music) {
|
|
||||||
if (autoPlay) {
|
|
||||||
if (shuffle) {
|
|
||||||
shuffle(false);
|
|
||||||
} else {
|
|
||||||
currentPlaybackID++;
|
|
||||||
}
|
|
||||||
loadMusic();
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shuffles the controller whether the shuffle boolean is true or false.
|
|
||||||
* @param load whether this method should also make sure to load the music, dispose of the last one, etc. Normally called unless you plan to manually call it elswhere.
|
|
||||||
*/
|
|
||||||
public void shuffle(boolean load) {
|
|
||||||
Gdx.app.debug("MusicListController", "shuffled.");
|
|
||||||
if (musicList.getTotal() == 0) {
|
|
||||||
currentPlaybackID = 0;
|
|
||||||
} else {
|
|
||||||
currentPlaybackID = rand.nextInt(musicList.getTotal());
|
|
||||||
}
|
|
||||||
if (load) {
|
|
||||||
loadMusic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutoPlay(boolean autoPlay) {
|
|
||||||
this.autoPlay = autoPlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShuffle(boolean shuffle) {
|
|
||||||
this.shuffle = shuffle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isShuffle() {
|
|
||||||
return shuffle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAutoPlay() {
|
|
||||||
return autoPlay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the current selected song.
|
|
||||||
*/
|
|
||||||
public void loadMusic() {
|
|
||||||
Gdx.app.debug("MusicListController", "music is being loaded and listeners are being notified.");
|
|
||||||
if (mm != null) {
|
|
||||||
mm.dispose();
|
|
||||||
}
|
|
||||||
if (currentPlaybackID < 0) {
|
|
||||||
currentPlaybackID = musicList.getTotal()-1;
|
|
||||||
}
|
|
||||||
if (currentPlaybackID >= musicList.getTotal()) {
|
|
||||||
currentPlaybackID = 0;
|
|
||||||
}
|
|
||||||
this.mm = musicList.getMusicManagerFromIndex(currentPlaybackID);
|
|
||||||
mm.setOnCompletionListener(this);
|
|
||||||
|
|
||||||
setChanged();
|
|
||||||
notifyObservers(mm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MusicList getMusicList() {
|
|
||||||
return musicList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public MusicManager getCurrentMusicManager() {
|
|
||||||
return mm;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(Observable o, Object arg) {
|
|
||||||
if (o == musicList) {
|
|
||||||
loadMusic();
|
|
||||||
play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
package zero1hd.rhythmbullet.desktop.audio.map;
|
|
||||||
|
|
||||||
import org.apache.commons.math3.random.MersenneTwister;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.FloatArray;
|
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.AudioDataPackage;
|
|
||||||
import zero1hd.rhythmbullet.entity.EntityManager;
|
|
||||||
import zero1hd.rhythmbullet.entity.coordinator.CoordinatorManager;
|
|
||||||
import zero1hd.rhythmbullet.game.EntitySpawnInfo;
|
|
||||||
import zero1hd.rhythmbullet.game.GamePlayMap;
|
|
||||||
|
|
||||||
public class RhythmMapAlgorithm implements Runnable {
|
|
||||||
|
|
||||||
private EntityManager em;
|
|
||||||
private CoordinatorManager cm;
|
|
||||||
|
|
||||||
private FloatArray bassPeaks;
|
|
||||||
private FloatArray mPeaks;
|
|
||||||
private FloatArray umPeaks;
|
|
||||||
private MersenneTwister rand;
|
|
||||||
private GamePlayMap map;
|
|
||||||
|
|
||||||
private float avgBass;
|
|
||||||
private float avgUM;
|
|
||||||
private float avgSPB;
|
|
||||||
private float umMax, bassMax;
|
|
||||||
|
|
||||||
private float speedMod, healthMod, difficultyMod;
|
|
||||||
|
|
||||||
private float windowPerSecond;
|
|
||||||
|
|
||||||
private volatile int progress;
|
|
||||||
public RhythmMapAlgorithm(EntityManager em, CoordinatorManager cm, AudioDataPackage adp, float speedMod, float healthMod, float difficultyMod) {
|
|
||||||
this.cm = cm;
|
|
||||||
this.em = em;
|
|
||||||
|
|
||||||
bassPeaks = adp.getBassPeaks();
|
|
||||||
mPeaks = adp.getmPeaks();
|
|
||||||
umPeaks = adp.getuMPeaks();
|
|
||||||
map = new GamePlayMap(adp.getMusicInfo(), umPeaks.size);
|
|
||||||
rand = new MersenneTwister(adp.getPUID());
|
|
||||||
avgSPB = adp.getAvgSPB();
|
|
||||||
windowPerSecond = 1/adp.getSecPerWin();
|
|
||||||
|
|
||||||
this.speedMod = speedMod;
|
|
||||||
this.healthMod = healthMod;
|
|
||||||
this.difficultyMod = difficultyMod;
|
|
||||||
|
|
||||||
umMax = adp.getuMMaxval();
|
|
||||||
avgUM = adp.getuMAvg();
|
|
||||||
|
|
||||||
bassMax = adp.getBassMaxVal();
|
|
||||||
avgBass = adp.getBassAvg();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EntitySpawnInfo esi;
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
map.beginBuild();
|
|
||||||
//TODO Map gen algorithm
|
|
||||||
map.endBuild();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized GamePlayMap getMap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized int getProgress() {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package zero1hd.rhythmbullet.desktop.audio.processor;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
|
||||||
|
import zero1hd.rhythmbullet.audio.AudioProcessorFactory;
|
||||||
|
import zero1hd.rhythmbullet.audio.processor.AudioProcessor;
|
||||||
|
|
||||||
|
public class DesktopAudioProcessorFactory implements AudioProcessorFactory {
|
||||||
|
@Override
|
||||||
|
public AudioProcessor newMP3AudioProcessor(FileHandle fileHandle) {
|
||||||
|
return new MP3AudioProcessor(fileHandle);
|
||||||
|
}
|
||||||
|
}
|
@ -4,56 +4,64 @@ import static org.lwjgl.openal.AL10.alGetSourcef;
|
|||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
|
||||||
import org.lwjgl.openal.AL11;
|
import org.lwjgl.openal.AL11;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.backends.lwjgl.audio.OpenALMusic;
|
import com.badlogic.gdx.backends.lwjgl.audio.OpenALMusic;
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
import com.badlogic.gdx.utils.reflect.Field;
|
import com.badlogic.gdx.utils.reflect.Field;
|
||||||
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.visualizer.MusicManagerFFT;
|
import zero1hd.rhythmbullet.audio.MinimalAudioHeader;
|
||||||
import zero1hd.rhythmbullet.audio.visualizer.Visualizer;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
|
|
||||||
public class DesktopVisualizer extends MusicManagerFFT implements Visualizer {
|
public class DesktopVisualizer implements Observer {
|
||||||
|
private int windowSize = 1024;
|
||||||
|
private float[] PCM = new float[windowSize];
|
||||||
private ShortBuffer playingBuffer;
|
private ShortBuffer playingBuffer;
|
||||||
private ShortBuffer compareBuffer;
|
private ShortBuffer compareBuffer;
|
||||||
private ShortBuffer buffer;
|
private ShortBuffer buffer;
|
||||||
private int sourceID;
|
private int sourceID;
|
||||||
|
private int channelCount;
|
||||||
|
private int sampleRate;
|
||||||
|
private MusicController mc;
|
||||||
|
private BufferStreamReadThread streamReadThread;
|
||||||
|
private int windowsRead;
|
||||||
|
private int currentPlaybackWindow;
|
||||||
|
|
||||||
public DesktopVisualizer() {
|
public DesktopVisualizer() {
|
||||||
super();
|
|
||||||
try {
|
try {
|
||||||
Field bufferField = ClassReflection.getDeclaredField(OpenALMusic.class, "tempBuffer");
|
Field bufferField = ClassReflection.getDeclaredField(OpenALMusic.class, "tempBuffer");
|
||||||
bufferField.setAccessible(true);
|
bufferField.setAccessible(true);
|
||||||
|
Field bufferSizeField = ClassReflection.getDeclaredField(OpenALMusic.class, "bufferSize");
|
||||||
|
bufferSizeField.setAccessible(true);
|
||||||
|
bufferSizeField.set(null, new Integer(4096*5));
|
||||||
|
|
||||||
buffer = ((ByteBuffer) bufferField.get(null)).asShortBuffer().asReadOnlyBuffer();
|
buffer = ((ByteBuffer) bufferField.get(null)).asShortBuffer().asReadOnlyBuffer();
|
||||||
} catch (IllegalArgumentException | SecurityException | ReflectionException e) {
|
} catch (IllegalArgumentException | SecurityException | ReflectionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Gdx.app.debug("Visualizer reflection", "Failed attempt at retrieving tempBuffer field.");
|
Gdx.app.debug("Visualizer reflection", "Failed attempt at retrieving tempBuffer field.");
|
||||||
Gdx.app.exit();
|
Gdx.app.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
streamReadThread = new BufferStreamReadThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
private synchronized void calcPCMData() {
|
||||||
* @see zero1hd.rhythmbullet.desktop.audio.visualizer.Visualizer#calcPCMData()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void calcPCMData() {
|
|
||||||
short chanVal;
|
short chanVal;
|
||||||
int bufferPosOffset = 0;
|
|
||||||
bufferPosOffset = updateBufferPosition();
|
|
||||||
playingBuffer.position(Math.max(playingBuffer.limit()+bufferPosOffset, 0));
|
|
||||||
|
|
||||||
for (int sid = 0; sid < getAudioPCM().length && sid < playingBuffer.remaining(); sid++) {
|
for (int sid = 0; sid < PCM.length && sid < playingBuffer.remaining(); sid++) {
|
||||||
getAudioPCM()[sid] = 0;
|
PCM[sid] = 0;
|
||||||
for (int channel = 0; channel < mm.getChannelCount(); channel ++) {
|
for (int channel = 0; channel < channelCount; channel ++) {
|
||||||
if (getAudioPCM()[sid] < (chanVal = playingBuffer.get())) {
|
if (PCM[sid] < (chanVal = playingBuffer.get())) {
|
||||||
getAudioPCM()[sid] = chanVal;
|
PCM[sid] = chanVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getAudioPCM()[sid] /= Short.MAX_VALUE+1f;
|
PCM[sid] /= Short.MAX_VALUE+1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -86,26 +94,31 @@ public class DesktopVisualizer extends MusicManagerFFT implements Visualizer {
|
|||||||
}
|
}
|
||||||
//put the new buffer into the remaining portion.
|
//put the new buffer into the remaining portion.
|
||||||
playingBuffer.put(compareBuffer);
|
playingBuffer.put(compareBuffer);
|
||||||
|
|
||||||
|
synchronizeBufferWithPlayback();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int updateBufferPosition() {
|
private int calcBufferPosition() {
|
||||||
int pos = (int) ((alGetSourcef(sourceID, AL11.AL_SAMPLE_OFFSET))-buffer.limit()-mm.getChannelCount()*mm.getReadWindowSize());
|
int offset = (int) alGetSourcef(sourceID, AL11.AL_SAMPLE_OFFSET);
|
||||||
return pos;
|
offset = (offset/windowSize) * windowSize;
|
||||||
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
private void synchronizeBufferWithPlayback() {
|
||||||
* @see zero1hd.rhythmbullet.desktop.audio.visualizer.Visualizer#setMM(zero1hd.rhythmbullet.audio.MusicManager)
|
playingBuffer.position(calcBufferPosition());
|
||||||
*/
|
windowsRead = (int) ((mc.getCurrentPosition()*sampleRate)/windowSize);
|
||||||
@Override
|
}
|
||||||
public void setMM(MusicManager mm) {
|
|
||||||
|
public void setMusic(MinimalAudioHeader header) {
|
||||||
try {
|
try {
|
||||||
Field sourceIDField = ClassReflection.getDeclaredField(OpenALMusic.class, "sourceID");
|
Field sourceIDField = ClassReflection.getDeclaredField(OpenALMusic.class, "sourceID");
|
||||||
sourceIDField.setAccessible(true);
|
sourceIDField.setAccessible(true);
|
||||||
sourceID = (int) sourceIDField.get(mm.getMusic());
|
sourceID = (int) sourceIDField.get(mc.getCurrentMusic());
|
||||||
} catch (ReflectionException e) {
|
} catch (ReflectionException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
int originalPos = buffer.position();
|
channelCount = header.getChannelCount();
|
||||||
|
sampleRate = header.getSampleRate();
|
||||||
|
|
||||||
playingBuffer = ShortBuffer.allocate(buffer.capacity()*2);
|
playingBuffer = ShortBuffer.allocate(buffer.capacity()*2);
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
@ -117,28 +130,76 @@ public class DesktopVisualizer extends MusicManagerFFT implements Visualizer {
|
|||||||
compareBuffer.put(buffer);
|
compareBuffer.put(buffer);
|
||||||
compareBuffer.flip();
|
compareBuffer.flip();
|
||||||
|
|
||||||
buffer.position(originalPos);
|
buffer.rewind();
|
||||||
this.mm = mm;
|
}
|
||||||
|
|
||||||
super.setMM(mm);
|
public synchronized float[] getAudioPCM() {
|
||||||
|
return PCM;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BufferStreamReadThread implements Runnable {
|
||||||
|
private String name = "PCM-Audio-Processing";
|
||||||
|
private Thread thread;
|
||||||
|
private boolean run, paused;
|
||||||
|
private volatile long timeOfLastRead;
|
||||||
|
private int waitTime;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (run) {
|
||||||
|
if (mc.isPlaying()) {
|
||||||
|
if (paused) {
|
||||||
|
timeOfLastRead = TimeUtils.millis();
|
||||||
|
paused = false;
|
||||||
|
}
|
||||||
|
waitTime = sampleRate/windowSize/Gdx.graphics.getFramesPerSecond();
|
||||||
|
if (TimeUtils.timeSinceMillis(timeOfLastRead) >= waitTime) {
|
||||||
|
calcPCMData();
|
||||||
|
windowsRead++;
|
||||||
|
timeOfLastRead = TimeUtils.millis();
|
||||||
|
|
||||||
|
|
||||||
|
currentPlaybackWindow = (int) ((mc.getCurrentPosition()*sampleRate)/windowSize);
|
||||||
|
if (windowsRead != currentPlaybackWindow) {
|
||||||
|
synchronizeBufferWithPlayback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
synchronized (this) {
|
||||||
|
try {
|
||||||
|
paused = true;
|
||||||
|
wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void start() {
|
||||||
|
if (thread == null && !thread.isAlive()) {
|
||||||
|
thread = new Thread(this, name);
|
||||||
|
thread.start();
|
||||||
|
} else {
|
||||||
|
notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MusicManager getMM() {
|
public void update(Observable o, Object arg) {
|
||||||
return mm;
|
if (o == mc) {
|
||||||
|
switch ((MusicController.States) arg) {
|
||||||
|
case Loaded:
|
||||||
|
setMusic(mc.getCurrentMusicHeader());
|
||||||
|
break;
|
||||||
|
case Playing:
|
||||||
|
streamReadThread.start();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(Batch batch, float parentAlpha) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float[] getAudioPCMData() {
|
|
||||||
return getAudioPCM();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fft() {
|
|
||||||
calculate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.desktop.screens.MainMenuScreen;
|
import zero1hd.rhythmbullet.desktop.screens.MainScreen;
|
||||||
|
|
||||||
public class GraphicsOptions extends Table {
|
public class GraphicsOptions extends Table {
|
||||||
private Label resolutions, shaders;
|
private Label resolutions, shaders;
|
||||||
@ -28,7 +28,7 @@ public class GraphicsOptions extends Table {
|
|||||||
_1366x768;
|
_1366x768;
|
||||||
|
|
||||||
|
|
||||||
public GraphicsOptions(final MainMenuScreen mainMenu, Skin skin, final Preferences prefs) {
|
public GraphicsOptions(final MainScreen mainMenu, Skin skin, final Preferences prefs) {
|
||||||
align(Align.center);
|
align(Align.center);
|
||||||
defaults().space(10f);
|
defaults().space(10f);
|
||||||
this.prefs = prefs;
|
this.prefs = prefs;
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
package zero1hd.rhythmbullet.desktop.graphics.ui.components;
|
package zero1hd.rhythmbullet.desktop.graphics.ui.components;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.audio.Music;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Widget;
|
import com.badlogic.gdx.scenes.scene2d.ui.Widget;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
|
||||||
import zero1hd.rhythmbullet.audio.visualizer.HorizontalVisualizer;
|
import zero1hd.rhythmbullet.audio.visualizer.HorizontalVisualizer;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.visualizer.DesktopVisualizer;
|
import zero1hd.rhythmbullet.desktop.audio.visualizer.DesktopVisualizer;
|
||||||
|
|
||||||
public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
||||||
private HorizontalVisualizer vis;
|
private HorizontalVisualizer vis;
|
||||||
private boolean updatePositioning = true;
|
private boolean updatePositioning = true;
|
||||||
private MusicManager mm;
|
private Music music;
|
||||||
private boolean initialLoad;
|
private boolean initialLoad;
|
||||||
private float visRefreshRate;
|
private float visRefreshRate;
|
||||||
private float timer;
|
private float timer;
|
||||||
@ -29,13 +29,13 @@ public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void act(float delta) {
|
public void act(float delta) {
|
||||||
if (mm != null && mm.isFinishedLoading() && !initialLoad) {
|
if (music != null && music.isFinishedLoading() && !initialLoad) {
|
||||||
visRefreshRate = mm.getReadWindowSize()/mm.getSampleRate();
|
visRefreshRate = music.getReadWindowSize()/music.getSampleRate();
|
||||||
Gdx.app.debug("Visualizer", "\nsample count: " + mm.getSampleCount()
|
Gdx.app.debug("Visualizer", "\nsample count: " + music.getSampleCount()
|
||||||
+ "\nDuration in seconds: " + mm.getDuration() +
|
+ "\nDuration in seconds: " + music.getDuration() +
|
||||||
"\nSample rate: " + mm.getSampleRate() +
|
"\nSample rate: " + music.getSampleRate() +
|
||||||
"\nRefresh rate: " + visRefreshRate);
|
"\nRefresh rate: " + visRefreshRate);
|
||||||
vis.setMM(mm);
|
vis.setMusic(music);
|
||||||
initialLoad = true;
|
initialLoad = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
|||||||
|
|
||||||
vis.update(delta);
|
vis.update(delta);
|
||||||
updateVisualizerProperties();
|
updateVisualizerProperties();
|
||||||
if (mm != null && initialLoad) {
|
if (music != null && initialLoad) {
|
||||||
if (timer >= visRefreshRate) {
|
if (timer >= visRefreshRate) {
|
||||||
timer = 0;
|
timer = 0;
|
||||||
vis.calculate();
|
vis.calculate();
|
||||||
@ -58,9 +58,9 @@ public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
|||||||
super.act(delta);
|
super.act(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMM(MusicManager mm) {
|
public void setMusic(Music music) {
|
||||||
initialLoad = false;
|
initialLoad = false;
|
||||||
this.mm = mm;
|
this.music = music;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,13 +7,13 @@ import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
|
|
||||||
public class MusicControls extends HorizontalGroup {
|
public class MusicControls extends HorizontalGroup {
|
||||||
private ImageButton reverse, forward;
|
private ImageButton reverse, forward;
|
||||||
private CheckBox shuffle, play;
|
private CheckBox shuffle, play;
|
||||||
private float disableTimer;
|
private float disableTimer;
|
||||||
public MusicControls(Skin skin, final MusicListController sc) {
|
public MusicControls(Skin skin, final MusicController sc) {
|
||||||
reverse = new ImageButton(skin, "rewind-button");
|
reverse = new ImageButton(skin, "rewind-button");
|
||||||
reverse.addListener(new ChangeListener() {
|
reverse.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,7 +39,7 @@ public class AnalysisPage extends Page {
|
|||||||
addActor(table);
|
addActor(table);
|
||||||
this.core = core;
|
this.core = core;
|
||||||
adjustment = new Table();
|
adjustment = new Table();
|
||||||
Skin skin = core.getDefaultSkin();
|
Skin skin = core.getSkinSkin();
|
||||||
|
|
||||||
difficultyModLabel = new Label("Difficulty Modifier: ", skin, "sub-font", skin.getColor("default"));
|
difficultyModLabel = new Label("Difficulty Modifier: ", skin, "sub-font", skin.getColor("default"));
|
||||||
difficultyModifierSlider = new Slider(1, 3, 0.5f, false, skin);
|
difficultyModifierSlider = new Slider(1, 3, 0.5f, false, skin);
|
||||||
|
@ -10,14 +10,14 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.components.GraphicsOptions;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.components.GraphicsOptions;
|
||||||
import zero1hd.rhythmbullet.desktop.screens.MainMenuScreen;
|
import zero1hd.rhythmbullet.desktop.screens.MainScreen;
|
||||||
|
|
||||||
public class GraphicsOptionsPage extends Page {
|
public class GraphicsOptionsPage extends Page {
|
||||||
private ScrollPane scrollPane;
|
private ScrollPane scrollPane;
|
||||||
private GraphicsOptions graphicsTable;
|
private GraphicsOptions graphicsTable;
|
||||||
private TextButton backButton;
|
private TextButton backButton;
|
||||||
|
|
||||||
public GraphicsOptionsPage(Skin skin, Preferences prefs, final MainMenuScreen menu, AssetManager assets) {
|
public GraphicsOptionsPage(Skin skin, Preferences prefs, final MainScreen menu, AssetManager assets) {
|
||||||
graphicsTable = new GraphicsOptions(menu, skin, prefs);
|
graphicsTable = new GraphicsOptions(menu, skin, prefs);
|
||||||
scrollPane = new ScrollPane(graphicsTable, skin);
|
scrollPane = new ScrollPane(graphicsTable, skin);
|
||||||
scrollPane.setFadeScrollBars(false);
|
scrollPane.setFadeScrollBars(false);
|
||||||
|
@ -14,17 +14,16 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
|||||||
import com.badlogic.gdx.utils.Align;
|
import com.badlogic.gdx.utils.Align;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.RhythmBullet;
|
import zero1hd.rhythmbullet.RhythmBullet;
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.components.MusicControls;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.components.MusicControls;
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.components.TitleBarVisualizer;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.components.TitleBarVisualizer;
|
||||||
import zero1hd.rhythmbullet.desktop.screens.MainMenuScreen;
|
import zero1hd.rhythmbullet.desktop.screens.MainScreen;
|
||||||
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
|
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
|
||||||
|
|
||||||
public class MainPage extends Page implements Observer {
|
public class MainPage extends Page implements Observer {
|
||||||
private Label versionLabel;
|
private Label versionLabel;
|
||||||
|
|
||||||
private MusicListController mlc;
|
private MusicController mc;
|
||||||
private TitleBarVisualizer titleBar;
|
private TitleBarVisualizer titleBar;
|
||||||
private Table table;
|
private Table table;
|
||||||
private TextButton playButton;
|
private TextButton playButton;
|
||||||
@ -32,17 +31,17 @@ public class MainPage extends Page implements Observer {
|
|||||||
private TextButton quitButton;
|
private TextButton quitButton;
|
||||||
|
|
||||||
private MusicControls musicControls;
|
private MusicControls musicControls;
|
||||||
private MainMenuScreen mMenu;
|
private MainScreen mMenu;
|
||||||
private ScrollText scrollText;
|
private ScrollText scrollText;
|
||||||
|
|
||||||
public MainPage(RhythmBullet core, final Vector3 targetPosition, MusicListController mlc, final MainMenuScreen mainMenu) {
|
public MainPage(RhythmBullet core, Vector3 targetPosition, MusicController mlc, MainScreen mainMenu) {
|
||||||
this.mlc = mlc;
|
this.mc = mlc;
|
||||||
this.mMenu = mainMenu;
|
this.mMenu = mainMenu;
|
||||||
titleBar = new TitleBarVisualizer(core.getAssetManager());
|
titleBar = new TitleBarVisualizer(core.getAssetManager());
|
||||||
addActor(titleBar);
|
addActor(titleBar);
|
||||||
|
|
||||||
versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getDefaultSkin(), "sub-font",
|
versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getSkinSkin(), "sub-font",
|
||||||
core.getDefaultSkin().getColor("default"));
|
core.getSkinSkin().getColor("default"));
|
||||||
versionLabel.setPosition(3, 3);
|
versionLabel.setPosition(3, 3);
|
||||||
addActor(versionLabel);
|
addActor(versionLabel);
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ public class MainPage extends Page implements Observer {
|
|||||||
table.align(Align.center);
|
table.align(Align.center);
|
||||||
table.defaults().space(10f);
|
table.defaults().space(10f);
|
||||||
addActor(table);
|
addActor(table);
|
||||||
playButton = new TextButton("Start!", core.getDefaultSkin());
|
playButton = new TextButton("Start!", core.getSkinSkin());
|
||||||
playButton.addListener(new ChangeListener() {
|
playButton.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -63,7 +62,7 @@ public class MainPage extends Page implements Observer {
|
|||||||
|
|
||||||
table.row();
|
table.row();
|
||||||
|
|
||||||
optionsButton = new TextButton("Options", core.getDefaultSkin(), "sub");
|
optionsButton = new TextButton("Options", core.getSkinSkin(), "sub");
|
||||||
optionsButton.addListener(new ChangeListener() {
|
optionsButton.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -74,7 +73,7 @@ public class MainPage extends Page implements Observer {
|
|||||||
|
|
||||||
table.row();
|
table.row();
|
||||||
|
|
||||||
quitButton = new TextButton("Quit", core.getDefaultSkin(), "sub");
|
quitButton = new TextButton("Quit", core.getSkinSkin(), "sub");
|
||||||
quitButton.addListener(new ChangeListener() {
|
quitButton.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -83,11 +82,11 @@ public class MainPage extends Page implements Observer {
|
|||||||
});
|
});
|
||||||
table.add(quitButton).fillX();
|
table.add(quitButton).fillX();
|
||||||
|
|
||||||
musicControls = new MusicControls(core.getDefaultSkin(), mlc);
|
musicControls = new MusicControls(core.getSkinSkin(), mlc);
|
||||||
musicControls.setPosition((getWidth()-musicControls.getMinWidth() - 20f), getHeight()-musicControls.getMinHeight()-20f);
|
musicControls.setPosition((getWidth()-musicControls.getMinWidth() - 20f), getHeight()-musicControls.getMinHeight()-20f);
|
||||||
addActor(musicControls);
|
addActor(musicControls);
|
||||||
|
|
||||||
scrollText = new ScrollText("...", "...", core.getDefaultSkin(), false, true);
|
scrollText = new ScrollText("...", "...", core.getSkinSkin(), false, true);
|
||||||
scrollText.setWidth(0.5f*getWidth());
|
scrollText.setWidth(0.5f*getWidth());
|
||||||
scrollText.setPosition(15, getHeight() - scrollText.getHeight()-25f);
|
scrollText.setPosition(15, getHeight() - scrollText.getHeight()-25f);
|
||||||
addActor(scrollText);
|
addActor(scrollText);
|
||||||
@ -111,21 +110,8 @@ public class MainPage extends Page implements Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Observable o, Object arg) {
|
public void update(Observable o, Object arg) {
|
||||||
if (o == mlc.getMusicList() && mlc.getMusicList().isSearched()) {
|
if (o == mc && arg == MusicController.States.Loaded) {
|
||||||
mlc.shuffle(true);
|
scrollText.setText("Currently playing: " + mc.getCurrentSongName(), null);
|
||||||
MusicManager mm = mlc.getCurrentMusicManager();
|
|
||||||
updateVisualsForDifferentSong(mm);
|
|
||||||
mMenu.getMusicSelectionPage().refreshUIList();
|
|
||||||
} else if (o == mlc) {
|
|
||||||
MusicManager mm = mlc.getCurrentMusicManager();
|
|
||||||
mlc.play();
|
|
||||||
updateVisualsForDifferentSong(mm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateVisualsForDifferentSong(MusicManager mm) {
|
|
||||||
titleBar.getHvisual().setMM(mm);
|
|
||||||
scrollText.setText("Currently playing: " + mm.getBasicSongName(), null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,17 +26,17 @@ import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
|
|||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicInfo;
|
import zero1hd.rhythmbullet.audio.MusicInfo;
|
||||||
|
import zero1hd.rhythmbullet.audio.MusicMetadataController;
|
||||||
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicInfoController;
|
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.components.MusicSelectable;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.components.MusicSelectable;
|
||||||
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
|
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
|
||||||
|
|
||||||
public class MusicSelectionPage extends Page implements Observer {
|
public class MusicSelectionPage extends Page implements Observer {
|
||||||
Preferences musicFileAnnotation;
|
Preferences musicFileAnnotation;
|
||||||
|
|
||||||
private MusicListController mc;
|
private MusicController mc;
|
||||||
private MusicInfoController mic;
|
private MusicMetadataController mic;
|
||||||
private Array<MusicSelectable> selectables;
|
private Array<MusicSelectable> selectables;
|
||||||
private Table musicTable;
|
private Table musicTable;
|
||||||
private ScrollPane musicTableScrollPane;
|
private ScrollPane musicTableScrollPane;
|
||||||
@ -65,7 +65,7 @@ public class MusicSelectionPage extends Page implements Observer {
|
|||||||
private int uiSongInfoCount;
|
private int uiSongInfoCount;
|
||||||
private float scrollTimer, scrollDelay = 0.2f, scrollDelMod, songSelectionTimer;
|
private float scrollTimer, scrollDelay = 0.2f, scrollDelMod, songSelectionTimer;
|
||||||
|
|
||||||
public MusicSelectionPage(Skin skin, MusicListController musicListController, MusicInfoController musicInfoController, AssetManager assetManager, final Vector3 cameraTarget, final AnalysisPage ap) {
|
public MusicSelectionPage(Skin skin, MusicController musicListController, MusicMetadataController musicInfoController, AssetManager assetManager, final Vector3 cameraTarget, final AnalysisPage ap) {
|
||||||
this.assets = assetManager;
|
this.assets = assetManager;
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
this.mc = musicListController;
|
this.mc = musicListController;
|
||||||
@ -139,7 +139,7 @@ public class MusicSelectionPage extends Page implements Observer {
|
|||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
if (getSelectedMusic() != null) {
|
if (getSelectedMusic() != null) {
|
||||||
cameraTarget.x = 2.5f*getWidth();
|
cameraTarget.x = 2.5f*getWidth();
|
||||||
ap.processSong(mc.getMusicList().getAudioData(getSelectedMusic()), (albumCoverTexture != null ? albumCoverTexture : assets.get("defaultCover.png", Texture.class)), mic.getInfo(getSelectedMusic()));
|
ap.processSong(mc.getMusicList().newAudioProcessor(getSelectedMusic()), (albumCoverTexture != null ? albumCoverTexture : assets.get("defaultCover.png", Texture.class)), mic.getInfo(getSelectedMusic()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -195,7 +195,7 @@ public class MusicSelectionPage extends Page implements Observer {
|
|||||||
selectMusicUI(mc.getCurrentMusicManager());
|
selectMusicUI(mc.getCurrentMusicManager());
|
||||||
}
|
}
|
||||||
} else if (uiSongInfoCount < selectables.size && mic.isDone()) {
|
} else if (uiSongInfoCount < selectables.size && mic.isDone()) {
|
||||||
selectables.get(uiSongInfoCount).updateInfo(mic.getSongInfoArray().get(uiSongInfoCount));
|
selectables.get(uiSongInfoCount).updateInfo(mic.getMetadataArray().get(uiSongInfoCount));
|
||||||
uiSongInfoCount++;
|
uiSongInfoCount++;
|
||||||
if (uiSongInfoCount == selectables.size) {
|
if (uiSongInfoCount == selectables.size) {
|
||||||
updateInformation();
|
updateInformation();
|
||||||
@ -291,9 +291,8 @@ public class MusicSelectionPage extends Page implements Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Observable o, Object arg) {
|
public void update(Observable o, Object arg) {
|
||||||
if (o == mc) {
|
if (o == mc && arg == MusicController.States.Loaded) {
|
||||||
MusicManager mm = (MusicManager) arg;
|
selectMusicUI(mc.getCurrentMusic());
|
||||||
selectMusicUI(mm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.RhythmBullet;
|
import zero1hd.rhythmbullet.RhythmBullet;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
|
|
||||||
public class OptionsPage extends Page {
|
public class OptionsPage extends Page {
|
||||||
Table optionsTable;
|
Table optionsTable;
|
||||||
@ -23,11 +23,11 @@ public class OptionsPage extends Page {
|
|||||||
private TextField directoryField;
|
private TextField directoryField;
|
||||||
private float musicSearchTimer;
|
private float musicSearchTimer;
|
||||||
|
|
||||||
public OptionsPage(final RhythmBullet core, final Vector3 targetPosition, KeybindOptionsPage moreOptionsPage, MusicListController mlc) {
|
public OptionsPage(final RhythmBullet core, final Vector3 targetPosition, KeybindOptionsPage moreOptionsPage, MusicController mlc) {
|
||||||
super("General", core.getDefaultSkin());
|
super("General", core.getSkinSkin());
|
||||||
|
|
||||||
//Back button
|
//Back button
|
||||||
TextButton backButton = new TextButton("Back", core.getDefaultSkin());
|
TextButton backButton = new TextButton("Back", core.getSkinSkin());
|
||||||
backButton.addListener(new ChangeListener() {
|
backButton.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -43,12 +43,12 @@ public class OptionsPage extends Page {
|
|||||||
optionsTable.setSize(getWidth(), getHeight());
|
optionsTable.setSize(getWidth(), getHeight());
|
||||||
addActor(optionsTable);
|
addActor(optionsTable);
|
||||||
|
|
||||||
Label musicVolSliderLabel = new Label("Music Volume: ", core.getDefaultSkin());
|
Label musicVolSliderLabel = new Label("Music Volume: ", core.getSkinSkin());
|
||||||
optionsTable.add(musicVolSliderLabel);
|
optionsTable.add(musicVolSliderLabel);
|
||||||
musicVolSlider = new Slider(0, 100, 0.1f, false, core.getDefaultSkin());
|
musicVolSlider = new Slider(0, 100, 0.1f, false, core.getSkinSkin());
|
||||||
musicVolSlider.setValue(core.getPrefs().getFloat("music vol", 100f)*100f);
|
musicVolSlider.setValue(core.getPrefs().getFloat("music vol", 100f)*100f);
|
||||||
optionsTable.add(musicVolSlider).minWidth(0.3f*getWidth());
|
optionsTable.add(musicVolSlider).minWidth(0.3f*getWidth());
|
||||||
final Label musicVolPercentage = new Label(MathUtils.round(musicVolSlider.getValue()) + "%", core.getDefaultSkin());
|
final Label musicVolPercentage = new Label(MathUtils.round(musicVolSlider.getValue()) + "%", core.getSkinSkin());
|
||||||
musicVolSlider.addListener(new ChangeListener() {
|
musicVolSlider.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -62,12 +62,12 @@ public class OptionsPage extends Page {
|
|||||||
|
|
||||||
optionsTable.row();
|
optionsTable.row();
|
||||||
|
|
||||||
Label fxVolSliderLabel = new Label("FX Volume: ", core.getDefaultSkin());
|
Label fxVolSliderLabel = new Label("FX Volume: ", core.getSkinSkin());
|
||||||
optionsTable.add(fxVolSliderLabel);
|
optionsTable.add(fxVolSliderLabel);
|
||||||
fxVolSlider = new Slider(0, 100, 0.1f, false, core.getDefaultSkin());
|
fxVolSlider = new Slider(0, 100, 0.1f, false, core.getSkinSkin());
|
||||||
fxVolSlider.setValue(core.getPrefs().getFloat("fx vol", 100f)*100f);
|
fxVolSlider.setValue(core.getPrefs().getFloat("fx vol", 100f)*100f);
|
||||||
optionsTable.add(fxVolSlider).fillX();
|
optionsTable.add(fxVolSlider).fillX();
|
||||||
final Label fxVolPercentage = new Label(MathUtils.round(fxVolSlider.getValue()) + "%", core.getDefaultSkin());
|
final Label fxVolPercentage = new Label(MathUtils.round(fxVolSlider.getValue()) + "%", core.getSkinSkin());
|
||||||
fxVolSlider.addListener(new ChangeListener() {
|
fxVolSlider.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -80,16 +80,16 @@ public class OptionsPage extends Page {
|
|||||||
|
|
||||||
optionsTable.row();
|
optionsTable.row();
|
||||||
|
|
||||||
Label musicDirectoryLabel = new Label("Music Directory: ", core.getDefaultSkin());
|
Label musicDirectoryLabel = new Label("Music Directory: ", core.getSkinSkin());
|
||||||
optionsTable.add(musicDirectoryLabel);
|
optionsTable.add(musicDirectoryLabel);
|
||||||
directoryField = new TextField(null, core.getDefaultSkin() ) {
|
directoryField = new TextField(null, core.getSkinSkin() ) {
|
||||||
@Override
|
@Override
|
||||||
public void act(float delta) {
|
public void act(float delta) {
|
||||||
if (musicSearchTimer > 0) {
|
if (musicSearchTimer > 0) {
|
||||||
musicSearchTimer -= delta;
|
musicSearchTimer -= delta;
|
||||||
if (musicSearchTimer <= 0) {
|
if (musicSearchTimer <= 0) {
|
||||||
mlc.getMusicList().setSearchPath(directoryField.getText());
|
mlc.getMusicList().setSearchPath(directoryField.getText());
|
||||||
mlc.getMusicList().asynchRefresh();
|
mlc.getMusicList().asyncSearch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.act(delta);
|
super.act(delta);
|
||||||
@ -106,7 +106,7 @@ public class OptionsPage extends Page {
|
|||||||
|
|
||||||
optionsTable.row();
|
optionsTable.row();
|
||||||
|
|
||||||
TextButton keybindSettings = new TextButton("Set Controls", core.getDefaultSkin());
|
TextButton keybindSettings = new TextButton("Set Controls", core.getSkinSkin());
|
||||||
keybindSettings.addListener(new ChangeListener() {
|
keybindSettings.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -117,7 +117,7 @@ public class OptionsPage extends Page {
|
|||||||
|
|
||||||
optionsTable.row();
|
optionsTable.row();
|
||||||
|
|
||||||
TextButton graphicsSettings = new TextButton("Graphics", core.getDefaultSkin());
|
TextButton graphicsSettings = new TextButton("Graphics", core.getSkinSkin());
|
||||||
graphicsSettings.addListener(new ChangeListener() {
|
graphicsSettings.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
@ -128,7 +128,7 @@ public class OptionsPage extends Page {
|
|||||||
|
|
||||||
optionsTable.row();
|
optionsTable.row();
|
||||||
|
|
||||||
Label fpsLabel = new Label("", core.getDefaultSkin()) {
|
Label fpsLabel = new Label("", core.getSkinSkin()) {
|
||||||
@Override
|
@Override
|
||||||
public void act(float delta) {
|
public void act(float delta) {
|
||||||
setText("Current Frames Per Second: " + Gdx.graphics.getFramesPerSecond());
|
setText("Current Frames Per Second: " + Gdx.graphics.getFramesPerSecond());
|
||||||
@ -139,7 +139,7 @@ public class OptionsPage extends Page {
|
|||||||
|
|
||||||
optionsTable.row();
|
optionsTable.row();
|
||||||
|
|
||||||
Label usageLabel = new Label("Current usage (lower the better): " + 100f*((float)(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/(float)Runtime.getRuntime().totalMemory()) + "%", core.getDefaultSkin()) {
|
Label usageLabel = new Label("Current usage (lower the better): " + 100f*((float)(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/(float)Runtime.getRuntime().totalMemory()) + "%", core.getSkinSkin()) {
|
||||||
float refreshTime = 60;
|
float refreshTime = 60;
|
||||||
@Override
|
@Override
|
||||||
public void act(float delta) {
|
public void act(float delta) {
|
||||||
|
@ -20,10 +20,10 @@ import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
|
|||||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.RhythmBullet;
|
import zero1hd.rhythmbullet.RhythmBullet;
|
||||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
import zero1hd.rhythmbullet.audio.MusicMetadataController;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicInfoController;
|
import zero1hd.rhythmbullet.audio.MusicList;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicList;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
import zero1hd.rhythmbullet.desktop.audio.processor.DesktopAudioProcessorFactory;
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.AnalysisPage;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.AnalysisPage;
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.CreditsPage;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.CreditsPage;
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.KeybindOptionsPage;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.KeybindOptionsPage;
|
||||||
@ -31,9 +31,9 @@ import zero1hd.rhythmbullet.desktop.graphics.ui.pages.MainPage;
|
|||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.MusicSelectionPage;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.MusicSelectionPage;
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.OptionsPage;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.OptionsPage;
|
||||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.GraphicsOptionsPage;
|
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.GraphicsOptionsPage;
|
||||||
import zero1hd.rhythmbullet.util.AdvancedResizeScreen;
|
import zero1hd.rhythmbullet.util.ResizeReadyScreen;
|
||||||
|
|
||||||
public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScreen {
|
public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
|
||||||
public Stage stage;
|
public Stage stage;
|
||||||
private Vector3 cameraPosition;
|
private Vector3 cameraPosition;
|
||||||
|
|
||||||
@ -46,8 +46,8 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
private AnalysisPage analysisPage;
|
private AnalysisPage analysisPage;
|
||||||
private RhythmBullet core;
|
private RhythmBullet core;
|
||||||
|
|
||||||
private MusicListController mlc;
|
private MusicController mlc;
|
||||||
private MusicInfoController mic;
|
private MusicMetadataController mmc;
|
||||||
|
|
||||||
private float lerpAlpha;
|
private float lerpAlpha;
|
||||||
|
|
||||||
@ -66,19 +66,18 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
private Batch screenBatch;
|
private Batch screenBatch;
|
||||||
private ScreenViewport screenViewport;
|
private ScreenViewport screenViewport;
|
||||||
|
|
||||||
public MainMenuScreen(RhythmBullet core) {
|
public MainScreen(RhythmBullet core) {
|
||||||
this.core = core;
|
this.core = core;
|
||||||
stage = new Stage(new ScreenViewport());
|
stage = new Stage(new ScreenViewport());
|
||||||
cameraPosition = new Vector3(stage.getCamera().position);
|
cameraPosition = new Vector3(stage.getCamera().position);
|
||||||
|
|
||||||
MusicList musicList = new MusicList();
|
MusicList musicList = new MusicList(new DesktopAudioProcessorFactory());
|
||||||
musicList.setSearchPath(core.getPrefs().getString("music dir"));
|
musicList.setSearchPath(core.getPrefs().getString("music dir"));
|
||||||
musicList.asynchRefresh();
|
mlc = new MusicController(musicList, core.getPrefs());
|
||||||
mlc = new MusicListController(musicList, core.getPrefs());
|
|
||||||
mlc.setAutoPlay(true);
|
mlc.setAutoPlay(true);
|
||||||
mlc.setShuffle(true);
|
mlc.setShuffle(true);
|
||||||
|
|
||||||
mic = new MusicInfoController(musicList);
|
mmc = new MusicMetadataController(musicList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -105,7 +104,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
fboRegion.setTexture(normalBuffer.getColorBufferTexture());
|
fboRegion.setTexture(normalBuffer.getColorBufferTexture());
|
||||||
screenBatch.setShader(brightFilterShader);
|
screenBatch.setShader(brightFilterShader);
|
||||||
screenBatch.setProjectionMatrix(screenViewport.getCamera().combined);
|
screenBatch.setProjectionMatrix(screenViewport.getCamera().combined);
|
||||||
screenBatch.begin(); //BATCH STARTS HERE
|
screenBatch.begin(); //SCREEN BATCH STARTS HERE
|
||||||
screenBatch.draw(fboRegion, 0, 0, stage.getWidth(), stage.getHeight());
|
screenBatch.draw(fboRegion, 0, 0, stage.getWidth(), stage.getHeight());
|
||||||
screenBatch.flush();
|
screenBatch.flush();
|
||||||
lightFilterBuffer.end();
|
lightFilterBuffer.end();
|
||||||
@ -180,6 +179,8 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postAssetLoad() {
|
public void postAssetLoad() {
|
||||||
|
mlc.deleteObservers();
|
||||||
|
|
||||||
background = core.getAssetManager().get("backgrounds/mainBG.png", Texture.class);
|
background = core.getAssetManager().get("backgrounds/mainBG.png", Texture.class);
|
||||||
screenBatch = new SpriteBatch();
|
screenBatch = new SpriteBatch();
|
||||||
|
|
||||||
@ -188,11 +189,11 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
stage.addActor(mainPage);
|
stage.addActor(mainPage);
|
||||||
//End main menu
|
//End main menu
|
||||||
|
|
||||||
keybindPage = new KeybindOptionsPage(core.getDefaultSkin(), core.getAssetManager(), cameraPosition);
|
keybindPage = new KeybindOptionsPage(core.getSkinSkin(), core.getAssetManager(), cameraPosition);
|
||||||
keybindPage.setPosition(-1f*Gdx.graphics.getWidth(), -1f*Gdx.graphics.getHeight());
|
keybindPage.setPosition(-1f*Gdx.graphics.getWidth(), -1f*Gdx.graphics.getHeight());
|
||||||
stage.addActor(keybindPage);
|
stage.addActor(keybindPage);
|
||||||
|
|
||||||
graphicsPage = new GraphicsOptionsPage(core.getDefaultSkin(), core.getPrefs(), this, core.getAssetManager());
|
graphicsPage = new GraphicsOptionsPage(core.getSkinSkin(), core.getPrefs(), this, core.getAssetManager());
|
||||||
|
|
||||||
graphicsPage.setPosition(-1f*Gdx.graphics.getWidth(), 1f*Gdx.graphics.getHeight());
|
graphicsPage.setPosition(-1f*Gdx.graphics.getWidth(), 1f*Gdx.graphics.getHeight());
|
||||||
stage.addActor(graphicsPage);
|
stage.addActor(graphicsPage);
|
||||||
@ -201,7 +202,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
optionsPage.setPosition(-Gdx.graphics.getWidth(), 0);
|
optionsPage.setPosition(-Gdx.graphics.getWidth(), 0);
|
||||||
stage.addActor(optionsPage);
|
stage.addActor(optionsPage);
|
||||||
|
|
||||||
creditsPage = new CreditsPage(core.getDefaultSkin());
|
creditsPage = new CreditsPage(core.getSkinSkin());
|
||||||
creditsPage.setPosition(0, Gdx.graphics.getHeight());
|
creditsPage.setPosition(0, Gdx.graphics.getHeight());
|
||||||
stage.addActor(creditsPage);
|
stage.addActor(creditsPage);
|
||||||
|
|
||||||
@ -209,7 +210,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
analysisPage.setPosition(2*Gdx.graphics.getWidth(), 0f);
|
analysisPage.setPosition(2*Gdx.graphics.getWidth(), 0f);
|
||||||
stage.addActor(analysisPage);
|
stage.addActor(analysisPage);
|
||||||
|
|
||||||
musicSelectionPage = new MusicSelectionPage(core.getDefaultSkin(), mlc, mic, core.getAssetManager(), cameraPosition, analysisPage);
|
musicSelectionPage = new MusicSelectionPage(core.getSkinSkin(), mlc, mmc, core.getAssetManager(), cameraPosition, analysisPage);
|
||||||
musicSelectionPage.setPosition(1f*Gdx.graphics.getWidth(), 0f);
|
musicSelectionPage.setPosition(1f*Gdx.graphics.getWidth(), 0f);
|
||||||
stage.addActor(musicSelectionPage);
|
stage.addActor(musicSelectionPage);
|
||||||
stage.addListener(new InputListener() {
|
stage.addListener(new InputListener() {
|
||||||
@ -233,17 +234,12 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
super.clicked(event, x, y);
|
super.clicked(event, x, y);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mlc.getMusicList().deleteObservers();
|
|
||||||
mlc.deleteObservers();
|
|
||||||
mlc.addObserver(musicSelectionPage);
|
mlc.addObserver(musicSelectionPage);
|
||||||
mlc.addObserver(mainPage);
|
mlc.addObserver(mainPage);
|
||||||
mlc.getMusicList().addObserver(mainPage);
|
|
||||||
|
|
||||||
if (mlc.getMusicList().isSearched() && mlc.getCurrentMusicManager() != null) {
|
mlc.getMusicList().asyncSearch();
|
||||||
MusicManager mManager = mlc.getCurrentMusicManager();
|
|
||||||
mainPage.updateVisualsForDifferentSong(mManager);
|
|
||||||
musicSelectionPage.refreshUIList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -281,7 +277,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
|||||||
if (gaussianBlurShader != null) {
|
if (gaussianBlurShader != null) {
|
||||||
dismantleShaders();
|
dismantleShaders();
|
||||||
}
|
}
|
||||||
mic.dispose();
|
mmc.dispose();
|
||||||
screenBatch.dispose();
|
screenBatch.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package zero1hd.rhythmbullet.desktop.screens;
|
package zero1hd.rhythmbullet.desktop.screens;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Screen;
|
||||||
import com.badlogic.gdx.ScreenAdapter;
|
import com.badlogic.gdx.ScreenAdapter;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.GL20;
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
@ -10,18 +11,21 @@ import com.badlogic.gdx.scenes.scene2d.actions.Actions;
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
import com.badlogic.gdx.scenes.scene2d.ui.Image;
|
||||||
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
||||||
|
|
||||||
|
import zero1hd.rhythmbullet.InitialScreen;
|
||||||
import zero1hd.rhythmbullet.RhythmBullet;
|
import zero1hd.rhythmbullet.RhythmBullet;
|
||||||
import zero1hd.rhythmbullet.util.AdvancedResizeScreen;
|
import zero1hd.rhythmbullet.util.ResizeReadyScreen;
|
||||||
|
|
||||||
public class SplashScreen extends ScreenAdapter implements AdvancedResizeScreen {
|
public class SplashScreen extends ScreenAdapter implements ResizeReadyScreen, InitialScreen {
|
||||||
private Stage stage;
|
private Stage stage;
|
||||||
private RhythmBullet core;
|
|
||||||
private Texture splash;
|
private Texture splash;
|
||||||
private Image zero1HD;
|
private Image zero1HD;
|
||||||
private boolean done;
|
|
||||||
|
|
||||||
public SplashScreen(RhythmBullet core) {
|
public SplashScreen() {
|
||||||
this.core = core;
|
splash = new Texture(Gdx.files.internal("splashlogo.png"));
|
||||||
|
zero1HD = new Image(splash);
|
||||||
|
zero1HD.setScale((Gdx.graphics.getHeight()*0.8f)/zero1HD.getHeight());
|
||||||
|
zero1HD.setColor(0f,1f,1f,0.1f);
|
||||||
|
stage.addActor(zero1HD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -34,49 +38,31 @@ public class SplashScreen extends ScreenAdapter implements AdvancedResizeScreen
|
|||||||
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
|
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
|
||||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
stage.act(delta);
|
stage.act(delta);
|
||||||
|
|
||||||
if (!zero1HD.hasActions() && core.isInitComplete()) {
|
|
||||||
attemptMoveOn();
|
|
||||||
}
|
|
||||||
|
|
||||||
stage.draw();
|
stage.draw();
|
||||||
super.render(delta);
|
super.render(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attemptMoveOn() {
|
|
||||||
if (!done) {
|
|
||||||
Gdx.app.debug("Loading Screen", "queue has all been loaded. Action is done playing.");
|
|
||||||
done = true;
|
|
||||||
core.setScreen(new MainMenuScreen(core));
|
|
||||||
zero1HD.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hide() {
|
public void hide() {
|
||||||
core.setInitComplete();
|
|
||||||
splash.dispose();
|
splash.dispose();
|
||||||
super.hide();
|
super.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preAssetLoad() {
|
public void preAssetLoad() {
|
||||||
if (stage != null) {
|
|
||||||
stage.dispose();
|
|
||||||
splash.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postAssetLoad() {
|
public void postAssetLoad() {
|
||||||
stage = new Stage(new ScreenViewport());
|
stage = new Stage(new ScreenViewport());
|
||||||
splash = new Texture(Gdx.files.internal("splashlogo.png"));
|
|
||||||
zero1HD = new Image(splash);
|
|
||||||
zero1HD.setScale((Gdx.graphics.getHeight()*0.8f)/zero1HD.getHeight());
|
zero1HD.setScale((Gdx.graphics.getHeight()*0.8f)/zero1HD.getHeight());
|
||||||
|
|
||||||
zero1HD.setColor(0f,1f,1f,0f);
|
zero1HD.setColor(0f,1f,1f,0f);
|
||||||
stage.addActor(zero1HD);
|
|
||||||
zero1HD.setPosition((stage.getWidth() - zero1HD.getWidth()*zero1HD.getScaleX())/2f, (stage.getHeight() - zero1HD.getHeight()*zero1HD.getScaleY())/2f);
|
zero1HD.setPosition((stage.getWidth() - zero1HD.getWidth()*zero1HD.getScaleX())/2f, (stage.getHeight() - zero1HD.getHeight()*zero1HD.getScaleY())/2f);
|
||||||
zero1HD.addAction(Actions.sequence(Actions.color(Color.WHITE, 1f), Actions.fadeOut(0.5f)));
|
zero1HD.addAction(Actions.sequence(Actions.color(Color.WHITE, 1f), Actions.fadeOut(0.5f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Screen createMainScreen(RhythmBullet game) {
|
||||||
|
return new MainScreen(game);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user