371 lines
9.8 KiB
Text
371 lines
9.8 KiB
Text
|
|
#IFNDEF __lib_pointer
|
|
#DEFINE __lib_pointer 1
|
|
|
|
GOTO __skip_lib_pointer
|
|
|
|
// ============================================================================
|
|
// SPRITE POINTER DRIVER FOR COMMODORE 64
|
|
// ============================================================================
|
|
// This library provides sprite-based pointer/cursor control.
|
|
// Can be driven by joystick, mouse, keyboard, or other input methods.
|
|
//
|
|
// Usage:
|
|
// #INCLUDE "pointer.c65"
|
|
// pointer_init(100, 50, 1, 192) // Init at x=100, y=50, white color, sprite data block 192
|
|
// WHILE 1
|
|
// // Read your input device (joystick, mouse, etc.)
|
|
// pointer_move(delta_x, delta_y) // Move pointer
|
|
// WEND
|
|
// ============================================================================
|
|
|
|
// VIC-II Sprite registers
|
|
WORD CONST VIC2 = $D000
|
|
BYTE sprite_x0 @ VIC2+0 // Sprite 0 X position
|
|
BYTE sprite_y0 @ VIC2+1 // Sprite 0 Y position
|
|
BYTE sprite_x_msb @ VIC2+16 // Sprite X MSB (for X > 255)
|
|
BYTE sprite_enable @ VIC2+21 // Sprite enable register
|
|
BYTE sprite_color0 @ VIC2+39 // Sprite 0 color
|
|
BYTE sprite_pointer0 @ $07F8 // Sprite 0 pointer (screen + $3F8)
|
|
|
|
// Pointer position variables
|
|
WORD pointer_x // Current pointer X position (0-511)
|
|
BYTE pointer_y // Current pointer Y position
|
|
BYTE pointer_speed // Base movement speed
|
|
BYTE pointer_accel // Current acceleration counter
|
|
BYTE pointer_max_speed // Maximum speed with acceleration
|
|
|
|
|
|
// ============================================================================
|
|
// Compact arrow pointer sprite - 7 pixels tall
|
|
// Tip at (0,0) for easy pointing at coordinates
|
|
// ============================================================================
|
|
LABEL pointer_sprite_data
|
|
ASM
|
|
// Simple compact arrow
|
|
!8 $80, $00, $00 // Row 0: *
|
|
!8 $C0, $00, $00 // Row 1: **
|
|
!8 $E0, $00, $00 // Row 2: ***
|
|
!8 $F0, $00, $00 // Row 3: ****
|
|
!8 $E0, $00, $00 // Row 4: ***
|
|
!8 $C0, $00, $00 // Row 5: **
|
|
!8 $80, $00, $00 // Row 6: *
|
|
!8 $00, $00, $00 // Row 7-20: blank
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00, $00, $00
|
|
!8 $00 // Padding
|
|
ENDASM
|
|
LABEL pointer_sprite_data_end
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_init
|
|
// Initialize sprite 0 as a pointer at given position
|
|
// Parameters:
|
|
// x_pos: Initial X position (0-255)
|
|
// y_pos: Initial Y position (0-250)
|
|
// color: Sprite color (0-15)
|
|
// sprite_data: Sprite data block number (0-255)
|
|
// ============================================================================
|
|
FUNC pointer_init({BYTE x_pos} {BYTE y_pos} {BYTE color} {BYTE sprite_data})
|
|
BYTE temp
|
|
|
|
// Set pointer position
|
|
pointer_x = x_pos
|
|
pointer_y = y_pos
|
|
pointer_speed = 1 // Base speed: 1 pixel
|
|
pointer_accel = 0 // No acceleration initially
|
|
pointer_max_speed = 10 // Max accelerated speed
|
|
|
|
// Set sprite X position (low byte)
|
|
sprite_x0 = x_pos
|
|
sprite_y0 = y_pos
|
|
|
|
// Clear X MSB for sprite 0 (x_pos is < 256)
|
|
temp = sprite_x_msb
|
|
temp = temp & %11111110 // Clear bit 0
|
|
sprite_x_msb = temp
|
|
|
|
// Set sprite color
|
|
sprite_color0 = color
|
|
|
|
// Set sprite data pointer
|
|
sprite_pointer0 = sprite_data
|
|
|
|
// Enable sprite 0
|
|
sprite_enable = 1
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_move_left
|
|
// Move pointer left by speed amount
|
|
// ============================================================================
|
|
FUNC pointer_move_left({BYTE speed})
|
|
|
|
// Move left with bounds check
|
|
IF pointer_x >= speed
|
|
pointer_x = pointer_x - speed
|
|
ELSE
|
|
pointer_x = 0
|
|
ENDIF
|
|
|
|
IF pointer_x < 24
|
|
pointer_x = 24
|
|
ENDIF
|
|
|
|
// Update VIC registers
|
|
sprite_x0 = pointer_x
|
|
|
|
IF pointer_x > 255
|
|
sprite_x_msb = sprite_x_msb | %00000001
|
|
ELSE
|
|
sprite_x_msb = sprite_x_msb & %11111110
|
|
ENDIF
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_move_right
|
|
// Move pointer right by speed amount
|
|
// ============================================================================
|
|
FUNC pointer_move_right({BYTE speed})
|
|
|
|
// Move right with bounds check
|
|
pointer_x = pointer_x + speed
|
|
IF pointer_x > 320+20
|
|
pointer_x = 320+20
|
|
ENDIF
|
|
|
|
// Update VIC registers
|
|
sprite_x0 = pointer_x
|
|
|
|
IF pointer_x > 255
|
|
sprite_x_msb = sprite_x_msb | %00000001
|
|
ELSE
|
|
sprite_x_msb = sprite_x_msb & %11111110
|
|
ENDIF
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_move_up
|
|
// Move pointer up by speed amount
|
|
// ============================================================================
|
|
FUNC pointer_move_up({BYTE speed})
|
|
|
|
IF pointer_y >= speed
|
|
pointer_y = pointer_y - speed
|
|
ENDIF
|
|
|
|
IF pointer_y < 50
|
|
pointer_y = 50 // Stop at top edge, not 0
|
|
ENDIF
|
|
|
|
sprite_y0 = pointer_y
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_move_down
|
|
// Move pointer down by speed amount
|
|
// ============================================================================
|
|
FUNC pointer_move_down({BYTE speed})
|
|
WORD new_y
|
|
new_y = pointer_y + speed
|
|
|
|
// Stop at bottom edge (around Y=229 for NTSC, 249 for PAL)
|
|
IF new_y > 247
|
|
pointer_y = 247
|
|
ELSE
|
|
pointer_y = new_y
|
|
ENDIF
|
|
|
|
sprite_y0 = pointer_y
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_update_joystick
|
|
// Update pointer based on joystick input state with acceleration
|
|
// Expects joy_state to be set (from joystick.c65 library)
|
|
// joy_state bits: UP=bit0, DOWN=bit1, LEFT=bit2, RIGHT=bit3, FIRE=bit4
|
|
// ============================================================================
|
|
FUNC pointer_update_joystick({BYTE joy_state})
|
|
BYTE actual_speed
|
|
BYTE any_direction
|
|
BYTE test_bit
|
|
|
|
// Check if any direction is pressed (mask all direction bits)
|
|
any_direction = joy_state & %00001111
|
|
|
|
// Reset acceleration if joystick is neutral
|
|
IF any_direction == 0
|
|
pointer_accel = 0
|
|
ELSE
|
|
// Increase acceleration while moving
|
|
IF pointer_accel < 255
|
|
pointer_accel++
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Calculate actual speed with acceleration
|
|
// Divide accel by 8 (shift right 3 times)
|
|
actual_speed = pointer_accel
|
|
ASM
|
|
lda |actual_speed|
|
|
;lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta |actual_speed|
|
|
ENDASM
|
|
|
|
actual_speed = pointer_speed + actual_speed
|
|
IF actual_speed > pointer_max_speed
|
|
actual_speed = pointer_max_speed
|
|
ENDIF
|
|
|
|
// Move in pressed directions
|
|
test_bit = joy_state & %00000100 // LEFT mask
|
|
IF test_bit
|
|
pointer_move_left(actual_speed)
|
|
ENDIF
|
|
|
|
test_bit = joy_state & %00001000 // RIGHT mask
|
|
IF test_bit
|
|
pointer_move_right(actual_speed)
|
|
ENDIF
|
|
|
|
test_bit = joy_state & %00000001 // UP mask
|
|
IF test_bit
|
|
pointer_move_up(actual_speed)
|
|
ENDIF
|
|
|
|
test_bit = joy_state & %00000010 // DOWN mask
|
|
IF test_bit
|
|
pointer_move_down(actual_speed)
|
|
ENDIF
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_update_mouse
|
|
// Update pointer based on mouse delta movements
|
|
// Expects mouse_delta_x and mouse_delta_y to be set (from mouse.c65 library)
|
|
// Mouse deltas are signed 8-bit values
|
|
// ============================================================================
|
|
FUNC pointer_update_mouse({BYTE delta_x} {BYTE delta_y})
|
|
BYTE sign_x
|
|
BYTE sign_y
|
|
BYTE abs_x
|
|
BYTE abs_y
|
|
|
|
// Handle X movement
|
|
sign_x = delta_x & %10000000
|
|
IF sign_x
|
|
// Negative (moving left)
|
|
abs_x = 0 - delta_x // Get absolute value
|
|
IF abs_x > 0
|
|
pointer_move_left(abs_x)
|
|
ENDIF
|
|
ELSE
|
|
// Positive (moving right)
|
|
IF delta_x > 0
|
|
pointer_move_right(delta_x)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Handle Y movement
|
|
sign_y = delta_y & %10000000
|
|
IF sign_y
|
|
// Negative (moving up)
|
|
abs_y = 0 - delta_y // Get absolute value
|
|
IF abs_y > 0
|
|
pointer_move_up(abs_y)
|
|
ENDIF
|
|
ELSE
|
|
// Positive (moving down)
|
|
IF delta_y > 0
|
|
pointer_move_down(delta_y)
|
|
ENDIF
|
|
ENDIF
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_set_speed
|
|
// Set pointer movement speed
|
|
// Parameters:
|
|
// speed: Pixels to move per movement (1-8 recommended)
|
|
// ============================================================================
|
|
FUNC pointer_set_speed({BYTE speed})
|
|
pointer_speed = speed
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_get_x
|
|
// Get current pointer X position
|
|
// Parameters:
|
|
// out:x_pos: X position (0-511)
|
|
// ============================================================================
|
|
FUNC pointer_get_x(out:{WORD x_pos})
|
|
x_pos = pointer_x
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_get_y
|
|
// Get current pointer Y position
|
|
// Returns: Y position in out parameter
|
|
// ============================================================================
|
|
FUNC pointer_get_y(out:{BYTE y_pos})
|
|
y_pos = pointer_y
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_enable
|
|
// Enable or disable pointer sprite
|
|
// Parameters:
|
|
// enable: 1 to enable, 0 to disable
|
|
// ============================================================================
|
|
FUNC pointer_enable({BYTE enable})
|
|
BYTE temp
|
|
temp = sprite_enable
|
|
|
|
IF enable
|
|
temp = temp | %00000001
|
|
ELSE
|
|
temp = temp & %11111110
|
|
ENDIF
|
|
|
|
sprite_enable = temp
|
|
FEND
|
|
|
|
|
|
// ============================================================================
|
|
// FUNC pointer_set_color
|
|
// Change pointer sprite color
|
|
// Parameters:
|
|
// color: Color value (0-15)
|
|
// ============================================================================
|
|
FUNC pointer_set_color({BYTE color})
|
|
sprite_color0 = color
|
|
FEND
|
|
|
|
|
|
LABEL __skip_lib_pointer
|
|
|
|
#IFEND
|