Skip to content

Commit f80b153

Browse files
fix: address Copilot review — DS touch tracking, normalization, outputFrame handling
1 parent 2df8d98 commit f80b153

File tree

3 files changed

+54
-24
lines changed

3 files changed

+54
-24
lines changed

Cores/Desmume2015/PVDesmume2015Core/Core/PVDesmume2015Core+Controls.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,10 @@ - (void)didRelease:(NSInteger)button forPlayer:(NSInteger)player {
287287
#pragma mark - DS Touchscreen
288288

289289
- (void)touchScreenAtPoint:(CGPoint)point {
290-
// DS hardware touchscreen coordinates: x in 0-255, y in 0-191
291-
// Normalize to 0.0-1.0 for the libretro pointer state used by RETRO_DEVICE_POINTER
292-
CGFloat normalizedX = point.x / 255.0;
293-
CGFloat normalizedY = point.y / 191.0;
290+
// Normalize to 0.0-1.0 for the libretro pointer state used by RETRO_DEVICE_POINTER,
291+
// matching PVThinLibretroCore (treating the resolution as 256x192)
292+
CGFloat normalizedX = point.x / 256.0;
293+
CGFloat normalizedY = point.y / 192.0;
294294
[self setMousePosition:CGPointMake(normalizedX, normalizedY)];
295295
[self setLeftMouseButtonPressed:YES];
296296
}

Cores/melonDS/PVMelonDSCore/Core/PVMelonDSCore+Controls.mm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,10 @@ - (void)didRelease:(NSInteger)button forPlayer:(NSInteger)player {
287287
#pragma mark - DS Touchscreen
288288

289289
- (void)touchScreenAtPoint:(CGPoint)point {
290-
// DS hardware touchscreen coordinates: x in 0-255, y in 0-191
291-
// Normalize to 0.0-1.0 for the libretro pointer state used by RETRO_DEVICE_POINTER
292-
CGFloat normalizedX = point.x / 255.0;
293-
CGFloat normalizedY = point.y / 191.0;
290+
// Normalize to 0.0-1.0 for the libretro pointer state used by RETRO_DEVICE_POINTER,
291+
// matching PVThinLibretroCore (treating the resolution as 256x192)
292+
CGFloat normalizedX = point.x / 256.0;
293+
CGFloat normalizedY = point.y / 192.0;
294294
[self setMousePosition:CGPointMake(normalizedX, normalizedY)];
295295
[self setLeftMouseButtonPressed:YES];
296296
}

PVUI/Sources/PVUIBase/SwiftUI/DeltaSkins/Views/DeltaSkinView.swift

Lines changed: 46 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public struct DeltaSkinView: View {
119119
@State private var processedTouches: Set<ObjectIdentifier> = []
120120

121121
// Track touch IDs that are actively touching the NDS bottom screen (for continuous updates and release)
122-
@State private var touchToNDSScreenMap: [ObjectIdentifier: Bool] = [:]
122+
@State private var ndsScreenTouches: Set<ObjectIdentifier> = []
123123

124124
// Track the current preview size
125125
@State private var previewSize: CGSize = .zero
@@ -865,7 +865,7 @@ public struct DeltaSkinView: View {
865865

866866
// Check if this touch is associated with a D-pad or NDS screen (needs continuous processing)
867867
let isDPadTouch = touchToDPadMap[touch.id] != nil
868-
let isNDSScreenTouch = touchToNDSScreenMap[touch.id] != nil
868+
let isNDSScreenTouch = ndsScreenTouches.contains(touch.id)
869869

870870
// Check if touch has moved significantly (more than 1 point)
871871
let hasMoved: Bool
@@ -941,18 +941,18 @@ public struct DeltaSkinView: View {
941941
}
942942

943943
// Release NDS bottom screen touch if this was a screen touch
944-
if touchToNDSScreenMap[touch.id] != nil {
944+
if ndsScreenTouches.contains(touch.id) {
945945
DLOG("Releasing NDS screen touch for touch \(touch.id)")
946-
touchToNDSScreenMap.removeValue(forKey: touch.id)
946+
ndsScreenTouches.remove(touch.id)
947947
// Only signal release when the last screen touch lifts
948-
if touchToNDSScreenMap.isEmpty {
948+
if ndsScreenTouches.isEmpty {
949949
inputHandler.ndsBottomScreenTouchReleased()
950950
}
951951
}
952952
}
953953

954954
// If all touches are gone, ensure everything is reset
955-
if touchToButtonMap.isEmpty && touchToDPadMap.isEmpty && touchToNDSScreenMap.isEmpty {
955+
if touchToButtonMap.isEmpty && touchToDPadMap.isEmpty && ndsScreenTouches.isEmpty {
956956
DLOG("All touches ended, cleaning up")
957957

958958
// Clear active buttons to ensure visual feedback is removed
@@ -1261,15 +1261,19 @@ public struct DeltaSkinView: View {
12611261

12621262
// NDS bottom-screen: if this touch is already tracked as an NDS screen touch,
12631263
// update the touch position or release if it has moved off the screen area.
1264-
if touchToNDSScreenMap[touchId] != nil {
1264+
if ndsScreenTouches.contains(touchId) {
12651265
if let normalizedPoint = mapToNDSBottomScreen(location, in: size) {
12661266
DLOG("DS bottom screen touch moved: normalized=\(normalizedPoint)")
12671267
inputHandler.ndsBottomScreenTouched(at: normalizedPoint)
12681268
} else {
1269-
// Touch dragged off the bottom screen — release and fall through to button detection
1270-
DLOG("DS bottom screen touch left screen area, releasing")
1271-
touchToNDSScreenMap.removeValue(forKey: touchId)
1272-
inputHandler.ndsBottomScreenTouchReleased()
1269+
// Touch dragged off the bottom screen — potentially release and fall through to button detection
1270+
DLOG("DS bottom screen touch left screen area for touchId=\(touchId), removing mapping")
1271+
ndsScreenTouches.remove(touchId)
1272+
// Only release when this was the last active NDS bottom-screen touch
1273+
if ndsScreenTouches.isEmpty {
1274+
DLOG("No remaining DS bottom screen touches, releasing stylus")
1275+
inputHandler.ndsBottomScreenTouchReleased()
1276+
}
12731277
}
12741278
return
12751279
}
@@ -1464,7 +1468,7 @@ public struct DeltaSkinView: View {
14641468
// Check if it is on the NDS bottom screen touchscreen area.
14651469
if let normalizedPoint = mapToNDSBottomScreen(location, in: size) {
14661470
DLOG("DS bottom screen touch began: normalized=\(normalizedPoint)")
1467-
touchToNDSScreenMap[touchId] = true
1471+
ndsScreenTouches.insert(touchId)
14681472
inputHandler.ndsBottomScreenTouched(at: normalizedPoint)
14691473
return
14701474
}
@@ -1596,12 +1600,38 @@ public struct DeltaSkinView: View {
15961600

15971601
guard let screen = bottomScreen, let outputFrame = screen.outputFrame else { return nil }
15981602

1603+
// Normalize outputFrame into 0–1 space if it is specified in mappingSize pixels.
1604+
// Some skins (e.g. DefaultDeltaSkin) already use normalized coordinates (0–1),
1605+
// while others may specify absolute positions in the skin's mapping space.
1606+
let isPixelBased = outputFrame.maxX > 1 || outputFrame.maxY > 1
1607+
let normalizedFrame: CGRect
1608+
if isPixelBased, mappingSize.width > 0, mappingSize.height > 0 {
1609+
normalizedFrame = CGRect(
1610+
x: outputFrame.minX / mappingSize.width,
1611+
y: outputFrame.minY / mappingSize.height,
1612+
width: outputFrame.width / mappingSize.width,
1613+
height: outputFrame.height / mappingSize.height
1614+
)
1615+
} else {
1616+
normalizedFrame = outputFrame
1617+
}
1618+
1619+
// Convert normalized frame back into mapping-space pixels so that
1620+
// calculateButtonTransform (which works in mappingSize coordinates)
1621+
// can be applied consistently for both normalized and pixel-based skins.
1622+
let mappingFrame = CGRect(
1623+
x: normalizedFrame.minX * mappingSize.width,
1624+
y: normalizedFrame.minY * mappingSize.height,
1625+
width: normalizedFrame.width * mappingSize.width,
1626+
height: normalizedFrame.height * mappingSize.height
1627+
)
1628+
15991629
let (scaleX, scaleY, xOffset, yOffset) = calculateButtonTransform(in: size, mappingSize: mappingSize)
16001630
let scaledFrame = CGRect(
1601-
x: outputFrame.minX * scaleX + xOffset,
1602-
y: yOffset + outputFrame.minY * scaleY,
1603-
width: outputFrame.width * scaleX,
1604-
height: outputFrame.height * scaleY
1631+
x: mappingFrame.minX * scaleX + xOffset,
1632+
y: yOffset + mappingFrame.minY * scaleY,
1633+
width: mappingFrame.width * scaleX,
1634+
height: mappingFrame.height * scaleY
16051635
)
16061636

16071637
guard scaledFrame.contains(location), scaledFrame.width > 0, scaledFrame.height > 0 else {

0 commit comments

Comments
 (0)