Implement 32x32 BFS visitor navigation and daily contracts system with companion .npc journals; add native assembly scenes for Clover slots, Pyramid cards, Blackjack Party and Russian Party; package animation and sprite packs; add comprehensive offline test suites and rebuild shipping binaries.
364 lines
9.6 KiB
PHP
364 lines
9.6 KiB
PHP
; Native state-machine regression. Tests never write the real player's profile.
|
|
.data
|
|
bjPartySeenLo dd 0
|
|
bjPartySeenHi dd 0
|
|
bjPartySeenCount dd 0
|
|
bjPartyShot1 db "build\actions\blackjack-party-1.bmp",0
|
|
bjPartyShot2 db "build\actions\blackjack-party-2.bmp",0
|
|
bjPartyShot3 db "build\actions\blackjack-party-3.bmp",0
|
|
bjPartyShots dd OFFSET bjPartyShot1,OFFSET bjPartyShot2,OFFSET bjPartyShot3
|
|
bjPartyFlightShot db "build\actions\blackjack-party-flight.bmp",0
|
|
bjPartyResultShot db "build\actions\blackjack-party-result.bmp",0
|
|
bjPartyExitShot db "build\actions\blackjack-party-exit.bmp",0
|
|
.code
|
|
CheckBJPartyHand3D PROC uses ebx esi hand:DWORD,count:DWORD
|
|
mov esi,hand
|
|
cmp count,2
|
|
jb bj_party_hand_bad
|
|
cmp count,12
|
|
ja bj_party_hand_bad
|
|
xor ebx,ebx
|
|
bj_party_hand_card:
|
|
mov eax,[esi+ebx*4]
|
|
cmp eax,52
|
|
jae bj_party_hand_bad
|
|
cmp eax,32
|
|
jb bj_party_hand_low
|
|
sub eax,32
|
|
bts bjPartySeenHi,eax
|
|
jc bj_party_hand_bad
|
|
jmp bj_party_hand_next
|
|
bj_party_hand_low:
|
|
bts bjPartySeenLo,eax
|
|
jc bj_party_hand_bad
|
|
bj_party_hand_next:
|
|
inc bjPartySeenCount
|
|
inc ebx
|
|
cmp ebx,count
|
|
jb bj_party_hand_card
|
|
xor eax,eax
|
|
ret
|
|
bj_party_hand_bad:
|
|
mov eax,8104
|
|
ret
|
|
CheckBJPartyHand3D ENDP
|
|
|
|
RunBJPartyTest3D PROC uses ebx esi edi
|
|
local rounds:DWORD,ticks:DWORD,savedBank:DWORD,savedSeed:DWORD,savedCursor:DWORD,fixtureSeed:DWORD
|
|
mov engineMode,MODE_BLACKJACK
|
|
mov cbBet3D,100
|
|
mov cbBotCount3D,0
|
|
call InitNativeBlackjack3D
|
|
cmp cbPartyArt3D.pixels,0
|
|
je bj_party_fail_art
|
|
cmp cbPartyRoom3D.pixels,0
|
|
je bj_party_fail_art
|
|
; Real mouse selection; changing seats resets the displayed hand, not money.
|
|
mov bankroll,10000
|
|
mov mouseClick3D,1
|
|
mov mouseX3D,270
|
|
mov mouseY3D,40
|
|
call BJPartyInput3D
|
|
cmp cbBotCount3D,2
|
|
jne bj_party_fail_input
|
|
cmp mouseClick3D,0
|
|
jne bj_party_fail_input
|
|
cmp bankroll,10000
|
|
jne bj_party_fail_input
|
|
call StartNativeBlackjack3D
|
|
invoke SetBJPartyCount3D,3
|
|
cmp cbBotCount3D,2
|
|
jne bj_party_fail_input
|
|
cmp cbCursor3D,8
|
|
jne bj_party_fail_deck
|
|
cmp bankroll,9900
|
|
jne bj_party_fail_wallet
|
|
; A bot decision may see its own total and the dealer's upcard, nothing else.
|
|
mov cbBots3D.score,16
|
|
mov cbBots3D.count,2
|
|
mov cbDealer3D,4
|
|
invoke BJBotDecision3D,0
|
|
mov savedCursor,eax
|
|
mov cbDealer3D[4],12
|
|
mov cbPlayer3D,51
|
|
mov cbDeck3D[120],33
|
|
invoke BJBotDecision3D,0
|
|
cmp eax,savedCursor
|
|
jne bj_party_fail_hidden
|
|
mov cbBots3D[SIZEOF BJBot3D].score,18
|
|
mov cbBots3D[SIZEOF BJBot3D].count,2
|
|
invoke BJBotDecision3D,1
|
|
cmp eax,1
|
|
jne bj_party_fail_hidden
|
|
mov cbBots3D[SIZEOF BJBot3D*2].score,13
|
|
mov cbBots3D[SIZEOF BJBot3D*2].count,2
|
|
invoke BJBotDecision3D,2
|
|
test eax,eax
|
|
jnz bj_party_fail_hidden
|
|
; Natural beats a drawn 21, but a dealer natural beats a drawn guest 21.
|
|
mov cbBotCount3D,3
|
|
mov cbBotsSettled3D,0
|
|
mov cbDealerScore3D,21
|
|
mov cbDealerCount3D,2
|
|
mov cbBots3D.score,21
|
|
mov cbBots3D.count,2
|
|
mov cbBots3D[SIZEOF BJBot3D].score,21
|
|
mov cbBots3D[SIZEOF BJBot3D].count,3
|
|
mov cbBots3D[SIZEOF BJBot3D*2].score,22
|
|
call ResolveBJParty3D
|
|
cmp cbBots3D.outcome,2
|
|
jne bj_party_fail_wallet
|
|
cmp cbBots3D[SIZEOF BJBot3D].outcome,1
|
|
jne bj_party_fail_wallet
|
|
cmp cbBots3D[SIZEOF BJBot3D*2].outcome,1
|
|
jne bj_party_fail_wallet
|
|
mov cbDealerCount3D,3
|
|
mov cbBotsSettled3D,0
|
|
call ResolveBJParty3D
|
|
cmp cbBots3D.outcome,3
|
|
jne bj_party_fail_wallet
|
|
; Run 200 full rounds with each party size, alternating hits and doubles.
|
|
mov edi,1
|
|
bj_party_test_size:
|
|
mov cbBotCount3D,edi
|
|
mov rounds,200
|
|
bj_party_test_round:
|
|
mov eax,rounds
|
|
imul eax,2137
|
|
add eax,edi
|
|
mov rngSeed3D,eax
|
|
mov bankroll,10000
|
|
mov cbState3D,CB_IDLE
|
|
mov engineMode,MODE_BLACKJACK
|
|
call StartNativeBlackjack3D
|
|
mov eax,edi
|
|
add eax,2
|
|
shl eax,1
|
|
cmp cbCursor3D,eax
|
|
jne bj_party_fail_deck
|
|
mov ticks,0
|
|
mov deltaTime3D,50
|
|
bj_party_test_tick:
|
|
cmp cbState3D,CB_RESULT
|
|
je bj_party_test_result
|
|
cmp cbState3D,CB_PLAYER
|
|
jne bj_party_test_handle
|
|
mov pressedKeys3D[53h],1
|
|
cmp cbPlayerScore3D,16
|
|
jae @F
|
|
mov pressedKeys3D[53h],0
|
|
mov pressedKeys3D[48h],1
|
|
@@:
|
|
cmp cbPlayerCount3D,2
|
|
jne bj_party_test_handle
|
|
test rounds,1
|
|
jz bj_party_test_handle
|
|
mov pressedKeys3D[44h],1
|
|
bj_party_test_handle:
|
|
call HandleNativeBlackjack3D
|
|
call ClearKeys3D
|
|
cmp cbBotCount3D,edi
|
|
jne bj_party_fail_input
|
|
cmp cbCursor3D,52
|
|
ja bj_party_fail_deck
|
|
inc ticks
|
|
cmp ticks,2000
|
|
jae bj_party_fail_stuck
|
|
jmp bj_party_test_tick
|
|
bj_party_test_result:
|
|
mov eax,10000
|
|
sub eax,cbStake3D
|
|
cmp cbOutcome3D,1
|
|
je bj_party_expected
|
|
add eax,cbStake3D
|
|
cmp cbOutcome3D,2
|
|
je bj_party_expected
|
|
add eax,cbStake3D
|
|
cmp cbOutcome3D,3
|
|
jne bj_party_expected
|
|
mov edx,cbStake3D
|
|
shr edx,1
|
|
add eax,edx
|
|
bj_party_expected:
|
|
cmp bankroll,eax
|
|
jne bj_party_fail_wallet
|
|
mov savedBank,eax
|
|
invoke NativeBJSettle3D,cbOutcome3D
|
|
mov eax,savedBank
|
|
cmp bankroll,eax
|
|
jne bj_party_fail_wallet
|
|
mov bjPartySeenLo,0
|
|
mov bjPartySeenHi,0
|
|
mov bjPartySeenCount,0
|
|
invoke CheckBJPartyHand3D,OFFSET cbPlayer3D,cbPlayerCount3D
|
|
test eax,eax
|
|
jnz bj_party_test_done
|
|
invoke CheckBJPartyHand3D,OFFSET cbDealer3D,cbDealerCount3D
|
|
test eax,eax
|
|
jnz bj_party_test_done
|
|
xor ebx,ebx
|
|
bj_party_check_guests:
|
|
mov esi,ebx
|
|
imul esi,SIZEOF BJBot3D
|
|
add esi,OFFSET cbBots3D
|
|
cmp [esi].BJBot3D.state,BJ_BOT_DONE
|
|
jne bj_party_fail_stuck
|
|
cmp [esi].BJBot3D.outcome,3
|
|
ja bj_party_fail_wallet
|
|
invoke CheckBJPartyHand3D,esi,[esi].BJBot3D.count
|
|
test eax,eax
|
|
jnz bj_party_test_done
|
|
inc ebx
|
|
cmp ebx,edi
|
|
jb bj_party_check_guests
|
|
mov eax,bjPartySeenCount
|
|
cmp cbCursor3D,eax
|
|
jne bj_party_fail_deck
|
|
xor ebx,ebx
|
|
bj_party_check_prefix:
|
|
mov eax,cbDeck3D[ebx*4]
|
|
cmp eax,32
|
|
jb @F
|
|
sub eax,32
|
|
bt bjPartySeenHi,eax
|
|
jnc bj_party_fail_deck
|
|
jmp bj_party_prefix_next
|
|
@@:
|
|
bt bjPartySeenLo,eax
|
|
jnc bj_party_fail_deck
|
|
bj_party_prefix_next:
|
|
inc ebx
|
|
cmp ebx,cbCursor3D
|
|
jb bj_party_check_prefix
|
|
dec rounds
|
|
jnz bj_party_test_round
|
|
cmp edi,3
|
|
jne @F
|
|
call RenderNativeBlackjack3D
|
|
invoke WriteActionSnapshot3D,OFFSET bjPartyResultShot
|
|
@@:
|
|
; Actual framebuffer for each seat count, then repeat without state changes.
|
|
mov cbState3D,CB_IDLE
|
|
mov bankroll,10000
|
|
call StartNativeBlackjack3D
|
|
mov cbState3D,CB_PLAYER
|
|
mov eax,cbInitialFlights3D
|
|
imul eax,TABLE_FLIGHT_MS
|
|
mov cbTimer3D,eax
|
|
mov eax,rngSeed3D
|
|
mov savedSeed,eax
|
|
mov eax,cbCursor3D
|
|
mov savedCursor,eax
|
|
mov eax,bankroll
|
|
mov savedBank,eax
|
|
call RenderNativeBlackjack3D
|
|
mov eax,edi
|
|
dec eax
|
|
invoke WriteActionSnapshot3D,bjPartyShots[eax*4]
|
|
mov ebx,8
|
|
bj_party_render_repeat:
|
|
call RenderNativeBlackjack3D
|
|
dec ebx
|
|
jnz bj_party_render_repeat
|
|
mov eax,savedSeed
|
|
cmp rngSeed3D,eax
|
|
jne bj_party_fail_render
|
|
mov eax,savedCursor
|
|
cmp cbCursor3D,eax
|
|
jne bj_party_fail_render
|
|
mov eax,savedBank
|
|
cmp bankroll,eax
|
|
jne bj_party_fail_render
|
|
inc edi
|
|
cmp edi,4
|
|
jb bj_party_test_size
|
|
; Player bust does not prematurely end or hide the other guests' turns.
|
|
invoke FinishBJPlayer3D,1
|
|
cmp cbState3D,CB_BOTS
|
|
jne bj_party_fail_stuck
|
|
; Choose a genuine deal that needs a guest card for the animation capture.
|
|
mov fixtureSeed,1001
|
|
bj_party_find_flight:
|
|
mov eax,fixtureSeed
|
|
mov rngSeed3D,eax
|
|
mov cbState3D,CB_IDLE
|
|
mov bankroll,10000
|
|
call StartNativeBlackjack3D
|
|
cmp cbPlayerScore3D,21
|
|
je bj_party_next_fixture
|
|
cmp cbDealerScore3D,21
|
|
je bj_party_next_fixture
|
|
cmp cbBots3D.score,17
|
|
jb bj_party_flight_found
|
|
bj_party_next_fixture:
|
|
inc fixtureSeed
|
|
cmp fixtureSeed,1101
|
|
jae bj_party_fail_stuck
|
|
jmp bj_party_find_flight
|
|
bj_party_flight_found:
|
|
invoke FinishBJPlayer3D,-1
|
|
mov deltaTime3D,50
|
|
mov cbBotTimer3D,BJ_PARTY_MS
|
|
call UpdateBJParty3D
|
|
cmp cbBots3D.state,BJ_BOT_FLIGHT
|
|
jne bj_party_fail_stuck
|
|
mov cbBotTimer3D,180
|
|
call RenderNativeBlackjack3D
|
|
invoke WriteActionSnapshot3D,OFFSET bjPartyFlightShot
|
|
; Confirmation pauses bot timers; leaving counts once as player's loss.
|
|
call RequestCardExit3D
|
|
cmp cardExitActive3D,1
|
|
jne bj_party_fail_input
|
|
mov savedCursor,180
|
|
call HandleNativeBlackjack3D
|
|
cmp cbBotTimer3D,180
|
|
jne bj_party_fail_input
|
|
call RenderNativeBlackjack3D
|
|
invoke WriteActionSnapshot3D,OFFSET bjPartyExitShot
|
|
mov eax,bankroll
|
|
mov savedBank,eax
|
|
mov pressedKeys3D[59h],1
|
|
call HandleNativeBlackjack3D
|
|
cmp engineMode,MODE_WALK
|
|
jne bj_party_fail_input
|
|
mov eax,savedBank
|
|
cmp bankroll,eax
|
|
jne bj_party_fail_wallet
|
|
mov engineMode,MODE_BLACKJACK
|
|
; A result table can return to solo by keyboard, without another settlement.
|
|
mov pressedKeys3D[30h],1
|
|
call BJPartyInput3D
|
|
cmp cbBotCount3D,0
|
|
jne bj_party_fail_input
|
|
cmp cbState3D,CB_IDLE
|
|
jne bj_party_fail_input
|
|
cmp cbPlayerCount3D,0
|
|
jne bj_party_fail_input
|
|
mov eax,savedBank
|
|
cmp bankroll,eax
|
|
jne bj_party_fail_wallet
|
|
xor eax,eax
|
|
ret
|
|
bj_party_fail_art:
|
|
mov eax,8101
|
|
ret
|
|
bj_party_fail_input:
|
|
mov eax,8102
|
|
ret
|
|
bj_party_fail_wallet:
|
|
mov eax,8103
|
|
ret
|
|
bj_party_fail_deck:
|
|
mov eax,8104
|
|
ret
|
|
bj_party_fail_hidden:
|
|
mov eax,8105
|
|
ret
|
|
bj_party_fail_stuck:
|
|
mov eax,8106
|
|
ret
|
|
bj_party_fail_render:
|
|
mov eax,8107
|
|
bj_party_test_done:
|
|
ret
|
|
RunBJPartyTest3D ENDP
|