@@ -1116,25 +1116,37 @@ static INLINE void android_input_poll_event_type_motion(
11161116 android -> mouse_x_viewport = android -> pointer [motion_ptr ].x ;
11171117 android -> mouse_y_viewport = android -> pointer [motion_ptr ].y ;
11181118
1119- if (stylus_pressed ) /* Only set pressed state and pointer count when contact detected */
1120- {
1121- /* Ensure pointer_count covers this motion_ptr */
1122- if (android -> pointer_count < (int )motion_ptr + 1 )
1123- android -> pointer_count = (int )motion_ptr + 1 ;
1124-
1125- /* Update mouse button states for menu interaction */
1126- android -> mouse_l = tip_down ; /* Left click when tip touches */
1127- android -> mouse_r = side_primary ; /* Right click on barrel button */
1128-
1119+ /* S-Pen Virtual Pointer System for libretro cores:
1120+ * Index 0 = tip pointer (when tip pressed)
1121+ * Index 1 = virtual barrel pointer (when barrel pressed, mirrors tip XY)
1122+ * This allows cores to detect barrel via pointer_count > 1 or checking index 1 */
1123+
1124+ android -> pointer_count = 0 ; /* Reset count, will increment based on active states */
1125+
1126+ if (tip_down ) {
1127+ /* Set up tip pointer at index 0 */
1128+ android -> pointer [0 ] = android -> pointer [motion_ptr ]; /* Copy translated coordinates */
1129+ android -> pointer_count = 1 ;
1130+ }
1131+
1132+ if (side_primary ) {
1133+ /* Set up virtual barrel pointer at index 1, mirroring tip coordinates */
1134+ android -> pointer [1 ] = android -> pointer [motion_ptr ]; /* Same coordinates as tip */
1135+ android -> pointer_count = tip_down ? 2 : 1 ; /* Increment if tip also active */
1136+ }
1137+
1138+ /* Update mouse button states for menu interaction */
1139+ android -> mouse_l = tip_down ; /* Left click when tip touches */
1140+ android -> mouse_r = side_primary ; /* Right click on barrel button */
1141+
11291142#ifdef DEBUG_ANDROID_INPUT
1130- if (action == AMOTION_EVENT_ACTION_DOWN )
1131- RARCH_LOG ("[Stylus] POINTER DOWN @ (%.1f, %.1f) idx=%zu cnt=%d\n" ,
1132- x , y , motion_ptr , android -> pointer_count );
1143+ if (action == AMOTION_EVENT_ACTION_DOWN )
1144+ RARCH_LOG ("[Stylus] POINTER DOWN @ (%.1f, %.1f) tip=%d barrel=%d cnt=%d\n" ,
1145+ x , y , tip_down , side_primary , android -> pointer_count );
11331146#endif
1134- }
1135- else
1136- {
1137- /* Hovering: clear button states but maintain cursor position */
1147+ if (!tip_down && !side_primary ) {
1148+ /* Hovering: no active pointers, clear button states but maintain cursor position */
1149+ android -> pointer_count = 0 ;
11381150 android -> mouse_l = false;
11391151 android -> mouse_r = false;
11401152
@@ -1148,18 +1160,13 @@ static INLINE void android_input_poll_event_type_motion(
11481160
11491161 if (action == AMOTION_EVENT_ACTION_UP )
11501162 {
1151- /* Compact/release pointer array like the touch path */
1152- if (motion_ptr < MAX_TOUCH - 1 )
1153- {
1154- memmove (android -> pointer + motion_ptr ,
1155- android -> pointer + motion_ptr + 1 ,
1156- (MAX_TOUCH - motion_ptr - 1 ) * sizeof (android -> pointer [0 ]));
1157- }
1158- if (android -> pointer_count > 0 )
1159- android -> pointer_count -- ;
1163+ /* S-Pen UP: Clear all virtual pointers and button states */
1164+ android -> pointer_count = 0 ;
1165+ android -> mouse_l = false;
1166+ android -> mouse_r = false;
11601167
11611168#ifdef DEBUG_ANDROID_INPUT
1162- RARCH_LOG ("[Stylus] POINTER UP idx=%zu cnt=%d \n" , motion_ptr , android -> pointer_count );
1169+ RARCH_LOG ("[Stylus] POINTER UP - cleared all virtual pointers \n" );
11631170#endif
11641171 return ; /* Early return - no shared processing */
11651172 }
0 commit comments