Skip to content

Add iOS SwiftUI emulator for TWSU DIY Gamer Kit#77

Open
Copilot wants to merge 8 commits into
mainfrom
copilot/create-ios-emulator-repo
Open

Add iOS SwiftUI emulator for TWSU DIY Gamer Kit#77
Copilot wants to merge 8 commits into
mainfrom
copilot/create-ios-emulator-repo

Conversation

Copilot AI commented Mar 8, 2026

Copy link
Copy Markdown
  • Fix SimonGame: guard simonStep >= maxSeq before sequence[simonStep] access — treats completing all 30 steps as an ultimate win (saves high score, plays win tune, resets) instead of crashing
  • Add AccentColor.colorset to Assets.xcassets — resolves asset catalog build failure caused by ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor referencing a missing color set

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: 28pins <262898015+28pins@users.noreply.github.com>
Copilot AI changed the title [WIP] Add iOS translation of gamer hardware emulator Add iOS SwiftUI emulator for TWSU DIY Gamer Kit Mar 8, 2026
@28pins 28pins marked this pull request as ready for review March 8, 2026 19:04
Copilot AI review requested due to automatic review settings March 8, 2026 19:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new iOS/iPadOS SwiftUI-based emulator for the TWSU DIY Gamer Kit, including a hardware abstraction layer and ports of the nine built-in games, all under ios/GamerEmulator/.

Changes:

  • Introduces SwiftUI app shell (launcher + views) and an @MainActor GamerHardware emulation layer (display/input/LED flash/sound/timing).
  • Ports nine games to Swift async game loops using await gamer.delay(...).
  • Adds Xcode project, assets catalog, and iOS-specific persistence (UserDefaults high scores).

Reviewed changes

Copilot reviewed 25 out of 25 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
ios/README.md Documents emulator features, build requirements, architecture, and controls.
ios/GamerEmulator/GamerEmulator/ContentView.swift SwiftUI app root that hosts the emulator UI.
ios/GamerEmulator/GamerEmulator/GamerEmulatorApp.swift App entry point + first-launch high-score initialization.
ios/GamerEmulator/GamerEmulator/Info.plist iOS app metadata and device/orientation configuration.
ios/GamerEmulator/GamerEmulator/Assets.xcassets/Contents.json Asset catalog root metadata.
ios/GamerEmulator/GamerEmulator/Assets.xcassets/AppIcon.appiconset/Contents.json App icon set metadata.
ios/GamerEmulator/GamerEmulator.xcodeproj/project.pbxproj Xcode project configuration and build settings.
ios/GamerEmulator/GamerEmulator/GameAssets/GameAssets.swift Ports bitmap frames, digit glyphs, and melody constants to Swift.
ios/GamerEmulator/GamerEmulator/Hardware/GamerHardware.swift Observable hardware emulation (display/input/LED flash/sound/timing helpers).
ios/GamerEmulator/GamerEmulator/Hardware/SoundEngine.swift AVAudioEngine-based tone generator matching OCR2A-derived pitch model.
ios/GamerEmulator/GamerEmulator/Persistence/HighScoreStore.swift UserDefaults-backed per-game high-score storage.
ios/GamerEmulator/GamerEmulator/Launcher/Launcher.swift Main launcher state machine + async tick loop + game task management.
ios/GamerEmulator/GamerEmulator/Games/GameProtocol.swift Defines the shared Game protocol used by all ports.
ios/GamerEmulator/GamerEmulator/Games/SnakeGame.swift Snake game port using async delay-based loop.
ios/GamerEmulator/GamerEmulator/Games/BreakoutGame.swift Breakout game port including physics and block propagation logic.
ios/GamerEmulator/GamerEmulator/Games/SimonGame.swift Simon game port with async playback/input waiting.
ios/GamerEmulator/GamerEmulator/Games/FlappyGame.swift Flappy game port with menu/game state and tick-based difficulty.
ios/GamerEmulator/GamerEmulator/Games/TetrisGame.swift Tetris port including rotation, line-clear animation, and melody playback.
ios/GamerEmulator/GamerEmulator/Games/AlienGame.swift Alien game port including shoot animation and falling rows.
ios/GamerEmulator/GamerEmulator/Games/ConwayGame.swift Conway’s Game of Life port + small-step preview support.
ios/GamerEmulator/GamerEmulator/Games/DinoGame.swift Dino runner port with obstacle types and jump/duck physics.
ios/GamerEmulator/GamerEmulator/Games/BrightnessGame.swift Brightness/settings screen port using gamer brightness/compensation flags.
ios/GamerEmulator/GamerEmulator/Views/ButtonsView.swift On-screen controls (D-pad, hardware buttons, cap-touch sound toggle).
ios/GamerEmulator/GamerEmulator/Views/MatrixDisplayView.swift SwiftUI renderer for the 8×8 LED matrix with brightness scaling.
ios/GamerEmulator/GamerEmulator/Views/GamerView.swift Composed emulator UI (status bar + matrix + controls).

