visualizer works in a basic manner, disposing needed, gui needs
tweaking, visualizer bar rate could be adjusted;
This commit is contained in:
parent
4a7f4962e2
commit
f2a60ea490
@ -203,4 +203,5 @@ public class RhythmBullet extends Game {
|
|||||||
}
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package zero1hd.rhythmbullet.audio.visualizer;
|
|
||||||
|
|
||||||
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
|
|
||||||
|
|
||||||
public class BasicFFT {
|
|
||||||
private FloatFFT_1D fft;
|
|
||||||
|
|
||||||
public BasicFFT(int window) {
|
|
||||||
fft = new FloatFFT_1D(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fft(float[] PCM) {
|
|
||||||
fft.realForward(PCM);
|
|
||||||
}
|
|
||||||
}
|
|
41
core/src/zero1hd/rhythmbullet/audio/visualizer/DoubleHorizontalVisualizer.java
Normal file → Executable file
41
core/src/zero1hd/rhythmbullet/audio/visualizer/DoubleHorizontalVisualizer.java
Normal file → Executable file
@ -3,21 +3,22 @@ package zero1hd.rhythmbullet.audio.visualizer;
|
|||||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
import zero1hd.rhythmbullet.audio.MusicController;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
|
|
||||||
public class DoubleHorizontalVisualizer {
|
public class DoubleHorizontalVisualizer implements Disposable {
|
||||||
private int width, height, barCount, barWidth, spaceBetweenBars;
|
private int width, height, barCount, barWidth, spaceBetweenBars;
|
||||||
private int x, y;
|
private int x, y;
|
||||||
private float barRate = 0.75f;
|
|
||||||
private ShapeRenderer shapeRenderer;
|
private ShapeRenderer shapeRenderer;
|
||||||
private PCMSystem pcm;
|
private PCMSystem pcm;
|
||||||
private int smoothRange;
|
private float[] amplitudes;
|
||||||
private int multiplier = 300;
|
|
||||||
private int[] amplitudes;
|
|
||||||
private int[] barHeights;
|
private int[] barHeights;
|
||||||
private int binsPerBar;
|
private int binsPerBar;
|
||||||
|
private float normalFactor = 20;
|
||||||
|
private float barChangeRate = 4f;
|
||||||
|
private int smoothRange = 1;
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param barCount amount of bars this visualizer should have.
|
* @param barCount amount of bars this visualizer should have.
|
||||||
@ -27,14 +28,14 @@ public class DoubleHorizontalVisualizer {
|
|||||||
public DoubleHorizontalVisualizer(int barCount, int width, int height, float spacePercentage, MusicController musicController, PCMSystem PCMSystem) {
|
public DoubleHorizontalVisualizer(int barCount, int width, int height, float spacePercentage, MusicController musicController, PCMSystem PCMSystem) {
|
||||||
this.barCount = barCount;
|
this.barCount = barCount;
|
||||||
this.barWidth = width/barCount;
|
this.barWidth = width/barCount;
|
||||||
this.spaceBetweenBars = (int) (barWidth * spacePercentage);
|
this.spaceBetweenBars = MathUtils.round(barWidth * spacePercentage);
|
||||||
this.barWidth -= spaceBetweenBars;
|
this.barWidth -= spaceBetweenBars;
|
||||||
pcm = PCMSystem;
|
pcm = PCMSystem;
|
||||||
if (barWidth < 1) throw new IllegalArgumentException("The arguments you passed caused the bar width to be 0.");
|
if (barWidth < 1) throw new IllegalArgumentException("The arguments you passed caused the bar width to be 0.");
|
||||||
binsPerBar = (pcm.getFrequencyBins().length/barCount);
|
binsPerBar = (pcm.getFrequencyBins().length/barCount);
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
amplitudes = new int[barCount];
|
amplitudes = new float[barCount];
|
||||||
barHeights = new int[barCount];
|
barHeights = new int[barCount];
|
||||||
shapeRenderer = new ShapeRenderer();
|
shapeRenderer = new ShapeRenderer();
|
||||||
}
|
}
|
||||||
@ -45,26 +46,29 @@ public class DoubleHorizontalVisualizer {
|
|||||||
for (int freq = bar*binsPerBar; freq < (bar*binsPerBar) + binsPerBar; freq++) {
|
for (int freq = bar*binsPerBar; freq < (bar*binsPerBar) + binsPerBar; freq++) {
|
||||||
normalizedAmplitude += Math.abs(pcm.getFrequencyBins()[freq]);
|
normalizedAmplitude += Math.abs(pcm.getFrequencyBins()[freq]);
|
||||||
}
|
}
|
||||||
amplitudes[bar] = (int) (normalizedAmplitude*multiplier);
|
amplitudes[bar] += normalizedAmplitude * normalFactor;
|
||||||
amplitudes[bar] /= binsPerBar;
|
amplitudes[bar] /= binsPerBar;
|
||||||
|
|
||||||
barHeights[bar] += Math.max(0, (amplitudes[bar] - barHeights[bar]) * barRate * delta);
|
|
||||||
if (barHeights[bar] > amplitudes[bar]) barHeights[bar] = amplitudes[bar];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
for (int bar = 0; bar < barHeights.length; bar++) {
|
for (int bar = 0; bar < barHeights.length; bar++) {
|
||||||
int smoothCount = 1;
|
int smoothCount = 1;
|
||||||
for (int range = 0; range < smoothRange; range++) {
|
for (int range = 0; range < smoothRange; range++) {
|
||||||
if (bar+range < amplitudes.length) {
|
if (bar+range < amplitudes.length) {
|
||||||
barHeights[bar] += amplitudes[bar+range];
|
amplitudes[bar] += amplitudes[bar+range];
|
||||||
smoothCount++;
|
smoothCount++;
|
||||||
}
|
}
|
||||||
if (bar-range > 0) {
|
if (bar-range > 0) {
|
||||||
barHeights[bar] += amplitudes[bar-range];
|
amplitudes[bar] += amplitudes[bar-range];
|
||||||
smoothCount++;
|
smoothCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
barHeights[bar] /= smoothCount;
|
amplitudes[bar] /= smoothCount;
|
||||||
|
|
||||||
|
int pixelsMoved = MathUtils.round(amplitudes[bar] - barHeights[bar]);
|
||||||
|
pixelsMoved = MathUtils.floor(pixelsMoved*delta*barChangeRate);
|
||||||
|
barHeights[bar] += pixelsMoved;
|
||||||
|
|
||||||
|
if (barHeights[bar] < 0) barHeights[bar] = 0;
|
||||||
|
if (barHeights[bar] > height) barHeights[bar] = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,4 +117,9 @@ public class DoubleHorizontalVisualizer {
|
|||||||
public int getY() {
|
public int getY() {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
pcm.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package zero1hd.rhythmbullet.audio.visualizer;
|
package zero1hd.rhythmbullet.audio.visualizer;
|
||||||
|
|
||||||
public interface PCMSystem {
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
|
public interface PCMSystem extends Disposable {
|
||||||
|
|
||||||
float[] getFrequencyBins();
|
float[] getFrequencyBins();
|
||||||
|
|
||||||
|
@ -2,8 +2,10 @@ package zero1hd.rhythmbullet.desktop.audio;
|
|||||||
|
|
||||||
import static org.lwjgl.openal.AL10.alGetSourcef;
|
import static org.lwjgl.openal.AL10.alGetSourcef;
|
||||||
|
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
@ -11,27 +13,29 @@ import org.lwjgl.openal.AL11;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.backends.lwjgl.audio.OpenALMusic;
|
import com.badlogic.gdx.backends.lwjgl.audio.OpenALMusic;
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
import com.badlogic.gdx.utils.reflect.Field;
|
import com.badlogic.gdx.utils.reflect.Field;
|
||||||
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||||
|
|
||||||
|
import edu.emory.mathcs.jtransforms.fft.FloatFFT_1D;
|
||||||
import zero1hd.rhythmbullet.audio.MusicController;
|
import zero1hd.rhythmbullet.audio.MusicController;
|
||||||
import zero1hd.rhythmbullet.audio.visualizer.BasicFFT;
|
|
||||||
import zero1hd.rhythmbullet.audio.visualizer.PCMSystem;
|
import zero1hd.rhythmbullet.audio.visualizer.PCMSystem;
|
||||||
|
|
||||||
public class PCMObtainer implements Observer, Disposable, PCMSystem {
|
public class PCMObtainer implements Observer, PCMSystem {
|
||||||
private int windowSize = 1024;
|
private int windowSize = 1024;
|
||||||
|
private int sampleRate;
|
||||||
|
private long millisPerWindow;
|
||||||
|
private DecimalFormat df;
|
||||||
private float[] PCM = new float[windowSize];
|
private float[] PCM = new float[windowSize];
|
||||||
private float[] frequencyBins = new float[windowSize / 2];
|
private float[] frequencyBins = new float[windowSize / 2];
|
||||||
private BasicFFT fft = new BasicFFT(windowSize);
|
private FloatFFT_1D fft = new FloatFFT_1D(windowSize);
|
||||||
private ShortBuffer playingBuffer;
|
private ShortBuffer playingBuffer;
|
||||||
private ShortBuffer compareBuffer;
|
private ShortBuffer compareBuffer;
|
||||||
private ShortBuffer buffer;
|
private ShortBuffer buffer;
|
||||||
private int sourceID;
|
private int sourceID;
|
||||||
private int channelCount;
|
private int channelCount;
|
||||||
private int sampleRate;
|
|
||||||
private MusicController mc;
|
private MusicController mc;
|
||||||
private BufferStreamReadThread streamReadThread;
|
private BufferStreamReadThread streamReadThread;
|
||||||
private int windowsRead;
|
private int windowsRead;
|
||||||
@ -51,6 +55,9 @@ public class PCMObtainer implements Observer, Disposable, PCMSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
streamReadThread = new BufferStreamReadThread();
|
streamReadThread = new BufferStreamReadThread();
|
||||||
|
|
||||||
|
df = new DecimalFormat("#.###");
|
||||||
|
df.setRoundingMode(RoundingMode.HALF_EVEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void calcPCMData() {
|
private synchronized void calcPCMData() {
|
||||||
@ -116,7 +123,8 @@ public class PCMObtainer implements Observer, Disposable, PCMSystem {
|
|||||||
|
|
||||||
channelCount = mc.getCurrentMusicHeader().getChannelCount();
|
channelCount = mc.getCurrentMusicHeader().getChannelCount();
|
||||||
sampleRate = mc.getCurrentMusicHeader().getSampleRate();
|
sampleRate = mc.getCurrentMusicHeader().getSampleRate();
|
||||||
|
String millisPerWindowF = df.format(windowSize/(float) sampleRate);
|
||||||
|
millisPerWindow = (long) (Float.valueOf(millisPerWindowF)*1000);
|
||||||
playingBuffer = ShortBuffer.allocate(buffer.capacity() * 2);
|
playingBuffer = ShortBuffer.allocate(buffer.capacity() * 2);
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
playingBuffer.put(buffer);
|
playingBuffer.put(buffer);
|
||||||
@ -134,7 +142,6 @@ public class PCMObtainer implements Observer, Disposable, PCMSystem {
|
|||||||
public float[] getFrequencyBins() {
|
public float[] getFrequencyBins() {
|
||||||
if (updated) {
|
if (updated) {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
fft.fft(PCM);
|
|
||||||
System.arraycopy(PCM, 1, frequencyBins, 0, frequencyBins.length);
|
System.arraycopy(PCM, 1, frequencyBins, 0, frequencyBins.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,34 +157,50 @@ public class PCMObtainer implements Observer, Disposable, PCMSystem {
|
|||||||
private String name = "PCM-Audio-Processing";
|
private String name = "PCM-Audio-Processing";
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
private volatile boolean run = true;
|
private volatile boolean run = true;
|
||||||
private boolean paused;
|
|
||||||
private long timeOfLastRead;
|
private long timeOfLastRead;
|
||||||
private int waitTime;
|
private long waitTime;
|
||||||
|
private int syncC, normC;
|
||||||
|
private float syncPercentage;
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (run) {
|
while (run) {
|
||||||
if (mc.isPlaying()) {
|
if (mc.isPlaying()) {
|
||||||
if (paused) {
|
//record time of read
|
||||||
timeOfLastRead = TimeUtils.millis();
|
timeOfLastRead = TimeUtils.millis();
|
||||||
paused = false;
|
|
||||||
}
|
|
||||||
waitTime = sampleRate / windowSize / Gdx.graphics.getFramesPerSecond();
|
|
||||||
if (TimeUtils.timeSinceMillis(timeOfLastRead) >= waitTime) {
|
|
||||||
calcPCMData();
|
|
||||||
updated = true;
|
|
||||||
windowsRead++;
|
|
||||||
timeOfLastRead = TimeUtils.millis();
|
|
||||||
|
|
||||||
currentPlaybackWindow = (int) ((mc.getCurrentPosition() * sampleRate) / windowSize);
|
//calculate current pcm data and notify that there is new data
|
||||||
if (windowsRead != currentPlaybackWindow) {
|
calcPCMData();
|
||||||
synchronizeBufferWithPlayback();
|
fft.realForward(PCM);
|
||||||
|
updated = true;
|
||||||
|
windowsRead++;
|
||||||
|
|
||||||
|
//contemplate synchronization
|
||||||
|
try {
|
||||||
|
currentPlaybackWindow = MathUtils.round((mc.getCurrentPosition() * sampleRate) / windowSize);
|
||||||
|
} catch (UnsatisfiedLinkError ule) {
|
||||||
|
if (run) {
|
||||||
|
ule.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (windowsRead != currentPlaybackWindow) {
|
||||||
|
synchronizeBufferWithPlayback();
|
||||||
|
syncC++;
|
||||||
|
} else {
|
||||||
|
normC++;
|
||||||
|
}
|
||||||
|
syncPercentage = (syncC*100)/(float)(normC+syncC);
|
||||||
|
System.out.printf("%.2f", syncPercentage);
|
||||||
|
System.out.print("%\n");
|
||||||
|
//wait for a bit before reading again depending on the speed at which the system does playback.
|
||||||
|
waitTime = Math.max(0, millisPerWindow - TimeUtils.timeSinceMillis(timeOfLastRead));
|
||||||
|
try {
|
||||||
|
Thread.sleep(waitTime);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
try {
|
try {
|
||||||
paused = true;
|
|
||||||
wait();
|
wait();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -199,6 +222,7 @@ public class PCMObtainer implements Observer, Disposable, PCMSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
Gdx.app.debug("PCMObtainer", "stopping " + thread.getName());
|
||||||
run = false;
|
run = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ public class GraphicsOptions extends Table {
|
|||||||
pack();
|
pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void saveOptions() {
|
||||||
Gdx.app.debug("Preferences", "Saved shading values values.");
|
Gdx.app.debug("Preferences", "Saved shading values values.");
|
||||||
prefs.putInteger("glow shader", (int) glowShaderLevel.getValue());
|
prefs.putInteger("glow shader", (int) glowShaderLevel.getValue());
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,10 @@ public class Page extends Group implements Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setStage(Stage stage) {
|
public void setStage(Stage stage) {
|
||||||
|
if (stage == null && !hasParent()) {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
if (!(stage.getViewport() instanceof ScreenViewport)) {
|
if (!(stage.getViewport() instanceof ScreenViewport)) {
|
||||||
throw new IllegalArgumentException("Pages are explicitly for GUIs, and thus should have a 1:1 ratio between pixel and texture size for maximum clarity. This means that the stage should be using a ScreenViewport.");
|
throw new IllegalArgumentException("Pages are explicitly for GUIs, and thus should have a 1:1 ratio between pixel and texture size for maximum clarity. This means that the stage should be using a ScreenViewport.");
|
||||||
}
|
}
|
||||||
@ -50,7 +53,16 @@ public class Page extends Group implements Disposable {
|
|||||||
setPosition(baseXPos*getWidth(), baseYPos*getHeight());
|
setPosition(baseXPos*getWidth(), baseYPos*getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParent(Group parent) {
|
||||||
|
if (parent == null && getStage() == null) {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
super.setParent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
Gdx.app.debug(getClass().getSimpleName(), "Disposing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,8 @@ public class GraphicsPage extends Page {
|
|||||||
super.act(delta);
|
super.act(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void saveOptions() {
|
||||||
graphicsTable.save();
|
graphicsTable.saveOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBloomLevel() {
|
public int getBloomLevel() {
|
||||||
|
@ -111,6 +111,7 @@ public class MainPage extends Page implements Observer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
dhv.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,11 +99,6 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
|
|||||||
@Override
|
@Override
|
||||||
public void preAssetLoad() {
|
public void preAssetLoad() {
|
||||||
stage.clear();
|
stage.clear();
|
||||||
mainPage.dispose();
|
|
||||||
optionsPage.dispose();
|
|
||||||
creditsPage.dispose();
|
|
||||||
keybindPage.dispose();
|
|
||||||
musicSelectionPage.dispose();
|
|
||||||
bloomShader.dispose();
|
bloomShader.dispose();
|
||||||
bloomShader = null;
|
bloomShader = null;
|
||||||
background = null;
|
background = null;
|
||||||
@ -187,7 +182,8 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
|
|||||||
|
|
||||||
public void saveAll() {
|
public void saveAll() {
|
||||||
if (optionsPage != null) {
|
if (optionsPage != null) {
|
||||||
optionsPage.saveOptions(rhythmBullet.getPreferences());
|
optionsPage.saveOptions();
|
||||||
|
graphicsPage.saveOptions();
|
||||||
rhythmBullet.getPreferences().flush();
|
rhythmBullet.getPreferences().flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +199,7 @@ public class MainScreen extends ScreenAdapter implements ResizeReadyScreen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
Gdx.app.debug("Mainscreen", "disposing...");
|
||||||
stage.dispose();
|
stage.dispose();
|
||||||
musicMetadataController.dispose();
|
musicMetadataController.dispose();
|
||||||
screenBatch.dispose();
|
screenBatch.dispose();
|
||||||
|
@ -22,9 +22,11 @@ public class OptionsPage extends Page {
|
|||||||
private ProgressBar fxVolSlider;
|
private ProgressBar fxVolSlider;
|
||||||
private TextField directoryField;
|
private TextField directoryField;
|
||||||
private float musicSearchTimer;
|
private float musicSearchTimer;
|
||||||
|
private Preferences prefs;
|
||||||
|
|
||||||
public OptionsPage(MusicController musicController, Skin skin, Preferences preferences, ChangeListener backButtonListener, ChangeListener graphicsButtonListener, ChangeListener controlsButtonListener) {
|
public OptionsPage(MusicController musicController, Skin skin, Preferences preferences, ChangeListener backButtonListener, ChangeListener graphicsButtonListener, ChangeListener controlsButtonListener) {
|
||||||
super(-1, 0, "General", skin);
|
super(-1, 0, "General", skin);
|
||||||
|
this.prefs = preferences;
|
||||||
|
|
||||||
//Back button
|
//Back button
|
||||||
TextButton backButton = new TextButton("Back", skin);
|
TextButton backButton = new TextButton("Back", skin);
|
||||||
@ -140,13 +142,14 @@ public class OptionsPage extends Page {
|
|||||||
optionsTable.add(usageLabel).colspan(2);
|
optionsTable.add(usageLabel).colspan(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveOptions(Preferences prefs) {
|
public void saveOptions() {
|
||||||
prefs.putString("music dir", directoryField.getText());
|
prefs.putString("music dir", directoryField.getText());
|
||||||
Gdx.app.debug("Preferences", "Saved all basic options page values.");
|
Gdx.app.debug("Preferences", "Saved all basic options page values.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
|
saveOptions();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user