From 76874ac514dbcaf5d2fd06b3ae3f53804af98960 Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Sat, 22 Aug 2015 11:57:22 -0500 Subject: [PATCH] Adding better unhook and kill keystoke for cheats. Also hooked up watches and resolved some JavaFX redraw issues. --- src/main/java/jace/cheat/Cheats.java | 17 ++- src/main/java/jace/cheat/MetaCheat.java | 4 +- .../jace/cheat/MontezumasRevengeCheats.java | 11 +- src/main/java/jace/ui/MetacheatUI.java | 119 ++++++++++++++---- 4 files changed, 116 insertions(+), 35 deletions(-) diff --git a/src/main/java/jace/cheat/Cheats.java b/src/main/java/jace/cheat/Cheats.java index b62ea5b..fb8f34c 100644 --- a/src/main/java/jace/cheat/Cheats.java +++ b/src/main/java/jace/cheat/Cheats.java @@ -19,6 +19,7 @@ package jace.cheat; import jace.apple2e.MOS65C02; +import jace.config.InvokableAction; import jace.core.Computer; import jace.core.Device; import jace.core.RAMEvent; @@ -33,12 +34,22 @@ import java.util.Set; * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public abstract class Cheats extends Device { - + boolean cheatsActive = true; Set listeners = new HashSet<>(); public Cheats(Computer 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) { int noOperation = MOS65C02.COMMAND.NOP.ordinal(); @@ -103,7 +114,9 @@ public abstract class Cheats extends Device { @Override public void reconfigure() { unregisterListeners(); - registerListeners(); + if (cheatsActive) { + registerListeners(); + } } @Override diff --git a/src/main/java/jace/cheat/MetaCheat.java b/src/main/java/jace/cheat/MetaCheat.java index 2e8007c..6ff840a 100644 --- a/src/main/java/jace/cheat/MetaCheat.java +++ b/src/main/java/jace/cheat/MetaCheat.java @@ -105,8 +105,8 @@ public class MetaCheat extends Cheats { MetacheatUI ui; - public int fadeRate = 2; - public int lightRate = 20; + public int fadeRate = 1; + public int lightRate = 30; public int historyLength = 10; private int startAddress = 0; diff --git a/src/main/java/jace/cheat/MontezumasRevengeCheats.java b/src/main/java/jace/cheat/MontezumasRevengeCheats.java index dc6b7d5..abd04b7 100644 --- a/src/main/java/jace/cheat/MontezumasRevengeCheats.java +++ b/src/main/java/jace/cheat/MontezumasRevengeCheats.java @@ -107,7 +107,6 @@ public class MontezumasRevengeCheats extends Cheats { forceValue(32, FLOOR_TIMER); forceValue(32, HAZARD_TIMER); forceValue(1, HAZARD_FLAG); - } if (scoreHack) { @@ -123,11 +122,15 @@ public class MontezumasRevengeCheats extends Cheats { } if (mouseHack) { EmulatorUILogic.addMouseListener(listener); - } else { - EmulatorUILogic.removeMouseListener(listener); } } + @Override + protected void unregisterListeners() { + super.unregisterListeners(); + EmulatorUILogic.removeMouseListener(listener); + } + private void repulsiveBehavior(RAMEvent e) { int playerX = computer.getMemory().readRaw(PLAYER_X); int playerY = computer.getMemory().readRaw(PLAYER_Y); @@ -198,4 +201,4 @@ public class MontezumasRevengeCheats extends Cheats { computer.memory.write(PLAYER_X, newX, false, false); computer.memory.write(PLAYER_Y, newY, false, false); } -} +} \ No newline at end of file diff --git a/src/main/java/jace/ui/MetacheatUI.java b/src/main/java/jace/ui/MetacheatUI.java index 2781919..5f587af 100644 --- a/src/main/java/jace/ui/MetacheatUI.java +++ b/src/main/java/jace/ui/MetacheatUI.java @@ -18,6 +18,7 @@ import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javafx.application.Platform; +import javafx.beans.property.BooleanProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; @@ -262,6 +263,9 @@ public class MetacheatUI { }); memoryViewPane.boundsInParentProperty().addListener((prop, oldVal, newVal) -> redrawMemoryView()); memoryViewCanvas.widthProperty().bind(memoryViewPane.widthProperty()); + + watchesPane.setHgap(5); + watchesPane.setVgap(5); } MetaCheat cheatEngine = null; @@ -312,6 +316,23 @@ public class MetacheatUI { int row = (int) (y / MEMORY_BOX_TOTAL_SIZE); int addr = cheatEngine.getStartAddress() + row * memoryViewColumns + col; 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.onHidingProperty().addListener((prop, oldVal, newVal) -> { watch.disconnect(); @@ -417,8 +438,36 @@ public class MetacheatUI { searchStatusLabel.setText(size + (size == 1 ? " result" : " results") + " found."); } - private static int GRAPH_WIDTH = 50; - private static double GRAPH_HEIGHT = 50; + private Watch addWatch(int addr) { + 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 { @@ -426,6 +475,8 @@ public class MetacheatUI { ScheduledFuture redraw; Canvas graph; List samples = Collections.synchronizedList(new ArrayList<>()); + int value = 0; + BooleanProperty holding = null; public Watch(int address) { super(); @@ -443,54 +494,68 @@ public class MetacheatUI { getChildren().add(graph); 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); + hold.setTextFill(Color.WHITE); + } + + public int getValue() { + return value; } public void redraw() { int val = cheatEngine.getMemoryCell(address).value.get() & 0x0ff; + if (!holding.get()) { + value = val; + } if (samples.size() >= GRAPH_WIDTH) { samples.remove(0); } samples.add(val); - GraphicsContext g = graph.getGraphicsContext2D(); - g.setFill(Color.BLACK); - g.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT); + Platform.runLater(() -> { + GraphicsContext g = graph.getGraphicsContext2D(); + g.setFill(Color.BLACK); + g.fillRect(0, 0, GRAPH_WIDTH, GRAPH_HEIGHT); - if (samples.size() > 1) { - g.setLineWidth(1); - g.setStroke(Color.LAWNGREEN); - int y = (int) (GRAPH_HEIGHT - ((samples.get(0) / 255.0) * GRAPH_HEIGHT)); - g.beginPath(); - g.moveTo(0, y); - for (int i = 1; i < samples.size(); i++) { - y = (int) (GRAPH_HEIGHT - ((samples.get(i) / 255.0) * GRAPH_HEIGHT)); - g.lineTo(i, y); + if (samples.size() > 1) { + g.setLineWidth(1); + g.setStroke(Color.LAWNGREEN); + int y = (int) (GRAPH_HEIGHT - ((samples.get(0) / 255.0) * GRAPH_HEIGHT)); + g.beginPath(); + g.moveTo(0, y); + for (int i = 1; i < samples.size(); i++) { + y = (int) (GRAPH_HEIGHT - ((samples.get(i) / 255.0) * GRAPH_HEIGHT)); + g.lineTo(i, y); + } + g.stroke(); } - g.stroke(); - } - g.beginPath(); - g.setStroke(Color.WHITE); - g.strokeText(String.valueOf(val), GRAPH_WIDTH - 25, GRAPH_HEIGHT - 5); + g.beginPath(); + g.setStroke(Color.WHITE); + g.strokeText(String.valueOf(val), GRAPH_WIDTH - 25, GRAPH_HEIGHT - 5); + }); } RAMListener holdListener; - private void hold(boolean state) { - if (!state) { + public BooleanProperty holdingProperty() { + return holding; + } + + private void updateHold() { + if (!holding.get()) { cheatEngine.removeListener(holdListener); holdListener = null; } else { - int val = cheatEngine.getMemoryCell(address).value.get() & 0x0ff; - holdListener = cheatEngine.forceValue(val, address); + value = Emulator.computer.memory.readRaw(address) & 0x0ff; + holdListener = cheatEngine.forceValue(value, address); } } public void disconnect() { - if (holdListener != null) { - cheatEngine.removeListener(holdListener); - } + holding.set(false); redraw.cancel(false); } }