Lambda simplification and code cleanup

This commit is contained in:
Brendan Robert 2015-08-15 22:57:49 -05:00
parent 5c0855d966
commit e7f731900a
9 changed files with 170 additions and 353 deletions

View File

@ -29,22 +29,6 @@ public class JaceApplication extends Application {
JaceUIController controller;
static boolean romStarted = false;
static RAMListener startListener = new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0FA62);
}
@Override
protected void doEvent(RAMEvent e) {
romStarted = true;
}
@Override
public boolean isRelevant(RAMEvent e) {
return super.isRelevant(e);
}
};
@Override
public void start(Stage stage) throws Exception {
@ -95,12 +79,16 @@ public class JaceApplication extends Application {
* Start the computer and make sure it runs through the expected rom routine for cold boot
*/
private void bootWatchdog() {
Emulator.computer.getMemory().addListener(startListener);
romStarted = false;
RAMListener startListener = Emulator.computer.getMemory().
observe(RAMEvent.TYPE.EXECUTE, 0x0FA62, (e)-> {
romStarted = true;
});
Emulator.computer.coldStart();
try {
Thread.sleep(250);
if (!romStarted) {
System.out.println("Boot not detected, performing a cold start");
Logger.getLogger(getClass().getName()).log(Level.WARNING,"Boot not detected, performing a cold start");
Emulator.computer.coldStart();
}
} catch (InterruptedException ex) {

View File

@ -425,19 +425,11 @@ public class Apple2e extends Computer {
private void enableHints() {
if (hints.isEmpty()) {
hints.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0FB63);
}
@Override
protected void doEvent(RAMEvent e) {
animationTimer.schedule(drawHints, 1, TimeUnit.SECONDS);
animationSchedule =
hints.add(getMemory().observe(RAMEvent.TYPE.EXECUTE, 0x0FB63, (e)->{
animationTimer.schedule(drawHints, 1, TimeUnit.SECONDS);
animationSchedule =
animationTimer.scheduleAtFixedRate(doAnimation, 1250, 100, TimeUnit.MILLISECONDS);
}
});
}));
// Latch to the PRODOS SYNTAX CHECK parser
/*
hints.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@ -458,9 +450,6 @@ public class Apple2e extends Computer {
});
*/
}
hints.stream().forEach((hint) -> {
getMemory().addListener(hint);
});
}
private void disableHints() {
@ -473,8 +462,4 @@ public class Apple2e extends Computer {
public String getShortName() {
return "computer";
}
private void attachMiscDevices() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

View File

@ -26,17 +26,17 @@ import jace.core.RAMEvent;
import jace.core.RAMListener;
import jace.core.SoundMixer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import java.io.FileNotFoundException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.stage.FileChooser;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
/**
* Apple // Speaker Emulation Created on May 9, 2007, 9:55 PM
@ -58,8 +58,8 @@ public class Speaker extends Device {
out = null;
fileOutputActive = false;
} else {
FileChooser fileChooser = new FileChooser();
File f = fileChooser.showSaveDialog(null);
FileChooser fileChooser = new FileChooser();
File f = fileChooser.showSaveDialog(null);
if (f == null) {
return;
}
@ -93,7 +93,7 @@ public class Speaker extends Device {
/**
* Number of samples in buffer
*/
static int BUFFER_SIZE = (int) (((float) SoundMixer.RATE) * 0.4);
static int BUFFER_SIZE = (int) (SoundMixer.RATE * 0.4);
// Number of samples available in output stream before playback happens (avoid extra blocking)
// static int MIN_PLAYBACK_BUFFER = BUFFER_SIZE / 2;
static int MIN_PLAYBACK_BUFFER = 64;
@ -129,35 +129,13 @@ public class Speaker extends Device {
byte[] secondaryBuffer;
int bufferPos = 0;
Timer playbackTimer;
private double TICKS_PER_SAMPLE = ((double) Motherboard.SPEED) / ((double) SoundMixer.RATE);
private double TICKS_PER_SAMPLE_FLOOR = Math.floor(TICKS_PER_SAMPLE);
private final RAMListener listener
= new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
@Override
public boolean isRelevant(RAMEvent e) {
return true;
}
@Override
protected void doConfig() {
setScopeStart(0x0C030);
setScopeEnd(0x0C03F);
}
@Override
protected void doEvent(RAMEvent e) {
if (e.getType() == RAMEvent.TYPE.WRITE) {
level += 2;
} else {
speakerBit = !speakerBit;
}
resetIdle();
}
};
private final double TICKS_PER_SAMPLE = ((double) Motherboard.SPEED) / SoundMixer.RATE;
private final double TICKS_PER_SAMPLE_FLOOR = Math.floor(TICKS_PER_SAMPLE);
private RAMListener listener = null;
/**
* Creates a new instance of Speaker
*
* @param computer
*/
public Speaker(Computer computer) {
@ -186,11 +164,12 @@ public class Speaker extends Device {
*/
@Override
public void resume() {
if (sdl != null && isRunning()) return;
System.out.println("Resuming speaker sound");
if (sdl != null && isRunning()) {
return;
}
try {
if (sdl == null || !sdl.isOpen()) {
sdl = computer.mixer.getLine(this);
sdl = computer.mixer.getLine(this);
}
sdl.start();
setRun(true);
@ -199,14 +178,14 @@ public class Speaker extends Device {
level = 0;
bufferPos = 0;
playbackTimer = new Timer();
playbackTimer.scheduleAtFixedRate(new TimerTask() {
playbackTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
playCurrentBuffer();
}
}, 10, 30);
} catch (LineUnavailableException ex) {
System.out.println("ERROR: Could not output sound: " + ex.getMessage());
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "ERROR: Could not output sound", ex);
}
}
@ -275,11 +254,20 @@ public class Speaker extends Device {
}
}
private void toggleSpeaker(RAMEvent e) {
if (e.getType() == RAMEvent.TYPE.WRITE) {
level += 2;
} else {
speakerBit = !speakerBit;
}
resetIdle();
}
/**
* Add a memory event listener for C03x for capturing speaker events
*/
private void configureListener() {
computer.getMemory().addListener(listener);
listener = computer.getMemory().observe(RAMEvent.TYPE.ANY, 0x0c030, 0x0c03f, this::toggleSpeaker);
}
private void removeListener() {

View File

@ -22,8 +22,10 @@ import jace.core.Computer;
import jace.core.Font;
import jace.core.Palette;
import jace.core.RAMEvent;
import jace.core.RAMListener;
import jace.core.Video;
import static jace.core.Video.hiresOffset;
import static jace.core.Video.hiresRowLookup;
import static jace.core.Video.textRowLookup;
import jace.core.VideoWriter;
import java.util.logging.Logger;
import javafx.scene.image.PixelWriter;
@ -69,6 +71,7 @@ public class VideoDHGR extends Video {
/**
* Creates a new instance of VideoDHGR
*
* @param computer
*/
public VideoDHGR(Computer computer) {
@ -681,47 +684,31 @@ public class VideoDHGR extends Video {
}
}
private void registerTextDirtyFlag(RAMEvent e) {
int row = textRowLookup[e.getAddress() & 0x03ff];
if (row > 23) {
return;
}
VideoWriter tmark = (e.getAddress() < 0x0800) ? textPage1 : textPage2;
row <<= 3;
int yy = row + 8;
for (int y = row; y < yy; y++) {
tmark.markDirty(y);
}
}
private void registerHiresDirtyFlag(RAMEvent e) {
int row = hiresRowLookup[e.getAddress() & 0x01fff];
if (row < 0 || row >= 192) {
return;
}
VideoWriter mark = (e.getAddress() < 0x04000) ? hiresPage1 : hiresPage2;
mark.markDirty(row);
}
private void registerDirtyFlagChecks() {
((RAM128k) computer.getMemory()).addListener(new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0400);
setScopeEnd(0x0bff);
}
@Override
protected void doEvent(RAMEvent e) {
int row = textRowLookup[e.getAddress() & 0x03ff];
// int row = identifyTextRow(e.getAddress() & 0x03ff);
if (row > 23) {
return;
}
VideoWriter tmark = (e.getAddress() < 0x0800) ? textPage1 : textPage2;
row <<= 3;
int yy = row + 8;
for (int y = row; y < yy; y++) {
tmark.markDirty(y);
}
}
});
((RAM128k) computer.getMemory()).addListener(new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x2000);
setScopeEnd(0x5fff);
}
@Override
protected void doEvent(RAMEvent e) {
int row = hiresRowLookup[e.getAddress() & 0x01fff];
// int row = identifyHiresRow(e.getAddress() & 0x03fff);
if (row < 0 || row >= 192) {
return;
}
VideoWriter mark = (e.getAddress() < 0x04000) ? hiresPage1 : hiresPage2;
mark.markDirty(row);
}
});
computer.getMemory().observe(RAMEvent.TYPE.WRITE, 0x0400, 0x0bff, this::registerTextDirtyFlag);
computer.getMemory().observe(RAMEvent.TYPE.WRITE, 0x02000, 0x05fff, this::registerHiresDirtyFlag);
}
@Override

