Skip to content

Commit

Permalink
[#314] Draft of cassette player + zx-spectrum-ula fixes
Browse files Browse the repository at this point in the history
+ emuStudio deps versions update
+ gradle 8.0.2
  • Loading branch information
vbmacher committed Apr 4, 2023
1 parent c11d070 commit 80839cb
Show file tree
Hide file tree
Showing 40 changed files with 1,462 additions and 97 deletions.
6 changes: 4 additions & 2 deletions application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ dependencies {
providedRuntime project(":plugins:device:vt100-terminal")
providedRuntime project(":plugins:device:simh-pseudo")
providedRuntime project(":plugins:device:ssem-display")
providedRuntime project(":plugins:device:zxspectrum-display")
providedRuntime project(":plugins:device:zxspectrum-ula")
providedRuntime project(":plugins:device:cassette-player")

testImplementation libs.junit
testImplementation libs.easyMock
Expand Down Expand Up @@ -217,7 +218,8 @@ distributions {
from(output(":plugins:device:vt100-terminal"))
from(output(":plugins:device:simh-pseudo"))
from(output(":plugins:device:ssem-display"))
from(output(":plugins:device:zxspectrum-display"))
from(output(":plugins:device:zxspectrum-ula"))
from(output(":plugins:device:cassette-player"))
}

// Examples
Expand Down
10 changes: 2 additions & 8 deletions application/src/main/files/config/ZxSpectrum48K.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@ name = "ZX Spectrum 48K"
#memorySize = 49152
banksCount = 0
ROMfrom0 = 0
imageName0 = "/home/vbmacher/tmp/emuStudio/z80full.out"
imageName1 = "/home/vbmacher/tmp/emuStudio/examples/zxspectrum-48k/48.rom"
imageAddress1 = 0
imageBank1 = 0
imageBank0 = 0
commonBoundary = 0
imageAddress0 = 32768
ROMto0 = 16383

# memorySize = 65536
Expand Down Expand Up @@ -59,9 +53,9 @@ name = "ZX Spectrum 48K"
# printCodeFileName = "syserr" # Or custom path to a file
[[DEVICE]]
schemaPoint = "380,180"
path = "zxspectrum-display.jar"
path = "zxspectrum-ula.jar"
settings = {}
name = "zxspectrum-display"
name = "zxspectrum-ula"
id = "1436ac2d-982f-4a52-b7c6-ecb6f2a0440d"
type = "DEVICE"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,26 @@ public Optional<Path> chooseFile(String title, String approveButtonText, Path ba
title, approveButtonText, baseDirectory, appendMissingExtension, filters.toArray(FileExtensionsFilter[]::new)
);
}

@Override
public Optional<Path> chooseDirectory(String title, String approveButtonText) {
return chooseDirectory(title, approveButtonText, Path.of(System.getProperty("user.dir")));
}

@Override
public Optional<Path> chooseDirectory(String title, String approveButtonText, Path baseDirectory) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle(title);
fileChooser.setAcceptAllFileFilterUsed(false);
fileChooser.setApproveButtonText(approveButtonText);
fileChooser.setCurrentDirectory(baseDirectory.toFile());
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

int result = fileChooser.showOpenDialog(parent);
fileChooser.setVisible(true);
if (result == JFileChooser.APPROVE_OPTION) {
return Optional.ofNullable(fileChooser.getSelectedFile()).map(File::toPath);
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,14 @@ public Optional<Path> chooseFile(String title, String approveButtonText, Path ba
boolean appendMissingExtension, List<FileExtensionsFilter> list) {
return Optional.empty();
}

@Override
public Optional<Path> chooseDirectory(String title, String approveButtonText) {
return Optional.empty();
}

@Override
public Optional<Path> chooseDirectory(String title, String approveButtonText, Path baseDirectory) {
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import java.util.function.Consumer;

import static net.emustudio.application.gui.debugtable.PaginatingDisassembler.INSTR_PER_PAGE;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

Expand Down
22 changes: 11 additions & 11 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,33 @@ import java.text.SimpleDateFormat
apply from: 'test_report.gradle'

ext.versions = [
slf4j: '2.0.6'
slf4j: '2.0.7'
]

ext.libs = [
emuLib : "net.emustudio:emulib:12.0.0",
emuLib : "net.emustudio:emulib:12.1.0-SNAPSHOT",
cpuTestSuite : "net.emustudio:cpu-testsuite_12.0:1.2.0",

jcipAnnotations : "net.jcip:jcip-annotations:1.0",
antlr : "org.antlr:antlr4:4.11.1",
antlrRuntime : "org.antlr:antlr4-runtime:4.11.1",
antlr : "org.antlr:antlr4:4.12.0",
antlrRuntime : "org.antlr:antlr4-runtime:4.12.0",

slf4JApi : "org.slf4j:slf4j-api:${versions.slf4j}",
slf4JSimple : "org.slf4j:slf4j-simple:${versions.slf4j}",
slf4JNop : "org.slf4j:slf4j-nop:${versions.slf4j}",
logback : "ch.qos.logback:logback-classic:1.4.5",
logback : "ch.qos.logback:logback-classic:1.4.6",

picocli : "info.picocli:picocli:4.7.0",
picocliAnnotation: "info.picocli:picocli-codegen:4.7.0",
picocli : "info.picocli:picocli:4.7.1",
picocliAnnotation: "info.picocli:picocli-codegen:4.7.1",

tomlj : "com.electronwill.night-config:toml:3.6.6",

editor : "com.fifesoft:rsyntaxtextarea:3.3.2",
editor : "com.fifesoft:rsyntaxtextarea:3.3.3",
editorDialogs : "com.fifesoft:rstaui:3.3.1",

junit : "junit:junit:4.13.1",
easyMock : "org.easymock:easymock:4.2",
mockito : "org.mockito:mockito-all:1.10.19"
junit : "junit:junit:4.13.2",
easyMock : "org.easymock:easymock:5.1.0",
mockito : "org.mockito:mockito-core:5.2.0"
]

allprojects {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class SioGui extends JDialog {
private final JLabel lblStatus = new JLabel("0x00");
private final JLabel lblStatusLong = new JLabel(". . . . . . . .");
private final JTextField txtAttachedDevice = new JTextField();

public SioGui(JFrame parent, UART uart) {
super(parent);

Expand Down
56 changes: 56 additions & 0 deletions plugins/device/cassette-player/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* This file is part of emuStudio.
*
* Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>.
*/

import org.apache.tools.ant.filters.ReplaceTokens

plugins {
id 'java'
id 'com.adarshr.test-logger' version '3.1.0'
}

dependencies {
implementation libs.emuLib
implementation libs.slf4JApi
implementation libs.jcipAnnotations
// cpuLib project(":plugins:cpu:8080-cpu")

testImplementation libs.junit
testImplementation libs.slf4JSimple
testImplementation libs.easyMock
}

jar {
archiveVersion = ''
manifest {
attributes manifestAttributes('')
}
}

processResources {
filesMatching("**/*.properties") {
filter ReplaceTokens, tokens: [
"project.version": project.version,
"today.year" : new Date().format("yyyy")
]
}
}

compileJava.options.encoding = 'UTF-8'
compileTestJava.options.encoding = 'UTF-8'
javadoc.options.encoding = 'UTF-8'
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* This file is part of emuStudio.
*
* Copyright (C) 2006-2023 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 <https://www.gnu.org/licenses/>.
*/
package net.emustudio.plugins.device.cassette_player;

import net.emustudio.plugins.device.cassette_player.loaders.Loader;
import net.jcip.annotations.GuardedBy;
import net.jcip.annotations.ThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

@ThreadSafe
public class CassetteController implements AutoCloseable {
private final static Logger LOGGER = LoggerFactory.getLogger(CassetteController.class);

public enum CassetteState {
UNLOADED,
PLAYING,
STOPPED,
CLOSED
}

private final Loader.CassetteListener listener;
private final ExecutorService playPool = Executors.newFixedThreadPool(1);

private final Object stateLock = new Object();
@GuardedBy("stateLock")
private CassetteState state = CassetteState.UNLOADED;
@GuardedBy("stateLock")
private Loader loader;
@GuardedBy("stateLock")
private Future<?> playFuture;

public CassetteController(Loader.CassetteListener listener) {
this.listener = Objects.requireNonNull(listener);
}

public CassetteState reset() {
return stop(true);
}

@Override
public void close() {
synchronized (stateLock) {
this.state = CassetteState.CLOSED;
Future<?> tmpFuture = this.playFuture;
this.playFuture = null;
if (tmpFuture != null) {
tmpFuture.cancel(true);
}
playPool.shutdown();
}
try {
if (!playPool.awaitTermination(5, TimeUnit.SECONDS)) {
playPool.shutdownNow();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

public CassetteState load(Path path) {
Optional<CassetteState> optResult = Loader.create(path).map(tmpLoader -> {
synchronized (stateLock) {
switch (state) {
case UNLOADED:
case STOPPED:
this.loader = tmpLoader;
this.state = CassetteState.STOPPED;
}
return this.state;
}
});
if (optResult.isPresent()) {
return optResult.get();
}
synchronized (stateLock) {
return this.state;
}
}

public CassetteState play() {
synchronized (stateLock) {
if (this.state == CassetteState.STOPPED) {
Loader tmpLoader = this.loader;
if (tmpLoader != null) {
this.state = CassetteState.PLAYING;
this.playFuture = playPool.submit(() -> {
try {
tmpLoader.load(listener);
} catch (IOException e) {
LOGGER.error("Could not load cassette", e);
Thread.currentThread().interrupt();
}
});
}
}
return this.state;
}
}

public CassetteState stop(boolean unload) {
synchronized (stateLock) {
if (this.state == CassetteState.PLAYING) {
Future<?> tmpFuture = this.playFuture;
this.playFuture = null;
if (tmpFuture != null) {
tmpFuture.cancel(true);
}
if (unload) {
this.loader = null;
this.state = CassetteState.UNLOADED;
} else {
this.state = CassetteState.STOPPED;
}
}
return this.state;
}
}
}
Loading

0 comments on commit 80839cb

Please sign in to comment.