From a799d7695cfe304483591de94088f9233addbba9 Mon Sep 17 00:00:00 2001 From: Mattias Hansson Date: Sun, 11 Jan 2026 18:38:24 +0100 Subject: [PATCH] Game menu working. Issue where reading keys cause interference with JOY/Mouse atm. --- cardgame.c65 | 8 +- cardsprites.c65 | 87 +++++++++- .../charpad_rank_sprites - Projectv2.asm | 149 ++++++++++++++++++ charpad_rank_sprites/charpad_rank_sprites.spd | Bin 980 -> 1044 bytes gameloop.c65 | 23 +-- gamemenu.c65 | 48 +++++- utils.c65 | 12 ++ 7 files changed, 305 insertions(+), 22 deletions(-) create mode 100644 charpad_rank_sprites/charpad_rank_sprites - Projectv2.asm diff --git a/cardgame.c65 b/cardgame.c65 index bd9a178..e6ce36c 100644 --- a/cardgame.c65 +++ b/cardgame.c65 @@ -12,6 +12,7 @@ ASM *=$3000 ENDASM +#INCLUDE #INCLUDE "utils.c65" #INCLUDE "cardconsts.c65" #INCLUDE "pileconsts.c65" @@ -24,6 +25,7 @@ ENDASM #INCLUDE "joystick.c65" #INCLUDE "mouse.c65" #INCLUDE "pointer.c65" +#INCLUDE "cardsprites.c65" #INCLUDE "keyboard.c65" #INCLUDE "gamemenu.c65" //#INCLUDE "joysticktests.c65" @@ -40,6 +42,9 @@ FUNC main sei ENDASM + lib_c64scr_blank() // screen later enabled just before gameloop starts. + + // Save zero page for potential kernal operations later save_zeropage() @@ -48,13 +53,12 @@ FUNC main // Normal game: random shuffle and deal // Seed RNG with multiple entropy sources for better randomness WORD timer_seed - BYTE raster @ $d012 BYTE extra_entropy BYTE warmup // Combine CIA timer with raster position timer_seed = PEEKW $DC04 - extra_entropy = raster + extra_entropy = vic_raster timer_seed = timer_seed ^ extra_entropy rand_seed(timer_seed) diff --git a/cardsprites.c65 b/cardsprites.c65 index 58558ea..58a258a 100644 --- a/cardsprites.c65 +++ b/cardsprites.c65 @@ -709,6 +709,33 @@ ASM !8 $00 ENDASM +// Sprite 25: "RETURN FOR MENU" text (XORed with $ff) +LABEL sprite_text_return_menu +ASM + !8 $ee, $ea, $e9 + !8 $a8, $4a, $ad + !8 $cc, $4a, $cb + !8 $a8, $4a, $a9 + !8 $ae, $4e, $a9 + !8 $00, $00, $00 + !8 $03, $bb, $80 + !8 $02, $2a, $80 + !8 $03, $2b, $00 + !8 $02, $2a, $80 + !8 $02, $3a, $80 + !8 $00, $00, $00 + !8 $0a, $e9, $50 + !8 $0e, $8d, $50 + !8 $0a, $cb, $50 + !8 $0a, $89, $50 + !8 $0a, $e9, $70 + !8 $00, $00, $00 + !8 $00, $00, $00 + !8 $00, $00, $00 + !8 $00, $00, $00 + !8 $fe +ENDASM + // ============================================================================ // CARD DISPLAY SPRITE MANAGEMENT // ============================================================================ @@ -716,7 +743,7 @@ ENDASM // Uses sprites 1-5 (sprite 0 is reserved for pointer) // ============================================================================ -// VIC-II Sprite registers for card display (sprites 1-5) +// VIC-II Sprite registers for card display (sprites 1-5) and menu hint (sprite 6) // Note: sprite_x_msb and sprite_enable already declared in pointer.c65 BYTE sprite_x1 @ $d002 // Sprite 1 X BYTE sprite_y1 @ $d003 // Sprite 1 Y @@ -728,16 +755,20 @@ BYTE sprite_x4 @ $d008 // Sprite 4 X BYTE sprite_y4 @ $d009 // Sprite 4 Y BYTE sprite_x5 @ $d00a // Sprite 5 X BYTE sprite_y5 @ $d00b // Sprite 5 Y +BYTE sprite_x6 @ $d00c // Sprite 6 X (menu hint) +BYTE sprite_y6 @ $d00d // Sprite 6 Y (menu hint) BYTE sprite_color1 @ $d028 // Sprite 1 color BYTE sprite_color2 @ $d029 // Sprite 2 color BYTE sprite_color3 @ $d02a // Sprite 3 color BYTE sprite_color4 @ $d02b // Sprite 4 color BYTE sprite_color5 @ $d02c // Sprite 5 color +BYTE sprite_color6 @ $d02d // Sprite 6 color (menu hint) BYTE sprite_pointer1 @ $07f9 // Sprite 1 pointer BYTE sprite_pointer2 @ $07fa // Sprite 2 pointer BYTE sprite_pointer3 @ $07fb // Sprite 3 pointer BYTE sprite_pointer4 @ $07fc // Sprite 4 pointer BYTE sprite_pointer5 @ $07fd // Sprite 5 pointer +BYTE sprite_pointer6 @ $07fe // Sprite 6 pointer (menu hint) // Card display sprite positions (upper right corner) // Screen starts at (24,50), size 320x200 @@ -888,12 +919,64 @@ FEND FUNC card_display_hide BYTE temp - // Disable sprites 1-5, keep sprite 0 (pointer) + // Disable sprites 1-5, keep sprite 0 (pointer) and sprite 6 (menu hint) temp = sprite_enable temp = temp & %11000001 sprite_enable = temp FEND + +// ============================================================================ +// MENU HINT SPRITE MANAGEMENT +// ============================================================================ +// "RETURN FOR MENU" text displayed at bottom of screen during gameplay +// Uses sprite 6 +// ============================================================================ + +// Menu hint sprite position (bottom right of screen) +WORD CONST MENU_HINT_X = 320 // Right edge (beyond 255, needs X MSB) +BYTE CONST MENU_HINT_Y = 230 // Bottom of screen (50 + 200 - 21 sprite height) + +// Sprite block for "RETURN FOR MENU" text (sprite 25) +BYTE CONST SPRITE_BLOCK_MENU_HINT = 162 // 137 + 25 = 162 + +// ============================================================================ +// FUNC menu_hint_show +// Show "RETURN FOR MENU" sprite at bottom of screen +// Call this when entering gameplay +// ============================================================================ +FUNC menu_hint_show + // Set sprite 6 pointer to "RETURN FOR MENU" sprite + sprite_pointer6 = SPRITE_BLOCK_MENU_HINT + + // Position at bottom right + sprite_x6 = MENU_HINT_X + sprite_y6 = MENU_HINT_Y + + // Set X MSB for sprite 6 (bit 6) if X > 255 + IF MENU_HINT_X > 255 + sprite_x_msb = sprite_x_msb | %01000000 + ENDIF + + // Set color to blue (6) + sprite_color6 = 6 + + // Enable sprite 6 + sprite_enable = sprite_enable | %01000000 +FEND + + +// ============================================================================ +// FUNC menu_hint_hide +// Hide "RETURN FOR MENU" sprite +// Call this when entering menu +// ============================================================================ +FUNC menu_hint_hide + // Disable sprite 6 + sprite_enable = sprite_enable & %10111111 +FEND + + LABEL __skip_lib_cardsprites #IFEND diff --git a/charpad_rank_sprites/charpad_rank_sprites - Projectv2.asm b/charpad_rank_sprites/charpad_rank_sprites - Projectv2.asm new file mode 100644 index 0000000..6eb75e8 --- /dev/null +++ b/charpad_rank_sprites/charpad_rank_sprites - Projectv2.asm @@ -0,0 +1,149 @@ + +; Generated by SpritePad C64 - Subchrist Software, 2003-2025. +; Assemble with 64TASS or similar. + + +; Colour values... + +colr_vic_bg0 = 0 +colr_vic_sprite_mc1 = 0 +colr_vic_sprite_mc2 = 1 + + +; Quantities and dimensions... + +sprite_count = 16 + + +; Data block addresses (dummy values) and sizes... + +addr_spriteset_data = $1000 +size_spriteset_data = $400 ; (1024 bytes) + +addr_spriteset_attrib_data = $1000 +size_spriteset_attrib_data = $10 ; (16 bytes) + + + + + +; * INSERT EXAMPLE PROGRAM HERE! * (or just include this file in your project). + + + + +; SpriteSet Data... +; 16 images, 64 bytes per image, total size is 1024 ($400) bytes. + +* = addr_spriteset_data +spriteset_data + +sprite_image_0 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ef,$ff,$ff +.byte $ef,$ff,$ff,$c7,$ff,$ff,$c7,$ff,$ff,$93,$ff,$ff,$93,$ff,$ff,$39 +.byte $ff,$ff,$01,$ff,$fe,$00,$ff,$fe,$7c,$ff,$fc,$38,$7f,$fc,$38,$7f +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_1 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$83,$ff,$ff +.byte $01,$ff,$ff,$39,$ff,$ff,$f9,$ff,$ff,$f1,$ff,$ff,$e3,$ff,$ff,$c7 +.byte $ff,$ff,$8f,$ff,$ff,$19,$ff,$ff,$39,$ff,$ff,$01,$ff,$ff,$01,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_2 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$ff,$ff +.byte $01,$ff,$ff,$33,$ff,$ff,$e7,$ff,$ff,$cf,$ff,$ff,$83,$ff,$ff,$81 +.byte $ff,$ff,$f9,$ff,$ff,$f9,$ff,$ff,$39,$ff,$ff,$01,$ff,$ff,$83,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_3 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$f3,$ff,$ff +.byte $e3,$ff,$ff,$c3,$ff,$ff,$83,$ff,$ff,$13,$ff,$fe,$33,$ff,$fe,$00 +.byte $ff,$fe,$00,$ff,$ff,$f3,$ff,$ff,$f3,$ff,$ff,$e1,$ff,$ff,$e1,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_4 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$ff,$ff +.byte $01,$ff,$ff,$3f,$ff,$ff,$3f,$ff,$ff,$03,$ff,$ff,$01,$ff,$ff,$f9 +.byte $ff,$ff,$f9,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$01,$ff,$ff,$83,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_5 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$c3,$ff,$ff +.byte $83,$ff,$ff,$1f,$ff,$ff,$3f,$ff,$ff,$03,$ff,$ff,$01,$ff,$ff,$39 +.byte $ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$01,$ff,$ff,$83,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_6 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01,$ff,$ff +.byte $01,$ff,$ff,$39,$ff,$ff,$f3,$ff,$ff,$f3,$ff,$ff,$e7,$ff,$ff,$e7 +.byte $ff,$ff,$e7,$ff,$ff,$cf,$ff,$ff,$cf,$ff,$ff,$cf,$ff,$ff,$cf,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_7 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$83,$ff,$ff +.byte $01,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$83,$ff,$ff,$01 +.byte $ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$01,$ff,$ff,$83,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_8 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$83,$ff,$ff +.byte $01,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$01 +.byte $ff,$ff,$81,$ff,$ff,$f9,$ff,$ff,$f1,$ff,$ff,$83,$ff,$ff,$87,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_9 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$61,$ff,$fe +.byte $40,$ff,$fe,$4c,$ff,$fe,$4c,$ff,$fe,$4c,$ff,$fe,$4c,$ff,$fe,$4c +.byte $ff,$fe,$4c,$ff,$fe,$4c,$ff,$fe,$4c,$ff,$fe,$40,$ff,$fe,$61,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_10 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$e1,$ff,$ff +.byte $e1,$ff,$ff,$f3,$ff,$ff,$f3,$ff,$ff,$f3,$ff,$ff,$f3,$ff,$ff,$f3 +.byte $ff,$ff,$f3,$ff,$ff,$33,$ff,$ff,$33,$ff,$ff,$03,$ff,$ff,$87,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_11 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$83,$ff,$ff +.byte $01,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39 +.byte $ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$39,$ff,$ff,$01,$ff,$ff,$83,$ff +.byte $ff,$f1,$ff,$ff,$f9,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_12 +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$10,$ff,$fe +.byte $10,$ff,$ff,$33,$ff,$ff,$27,$ff,$ff,$0f,$ff,$ff,$1f,$ff,$ff,$0f +.byte $ff,$ff,$27,$ff,$ff,$33,$ff,$ff,$39,$ff,$fe,$10,$ff,$fe,$10,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_13 +.byte $51,$15,$11,$55,$75,$d5,$11,$73,$b5,$55,$75,$75,$55,$15,$11,$ff +.byte $ff,$ff,$f1,$b3,$11,$f7,$b5,$75,$f1,$b5,$31,$fd,$b5,$73,$f1,$b3 +.byte $15,$ff,$ff,$ff,$ff,$11,$11,$ff,$d5,$d7,$ff,$15,$11,$ff,$75,$75 +.byte $ff,$11,$11,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_14 +.byte $b3,$ff,$ff,$b5,$ff,$ff,$b5,$ff,$ff,$b5,$ff,$ff,$b3,$ff,$ff,$ff +.byte $ff,$ff,$1f,$ff,$ff,$7f,$ff,$ff,$1f,$ff,$ff,$df,$ff,$ff,$1f,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff +.byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + +sprite_image_15 +.byte $11,$15,$16,$57,$b5,$52,$33,$b5,$34,$57,$b5,$56,$51,$b1,$56,$ff +.byte $ff,$ff,$fc,$44,$7f,$fd,$d5,$7f,$fc,$d4,$ff,$fd,$d5,$7f,$fd,$c5 +.byte $7f,$ff,$ff,$ff,$f5,$16,$af,$f1,$72,$af,$f5,$34,$af,$f5,$76,$af +.byte $f5,$16,$8f,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$01 + + + +; SpriteSet Attribute Data... +; 16 attributes, 1 per image, 8 bits each, total size is 16 ($10) bytes. +; nb. Upper nybbles = MYXV, lower nybbles = colour (0-15). + +* = addr_spriteset_attrib_data +spriteset_attrib_data + +.byte $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01 + + + diff --git a/charpad_rank_sprites/charpad_rank_sprites.spd b/charpad_rank_sprites/charpad_rank_sprites.spd index d48f8d9524bfc6a4ffaae6503fc3e1aedb3b909f..83343e2a29d975ab3dabd37cbe5143030e0cb40c 100644 GIT binary patch delta 80 zcmcb@K81rVIKYLKL0}`>Ic5hzQL*r?LB?B6!ncM6ZVdbX|NkGC`oCA}|6KVGB>x_* b2a0?ZTmP|W{a2IqU(42i73&9zzyTuwETS-K delta 15 WcmbQjafO{NIKYLKfqx_0Ic5MMmIMI+ diff --git a/gameloop.c65 b/gameloop.c65 index f434e27..6d0e985 100644 --- a/gameloop.c65 +++ b/gameloop.c65 @@ -883,17 +883,16 @@ FUNC game_loop mem_copy(src_ptr, src_end_ptr, dst_ptr) // Copy card sprite data to $2240 (sprite blocks 137+) - // 25 sprites × 64 bytes = 1600 bytes + // 26 sprites × 64 bytes = 1664 bytes (includes "RETURN FOR MENU" sprite) POINTER src_ptr -> sprite_rank_ace POINTER dst_ptr -> $2240 - mem_copy_range(src_ptr, dst_ptr, 64*25) + mem_copy_range(src_ptr, dst_ptr, 64*26) // Outer loop for restart handling WHILE 1 - // Initialize mouse and pointer mouse_init() pointer_init(160, 100, color_red, 136) // Sprite block 136 = $2200, bright red color @@ -904,6 +903,9 @@ FUNC game_loop // Initialize card display sprites card_display_init() + // Show menu hint sprite + menu_hint_show() + #IFDEF TEST_GAMES // Test game options (comment/uncomment one): //setup_test_game_tall_tableau() // K->3 in tab0, red 2 in waste @@ -911,7 +913,6 @@ FUNC game_loop setup_test_game_overflow() // K->A in tab3 to test screen overflow #IFEND - BYTE raster @ $d012 BYTE menu_key BYTE menu_action @@ -921,10 +922,12 @@ FUNC game_loop render_all_piles_initial() + lib_c64scr_show() + // Inner game loop WHILE 1 // Wait for raster to avoid tearing - WHILE raster != 250 + WHILE vic_raster != 250 WEND // Check for menu key (Return or Left Arrow) @@ -939,16 +942,6 @@ FUNC game_loop fill_mem($0400, $0400+999, 0) render_all_piles_initial() ENDIF - IF menu_key == KEY_LEFT_ARROW - menu_show(menu_action) - IF menu_action == MENU_ACTION_RESTART - // Restart requested - break out to restart - BREAK - ENDIF - // Clear screen and re-render after resume - fill_mem($0400, $0400+999, 0) - render_all_piles_initial() - ENDIF // Read mouse input (Port 1) mouse_read() diff --git a/gamemenu.c65 b/gamemenu.c65 index 35cce13..9a92eba 100644 --- a/gamemenu.c65 +++ b/gamemenu.c65 @@ -149,8 +149,8 @@ FEND // Render the full menu screen with current settings // ============================================================================ FUNC menu_render - WORD screen_pos @ $f0 - WORD str_ptr @ $f2 + WORD screen_pos + WORD str_ptr // Clear screen fill_mem($0400, $0400+999, 32) // 32 = space character @@ -178,7 +178,7 @@ FUNC menu_render menu_update_found_to_tab() // Instructions for resume/restart (row 14+) - screen_pos = 14*40+$0400+4 + screen_pos = 12*40+$0400+4 POINTER str_ptr -> str_inst_f7 menu_print_string(screen_pos, str_ptr) @@ -186,6 +186,17 @@ FUNC menu_render POINTER str_ptr -> str_inst_f8 menu_print_string(screen_pos, str_ptr) + // License (row 23, centered) + screen_pos = 20*40+$0400+2 + POINTER str_ptr -> str_controls + menu_print_string(screen_pos, str_ptr) + + + // License (row 23, centered) + screen_pos = 23*40+$0400+1 + POINTER str_ptr -> str_license + menu_print_string(screen_pos, str_ptr) + // Set border color to menu color (purple) POKE $d020 , 4 FEND @@ -196,6 +207,9 @@ FEND // Display menu and handle input, return action to take // ============================================================================ FUNC menu_show(out:{BYTE action}) + + lib_c64scr_blank() + BYTE key BYTE prev_key @@ -206,6 +220,9 @@ FUNC menu_show(out:{BYTE action}) game_selected_pile = PILE_ID_NONE game_selected_card_count = 0 + // Hide menu hint sprite + menu_hint_hide() + // Save current screen state menu_save_screen() @@ -219,6 +236,8 @@ FUNC menu_show(out:{BYTE action}) // Render menu menu_render() + lib_c64scr_show() + // Wait for key release first (debounce) key_scan(key) WHILE key != KEY_NONE @@ -256,6 +275,11 @@ FUNC menu_show(out:{BYTE action}) action = MENU_ACTION_RESUME BREAK + CASE KEY_RETURN + // Resume game + action = MENU_ACTION_RESUME + BREAK + CASE KEY_F8 // Restart game (SHIFT+F7) action = MENU_ACTION_RESTART @@ -272,6 +296,8 @@ FUNC menu_show(out:{BYTE action}) key_scan(key) WEND + lib_c64scr_blank() + // Restore screen or clear for restart IF action == MENU_ACTION_RESUME menu_restore_screen() @@ -288,8 +314,13 @@ FUNC menu_show(out:{BYTE action}) // Re-enable pointer sprite (game loop will handle card display sprites) pointer_enable(1) + // Show menu hint sprite again + menu_hint_show() + // Restore border color POKE $d020 , 1 // White + + lib_c64scr_show() FEND // Menu strings (null-terminated) - Using !scr for screen codes @@ -338,6 +369,17 @@ ASM !scr "F8: Restart game", 0 ENDASM +LABEL str_controls +ASM + !scr "1351 Mouse Port 1 / Joystick Port 2", 0 +ENDASM + +LABEL str_license +ASM + !scr "by Hackz0id/Siders 2026 (GNU GPL v2.0)", 0 +ENDASM + + LABEL __skip_lib_gamemenu diff --git a/utils.c65 b/utils.c65 index ed82796..c39346a 100644 --- a/utils.c65 +++ b/utils.c65 @@ -4,6 +4,18 @@ GOTO __skip_lib_utils +// ============================================================================ +// HARDWARE REGISTER DEFINITIONS +// ============================================================================ +// Shared hardware register references to avoid duplicate declarations +// ============================================================================ + +BYTE vic_raster @ $d012 // VIC-II raster line register + +// ============================================================================ +// UTILITY FUNCTIONS +// ============================================================================ + FUNC fill_mem({WORD start_addr @ $fb} {WORD end_addr} {BYTE value}) FOR start_addr = start_addr TO end_addr