View File

@ -18,11 +18,12 @@
*/
package jace.apple2e;
import static jace.apple2e.VideoDHGR.BLACK;
import jace.config.ConfigurableField;
import jace.core.Computer;
import jace.core.RAM;
import jace.core.RAMEvent;
import jace.core.RAMListener;
import jace.core.Video;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@ -64,7 +65,7 @@ public class VideoNTSC extends VideoDHGR {
public VideoNTSC(Computer computer) {
super(computer);
createStateListeners();
registerStateListeners();
}
@Override
@ -269,7 +270,7 @@ public class VideoNTSC extends VideoDHGR {
col = ((col & 8) >> 3) | ((col << 1) & 0x0f);
}
double y1 = YIQ_VALUES[col][0];
double y2 = ((double) level / (double) maxLevel);
double y2 = (level / (double) maxLevel);
SOLID_PALETTE[offset][pattern] = yiqToRgb(y1, YIQ_VALUES[col][1] * MAX_I, YIQ_VALUES[col][2] * MAX_Q);
TEXT_PALETTE[offset][pattern] = yiqToRgb(y2, YIQ_VALUES[col][1] * MAX_I, YIQ_VALUES[col][2] * MAX_Q);
}
@ -325,113 +326,61 @@ public class VideoNTSC extends VideoDHGR {
}
boolean f1 = true;
boolean f2 = true;
boolean an3 = true;
boolean an3 = false;
public void rgbStateChange() {
public void rgbStateChange(ModeStateChanges state) {
switch (state) {
case CLEAR_80:
break;
case CLEAR_AN3:
an3 = false;
break;
case SET_80:
break;
case SET_AN3:
if (!an3) {
f2 = f1;
f1 = SoftSwitches._80COL.getState();
}
an3 = true;
break;
}
// This is the more technically correct implementation except for two issues:
// 1) 160-column mode isn't implemented so it's not worth bothering to capture that state
// 2) A lot of programs are clueless about RGB modes so it's good to default to normal color mode
// graphicsMode = f1 ? (f2 ? rgbMode.color : rgbMode.mix) : (f2 ? rgbMode._160col : rgbMode.bw);
graphicsMode = f1 ? (f2 ? rgbMode.COLOR : rgbMode.MIX) : (f2 ? rgbMode.COLOR : rgbMode.BW);
// System.out.println(state + ": "+ graphicsMode);
}
// These catch changes to the RGB mode to toggle between color, BW and mixed
Set<RAMListener> rgbStateListeners = new HashSet<>();
private void createStateListeners() {
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0c05e);
private void registerStateListeners() {
if (!rgbStateListeners.isEmpty() || computer.getVideo() != this) {
return;
}
RAM memory = computer.getMemory();
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.ANY, 0x0c05e, (e) -> {
an3 = false;
rgbStateChange();
}));
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.ANY, 0x0c05f, (e) -> {
if (!an3) {
f2 = f1;
f1 = SoftSwitches._80COL.getState();
}
@Override
protected void doEvent(RAMEvent e) {
Video v = computer.getVideo();
if (v instanceof VideoNTSC) {
((VideoNTSC) v).rgbStateChange(ModeStateChanges.CLEAR_AN3);
}
}
});
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0c05f);
}
@Override
protected void doEvent(RAMEvent e) {
Video v = computer.getVideo();
if (v instanceof VideoNTSC) {
((VideoNTSC) v).rgbStateChange(ModeStateChanges.SET_AN3);
}
}
});
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.EXECUTE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0fa62);
}
@Override
protected void doEvent(RAMEvent e) {
Video v = computer.getVideo();
if (v instanceof VideoNTSC) {
// When reset hook is called, reset the graphics mode
// This is useful in case a program is running that
// is totally clueless how to set the RGB state correctly.
((VideoNTSC) v).f1 = true;
((VideoNTSC) v).f2 = true;
((VideoNTSC) v).an3 = false;
((VideoNTSC) v).graphicsMode = rgbMode.COLOR;
}
}
});
rgbStateListeners.add(new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0c00d);
}
@Override
protected void doEvent(RAMEvent e) {
Video v = computer.getVideo();
if (v instanceof VideoNTSC) {
((VideoNTSC) v).rgbStateChange(ModeStateChanges.SET_80);
}
}
});
an3 = true;
rgbStateChange();
}));
rgbStateListeners.add(memory.observe(RAMEvent.TYPE.EXECUTE, 0x0fa62, (e) -> {
// When reset hook is called, reset the graphics mode
// This is useful in case a program is running that
// is totally clueless how to set the RGB state correctly.
f1 = true;
f2 = true;
an3 = false;
graphicsMode = rgbMode.COLOR;
rgbStateChange();
}));
}
@Override
public void detach() {
rgbStateListeners.stream().forEach((l) -> {
computer.getMemory().removeListener(l);
});
rgbStateListeners.clear();
super.detach();
}
@Override
public void attach() {
super.attach();
rgbStateListeners.stream().forEach((l) -> {
computer.getMemory().addListener(l);
});
registerStateListeners();
}
}

