From 755e7758e4a48040151818557229bd9d2917a598 Mon Sep 17 00:00:00 2001 From: ml Date: Sun, 14 Jun 2026 09:46:17 +0200 Subject: [PATCH] Add hero save editor with D64 format documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pencil button next to each hero disk opens an editor dialog that parses the D64 directly, lists all PRG save files in a spinner, and lets the user adjust all nine stats (Vitalität, grade, six percentage stats) with +/− buttons. Changes to multiple heroes in one session are written back together on Save. PETSCII decoding now distinguishes unshifted (0x41–0x5A → lowercase) from shifted (0xC1–0xDA → uppercase) so names display in natural mixed case (e.g. "Mark" instead of "MARK"). D64 sector layout helpers extracted to class level so createBlankD64 and the new editor share the same offset function. Save format documented in res/HELD_D64_FORMAT.md. Editor strings localised in EN/DE. --- .../MainActivity.kt | 249 ++++++++++++++++-- .../app/src/main/res/layout/activity_main.xml | 12 + .../app/src/main/res/values-de/strings.xml | 6 + .../app/src/main/res/values/strings.xml | 6 + .../res/hero_save_analysis.zip | Bin 0 -> 272452 bytes 5 files changed, 251 insertions(+), 22 deletions(-) create mode 100644 SchwertUndMagieOnPebbleCompanionApp/res/hero_save_analysis.zip 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 d422633..326f3c0 100644 --- a/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt +++ b/SchwertUndMagieOnPebbleCompanionApp/app/src/main/java/de/ladkau/schwertundmagieonpebblecompanionapp/MainActivity.kt @@ -12,9 +12,12 @@ import android.content.res.ColorStateList import android.graphics.Color import android.graphics.drawable.GradientDrawable import android.view.Choreographer +import android.widget.AdapterView +import android.widget.ArrayAdapter import android.widget.Button import android.widget.ImageView import android.widget.ScrollView +import android.widget.Spinner import android.widget.TextView import android.widget.Toast import androidx.activity.result.ActivityResultLauncher @@ -64,6 +67,24 @@ class MainActivity : AppCompatActivity() { // ---- disk slots --------------------------------------------------------- + // ---- D64 helpers (shared by createBlankD64 and the hero editor) ---------- + + private val d64Spt = intArrayOf( + 0, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 19, 19, 19, 19, 19, 19, 19, + 18, 18, 18, 18, 18, 18, + 17, 17, 17, 17, 17 + ) + + private fun d64Off(track: Int, sector: Int): Int { + var off = 0 + for (t in 1 until track) off += d64Spt[t] * 256 + return off + sector * 256 + } + + // ---- disk slots --------------------------------------------------------- + private val diskSlots = listOf( DiskSlot(1, 'A', R.id.btn_ep_1a, "Folge 1: Das geheimnisvolle Kraut"), DiskSlot(1, 'B', R.id.btn_ep_1b, "Folge 2: Der unheimliche Tempel"), @@ -77,8 +98,9 @@ class MainActivity : AppCompatActivity() { DiskSlot(0, ' ', R.id.btn_hero_2, "Held 2", "HELD2.D64"), DiskSlot(0, ' ', R.id.btn_hero_3, "Held 3", "HELD3.D64"), ) - private val episodeButtons = mutableMapOf() - private val loadedADisks = mutableSetOf() + private val episodeButtons = mutableMapOf() + private val heroEditButtons = mutableMapOf() + private val loadedADisks = mutableSetOf() private var activeSlot: DiskSlot? = null private var currentDiskPath: String? = null // path last passed to engine.loadDisk() @@ -187,6 +209,17 @@ class MainActivity : AppCompatActivity() { findViewById