Tightened up the code with better label and pointer handling. README improved.
This commit is contained in:
parent
f4bff18f29
commit
788c6ed60d
5 changed files with 20 additions and 58 deletions
21
README.md
21
README.md
|
|
@ -1,26 +1,17 @@
|
||||||
# Solitaire C64
|
# Solitaire C64
|
||||||
|
|
||||||
A classic Klondike solitaire card game for the Commodore 64, written in c65gm.
|
A classic Klondike solitaire card game for the Commodore 64.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Full Klondike Solitaire**: Stock, waste, 7 tableaus, and 4 foundation piles
|
- Full Klondike with draw-1 and draw-3 modes
|
||||||
- **Dual Input Support**: Play with joystick or 1351 mouse
|
- Joystick and 1351 mouse support
|
||||||
- **Draw Modes**: Toggle between draw-1 and draw-3 gameplay
|
- Extended color mode graphics with sprite cursor
|
||||||
- **Custom Graphics**: Character-based card rendering using extended color mode
|
- Hardware-seeded RNG for shuffling
|
||||||
- **Sprite Cursor**: Visual pointer for card selection and movement
|
|
||||||
- **Smart Shuffling**: Hardware-seeded RNG for true randomness
|
|
||||||
|
|
||||||
## Technical Details
|
|
||||||
|
|
||||||
**Language**: c65gm (C-like language for 6502/C64)
|
|
||||||
**Memory Layout**: Code at $3000, custom charset at $2000
|
|
||||||
**Graphics**: Extended Color Mode (ECM) with custom character set
|
|
||||||
**Input**: CIA joystick ports + 1351 proportional mouse support
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
Requires the c65gm compiler and ACME assembler:
|
Requires the [c65gm compiler](https://git.techserio.com/mattiashz/c65gm) and ACME assembler:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./cm.sh
|
./cm.sh
|
||||||
|
|
|
||||||
29
carddeck.c65
29
carddeck.c65
|
|
@ -95,28 +95,13 @@ FEND
|
||||||
// Tab0=1, Tab1=2, Tab2=3, Tab3=4, Tab4=5, Tab5=6, Tab6=7 cards
|
// Tab0=1, Tab1=2, Tab2=3, Tab3=4, Tab4=5, Tab5=6, Tab6=7 cards
|
||||||
// Top card of each tableau is face up
|
// Top card of each tableau is face up
|
||||||
FUNC deal_tableaus
|
FUNC deal_tableaus
|
||||||
WORD ptr
|
deal_to_tableau(@pile_tab0, 1)
|
||||||
|
deal_to_tableau(@pile_tab1, 2)
|
||||||
POINTER ptr -> pile_tab0
|
deal_to_tableau(@pile_tab2, 3)
|
||||||
deal_to_tableau(ptr, 1)
|
deal_to_tableau(@pile_tab3, 4)
|
||||||
|
deal_to_tableau(@pile_tab4, 5)
|
||||||
POINTER ptr -> pile_tab1
|
deal_to_tableau(@pile_tab5, 6)
|
||||||
deal_to_tableau(ptr, 2)
|
deal_to_tableau(@pile_tab6, 7)
|
||||||
|
|
||||||
POINTER ptr -> pile_tab2
|
|
||||||
deal_to_tableau(ptr, 3)
|
|
||||||
|
|
||||||
POINTER ptr -> pile_tab3
|
|
||||||
deal_to_tableau(ptr, 4)
|
|
||||||
|
|
||||||
POINTER ptr -> pile_tab4
|
|
||||||
deal_to_tableau(ptr, 5)
|
|
||||||
|
|
||||||
POINTER ptr -> pile_tab5
|
|
||||||
deal_to_tableau(ptr, 6)
|
|
||||||
|
|
||||||
POINTER ptr -> pile_tab6
|
|
||||||
deal_to_tableau(ptr, 7)
|
|
||||||
FEND
|
FEND
|
||||||
|
|
||||||
// Clear the seen array
|
// Clear the seen array
|
||||||
|
|
|
||||||
|
|
@ -84,13 +84,7 @@ FUNC main
|
||||||
set_vic_charmem(4) // $2000
|
set_vic_charmem(4) // $2000
|
||||||
set_vic_ecm()
|
set_vic_ecm()
|
||||||
|
|
||||||
|
mem_copy(@card_charset, @card_charset_end, $2000)
|
||||||
WORD charset_ptr
|
|
||||||
WORD charset_end_ptr
|
|
||||||
POINTER charset_ptr -> card_charset
|
|
||||||
POINTER charset_end_ptr -> card_charset_end
|
|
||||||
mem_copy(charset_ptr, charset_end_ptr, $2000)
|
|
||||||
//mem_copy_range(charset_ptr, $2000, 512)
|
|
||||||
|
|
||||||
fill_mem($d800, $d800+999, color_white) // Fill color mem
|
fill_mem($d800, $d800+999, color_white) // Fill color mem
|
||||||
POKE $d020 , color_white //color_grey
|
POKE $d020 , color_white //color_grey
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ FEND
|
||||||
|
|
||||||
// Waste to Tableau
|
// Waste to Tableau
|
||||||
FUNC move_waste_to_tab({WORD tab_ptr} out:{BYTE success})
|
FUNC move_waste_to_tab({WORD tab_ptr} out:{BYTE success})
|
||||||
WORD waste_ptr @ $8c
|
WORD waste_ptr
|
||||||
POINTER waste_ptr -> pile_waste
|
POINTER waste_ptr -> pile_waste
|
||||||
BYTE card
|
BYTE card
|
||||||
BYTE valid
|
BYTE valid
|
||||||
|
|
@ -249,7 +249,7 @@ FEND
|
||||||
|
|
||||||
// Waste to Foundation
|
// Waste to Foundation
|
||||||
FUNC move_waste_to_found({WORD found_ptr} out:{BYTE success})
|
FUNC move_waste_to_found({WORD found_ptr} out:{BYTE success})
|
||||||
WORD waste_ptr @ $aa
|
WORD waste_ptr
|
||||||
POINTER waste_ptr -> pile_waste
|
POINTER waste_ptr -> pile_waste
|
||||||
BYTE card
|
BYTE card
|
||||||
BYTE valid
|
BYTE valid
|
||||||
|
|
@ -273,7 +273,7 @@ FUNC move_waste_to_found({WORD found_ptr} out:{BYTE success})
|
||||||
FEND
|
FEND
|
||||||
|
|
||||||
// Tableau to Foundation (top card only)
|
// Tableau to Foundation (top card only)
|
||||||
FUNC move_tab_to_found({WORD tab_ptr @ $8e} {WORD found_ptr} out:{BYTE success})
|
FUNC move_tab_to_found({WORD tab_ptr} {WORD found_ptr} out:{BYTE success})
|
||||||
BYTE card
|
BYTE card
|
||||||
BYTE valid
|
BYTE valid
|
||||||
BYTE is_facedown
|
BYTE is_facedown
|
||||||
|
|
@ -358,7 +358,7 @@ FUNC move_tab_to_tab({WORD src_ptr @ $b0} {WORD dst_ptr} {BYTE card_count} out:{
|
||||||
FEND
|
FEND
|
||||||
|
|
||||||
// Foundation to Tableau (optional rule - some variants allow this)
|
// Foundation to Tableau (optional rule - some variants allow this)
|
||||||
FUNC move_found_to_tab({WORD found_ptr @ $84} {WORD tab_ptr} out:{BYTE success})
|
FUNC move_found_to_tab({WORD found_ptr} {WORD tab_ptr} out:{BYTE success})
|
||||||
BYTE card
|
BYTE card
|
||||||
BYTE valid
|
BYTE valid
|
||||||
|
|
||||||
|
|
|
||||||
12
gameloop.c65
12
gameloop.c65
|
|
@ -871,22 +871,14 @@ FUNC game_loop
|
||||||
BYTE button_state
|
BYTE button_state
|
||||||
BYTE clicked
|
BYTE clicked
|
||||||
BYTE is_won
|
BYTE is_won
|
||||||
WORD src_ptr @ $8a
|
|
||||||
WORD src_end_ptr
|
|
||||||
WORD dst_ptr
|
|
||||||
|
|
||||||
// Copy sprite data to $2200 (sprite block 136)
|
// Copy sprite data to $2200 (sprite block 136)
|
||||||
// $2000-$21FF reserved for charset
|
// $2000-$21FF reserved for charset
|
||||||
POINTER src_ptr -> pointer_sprite_data
|
mem_copy(@pointer_sprite_data, @pointer_sprite_data_end, $2200)
|
||||||
POINTER src_end_ptr -> pointer_sprite_data_end
|
|
||||||
POINTER dst_ptr -> $2200
|
|
||||||
mem_copy(src_ptr, src_end_ptr, dst_ptr)
|
|
||||||
|
|
||||||
// Copy card sprite data to $2240 (sprite blocks 137+)
|
// Copy card sprite data to $2240 (sprite blocks 137+)
|
||||||
// 26 sprites × 64 bytes = 1664 bytes (includes "RETURN FOR MENU" sprite)
|
// 26 sprites × 64 bytes = 1664 bytes (includes "RETURN FOR MENU" sprite)
|
||||||
POINTER src_ptr -> sprite_rank_ace
|
mem_copy_range(@sprite_rank_ace, $2240, 64*26)
|
||||||
POINTER dst_ptr -> $2240
|
|
||||||
mem_copy_range(src_ptr, dst_ptr, 64*26)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue