diff --git a/programs/games/solitare/solitare.asm b/programs/games/solitare/solitare.asm new file mode 100644 index 000000000..a2a6ca0bc --- /dev/null +++ b/programs/games/solitare/solitare.asm @@ -0,0 +1,1140 @@ +; Solitare - Refactored Version +; Author: Max +; Compile with FASM + +format binary as 'run' +use32 +org 0x0 + +; --- SYSTEM MACROS --- +macro mcall a,b,c,d,e,f { + if ~ a eq + mov eax, a + end if + if ~ b eq + mov ebx, b + end if + if ~ c eq + mov ecx, c + end if + if ~ d eq + mov edx, d + end if + if ~ e eq + mov esi, e + end if + if ~ f eq + mov edi, f + end if + int 0x40 +} + +; --- CONSTANTS --- +; System Functions +SYS_REDRAW equ 12 +SYS_KEY equ 2 +SYS_BUTTON equ 17 +SYS_MOUSE_POS equ 37 +SYS_DRAW_WINDOW equ 0 +SYS_EXIT equ -1 +SYS_BLIT equ 7 +SYS_RANDOM equ 3 +SYS_DELAY equ 5 + +; Card Structure Offsets +CARD_VALUE equ 0 +CARD_SUIT equ 1 +CARD_STATE equ 2 ; 0=Face Down, 1=Face Up +CARD_LOC equ 3 ; 0-6=Tableau, 7=Stock, 8=Found, 9=Waste +CARD_X equ 4 +CARD_Y equ 6 +CARD_OLD_X equ 8 +CARD_OLD_Y equ 10 +CARD_STRUCT_SIZE equ 12 + +; Game Constants +CARD_W equ 50 +CARD_H equ 70 +STACK_OFFSET equ 22 +WIN_W equ 800 +WIN_H equ 600 +BPP equ 3 +STRIDE equ WIN_W * BPP + +; Colors +COL_TABLE equ 0x207020 +COL_REVERSE equ 0x0000AA +COL_WHITE equ 0xFFFFFF +COL_RED equ 0xCC0000 +COL_BLACK equ 0x000000 +COL_SLOT equ 0x185018 + +; Positions +STOCK_X equ 20 +WASTE_X equ 80 +FOUNDATION_X equ 400 +FOUND_Y equ 20 +EXIT_BTN_X equ 760 +EXIT_BTN_Y equ 10 +EXIT_BTN_SIZE equ 20 + +; --- HEADER --- +db 'MENUET01' +dd 0x01 +dd start +dd i_end +dd mem_end +dd stacktop +dd 0, 0 + +start: + mov esp, stacktop + call init_deck + call shuffle_deck + call layout_tableau + mov dword [score], 0 + mov byte [game_won], 0 + +event_loop: + mcall 11 ; Check event + cmp eax, 1 + je on_redraw + cmp eax, 2 + je on_key + cmp eax, 3 + je on_button + + call handle_mouse + + cmp dword [active_card_count], 0 + ja on_redraw + + mcall SYS_DELAY, 2 ; Yield CPU + jmp event_loop + +on_key: + mcall SYS_KEY + jmp event_loop + +on_button: + mcall SYS_BUTTON + shr eax, 8 + cmp eax, 1 + jne event_loop + mcall SYS_EXIT + +on_redraw: + mcall SYS_REDRAW, 1 ; Start Redraw + + ; Draw Window + mcall SYS_DRAW_WINDOW, 100 shl 16 + WIN_W, 100 shl 16 + WIN_H, 0x01000000 or COL_TABLE, , title + + ; Clear Buffer + mov edi, screen_buffer + mov ecx, WIN_W * WIN_H +.clear_loop: + mov eax, COL_TABLE + mov [edi], al + mov [edi+1], ah + shr eax, 16 + mov [edi+2], al + add edi, 3 + loop .clear_loop + + ; Exit Button + mov ebx, EXIT_BTN_X + mov ecx, EXIT_BTN_Y + mov edx, COL_RED + mov edi, EXIT_BTN_SIZE + mov ebp, EXIT_BTN_SIZE + call fill_rect_buf + + call draw_slots + + ; Draw Static Cards + xor ecx, ecx +.draw_loop: + call is_card_active + jc .skip + push ecx + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + call draw_card_to_buffer + pop ecx +.skip: + inc ecx + cmp ecx, 52 + jl .draw_loop + + ; Draw Active (Dragged) Cards + xor ecx, ecx +.draw_active: + cmp ecx, [active_card_count] + jae .draw_score + push ecx + mov eax, [active_stack + ecx*4] + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + call draw_card_to_buffer + pop ecx + inc ecx + jmp .draw_active + +.draw_score: + call render_score_ui + +.blit: + mcall SYS_BLIT, screen_buffer, WIN_W shl 16 + WIN_H, 0 + mcall SYS_REDRAW, 2 ; End Redraw + jmp event_loop + +; --- UI HELPERS --- + +render_score_ui: + mov edx, COL_BLACK + mov ebx, 620 + mov ecx, 570 + mov esi, 17 ; 'S' + call draw_char_to_buf + add ebx, 7 + mov esi, 18 ; 'C' + call draw_char_to_buf + add ebx, 7 + mov esi, 19 ; 'O' + call draw_char_to_buf + add ebx, 7 + mov esi, 20 ; 'R' + call draw_char_to_buf + add ebx, 7 + mov esi, 21 ; 'E' + call draw_char_to_buf + add ebx, 15 + + mov eax, [score] + test eax, eax + jns .pos + neg eax + push eax + mov ecx, 570 + mov esi, 22 ; '-' + call draw_char_to_buf + add ebx, 7 + pop eax +.pos: + mov edi, 10 + xor ecx, ecx +.dec_loop: + xor edx, edx + div edi + push edx + inc ecx + test eax, eax + jnz .dec_loop +.print_dec: + pop edx + add edx, 23 ; Font offset for '0' + push ecx + mov ecx, 570 + mov esi, edx + mov edx, COL_BLACK + call draw_char_to_buf + add ebx, 7 + pop ecx + loop .print_dec + ret + +; --- DRAWING PROCEDURES --- + +draw_char_to_buf: + pushad + imul esi, 7 + add esi, font_5x7 + mov ebp, 7 +.y_loop: + push ebx + push ecx + mov al, [esi] + mov ah, 10000000b + mov dword [temp_counter], 5 +.x_loop: + test al, ah + jz .skip_pixel + push eax + imul eax, ecx, STRIDE + mov edi, ebx + imul edi, 3 + add eax, edi + add eax, screen_buffer + mov [eax], dl + mov [eax+1], dh + push edx + shr edx, 16 + mov [eax+2], dl + pop edx + pop eax +.skip_pixel: + shr ah, 1 + inc ebx + dec dword [temp_counter] + jnz .x_loop + pop ecx + pop ebx + inc esi + inc ecx + dec ebp + jnz .y_loop + popad + ret + +draw_card_to_buffer: + pushad + movzx ebx, word [esi+CARD_X] + movzx ecx, word [esi+CARD_Y] + mov edx, COL_BLACK + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + inc ebx + inc ecx + mov edx, COL_WHITE + mov edi, CARD_W-2 + mov ebp, CARD_H-2 + call fill_rect_buf + + cmp byte [esi+CARD_STATE], 1 + je .face_up + + ; Draw Card Back + add ebx, 4 + add ecx, 4 + mov edx, COL_REVERSE + mov edi, CARD_W-10 + mov ebp, CARD_H-10 + call fill_rect_buf + popad + ret + +.face_up: + mov edx, COL_RED + cmp byte [esi+CARD_SUIT], 2 + jb .is_red + mov edx, COL_BLACK +.is_red: + push edx + push esi + ; Rank and Suit Top-Left + movzx eax, byte [esi+CARD_VALUE] + dec eax + mov esi, eax + add ebx, 3 + add ecx, 3 + call draw_char_to_buf + + pop esi + push esi + movzx eax, byte [esi+CARD_SUIT] + add eax, 13 + add ebx, 6 + mov esi, eax + call draw_char_to_buf + + ; Rank and Suit Bottom-Right + pop esi + pop edx + push edx + push esi + movzx ebx, word [esi+CARD_X] + add ebx, CARD_W - 8 + movzx ecx, word [esi+CARD_Y] + add ecx, CARD_H - 10 + + movzx eax, byte [esi+CARD_VALUE] + dec eax + mov esi, eax + call draw_char_to_buf + + pop esi + push esi + movzx eax, byte [esi+CARD_SUIT] + add eax, 13 + sub ebx, 6 + mov esi, eax + call draw_char_to_buf + + pop esi + pop edx + popad + ret + +fill_rect_buf: + pushad + imul eax, ecx, STRIDE + imul ecx, ebx, BPP + add eax, ecx + add eax, screen_buffer + mov ecx, edx +.yl: + push eax + mov edx, edi +.xl: + mov [eax], cl + mov [eax+1], ch + push ecx + shr ecx, 16 + mov [eax+2], cl + pop ecx + add eax, 3 + dec edx + jnz .xl + pop eax + add eax, STRIDE + dec ebp + jnz .yl + popad + ret + +draw_slots: + pushad + mov ebx, FOUNDATION_X + mov ecx, FOUND_Y + mov dword [temp_counter2], 4 +.f_loop: + mov edx, COL_SLOT + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + add ebx, 60 + dec dword [temp_counter2] + jnz .f_loop + + mov ebx, 50 + mov ecx, 120 + mov dword [temp_counter2], 7 +.t_loop: + mov edx, COL_SLOT + mov edi, CARD_W + mov ebp, CARD_H + call fill_rect_buf + add ebx, 100 + dec dword [temp_counter2] + jnz .t_loop + popad + ret + +; --- GAME LOGIC --- + +is_card_active: + push eax + push ebx + xor ebx, ebx +.l: + cmp ebx, [active_card_count] + jae .no + mov eax, [active_stack + ebx*4] + cmp eax, ecx + je .yes + inc ebx + jmp .l +.yes: + pop ebx + pop eax + stc + ret +.no: + pop ebx + pop eax + clc + ret + +handle_mouse: + pushad + mcall SYS_MOUSE_POS, 0 + mov ebp, eax + shr ebp, 16 + and eax, 0xFFFF + mov edi, eax + + mcall SYS_MOUSE_POS, 2 + test eax, 1 + jnz .dragging_state + + ; Mouse Released + mov dword [mouse_lock], 0 + cmp dword [active_card_count], 0 + je .exit + call check_stack_move + mov dword [active_card_count], 0 + popad + jmp on_redraw +.exit: + popad + ret + +.dragging_state: + cmp dword [mouse_lock], 1 + je .no_deal_click + + ; Exit Check + cmp ebp, EXIT_BTN_X + jb .no_exit + cmp ebp, EXIT_BTN_X + EXIT_BTN_SIZE + jae .no_exit + cmp edi, EXIT_BTN_Y + jb .no_exit + cmp edi, EXIT_BTN_Y + EXIT_BTN_SIZE + jae .no_exit + mcall SYS_EXIT + +.no_exit: + ; Stock Click + cmp ebp, STOCK_X + jb .find_card + cmp ebp, STOCK_X+CARD_W + ja .find_card + cmp edi, FOUND_Y + jb .find_card + cmp edi, FOUND_Y+CARD_H + jae .find_card + mov dword [mouse_lock], 1 + call deal_from_stock + popad + jmp on_redraw + +.find_card: + mov ebx, 51 +.f_loop: + imul edx, ebx, CARD_STRUCT_SIZE + add edx, deck_data + movzx esi, word [edx+CARD_X] + movzx ecx, word [edx+CARD_Y] + cmp ebp, esi + jb .next_s + add esi, CARD_W + cmp ebp, esi + jae .next_s + cmp edi, ecx + jb .next_s + add ecx, CARD_H + cmp edi, ecx + jae .next_s + cmp byte [edx+CARD_STATE], 1 + jne .next_s + + ; Found Card to Drag + mov dword [mouse_lock], 1 + mov [active_stack], ebx + mov dword [active_card_count], 1 + mov ax, [edx+CARD_X] + sub ax, bp + mov [mouse_off_x], ax + mov ax, [edx+CARD_Y] + sub ax, di + mov [mouse_off_y], ax + mov eax, ebx + call build_active_stack + popad + ret +.next_s: + dec ebx + jns .f_loop + +.no_deal_click: + cmp dword [active_card_count], 0 + je .exit_drag +.drag_active: + xor ecx, ecx +.d_lp: + cmp ecx, [active_card_count] + jae .exit_drag + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov dx, [mouse_off_x] + add dx, bp + mov [eax+CARD_X], dx + mov dx, [mouse_off_y] + add dx, di + push eax + mov eax, ecx + imul eax, STACK_OFFSET + add dx, ax + pop eax + mov [eax+CARD_Y], dx + inc ecx + jmp .d_lp +.exit_drag: + popad + ret + +build_active_stack: + pushad + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + mov bx, [esi+CARD_X] + mov dx, [esi+CARD_Y] + movzx ebp, dx + add ebp, STACK_OFFSET +.y_search: + xor ecx, ecx +.l: + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + cmp word [edi+CARD_X], bx + jne .nx + cmp word [edi+CARD_Y], bp + jne .nx + mov edx, [active_card_count] + mov [active_stack + edx*4], ecx + inc dword [active_card_count] + add ebp, STACK_OFFSET + jmp .y_search +.nx: + inc ecx + cmp ecx, 52 + jl .l +.done: + xor ecx, ecx +.save: + cmp ecx, [active_card_count] + jae .fin + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov dx, [eax+CARD_X] + mov [eax+CARD_OLD_X], dx + mov dx, [eax+CARD_Y] + mov [eax+CARD_OLD_Y], dx + inc ecx + jmp .save +.fin: + popad + ret + +check_stack_move: + pushad + mov esi, [active_stack] + imul esi, CARD_STRUCT_SIZE + add esi, deck_data + cmp dword [active_card_count], 1 + jne .tableau_check + + ; Check Foundations + mov ebx, FOUNDATION_X + xor ecx, ecx +.f_lp: + mov ax, [esi+CARD_X] + sub ax, bx + add ax, 25 + cmp ax, 50 + ja .next_f + mov ax, [esi+CARD_Y] + sub ax, FOUND_Y + add ax, 30 + cmp ax, 60 + ja .next_f + call check_foundation_logic + jc .found_match +.next_f: + add ebx, 60 + inc ecx + cmp ecx, 4 + jl .f_lp + +.tableau_check: + mov ebx, 50 +.col_lp: + xor ecx, ecx + mov dword [temp_val], -1 + mov dword [temp_counter], 0 +.find_l: + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + push ecx + call is_card_active + pop ecx + jc .sk_l + cmp word [edi+CARD_X], bx + jne .sk_l + movzx eax, word [edi+CARD_Y] + cmp eax, [temp_counter] + jl .sk_l + mov [temp_counter], eax + mov [temp_val], ecx +.sk_l: + inc ecx + cmp ecx, 52 + jl .find_l + + cmp dword [temp_val], -1 + je .empty_col + + ; Logic for placing on another card + mov ecx, [temp_val] + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + mov ax, [esi+CARD_X] + mov dx, [edi+CARD_X] + sub ax, dx + add ax, 25 + cmp ax, 50 + ja .nx_col + mov ax, [esi+CARD_Y] + mov dx, [edi+CARD_Y] + sub ax, dx + add ax, 30 + cmp ax, 60 + ja .nx_col + + ; Alternate colors and value-1 + mov al, [esi+CARD_SUIT] + mov dl, [edi+CARD_SUIT] + shr al, 1 + shr dl, 1 + cmp al, dl + je .nx_col + mov al, [esi+CARD_VALUE] + mov dl, [edi+CARD_VALUE] + inc al + cmp al, dl + jne .nx_col + mov dx, [edi+CARD_Y] + add dx, STACK_OFFSET + jmp .apply_move + +.empty_col: + mov ax, [esi+CARD_X] + sub ax, bx + add ax, 25 + cmp ax, 50 + ja .nx_col + mov ax, [esi+CARD_Y] + sub ax, 120 + add ax, 30 + cmp ax, 60 + ja .nx_col + cmp byte [esi+CARD_VALUE], 13 ; Must be King + jne .nx_col + mov dx, 120 + jmp .apply_move + +.nx_col: + add ebx, 100 + cmp ebx, 750 + jl .col_lp + + ; No valid move - Return to Old Pos + xor ecx, ecx +.back: + cmp ecx, [active_card_count] + jae .out + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov dx, [eax+CARD_OLD_X] + mov [eax+CARD_X], dx + mov dx, [eax+CARD_OLD_Y] + mov [eax+CARD_Y], dx + inc ecx + jmp .back +.out: + popad + ret + +.found_match: + add dword [score], 10 + mov [esi+CARD_X], bx + mov word [esi+CARD_Y], FOUND_Y + mov byte [esi+CARD_LOC], 8 + pushad + mov eax, [active_stack] + mov [temp_active], eax + call move_single_to_top + popad + call auto_reveal_all + call check_win + popad + ret + +.apply_move: + xor ecx, ecx + push eax + push edx + mov eax, ebx + sub eax, 50 + xor edx, edx + mov edi, 100 + div edi + mov [temp_val], eax + pop edx + pop eax + mov [temp_counter2], edx +.sticky_loop: + cmp ecx, [active_card_count] + jae .sticky_done + mov eax, [active_stack + ecx*4] + imul eax, CARD_STRUCT_SIZE + add eax, deck_data + mov [eax+CARD_X], bx + mov dx, word [temp_counter2] + mov [eax+CARD_Y], dx + mov dl, byte [temp_val] + mov [eax+CARD_LOC], dl + add word [temp_counter2], STACK_OFFSET + inc ecx + jmp .sticky_loop +.sticky_done: + xor ecx, ecx +.top_loop: + cmp ecx, [active_card_count] + jae .ok + push ecx + mov eax, [active_stack + ecx*4] + mov [temp_active], eax + call move_single_to_top + call update_active_stack_after_move + pop ecx + inc ecx + jmp .top_loop +.ok: + call auto_reveal_all + popad + ret + +update_active_stack_after_move: + pushad + mov edx, [temp_active] + xor ecx, ecx +.up_lp: + cmp ecx, [active_card_count] + jae .up_dn + mov eax, [active_stack + ecx*4] + cmp eax, edx + jbe .no_chg + dec eax + mov [active_stack + ecx*4], eax +.no_chg: + inc ecx + jmp .up_lp +.up_dn: + popad + ret + +check_foundation_logic: + pushad + xor eax, eax + mov dword [temp_val], 0 + mov dword [temp_counter], -1 + xor ebp, ebp +.find_top: + imul edi, ebp, CARD_STRUCT_SIZE + add edi, deck_data + cmp [edi+CARD_X], bx + jne .nx_c + cmp word [edi+CARD_Y], FOUND_Y + jne .nx_c + movzx edx, byte [edi+CARD_VALUE] + cmp edx, [temp_val] + jle .nx_c + mov [temp_val], edx + mov [temp_counter], ebp +.nx_c: + inc ebp + cmp ebp, 52 + jl .find_top + + mov al, [esi+CARD_VALUE] + mov dl, [esi+CARD_SUIT] + cmp dword [temp_counter], -1 + jne .not_empty + cmp al, 1 ; Must be Ace + je .valid + jmp .invalid +.not_empty: + mov edi, [temp_counter] + imul edi, 12 + add edi, deck_data + cmp dl, [edi+CARD_SUIT] + jne .invalid + mov dl, [edi+CARD_VALUE] + inc dl + cmp al, dl + je .valid +.invalid: + popad + clc + ret +.valid: + popad + stc + ret + +check_win: + pushad + xor ecx, ecx + xor eax, eax +.l: + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + cmp byte [esi+CARD_LOC], 8 + jne .no + inc eax +.no: + inc ecx + cmp ecx, 52 + jl .l + cmp eax, 52 + jne .out + cmp byte [game_won], 0 + jne .out + add dword [score], 100 + mov byte [game_won], 1 +.out: + popad + ret + +auto_reveal_all: + pushad + mov ebx, 50 +.col_loop: + xor esi, esi + mov dword [temp_val], -1 + xor ecx, ecx +.find_lowest: + imul edi, ecx, CARD_STRUCT_SIZE + add edi, deck_data + cmp [edi+CARD_X], bx + jne .next_card + movzx eax, word [edi+CARD_Y] + cmp eax, [temp_val] + jle .next_card + mov [temp_val], eax + mov esi, edi +.next_card: + inc ecx + cmp ecx, 52 + jl .find_lowest + cmp dword [temp_val], -1 + je .next_col + mov byte [esi+CARD_STATE], 1 +.next_col: + add ebx, 100 + cmp ebx, 750 + jl .col_loop + popad + ret + +move_single_to_top: + mov eax, [temp_active] + cmp eax, 51 + je .done + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + mov edi, temp_card_buf + mov ecx, 3 + rep movsd + + mov eax, [temp_active] + inc eax + imul esi, eax, CARD_STRUCT_SIZE + add esi, deck_data + imul edi, [temp_active], CARD_STRUCT_SIZE + add edi, deck_data + mov ecx, 51 + sub ecx, [temp_active] + imul ecx, 3 + rep movsd + + mov esi, temp_card_buf + mov edi, deck_data + (51 * CARD_STRUCT_SIZE) + mov ecx, 3 + rep movsd +.done: ret + +deal_from_stock: + pushad + mov ecx, 51 +.f: + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + cmp byte [esi+CARD_LOC], 7 + jne .n + cmp byte [esi+CARD_STATE], 0 + je .o +.n: dec ecx + jns .f + call reset_stock + popad + ret +.o: + mov byte [esi+CARD_STATE], 1 + mov byte [esi+CARD_LOC], 9 + mov word [esi+CARD_X], WASTE_X + mov word [esi+CARD_Y], FOUND_Y + mov [temp_active], ecx + call move_single_to_top + popad + ret + +reset_stock: + sub dword [score], 20 + xor ecx, ecx +.l: + imul esi, ecx, CARD_STRUCT_SIZE + add esi, deck_data + cmp byte [esi+CARD_LOC], 9 + jne .s + mov byte [esi+CARD_STATE], 0 + mov byte [esi+CARD_LOC], 7 + mov word [esi+CARD_X], STOCK_X + mov word [esi+CARD_Y], FOUND_Y +.s: inc ecx + cmp ecx, 52 + jl .l + ret + +init_deck: + mov edi, deck_data + xor eax, eax +.s: xor ebx, ebx +.r: inc ebx + mov [edi+CARD_VALUE], bl + mov [edi+CARD_SUIT], al + mov byte [edi+CARD_STATE], 0 + mov byte [edi+CARD_LOC], 7 + add edi, CARD_STRUCT_SIZE + cmp ebx, 13 + jne .r + inc eax + cmp eax, 4 + jne .s + ret + +shuffle_deck: + mov dword [temp_counter2], 51 +.sh: + mcall SYS_RANDOM + and eax, 0xFFFF + xor edx, edx + mov ebx, [temp_counter2] + inc ebx + div ebx + imul esi, [temp_counter2], CARD_STRUCT_SIZE + add esi, deck_data + imul edi, edx, CARD_STRUCT_SIZE + add edi, deck_data + mov ecx, 3 +.sw: + mov eax, [esi] + mov edx, [edi] + mov [esi], edx + mov [edi], eax + add esi, 4 + add edi, 4 + loop .sw + dec dword [temp_counter2] + jnz .sh + ret + +layout_tableau: + mov edi, deck_data + mov ebx, 50 + xor edx, edx +.cols: + mov ecx, 120 + mov eax, edx + inc eax + mov ebp, eax +.cards: + mov [edi+CARD_X], bx + mov [edi+CARD_Y], cx + mov byte [edi+CARD_LOC], dl + dec ebp + jnz .h + mov byte [edi+CARD_STATE], 1 + jmp .nx +.h: + mov byte [edi+CARD_STATE], 0 +.nx: + add edi, CARD_STRUCT_SIZE + add ecx, STACK_OFFSET + cmp edx, 6 + je .cl + cmp ebp, 0 + jne .cards + add ebx, 100 + inc edx + jmp .cols +.cl: + cmp ebp, 0 + jne .cards +.sf: + cmp edi, deck_data + (52 * CARD_STRUCT_SIZE) + jae .fin + mov word [edi+CARD_X], STOCK_X + mov word [edi+CARD_Y], FOUND_Y + mov byte [edi+CARD_LOC], 7 + mov byte [edi+CARD_STATE], 0 + add edi, CARD_STRUCT_SIZE + jmp .sf +.fin: ret + +; --- DATA --- +title db 'Solitare V1.1', 0 +score dd 0 +game_won db 0 +mouse_lock dd 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_stack rd 13 + +font_5x7: +; Font bitmap data remains unchanged... +db 01110000b,10001000b,10001000b,11111000b,10001000b,10001000b,10001000b ; 0:A +db 11110000b,00001000b,00010000b,00100000b,01000000b,10000000b,11111000b ; 1:2 +db 11110000b,00001000b,00001000b,01110000b,00001000b,00001000b,11110000b ; 2:3 +db 10001000b,10001000b,10001000b,11111000b,00001000b,00001000b,00001000b ; 3:4 +db 11111000b,10000000b,10000000b,11110000b,00001000b,00001000b,11111000b ; 4:5 +db 01110000b,10000000b,10000000b,11110000b,10001000b,10001000b,01110000b ; 5:6 +db 11111000b,00001000b,00010000b,00100000b,01000000b,01000000b,01000000b ; 6:7 +db 01110000b,10001000b,10001000b,01110000b,10001000b,10001000b,01110000b ; 7:8 +db 01110000b,10001000b,10001000b,01111000b,00001000b,00001000b,01110000b ; 8:9 +db 10111000b,10101000b,10101000b,10101000b,10101000b,10101000b,10111000b ; 9:10 +db 00011000b,00001000b,00001000b,00001000b,00001000b,10001000b,01110000b ; 10:J +db 01110000b,10001000b,10001000b,10001000b,10101000b,10010000b,01101000b ; 11:Q +db 10001000b,10010000b,10100000b,11000000b,10100000b,10010000b,10001000b ; 12:K +db 01010000b,11111000b,11111000b,01110000b,00100000b,00000000b,00000000b ; 13:Hearts +db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,00000000b ; 14:Diamonds +db 00100000b,00100000b,11111000b,11111000b,00100000b,00100000b,01110000b ; 15:Clubs +db 00100000b,01110000b,11111000b,11111000b,01110000b,00100000b,01110000b ; 16:Spades +db 01111000b,10000000b,01110000b,00001000b,00001000b,11110000b,00000000b ; 17:S +db 01110000b,10001000b,10000000b,10000000b,10000000b,10001000b,01110000b ; 18:C +db 01110000b,10001000b,10001000b,10001000b,10001000b,10001000b,01110000b ; 19:O +db 11110000b,10001000b,10001000b,11110000b,10100000b,10010000b,10001000b ; 20:R +db 01111000b,10000000b,10000000b,11110000b,10000000b,10000000b,11111000b ; 21:E +db 00000000b,00000000b,00000000b,11111000b,00000000b,00000000b,00000000b ; 22:- +db 01110000b,10001000b,10001000b,10001000b,10001000b,10001000b,01110000b ; 23:0 +db 00100000b,01100000b,00100000b,00100000b,00100000b,00100000b,01110000b ; 24:1 +db 01110000b,10001000b,00001000b,01110000b,10000000b,10000000b,11111000b ; 25:2 +db 11111000b,00001000b,00010000b,00110000b,00001000b,10001000b,01110000b ; 26:3 +db 00010000b,00110000b,01010000b,10010000b,11111000b,00010000b,00010000b ; 27:4 +db 11111000b,10000000b,11110000b,00001000b,00001000b,10001000b,01110000b ; 28:5 +db 01110000b,10000000b,11110000b,10001000b,10001000b,10001000b,01110000b ; 29:6 +db 11111000b,00001000b,00010000b,00100000b,01000000b,01000000b,01000000b ; 30:7 +db 01110000b,10001000b,10001000b,01110000b,10001000b,10001000b,01110000b ; 31:8 +db 01110000b,10001000b,10001000b,01111000b,00001000b,00001000b,01110000b ; 32:9 + +align 4 +deck_data: rb 52 * CARD_STRUCT_SIZE +i_end: + +align 4096 +screen_buffer: rb WIN_W * WIN_H * 3 + 32768 +stack_bottom: rb 8192 +stacktop: +mem_end: