From 11a54d37f05ef885978404e07b81ecd2f84135aa Mon Sep 17 00:00:00 2001 From: Peter Jakubco Date: Tue, 2 Jan 2024 10:34:30 +0100 Subject: [PATCH] [#314] Cleanup + refactoring --- .../device/zxspectrum/ula/DeviceImpl.java | 5 ++ .../zxspectrum/ula/PassedCyclesMediator.java | 83 +++++++++++++++++++ .../plugins/device/zxspectrum/ula/ULA.java | 71 ++++++++-------- .../device/zxspectrum/ula/ZxParameters.java | 36 ++++++++ .../zxspectrum/ula/gui/DisplayCanvas.java | 66 +-------------- .../zxspectrum/ula/gui/DisplayWindow.java | 11 ++- .../zxspectrum/ula/gui/KeyboardCanvas.java | 6 +- 7 files changed, 177 insertions(+), 101 deletions(-) create mode 100644 plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/PassedCyclesMediator.java create mode 100644 plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ZxParameters.java diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/DeviceImpl.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/DeviceImpl.java index c7681e8bc..c715cffcd 100644 --- a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/DeviceImpl.java +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/DeviceImpl.java @@ -34,6 +34,7 @@ import java.util.Optional; import java.util.ResourceBundle; +@SuppressWarnings("unused") @PluginRoot(type = PLUGIN_TYPE.DEVICE, title = "ZX Spectrum48K ULA") public class DeviceImpl extends AbstractDevice { @@ -42,6 +43,7 @@ public class DeviceImpl extends AbstractDevice { private boolean guiIOset = false; private ULA ula; + private PassedCyclesMediator passedCyclesMediator; private DisplayWindow gui; public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings settings) { @@ -54,6 +56,8 @@ public DeviceImpl(long pluginID, ApplicationApi applicationApi, PluginSettings s public void initialize() throws PluginInitializationException { ZxSpectrumBus bus = applicationApi.getContextPool().getDeviceContext(pluginID, ZxSpectrumBus.class); this.ula = new ULA(bus); + this.passedCyclesMediator = new PassedCyclesMediator(ula); + bus.addPassedCyclesListener(passedCyclesMediator); keyboard.addOnKeyListener(ula); bus.attachDevice(0xFE, ula); } @@ -88,6 +92,7 @@ public void showGUI(JFrame parent) { if (guiSupported) { if (!guiIOset) { this.gui = new DisplayWindow(parent, ula, keyboard); + passedCyclesMediator.setCanvas(gui.getCanvas()); GuiUtils.addKeyListener(gui, keyboard); guiIOset = true; this.gui.setVisible(true); diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/PassedCyclesMediator.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/PassedCyclesMediator.java new file mode 100644 index 000000000..cf43abe64 --- /dev/null +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/PassedCyclesMediator.java @@ -0,0 +1,83 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2024 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.zxspectrum.ula; + +import net.emustudio.emulib.plugins.cpu.CPUContext; +import net.emustudio.plugins.device.zxspectrum.ula.gui.DisplayCanvas; + +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.*; + +/** + * Triggers actions based on passed CPU cycles. + *

+ * For ZX Spectrum 48K the actions are: + *

+ * - 0: CPU interrupt + * - 0 - 14336: first 64 lines. From those, at least 48 are border-lines, others are either border or vertical retraces + * After an interrupt occurs, 64 line times (14336 T states; see below for exact timings) pass before + * - 14337 - 57344: 192 screen lines are displayed + * - 57345 - 69888: 56 border-lines are displayed + *

+ * This means a frame is (64+192+56)*224=69888 T states long, which means that the CPU interrupt occurs + * at 3.5MHz/69888=50.08 Hz. + */ +public class PassedCyclesMediator implements CPUContext.PassedCyclesListener { + private static final long LINE_CYCLES = 224; + private static final long FRAME_CYCLES = (PRE_SCREEN_LINES + SCREEN_HEIGHT + POST_SCREEN_LINES) * LINE_CYCLES; // 69888; + + private long frameCycles = 0; + private long lineCycles = 0; + private int lastLinePainted = 0; + + private final AtomicReference canvas = new AtomicReference<>(); + private final ULA ula; + + public PassedCyclesMediator(ULA ula) { + this.ula = Objects.requireNonNull(ula); + } + + public void setCanvas(DisplayCanvas canvas) { + this.canvas.set(canvas); + } + + @Override + public void passedCycles(long cycles) { + frameCycles += cycles; + lineCycles += cycles; + + DisplayCanvas canvas = this.canvas.get(); + if (canvas != null) { + if (lineCycles >= LINE_CYCLES) { + canvas.drawNextLine(lastLinePainted++); + } + } + lineCycles = lineCycles % LINE_CYCLES; + if (frameCycles >= FRAME_CYCLES) { + lastLinePainted = 0; + ula.onNextFrame(); + frameCycles = frameCycles % FRAME_CYCLES; + if (canvas != null) { + canvas.runPaintCycle(); // expensive operation + } + } + } +} diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ULA.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ULA.java index 4a8229276..f4a781675 100644 --- a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ULA.java +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ULA.java @@ -28,6 +28,8 @@ import java.util.Map; import java.util.Objects; +import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.*; + /** * Uncommitted Logic Array (ULA). *

@@ -36,7 +38,14 @@ * - Screen Memory layout * *

- * OUT: + * The ULA component in emuStudio is a "mediator" of interaction between host and emulator. That means, it handles: + * - keyboard + * - audio + * - video (maps RAM to video/attribute memory, video flash, border color) + *

+ * From the ZX Spectrum point of view, it represents the port 0xFE (254). + *

+ * Port 0xFE write: * 7 6 5 4 3 2 1 0 * +-------------------------------+ * | | | | E | M | Border | @@ -47,15 +56,14 @@ * - on host CTRL + letter/number = ZX symbol "shift" + letter/number * - on host plain letter/number = ZX letter/number *

- * IN: (bit 0 to bit 4 inclusive) + * Port 0xFE read (bit 0 to bit 4 inclusive): * 0xfefe SHIFT, Z, X, C, V 0xeffe 0, 9, 8, 7, 6 * 0xfdfe A, S, D, F, G 0xdffe P, O, I, U, Y * 0xfbfe Q, W, E, R, T 0xbffe ENTER, L, K, J, H * 0xf7fe 1, 2, 3, 4, 5 0x7ffe SPACE, SYM SHIFT, M, N, B *

* The colour attribute data overlays the monochrome bitmap data and is arranged in a linear fashion from left to right, - * top to bottom. - * Each attribute byte colours is 8x8 character on the screen and is encoded as follows: + * top to bottom. Each attribute byte colours is 8x8 character on the screen and is encoded as follows: *

* 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * F | B | P2| P1| P0| I2| I1| I0| @@ -67,18 +75,16 @@ * - I2 to I0 is the INK colour */ public class ULA implements Context8080.CpuPortDevice, Keyboard.OnKeyListener { - public static final int SCREEN_WIDTH = 32; // in bytes; each byte represents 8 pixels in a row, reversed - public static final int SCREEN_HEIGHT = 192; - public static final int ATTRIBUTE_HEIGHT = SCREEN_HEIGHT / 8; - private final static byte[] RST_7 = new byte[0x38]; // works for IM1 and IM2 modes private final static byte[] KEY_SHIFT = new byte[]{0, 1}; private final static byte[] KEY_SYM_SHIFT = new byte[]{7, 2}; + private final static int[] LINE_OFFSETS = computeLineOffsets(); private final byte[] keymap = new byte[8]; // keyboard state + + // accessible from outside public final byte[][] videoMemory = new byte[SCREEN_WIDTH][SCREEN_HEIGHT]; public final byte[][] attributeMemory = new byte[SCREEN_WIDTH][ATTRIBUTE_HEIGHT]; - private final static int[] lineStartOffsets = computeLineStartOffsets(); // maps host characters to ZX Spectrum key "commands" // Byte[] = {keymap index, "zero" value, shift, symshift} @@ -127,8 +133,6 @@ public class ULA implements Context8080.CpuPortDevice, Keyboard.OnKeyListener { CHAR_MAPPING.put((char) 127, new Byte[]{4, 1, 1, -1}); // delete } - // The Spectrum's 'FLASH' effect is also produced by the ULA: Every 16 frames, the ink and paper of all flashing - // bytes is swapped; ie a normal to inverted to normal cycle takes 32 frames, which is (good as) 0.64 seconds. public boolean videoFlash = false; private int flashFramesCount = 0; @@ -137,7 +141,6 @@ public class ULA implements Context8080.CpuPortDevice, Keyboard.OnKeyListener { private int borderColor; private boolean microphoneAndEarOut; // TODO: audio - public ULA(ZxSpectrumBus bus) { this.bus = Objects.requireNonNull(bus); Arrays.fill(keymap, (byte) 0xBF); @@ -150,32 +153,22 @@ public void reset() { } public void onNextFrame() { - if (flashFramesCount == 15) { + bus.signalInterrupt(RST_7); + if (flashFramesCount == VIDEO_FLASH_FRAME) { videoFlash = !videoFlash; } - flashFramesCount = (flashFramesCount + 1) % 16; + flashFramesCount = (flashFramesCount + 1) % (VIDEO_FLASH_FRAME + 1); } public void readScreen() { - for (int x = 0; x < SCREEN_WIDTH; x++) { - for (int y = 0; y < SCREEN_HEIGHT; y++) { - videoMemory[x][y] = bus.readMemoryNotContended(0x4000 + lineStartOffsets[y] + x); - if (y < ATTRIBUTE_HEIGHT) { - int off = ((y >>> 3) << 8) | (((y & 0x07) << 5) | x); - int attributeAddress = 0x5800 + off; - attributeMemory[x][y] = bus.readMemoryNotContended(attributeAddress); - } - } + for (int y = 0; y < SCREEN_HEIGHT; y++) { + readLine(y); } } - public void triggerInterrupt() { - bus.signalInterrupt(RST_7); - } - public void readLine(int y) { for (int x = 0; x < SCREEN_WIDTH; x++) { - videoMemory[x][y] = bus.readMemoryNotContended(0x4000 + lineStartOffsets[y] + x); + videoMemory[x][y] = bus.readMemoryNotContended(0x4000 + LINE_OFFSETS[y] + x); if (y < ATTRIBUTE_HEIGHT) { int off = ((y >>> 3) << 8) | (((y & 0x07) << 5) | x); int attributeAddress = 0x5800 + off; @@ -188,10 +181,6 @@ public int getBorderColor() { return borderColor; } - public ZxSpectrumBus getBus() { - return bus; - } - @Override public byte read(int portAddress) { // A zero in one of the five lowest bits means that the corresponding key is pressed. @@ -220,7 +209,7 @@ public byte read(int portAddress) { // ENTER, L, K, J, H result &= keymap[6]; } else if ((portAddress & 0x7FFE) == 0x7FFE) { - // SPACE, SYM SHFT, M, N, B + // SPACE, SYM SHIFT, M, N, B result &= keymap[7]; } @@ -271,7 +260,6 @@ public void onKeyUp(KeyEvent evt) { keymap[command[0]] |= command[1]; } } - } @Override @@ -302,7 +290,20 @@ public void onKeyDown(KeyEvent evt) { } } - private static int[] computeLineStartOffsets() { + /** + * Computes address offsets for each line in the screen. + *

+ * The Spectrum’s screen memory starts at 0x4000 so the most significant three bits of our address will always be 010. + * The 5 least significant bits will always be the X (column) address. The 8 bits from 5-12 represent the pixel Y: + *

+ * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * 0 1 0 Y7 Y6 Y2 Y1 Y0 Y5 Y4 Y3 X4 X3 X2 X1 X0 + *

+ * This method sets all X bits to 0, and then sets the Y bits according to the line number. + * + * @return array of offsets + */ + private static int[] computeLineOffsets() { final int[] result = new int[SCREEN_HEIGHT]; for (int y = 0; y < SCREEN_HEIGHT; y++) { result[y] = ((y & 0xC0) << 5) | ((y & 7) << 8) | ((y & 0x38) << 2); diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ZxParameters.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ZxParameters.java new file mode 100644 index 000000000..3cb97d078 --- /dev/null +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/ZxParameters.java @@ -0,0 +1,36 @@ +/* + * This file is part of emuStudio. + * + * Copyright (C) 2006-2024 Peter Jakubčo + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package net.emustudio.plugins.device.zxspectrum.ula; + +public class ZxParameters { + public static final int SCREEN_WIDTH = 32; // in bytes; each byte represents 8 pixels in a row, reversed + public static final int SCREEN_HEIGHT = 192; + public static final int ATTRIBUTE_HEIGHT = SCREEN_HEIGHT / 8; + + public static final int PRE_SCREEN_LINES = 64; + public static final int POST_SCREEN_LINES = 56; + public static final int BORDER_WIDTH = 48; // pixels + + public static final int SCREEN_IMAGE_WIDTH = 2 * BORDER_WIDTH + SCREEN_WIDTH * 8; + public static final int SCREEN_IMAGE_HEIGHT = PRE_SCREEN_LINES + SCREEN_HEIGHT + POST_SCREEN_LINES; + + // The Spectrum's 'FLASH' effect is also produced by the ULA: Every 16 frames, the ink and paper of all flashing + // bytes is swapped; ie a normal to inverted to normal cycle takes 32 frames, which is (good as) 0.64 seconds. + public static final int VIDEO_FLASH_FRAME = 15; +} diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayCanvas.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayCanvas.java index 53c2fca21..8880a7e80 100644 --- a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayCanvas.java +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayCanvas.java @@ -18,7 +18,6 @@ */ package net.emustudio.plugins.device.zxspectrum.ula.gui; -import net.emustudio.emulib.plugins.cpu.CPUContext; import net.emustudio.plugins.device.zxspectrum.ula.ULA; import java.awt.*; @@ -28,43 +27,11 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicBoolean; -import static net.emustudio.plugins.device.zxspectrum.ula.ULA.SCREEN_HEIGHT; -import static net.emustudio.plugins.device.zxspectrum.ula.ULA.SCREEN_WIDTH; +import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.*; import static net.emustudio.plugins.device.zxspectrum.ula.gui.DisplayWindow.MARGIN; -// https://worldofspectrum.org/faq/reference/48kreference.htm - -/** - * DisplayCanvas - *

- * A frame is (64+192+56)*224=69888 T states long, which means that the '50 Hz' interrupt is actually - * a 3.5MHz/69888=50.08 Hz interrupt. - */ -public class DisplayCanvas extends Canvas implements AutoCloseable, CPUContext.PassedCyclesListener { - private static final int PRE_SCREEN_LINES = 64; - private static final int POST_SCREEN_LINES = 56; - private static final int BORDER_WIDTH = 48; // pixels - +public class DisplayCanvas extends Canvas implements AutoCloseable { public static final float ZOOM = 2f; - public static final int SCREEN_IMAGE_WIDTH = 2 * BORDER_WIDTH + SCREEN_WIDTH * 8; - public static final int SCREEN_IMAGE_HEIGHT = PRE_SCREEN_LINES + SCREEN_HEIGHT + POST_SCREEN_LINES; - - private static final long FRAME_CPU_TSTATES = 69888; - private static final long LINE_CPU_TSTATES = 224; - - // After an interrupt occurs, 64 line times (14336 T states; see below for exact timings) pass before - // the first byte of the screen (16384) is displayed. At least the last 48 of these are actual - // border-lines; the others may be either border or vertical retrace. - // - //Then the 192 screen+border lines are displayed, followed by 56 border lines again. Note that this - // means that a frame is (64+192+56)*224=69888 T states long, which means that the '50 Hz' interrupt is actually - // a 3.5MHz/69888=50.08 Hz interrupt. This fact can be seen by taking a clock program, and running it for an hour, - // after which it will be the expected 6 seconds fast. However, on a real Spectrum, the frequency of the interrupt - // varies slightly as the Spectrum gets hot; the reason for this is unknown, but placing a cooler onto the ULA has - // been observed to remove this effect. - private long frameCycleCounter = 0; - private long lineCycleCounter = 0; - private int lastLinePainted = 0; private final BufferedImage screenImage = new BufferedImage( SCREEN_IMAGE_WIDTH, SCREEN_IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB); @@ -100,7 +67,6 @@ public class DisplayCanvas extends Canvas implements AutoCloseable, CPUContext.P public DisplayCanvas(ULA ula) { this.ula = Objects.requireNonNull(ula); - ula.getBus().addPassedCyclesListener(this); this.screenImage.setAccelerationPriority(1.0f); this.screenImageData = ((DataBufferInt) this.screenImage.getRaster().getDataBuffer()).getData(); } @@ -108,18 +74,14 @@ public DisplayCanvas(ULA ula) { public void start() { if (painting.compareAndSet(false, true)) { createBufferStrategy(2); - frameCycleCounter = 0; - lineCycleCounter = 0; - lastLinePainted = 0; } } - private void triggerCpuInterrupt() { - ula.triggerInterrupt(); + public void runPaintCycle() { paintCycle.run(); } - private void drawNextLine(int line) { + public void drawNextLine(int line) { int borderColor = COLOR_MAP[ula.getBorderColor()].getRGB(); if (line < PRE_SCREEN_LINES || line >= (PRE_SCREEN_LINES + SCREEN_HEIGHT)) { for (int i = 0; i < SCREEN_IMAGE_WIDTH; i++) { @@ -196,25 +158,6 @@ public void close() { painting.set(false); } - @Override - public void passedCycles(long tstates) { - if (painting.get()) { - frameCycleCounter += tstates; - lineCycleCounter += tstates; - - for (int i = 0; i < lineCycleCounter / LINE_CPU_TSTATES; i++) { - drawNextLine(lastLinePainted++); - } - lineCycleCounter = lineCycleCounter % LINE_CPU_TSTATES; - if (frameCycleCounter >= FRAME_CPU_TSTATES) { - lastLinePainted = 0; - triggerCpuInterrupt(); - ula.onNextFrame(); - frameCycleCounter = frameCycleCounter % FRAME_CPU_TSTATES; - } - } - } - public class PaintCycle implements Runnable { private BufferStrategy strategy; @@ -235,7 +178,6 @@ protected void paint() { try { do { do { - Graphics2D graphics = (Graphics2D) strategy.getDrawGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED); diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayWindow.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayWindow.java index a837bfd98..babd58519 100644 --- a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayWindow.java +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/DisplayWindow.java @@ -23,6 +23,9 @@ import javax.swing.*; import java.awt.event.WindowEvent; +import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.SCREEN_IMAGE_HEIGHT; +import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.SCREEN_IMAGE_WIDTH; + public class DisplayWindow extends JDialog { private final DisplayCanvas canvas; private final KeyboardCanvas keyboardCanvas; @@ -58,8 +61,8 @@ private void initComponents() { setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); canvas.setBounds( MARGIN, MARGIN, - (int) (DisplayCanvas.ZOOM * DisplayCanvas.SCREEN_IMAGE_WIDTH + 2 * MARGIN), - (int) (DisplayCanvas.ZOOM * DisplayCanvas.SCREEN_IMAGE_HEIGHT + 2 * MARGIN)); + (int) (DisplayCanvas.ZOOM * SCREEN_IMAGE_WIDTH + 2 * MARGIN), + (int) (DisplayCanvas.ZOOM * SCREEN_IMAGE_HEIGHT + 2 * MARGIN)); GroupLayout layout = new GroupLayout(getContentPane()); getContentPane().setLayout(layout); @@ -76,4 +79,8 @@ private void initComponents() { .addContainerGap())); pack(); } + + public DisplayCanvas getCanvas() { + return canvas; + } } diff --git a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/KeyboardCanvas.java b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/KeyboardCanvas.java index 20ac54b80..d09e36925 100644 --- a/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/KeyboardCanvas.java +++ b/plugins/device/zxspectrum-ula/src/main/java/net/emustudio/plugins/device/zxspectrum/ula/gui/KeyboardCanvas.java @@ -5,10 +5,13 @@ import java.awt.event.KeyEvent; import java.awt.font.GlyphVector; -import static net.emustudio.plugins.device.zxspectrum.ula.gui.DisplayCanvas.SCREEN_IMAGE_WIDTH; +import static net.emustudio.plugins.device.zxspectrum.ula.ZxParameters.SCREEN_IMAGE_WIDTH; import static net.emustudio.plugins.device.zxspectrum.ula.gui.DisplayCanvas.ZOOM; import static net.emustudio.plugins.device.zxspectrum.ula.gui.DisplayWindow.MARGIN; +/** + * Host-ZX Keyboard mapping visual representation. + */ public class KeyboardCanvas extends JComponent implements Keyboard.OnKeyListener { private final static int bw = 45; // button width private final static int bh = 33; // button height @@ -167,7 +170,6 @@ public void paint(Graphics g) { private void drawKeyboard(Graphics2D g) { BasicStroke stroke = new BasicStroke(2.0f); - // keyboard shape g.setStroke(stroke); g.drawRoundRect(X_SHIFT, 0, KEYBOARD_WIDTH, KEYBOARD_HEIGHT, arc, arc);