Comment thread ios/GamerEmulator/GamerEmulator/Games/BreakoutGame.swift Outdated
Comment on lines +48 to +50
// Add a new item to the sequence
sequence[simonStep] = Int.random(in: 0..<Self.numDirs)

Copilot AI Mar 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sequence[simonStep] = ... will go out of bounds once simonStep reaches 30 (the array has 30 elements, indices 0–29). Since simonStep is incremented on success without a cap, the emulator can crash late-game. Clamp simonStep to maxSeq - 1 before indexing/incrementing (or end the game / treat completion as win when simonStep == maxSeq - 1).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5231605. Added a guard at the top of loop() that fires when simonStep >= maxSeq (i.e. the player completed all 30 steps): saves the high score, plays the win tune, shows the checkmark, then resets — no array access occurs. This covers the crash path where the success branch incremented simonStep to 30 between loop iterations.

Comment thread ios/GamerEmulator/GamerEmulator/Games/DinoGame.swift Outdated
Comment thread ios/GamerEmulator/GamerEmulator/Games/BrightnessGame.swift Outdated
Comment thread ios/GamerEmulator/GamerEmulator/Info.plist Outdated
Comment on lines +376 to +378
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;

Copilot AI Mar 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project build settings specify ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor, but Assets.xcassets in this PR does not include an AccentColor.colorset. This can cause asset catalog build failures or missing accent color at runtime. Either add an AccentColor color set to the asset catalog, or remove the build setting so the app uses the default SwiftUI accent.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 38c2f32. Added AccentColor.colorset/Contents.json to Assets.xcassets (universal, no custom color — uses the system default accent). The ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor build setting now resolves correctly and won't cause asset catalog build failures.

Comment on lines +88 to +102
if gamer.display[newX][ballY - velY] == 0 {
blocks[newX][ballY + velY] = 0
velY *= -1
} else {
blocks[ballX + velX][ballY + velY] = 0
velY *= -1; velX *= -1
}
}
} else {
if gamer.display[ballX - velX][newY] == 0 {
blocks[ballX + velX][newY] = 0
velX *= -1
if !(newY > -1 && newY < 8) {
if gamer.display[ballX + velX][ballY - velY] == 0 {
blocks[ballX - velX][ballY - velY] = 0

Copilot AI Mar 8, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newY is already known to be out of bounds in this branch, but the code writes blocks[newX][ballY + velY] / blocks[ballX + velX][ballY + velY]. In Swift this will crash when ballY + velY is -1 or 8 (same condition that made newY out of bounds). Add bounds checks (only write when both indices are 0..<8) or restructure the collision handling to avoid out-of-range indexing.

Suggested change
if gamer.display[newX][ballY - velY] == 0 {
blocks[newX][ballY + velY] = 0
velY *= -1
} else {
blocks[ballX + velX][ballY + velY] = 0
velY *= -1; velX *= -1
}
}
} else {
if gamer.display[ballX - velX][newY] == 0 {
blocks[ballX + velX][newY] = 0
velX *= -1
if !(newY > -1 && newY < 8) {
if gamer.display[ballX + velX][ballY - velY] == 0 {
blocks[ballX - velX][ballY - velY] = 0
let checkY = ballY - velY
if checkY >= 0 && checkY < 8 && gamer.display[newX][checkY] == 0 {
let targetY = ballY + velY
if targetY >= 0 && targetY < 8 {
blocks[newX][targetY] = 0
}
velY *= -1
} else {
let targetX = ballX + velX
let targetY = ballY + velY
if targetX >= 0 && targetX < 8 && targetY >= 0 && targetY < 8 {
blocks[targetX][targetY] = 0
}
velY *= -1; velX *= -1
}
}
} else {
let checkX = ballX - velX
if checkX >= 0 && checkX < 8 && newY >= 0 && newY < 8 && gamer.display[checkX][newY] == 0 {
let targetX = ballX + velX
if targetX >= 0 && targetX < 8 {
blocks[targetX][newY] = 0
}
velX *= -1
if !(newY > -1 && newY < 8) {
let dispX = ballX + velX
let dispY = ballY - velY
let blockX = ballX - velX
let blockY = ballY - velY
if dispX >= 0 && dispX < 8 && dispY >= 0 && dispY < 8 &&
blockX >= 0 && blockX < 8 && blockY >= 0 && blockY < 8 &&
gamer.display[dispX][dispY] == 0 {
blocks[blockX][blockY] = 0

Copilot uses AI. Check for mistakes.
28pins and others added 4 commits March 8, 2026 17:49
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: 28pins <262898015+28pins@users.noreply.github.com>
…log build

Co-authored-by: 28pins <262898015+28pins@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants