Skip to content

Commit 74cfbb8

Browse files
author
Federico Berti
committed
mcd: show leds activity in UI
1 parent b15dbbb commit 74cfbb8

19 files changed

+160
-99
lines changed

res/icon/mcd_leds/mcd-leds.png

339 Bytes
Loading

res/icon/mcd_leds/mcd-leds_00.png

888 Bytes
Loading

res/icon/mcd_leds/mcd-leds_01.png

907 Bytes
Loading

res/icon/mcd_leds/mcd-leds_10.png

913 Bytes
Loading

res/icon/mcd_leds/mcd-leds_11.png

910 Bytes
Loading

src/main/java/mcd/MegaCd.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import s32x.util.Md32xRuntimeData;
5252

5353
import java.nio.file.Path;
54+
import java.util.Optional;
5455

5556
import static omegadrive.util.BufferUtil.CpuDeviceAccess.*;
5657
import static omegadrive.util.Util.GEN_NTSC_MCLOCK_MHZ;
@@ -221,20 +222,20 @@ protected final void runFM() {
221222
}
222223
@Override
223224
protected void updateVideoMode(boolean force) {
224-
if (force || videoMode != vdp.getVideoMode()) {
225-
videoMode = vdp.getVideoMode();
225+
if (force || displayContext.videoMode != vdp.getVideoMode()) {
226+
displayContext.videoMode = vdp.getVideoMode();
226227
double microsPerTick = getMicrosPerTick();
227228
sound.getFm().setMicrosPerTick(microsPerTick);
228229
targetNs = (long) (getRegion().getFrameIntervalMs() * Util.MILLI_IN_NS);
229-
mcd68kRatio = videoMode.isPal() ? MCD_68K_RATIO_PAL : MCD_68K_RATIO_NTSC;
230-
mcdLaunchContext.pcm.updateVideoMode(videoMode);
231-
mcdLaunchContext.cdd.updateVideoMode(videoMode);
232-
LOG.info("Video mode changed: {}, mcd68kRatio: {}, microsPerTick: {}", videoMode, mcd68kRatio, microsPerTick);
230+
mcd68kRatio = displayContext.videoMode.isPal() ? MCD_68K_RATIO_PAL : MCD_68K_RATIO_NTSC;
231+
mcdLaunchContext.pcm.updateVideoMode(displayContext.videoMode);
232+
mcdLaunchContext.cdd.updateVideoMode(displayContext.videoMode);
233+
LOG.info("Video mode changed: {}, mcd68kRatio: {}, microsPerTick: {}", displayContext.videoMode, mcd68kRatio, microsPerTick);
233234
}
234235
}
235236

236237
private double getMicrosPerTick() {
237-
double mclkhz = videoMode.isPal() ? GEN_PAL_MCLOCK_MHZ : GEN_NTSC_MCLOCK_MHZ;
238+
double mclkhz = displayContext.videoMode.isPal() ? GEN_PAL_MCLOCK_MHZ : GEN_NTSC_MCLOCK_MHZ;
238239
return 1_000_000.0 / (mclkhz / (FM_DIVIDER * MCLK_DIVIDER));
239240
}
240241

@@ -255,6 +256,7 @@ public void newFrame() {
255256
memView.update();
256257
mcdLaunchContext.pcm.newFrame();
257258
mcdLaunchContext.cdd.newFrame();
259+
displayContext.megaCdLedState = Optional.of(mcdLaunchContext.subBus.getLedState());
258260
super.newFrame();
259261
}
260262

@@ -273,7 +275,7 @@ protected void resetCycleCounters(int counter) {
273275
if ((getFrameCounter() + 1) % 60 == 0) {
274276
boolean rangeOk = Math.abs(MCD_SUB_68K_CLOCK_MHZ - subCnt) < 250_000; //250Khz slack
275277
if (!rangeOk) {
276-
logTimingWarn(LOG, "SubCpu timing off!!!, 68K clock: {}, mode: {}", videoMode);
278+
logTimingWarn(LOG, "SubCpu timing off!!!, 68K clock: {}, mode: {}", subCnt, displayContext.videoMode);
277279
}
278280
subCnt = 0;
279281
}
@@ -345,7 +347,7 @@ protected void handleSoftReset() {
345347
}
346348

347349
private void logTimingWarn(Logger log, String str, Object... pars) {
348-
if (videoMode.isPal()) {
350+
if (displayContext.videoMode.isPal()) {
349351
//known issue, warn once
350352
LogHelper.logWarnOnce(log, str, pars);
351353
} else {

src/main/java/mcd/bus/MegaCdSubCpuBus.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
import static omegadrive.cpu.m68k.M68kProvider.MD_PC_MASK;
3838
import static omegadrive.util.BufferUtil.*;
3939
import static omegadrive.util.BufferUtil.CpuDeviceAccess.M68K;
40-
import static omegadrive.util.Util.getBitFromWord;
41-
import static omegadrive.util.Util.th;
40+
import static omegadrive.util.BufferUtil.CpuDeviceAccess.SUB_M68K;
41+
import static omegadrive.util.Util.*;
4242

4343
/**
4444
* Federico Berti
@@ -506,11 +506,15 @@ private void releaseSubCpuReset() {
506506
subCpu.reset();
507507
resetDone();
508508
//get SBRQ from main
509-
int bval = readBuffer(memCtx.getGateSysRegs(M68K), MCD_RESET.addr + 1, Size.BYTE);
509+
int bval = readBufferByte(memCtx.getGateSysRegs(M68K), MCD_RESET.addr + 1);
510510
int sbusreq = (bval >> 1) & 1;
511511
subCpu.setStop(sbusreq > 0);
512512
}
513513

514+
public int getLedState() {
515+
return readBufferByte(memCtx.getGateSysRegs(SUB_M68K), MCD_RESET.addr) & 3;
516+
}
517+
514518
public void softReset() {
515519
/* RESET register always return 1 */
516520
writeReg(memCtx, cpuType, MCD_RESET, MCD_RESET.addr + 1, 1, Size.BYTE);

src/main/java/omegadrive/system/BaseSystem.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public abstract class BaseSystem<BUS extends BaseBusProvider> implements
7070
protected Future<Void> runningRomFuture;
7171
protected DisplayWindow emuFrame;
7272

73+
protected DisplayWindow.DisplayContext displayContext;
74+
7375
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
7476

7577
protected volatile boolean saveStateFlag = false;
@@ -89,7 +91,6 @@ public abstract class BaseSystem<BUS extends BaseBusProvider> implements
8991
protected long elapsedWaitNs, frameProcessingDelayNs;
9092
protected long targetNs, startNs = 0;
9193
private long driftNs = 0;
92-
private Optional<String> stats = Optional.empty();
9394

9495
private final CyclicBarrier pauseBarrier = new CyclicBarrier(2);
9596

@@ -102,6 +103,9 @@ public abstract class BaseSystem<BUS extends BaseBusProvider> implements
102103
@Override
103104
public void init() {
104105
sound = AbstractSoundManager.createSoundProvider(systemType);
106+
displayContext = new DisplayWindow.DisplayContext();
107+
displayContext.megaCdLedState = Optional.empty();
108+
displayContext.videoMode = VideoMode.PAL_H40_V30;
105109
}
106110

107111
protected void initAfterRomLoad() {
@@ -265,12 +269,11 @@ protected void pauseAndWait() {
265269
}
266270
}
267271

268-
protected Optional<String> getStats(long nowNs, long prevStartNs) {
272+
protected void getStats(long nowNs, long prevStartNs) {
269273
if (!SystemLoader.showFps) {
270-
return Optional.empty();
274+
return;
271275
}
272276
telemetry.newFrame(nowNs - prevStartNs, driftNs).ifPresent(statsConsumer);
273-
return stats;
274277
}
275278

276279
protected long syncCycle(long startCycle) {
@@ -336,7 +339,8 @@ public void newFrame() {
336339
elapsedWaitNs = syncCycle(startNs) - startWaitNs;
337340
startNs = System.nanoTime();
338341
updateVideoMode(false);
339-
doRendering(videoMode, vdp.getScreenDataLinear(), getStats(startNs, prevStartNs));
342+
getStats(startNs, prevStartNs);
343+
doRendering(vdp.getScreenDataLinear());
340344
frameProcessingDelayNs = startNs - startWaitNs - elapsedWaitNs;
341345
handleVdpDumpScreenData();
342346
processSaveState();
@@ -350,7 +354,7 @@ public void newFrame() {
350354
// LOG.info("{}, {}", elapsedWaitNs, frameProcessingDelayNs);
351355
}
352356

353-
final Consumer<String> statsConsumer = st -> stats = Optional.of(st);
357+
final Consumer<String> statsConsumer = st -> displayContext.label = Optional.of(st);
354358

355359
class RomRunnable implements Runnable {
356360
private final RomSpec romSpec;
@@ -402,8 +406,9 @@ protected void handleVdpDumpScreenData() {
402406
}
403407
}
404408

405-
protected void doRendering(VideoMode videoMode, int[] data, Optional<String> label) {
406-
emuFrame.renderScreenLinear(data, label, videoMode);
409+
protected void doRendering(int[] data) {
410+
displayContext.data = data;
411+
emuFrame.renderScreenLinear(displayContext);
407412
}
408413

409414
private void handlePause() {

src/main/java/omegadrive/system/Genesis.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,17 +195,17 @@ protected GenesisBusProvider createBus() {
195195

196196
@Override
197197
protected void updateVideoMode(boolean force) {
198-
if (force || videoMode != vdp.getVideoMode()) {
199-
videoMode = vdp.getVideoMode();
198+
if (force || displayContext.videoMode != vdp.getVideoMode()) {
199+
displayContext.videoMode = vdp.getVideoMode();
200200
double microsPerTick = getMicrosPerTick();
201201
sound.getFm().setMicrosPerTick(microsPerTick);
202202
targetNs = (long) (getRegion().getFrameIntervalMs() * Util.MILLI_IN_NS);
203-
LOG.info("Video mode changed: {}, microsPerTick: {}", videoMode, microsPerTick);
203+
LOG.info("Video mode changed: {}, microsPerTick: {}", displayContext.videoMode, microsPerTick);
204204
}
205205
}
206206

207207
private double getMicrosPerTick() {
208-
double mclkhz = videoMode.isPal() ? Util.GEN_PAL_MCLOCK_MHZ : Util.GEN_NTSC_MCLOCK_MHZ;
208+
double mclkhz = displayContext.videoMode.isPal() ? Util.GEN_PAL_MCLOCK_MHZ : Util.GEN_NTSC_MCLOCK_MHZ;
209209
return 1_000_000.0 / (mclkhz / (FM_DIVIDER * MCLK_DIVIDER));
210210
}
211211

src/main/java/omegadrive/system/Megadrive.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,17 @@ protected GenesisBusProvider createBus() {
186186

187187
@Override
188188
protected void updateVideoMode(boolean force) {
189-
if (force || videoMode != vdp.getVideoMode()) {
190-
videoMode = vdp.getVideoMode();
189+
if (force || displayContext.videoMode != vdp.getVideoMode()) {
190+
displayContext.videoMode = vdp.getVideoMode();
191191
double microsPerTick = getMicrosPerTick();
192192
sound.getFm().setMicrosPerTick(microsPerTick);
193193
targetNs = (long) (getRegion().getFrameIntervalMs() * Util.MILLI_IN_NS);
194-
LOG.info("Video mode changed: {}, microsPerTick: {}", videoMode, microsPerTick);
194+
LOG.info("Video mode changed: {}, microsPerTick: {}", displayContext.videoMode, microsPerTick);
195195
}
196196
}
197197

198198
private double getMicrosPerTick() {
199-
double mclkhz = videoMode.isPal() ? Util.GEN_PAL_MCLOCK_MHZ : Util.GEN_NTSC_MCLOCK_MHZ;
199+
double mclkhz = displayContext.videoMode.isPal() ? Util.GEN_PAL_MCLOCK_MHZ : Util.GEN_NTSC_MCLOCK_MHZ;
200200
return 1_000_000.0 / (mclkhz / (FM_DIVIDER * MCLK_DIVIDER));
201201
}
202202

src/main/java/omegadrive/system/Sms.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ protected void loop() {
100100

101101
@Override
102102
protected void updateVideoMode(boolean force) {
103-
videoMode = vdp.getVideoMode();
103+
displayContext.videoMode = vdp.getVideoMode();
104104
}
105105

106106
@Override

src/main/java/omegadrive/system/Z80BaseSystem.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ protected void resetCycleCounters(int counter) {
125125
@Override
126126
protected void updateVideoMode(boolean force) {
127127
VideoMode vm = vdp.getVideoMode();
128-
if (force || videoMode != vm) {
128+
if (force || displayContext.videoMode != vm) {
129129
LOG.info("Video mode changed: {}", vm);
130-
videoMode = vm;
130+
displayContext.videoMode = vm;
131131
}
132132
}
133133

src/main/java/omegadrive/system/gb/Gb.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ protected void resetCycleCounters(int counter) {
116116

117117
@Override
118118
protected void updateVideoMode(boolean force) {
119-
videoMode = vdp.getVideoMode();
119+
displayContext.videoMode = vdp.getVideoMode();
120120
}
121121

122122
@Override

src/main/java/omegadrive/system/nes/Nes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void init() {
8383
@Override
8484
protected void loop() {
8585
targetNs = (long) (getRegion().getFrameIntervalMs() * Util.MILLI_IN_NS);
86-
videoMode = vdp.getVideoMode();
86+
displayContext.videoMode = vdp.getVideoMode();
8787
gui = NesHelper.createNes(getRomPath(), this, (AudioOutInterface) sound.getFm());
8888
vdp = gui.getVdpProvider();
8989
gui.run(); //blocking
@@ -108,6 +108,6 @@ protected void resetCycleCounters(int counter) {
108108

109109
@Override
110110
protected void updateVideoMode(boolean force) {
111-
videoMode = vdp.getVideoMode();
111+
displayContext.videoMode = vdp.getVideoMode();
112112
}
113113
}

src/main/java/omegadrive/ui/DisplayWindow.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@ public interface DisplayWindow {
3737
int SHOW_INFO_FRAMES_DELAY = 120; //~2sec
3838

3939

40+
class DisplayContext {
41+
public int[] data;
42+
public VideoMode videoMode;
43+
public Optional<String> label;
44+
public Optional<Integer> megaCdLedState;
45+
}
46+
47+
4048
DisplayWindow HEADLESS_INSTANCE = new DisplayWindow() {
4149
@Override
4250
public void addKeyListener(KeyListener keyAdapter) {
@@ -54,7 +62,7 @@ public void init() {
5462
}
5563

5664
@Override
57-
public void renderScreenLinear(int[] data, Optional<String> label, VideoMode videoMode) {
65+
public void renderScreenLinear(DisplayContext displayContext) {
5866

5967
}
6068

@@ -83,7 +91,7 @@ public void reloadSystem(SystemProvider systemProvider) {
8391

8492
void init();
8593

86-
void renderScreenLinear(int[] data, Optional<String> label, VideoMode videoMode);
94+
void renderScreenLinear(DisplayContext displayContext);
8795

8896
void resetScreen();
8997

src/main/java/omegadrive/ui/SwingWindow.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import omegadrive.system.SysUtil.RomSpec;
2929
import omegadrive.system.SystemProvider;
3030
import omegadrive.ui.flatlaf.FlatLafHelper;
31-
import omegadrive.ui.util.CountryFlagsLoader;
31+
import omegadrive.ui.util.IconsLoader;
3232
import omegadrive.ui.util.UiFileFilters;
3333
import omegadrive.ui.util.UiFileFilters.FileResourceType;
3434
import omegadrive.util.*;
@@ -88,6 +88,7 @@ public class SwingWindow implements DisplayWindow {
8888
private final JLabel screenLabel = new JLabel();
8989
private final JLabel perfLabel = new JLabel("");
9090
private final JLabel regionLabel = new JLabel("");
91+
private final JLabel megaCdLedLabel = new JLabel("");
9192

9293
private JFrame jFrame;
9394
private SystemProvider mainEmu;
@@ -129,11 +130,14 @@ public void setRomData(RomContext rom) {
129130
}
130131
jFrame.setTitle(APP_NAME + mainEmu.getSystemType().getShortName() + " " + VERSION + " - " +
131132
FileUtil.getFileName(romContext.romSpec.file));
132-
Icon icon = CountryFlagsLoader.getRegionIcon(romContext.region);
133+
Icon icon = IconsLoader.getRegionIcon(romContext.region);
133134
regionLabel.setIcon(icon);
134135
regionLabel.setText(icon == null ? romContext.region.name() : "");
135136
regionLabel.setToolTipText(romContext.region.name());
136137
reloadRecentFiles();
138+
if (mainEmu.getSystemType() == SystemType.MEGACD) {
139+
megaCdLedLabel.setIcon(IconsLoader.getLedIcon(0));
140+
}
137141
}
138142

139143
private void addKeyAction(AbstractButton component, SystemEvent event, ActionListener l) {
@@ -209,6 +213,7 @@ public void resetScreen() {
209213
perfLabel.setText("");
210214
regionLabel.setIcon(null);
211215
regionLabel.setText("");
216+
megaCdLedLabel.setIcon(null);
212217
jFrame.setTitle(FRAME_TITLE_HEAD);
213218
cursorHandler.reset();
214219
LOG.info("Blanking screen");
@@ -231,18 +236,23 @@ public String getRegionOverride() {
231236

232237
private Future<?> previousFrame = CompletableFuture.completedFuture(null);
233238

239+
private DisplayContext dcCopy = new DisplayContext();
240+
234241
//NOTE: this will copy the input array
235242
@Override
236-
public void renderScreenLinear(int[] data, Optional<String> label, VideoMode videoMode) {
237-
if (data.length != pixelsSrc.length) {
238-
pixelsSrc = data.clone();
243+
public void renderScreenLinear(DisplayContext dc) {
244+
if (dc.data.length != pixelsSrc.length) {
245+
pixelsSrc = dc.data.clone();
239246
}
240-
System.arraycopy(data, 0, pixelsSrc, 0, data.length);
247+
System.arraycopy(dc.data, 0, pixelsSrc, 0, dc.data.length);
241248
if (UI_SCALE_ON_THREAD) {
242249
assert checkSlowDown();
243-
previousFrame = executorService.submit(() -> renderScreenLinearInternal(pixelsSrc, label, videoMode));
250+
dcCopy.megaCdLedState = dc.megaCdLedState;
251+
dcCopy.label = dc.label;
252+
dcCopy.videoMode = dc.videoMode;
253+
previousFrame = executorService.submit(() -> renderScreenLinearInternal(pixelsSrc, dcCopy));
244254
} else {
245-
renderScreenLinearInternal(pixelsSrc, label, videoMode);
255+
renderScreenLinearInternal(pixelsSrc, dc);
246256
}
247257
}
248258

@@ -338,6 +348,7 @@ public void init() {
338348
bar.add(Box.createHorizontalGlue());
339349
bar.add(perfLabel);
340350
bar.add(Box.createHorizontalGlue());
351+
bar.add(megaCdLedLabel);
341352
bar.add(regionLabel);
342353

343354
JMenuItem loadRomItem = new JMenuItem("Load ROM");
@@ -431,10 +442,11 @@ public void init() {
431442
showDebugInfo(SystemLoader.showFps);
432443
}
433444

434-
private void renderScreenLinearInternal(int[] data, Optional<String> label, VideoMode videoMode) {
435-
resizeScreen(videoMode);
445+
private void renderScreenLinearInternal(int[] data, DisplayContext dc) {
446+
resizeScreen(dc.videoMode);
436447
RenderingStrategy.renderNearest(data, pixelsDest, nativeScreenSize, outputScreenSize);
437-
label.ifPresent(this::showLabel);
448+
dc.label.ifPresent(this::showLabel);
449+
dc.megaCdLedState.ifPresent(v -> megaCdLedLabel.setIcon(IconsLoader.getLedIcon(v)));
438450
screenLabel.repaint();
439451
detectUserScreenChange();
440452
cursorHandler.newFrame();

0 commit comments

Comments
 (0)