Replace bundled ROM extraction with runtime import/download flow
Commodore ROMs are copyrighted and can no longer ship inside the APK. MainActivity now detects missing ROMs on first launch and blocks startup with a dialog offering two paths: pick files via the system file picker, or download the official VICE 3.8 tarball and extract the four ROMs from it client-side (minimal USTAR reader, no extra deps). - Drop the extractViceRoms Gradle task and asset bundling; add res/extract_roms.sh for local sideloading during development instead - gitignore keystores/keystore.properties ahead of a signed release - Move architecture.md into docs/, refresh it for the screen-mirroring and watch-input additions, and add accompanying Mermaid diagrams - Add docs/debugging.md and docs/publish.md (Play Store release notes, ROM-import compliance rationale)
@@ -0,0 +1,16 @@
|
||||
graph TD
|
||||
Main["Main/UI thread<br/>Choreographer vsync loop, touch events"]
|
||||
Vice["VICE thread<br/>main_program() → maincpu_mainloop()"]
|
||||
Http["NanoHTTPD worker thread(s)<br/>one per request"]
|
||||
StdoutT["stdout reader thread"]
|
||||
StderrT["stderr reader thread"]
|
||||
Audio["OpenSL ES callback thread"]
|
||||
|
||||
Main -->|"captureFrame(): reads g_framebuf"| Vice
|
||||
Main -->|"injectKey(): writes keyboard matrix"| Vice
|
||||
Http -->|"onKey → injectWatchKey → injectKey"| Vice
|
||||
Http -->|"getScreenText(): reads C64 RAM"| Vice
|
||||
Vice -->|"writes g_framebuf, drains pending queues"| Main
|
||||
Vice -->|stdout/stderr pipes| StdoutT
|
||||
Vice -->|stdout/stderr pipes| StderrT
|
||||
Vice -->|sound ring buffer| Audio
|
||||
|
After Width: | Height: | Size: 178 KiB |
@@ -0,0 +1,11 @@
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant KB as C64KeyboardView
|
||||
participant Main as MainActivity
|
||||
participant JNI as vice_jni.c
|
||||
participant VICE as VICE keyboard matrix
|
||||
|
||||
User->>KB: touch down/up on key
|
||||
KB->>Main: onKeyEvent(key, pressed)
|
||||
Main->>JNI: engine.injectKey(code, pressed) (per code, for composites)
|
||||
JNI->>VICE: keyboard_set_keyarr(row, col, pressed)
|
||||
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,16 @@
|
||||
sequenceDiagram
|
||||
participant VICE as VICE thread
|
||||
participant JNI as vice_jni.c
|
||||
participant HTTP as NanoHTTPD /screen
|
||||
participant JS as PebbleKit JS
|
||||
participant Watch as Watch app (KEY_SCREEN)
|
||||
|
||||
loop every 1s
|
||||
JS->>HTTP: GET /screen
|
||||
HTTP->>JNI: getScreenText()
|
||||
JNI->>VICE: mem_read_screen($0400..$07E7)
|
||||
JNI-->>HTTP: UTF-8 text (40x25, \n per row)
|
||||
HTTP-->>JS: {"text": "..."}
|
||||
JS->>Watch: AppMessage KEY_SCREEN
|
||||
Watch->>Watch: update ScrollLayer/TextLayer
|
||||
end
|
||||
|
After Width: | Height: | Size: 114 KiB |
@@ -0,0 +1,15 @@
|
||||
sequenceDiagram
|
||||
participant UI as MainActivity (save/load button)
|
||||
participant Pending as g_pending_save_state / g_pending_load_state
|
||||
participant Refresh as video_canvas_refresh (VICE thread)
|
||||
participant Trap as interrupt_maincpu_trigger_trap
|
||||
participant CPU as 6510core.c DO_INTERRUPT(IK_TRAP)
|
||||
|
||||
UI->>Pending: saveState(path) / loadState(path) [mutex-guarded]
|
||||
Refresh->>Pending: drain pending path next frame
|
||||
Refresh->>Trap: schedule save_state_trap / load_state_trap
|
||||
CPU->>CPU: EXPORT_REGISTERS()
|
||||
CPU->>Trap: run trap function
|
||||
Trap->>Trap: machine_write_snapshot() / machine_read_snapshot()
|
||||
CPU->>CPU: IMPORT_REGISTERS()
|
||||
Note over CPU: reg_pc now matches the saved/restored maincpu_regs.pc
|
||||
|
After Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,21 @@
|
||||
graph LR
|
||||
subgraph Watch["Pebble Time 2 (watch)"]
|
||||
WatchC["Watch app (C)<br/>splash / main / wheel windows"]
|
||||
end
|
||||
|
||||
subgraph Phone["Android phone"]
|
||||
CFP["Core for Pebble<br/>(PebbleKit JS runtime, separate app)"]
|
||||
|
||||
subgraph Companion["Companion app process"]
|
||||
HTTP["NanoHTTPD server :8888"]
|
||||
UI["MainActivity / UI<br/>C64DisplayView, C64KeyboardView"]
|
||||
JNI["JNI bridge<br/>vice_jni.c"]
|
||||
VICE["VICE C64 core<br/>(own pthread)"]
|
||||
end
|
||||
end
|
||||
|
||||
WatchC <-->|Bluetooth AppMessage| CFP
|
||||
CFP <-->|HTTP loopback 127.0.0.1:8888| HTTP
|
||||
HTTP --> UI
|
||||
UI --> JNI
|
||||
JNI <--> VICE
|
||||
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,15 @@
|
||||
sequenceDiagram
|
||||
participant Watch
|
||||
participant JS as PebbleKit JS
|
||||
participant HTTP as NanoHTTPD /key
|
||||
participant Main as MainActivity
|
||||
participant JNI as vice_jni.c
|
||||
|
||||
Watch->>Watch: SELECT opens wheel, UP/DOWN rotate, SELECT confirms
|
||||
Watch->>JS: AppMessage KEY_COMMAND = "LABEL"
|
||||
JS->>HTTP: GET /key?cmd=LABEL
|
||||
HTTP->>Main: onKey(cmd)
|
||||
Main->>Main: watchKeyMap[cmd] → codes
|
||||
Main->>JNI: injectKey(code, true) for each code
|
||||
Main->>Main: postDelayed 80ms
|
||||
Main->>JNI: injectKey(code, false) for each code
|
||||
|
After Width: | Height: | Size: 92 KiB |
@@ -0,0 +1,5 @@
|
||||
stateDiagram-v2
|
||||
[*] --> Splash
|
||||
Splash --> Main: 1800ms timer\n(window_stack_remove splash)
|
||||
Main --> Wheel: SELECT\n(push wheel)
|
||||
Wheel --> Main: SELECT (send + pop)\nor BACK (cancel, pop)
|
||||
|
After Width: | Height: | Size: 79 KiB |