Upload files to "programs/games/solitare"
Final version of game
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
; Solitare V1.5.2
|
; Solitare V1.5.3 FINAL
|
||||||
; Platform: KolibriOS / MenuetOS
|
; Platform: KolibriOS
|
||||||
; Author: Max (Refactored/Fixed)
|
; Author: Max
|
||||||
; Scoring Fix: Cards only give points ONCE, even if moved back and forth.
|
; Format: FASM (Flat Assembler)
|
||||||
|
|
||||||
format binary as 'run'
|
format binary as 'run'
|
||||||
use32
|
use32
|
||||||
org 0x0
|
org 0x0
|
||||||
|
|
||||||
; --- SYSTEM INCLUDES ---
|
; --- EXTERNAL INCLUDES ---
|
||||||
include 'macros.inc'
|
include 'macros.inc'
|
||||||
include 'KOSfuncs.inc'
|
include 'KOSfuncs.inc'
|
||||||
|
|
||||||
@@ -27,12 +27,11 @@ COL_RED equ 0xCC0000
|
|||||||
COL_BLACK equ 0x000000
|
COL_BLACK equ 0x000000
|
||||||
COL_SLOT equ 0x185018
|
COL_SLOT equ 0x185018
|
||||||
|
|
||||||
; Card structure offsets
|
|
||||||
CARD_STRUCT_SIZE equ 12
|
CARD_STRUCT_SIZE equ 12
|
||||||
CARD_VALUE equ 0
|
CARD_VALUE equ 0
|
||||||
CARD_SUIT equ 1
|
CARD_SUIT equ 1
|
||||||
CARD_STATE equ 2 ; Bit 0: Face-up, Bit 7: Already Scored
|
CARD_STATE equ 2
|
||||||
CARD_LOC equ 3 ; 0-6: Tableau, 7: Stock, 8: Foundation, 9: Waste
|
CARD_LOC equ 3
|
||||||
CARD_X equ 4
|
CARD_X equ 4
|
||||||
CARD_Y equ 6
|
CARD_Y equ 6
|
||||||
CARD_OLD_X equ 8
|
CARD_OLD_X equ 8
|
||||||
@@ -44,6 +43,9 @@ FOUNDATION_X equ 350
|
|||||||
FOUND_Y equ 20
|
FOUND_Y equ 20
|
||||||
SCORE_Y equ 535
|
SCORE_Y equ 535
|
||||||
|
|
||||||
|
BTN_REPLAY equ 100
|
||||||
|
BTN_EXIT equ 101
|
||||||
|
|
||||||
; --- HEADER ---
|
; --- HEADER ---
|
||||||
db 'MENUET01'
|
db 'MENUET01'
|
||||||
dd 0x01
|
dd 0x01
|
||||||
@@ -56,18 +58,19 @@ dd 0, 0
|
|||||||
start:
|
start:
|
||||||
mov esp, stacktop
|
mov esp, stacktop
|
||||||
|
|
||||||
; Get system skin height
|
; Get system skin height for proper coordinate calculation
|
||||||
mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT
|
mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT
|
||||||
mov [skin_h], eax
|
mov [skin_h], eax
|
||||||
|
|
||||||
call init_deck
|
call init_game_state
|
||||||
call shuffle_deck
|
|
||||||
call layout_tableau
|
|
||||||
mov dword [score], 0
|
|
||||||
mov byte [game_won], 0
|
|
||||||
|
|
||||||
event_loop:
|
event_loop:
|
||||||
|
; --- GLOBAL EXIT CHECK ---
|
||||||
|
cmp byte [exit_request], 1
|
||||||
|
je .force_exit
|
||||||
|
|
||||||
mcall SF_CHECK_EVENT
|
mcall SF_CHECK_EVENT
|
||||||
|
|
||||||
cmp eax, 1 ; Redraw event
|
cmp eax, 1 ; Redraw event
|
||||||
je on_redraw
|
je on_redraw
|
||||||
cmp eax, 2 ; Key event
|
cmp eax, 2 ; Key event
|
||||||
@@ -75,9 +78,37 @@ event_loop:
|
|||||||
cmp eax, 3 ; Button event
|
cmp eax, 3 ; Button event
|
||||||
je on_button
|
je on_button
|
||||||
|
|
||||||
call handle_mouse
|
; If win condition met, run animation
|
||||||
|
cmp byte [game_won], 1
|
||||||
|
je .win_animation
|
||||||
|
|
||||||
; Update display if dragging or forced
|
call handle_mouse
|
||||||
|
jmp .check_redraw
|
||||||
|
|
||||||
|
.win_animation:
|
||||||
|
call update_cascade
|
||||||
|
mov byte [force_redraw], 1
|
||||||
|
|
||||||
|
; Logic to spawn win thread once
|
||||||
|
cmp byte [win_thread_active], 0
|
||||||
|
jne .check_reset
|
||||||
|
inc dword [win_timer]
|
||||||
|
cmp dword [win_timer], 120 ; Delay before popup
|
||||||
|
jl .check_reset
|
||||||
|
|
||||||
|
mov byte [win_thread_active], 1
|
||||||
|
call create_win_thread
|
||||||
|
|
||||||
|
.check_reset:
|
||||||
|
cmp byte [should_reset], 1
|
||||||
|
jne .no_reset
|
||||||
|
call init_game_state
|
||||||
|
call draw_main_window
|
||||||
|
.no_reset:
|
||||||
|
mcall SF_SLEEP, 1
|
||||||
|
jmp update_screen_only
|
||||||
|
|
||||||
|
.check_redraw:
|
||||||
cmp dword [active_card_count], 0
|
cmp dword [active_card_count], 0
|
||||||
ja update_screen_only
|
ja update_screen_only
|
||||||
cmp byte [force_redraw], 1
|
cmp byte [force_redraw], 1
|
||||||
@@ -86,6 +117,9 @@ event_loop:
|
|||||||
mcall SF_SLEEP, 1
|
mcall SF_SLEEP, 1
|
||||||
jmp event_loop
|
jmp event_loop
|
||||||
|
|
||||||
|
.force_exit:
|
||||||
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
|
||||||
on_key:
|
on_key:
|
||||||
mcall SF_GET_KEY
|
mcall SF_GET_KEY
|
||||||
jmp event_loop
|
jmp event_loop
|
||||||
@@ -93,65 +127,258 @@ on_key:
|
|||||||
on_button:
|
on_button:
|
||||||
mcall SF_GET_BUTTON
|
mcall SF_GET_BUTTON
|
||||||
shr eax, 8
|
shr eax, 8
|
||||||
cmp eax, 1 ; Window close button
|
cmp eax, 1 ; Close button
|
||||||
jne event_loop
|
jne event_loop
|
||||||
|
|
||||||
mcall SF_TERMINATE_PROCESS
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
|
||||||
on_redraw:
|
on_redraw:
|
||||||
mcall SF_REDRAW, SSF_BEGIN_DRAW
|
call draw_main_window
|
||||||
mov ebx, 100 shl 16 + (WIN_W + 9)
|
|
||||||
mov eax, [skin_h]
|
|
||||||
add eax, WIN_H + 5
|
|
||||||
mov ecx, 100 shl 16
|
|
||||||
mov cx, ax
|
|
||||||
mcall SF_CREATE_WINDOW, , , 0x14000000 or COL_TABLE, , title
|
|
||||||
mcall SF_REDRAW, SSF_END_DRAW
|
|
||||||
mov byte [force_redraw], 1
|
mov byte [force_redraw], 1
|
||||||
jmp update_screen_only
|
jmp update_screen_only
|
||||||
|
|
||||||
update_screen_only:
|
update_screen_only:
|
||||||
mov byte [force_redraw], 0
|
mov byte [force_redraw], 0
|
||||||
call prepare_buffer
|
call prepare_buffer
|
||||||
|
|
||||||
|
; Render buffer to window
|
||||||
mov edx, 4 shl 16
|
mov edx, 4 shl 16
|
||||||
add dx, word [skin_h]
|
add dx, word [skin_h]
|
||||||
mcall SF_PUT_IMAGE, screen_buffer, WIN_W shl 16 + WIN_H, edx
|
mcall SF_PUT_IMAGE, screen_buffer, WIN_W shl 16 + WIN_H
|
||||||
jmp event_loop
|
jmp event_loop
|
||||||
|
|
||||||
; --- MOUSE HANDLING ---
|
; --- WIN WINDOW THREAD LOGIC ---
|
||||||
|
|
||||||
|
create_win_thread:
|
||||||
|
mcall SF_CREATE_THREAD, SSF_CREATE_THREAD, win_thread_entry, win_stack_top
|
||||||
|
ret
|
||||||
|
|
||||||
|
win_thread_entry:
|
||||||
|
mcall SF_THREAD_INFO, win_proc_info, -1
|
||||||
|
|
||||||
|
; Center win window relative to main window
|
||||||
|
mov eax, [win_proc_info + 34]
|
||||||
|
add eax, 220
|
||||||
|
shl eax, 16
|
||||||
|
add eax, 300
|
||||||
|
mov [win_pos_x], eax
|
||||||
|
|
||||||
|
mov eax, [win_proc_info + 38]
|
||||||
|
add eax, 200
|
||||||
|
shl eax, 16
|
||||||
|
add eax, 180
|
||||||
|
mov [win_pos_y], eax
|
||||||
|
|
||||||
|
.redr:
|
||||||
|
mcall SF_REDRAW, SSF_BEGIN_DRAW
|
||||||
|
mcall SF_CREATE_WINDOW, [win_pos_x], [win_pos_y], 0x34FFFFFF, 0x80505050, title_win
|
||||||
|
mcall SF_DRAW_TEXT, 70 shl 16 + 35, 0x80000000, msg_congrats
|
||||||
|
mcall SF_DRAW_TEXT, 100 shl 16 + 65, 0x80000000, msg_score_lbl
|
||||||
|
mov eax, [score]
|
||||||
|
mov edi, score_str
|
||||||
|
call int_to_string
|
||||||
|
mcall SF_DRAW_TEXT, 160 shl 16 + 65, 0x80000000, score_str
|
||||||
|
|
||||||
|
mcall SF_DEFINE_BUTTON, 40 shl 16 + 100, 100 shl 16 + 30, BTN_REPLAY, 0xCCCCCC
|
||||||
|
mcall SF_DRAW_TEXT, 66 shl 16 + 110, 0x80000000, txt_replay
|
||||||
|
mcall SF_DEFINE_BUTTON, 160 shl 16 + 100, 100 shl 16 + 30, BTN_EXIT, 0xCCCCCC
|
||||||
|
mcall SF_DRAW_TEXT, 194 shl 16 + 110, 0x80000000, txt_exit
|
||||||
|
mcall SF_REDRAW, SSF_END_DRAW
|
||||||
|
|
||||||
|
.wait_ev:
|
||||||
|
mcall SF_WAIT_EVENT
|
||||||
|
cmp eax, 1
|
||||||
|
je .redr
|
||||||
|
cmp eax, 3
|
||||||
|
jne .wait_ev
|
||||||
|
mcall SF_GET_BUTTON
|
||||||
|
shr eax, 8
|
||||||
|
|
||||||
|
cmp eax, BTN_EXIT
|
||||||
|
je .trigger_exit
|
||||||
|
cmp eax, BTN_REPLAY
|
||||||
|
jne .wait_ev
|
||||||
|
|
||||||
|
.replay_game:
|
||||||
|
mov byte [should_reset], 1
|
||||||
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
jmp .wait_ev
|
||||||
|
|
||||||
|
.trigger_exit:
|
||||||
|
; Signal the main thread to terminate the entire process
|
||||||
|
mov byte [exit_request], 1
|
||||||
|
mcall SF_TERMINATE_PROCESS
|
||||||
|
|
||||||
|
; --- GAME ENGINE LOGIC ---
|
||||||
|
|
||||||
|
init_game_state:
|
||||||
|
call init_deck
|
||||||
|
call shuffle_deck
|
||||||
|
call layout_tableau
|
||||||
|
mov dword [score], 0
|
||||||
|
mov byte [game_won], 0
|
||||||
|
mov dword [win_timer], 0
|
||||||
|
mov byte [win_thread_active], 0
|
||||||
|
mov byte [should_reset], 0
|
||||||
|
mov byte [exit_request], 0
|
||||||
|
mov dword [active_cascade_idx], -1
|
||||||
|
mov dword [cascade_timer], 0
|
||||||
|
ret
|
||||||
|
|
||||||
|
draw_main_window:
|
||||||
|
mcall SF_REDRAW, SSF_BEGIN_DRAW
|
||||||
|
mov ebx, 100 shl 16 + (WIN_W + 9)
|
||||||
|
mov eax, [skin_h]
|
||||||
|
add eax, WIN_H + 5
|
||||||
|
mov ecx, 100 shl 16
|
||||||
|
mov cx, ax
|
||||||
|
mcall SF_CREATE_WINDOW, , , 0x14000000 or COL_TABLE, 0, title
|
||||||
|
mcall SF_REDRAW, SSF_END_DRAW
|
||||||
|
ret
|
||||||
|
|
||||||
|
int_to_string:
|
||||||
|
pushad
|
||||||
|
mov ebx, 10
|
||||||
|
xor ecx, ecx
|
||||||
|
.l1: xor edx, edx
|
||||||
|
div ebx
|
||||||
|
add dl, '0'
|
||||||
|
push edx
|
||||||
|
inc ecx
|
||||||
|
test eax, eax
|
||||||
|
jnz .l1
|
||||||
|
.l2: pop edx
|
||||||
|
mov [edi], dl
|
||||||
|
inc edi
|
||||||
|
loop .l2
|
||||||
|
mov byte [edi], 0
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
|
||||||
|
update_cascade:
|
||||||
|
pushad
|
||||||
|
inc dword [cascade_timer]
|
||||||
|
cmp dword [cascade_timer], 3
|
||||||
|
jl .move_active
|
||||||
|
mov dword [cascade_timer], 0
|
||||||
|
cmp dword [active_cascade_idx], 51
|
||||||
|
jge .move_active
|
||||||
|
inc dword [active_cascade_idx]
|
||||||
|
.move_active:
|
||||||
|
mov ecx, [active_cascade_idx]
|
||||||
|
cmp ecx, 0
|
||||||
|
jl .done
|
||||||
|
.l:
|
||||||
|
push ecx
|
||||||
|
imul esi, ecx, CARD_STRUCT_SIZE
|
||||||
|
add esi, deck_data
|
||||||
|
imul edi, ecx, 4
|
||||||
|
add edi, card_vectors
|
||||||
|
|
||||||
|
; Apply Gravity (Vertical velocity increases)
|
||||||
|
inc word [edi+2]
|
||||||
|
|
||||||
|
; Update Y Position
|
||||||
|
mov ax, [edi+2]
|
||||||
|
add [esi+CARD_Y], ax
|
||||||
|
|
||||||
|
; Update X Position
|
||||||
|
mov ax, [edi]
|
||||||
|
add [esi+CARD_X], ax
|
||||||
|
|
||||||
|
; Bounce off the bottom
|
||||||
|
mov ax, [esi+CARD_Y]
|
||||||
|
add ax, CARD_H
|
||||||
|
cmp ax, WIN_H
|
||||||
|
jl .no_y_bounce
|
||||||
|
mov word [esi+CARD_Y], WIN_H - CARD_H
|
||||||
|
mov ax, [edi+2]
|
||||||
|
neg ax
|
||||||
|
sar ax, 1 ; Dampen vertical bounce (energy loss)
|
||||||
|
mov [edi+2], ax
|
||||||
|
.no_y_bounce:
|
||||||
|
|
||||||
|
; Bounce off the left wall
|
||||||
|
mov ax, [esi+CARD_X]
|
||||||
|
cmp ax, 0
|
||||||
|
jg .not_left
|
||||||
|
mov word [esi+CARD_X], 0
|
||||||
|
neg word [edi] ; Reverse X velocity
|
||||||
|
.not_left:
|
||||||
|
|
||||||
|
; Bounce off the right wall
|
||||||
|
add ax, CARD_W
|
||||||
|
cmp ax, WIN_W
|
||||||
|
jl .no_x_bounce
|
||||||
|
mov word [esi+CARD_X], WIN_W - CARD_W
|
||||||
|
neg word [edi] ; Reverse X velocity
|
||||||
|
.no_x_bounce:
|
||||||
|
|
||||||
|
pop ecx
|
||||||
|
dec ecx
|
||||||
|
jns .l
|
||||||
|
.done:
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
|
||||||
|
init_cascade_vectors:
|
||||||
|
pushad
|
||||||
|
xor ecx, ecx
|
||||||
|
.l:
|
||||||
|
imul edi, ecx, 4
|
||||||
|
add edi, card_vectors
|
||||||
|
|
||||||
|
; Get pseudo-random value from system time
|
||||||
|
mcall SF_GET_SYS_TIME
|
||||||
|
push eax
|
||||||
|
|
||||||
|
; Random Horizontal Velocity (-7 to +8 range)
|
||||||
|
and eax, 0x0F
|
||||||
|
sub eax, 7
|
||||||
|
jnz .x_ok
|
||||||
|
inc eax ; Avoid 0 horizontal speed for variety
|
||||||
|
.x_ok:
|
||||||
|
mov [edi], ax
|
||||||
|
|
||||||
|
; Random Initial Vertical Kick (Bounce up)
|
||||||
|
pop eax
|
||||||
|
shr eax, 4
|
||||||
|
and eax, 0x07 ; 0 to 7 range
|
||||||
|
neg eax ; Make it negative (moving UP)
|
||||||
|
sub eax, 4 ; Ensure a minimum upward kick
|
||||||
|
mov [edi+2], ax
|
||||||
|
|
||||||
|
inc ecx
|
||||||
|
cmp ecx, 52
|
||||||
|
jl .l
|
||||||
|
popad
|
||||||
|
ret
|
||||||
|
|
||||||
handle_mouse:
|
handle_mouse:
|
||||||
pushad
|
pushad
|
||||||
mcall SF_MOUSE_GET, SSF_WINDOW_POSITION
|
mcall SF_MOUSE_GET, SSF_WINDOW_POSITION
|
||||||
mov ebp, eax
|
mov ebp, eax
|
||||||
shr ebp, 16
|
shr ebp, 16
|
||||||
sub ebp, 5 ; Mouse X correction
|
sub ebp, 5
|
||||||
|
|
||||||
and eax, 0xFFFF
|
and eax, 0xFFFF
|
||||||
sub eax, [skin_h]
|
sub eax, [skin_h]
|
||||||
mov edi, eax ; Mouse Y in workspace
|
mov edi, eax
|
||||||
|
|
||||||
mcall SF_MOUSE_GET, SSF_BUTTON
|
mcall SF_MOUSE_GET, SSF_BUTTON
|
||||||
test eax, 1 ; Left click?
|
test eax, 1
|
||||||
jnz .dragging_state
|
jnz .dragging_state
|
||||||
|
|
||||||
cmp dword [mouse_lock], 1
|
cmp dword [mouse_lock], 1
|
||||||
jne .exit
|
jne .exit
|
||||||
|
|
||||||
mov dword [mouse_lock], 0
|
mov dword [mouse_lock], 0
|
||||||
cmp dword [active_card_count], 0
|
cmp dword [active_card_count], 0
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
call check_stack_move
|
call check_stack_move
|
||||||
mov dword [active_card_count], 0
|
mov dword [active_card_count], 0
|
||||||
mov byte [force_redraw], 1
|
mov byte [force_redraw], 1
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.dragging_state:
|
.dragging_state:
|
||||||
cmp dword [mouse_lock], 1
|
cmp dword [mouse_lock], 1
|
||||||
je .no_deal_click
|
je .no_deal_click
|
||||||
|
|
||||||
; Stock pile interaction
|
|
||||||
cmp ebp, STOCK_X
|
cmp ebp, STOCK_X
|
||||||
jb .find_card
|
jb .find_card
|
||||||
cmp ebp, STOCK_X+CARD_W
|
cmp ebp, STOCK_X+CARD_W
|
||||||
@@ -160,13 +387,11 @@ handle_mouse:
|
|||||||
jb .find_card
|
jb .find_card
|
||||||
cmp edi, FOUND_Y+CARD_H
|
cmp edi, FOUND_Y+CARD_H
|
||||||
jae .find_card
|
jae .find_card
|
||||||
|
|
||||||
mov dword [mouse_lock], 1
|
mov dword [mouse_lock], 1
|
||||||
call deal_from_stock
|
call deal_from_stock
|
||||||
mov byte [force_redraw], 1
|
mov byte [force_redraw], 1
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.find_card:
|
.find_card:
|
||||||
mov ebx, 51
|
mov ebx, 51
|
||||||
.f_loop:
|
.f_loop:
|
||||||
@@ -174,7 +399,6 @@ handle_mouse:
|
|||||||
add edx, deck_data
|
add edx, deck_data
|
||||||
movsx esi, word [edx+CARD_X]
|
movsx esi, word [edx+CARD_X]
|
||||||
movsx ecx, word [edx+CARD_Y]
|
movsx ecx, word [edx+CARD_Y]
|
||||||
|
|
||||||
cmp ebp, esi
|
cmp ebp, esi
|
||||||
jb .next_s
|
jb .next_s
|
||||||
add esi, CARD_W
|
add esi, CARD_W
|
||||||
@@ -185,21 +409,17 @@ handle_mouse:
|
|||||||
add ecx, CARD_H
|
add ecx, CARD_H
|
||||||
cmp edi, ecx
|
cmp edi, ecx
|
||||||
jae .next_s
|
jae .next_s
|
||||||
|
test byte [edx+CARD_STATE], 1
|
||||||
test byte [edx+CARD_STATE], 1 ; Is card face up?
|
|
||||||
jz .next_s
|
jz .next_s
|
||||||
|
|
||||||
mov dword [mouse_lock], 1
|
mov dword [mouse_lock], 1
|
||||||
mov [active_stack], ebx
|
mov [active_stack], ebx
|
||||||
mov dword [active_card_count], 1
|
mov dword [active_card_count], 1
|
||||||
|
|
||||||
mov ax, word [edx+CARD_X]
|
mov ax, word [edx+CARD_X]
|
||||||
sub ax, bp
|
sub ax, bp
|
||||||
mov [mouse_off_x], ax
|
mov [mouse_off_x], ax
|
||||||
mov ax, word [edx+CARD_Y]
|
mov ax, word [edx+CARD_Y]
|
||||||
sub ax, di
|
sub ax, di
|
||||||
mov [mouse_off_y], ax
|
mov [mouse_off_y], ax
|
||||||
|
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
call build_active_stack
|
call build_active_stack
|
||||||
popad
|
popad
|
||||||
@@ -209,11 +429,9 @@ handle_mouse:
|
|||||||
jns .f_loop
|
jns .f_loop
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.no_deal_click:
|
.no_deal_click:
|
||||||
cmp dword [active_card_count], 0
|
cmp dword [active_card_count], 0
|
||||||
je .exit_drag
|
je .exit_drag
|
||||||
.drag_active:
|
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
.d_lp:
|
.d_lp:
|
||||||
cmp ecx, [active_card_count]
|
cmp ecx, [active_card_count]
|
||||||
@@ -221,20 +439,17 @@ handle_mouse:
|
|||||||
mov eax, [active_stack + ecx*4]
|
mov eax, [active_stack + ecx*4]
|
||||||
imul eax, CARD_STRUCT_SIZE
|
imul eax, CARD_STRUCT_SIZE
|
||||||
add eax, deck_data
|
add eax, deck_data
|
||||||
|
|
||||||
mov dx, [mouse_off_x]
|
mov dx, [mouse_off_x]
|
||||||
add dx, bp
|
add dx, bp
|
||||||
mov [eax+CARD_X], dx
|
mov [eax+CARD_X], dx
|
||||||
mov dx, [mouse_off_y]
|
mov dx, [mouse_off_y]
|
||||||
add dx, di
|
add dx, di
|
||||||
|
|
||||||
push eax
|
push eax
|
||||||
mov eax, ecx
|
mov eax, ecx
|
||||||
imul eax, STACK_OFFSET
|
imul eax, STACK_OFFSET
|
||||||
add dx, ax
|
add dx, ax
|
||||||
pop eax
|
pop eax
|
||||||
mov [eax+CARD_Y], dx
|
mov [eax+CARD_Y], dx
|
||||||
|
|
||||||
inc ecx
|
inc ecx
|
||||||
jmp .d_lp
|
jmp .d_lp
|
||||||
.exit_drag:
|
.exit_drag:
|
||||||
@@ -244,8 +459,6 @@ handle_mouse:
|
|||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; --- RENDERING ---
|
|
||||||
|
|
||||||
prepare_buffer:
|
prepare_buffer:
|
||||||
mov edi, screen_buffer
|
mov edi, screen_buffer
|
||||||
mov ecx, WIN_W * WIN_H
|
mov ecx, WIN_W * WIN_H
|
||||||
@@ -260,10 +473,8 @@ prepare_buffer:
|
|||||||
add edi, 3
|
add edi, 3
|
||||||
dec ecx
|
dec ecx
|
||||||
jnz .clear_loop
|
jnz .clear_loop
|
||||||
|
|
||||||
call draw_slots
|
call draw_slots
|
||||||
call render_score_ui
|
call render_score_ui
|
||||||
|
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
.draw_loop:
|
.draw_loop:
|
||||||
call is_card_active
|
call is_card_active
|
||||||
@@ -277,7 +488,6 @@ prepare_buffer:
|
|||||||
inc ecx
|
inc ecx
|
||||||
cmp ecx, 52
|
cmp ecx, 52
|
||||||
jl .draw_loop
|
jl .draw_loop
|
||||||
|
|
||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
.draw_active:
|
.draw_active:
|
||||||
cmp ecx, [active_card_count]
|
cmp ecx, [active_card_count]
|
||||||
@@ -290,7 +500,6 @@ prepare_buffer:
|
|||||||
pop ecx
|
pop ecx
|
||||||
inc ecx
|
inc ecx
|
||||||
jmp .draw_active
|
jmp .draw_active
|
||||||
|
|
||||||
.done_rendering:
|
.done_rendering:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@@ -772,11 +981,10 @@ check_stack_move:
|
|||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
.found_match:
|
.found_match:
|
||||||
; FIXED SCORING: Check Bit 7 of STATE (Scored flag)
|
|
||||||
test byte [esi+CARD_STATE], 0x80
|
test byte [esi+CARD_STATE], 0x80
|
||||||
jnz .already_scored
|
jnz .already_scored
|
||||||
add dword [score], 10
|
add dword [score], 10
|
||||||
or byte [esi+CARD_STATE], 0x80 ; Set Scored Flag
|
or byte [esi+CARD_STATE], 0x80
|
||||||
.already_scored:
|
.already_scored:
|
||||||
mov word [esi+CARD_X], bx
|
mov word [esi+CARD_X], bx
|
||||||
mov word [esi+CARD_Y], FOUND_Y
|
mov word [esi+CARD_Y], FOUND_Y
|
||||||
@@ -922,6 +1130,7 @@ check_win:
|
|||||||
jne .out
|
jne .out
|
||||||
add dword [score], 100
|
add dword [score], 100
|
||||||
mov byte [game_won], 1
|
mov byte [game_won], 1
|
||||||
|
call init_cascade_vectors
|
||||||
.out:
|
.out:
|
||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
@@ -949,7 +1158,7 @@ auto_reveal_all:
|
|||||||
jl .find_lowest
|
jl .find_lowest
|
||||||
cmp dword [temp_val], -1
|
cmp dword [temp_val], -1
|
||||||
je .next_col
|
je .next_col
|
||||||
or byte [esi+CARD_STATE], 1 ; Reveal face up
|
or byte [esi+CARD_STATE], 1
|
||||||
.next_col:
|
.next_col:
|
||||||
add ebx, 100
|
add ebx, 100
|
||||||
cmp ebx, 740
|
cmp ebx, 740
|
||||||
@@ -991,7 +1200,7 @@ deal_from_stock:
|
|||||||
add esi, deck_data
|
add esi, deck_data
|
||||||
cmp byte [esi+CARD_LOC], 7
|
cmp byte [esi+CARD_LOC], 7
|
||||||
jne .n
|
jne .n
|
||||||
test byte [esi+CARD_STATE], 1 ; Already visible?
|
test byte [esi+CARD_STATE], 1
|
||||||
jnz .n
|
jnz .n
|
||||||
.o:
|
.o:
|
||||||
or byte [esi+CARD_STATE], 1
|
or byte [esi+CARD_STATE], 1
|
||||||
@@ -1016,7 +1225,7 @@ reset_stock:
|
|||||||
add esi, deck_data
|
add esi, deck_data
|
||||||
cmp byte [esi+CARD_LOC], 9
|
cmp byte [esi+CARD_LOC], 9
|
||||||
jne .s
|
jne .s
|
||||||
and byte [esi+CARD_STATE], 0xFE ; Set face down
|
and byte [esi+CARD_STATE], 0xFE
|
||||||
mov byte [esi+CARD_LOC], 7
|
mov byte [esi+CARD_LOC], 7
|
||||||
mov word [esi+CARD_X], STOCK_X
|
mov word [esi+CARD_X], STOCK_X
|
||||||
mov word [esi+CARD_Y], FOUND_Y
|
mov word [esi+CARD_Y], FOUND_Y
|
||||||
@@ -1032,7 +1241,7 @@ init_deck:
|
|||||||
.r: inc ebx
|
.r: inc ebx
|
||||||
mov byte [edi+CARD_VALUE], bl
|
mov byte [edi+CARD_VALUE], bl
|
||||||
mov byte [edi+CARD_SUIT], al
|
mov byte [edi+CARD_SUIT], al
|
||||||
mov byte [edi+CARD_STATE], 0 ; Face down, Not Scored
|
mov byte [edi+CARD_STATE], 0
|
||||||
mov byte [edi+CARD_LOC], 7
|
mov byte [edi+CARD_LOC], 7
|
||||||
add edi, CARD_STRUCT_SIZE
|
add edi, CARD_STRUCT_SIZE
|
||||||
cmp ebx, 13
|
cmp ebx, 13
|
||||||
@@ -1083,10 +1292,10 @@ layout_tableau:
|
|||||||
mov byte [edi+CARD_LOC], dl
|
mov byte [edi+CARD_LOC], dl
|
||||||
dec ebp
|
dec ebp
|
||||||
jnz .h
|
jnz .h
|
||||||
or byte [edi+CARD_STATE], 1 ; Top card face up
|
or byte [edi+CARD_STATE], 1
|
||||||
jmp .nx
|
jmp .nx
|
||||||
.h:
|
.h:
|
||||||
and byte [edi+CARD_STATE], 0xFE ; Other cards face down
|
and byte [edi+CARD_STATE], 0xFE
|
||||||
.nx:
|
.nx:
|
||||||
add edi, CARD_STRUCT_SIZE
|
add edi, CARD_STRUCT_SIZE
|
||||||
add ecx, STACK_OFFSET
|
add ecx, STACK_OFFSET
|
||||||
@@ -1111,68 +1320,90 @@ layout_tableau:
|
|||||||
jmp .sf
|
jmp .sf
|
||||||
.fin: ret
|
.fin: ret
|
||||||
|
|
||||||
; --- DATA & FONTS ---
|
; --- DATA SECTION ---
|
||||||
title db 'Solitare V1.5.2', 0
|
title db 'Solitare V1.5.3', 0
|
||||||
score dd 0
|
title_win db 'Winner!', 0
|
||||||
game_won db 0
|
msg_congrats db 'Congrats You Win', 0
|
||||||
mouse_lock dd 0
|
msg_score_lbl db 'SCORE: ', 0
|
||||||
force_redraw db 0
|
txt_replay db 'REPLAY', 0
|
||||||
temp_counter dd 0
|
txt_exit db 'EXIT', 0
|
||||||
temp_counter2 dd 0
|
score_str rb 16
|
||||||
temp_val dd 0
|
score dd 0
|
||||||
mouse_off_x dw 0
|
game_won db 0
|
||||||
mouse_off_y dw 0
|
win_timer dd 0
|
||||||
temp_active dd 0
|
win_thread_active db 0
|
||||||
temp_card_buf rd 3
|
should_reset db 0
|
||||||
|
exit_request db 0 ; GLOBAL EXIT FLAG
|
||||||
|
mouse_lock dd 0
|
||||||
|
force_redraw db 0
|
||||||
|
temp_counter dd 0
|
||||||
|
temp_counter2 dd 0
|
||||||
|
temp_val dd 0
|
||||||
|
mouse_off_x dw 0
|
||||||
|
mouse_off_y dw 0
|
||||||
|
temp_active dd 0
|
||||||
|
temp_card_buf rd 3
|
||||||
active_card_count dd 0
|
active_card_count dd 0
|
||||||
active_stack rd 13
|
active_stack rd 13
|
||||||
skin_h dd 0
|
skin_h dd 0
|
||||||
|
cascade_timer dd 0
|
||||||
font_8x12:
|
active_cascade_idx dd -1
|
||||||
; S, C, O, R, E, -, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
win_pos_x dd 0
|
||||||
db 01111100b,10000010b,10000000b,10000000b,01111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; S
|
win_pos_y dd 0
|
||||||
db 01111100b,10000010b,10000000b,10000000b,10000000b,10000000b,10000000b,10000010b,01111100b,00000000b,00000000b,00000000b ; C
|
|
||||||
db 01111100b,10000010b,10000010b,10000010b,10000010b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; O
|
|
||||||
db 11111100b,10000010b,10000010b,10000010b,11111100b,10010000b,10001000b,10000100b,10000010b,00000000b,00000000b,00000000b ; R
|
|
||||||
db 11111110b,10000000b,10000000b,10000000b,11111100b,10000000b,10000000b,10000000b,11111110b,00000000b,00000000b,00000000b ; E
|
|
||||||
db 00000000b,00000000b,00000000b,00000000b,11111111b,00000000b,00000000b,00000000b,00000000b,00000000b,00000000b,00000000b ; -
|
|
||||||
db 00111100b,01000010b,10000001b,10000001b,10000001b,10000001b,10000001b,01000010b,00111100b,00000000b,00000000b,00000000b ; 0
|
|
||||||
db 00011000b,00111000b,00001000b,00001000b,00001000b,00001000b,00001000b,00001000b,00111100b,00000000b,00000000b,00000000b ; 1
|
|
||||||
db 01111100b,10000010b,00000010b,00000010b,01111100b,10000000b,10000000b,10000000b,11111110b,00000000b,00000000b,00000000b ; 2
|
|
||||||
db 01111100b,10000010b,00000010b,00000010b,00111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; 3
|
|
||||||
db 00001000b,00011000b,00101000b,01001000b,10001000b,11111111b,00001000b,00001000b,00001000b,00000000b,00000000b,00000000b ; 4
|
|
||||||
db 11111110b,10000000b,10000000b,11111100b,00000010b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; 5
|
|
||||||
db 01111100b,10000010b,10000000b,11111100b,10000010b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; 6
|
|
||||||
db 11111110b,00000010b,00000100b,00001000b,00010000b,00100000b,00100000b,00100000b,00100000b,00000000b,00000000b,00000000b ; 7
|
|
||||||
db 01111100b,10000010b,10000010b,10000010b,01111100b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; 8
|
|
||||||
db 01111100b,10000010b,10000010b,10000010b,10000010b,01111110b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; 9
|
|
||||||
|
|
||||||
font_5x7:
|
|
||||||
; A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, Hearts, Diamonds, Clubs, Spades
|
|
||||||
db 01110000b,10001000b,10001000b,11111000b,10001000b,10001000b,10001000b ; A
|
|
||||||
db 11110000b,00001000b,00010000b,00100000b,01000000b,10000000b,11111000b ; 2
|
|
||||||
db 11110000b,00001000b,00001000b,01110000b,00001000b,00001000b,11110000b ; 3
|
|
||||||
db 10001000b,10001000b,10001000b,11111000b,00001000b,00001000b,00001000b ; 4
|
|
||||||
db 11111000b,10000000b,10000000b,11110000b,00001000b,00001000b,11111000b ; 5
|
|
||||||
db 01110000b,10000000b,10000000b,11110000b,10001000b,10001000b,01110000b ; 6
|
|
||||||
db 11111000b,00001000b,00010000b,00100000b,01000000b,01000000b,01000000b ; 7
|
|
||||||
db 01110000b,10001000b,10001000b,01110000b,10001000b,10001000b,01110000b ; 8
|
|
||||||
db 01110000b,10001000b,10001000b,01111000b,00001000b,00001000b,01110000b ; 9
|
|
||||||
db 10111000b,10101000b,10101000b,10101000b,10101000b,10101000b,10111000b ; 10
|
|
||||||
db 00011000b,00001000b,00001000b,00001000b,00001000b,10001000b,01110000b ; J
|
|
||||||
db 01110000b,10001000b,10001000b,10001000b,10101000b,10010000b,01101000b ; Q
|
|
||||||
db 10001000b,10010000b,10100000b,11000000b,10100000b,10010000b,10001000b ; K
|
|
||||||
db 01010000b,11111000b,11111000b,01110000b,00100000b,00000000b,00000000b ; Hearts
|
|
||||||
db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,00000000b ; Diamonds
|
|
||||||
db 00100000b,00100000b,11111000b,11111000b,00100000b,00100000b,01110000b ; Clubs
|
|
||||||
db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,01110000b ; Spades
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
deck_data: rb 52 * CARD_STRUCT_SIZE
|
card_vectors: rw 52 * 2 ; (X velocity, Y velocity) per card
|
||||||
|
win_proc_info: rb 1024
|
||||||
|
|
||||||
|
font_8x12:
|
||||||
|
; 0-4 (SCRE-) 5(-) 6-15 (0-9)
|
||||||
|
db 01111100b,10000010b,10000000b,10000000b,01111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,10000000b,10000000b,10000000b,10000000b,10000000b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,10000010b,10000010b,10000010b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 11111100b,10000010b,10000010b,10000010b,11111100b,10010000b,10001000b,10000100b,10000010b,00000000b,00000000b,00000000b
|
||||||
|
db 11111110b,10000000b,10000000b,10000000b,11111100b,10000000b,10000000b,10000000b,11111110b,00000000b,00000000b,00000000b
|
||||||
|
db 00000000b,00000000b,00000000b,00000000b,11111111b,00000000b,00000000b,00000000b,00000000b,00000000b,00000000b,00000000b
|
||||||
|
db 00111100b,01000010b,10000001b,10000001b,10000001b,10000001b,10000001b,01000010b,00111100b,00000000b,00000000b,00000000b
|
||||||
|
db 00011000b,00111000b,00001000b,00001000b,00001000b,00001000b,00001000b,00001000b,00111100b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,00000010b,00000010b,01111100b,10000000b,10000000b,10000000b,11111110b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,00000010b,00000010b,00111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 00001000b,00011000b,00101000b,01001000b,10001000b,11111111b,00001000b,00001000b,00001000b,00000000b,00000000b,00000000b
|
||||||
|
db 11111110b,10000000b,10000000b,11111100b,00000010b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,10000000b,11111100b,10000010b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 11111110b,00000010b,00000100b,00001000b,00010000b,00100000b,00100000b,00100000b,00100000b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,10000010b,10000010b,01111100b,10000010b,10000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
db 01111100b,10000010b,10000010b,10000010b,10000010b,01111110b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b
|
||||||
|
|
||||||
|
font_5x7:
|
||||||
|
db 01110000b,10001000b,10001000b,11111000b,10001000b,10001000b,10001000b
|
||||||
|
db 11110000b,00001000b,00010000b,00100000b,01000000b,10000000b,11111000b
|
||||||
|
db 11110000b,00001000b,00001000b,01110000b,00001000b,00001000b,11110000b
|
||||||
|
db 10001000b,10001000b,10001000b,11111000b,00001000b,00001000b,00001000b
|
||||||
|
db 11111000b,10000000b,10000000b,11110000b,00001000b,00001000b,11111000b
|
||||||
|
db 01110000b,10000000b,10000000b,11110000b,10001000b,10001000b,01110000b
|
||||||
|
db 11111000b,00001000b,00010000b,00100000b,01000000b,01000000b,01000000b
|
||||||
|
db 01110000b,10001000b,10001000b,01110000b,10001000b,10001000b,01110000b
|
||||||
|
db 01110000b,10001000b,10001000b,01111000b,00001000b,00001000b,01110000b
|
||||||
|
db 10111000b,10101000b,10101000b,10101000b,10101000b,10101000b,10111000b
|
||||||
|
db 00011000b,00001000b,00001000b,00001000b,00001000b,10001000b,01110000b
|
||||||
|
db 01110000b,10001000b,10001000b,10001000b,10101000b,10010000b,01101000b
|
||||||
|
db 10001000b,10010000b,10100000b,11000000b,10100000b,10010000b,10001000b
|
||||||
|
db 01010000b,11111000b,11111000b,01110000b,00100000b,00000000b,00000000b
|
||||||
|
db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,00000000b
|
||||||
|
db 00100000b,00100000b,11111000b,11111000b,00100000b,00100000b,01110000b
|
||||||
|
db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,01110000b
|
||||||
|
|
||||||
|
align 4
|
||||||
|
deck_data: rb 52 * CARD_STRUCT_SIZE
|
||||||
i_end:
|
i_end:
|
||||||
|
|
||||||
align 4096
|
align 64
|
||||||
screen_buffer: rb WIN_W * WIN_H * 3 + 32768
|
stack_bottom: rb 16384
|
||||||
stack_bottom: rb 8192
|
|
||||||
stacktop:
|
stacktop:
|
||||||
|
|
||||||
|
align 64
|
||||||
|
win_stack_bottom: rb 8192
|
||||||
|
win_stack_top:
|
||||||
|
|
||||||
|
screen_buffer: rb WIN_W * WIN_H * 3 + 32768
|
||||||
mem_end:
|
mem_end:
|
||||||
|
|||||||
Reference in New Issue
Block a user