mirror of
https://github.com/badvision/lawless-legends.git
synced 2025-01-18 04:33:00 +00:00
Tweaks to timing/speaker sound, visual sound debug feature added
This commit is contained in:
parent
4946dbd1e9
commit
24fd496d31
@ -52,6 +52,9 @@ public class Speaker extends Device {
|
||||
@ConfigurableField(category = "sound", name = "1mhz timing", description = "Force speaker output to 1mhz?")
|
||||
public static boolean force1mhz = true;
|
||||
|
||||
@ConfigurableField(category = "sound", name = "Show sound", description = "Use black color value to show sound output")
|
||||
public static boolean showSound = false;
|
||||
|
||||
@InvokableAction(category = "sound", name = "Record sound", description="Toggles recording (saving) sound output to a file", defaultKeyMapping = "ctrl+shift+w")
|
||||
public static void toggleFileOutput() {
|
||||
if (fileOutputActive) {
|
||||
@ -95,20 +98,23 @@ public class Speaker extends Device {
|
||||
*/
|
||||
@ConfigurableField(name = "Speaker Volume", shortName = "vol", description = "Should be under 1400")
|
||||
public static int VOLUME = 400;
|
||||
/**
|
||||
* Number of idle cycles until speaker playback is deactivated
|
||||
*/
|
||||
@ConfigurableField(name = "Idle cycles before sleep", shortName = "idle")
|
||||
public static int MAX_IDLE_CYCLES = 2000000;
|
||||
private int currentVolume = 0;
|
||||
private int fadeOffAmount = 1;
|
||||
/**
|
||||
* Manifestation of the apple speaker softswitch
|
||||
*/
|
||||
private boolean speakerBit = false;
|
||||
private double TICKS_PER_SAMPLE = ((double) TimedDevice.NTSC_1MHZ) / SoundMixer.RATE;
|
||||
private double TICKS_PER_SAMPLE_FLOOR = Math.floor(TICKS_PER_SAMPLE);
|
||||
private static double TICKS_PER_SAMPLE = ((double) TimedDevice.NTSC_1MHZ) / SoundMixer.RATE;
|
||||
private RAMListener listener = null;
|
||||
private SoundBuffer buffer = null;
|
||||
|
||||
/**
|
||||
* Number of idle cycles until speaker playback is deactivated
|
||||
*/
|
||||
@ConfigurableField(name = "Idle cycles before sleep", shortName = "idle")
|
||||
// public static int MAX_IDLE_CYCLES = (int) (SoundMixer.BUFFER_SIZE * TICKS_PER_SAMPLE * 2);
|
||||
public static int MAX_IDLE_CYCLES = (int) TimedDevice.NTSC_1MHZ / 4;
|
||||
|
||||
/**
|
||||
* Suspend playback of sound
|
||||
*
|
||||
@ -118,7 +124,6 @@ public class Speaker extends Device {
|
||||
public boolean suspend() {
|
||||
boolean result = super.suspend();
|
||||
speakerBit = false;
|
||||
Emulator.withComputer(c->c.getMotherboard().cancelSpeedRequest(this));
|
||||
if (buffer != null) {
|
||||
try {
|
||||
buffer.shutdown();
|
||||
@ -128,6 +133,7 @@ public class Speaker extends Device {
|
||||
buffer = null;
|
||||
}
|
||||
}
|
||||
Emulator.withComputer(c->c.getMotherboard().cancelSpeedRequest(this));
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -164,7 +170,6 @@ public class Speaker extends Device {
|
||||
} else {
|
||||
TICKS_PER_SAMPLE = Emulator.withComputer(c-> ((double) c.getMotherboard().getSpeedInHz()) / SoundMixer.RATE, 0.0);
|
||||
}
|
||||
TICKS_PER_SAMPLE_FLOOR = Math.floor(TICKS_PER_SAMPLE);
|
||||
super.resume();
|
||||
}
|
||||
|
||||
@ -172,9 +177,9 @@ public class Speaker extends Device {
|
||||
* Reset idle counter whenever sound playback occurs
|
||||
*/
|
||||
public void resetIdle() {
|
||||
currentVolume = VOLUME;
|
||||
idleCycles = 0;
|
||||
if (!isRunning()) {
|
||||
speakerBit = false;
|
||||
resume();
|
||||
}
|
||||
}
|
||||
@ -186,21 +191,32 @@ public class Speaker extends Device {
|
||||
*/
|
||||
@Override
|
||||
public void tick() {
|
||||
if (idleCycles++ >= MAX_IDLE_CYCLES) {
|
||||
suspend();
|
||||
}
|
||||
if (speakerBit) {
|
||||
level++;
|
||||
if (showSound) {
|
||||
VideoNTSC.CHANGE_BLACK_COLOR(40, 20, 20);
|
||||
}
|
||||
} else if (showSound) {
|
||||
VideoNTSC.CHANGE_BLACK_COLOR(20,20,40);
|
||||
}
|
||||
if (idleCycles++ >= MAX_IDLE_CYCLES && (currentVolume <= 0 || !speakerBit)) {
|
||||
suspend();
|
||||
if (showSound) {
|
||||
VideoNTSC.CHANGE_BLACK_COLOR(0,0,0);
|
||||
}
|
||||
}
|
||||
counter += 1.0d;
|
||||
if (counter >= TICKS_PER_SAMPLE) {
|
||||
playSample(level * VOLUME);
|
||||
Emulator.withComputer(c->c.getMotherboard().requestSpeed(this));
|
||||
if (idleCycles >= MAX_IDLE_CYCLES) {
|
||||
currentVolume -= fadeOffAmount;
|
||||
}
|
||||
playSample(level * currentVolume);
|
||||
// Emulator.withComputer(c->c.getMotherboard().requestSpeed(this));
|
||||
|
||||
// Set level back to 0
|
||||
level = 0;
|
||||
// Set counter to 0
|
||||
counter -= TICKS_PER_SAMPLE_FLOOR;
|
||||
counter -= TICKS_PER_SAMPLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,7 +640,7 @@ public class VideoDHGR extends Video {
|
||||
Logger.getLogger(getClass().getName()).warning("Went out of bounds in video display");
|
||||
}
|
||||
}
|
||||
static final Color BLACK = Color.BLACK;
|
||||
static Color BLACK = Color.BLACK;
|
||||
static Color WHITE = Color.WHITE;
|
||||
static final int[][] XY_OFFSET;
|
||||
|
||||
|
@ -27,6 +27,7 @@ import jace.config.InvokableAction;
|
||||
import jace.core.Computer;
|
||||
import jace.core.RAMEvent;
|
||||
import jace.core.RAMListener;
|
||||
import jace.core.Video;
|
||||
import javafx.scene.image.PixelWriter;
|
||||
import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.paint.Color;
|
||||
@ -331,6 +332,19 @@ public class VideoNTSC extends VideoDHGR {
|
||||
{1.0, 0.0, 0.0}, //1111 f
|
||||
};
|
||||
|
||||
public static void CHANGE_BLACK_COLOR(int r, int g, int b) {
|
||||
Emulator.withVideo(v->{
|
||||
VideoNTSC vntsc = (VideoNTSC) v;
|
||||
BLACK = Color.rgb(r, g, b);
|
||||
int c = colorToInt(BLACK);
|
||||
for (int i1 = 0; i1 < 4; i1++) {
|
||||
vntsc.SOLID_PALETTE[i1][0] = c;
|
||||
vntsc.TEXT_PALETTE[i1][0] = c;
|
||||
}
|
||||
});
|
||||
Video.forceRefresh();
|
||||
}
|
||||
|
||||
private void initDivideTables() {
|
||||
for (int i = 0; i < 560; i++) {
|
||||
divBy28[i] = i / 28;
|
||||
@ -361,10 +375,18 @@ public class VideoNTSC extends VideoDHGR {
|
||||
}
|
||||
|
||||
static public int yiqToRgb(double y, double i, double q) {
|
||||
return colorToInt(yiqToRgbColor(y, i, q));
|
||||
}
|
||||
|
||||
static public Color yiqToRgbColor(double y, double i, double q) {
|
||||
int r = (int) (normalize((y + 0.956 * i + 0.621 * q), 0, 1) * 255);
|
||||
int g = (int) (normalize((y - 0.272 * i - 0.647 * q), 0, 1) * 255);
|
||||
int b = (int) (normalize((y - 1.105 * i + 1.702 * q), 0, 1) * 255);
|
||||
return (255 << 24) | (r << 16) | (g << 8) | b;
|
||||
return Color.rgb(r, g, b);
|
||||
}
|
||||
|
||||
static public int colorToInt(Color c) {
|
||||
return (int) (255 << 24) | (int) (c.getRed() * 255) << 16 | (int) (c.getGreen() * 255) << 8 | (int) (c.getBlue() * 255);
|
||||
}
|
||||
|
||||
public static double normalize(double x, double minX, double maxX) {
|
||||
|
@ -188,6 +188,8 @@ public abstract class TimedDevice extends Device {
|
||||
return null;
|
||||
}
|
||||
cycleTimer = 0;
|
||||
long retVal = nextSync;
|
||||
nextSync = Math.max(nextSync, System.nanoTime()) + nanosPerInterval;
|
||||
if (isMaxSpeed() || useParentTiming()) {
|
||||
if (tempSpeedDuration > 0) {
|
||||
tempSpeedDuration -= cyclesPerInterval;
|
||||
@ -195,11 +197,8 @@ public abstract class TimedDevice extends Device {
|
||||
disableTempMaxSpeed();
|
||||
}
|
||||
}
|
||||
nextSync += nanosPerInterval;
|
||||
return null;
|
||||
}
|
||||
long retVal = nextSync;
|
||||
nextSync = Math.min(nextSync + nanosPerInterval, System.nanoTime() + nanosPerInterval * 2); // Avoid drift (but not too much!
|
||||
return retVal;
|
||||
}
|
||||
}
|
@ -274,7 +274,7 @@ public abstract class Video extends TimedDevice {
|
||||
Emulator.withVideo(v->v._forceRefresh());
|
||||
}
|
||||
|
||||
private void _forceRefresh() {
|
||||
protected void _forceRefresh() {
|
||||
lineDirty = true;
|
||||
screenDirty = true;
|
||||
forceRedrawRowCount = APPLE_SCREEN_LINES + 1;
|
||||
|
@ -426,7 +426,7 @@ public class CardAppleMouse extends Card {
|
||||
* Described in Apple Mouse technical note #7
|
||||
* Cn1A: Read mouse clamping values
|
||||
* Register number is stored in $478 and ranges from x47 to x4e
|
||||
* Return value should be stored in $5782
|
||||
* Return value should be stored in $578
|
||||
* Values should be returned in this order:
|
||||
* MinXH, MinYH, MinXL, MinYL, MaxXH, MaxYH, MaxXL, MaxYL
|
||||
*/
|
||||
|
@ -24,6 +24,7 @@ import jace.core.RAMListener;
|
||||
/**
|
||||
* Implements a basic hardware accelerator that is able to adjust the speed of the emulator
|
||||
*/
|
||||
// TODO: Support the registers used here: https://github.com/a2-4am/4cade/blob/main/src/hw.accel.a#L238
|
||||
public class ZipWarpAccelerator extends Device {
|
||||
@ConfigurableField(category = "debug", name = "Debug messages")
|
||||
public boolean debugMessagesEnabled = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user