Merge branch 'master' of github.com:badvision/lawless-legends

This commit is contained in:
Martin Haye 2021-08-05 09:47:33 -07:00
commit cce4a4b60d
4 changed files with 79 additions and 54 deletions

View File

@ -35,6 +35,7 @@
<goal>unpack-dependencies</goal> <goal>unpack-dependencies</goal>
</goals> </goals>
<configuration> <configuration>
<excludes>**/*.SF,**/*.DSA,**/*.RSA</excludes>
<excludeScope>system</excludeScope> <excludeScope>system</excludeScope>
<excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds> <excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
<outputDirectory>${project.build.directory}/classes</outputDirectory> <outputDirectory>${project.build.directory}/classes</outputDirectory>

View File

@ -60,7 +60,7 @@ public abstract class Cheats extends Device {
return addCheat(RAMEvent.TYPE.ANY, (e) -> e.setNewValue(value), address); return addCheat(RAMEvent.TYPE.ANY, (e) -> e.setNewValue(value), address);
} }
public RAMListener forceValue(int value, boolean auxFlag, int... address) { public RAMListener forceValue(int value, Boolean auxFlag, int... address) {
return addCheat(RAMEvent.TYPE.ANY, auxFlag, (e) -> e.setNewValue(value), address); return addCheat(RAMEvent.TYPE.ANY, auxFlag, (e) -> e.setNewValue(value), address);
} }
@ -75,7 +75,7 @@ public abstract class Cheats extends Device {
return listener; return listener;
} }
public RAMListener addCheat(RAMEvent.TYPE type, boolean auxFlag, RAMEvent.RAMEventHandler handler, int... address) { public RAMListener addCheat(RAMEvent.TYPE type, Boolean auxFlag, RAMEvent.RAMEventHandler handler, int... address) {
RAMListener listener; RAMListener listener;
if (address.length == 1) { if (address.length == 1) {
listener = computer.getMemory().observe(type, address[0], auxFlag, handler); listener = computer.getMemory().observe(type, address[0], auxFlag, handler);

View File

@ -214,7 +214,7 @@ public abstract class RAM implements Reconfigurable {
}); });
} }
public RAMListener observe(RAMEvent.TYPE type, int address, boolean auxFlag, RAMEvent.RAMEventHandler handler) { public RAMListener observe(RAMEvent.TYPE type, int address, Boolean auxFlag, RAMEvent.RAMEventHandler handler) {
return addListener(new RAMListener(type, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) { return addListener(new RAMListener(type, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override @Override
protected void doConfig() { protected void doConfig() {
@ -245,7 +245,7 @@ public abstract class RAM implements Reconfigurable {
}); });
} }
public RAMListener observe(RAMEvent.TYPE type, int addressStart, int addressEnd, boolean auxFlag, RAMEvent.RAMEventHandler handler) { public RAMListener observe(RAMEvent.TYPE type, int addressStart, int addressEnd, Boolean auxFlag, RAMEvent.RAMEventHandler handler) {
return addListener(new RAMListener(type, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) { return addListener(new RAMListener(type, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
@Override @Override
protected void doConfig() { protected void doConfig() {
@ -262,12 +262,15 @@ public abstract class RAM implements Reconfigurable {
}); });
} }
private boolean isAuxFlagCorrect(RAMEvent e, boolean auxFlag) { private boolean isAuxFlagCorrect(RAMEvent e, Boolean auxFlag) {
if (e.getAddress() < 0x0100) { if (e.getAddress() < 0x0100) {
if (SoftSwitches.AUXZP.getState() != auxFlag) { if (SoftSwitches.AUXZP.getState() != auxFlag) {
return false; return false;
} }
} else if (SoftSwitches.RAMRD.getState() != auxFlag) { } else if (e.getAddress() >= 0x0C000 && e.getAddress() <= 0x0CFFF) {
// I/O page doesn't care about the aux flag
return true;
} else if (auxFlag != null && SoftSwitches.RAMRD.getState() != auxFlag) {
return false; return false;
} }
return true; return true;

View File

@ -43,16 +43,17 @@ public class LawlessHacks extends Cheats {
@Override @Override
public void registerListeners() { public void registerListeners() {
// Observe graphics changes // Observe graphics changes
addCheat(RAMEvent.TYPE.ANY, false, (e) -> { addCheat(RAMEvent.TYPE.ANY, (e) -> {
int addr = e.getAddress(); int addr = e.getAddress();
if (addr >= MODE_SOFTSWITCH_MIN && e.getAddress() <= MODE_SOFTSWITCH_MAX) { if (addr >= MODE_SOFTSWITCH_MIN && e.getAddress() <= MODE_SOFTSWITCH_MAX) {
System.out.println("Trapped " + e.getType().toString() + " to $" + Integer.toHexString(e.getAddress())); // System.out.println("Trapped " + e.getType().toString() + " to $" + Integer.toHexString(e.getAddress()));
setEngineByOrdinal(e.getAddress() - MODE_SOFTSWITCH_MIN); setEngineByOrdinal(e.getAddress() - MODE_SOFTSWITCH_MIN);
} }
}, MODE_SOFTSWITCH_MIN, MODE_SOFTSWITCH_MAX); }, MODE_SOFTSWITCH_MIN, MODE_SOFTSWITCH_MAX);
addCheat(RAMEvent.TYPE.WRITE, false, (e) -> { addCheat(RAMEvent.TYPE.WRITE, (e) -> {
// System.out.println(Integer.toHexString(e.getAddress()) + " => " + Integer.toHexString(e.getNewValue() & 0x0ff));
playSound(e.getNewValue()); playSound(e.getNewValue());
}, SFX_TRIGGER, SFX_TRIGGER); }, SFX_TRIGGER);
} }
@Override @Override
@ -73,11 +74,17 @@ public class LawlessHacks extends Cheats {
} }
} }
int currentSong; public static final String SCORE_NONE = "none";
boolean repeatSong = false; public static final String SCORE_COMMON = "common";
Thread playbackEffect; public static final String SCORE_ORCHESTRAL = "orchestral";
MediaPlayer currentSongPlayer; public static final String SCORE_CHIPTUNE = "chiptune";
MediaPlayer currentSfxPlayer;
private static int currentSong;
private static boolean repeatSong = false;
private static Thread playbackEffect;
private static MediaPlayer currentSongPlayer;
private static MediaPlayer currentSfxPlayer;
private static String currentScore = SCORE_COMMON;
private void playSound(int soundNumber) { private void playSound(int soundNumber) {
boolean isMusic = soundNumber >= 0; boolean isMusic = soundNumber >= 0;
@ -85,17 +92,17 @@ public class LawlessHacks extends Cheats {
repeatSong = (soundNumber & 0x040) > 0; repeatSong = (soundNumber & 0x040) > 0;
if (track == 0) { if (track == 0) {
if (isMusic) { if (isMusic) {
// System.out.println("Stop music"); System.out.println("Stop music");
stopMusic(); stopMusic();
} else { } else {
// System.out.println("Stop sfx"); System.out.println("Stop sfx");
stopSfx(); stopSfx();
} }
} else if (isMusic) { } else if (isMusic) {
// System.out.println("Play music "+track); System.out.println("Play music "+track);
playMusic(track); playMusic(track);
} else { } else {
// System.out.println("Play sfx "+track); System.out.println("Play sfx "+track);
playSfx(track); playSfx(track);
} }
} }
@ -133,6 +140,11 @@ public class LawlessHacks extends Cheats {
} else { } else {
new Thread(() -> startNewSong(track)).start(); new Thread(() -> startNewSong(track)).start();
} }
currentSong = track;
}
private boolean isPlayingMusic() {
return currentSongPlayer != null && currentSongPlayer.getStatus() == MediaPlayer.Status.PLAYING;
} }
private void stopSongEffect() { private void stopSongEffect() {
@ -145,11 +157,11 @@ public class LawlessHacks extends Cheats {
private void fadeOutSong(Runnable nextAction) { private void fadeOutSong(Runnable nextAction) {
stopSongEffect(); stopSongEffect();
if (currentSongPlayer != null) { MediaPlayer player = currentSongPlayer;
if (player != null) {
playbackEffect = new Thread(() -> { playbackEffect = new Thread(() -> {
DoubleProperty volume = currentSongPlayer.volumeProperty(); DoubleProperty volume = player.volumeProperty();
while (playbackEffect == Thread.currentThread() && currentSongPlayer != null && volume.get() > 0.0) { while (playbackEffect == Thread.currentThread() && volume.get() > 0.0) {
// System.out.println("Fading down: " + volume.get());
volume.set(volume.get() - FADE_AMT); volume.set(volume.get() - FADE_AMT);
try { try {
Thread.sleep(FADE_SPEED); Thread.sleep(FADE_SPEED);
@ -158,8 +170,10 @@ public class LawlessHacks extends Cheats {
return; return;
} }
} }
currentSongPlayer.stop(); player.stop();
currentSongPlayer = null; if (currentSongPlayer == player) {
currentSongPlayer = null;
}
if (nextAction != null) { if (nextAction != null) {
nextAction.run(); nextAction.run();
} }
@ -170,32 +184,17 @@ public class LawlessHacks extends Cheats {
} }
} }
double FADE_AMT = 0.05; // 5% per interval, or 20 stops between 0% and 100% private void fadeInSong(MediaPlayer player) {
int FADE_SPEED = 100; // 100ms per 5%, or 2 second duration
private void startNewSong(int track) {
if (track != currentSong || currentSongPlayer == null || isMusicEnabled()) {
// If the same song is already playing don't restart it
Media song = getAudioTrack(track);
if (song == null) {
System.out.println("Unable to start song " + track + "; File not found");
return;
}
currentSongPlayer = new MediaPlayer(song);
currentSongPlayer.setCycleCount(repeatSong ? MediaPlayer.INDEFINITE : 1);
currentSongPlayer.setVolume(0.0);
currentSongPlayer.play();
currentSong = track;
}
// But if the same song was already playing but possibly fading out
// then this will fade it back in neatly.
stopSongEffect(); stopSongEffect();
// System.out.println("Starting "+track+" NOW"); currentSongPlayer = player;
DoubleProperty volume = player.volumeProperty();
if (volume.get() >= 1.0) {
return;
}
playbackEffect = new Thread(() -> { playbackEffect = new Thread(() -> {
DoubleProperty volume = currentSongPlayer.volumeProperty(); while (playbackEffect == Thread.currentThread() && volume.get() < 1.0) {
while (playbackEffect == Thread.currentThread() && currentSongPlayer != null && volume.get() < 1.0) {
volume.set(volume.get() + FADE_AMT); volume.set(volume.get() + FADE_AMT);
// System.out.println("Fading up: " + volume.get());
try { try {
Thread.sleep(FADE_SPEED); Thread.sleep(FADE_SPEED);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -207,6 +206,33 @@ public class LawlessHacks extends Cheats {
playbackEffect.start(); playbackEffect.start();
} }
double FADE_AMT = 0.05; // 5% per interval, or 20 stops between 0% and 100%
int FADE_SPEED = 100; // 100ms per 5%, or 2 second duration
private void startNewSong(int track) {
if (!isMusicEnabled()) {
return;
}
MediaPlayer player;
if (track != currentSong || !isPlayingMusic()) {
// If the same song is already playing don't restart it
Media song = getAudioTrack(track);
if (song == null) {
System.out.println("Unable to start song " + track + "; File not found");
return;
}
player = new MediaPlayer(song);
player.setCycleCount(repeatSong ? MediaPlayer.INDEFINITE : 1);
player.setVolume(0.0);
player.play();
} else {
// But if the same song was already playing but possibly fading out
// then this will fade it back in neatly.
player = currentSongPlayer;
}
fadeInSong(player);
}
private void stopMusic() { private void stopMusic() {
stopSongEffect(); stopSongEffect();
fadeOutSong(()->{ fadeOutSong(()->{
@ -236,12 +262,6 @@ public class LawlessHacks extends Cheats {
} }
} }
public static final String SCORE_NONE = "none";
public static final String SCORE_COMMON = "common";
public static final String SCORE_ORCHESTRAL = "orchestral";
public static final String SCORE_CHIPTUNE = "chiptune";
private String currentScore = SCORE_COMMON;
public void changeMusicScore(String score) { public void changeMusicScore(String score) {
if (currentScore.equalsIgnoreCase(score)) { if (currentScore.equalsIgnoreCase(score)) {
return; return;
@ -252,6 +272,7 @@ public class LawlessHacks extends Cheats {
stopMusic(); stopMusic();
currentSong = -1; currentSong = -1;
} else if ((currentSongPlayer != null || wasStoppedPreviously) && currentSong > 0) { } else if ((currentSongPlayer != null || wasStoppedPreviously) && currentSong > 0) {
stopSongEffect();
int currentSongTemp = currentSong; int currentSongTemp = currentSong;
currentSong = Integer.MAX_VALUE; currentSong = Integer.MAX_VALUE;
startNewSong(currentSongTemp); startNewSong(currentSongTemp);