forked from Apple-2-Tools/jace
Adding better unhook and kill keystoke for cheats. Also hooked up watches and resolved some JavaFX redraw issues.
This commit is contained in:
parent
2d9ef8b30d
commit
76874ac514
@ -19,6 +19,7 @@
|
|||||||
package jace.cheat;
|
package jace.cheat;
|
||||||
|
|
||||||
import jace.apple2e.MOS65C02;
|
import jace.apple2e.MOS65C02;
|
||||||
|
import jace.config.InvokableAction;
|
||||||
import jace.core.Computer;
|
import jace.core.Computer;
|
||||||
import jace.core.Device;
|
import jace.core.Device;
|
||||||
import jace.core.RAMEvent;
|
import jace.core.RAMEvent;
|
||||||
@ -33,13 +34,23 @@ import java.util.Set;
|
|||||||
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
|
||||||
*/
|
*/
|
||||||
public abstract class Cheats extends Device {
|
public abstract class Cheats extends Device {
|
||||||
|
boolean cheatsActive = true;
|
||||||
Set<RAMListener> listeners = new HashSet<>();
|
Set<RAMListener> listeners = new HashSet<>();
|
||||||
|
|
||||||
public Cheats(Computer computer) {
|
public Cheats(Computer computer) {
|
||||||
super(computer);
|
super(computer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@InvokableAction(name = "Toggle Cheats", alternatives = "cheat", defaultKeyMapping = "ctrl+shift+m")
|
||||||
|
public void toggleCheats() {
|
||||||
|
cheatsActive = !cheatsActive;
|
||||||
|
if (cheatsActive) {
|
||||||
|
attach();
|
||||||
|
} else {
|
||||||
|
detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public RAMListener bypassCode(int address, int addressEnd) {
|
public RAMListener bypassCode(int address, int addressEnd) {
|
||||||
int noOperation = MOS65C02.COMMAND.NOP.ordinal();
|
int noOperation = MOS65C02.COMMAND.NOP.ordinal();
|
||||||
return addCheat(RAMEvent.TYPE.READ, (e) -> e.setNewValue(noOperation), address, addressEnd);
|
return addCheat(RAMEvent.TYPE.READ, (e) -> e.setNewValue(noOperation), address, addressEnd);
|
||||||
@ -103,8 +114,10 @@ public abstract class Cheats extends Device {
|
|||||||
@Override
|
@Override
|
||||||
public void reconfigure() {
|
public void reconfigure() {
|
||||||
unregisterListeners();
|
unregisterListeners();
|
||||||
|
if (cheatsActive) {
|
||||||
registerListeners();
|
registerListeners();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getShortName() {
|
public String getShortName() {
|
||||||
|
@ -105,8 +105,8 @@ public class MetaCheat extends Cheats {
|
|||||||
|
|
||||||
MetacheatUI ui;
|
MetacheatUI ui;
|
||||||
|
|
||||||
public int fadeRate = 2;
|
public int fadeRate = 1;
|
||||||
public int lightRate = 20;
|
public int lightRate = 30;
|
||||||
public int historyLength = 10;
|
public int historyLength = 10;
|
||||||
|
|
||||||
private int startAddress = 0;
|
private int startAddress = 0;
|
||||||
|
@ -107,7 +107,6 @@ public class MontezumasRevengeCheats extends Cheats {
|
|||||||
forceValue(32, FLOOR_TIMER);
|
forceValue(32, FLOOR_TIMER);
|
||||||
forceValue(32, HAZARD_TIMER);
|
forceValue(32, HAZARD_TIMER);
|
||||||
forceValue(1, HAZARD_FLAG);
|
forceValue(1, HAZARD_FLAG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scoreHack) {
|
if (scoreHack) {
|
||||||
@ -123,11 +122,15 @@ public class MontezumasRevengeCheats extends Cheats {
|
|||||||
}
|
}
|
||||||
if (mouseHack) {
|
if (mouseHack) {
|
||||||
EmulatorUILogic.addMouseListener(listener);
|
EmulatorUILogic.addMouseListener(listener);
|
||||||
} else {
|
|
||||||
EmulatorUILogic.removeMouseListener(listener);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void unregisterListeners() {
|
||||||
|
super.unregisterListeners();
|
||||||
|
EmulatorUILogic.removeMouseListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
private void repulsiveBehavior(RAMEvent e) {
|
private void repulsiveBehavior(RAMEvent e) {
|
||||||
int playerX = computer.getMemory().readRaw(PLAYER_X);
|
int playerX = computer.getMemory().readRaw(PLAYER_X);
|
||||||
int playerY = computer.getMemory().readRaw(PLAYER_Y);
|
int playerY = computer.getMemory().readRaw(PLAYER_Y);
|
||||||
|
@ -18,6 +18,7 @@ import java.util.concurrent.ScheduledFuture;
|
|||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
@ -262,6 +263,9 @@ public class MetacheatUI {
|
|||||||
});
|
});
|
||||||
memoryViewPane.boundsInParentProperty().addListener((prop, oldVal, newVal) -> redrawMemoryView());
|
memoryViewPane.boundsInParentProperty().addListener((prop, oldVal, newVal) -> redrawMemoryView());
|
||||||
memoryViewCanvas.widthProperty().bind(memoryViewPane.widthProperty());
|
memoryViewCanvas.widthProperty().bind(memoryViewPane.widthProperty());
|
||||||
|
|
||||||
|
watchesPane.setHgap(5);
|
||||||
|
watchesPane.setVgap(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaCheat cheatEngine = null;
|
MetaCheat cheatEngine = null;
|
||||||
@ -312,6 +316,23 @@ public class MetacheatUI {
|
|||||||
int row = (int) (y / MEMORY_BOX_TOTAL_SIZE);
|
int row = (int) (y / MEMORY_BOX_TOTAL_SIZE);
|
||||||
int addr = cheatEngine.getStartAddress() + row * memoryViewColumns + col;
|
int addr = cheatEngine.getStartAddress() + row * memoryViewColumns + col;
|
||||||
Watch watch = new Watch(addr);
|
Watch watch = new Watch(addr);
|
||||||
|
|
||||||
|
Label addWatch = new Label("Watch >>");
|
||||||
|
addWatch.setOnMouseClicked((mouseEvent) -> {
|
||||||
|
Watch newWatch = addWatch(addr);
|
||||||
|
if (watch.holdingProperty().get()) {
|
||||||
|
newWatch.holdingProperty().set(true);
|
||||||
|
}
|
||||||
|
memoryWatchTooltip.hide();
|
||||||
|
});
|
||||||
|
watch.getChildren().add(addWatch);
|
||||||
|
|
||||||
|
Label addCheat = new Label("Cheat >>");
|
||||||
|
addCheat.setOnMouseClicked((mouseEvent) -> {
|
||||||
|
addCheat(addr, watch.getValue());
|
||||||
|
});
|
||||||
|
watch.getChildren().add(addCheat);
|
||||||
|
|
||||||
memoryWatchTooltip.setStyle("-fx-background-color:NAVY");
|
memoryWatchTooltip.setStyle("-fx-background-color:NAVY");
|
||||||
memoryWatchTooltip.onHidingProperty().addListener((prop, oldVal, newVal) -> {
|
memoryWatchTooltip.onHidingProperty().addListener((prop, oldVal, newVal) -> {
|
||||||
watch.disconnect();
|
watch.disconnect();
|
||||||
@ -417,8 +438,36 @@ public class MetacheatUI {
|
|||||||
searchStatusLabel.setText(size + (size == 1 ? " result" : " results") + " found.");
|
searchStatusLabel.setText(size + (size == 1 ? " result" : " results") + " found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int GRAPH_WIDTH = 50;
|
private Watch addWatch(int addr) {
|
||||||
private static double GRAPH_HEIGHT = 50;
|
Watch watch = new Watch(addr);
|
||||||
|
watch.setPadding(new Insets(5));
|
||||||
|
watch.setOpaqueInsets(new Insets(10));
|
||||||
|
|
||||||
|
Label addCheat = new Label("Cheat >>");
|
||||||
|
addCheat.setOnMouseClicked((mouseEvent) -> {
|
||||||
|
addCheat(addr, watch.getValue());
|
||||||
|
});
|
||||||
|
addCheat.setTextFill(Color.WHITE);
|
||||||
|
watch.getChildren().add(addCheat);
|
||||||
|
|
||||||
|
Label close = new Label("Close X");
|
||||||
|
close.setOnMouseClicked((mouseEvent) -> {
|
||||||
|
watch.disconnect();
|
||||||
|
watchesPane.getChildren().remove(watch);
|
||||||
|
});
|
||||||
|
close.setTextFill(Color.WHITE);
|
||||||
|
watch.getChildren().add(close);
|
||||||
|
|
||||||
|
watchesPane.getChildren().add(watch);
|
||||||
|
return watch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCheat(int addr, int val) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int GRAPH_WIDTH = 50;
|
||||||
|
private static final double GRAPH_HEIGHT = 50;
|
||||||
|
|
||||||
private class Watch extends VBox {
|
private class Watch extends VBox {
|
||||||
|
|
||||||
@ -426,6 +475,8 @@ public class MetacheatUI {
|
|||||||
ScheduledFuture redraw;
|
ScheduledFuture redraw;
|
||||||
Canvas graph;
|
Canvas graph;
|
||||||
List<Integer> samples = Collections.synchronizedList(new ArrayList<>());
|
List<Integer> samples = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
int value = 0;
|
||||||
|
BooleanProperty holding = null;
|
||||||
|
|
||||||
public Watch(int address) {
|
public Watch(int address) {
|
||||||
super();
|
super();
|
||||||
@ -443,17 +494,28 @@ public class MetacheatUI {
|
|||||||
getChildren().add(graph);
|
getChildren().add(graph);
|
||||||
|
|
||||||
CheckBox hold = new CheckBox("Hold");
|
CheckBox hold = new CheckBox("Hold");
|
||||||
hold.selectedProperty().addListener((prop, oldVal, newVal) -> this.hold(newVal));
|
holding = hold.selectedProperty();
|
||||||
|
holding.addListener((prop, oldVal, newVal) -> this.updateHold());
|
||||||
|
|
||||||
getChildren().add(hold);
|
getChildren().add(hold);
|
||||||
|
hold.setTextFill(Color.WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redraw() {
|
public void redraw() {
|
||||||
int val = cheatEngine.getMemoryCell(address).value.get() & 0x0ff;
|
int val = cheatEngine.getMemoryCell(address).value.get() & 0x0ff;
|
||||||
|
if (!holding.get()) {
|
||||||
|
value = val;
|
||||||
|
}
|
||||||
if (samples.size() >= GRAPH_WIDTH) {
|
if (samples.size() >= GRAPH_WIDTH) {
|
||||||
samples.remove(0);
|
samples.remove(0);
|
||||||
}
|
}
|
||||||
samples.add(val);
|
samples.add(val);
|
||||||
|
|
||||||
|
Platform.runLater(() -> {
|
||||||
GraphicsContext g = graph.getGraphicsContext2D();
|
GraphicsContext g = graph.getGraphicsContext2D();
|
||||||
g.setFill(Color.BLACK);
|
g.setFill(Color.BLACK);
|
||||||
g.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
|
g.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT);
|
||||||
@ -473,24 +535,27 @@ public class MetacheatUI {
|
|||||||
g.beginPath();
|
g.beginPath();
|
||||||
g.setStroke(Color.WHITE);
|
g.setStroke(Color.WHITE);
|
||||||
g.strokeText(String.valueOf(val), GRAPH_WIDTH - 25, GRAPH_HEIGHT - 5);
|
g.strokeText(String.valueOf(val), GRAPH_WIDTH - 25, GRAPH_HEIGHT - 5);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
RAMListener holdListener;
|
RAMListener holdListener;
|
||||||
|
|
||||||
private void hold(boolean state) {
|
public BooleanProperty holdingProperty() {
|
||||||
if (!state) {
|
return holding;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateHold() {
|
||||||
|
if (!holding.get()) {
|
||||||
cheatEngine.removeListener(holdListener);
|
cheatEngine.removeListener(holdListener);
|
||||||
holdListener = null;
|
holdListener = null;
|
||||||
} else {
|
} else {
|
||||||
int val = cheatEngine.getMemoryCell(address).value.get() & 0x0ff;
|
value = Emulator.computer.memory.readRaw(address) & 0x0ff;
|
||||||
holdListener = cheatEngine.forceValue(val, address);
|
holdListener = cheatEngine.forceValue(value, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
if (holdListener != null) {
|
holding.set(false);
|
||||||
cheatEngine.removeListener(holdListener);
|
|
||||||
}
|
|
||||||
redraw.cancel(false);
|
redraw.cancel(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user