From 8f499f78d50746e26d1bd782620cb03f4c191acd Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 4 Mar 2026 17:23:46 +0000 Subject: [PATCH] Upload files to "programs/games/solitare" Final version of game --- programs/games/solitare/solitare.asm | 477 ++++++++++++++++++++------- 1 file changed, 354 insertions(+), 123 deletions(-) diff --git a/programs/games/solitare/solitare.asm b/programs/games/solitare/solitare.asm index 8da904563..3a42fb8d8 100644 --- a/programs/games/solitare/solitare.asm +++ b/programs/games/solitare/solitare.asm @@ -1,13 +1,13 @@ -; Solitare V1.5.2 -; Platform: KolibriOS / MenuetOS -; Author: Max (Refactored/Fixed) -; Scoring Fix: Cards only give points ONCE, even if moved back and forth. +; Solitare V1.5.3 FINAL +; Platform: KolibriOS +; Author: Max +; Format: FASM (Flat Assembler) format binary as 'run' use32 org 0x0 -; --- SYSTEM INCLUDES --- +; --- EXTERNAL INCLUDES --- include 'macros.inc' include 'KOSfuncs.inc' @@ -27,12 +27,11 @@ COL_RED equ 0xCC0000 COL_BLACK equ 0x000000 COL_SLOT equ 0x185018 -; Card structure offsets CARD_STRUCT_SIZE equ 12 CARD_VALUE equ 0 CARD_SUIT equ 1 -CARD_STATE equ 2 ; Bit 0: Face-up, Bit 7: Already Scored -CARD_LOC equ 3 ; 0-6: Tableau, 7: Stock, 8: Foundation, 9: Waste +CARD_STATE equ 2 +CARD_LOC equ 3 CARD_X equ 4 CARD_Y equ 6 CARD_OLD_X equ 8 @@ -44,6 +43,9 @@ FOUNDATION_X equ 350 FOUND_Y equ 20 SCORE_Y equ 535 +BTN_REPLAY equ 100 +BTN_EXIT equ 101 + ; --- HEADER --- db 'MENUET01' dd 0x01 @@ -56,18 +58,19 @@ dd 0, 0 start: mov esp, stacktop - ; Get system skin height + ; Get system skin height for proper coordinate calculation mcall SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT mov [skin_h], eax - call init_deck - call shuffle_deck - call layout_tableau - mov dword [score], 0 - mov byte [game_won], 0 + call init_game_state event_loop: + ; --- GLOBAL EXIT CHECK --- + cmp byte [exit_request], 1 + je .force_exit + mcall SF_CHECK_EVENT + cmp eax, 1 ; Redraw event je on_redraw cmp eax, 2 ; Key event @@ -75,9 +78,37 @@ event_loop: cmp eax, 3 ; Button event 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 ja update_screen_only cmp byte [force_redraw], 1 @@ -86,6 +117,9 @@ event_loop: mcall SF_SLEEP, 1 jmp event_loop +.force_exit: + mcall SF_TERMINATE_PROCESS + on_key: mcall SF_GET_KEY jmp event_loop @@ -93,65 +127,258 @@ on_key: on_button: mcall SF_GET_BUTTON shr eax, 8 - cmp eax, 1 ; Window close button + cmp eax, 1 ; Close button jne event_loop + mcall SF_TERMINATE_PROCESS on_redraw: - 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, , title - mcall SF_REDRAW, SSF_END_DRAW + call draw_main_window mov byte [force_redraw], 1 jmp update_screen_only update_screen_only: mov byte [force_redraw], 0 call prepare_buffer + + ; Render buffer to window mov edx, 4 shl 16 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 -; --- 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: pushad mcall SF_MOUSE_GET, SSF_WINDOW_POSITION mov ebp, eax shr ebp, 16 - sub ebp, 5 ; Mouse X correction - + sub ebp, 5 and eax, 0xFFFF sub eax, [skin_h] - mov edi, eax ; Mouse Y in workspace - + mov edi, eax mcall SF_MOUSE_GET, SSF_BUTTON - test eax, 1 ; Left click? + test eax, 1 jnz .dragging_state - cmp dword [mouse_lock], 1 jne .exit - mov dword [mouse_lock], 0 cmp dword [active_card_count], 0 je .exit - call check_stack_move mov dword [active_card_count], 0 mov byte [force_redraw], 1 popad ret - .dragging_state: cmp dword [mouse_lock], 1 je .no_deal_click - - ; Stock pile interaction cmp ebp, STOCK_X jb .find_card cmp ebp, STOCK_X+CARD_W @@ -160,13 +387,11 @@ handle_mouse: jb .find_card cmp edi, FOUND_Y+CARD_H jae .find_card - mov dword [mouse_lock], 1 call deal_from_stock mov byte [force_redraw], 1 popad ret - .find_card: mov ebx, 51 .f_loop: @@ -174,7 +399,6 @@ handle_mouse: add edx, deck_data movsx esi, word [edx+CARD_X] movsx ecx, word [edx+CARD_Y] - cmp ebp, esi jb .next_s add esi, CARD_W @@ -185,21 +409,17 @@ handle_mouse: add ecx, CARD_H cmp edi, ecx jae .next_s - - test byte [edx+CARD_STATE], 1 ; Is card face up? + test byte [edx+CARD_STATE], 1 jz .next_s - mov dword [mouse_lock], 1 mov [active_stack], ebx mov dword [active_card_count], 1 - mov ax, word [edx+CARD_X] sub ax, bp mov [mouse_off_x], ax mov ax, word [edx+CARD_Y] sub ax, di mov [mouse_off_y], ax - mov eax, ebx call build_active_stack popad @@ -209,11 +429,9 @@ handle_mouse: jns .f_loop popad ret - .no_deal_click: cmp dword [active_card_count], 0 je .exit_drag -.drag_active: xor ecx, ecx .d_lp: cmp ecx, [active_card_count] @@ -221,20 +439,17 @@ handle_mouse: 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: @@ -244,8 +459,6 @@ handle_mouse: popad ret -; --- RENDERING --- - prepare_buffer: mov edi, screen_buffer mov ecx, WIN_W * WIN_H @@ -260,10 +473,8 @@ prepare_buffer: add edi, 3 dec ecx jnz .clear_loop - call draw_slots call render_score_ui - xor ecx, ecx .draw_loop: call is_card_active @@ -277,7 +488,6 @@ prepare_buffer: inc ecx cmp ecx, 52 jl .draw_loop - xor ecx, ecx .draw_active: cmp ecx, [active_card_count] @@ -290,7 +500,6 @@ prepare_buffer: pop ecx inc ecx jmp .draw_active - .done_rendering: ret @@ -772,11 +981,10 @@ check_stack_move: popad ret .found_match: - ; FIXED SCORING: Check Bit 7 of STATE (Scored flag) test byte [esi+CARD_STATE], 0x80 jnz .already_scored add dword [score], 10 - or byte [esi+CARD_STATE], 0x80 ; Set Scored Flag + or byte [esi+CARD_STATE], 0x80 .already_scored: mov word [esi+CARD_X], bx mov word [esi+CARD_Y], FOUND_Y @@ -922,6 +1130,7 @@ check_win: jne .out add dword [score], 100 mov byte [game_won], 1 + call init_cascade_vectors .out: popad ret @@ -949,7 +1158,7 @@ auto_reveal_all: jl .find_lowest cmp dword [temp_val], -1 je .next_col - or byte [esi+CARD_STATE], 1 ; Reveal face up + or byte [esi+CARD_STATE], 1 .next_col: add ebx, 100 cmp ebx, 740 @@ -991,7 +1200,7 @@ deal_from_stock: add esi, deck_data cmp byte [esi+CARD_LOC], 7 jne .n - test byte [esi+CARD_STATE], 1 ; Already visible? + test byte [esi+CARD_STATE], 1 jnz .n .o: or byte [esi+CARD_STATE], 1 @@ -1016,7 +1225,7 @@ reset_stock: add esi, deck_data cmp byte [esi+CARD_LOC], 9 jne .s - and byte [esi+CARD_STATE], 0xFE ; Set face down + and byte [esi+CARD_STATE], 0xFE mov byte [esi+CARD_LOC], 7 mov word [esi+CARD_X], STOCK_X mov word [esi+CARD_Y], FOUND_Y @@ -1032,7 +1241,7 @@ init_deck: .r: inc ebx mov byte [edi+CARD_VALUE], bl 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 add edi, CARD_STRUCT_SIZE cmp ebx, 13 @@ -1083,10 +1292,10 @@ layout_tableau: mov byte [edi+CARD_LOC], dl dec ebp jnz .h - or byte [edi+CARD_STATE], 1 ; Top card face up + or byte [edi+CARD_STATE], 1 jmp .nx .h: - and byte [edi+CARD_STATE], 0xFE ; Other cards face down + and byte [edi+CARD_STATE], 0xFE .nx: add edi, CARD_STRUCT_SIZE add ecx, STACK_OFFSET @@ -1111,68 +1320,90 @@ layout_tableau: jmp .sf .fin: ret -; --- DATA & FONTS --- -title db 'Solitare V1.5.2', 0 -score dd 0 -game_won db 0 -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 +; --- DATA SECTION --- +title db 'Solitare V1.5.3', 0 +title_win db 'Winner!', 0 +msg_congrats db 'Congrats You Win', 0 +msg_score_lbl db 'SCORE: ', 0 +txt_replay db 'REPLAY', 0 +txt_exit db 'EXIT', 0 +score_str rb 16 +score dd 0 +game_won db 0 +win_timer dd 0 +win_thread_active db 0 +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_stack rd 13 -skin_h dd 0 - -font_8x12: -; S, C, O, R, E, -, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 -db 01111100b,10000010b,10000000b,10000000b,01111100b,00000010b,00000010b,10000010b,01111100b,00000000b,00000000b,00000000b ; S -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 +active_stack rd 13 +skin_h dd 0 +cascade_timer dd 0 +active_cascade_idx dd -1 +win_pos_x dd 0 +win_pos_y dd 0 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: -align 4096 -screen_buffer: rb WIN_W * WIN_H * 3 + 32768 -stack_bottom: rb 8192 +align 64 +stack_bottom: rb 16384 stacktop: + +align 64 +win_stack_bottom: rb 8192 +win_stack_top: + +screen_buffer: rb WIN_W * WIN_H * 3 + 32768 mem_end: