Skip to content

Commit

Permalink
Allow changing VM between CHIP-8 and SuperCHIP-8 in runtime.
Browse files Browse the repository at this point in the history
  • Loading branch information
krk committed Jun 30, 2020
1 parent 98031f1 commit e8b8f46
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 37 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ java --enable-preview -jar emulator-awt/target/emulator-awt-1.0-SNAPSHOT-jar-wit

To emulate **SuperCHIP-8**:

Select `SuperCHIP-8` from the VM menu or start the emulator with:

```bash
java --enable-preview -jar emulator-awt/target/emulator-awt-1.0-SNAPSHOT-jar-with-dependencies.jar --superchip8
```
Expand Down Expand Up @@ -142,7 +144,7 @@ interpreter.load(0x200, program)
interpreter.tick();
}
```

__
## Further direction

- Add VM save and load snapshot feature - save game support for all kinds of programs.
Expand Down
Binary file modified chipsekiz/docs/chipsekiz.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 2 additions & 28 deletions emulator-awt/src/main/java/dev/krk/chipsekiz/emulator/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

import javax.sound.sampled.LineUnavailableException;

import java.util.Timer;
import java.util.TimerTask;

public class App {
public static void main(String[] args) throws LineUnavailableException {
EmulatorOptions options = new EmulatorOptions(true);
Expand All @@ -26,30 +23,7 @@ public static void main(String[] args) throws LineUnavailableException {
}
}

runEmulator(factory, options, resolution);
}

private static void runEmulator(IEmulatableFactory factory, EmulatorOptions options,
Resolution resolution) throws LineUnavailableException {
final Tone tone = new Tone(1600);

IEmulatable e = factory.create(options, tone);
IEmulatorController controller = e.getController();
EmulatorWindow win = new EmulatorWindow(e.getCanvas(), controller, resolution);

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override public void run() {
win.setTitle(
String.format("chipsekiz emulator - %d Hz", controller.getActualFrequency()));
}
}, 0, 100);

if (!e.hasDemoProgram()) {
controller.pause();
}
controller.run();

tone.close();
EmulatorWindow win = new EmulatorWindow(factory, options, resolution);
win.run();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public EmulatorController(Emulator emulator, IInterpreter interpreter, IDebugger

@Override public void stop() {
emulator.stop();
if (debugger != null) {
debugger.closeDebuggerWindow();
}
}

@Override public void pause() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.io.Files;
import dev.krk.chipsekiz.superchip.interpreter.Resolution;

import javax.sound.sampled.LineUnavailableException;
import javax.swing.ButtonGroup;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
Expand All @@ -15,19 +16,25 @@
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

public class EmulatorWindow extends JFrame implements KeyListener {
private final IEmulatorController controller;

EmulatorWindow(EmulatorCanvas canvas, IEmulatorController controller, Resolution resolution) {
private IEmulatable emulatable;
private EmulatorCanvas canvas;
private IEmulatorController controller;
private final Tone tone;
private String vmName = "CHIP-8";

EmulatorWindow(IEmulatableFactory factory, EmulatorOptions options, Resolution resolution)
throws LineUnavailableException {
super("chipsekiz emulator");
this.controller = controller;

setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize((resolution == Resolution.High ? 128 : 64) * 12,
(resolution == Resolution.High ? 64 : 32) * 12 + 88);

add(canvas);
tone = new Tone(1600);

loadEmulator(factory, options, resolution);

addKeyListener(this);

Expand Down Expand Up @@ -73,6 +80,31 @@ public class EmulatorWindow extends JFrame implements KeyListener {

menuBar.add(menu);

menu = new JMenu("VM");
menu.setMnemonic('v');

ButtonGroup vmGroup = new ButtonGroup();

JRadioButtonMenuItem vm = new JRadioButtonMenuItem("CHIP-8", true);
vm.setMnemonic(KeyEvent.VK_0);
menu.add(vm);
vm.addActionListener(e -> {
loadEmulator(new Chip8EmulatableFactory(), options, Resolution.Low);
vmName = "CHIP-8";
runAsync();
});
vmGroup.add(vm);

vm = new JRadioButtonMenuItem("Super CHIP-8", false);
menu.add(vm);
vm.addActionListener(e -> {
loadEmulator(new SuperChip8EmulatableFactory(), options, Resolution.High);
vmName = "SuperCHIP-8";
runAsync();
});
vmGroup.add(vm);
menuBar.add(menu);

// Sound menu
menu = new JMenu("Sound");
menu.setMnemonic('u');
Expand Down Expand Up @@ -141,7 +173,7 @@ public class EmulatorWindow extends JFrame implements KeyListener {
scale.addActionListener(scaleSetter);
scaleGroup.add(scale);

scale = new JRadioButtonMenuItem("3x3", true);
scale = new JRadioButtonMenuItem("3x3", false);
scale.setMnemonic(KeyEvent.VK_3);
scale.setActionCommand("3");
menu.add(scale);
Expand Down Expand Up @@ -237,6 +269,25 @@ public class EmulatorWindow extends JFrame implements KeyListener {
setJMenuBar(menuBar);

setVisible(true);

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override public void run() {
setTitle(String.format("chipsekiz %s emulator - %d Hz", vmName,
controller.getActualFrequency()));
}
}, 0, 100);
}

public void run() {
if (!emulatable.hasDemoProgram()) {
controller.pause();
}
controller.run();
}

private void runAsync() {
new Thread(this::run).start();
}

private void loadROM() throws IOException {
Expand All @@ -250,6 +301,29 @@ private void loadROM() throws IOException {
}
}

private void loadEmulator(IEmulatableFactory factory, EmulatorOptions options,
Resolution resolution) {

emulatable = factory.create(options, tone);
EmulatorCanvas canvas = emulatable.getCanvas();
IEmulatorController controller = emulatable.getController();

if (this.controller != null) {
this.controller.stop();
}

setSize((resolution == Resolution.High ? 128 : 64) * 12,
(resolution == Resolution.High ? 64 : 32) * 12 + 88);

if (this.canvas != null) {
remove(this.canvas);
}
add(canvas);

this.canvas = canvas;
this.controller = controller;
}

@Override public void keyTyped(KeyEvent e) {
// NOOP.
}
Expand All @@ -261,4 +335,10 @@ private void loadROM() throws IOException {
@Override public void keyReleased(KeyEvent e) {
controller.keyUp();
}

@Override public void dispose() {
super.dispose();

tone.close();
}
}

0 comments on commit e8b8f46

Please sign in to comment.