From e2cbf2b37d51641ad787fdee26c5cd32387b3938 Mon Sep 17 00:00:00 2001 From: ml Date: Sun, 14 Jun 2026 08:15:33 +0200 Subject: [PATCH] Add Reset button, fix disk swap regression, and add sticky Shift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Reset button (left of Sound) ejects disk and power-cycles the C64 to BASIC without reloading — loadedADisks is cleared so episode buttons trigger autostart again on next press - A-side episode disks that were already loaded now hot-swap instead of resetting the machine; use Reset explicitly when a cold start is needed (fixes unintended reset when returning from hero disk) - Virtual keyboard Shift is now a toggle: tap SHF to lock shift on (key stays highlighted), tap again to release — no multi-touch required to type capital letters --- .../C64Engine.kt | 3 ++ .../C64KeyboardView.kt | 23 +++++++++--- .../MainActivity.kt | 25 +++++++++++-- .../app/src/main/jni/vice_jni.c | 35 ++++++++++++++++--- .../app/src/main/res/layout/activity_main.xml | 29 ++++++++++++--- 5 files changed, 98 insertions(+), 17 deletions(-) diff --git a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64Engine.kt b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64Engine.kt index 77f7d74..98952f0 100644 --- a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64Engine.kt +++ b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64Engine.kt @@ -25,6 +25,9 @@ class C64Engine { /** Hot-swap disk in drive 8 without resetting (use for B-side / hero disks). */ external fun attachDisk(path: String): Boolean + /** Eject the disk and hard-reset the C64 to a BASIC ready prompt. */ + external fun resetMachine(): Boolean + /** Run the emulator for one video frame (~20 000 CPU cycles). */ external fun runFrame() diff --git a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64KeyboardView.kt b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64KeyboardView.kt index dee4be0..54c6d48 100644 --- a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64KeyboardView.kt +++ b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/C64KeyboardView.kt @@ -91,6 +91,15 @@ class C64KeyboardView @JvmOverloads constructor( private val heldKeys = mutableMapOf() + /* Sticky Shift: tapping either SHF key toggles LSHIFT on/off. + * When true, the SHF keys are drawn highlighted and LSHIFT stays held. */ + private var shiftActive = false + private val lshiftKey = C64Key("SHF", C64Engine.KEY_LSHIFT) + + private fun isShiftKey(key: C64Key) = + key.codes.size == 1 && + (key.codes[0] == C64Engine.KEY_LSHIFT || key.codes[0] == C64Engine.KEY_RSHIFT) + private val keyPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.parseColor("#2C2C6C") } @@ -127,12 +136,12 @@ class C64KeyboardView @JvmOverloads constructor( override fun onDraw(canvas: Canvas) { val held = heldKeys.values.toSet() - // Scale text so it fits roughly in half the row height textPaint.textSize = (height / rows.size) * 0.38f for (row in keyRects) { for ((rect, key) in row) { - canvas.drawRoundRect(rect, 5f, 5f, if (key in held) pressedPaint else keyPaint) + val pressed = key in held || (shiftActive && isShiftKey(key)) + canvas.drawRoundRect(rect, 5f, 5f, if (pressed) pressedPaint else keyPaint) drawKeyLabel(canvas, rect, key.label) } } @@ -157,8 +166,14 @@ class C64KeyboardView @JvmOverloads constructor( when (event.actionMasked) { MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> { val key = keyAt(ex, ey) ?: return true - heldKeys[pid] = key - onKeyEvent?.invoke(key, true) + if (isShiftKey(key)) { + // Toggle sticky shift; always use LSHIFT so there's no phantom held key. + shiftActive = !shiftActive + onKeyEvent?.invoke(lshiftKey, shiftActive) + } else { + heldKeys[pid] = key + onKeyEvent?.invoke(key, true) + } invalidate() } MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP, diff --git a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt index 92eb505..10fdca8 100644 --- a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt +++ b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt @@ -80,6 +80,7 @@ class MainActivity : AppCompatActivity() { private val episodeButtons = mutableMapOf() private val loadedADisks = mutableSetOf() private var activeSlot: DiskSlot? = null + private var currentDiskPath: String? = null // path last passed to engine.loadDisk() // ---- Disk import (multi-select) ----------------------------------------- @@ -157,6 +158,18 @@ class MainActivity : AppCompatActivity() { btnSound.text = if (soundEnabled) "Sound: ON" else "Sound: OFF" } + val btnReset = findViewById