diff --git a/src/main/java/jace/cheat/Cheats.java b/src/main/java/jace/cheat/Cheats.java index f796ab1..a39fa5c 100644 --- a/src/main/java/jace/cheat/Cheats.java +++ b/src/main/java/jace/cheat/Cheats.java @@ -19,7 +19,6 @@ package jace.cheat; import jace.apple2e.MOS65C02; -import jace.apple2e.SoftSwitches; import jace.core.Computer; import jace.core.Device; import jace.core.RAMEvent; @@ -42,40 +41,32 @@ public abstract class Cheats extends Device { } public void bypassCode(int address, int addressEnd) { - addCheat(RAMEvent.TYPE.READ, address, addressEnd, (e) -> { - e.setNewValue(MOS65C02.COMMAND.NOP.ordinal()); - }); + int noOperation = MOS65C02.COMMAND.NOP.ordinal(); + addCheat(RAMEvent.TYPE.READ, (e) -> {e.setNewValue(noOperation);}, address, addressEnd); } - public void forceValue(int address, int value) { - addCheat(RAMEvent.TYPE.READ, address, (e) -> { - e.setNewValue(value); - }); + public void forceValue(int value, int... address) { + addCheat(RAMEvent.TYPE.READ, (e) -> {e.setNewValue(value);}, address); } - public void forceValue(int address, boolean auxFlag, int value) { - addCheat(RAMEvent.TYPE.READ, address, (e) -> { - if (address < 0x0100) { - if (SoftSwitches.AUXZP.getState() != auxFlag) { - return; - } - } else { - if (SoftSwitches.RAMRD.getState() != auxFlag) { - return; - } - } - e.setNewValue(value); - }); + public void forceValue(int value, boolean auxFlag, int... address) { + addCheat(RAMEvent.TYPE.READ, auxFlag, (e) -> {e.setNewValue(value);}, address); } - public void addCheat(RAMEvent.TYPE type, int address, RAMEvent.RAMEventHandler handler) { - RAMListener l = computer.getMemory().observe(type, address, handler); - listeners.add(l); + public void addCheat(RAMEvent.TYPE type, RAMEvent.RAMEventHandler handler, int... address) { + if (address.length == 1) { + listeners.add(computer.getMemory().observe(type, address[0], handler)); + } else { + listeners.add(computer.getMemory().observe(type, address[0], address[1], handler)); + } } - - public void addCheat(RAMEvent.TYPE type, int addressStart, int addressEnd, RAMEvent.RAMEventHandler handler) { - RAMListener l = computer.getMemory().observe(type, addressStart, addressEnd, handler); - listeners.add(l); + + public void addCheat(RAMEvent.TYPE type, boolean auxFlag, RAMEvent.RAMEventHandler handler, int... address) { + if (address.length == 1) { + listeners.add(computer.getMemory().observe(type, address[0], auxFlag, handler)); + } else { + listeners.add(computer.getMemory().observe(type, address[0], address[1], auxFlag, handler)); + } } @Override diff --git a/src/main/java/jace/cheat/MontezumasRevengeCheats.java b/src/main/java/jace/cheat/MontezumasRevengeCheats.java index 9a4ad38..e92e648 100644 --- a/src/main/java/jace/cheat/MontezumasRevengeCheats.java +++ b/src/main/java/jace/cheat/MontezumasRevengeCheats.java @@ -1,7 +1,6 @@ package jace.cheat; import jace.EmulatorUILogic; -import jace.apple2e.MOS65C02; import jace.config.ConfigurableField; import jace.core.Computer; import jace.core.RAMEvent; @@ -65,17 +64,17 @@ public class MontezumasRevengeCheats extends Cheats { @Override void registerListeners() { if (repulsiveHack) { - addCheat(RAMEvent.TYPE.WRITE, 0x1508, 0x1518, this::repulsiveBehavior); + addCheat(RAMEvent.TYPE.WRITE, this::repulsiveBehavior, 0x1508, 0x1518); } if (featherFall) { - addCheat(RAMEvent.TYPE.WRITE, PLAYER_Y, this::featherFallBehavior); + addCheat(RAMEvent.TYPE.WRITE, this::featherFallBehavior, PLAYER_Y); // Bypass the part that realizes you should die when you hit the floor bypassCode(0x6bb3, 0x6bb4); } if (moonJump) { - addCheat(RAMEvent.TYPE.WRITE, Y_VELOCITY, this::moonJumpBehavior); + addCheat(RAMEvent.TYPE.WRITE, this::moonJumpBehavior, Y_VELOCITY); } if (infiniteLives) { @@ -84,9 +83,9 @@ public class MontezumasRevengeCheats extends Cheats { if (scoreHack) { // Score: 900913 - forceValue(SCORE, 0x90); - forceValue(SCORE + 1, 0x09); - forceValue(SCORE + 2, 0x13); + forceValue(0x90, SCORE); + forceValue(0x09, SCORE + 1); + forceValue(0x13, SCORE + 2); } if (snakeCharmer) { diff --git a/src/main/java/jace/cheat/PrinceOfPersiaCheats.java b/src/main/java/jace/cheat/PrinceOfPersiaCheats.java index a60fcf5..39ab5f4 100644 --- a/src/main/java/jace/cheat/PrinceOfPersiaCheats.java +++ b/src/main/java/jace/cheat/PrinceOfPersiaCheats.java @@ -173,19 +173,19 @@ public class PrinceOfPersiaCheats extends Cheats { @Override public void registerListeners() { if (velocityHack) { - addCheat(RAMEvent.TYPE.READ_DATA, CharYVel, this::velocityHackBehavior); + addCheat(RAMEvent.TYPE.READ_DATA, true, this::velocityHackBehavior, CharYVel); } if (invincibilityHack) { - forceValue(KidStrength, true, 3); + forceValue(3, true, KidStrength); } if (sleepHack) { - forceValue(EnemyAlert, true, 0); + forceValue(0, true, EnemyAlert); } if (swordHack) { - forceValue(hasSword, true, 1); + forceValue(1, true, hasSword); } if (timeHack) { - forceValue(MinLeft, true, 0x069); + forceValue(0x69, true, MinLeft); } if (mouseHack) { EmulatorUILogic.addMouseListener(listener); @@ -201,15 +201,12 @@ public class PrinceOfPersiaCheats extends Cheats { } public static int BlueType = 0x0b700; - private void velocityHackBehavior(RAMEvent e) { - if (!SoftSwitches.AUXZP.getState()) { - return; - } - int newVel = e.getNewValue(); + private void velocityHackBehavior(RAMEvent velocityChangeEvent) { + int newVel = velocityChangeEvent.getNewValue(); if (newVel > 5) { newVel = 1; } - e.setNewValue(newVel & 0x0ff); + velocityChangeEvent.setNewValue(newVel & 0x0ff); } public void mouseClicked(MouseButton button) { diff --git a/src/main/java/jace/core/RAM.java b/src/main/java/jace/core/RAM.java index fea2dd1..6bfc182 100644 --- a/src/main/java/jace/core/RAM.java +++ b/src/main/java/jace/core/RAM.java @@ -31,9 +31,10 @@ import java.util.Optional; * manages cards in the emulator because they are tied into the MMU memory * bankswitch logic. * - * @author Brendan Robert (BLuRry) brendan.robert@gmail.com + * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public abstract class RAM implements Reconfigurable { + public PagedMemory activeRead; public PagedMemory activeWrite; public List listeners; @@ -46,13 +47,14 @@ public abstract class RAM implements Reconfigurable { /** * Creates a new instance of RAM + * * @param computer */ public RAM(Computer computer) { this.computer = computer; listeners = new ArrayList<>(); cards = new Optional[8]; - for (int i=0; i < 8; i ++) { + for (int i = 0; i < 8; i++) { cards[i] = Optional.empty(); } refreshListenerMap(); @@ -202,36 +204,80 @@ public abstract class RAM implements Reconfigurable { addListenerRange(l); }); } - + public RAMListener observe(RAMEvent.TYPE type, int address, 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 protected void doConfig() { setScopeStart(address); } - + @Override protected void doEvent(RAMEvent e) { handler.handleEvent(e); } }); } - + + public RAMListener observe(RAMEvent.TYPE type, int address, boolean auxFlag, RAMEvent.RAMEventHandler handler) { + return addListener(new RAMListener(type, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) { + @Override + protected void doConfig() { + setScopeStart(address); + } + + @Override + protected void doEvent(RAMEvent e) { + if (isAuxFlagCorrect(e, auxFlag)) { + handler.handleEvent(e); + } + } + }); + } + public RAMListener observe(RAMEvent.TYPE type, int addressStart, int addressEnd, 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 protected void doConfig() { setScopeStart(addressStart); setScopeEnd(addressEnd); } - + @Override protected void doEvent(RAMEvent e) { handler.handleEvent(e); } }); - } - + } + + public RAMListener observe(RAMEvent.TYPE type, int addressStart, int addressEnd, boolean auxFlag, RAMEvent.RAMEventHandler handler) { + return addListener(new RAMListener(type, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) { + @Override + protected void doConfig() { + setScopeStart(addressStart); + setScopeEnd(addressEnd); + } + + @Override + protected void doEvent(RAMEvent e) { + if (isAuxFlagCorrect(e, auxFlag)) { + handler.handleEvent(e); + } + } + }); + } + + private boolean isAuxFlagCorrect(RAMEvent e, boolean auxFlag) { + if (e.getAddress() < 0x0100) { + if (SoftSwitches.AUXZP.getState() != auxFlag) { + return false; + } + } else if (SoftSwitches.RAMRD.getState() != auxFlag) { + return false; + } + return true; + } + public RAMListener addListener(final RAMListener l) { boolean restart = computer.pause(); if (listeners.contains(l)) { @@ -321,7 +367,8 @@ public abstract class RAM implements Reconfigurable { // System.out.println(Integer.toString(i, 16)+":"+part1+" -> "+part2); } } - + abstract public void attach(); + abstract public void detach(); -} \ No newline at end of file +}