View File

@ -31,7 +31,7 @@ import jace.apple2e.SoftSwitches;
* synchronization.
* Created on February 1, 2007, 5:35 PM
*
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
* @author Brendan Robert (BLuRry) brendan.robert@gmail.com
*/
public abstract class Card extends Device {
@ -44,6 +44,7 @@ public abstract class Card extends Device {
/**
* Creates a new instance of Card
*
* @param computer
*/
public Card(Computer computer) {
@ -117,72 +118,32 @@ public abstract class Card extends Device {
}
protected void registerListeners() {
ioListener = new RAMListener(
RAMEvent.TYPE.ANY,
RAMEvent.SCOPE.RANGE,
RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(slot * 16 + 0x00c080);
setScopeEnd(slot * 16 + 0x00c08F);
}
RAM memory = computer.getMemory();
int baseIO = 0x0c080 + slot * 16;
int baseRom = 0x0c000 + slot * 256;
ioListener = memory.observe(RAMEvent.TYPE.ANY, baseIO, baseIO + 15, (e) -> {
int address = e.getAddress() & 0x0f;
handleIOAccess(address, e.getType(), e.getNewValue(), e);
});
@Override
protected void doEvent(RAMEvent e) {
int address = e.getAddress() & 0x0f;
handleIOAccess(address, e.getType(), e.getNewValue(), e);
}
};
firmwareListener = new RAMListener(
RAMEvent.TYPE.ANY,
RAMEvent.SCOPE.RANGE,
RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(slot * 256 + 0x00c000);
setScopeEnd(slot * 256 + 0x00c0ff);
}
@Override
protected void doEvent(RAMEvent e) {
computer.getMemory().setActiveCard(slot);
if (SoftSwitches.CXROM.getState()) {
return;
}
firmwareListener = memory.observe(RAMEvent.TYPE.ANY, baseRom, baseRom + 255, (e) -> {
computer.getMemory().setActiveCard(slot);
if (SoftSwitches.CXROM.isOff()) {
handleFirmwareAccess(e.getAddress() & 0x0ff, e.getType(), e.getNewValue(), e);
}
};
});
c8firmwareListener = new RAMListener(
RAMEvent.TYPE.ANY,
RAMEvent.SCOPE.RANGE,
RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(slot * 256 + 0x00c800);
setScopeEnd(slot * 256 + 0x00cfff);
}
@Override
protected void doEvent(RAMEvent e) {
if (SoftSwitches.CXROM.getState()
|| computer.getMemory().getActiveSlot() != getSlot()
|| SoftSwitches.INTC8ROM.getState()) {
return;
}
c8firmwareListener = memory.observe(RAMEvent.TYPE.ANY, 0xc800, 0xcfff, (e) -> {
if (SoftSwitches.CXROM.isOff() && SoftSwitches.INTC8ROM.isOff()
&& computer.getMemory().getActiveSlot() == slot) {
handleC8FirmwareAccess(e.getAddress() - 0x0c800, e.getType(), e.getNewValue(), e);
}
};
computer.getMemory().addListener(ioListener);
computer.getMemory().addListener(firmwareListener);
computer.getMemory().addListener(c8firmwareListener);
});
}
protected void unregisterListeners() {
computer.getMemory().removeListener(ioListener);
computer.getMemory().removeListener(firmwareListener);
computer.getMemory().removeListener(c8firmwareListener);
}
}
}
}

