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.ResolutionFileResolver.Resolution;
|
||||
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.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.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.RoundingResolutionHandler;
|
||||
import zero1hd.rhythmbullet.util.AdvancedResizeScreen;
|
||||
import zero1hd.rhythmbullet.util.ResizeReadyScreen;
|
||||
|
||||
|
||||
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 SPAWN_CIRCLE_RADIUS = 6;
|
||||
public static int pixels_per_unit;
|
||||
private boolean initComplete = false;
|
||||
private boolean initiated;
|
||||
private boolean resizing;
|
||||
private int screenWidth, screenHeight;
|
||||
public static final String VERSION = "(0.1)R1-PreAlpha";
|
||||
|
||||
private AssetManager assetManager = new AssetManager();
|
||||
private Skin defaultSkin = new Skin();
|
||||
private FreeTypeFontGenerator default_fontGenerator;
|
||||
private FreeTypeFontGenerator darktech_ldr_fontGenerator;
|
||||
private Skin skin;
|
||||
TextureAtlas skinAtlas;
|
||||
private Preferences prefs;
|
||||
private RoundingResolutionHandler rRHandler;
|
||||
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.assetPack = assetPack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||
prefs = Gdx.app.getPreferences("RhythmBullet Preferences");
|
||||
setScreen(initialScreen);
|
||||
|
||||
if (getPrefs().getBoolean("fullscreen", true)) {
|
||||
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
|
||||
} else {
|
||||
Gdx.graphics.setWindowedMode(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
|
||||
}
|
||||
assetPack.initiateResources();
|
||||
|
||||
prefs = Gdx.app.getPreferences("RhythmBullet Preferences");
|
||||
|
||||
Resolution[] resolution = {
|
||||
new Resolution(1280, 720, "1280x720"),
|
||||
@ -88,57 +77,68 @@ public class RhythmBullet extends Game {
|
||||
assetManager.setLoader(Texture.class, new TextureLoader(rRHandler));
|
||||
assetManager.setLoader(ParticleEffect.class, new ParticleEffectLoader(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();
|
||||
screenHeight = Gdx.graphics.getHeight();
|
||||
|
||||
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
|
||||
}
|
||||
|
||||
public void checkAssetQueue() {
|
||||
if (!initComplete) {
|
||||
if (assetManager.update()) {
|
||||
generateFonts(Gdx.graphics.getHeight());
|
||||
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();
|
||||
}
|
||||
if (getPrefs().getBoolean("fullscreen", true)) {
|
||||
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
|
||||
} else {
|
||||
Gdx.graphics.setWindowedMode(getPrefs().getInteger("screen-width"), getPrefs().getInteger("screen-height"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render() {
|
||||
checkResize();
|
||||
checkAssetQueue();
|
||||
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
|
||||
public void setScreen(Screen screen) {
|
||||
if (screen instanceof AdvancedResizeScreen) {
|
||||
AdvancedResizeScreen advancedResizeScreen = (AdvancedResizeScreen) screen;
|
||||
if (screen instanceof ResizeReadyScreen) {
|
||||
ResizeReadyScreen advancedResizeScreen = (ResizeReadyScreen) screen;
|
||||
try {
|
||||
advancedResizeScreen.preAssetLoad();
|
||||
} catch (NullPointerException cleanScreen) {
|
||||
//Tried to perform pre-asset reload, but had uninitialized objects, meaning this is a new screen, or "clean" screen.
|
||||
} finally {
|
||||
advancedResizeScreen.postAssetLoad();
|
||||
}
|
||||
@ -146,235 +146,61 @@ public class RhythmBullet extends Game {
|
||||
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
|
||||
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) {
|
||||
screenWidth = Gdx.graphics.getWidth();
|
||||
screenHeight = Gdx.graphics.getHeight();
|
||||
|
||||
pixels_per_unit = (int) (Float.valueOf(screenHeight)/Float.valueOf(WORLD_HEIGHT));
|
||||
|
||||
if (initComplete) {
|
||||
Gdx.app.debug("Resize", "Pre-transition is happening. Using resolution " + width + "x" + height);
|
||||
rRHandler.setResolution(width, height);
|
||||
((AdvancedResizeScreen) getScreen()).preAssetLoad();
|
||||
assetManager.clear();
|
||||
prefs.putInteger("screen-width", width);
|
||||
prefs.putInteger("screen-height", height);
|
||||
prefs.flush();
|
||||
resizing = true;
|
||||
queueAssets();
|
||||
Gdx.app.debug("Resize", "Pre-resize is happening. Resizing to " + width + "x" + height);
|
||||
rRHandler.setResolution(width, height);
|
||||
if (getScreen() instanceof ResizeReadyScreen) {
|
||||
((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-height", height);
|
||||
prefs.flush();
|
||||
resizing = true;
|
||||
assetManager.clear();
|
||||
queueAssets();
|
||||
}
|
||||
super.resize(width, height);
|
||||
}
|
||||
|
||||
public int fontScale(float fontSize, int height) {
|
||||
int size = MathUtils.round(Gdx.graphics.getDensity()*(fontSize*height));
|
||||
if (size >= 200) {
|
||||
size = 200;
|
||||
}
|
||||
return size;
|
||||
public void queueAssets() {
|
||||
assetPack.queueTextures(assetManager);
|
||||
assetPack.queueSFX(assetManager);
|
||||
assetPack.queueParticles(assetManager);
|
||||
}
|
||||
|
||||
public AssetManager getAssetManager() {
|
||||
return assetManager;
|
||||
}
|
||||
|
||||
public Skin getDefaultSkin() {
|
||||
return defaultSkin;
|
||||
public Skin getSkinSkin() {
|
||||
return skin;
|
||||
}
|
||||
|
||||
public Preferences getPrefs() {
|
||||
return prefs;
|
||||
}
|
||||
|
||||
public void setInitComplete() {
|
||||
initComplete = true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
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.graphics.Texture;
|
@ -1,4 +1,4 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
package zero1hd.rhythmbullet.audio.metadata;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package zero1hd.rhythmbullet.audio;
|
||||
package zero1hd.rhythmbullet.audio.metadata;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -7,6 +7,7 @@ import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.files.FileHandle;
|
||||
|
||||
public class WAVAudioProcessor implements AudioProcessor {
|
||||
@ -17,11 +18,18 @@ public class WAVAudioProcessor implements AudioProcessor {
|
||||
private AudioInputStream audioInputStream;
|
||||
private boolean initiated;
|
||||
|
||||
public WAVAudioProcessor(FileHandle fileHandle, int windowSize) throws IOException, UnsupportedAudioFileException {
|
||||
public WAVAudioProcessor(FileHandle fileHandle) {
|
||||
this.fileHandle = fileHandle;
|
||||
AudioFormat format = AudioSystem.getAudioFileFormat(fileHandle.file()).getFormat();
|
||||
stereo = format.getChannels() > 1 ? true : false;
|
||||
sampleRate = (int) format.getSampleRate();
|
||||
AudioFormat format;
|
||||
try {
|
||||
format = AudioSystem.getAudioFileFormat(fileHandle.file()).getFormat();
|
||||
stereo = format.getChannels() > 1 ? true : false;
|
||||
sampleRate = (int) format.getSampleRate();
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
Gdx.app.debug("WAVAudioProcessor", "Couldn't instantiate WAVAUdioProcessor due to error.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -12,7 +12,6 @@ import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
|
||||
public class HorizontalVisualizer implements Disposable {
|
||||
private Pixmap pixmap;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package zero1hd.rhythmbullet.util;
|
||||
|
||||
public interface AdvancedResizeScreen {
|
||||
public interface ResizeReadyScreen {
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||
|
||||
@ -11,16 +8,15 @@ import zero1hd.rhythmbullet.desktop.screens.SplashScreen;
|
||||
|
||||
public class DesktopLauncher {
|
||||
public static void main (String[] arg) {
|
||||
Logger.getLogger("org.jaudiotagger").setLevel(Level.OFF);
|
||||
|
||||
RhythmBullet core;
|
||||
LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
|
||||
config.title = "Rhythm Bullet";
|
||||
config.resizable = false;
|
||||
config.allowSoftwareMode = true;
|
||||
config.useHDPI = true;
|
||||
|
||||
core = new RhythmBullet();
|
||||
core.setInitialScreen(new SplashScreen(core));
|
||||
core.setup(new SplashScreen(), new DesktopAssetPack());
|
||||
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.ShortBuffer;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
import org.lwjgl.openal.AL11;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
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.Field;
|
||||
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.visualizer.MusicManagerFFT;
|
||||
import zero1hd.rhythmbullet.audio.visualizer.Visualizer;
|
||||
import zero1hd.rhythmbullet.audio.MinimalAudioHeader;
|
||||
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 compareBuffer;
|
||||
private ShortBuffer buffer;
|
||||
private int sourceID;
|
||||
private int channelCount;
|
||||
private int sampleRate;
|
||||
private MusicController mc;
|
||||
private BufferStreamReadThread streamReadThread;
|
||||
private int windowsRead;
|
||||
private int currentPlaybackWindow;
|
||||
|
||||
public DesktopVisualizer() {
|
||||
super();
|
||||
try {
|
||||
Field bufferField = ClassReflection.getDeclaredField(OpenALMusic.class, "tempBuffer");
|
||||
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();
|
||||
} catch (IllegalArgumentException | SecurityException | ReflectionException e) {
|
||||
e.printStackTrace();
|
||||
Gdx.app.debug("Visualizer reflection", "Failed attempt at retrieving tempBuffer field.");
|
||||
Gdx.app.exit();
|
||||
}
|
||||
|
||||
streamReadThread = new BufferStreamReadThread();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see zero1hd.rhythmbullet.desktop.audio.visualizer.Visualizer#calcPCMData()
|
||||
*/
|
||||
@Override
|
||||
public void calcPCMData() {
|
||||
private synchronized void calcPCMData() {
|
||||
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++) {
|
||||
getAudioPCM()[sid] = 0;
|
||||
for (int channel = 0; channel < mm.getChannelCount(); channel ++) {
|
||||
if (getAudioPCM()[sid] < (chanVal = playingBuffer.get())) {
|
||||
getAudioPCM()[sid] = chanVal;
|
||||
for (int sid = 0; sid < PCM.length && sid < playingBuffer.remaining(); sid++) {
|
||||
PCM[sid] = 0;
|
||||
for (int channel = 0; channel < channelCount; channel ++) {
|
||||
if (PCM[sid] < (chanVal = playingBuffer.get())) {
|
||||
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.
|
||||
playingBuffer.put(compareBuffer);
|
||||
|
||||
synchronizeBufferWithPlayback();
|
||||
}
|
||||
|
||||
private int updateBufferPosition() {
|
||||
int pos = (int) ((alGetSourcef(sourceID, AL11.AL_SAMPLE_OFFSET))-buffer.limit()-mm.getChannelCount()*mm.getReadWindowSize());
|
||||
return pos;
|
||||
private int calcBufferPosition() {
|
||||
int offset = (int) alGetSourcef(sourceID, AL11.AL_SAMPLE_OFFSET);
|
||||
offset = (offset/windowSize) * windowSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see zero1hd.rhythmbullet.desktop.audio.visualizer.Visualizer#setMM(zero1hd.rhythmbullet.audio.MusicManager)
|
||||
*/
|
||||
@Override
|
||||
public void setMM(MusicManager mm) {
|
||||
private void synchronizeBufferWithPlayback() {
|
||||
playingBuffer.position(calcBufferPosition());
|
||||
windowsRead = (int) ((mc.getCurrentPosition()*sampleRate)/windowSize);
|
||||
}
|
||||
|
||||
public void setMusic(MinimalAudioHeader header) {
|
||||
try {
|
||||
Field sourceIDField = ClassReflection.getDeclaredField(OpenALMusic.class, "sourceID");
|
||||
sourceIDField.setAccessible(true);
|
||||
sourceID = (int) sourceIDField.get(mm.getMusic());
|
||||
sourceID = (int) sourceIDField.get(mc.getCurrentMusic());
|
||||
} catch (ReflectionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int originalPos = buffer.position();
|
||||
channelCount = header.getChannelCount();
|
||||
sampleRate = header.getSampleRate();
|
||||
|
||||
playingBuffer = ShortBuffer.allocate(buffer.capacity()*2);
|
||||
buffer.rewind();
|
||||
@ -117,28 +130,76 @@ public class DesktopVisualizer extends MusicManagerFFT implements Visualizer {
|
||||
compareBuffer.put(buffer);
|
||||
compareBuffer.flip();
|
||||
|
||||
buffer.position(originalPos);
|
||||
this.mm = mm;
|
||||
buffer.rewind();
|
||||
}
|
||||
|
||||
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
|
||||
public MusicManager getMM() {
|
||||
return mm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Batch batch, float parentAlpha) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] getAudioPCMData() {
|
||||
return getAudioPCM();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fft() {
|
||||
calculate();
|
||||
public void update(Observable o, Object arg) {
|
||||
if (o == mc) {
|
||||
switch ((MusicController.States) arg) {
|
||||
case Loaded:
|
||||
setMusic(mc.getCurrentMusicHeader());
|
||||
break;
|
||||
case Playing:
|
||||
streamReadThread.start();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
|
||||
import zero1hd.rhythmbullet.desktop.screens.MainMenuScreen;
|
||||
import zero1hd.rhythmbullet.desktop.screens.MainScreen;
|
||||
|
||||
public class GraphicsOptions extends Table {
|
||||
private Label resolutions, shaders;
|
||||
@ -28,7 +28,7 @@ public class GraphicsOptions extends Table {
|
||||
_1366x768;
|
||||
|
||||
|
||||
public GraphicsOptions(final MainMenuScreen mainMenu, Skin skin, final Preferences prefs) {
|
||||
public GraphicsOptions(final MainScreen mainMenu, Skin skin, final Preferences prefs) {
|
||||
align(Align.center);
|
||||
defaults().space(10f);
|
||||
this.prefs = prefs;
|
||||
|
@ -1,19 +1,19 @@
|
||||
package zero1hd.rhythmbullet.desktop.graphics.ui.components;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.audio.Music;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Widget;
|
||||
import com.badlogic.gdx.utils.Disposable;
|
||||
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.audio.visualizer.HorizontalVisualizer;
|
||||
import zero1hd.rhythmbullet.desktop.audio.visualizer.DesktopVisualizer;
|
||||
|
||||
public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
||||
private HorizontalVisualizer vis;
|
||||
private boolean updatePositioning = true;
|
||||
private MusicManager mm;
|
||||
private Music music;
|
||||
private boolean initialLoad;
|
||||
private float visRefreshRate;
|
||||
private float timer;
|
||||
@ -29,13 +29,13 @@ public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
if (mm != null && mm.isFinishedLoading() && !initialLoad) {
|
||||
visRefreshRate = mm.getReadWindowSize()/mm.getSampleRate();
|
||||
Gdx.app.debug("Visualizer", "\nsample count: " + mm.getSampleCount()
|
||||
+ "\nDuration in seconds: " + mm.getDuration() +
|
||||
"\nSample rate: " + mm.getSampleRate() +
|
||||
if (music != null && music.isFinishedLoading() && !initialLoad) {
|
||||
visRefreshRate = music.getReadWindowSize()/music.getSampleRate();
|
||||
Gdx.app.debug("Visualizer", "\nsample count: " + music.getSampleCount()
|
||||
+ "\nDuration in seconds: " + music.getDuration() +
|
||||
"\nSample rate: " + music.getSampleRate() +
|
||||
"\nRefresh rate: " + visRefreshRate);
|
||||
vis.setMM(mm);
|
||||
vis.setMusic(music);
|
||||
initialLoad = true;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
||||
|
||||
vis.update(delta);
|
||||
updateVisualizerProperties();
|
||||
if (mm != null && initialLoad) {
|
||||
if (music != null && initialLoad) {
|
||||
if (timer >= visRefreshRate) {
|
||||
timer = 0;
|
||||
vis.calculate();
|
||||
@ -58,9 +58,9 @@ public class HorizontalVisualizerWidget extends Widget implements Disposable {
|
||||
super.act(delta);
|
||||
}
|
||||
|
||||
public void setMM(MusicManager mm) {
|
||||
public void setMusic(Music music) {
|
||||
initialLoad = false;
|
||||
this.mm = mm;
|
||||
this.music = music;
|
||||
}
|
||||
|
||||
@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.utils.ChangeListener;
|
||||
|
||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.audio.MusicController;
|
||||
|
||||
public class MusicControls extends HorizontalGroup {
|
||||
private ImageButton reverse, forward;
|
||||
private CheckBox shuffle, play;
|
||||
private float disableTimer;
|
||||
public MusicControls(Skin skin, final MusicListController sc) {
|
||||
public MusicControls(Skin skin, final MusicController sc) {
|
||||
reverse = new ImageButton(skin, "rewind-button");
|
||||
reverse.addListener(new ChangeListener() {
|
||||
@Override
|
||||
|
@ -39,7 +39,7 @@ public class AnalysisPage extends Page {
|
||||
addActor(table);
|
||||
this.core = core;
|
||||
adjustment = new Table();
|
||||
Skin skin = core.getDefaultSkin();
|
||||
Skin skin = core.getSkinSkin();
|
||||
|
||||
difficultyModLabel = new Label("Difficulty Modifier: ", skin, "sub-font", skin.getColor("default"));
|
||||
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 zero1hd.rhythmbullet.desktop.graphics.ui.components.GraphicsOptions;
|
||||
import zero1hd.rhythmbullet.desktop.screens.MainMenuScreen;
|
||||
import zero1hd.rhythmbullet.desktop.screens.MainScreen;
|
||||
|
||||
public class GraphicsOptionsPage extends Page {
|
||||
private ScrollPane scrollPane;
|
||||
private GraphicsOptions graphicsTable;
|
||||
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);
|
||||
scrollPane = new ScrollPane(graphicsTable, skin);
|
||||
scrollPane.setFadeScrollBars(false);
|
||||
|
@ -14,17 +14,16 @@ import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.audio.MusicController;
|
||||
import zero1hd.rhythmbullet.desktop.graphics.ui.components.MusicControls;
|
||||
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;
|
||||
|
||||
public class MainPage extends Page implements Observer {
|
||||
private Label versionLabel;
|
||||
|
||||
private MusicListController mlc;
|
||||
private MusicController mc;
|
||||
private TitleBarVisualizer titleBar;
|
||||
private Table table;
|
||||
private TextButton playButton;
|
||||
@ -32,17 +31,17 @@ public class MainPage extends Page implements Observer {
|
||||
private TextButton quitButton;
|
||||
|
||||
private MusicControls musicControls;
|
||||
private MainMenuScreen mMenu;
|
||||
private MainScreen mMenu;
|
||||
private ScrollText scrollText;
|
||||
|
||||
public MainPage(RhythmBullet core, final Vector3 targetPosition, MusicListController mlc, final MainMenuScreen mainMenu) {
|
||||
this.mlc = mlc;
|
||||
public MainPage(RhythmBullet core, Vector3 targetPosition, MusicController mlc, MainScreen mainMenu) {
|
||||
this.mc = mlc;
|
||||
this.mMenu = mainMenu;
|
||||
titleBar = new TitleBarVisualizer(core.getAssetManager());
|
||||
addActor(titleBar);
|
||||
|
||||
versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getDefaultSkin(), "sub-font",
|
||||
core.getDefaultSkin().getColor("default"));
|
||||
versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getSkinSkin(), "sub-font",
|
||||
core.getSkinSkin().getColor("default"));
|
||||
versionLabel.setPosition(3, 3);
|
||||
addActor(versionLabel);
|
||||
|
||||
@ -51,7 +50,7 @@ public class MainPage extends Page implements Observer {
|
||||
table.align(Align.center);
|
||||
table.defaults().space(10f);
|
||||
addActor(table);
|
||||
playButton = new TextButton("Start!", core.getDefaultSkin());
|
||||
playButton = new TextButton("Start!", core.getSkinSkin());
|
||||
playButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -63,7 +62,7 @@ public class MainPage extends Page implements Observer {
|
||||
|
||||
table.row();
|
||||
|
||||
optionsButton = new TextButton("Options", core.getDefaultSkin(), "sub");
|
||||
optionsButton = new TextButton("Options", core.getSkinSkin(), "sub");
|
||||
optionsButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -74,7 +73,7 @@ public class MainPage extends Page implements Observer {
|
||||
|
||||
table.row();
|
||||
|
||||
quitButton = new TextButton("Quit", core.getDefaultSkin(), "sub");
|
||||
quitButton = new TextButton("Quit", core.getSkinSkin(), "sub");
|
||||
quitButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -83,11 +82,11 @@ public class MainPage extends Page implements Observer {
|
||||
});
|
||||
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);
|
||||
addActor(musicControls);
|
||||
|
||||
scrollText = new ScrollText("...", "...", core.getDefaultSkin(), false, true);
|
||||
scrollText = new ScrollText("...", "...", core.getSkinSkin(), false, true);
|
||||
scrollText.setWidth(0.5f*getWidth());
|
||||
scrollText.setPosition(15, getHeight() - scrollText.getHeight()-25f);
|
||||
addActor(scrollText);
|
||||
@ -111,21 +110,8 @@ public class MainPage extends Page implements Observer {
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
if (o == mlc.getMusicList() && mlc.getMusicList().isSearched()) {
|
||||
mlc.shuffle(true);
|
||||
MusicManager mm = mlc.getCurrentMusicManager();
|
||||
updateVisualsForDifferentSong(mm);
|
||||
mMenu.getMusicSelectionPage().refreshUIList();
|
||||
} else if (o == mlc) {
|
||||
MusicManager mm = mlc.getCurrentMusicManager();
|
||||
mlc.play();
|
||||
updateVisualsForDifferentSong(mm);
|
||||
if (o == mc && arg == MusicController.States.Loaded) {
|
||||
scrollText.setText("Currently playing: " + mc.getCurrentSongName(), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 zero1hd.rhythmbullet.audio.MusicInfo;
|
||||
import zero1hd.rhythmbullet.audio.MusicMetadataController;
|
||||
import zero1hd.rhythmbullet.audio.MusicController;
|
||||
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.graphics.ui.components.ScrollText;
|
||||
|
||||
public class MusicSelectionPage extends Page implements Observer {
|
||||
Preferences musicFileAnnotation;
|
||||
|
||||
private MusicListController mc;
|
||||
private MusicInfoController mic;
|
||||
private MusicController mc;
|
||||
private MusicMetadataController mic;
|
||||
private Array<MusicSelectable> selectables;
|
||||
private Table musicTable;
|
||||
private ScrollPane musicTableScrollPane;
|
||||
@ -65,7 +65,7 @@ public class MusicSelectionPage extends Page implements Observer {
|
||||
private int uiSongInfoCount;
|
||||
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.skin = skin;
|
||||
this.mc = musicListController;
|
||||
@ -139,7 +139,7 @@ public class MusicSelectionPage extends Page implements Observer {
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
if (getSelectedMusic() != null) {
|
||||
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());
|
||||
}
|
||||
} else if (uiSongInfoCount < selectables.size && mic.isDone()) {
|
||||
selectables.get(uiSongInfoCount).updateInfo(mic.getSongInfoArray().get(uiSongInfoCount));
|
||||
selectables.get(uiSongInfoCount).updateInfo(mic.getMetadataArray().get(uiSongInfoCount));
|
||||
uiSongInfoCount++;
|
||||
if (uiSongInfoCount == selectables.size) {
|
||||
updateInformation();
|
||||
@ -291,9 +291,8 @@ public class MusicSelectionPage extends Page implements Observer {
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
if (o == mc) {
|
||||
MusicManager mm = (MusicManager) arg;
|
||||
selectMusicUI(mm);
|
||||
if (o == mc && arg == MusicController.States.Loaded) {
|
||||
selectMusicUI(mc.getCurrentMusic());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField;
|
||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
|
||||
|
||||
import zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.audio.MusicController;
|
||||
|
||||
public class OptionsPage extends Page {
|
||||
Table optionsTable;
|
||||
@ -23,11 +23,11 @@ public class OptionsPage extends Page {
|
||||
private TextField directoryField;
|
||||
private float musicSearchTimer;
|
||||
|
||||
public OptionsPage(final RhythmBullet core, final Vector3 targetPosition, KeybindOptionsPage moreOptionsPage, MusicListController mlc) {
|
||||
super("General", core.getDefaultSkin());
|
||||
public OptionsPage(final RhythmBullet core, final Vector3 targetPosition, KeybindOptionsPage moreOptionsPage, MusicController mlc) {
|
||||
super("General", core.getSkinSkin());
|
||||
|
||||
//Back button
|
||||
TextButton backButton = new TextButton("Back", core.getDefaultSkin());
|
||||
TextButton backButton = new TextButton("Back", core.getSkinSkin());
|
||||
backButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -43,12 +43,12 @@ public class OptionsPage extends Page {
|
||||
optionsTable.setSize(getWidth(), getHeight());
|
||||
addActor(optionsTable);
|
||||
|
||||
Label musicVolSliderLabel = new Label("Music Volume: ", core.getDefaultSkin());
|
||||
Label musicVolSliderLabel = new Label("Music Volume: ", core.getSkinSkin());
|
||||
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);
|
||||
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() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -62,12 +62,12 @@ public class OptionsPage extends Page {
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
Label fxVolSliderLabel = new Label("FX Volume: ", core.getDefaultSkin());
|
||||
Label fxVolSliderLabel = new Label("FX Volume: ", core.getSkinSkin());
|
||||
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);
|
||||
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() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -80,16 +80,16 @@ public class OptionsPage extends Page {
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
Label musicDirectoryLabel = new Label("Music Directory: ", core.getDefaultSkin());
|
||||
Label musicDirectoryLabel = new Label("Music Directory: ", core.getSkinSkin());
|
||||
optionsTable.add(musicDirectoryLabel);
|
||||
directoryField = new TextField(null, core.getDefaultSkin() ) {
|
||||
directoryField = new TextField(null, core.getSkinSkin() ) {
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
if (musicSearchTimer > 0) {
|
||||
musicSearchTimer -= delta;
|
||||
if (musicSearchTimer <= 0) {
|
||||
mlc.getMusicList().setSearchPath(directoryField.getText());
|
||||
mlc.getMusicList().asynchRefresh();
|
||||
mlc.getMusicList().asyncSearch();
|
||||
}
|
||||
}
|
||||
super.act(delta);
|
||||
@ -106,7 +106,7 @@ public class OptionsPage extends Page {
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
TextButton keybindSettings = new TextButton("Set Controls", core.getDefaultSkin());
|
||||
TextButton keybindSettings = new TextButton("Set Controls", core.getSkinSkin());
|
||||
keybindSettings.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -117,7 +117,7 @@ public class OptionsPage extends Page {
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
TextButton graphicsSettings = new TextButton("Graphics", core.getDefaultSkin());
|
||||
TextButton graphicsSettings = new TextButton("Graphics", core.getSkinSkin());
|
||||
graphicsSettings.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
@ -128,7 +128,7 @@ public class OptionsPage extends Page {
|
||||
|
||||
optionsTable.row();
|
||||
|
||||
Label fpsLabel = new Label("", core.getDefaultSkin()) {
|
||||
Label fpsLabel = new Label("", core.getSkinSkin()) {
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
setText("Current Frames Per Second: " + Gdx.graphics.getFramesPerSecond());
|
||||
@ -139,7 +139,7 @@ public class OptionsPage extends Page {
|
||||
|
||||
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;
|
||||
@Override
|
||||
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 zero1hd.rhythmbullet.RhythmBullet;
|
||||
import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.desktop.audio.MusicInfoController;
|
||||
import zero1hd.rhythmbullet.desktop.audio.MusicList;
|
||||
import zero1hd.rhythmbullet.desktop.audio.MusicListController;
|
||||
import zero1hd.rhythmbullet.audio.MusicMetadataController;
|
||||
import zero1hd.rhythmbullet.audio.MusicList;
|
||||
import zero1hd.rhythmbullet.audio.MusicController;
|
||||
import zero1hd.rhythmbullet.desktop.audio.processor.DesktopAudioProcessorFactory;
|
||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.AnalysisPage;
|
||||
import zero1hd.rhythmbullet.desktop.graphics.ui.pages.CreditsPage;
|
||||
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.OptionsPage;
|
||||
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;
|
||||
private Vector3 cameraPosition;
|
||||
|
||||
@ -46,8 +46,8 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
private AnalysisPage analysisPage;
|
||||
private RhythmBullet core;
|
||||
|
||||
private MusicListController mlc;
|
||||
private MusicInfoController mic;
|
||||
private MusicController mlc;
|
||||
private MusicMetadataController mmc;
|
||||
|
||||
private float lerpAlpha;
|
||||
|
||||
@ -66,19 +66,18 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
private Batch screenBatch;
|
||||
private ScreenViewport screenViewport;
|
||||
|
||||
public MainMenuScreen(RhythmBullet core) {
|
||||
public MainScreen(RhythmBullet core) {
|
||||
this.core = core;
|
||||
stage = new Stage(new ScreenViewport());
|
||||
cameraPosition = new Vector3(stage.getCamera().position);
|
||||
|
||||
MusicList musicList = new MusicList();
|
||||
MusicList musicList = new MusicList(new DesktopAudioProcessorFactory());
|
||||
musicList.setSearchPath(core.getPrefs().getString("music dir"));
|
||||
musicList.asynchRefresh();
|
||||
mlc = new MusicListController(musicList, core.getPrefs());
|
||||
mlc = new MusicController(musicList, core.getPrefs());
|
||||
mlc.setAutoPlay(true);
|
||||
mlc.setShuffle(true);
|
||||
|
||||
mic = new MusicInfoController(musicList);
|
||||
mmc = new MusicMetadataController(musicList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -105,7 +104,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
fboRegion.setTexture(normalBuffer.getColorBufferTexture());
|
||||
screenBatch.setShader(brightFilterShader);
|
||||
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.flush();
|
||||
lightFilterBuffer.end();
|
||||
@ -180,6 +179,8 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
|
||||
@Override
|
||||
public void postAssetLoad() {
|
||||
mlc.deleteObservers();
|
||||
|
||||
background = core.getAssetManager().get("backgrounds/mainBG.png", Texture.class);
|
||||
screenBatch = new SpriteBatch();
|
||||
|
||||
@ -188,11 +189,11 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
stage.addActor(mainPage);
|
||||
//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());
|
||||
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());
|
||||
stage.addActor(graphicsPage);
|
||||
@ -201,7 +202,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
optionsPage.setPosition(-Gdx.graphics.getWidth(), 0);
|
||||
stage.addActor(optionsPage);
|
||||
|
||||
creditsPage = new CreditsPage(core.getDefaultSkin());
|
||||
creditsPage = new CreditsPage(core.getSkinSkin());
|
||||
creditsPage.setPosition(0, Gdx.graphics.getHeight());
|
||||
stage.addActor(creditsPage);
|
||||
|
||||
@ -209,7 +210,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
analysisPage.setPosition(2*Gdx.graphics.getWidth(), 0f);
|
||||
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);
|
||||
stage.addActor(musicSelectionPage);
|
||||
stage.addListener(new InputListener() {
|
||||
@ -233,17 +234,12 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
super.clicked(event, x, y);
|
||||
}
|
||||
});
|
||||
mlc.getMusicList().deleteObservers();
|
||||
mlc.deleteObservers();
|
||||
|
||||
mlc.addObserver(musicSelectionPage);
|
||||
mlc.addObserver(mainPage);
|
||||
mlc.getMusicList().addObserver(mainPage);
|
||||
|
||||
if (mlc.getMusicList().isSearched() && mlc.getCurrentMusicManager() != null) {
|
||||
MusicManager mManager = mlc.getCurrentMusicManager();
|
||||
mainPage.updateVisualsForDifferentSong(mManager);
|
||||
musicSelectionPage.refreshUIList();
|
||||
}
|
||||
mlc.getMusicList().asyncSearch();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -281,7 +277,7 @@ public class MainMenuScreen extends ScreenAdapter implements AdvancedResizeScree
|
||||
if (gaussianBlurShader != null) {
|
||||
dismantleShaders();
|
||||
}
|
||||
mic.dispose();
|
||||
mmc.dispose();
|
||||
screenBatch.dispose();
|
||||
super.dispose();
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package zero1hd.rhythmbullet.desktop.screens;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.ScreenAdapter;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
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.utils.viewport.ScreenViewport;
|
||||
|
||||
import zero1hd.rhythmbullet.InitialScreen;
|
||||
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 RhythmBullet core;
|
||||
private Texture splash;
|
||||
private Image zero1HD;
|
||||
private boolean done;
|
||||
|
||||
public SplashScreen(RhythmBullet core) {
|
||||
this.core = core;
|
||||
public SplashScreen() {
|
||||
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
|
||||
@ -34,49 +38,31 @@ public class SplashScreen extends ScreenAdapter implements AdvancedResizeScreen
|
||||
Gdx.gl.glClearColor(1f, 1f, 1f, 1f);
|
||||
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||
stage.act(delta);
|
||||
|
||||
if (!zero1HD.hasActions() && core.isInitComplete()) {
|
||||
attemptMoveOn();
|
||||
}
|
||||
|
||||
stage.draw();
|
||||
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
|
||||
public void hide() {
|
||||
core.setInitComplete();
|
||||
splash.dispose();
|
||||
super.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preAssetLoad() {
|
||||
if (stage != null) {
|
||||
stage.dispose();
|
||||
splash.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postAssetLoad() {
|
||||
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.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.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