View File

@ -105,30 +105,28 @@ public abstract class RAM implements Reconfigurable {
abstract public void configureActiveMemory();
public byte write(int address, byte b, boolean generateEvent, boolean requireSynchronization) {
public void write(int address, byte b, boolean generateEvent, boolean requireSynchronization) {
byte[] page = activeWrite.getMemoryPage(address);
byte old = 0;
if (page == null) {
if (generateEvent) {
callListener(RAMEvent.TYPE.WRITE, address, old, b, requireSynchronization);
callListener(RAMEvent.TYPE.WRITE, address, 0, b, requireSynchronization);
}
} else {
int offset = address & 0x0FF;
old = page[offset];
byte old = page[offset];
if (generateEvent) {
b = callListener(RAMEvent.TYPE.WRITE, address, old, b, requireSynchronization);
page[offset] = callListener(RAMEvent.TYPE.WRITE, address, old, b, requireSynchronization);
} else {
page[offset] = b;
}
page[offset] = b;
}
return old;
}
public void writeWord(int address, int w, boolean generateEvent, boolean requireSynchronization) {
int lsb = write(address, (byte) (w & 0x0ff), generateEvent, requireSynchronization);
int msb = write(address + 1, (byte) (w >> 8), generateEvent, requireSynchronization);
// int oldValue = msb << 8 + lsb;
write(address, (byte) (w & 0x0ff), generateEvent, requireSynchronization);
write(address + 1, (byte) (w >> 8), generateEvent, requireSynchronization);
}
public byte readRaw(int address) {
// if (address >= 65536) return 0;
return activeRead.getMemoryPage(address)[address & 0x0FF];
@ -236,7 +234,7 @@ public abstract class RAM implements Reconfigurable {
}
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.RANGE, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(addressStart);
@ -251,7 +249,7 @@ public abstract class RAM implements Reconfigurable {
}
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) {
return addListener(new RAMListener(type, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(addressStart);
@ -334,40 +332,6 @@ public abstract class RAM implements Reconfigurable {
abstract protected void loadRom(String path) throws IOException;
public void dump() {
for (int i = 0; i < 0x0FFFF; i += 16) {
System.out.print(Integer.toString(i, 16));
System.out.print(":");
String part1 = "";
String part2 = "";
for (int j = 0; j < 16; j++) {
int a = i + j;
int br = 0x0FF & activeRead.getMemory()[i >> 8][i & 0x0ff];
String s1 = Integer.toString(br, 16);
System.out.print(' ');
if (s1.length() == 1) {
System.out.print('0');
}
System.out.print(s1);
/*
try {
int bw = 0;
bw = 0x0FF & activeWrite.getMemory().get(a/256)[a%256];
String s2 = (br == bw) ? "**" : Integer.toString(bw,16);
System.out.print(' ');
if (s2.length()==1) System.out.print('0');
System.out.print(s2);
} catch (NullPointerException ex) {
System.out.print(" --");
}
*/
}
System.out.println();
// System.out.println(Integer.toString(i, 16)+":"+part1+" -> "+part2);
}
}
abstract public void attach();
abstract public void detach();

View File

@ -117,8 +117,11 @@ public class CardRamworks extends RAM128k {
public void reconfigure() {
boolean resume = computer.pause();
maxBank = memorySize / 64;
if (maxBank < 1) maxBank = 1;
if (maxBank > 128) maxBank = 128;
if (maxBank < 1) {
maxBank = 1;
} else if (maxBank > 128) {
maxBank = 128;
}
for (int i = memory.size(); i < maxBank; i++) {
memory.add(null);
}
@ -127,23 +130,14 @@ public class CardRamworks extends RAM128k {
computer.resume();
}
}
RAMListener bankSelectListener = new RAMListener(RAMEvent.TYPE.WRITE, RAMEvent.SCOPE.ADDRESS, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(BANK_SELECT);
setScopeEnd(BANK_SELECT);
}
@Override
protected void doEvent(RAMEvent e) {
currentBank = e.getNewValue();
configureActiveMemory();
}
};
private RAMListener bankSelectListener;
@Override
public void attach() {
addListener(bankSelectListener);
bankSelectListener = computer.getMemory().observe(RAMEvent.TYPE.WRITE, BANK_SELECT, (e) -> {
currentBank = e.getNewValue();
configureActiveMemory();
});
}
@Override

View File

@ -46,6 +46,7 @@ import java.util.logging.Logger;
*/
@Stateful
public class Joystick extends Device {
@ConfigurableField(name = "Center Mouse", shortName = "center", description = "Moves mouse back to the center of the screen, can get annoying.")
public boolean centerMouse = false;
@ConfigurableField(name = "Use keyboard", shortName = "useKeys", description = "Arrow keys will control joystick instead of the mouse.")
@ -91,8 +92,8 @@ public class Joystick extends Device {
private void readJoystick() {
if (useKeyboard) {
joyX = (leftPressed ? -128 : 0) + (rightPressed ? 255:128);
joyY = (upPressed ? -128 : 0) + (downPressed ? 255:128);
joyX = (leftPressed ? -128 : 0) + (rightPressed ? 255 : 128);
joyY = (upPressed ? -128 : 0) + (downPressed ? 255 : 128);
} else {
Point l = MouseInfo.getPointerInfo().getLocation();
if (l.x < lastMouseLocation.x) {
@ -187,29 +188,12 @@ public class Joystick extends Device {
y = 0;
registerListeners();
}
RAMListener listener = new RAMListener(RAMEvent.TYPE.ANY, RAMEvent.SCOPE.RANGE, RAMEvent.VALUE.ANY) {
@Override
protected void doConfig() {
setScopeStart(0x0C070);
setScopeEnd(0x0C07f);
}
@Override
protected void doEvent(RAMEvent e) {
readJoystick();
xSwitch.setState(true);
x = 10 + joyX * 11;
ySwitch.setState(true);
y = 10 + joyY * 11;
e.setNewValue(computer.getVideo().getFloatingBus());
resume();
}
};
@InvokableAction(name = "Left", category = "joystick", defaultKeyMapping = "left", notifyOnRelease = true)
public boolean joystickLeft(boolean pressed) {
if (!useKeyboard) return false;
if (!useKeyboard) {
return false;
}
leftPressed = pressed;
if (pressed) {
rightPressed = false;
@ -220,7 +204,9 @@ public class Joystick extends Device {
;
@InvokableAction(name = "Right", category = "joystick", defaultKeyMapping = "right", notifyOnRelease = true)
public boolean joystickRight(boolean pressed) {
if (!useKeyboard) return false;
if (!useKeyboard) {
return false;
}
rightPressed = pressed;
if (pressed) {
leftPressed = false;
@ -231,7 +217,9 @@ public class Joystick extends Device {
;
@InvokableAction(name = "Up", category = "joystick", defaultKeyMapping = "up", notifyOnRelease = true)
public boolean joystickUp(boolean pressed) {
if (!useKeyboard) return false;
if (!useKeyboard) {
return false;
}
upPressed = pressed;
if (pressed) {
downPressed = false;
@ -242,7 +230,9 @@ public class Joystick extends Device {
;
@InvokableAction(name = "Down", category = "joystick", defaultKeyMapping = "down", notifyOnRelease = true)
public boolean joystickDown(boolean pressed) {
if (!useKeyboard) return false;
if (!useKeyboard) {
return false;
}
downPressed = pressed;
if (pressed) {
upPressed = false;
@ -250,12 +240,23 @@ public class Joystick extends Device {
return hogKeyboard;
}
public void initJoystickRead(RAMEvent e) {
readJoystick();
xSwitch.setState(true);
x = 10 + joyX * 11;
ySwitch.setState(true);
y = 10 + joyY * 11;
e.setNewValue(computer.getVideo().getFloatingBus());
resume();
}
RAMListener listener;
private void registerListeners() {
computer.getMemory().addListener(listener);
listener = computer.getMemory().observe(RAMEvent.TYPE.ANY, 0x0c070, 0x0c07f, this::initJoystickRead);
}
private void removeListeners() {
computer.getMemory().removeListener(listener);
// Keyboard.unregisterAllHandlers(this);
}
}