Add native Durak, poker, blackjack, roulette, Buckshot and billiards scenes with animation assets and regression tests. Improve arrival, city, hall, profiles, shops, audio and exit handling; remove the portable C game core and refresh shipping executables.
587 lines
14 KiB
PHP
587 lines
14 KiB
PHP
.data
|
|
dkTestSeen dd 52 dup(0)
|
|
dkTestTotal dd 0
|
|
dkTestReady db "build\actions\durak-ready.bmp",0
|
|
dkTestDeal db "build\actions\durak-deal.bmp",0
|
|
dkTestAttack db "build\actions\durak-attack.bmp",0
|
|
dkTestDefense db "build\actions\durak-defense.bmp",0
|
|
dkTestFlight db "build\actions\durak-flight.bmp",0
|
|
dkTestTaking db "build\actions\durak-taking.bmp",0
|
|
dkTestResult db "build\actions\durak-result.bmp",0
|
|
dkTestLong db "build\actions\durak-long-hand.bmp",0
|
|
dkTestExit db "build\actions\durak-exit.bmp",0
|
|
dkTestStages dd 0
|
|
dkTestTakingFrames dd 0
|
|
.code
|
|
DurakTestMark3D PROC uses ebx card:DWORD
|
|
mov ebx, card
|
|
cmp ebx, 52
|
|
jae dk_mark_bad
|
|
invoke DurakCardRank, ebx
|
|
cmp eax, 4
|
|
jb dk_mark_bad
|
|
cmp dkTestSeen[ebx*4], 0
|
|
jne dk_mark_bad
|
|
inc dkTestSeen[ebx*4]
|
|
inc dkTestTotal
|
|
mov eax, 1
|
|
ret
|
|
dk_mark_bad:
|
|
xor eax, eax
|
|
ret
|
|
DurakTestMark3D ENDP
|
|
|
|
DurakTestHand3D PROC uses ebx esi ptrHand:DWORD,nCards:DWORD
|
|
xor esi, esi
|
|
mov ebx, ptrHand
|
|
dk_test_hand_loop:
|
|
cmp esi, nCards
|
|
jae dk_test_hand_ok
|
|
invoke DurakTestMark3D, DWORD PTR [ebx+esi*4]
|
|
test eax, eax
|
|
jz dk_test_hand_done
|
|
inc esi
|
|
jmp dk_test_hand_loop
|
|
dk_test_hand_ok:
|
|
mov eax, 1
|
|
dk_test_hand_done:
|
|
ret
|
|
DurakTestHand3D ENDP
|
|
|
|
DurakTestConservation3D PROC uses ebx esi edi
|
|
lea edi, dkTestSeen
|
|
xor eax, eax
|
|
mov ecx, 52
|
|
rep stosd
|
|
mov dkTestTotal, 0
|
|
cmp durakPlayerCnt, 36
|
|
ja dk_conserve_bad
|
|
cmp durakAICnt, 36
|
|
ja dk_conserve_bad
|
|
cmp dkDiscardCount3D, 36
|
|
ja dk_conserve_bad
|
|
cmp durakTableCnt, 6
|
|
ja dk_conserve_bad
|
|
cmp dkCursor3D, 36
|
|
ja dk_conserve_bad
|
|
mov eax, 36
|
|
sub eax, dkCursor3D
|
|
cmp eax, durakDeckLeft
|
|
jne dk_conserve_bad
|
|
invoke DurakTestHand3D, OFFSET durakPlayerHand, durakPlayerCnt
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
invoke DurakTestHand3D, OFFSET durakAIHand, durakAICnt
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
invoke DurakTestHand3D, OFFSET dkDiscard3D, dkDiscardCount3D
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
mov eax, dkCursor3D
|
|
lea ebx, dkDeck3D[eax*4]
|
|
invoke DurakTestHand3D, ebx, durakDeckLeft
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
xor esi, esi
|
|
dk_conserve_table:
|
|
cmp esi, durakTableCnt
|
|
jae dk_conserve_pending
|
|
invoke DurakTestMark3D, durakAttackCards[esi*4]
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
mov eax, durakDefenseCards[esi*4]
|
|
cmp eax, 0FFFFFFFFh
|
|
je @F
|
|
invoke DurakTestMark3D, eax
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
@@:
|
|
inc esi
|
|
jmp dk_conserve_table
|
|
dk_conserve_pending:
|
|
cmp dkPendingCard3D, 0FFFFFFFFh
|
|
je @F
|
|
invoke DurakTestMark3D, dkPendingCard3D
|
|
test eax, eax
|
|
jz dk_conserve_bad
|
|
@@:
|
|
cmp dkTestTotal, 36
|
|
jne dk_conserve_bad
|
|
mov eax, 1
|
|
ret
|
|
dk_conserve_bad:
|
|
xor eax, eax
|
|
ret
|
|
DurakTestConservation3D ENDP
|
|
|
|
RunDurakTest3D PROC uses ebx esi edi
|
|
local rounds:DWORD,ticks:DWORD,expected:DWORD,oldTimer:DWORD
|
|
local attackSuit:DWORD,attackRank:DWORD,defSuit:DWORD,defRank:DWORD
|
|
mov interactTargetId, INTERACT_DURAK
|
|
mov engineMode, MODE_WALK
|
|
call Trigger3DInteraction
|
|
cmp engineMode, MODE_DURAK
|
|
jne dk_test_301
|
|
cmp dkState3D, DK_IDLE
|
|
jne dk_test_301
|
|
mov bankroll, 10000
|
|
call RenderNativeDurak3D
|
|
invoke WriteActionSnapshot3D, OFFSET dkTestReady
|
|
test eax, eax
|
|
jz dk_test_301
|
|
; Face-up fills cannot index back colors with a clobbered DrawBox EAX.
|
|
xor esi, esi
|
|
dk_test_face_fill:
|
|
invoke DrawNativeCard3D, 100, 100, esi, 0, 34
|
|
cmp screenBuffer[(244*SCREEN_W+212)*4], 00EEEDE2h
|
|
jne dk_test_307
|
|
inc esi
|
|
cmp esi, 52
|
|
jb dk_test_face_fill
|
|
; Independent 36x36 beat matrix for all four trump suits.
|
|
mov durakTrumpSuit, 0
|
|
dk_test_trump:
|
|
xor esi, esi
|
|
dk_test_attack_matrix:
|
|
invoke DurakCardRank, esi
|
|
cmp eax, 4
|
|
jb dk_test_next_attack
|
|
mov attackRank, eax
|
|
invoke DurakCardSuit, esi
|
|
mov attackSuit, eax
|
|
xor edi, edi
|
|
dk_test_def_matrix:
|
|
invoke DurakCardRank, edi
|
|
cmp eax, 4
|
|
jb dk_test_next_def
|
|
mov defRank, eax
|
|
invoke DurakCardSuit, edi
|
|
mov defSuit, eax
|
|
mov expected, 0
|
|
cmp eax, attackSuit
|
|
jne dk_test_matrix_trump
|
|
mov eax, defRank
|
|
cmp eax, attackRank
|
|
jbe dk_test_matrix_call
|
|
jmp dk_test_matrix_yes
|
|
dk_test_matrix_trump:
|
|
cmp eax, durakTrumpSuit
|
|
jne dk_test_matrix_call
|
|
mov eax, attackSuit
|
|
cmp eax, durakTrumpSuit
|
|
je dk_test_matrix_call
|
|
dk_test_matrix_yes:
|
|
mov expected, 1
|
|
dk_test_matrix_call:
|
|
invoke CanDurakBeat, esi, edi
|
|
cmp eax, expected
|
|
jne dk_test_302
|
|
dk_test_next_def:
|
|
inc edi
|
|
cmp edi, 52
|
|
jb dk_test_def_matrix
|
|
dk_test_next_attack:
|
|
inc esi
|
|
cmp esi, 52
|
|
jb dk_test_attack_matrix
|
|
inc durakTrumpSuit
|
|
cmp durakTrumpSuit, 4
|
|
jb dk_test_trump
|
|
|
|
; Transfer must precede any defense and fit the new defender's hand.
|
|
mov durakTrumpSuit, 3
|
|
mov dkVariant3D, 1
|
|
mov dkState3D, DK_TURN
|
|
mov dkActor3D, 0
|
|
mov dkAttacker3D, 1
|
|
mov dkTaking3D, 0
|
|
mov dkLimit3D, 3
|
|
mov durakTableCnt, 1
|
|
mov durakAttackCards[0], 5
|
|
mov durakDefenseCards[0], 0FFFFFFFFh
|
|
mov durakPlayerCnt, 2
|
|
mov durakPlayerHand[0], 18
|
|
mov durakPlayerHand[4], 6
|
|
mov durakAICnt, 3
|
|
invoke DurakCanPlay3D, 0, 0, DK_TRANSFER
|
|
cmp eax, 1
|
|
jne dk_test_303
|
|
mov durakAICnt, 1
|
|
invoke DurakCanPlay3D, 0, 0, DK_TRANSFER
|
|
test eax, eax
|
|
jnz dk_test_303
|
|
mov durakAICnt, 3
|
|
mov durakDefenseCards[0], 6
|
|
invoke DurakCanPlay3D, 0, 0, DK_TRANSFER
|
|
test eax, eax
|
|
jnz dk_test_303
|
|
mov durakDefenseCards[0], 0FFFFFFFFh
|
|
invoke DurakCanPlay3D, 0, 1, DK_DEFEND
|
|
cmp eax, 1
|
|
jne dk_test_303
|
|
mov dkVariant3D, 0
|
|
invoke DurakCanPlay3D, 0, 0, DK_TRANSFER
|
|
test eax, eax
|
|
jnz dk_test_303
|
|
|
|
; Neither the opponent's identities nor the unrevealed talon influence AI.
|
|
call ClearDurakTable
|
|
mov dkAttacker3D, 1
|
|
mov dkActor3D, 1
|
|
mov dkLimit3D, 6
|
|
mov durakAICnt, 2
|
|
mov durakAIHand[0], 5
|
|
mov durakAIHand[4], 43
|
|
mov durakPlayerCnt, 6
|
|
mov durakPlayerHand[0], 12
|
|
mov dkDeck3D[35*4], 51
|
|
invoke DurakFindMove3D, 1, DK_ATTACK
|
|
cmp eax, 0
|
|
jne dk_test_303
|
|
mov durakPlayerHand[0], 0FFFFFFFFh
|
|
mov dkDeck3D[35*4], 0FFFFFFFFh
|
|
invoke DurakFindMove3D, 1, DK_ATTACK
|
|
cmp eax, 0
|
|
jne dk_test_303
|
|
|
|
; Full real handlers, both variants, visible and pending card conservation.
|
|
mov rounds, 500
|
|
mov dkTestStages, 0
|
|
mov dkTestTakingFrames, 0
|
|
dk_test_round:
|
|
mov engineMode, MODE_DURAK
|
|
mov cardExitActive3D, 0
|
|
mov bankroll, 10000
|
|
mov dkState3D, DK_IDLE
|
|
mov dkBet3D, 100
|
|
mov eax, rounds
|
|
and eax, 1
|
|
mov dkVariant3D, eax
|
|
mov eax, rounds
|
|
imul eax, 7919
|
|
mov rngSeed3D, eax
|
|
call StartNativeDurak3D
|
|
cmp dkState3D, DK_DEAL
|
|
jne dk_test_304
|
|
cmp bankroll, 9900
|
|
jne dk_test_304
|
|
mov eax, dkDeck3D[35*4]
|
|
cmp eax, durakTrumpCard
|
|
jne dk_test_304
|
|
call DurakTestConservation3D
|
|
test eax, eax
|
|
jz dk_test_305
|
|
cmp rounds, 500
|
|
jne @F
|
|
mov dkTimer3D, 1850
|
|
call RenderNativeDurak3D
|
|
invoke WriteActionSnapshot3D, OFFSET dkTestDeal
|
|
test eax, eax
|
|
jz dk_test_304
|
|
@@:
|
|
mov ticks, 0
|
|
mov deltaTime3D, 1000
|
|
dk_test_tick:
|
|
call ClearKeys3D
|
|
cmp dkState3D, DK_TURN
|
|
jne dk_test_advance
|
|
cmp dkActor3D, 0
|
|
jne dk_test_advance
|
|
cmp dkAttacker3D, 0
|
|
je dk_test_player_attack
|
|
invoke DurakFindMove3D, 0, DK_TRANSFER
|
|
cmp eax, 0FFFFFFFFh
|
|
je @F
|
|
mov dkSelection3D, eax
|
|
mov pressedKeys3D[54h], 1
|
|
jmp dk_test_advance
|
|
@@:
|
|
invoke DurakFindMove3D, 0, DK_DEFEND
|
|
cmp eax, 0FFFFFFFFh
|
|
je dk_test_player_take
|
|
mov dkSelection3D, eax
|
|
mov pressedKeys3D[0Dh], 1
|
|
jmp dk_test_advance
|
|
dk_test_player_take:
|
|
mov pressedKeys3D[42h], 1
|
|
jmp dk_test_advance
|
|
dk_test_player_attack:
|
|
invoke DurakFindMove3D, 0, DK_ATTACK
|
|
cmp eax, 0FFFFFFFFh
|
|
je dk_test_player_finish
|
|
mov dkSelection3D, eax
|
|
mov pressedKeys3D[0Dh], 1
|
|
jmp dk_test_advance
|
|
dk_test_player_finish:
|
|
mov pressedKeys3D[44h], 1
|
|
dk_test_advance:
|
|
call HandleNativeDurak3D
|
|
call DurakTestConservation3D
|
|
test eax, eax
|
|
jz dk_test_305
|
|
inc ticks
|
|
cmp ticks, 12000
|
|
ja dk_test_306
|
|
cmp dkState3D, DK_RESULT
|
|
je dk_test_round_end
|
|
; Snapshot real phases, rendering must not alter RNG, cards or bank.
|
|
mov esi, 1
|
|
mov edi, OFFSET dkTestAttack
|
|
cmp dkState3D, DK_TURN
|
|
jne dk_test_flight_snap
|
|
cmp dkActor3D, 0
|
|
jne dk_test_tick
|
|
cmp dkTaking3D, 0
|
|
jne dk_test_taking_snap
|
|
cmp dkAttacker3D, 0
|
|
je dk_test_snapshot
|
|
mov esi, 2
|
|
mov edi, OFFSET dkTestDefense
|
|
jmp dk_test_snapshot
|
|
dk_test_taking_snap:
|
|
mov esi, 8
|
|
mov edi, OFFSET dkTestTaking
|
|
jmp dk_test_snapshot
|
|
dk_test_flight_snap:
|
|
cmp dkState3D, DK_FLIGHT
|
|
jne dk_test_tick
|
|
mov esi, 4
|
|
mov edi, OFFSET dkTestFlight
|
|
mov dkTimer3D, 180
|
|
dk_test_snapshot:
|
|
test dkTestStages, esi
|
|
jnz dk_test_tick
|
|
or dkTestStages, esi
|
|
mov ebx, rngSeed3D
|
|
call RenderNativeDurak3D
|
|
cmp ebx, rngSeed3D
|
|
jne dk_test_307
|
|
call DurakTestConservation3D
|
|
test eax, eax
|
|
jz dk_test_307
|
|
invoke WriteActionSnapshot3D, edi
|
|
test eax, eax
|
|
jz dk_test_307
|
|
jmp dk_test_tick
|
|
dk_test_round_end:
|
|
mov eax, 9900
|
|
cmp dkOutcome3D, 1
|
|
je @F
|
|
add eax, 100
|
|
cmp dkOutcome3D, 2
|
|
je @F
|
|
add eax, 100
|
|
@@:
|
|
cmp bankroll, eax
|
|
jne dk_test_308
|
|
mov expected, eax
|
|
invoke NativeDurakSettle3D, dkOutcome3D
|
|
mov eax, expected
|
|
cmp bankroll, eax
|
|
jne dk_test_308
|
|
cmp rounds, 500
|
|
jne @F
|
|
call RenderNativeDurak3D
|
|
invoke WriteActionSnapshot3D, OFFSET dkTestResult
|
|
test eax, eax
|
|
jz dk_test_307
|
|
@@:
|
|
dec rounds
|
|
jnz dk_test_round
|
|
cmp dkTestStages, 15
|
|
jne dk_test_307
|
|
|
|
; Fixed bout limit does not shrink as a defender spends cards.
|
|
mov dkState3D, DK_TURN
|
|
mov dkActor3D, 0
|
|
mov dkAttacker3D, 0
|
|
mov dkTaking3D, 0
|
|
mov dkLimit3D, 3
|
|
mov durakPlayerCnt, 1
|
|
mov durakPlayerHand[0], 18
|
|
mov durakAICnt, 1
|
|
mov durakTableCnt, 2
|
|
mov durakAttackCards[0], 5
|
|
mov durakDefenseCards[0], 6
|
|
mov durakAttackCards[4], 19
|
|
mov durakDefenseCards[4], 20
|
|
invoke DurakCanPlay3D, 0, 0, DK_ATTACK
|
|
cmp eax, 1
|
|
jne dk_test_309
|
|
mov durakTableCnt, 3
|
|
invoke DurakCanPlay3D, 0, 0, DK_ATTACK
|
|
test eax, eax
|
|
jnz dk_test_309
|
|
|
|
; Refill original attacker first, exposed trump last, next attacker skips taker.
|
|
mov dkState3D, DK_SWEEP
|
|
mov dkOriginal3D, 0
|
|
mov dkAttacker3D, 0
|
|
mov dkTaking3D, 1
|
|
mov dkBouts3D, 1
|
|
mov durakTableCnt, 1
|
|
mov durakAttackCards[0], 5
|
|
mov durakDefenseCards[0], 0FFFFFFFFh
|
|
mov durakPlayerCnt, 5
|
|
mov durakAICnt, 3
|
|
mov dkCursor3D, 34
|
|
mov durakDeckLeft, 2
|
|
mov dkDeck3D[34*4], 12
|
|
mov dkDeck3D[35*4], 51
|
|
call DurakResolveBout3D
|
|
cmp durakPlayerHand[5*4], 12
|
|
jne dk_test_310
|
|
cmp durakAIHand[4*4], 51
|
|
jne dk_test_310
|
|
cmp durakDeckLeft, 0
|
|
jne dk_test_310
|
|
cmp dkAttacker3D, 0
|
|
jne dk_test_310
|
|
|
|
; Every card remains selectable even with all 36 cards in one hand.
|
|
mov durakPlayerCnt, 36
|
|
xor esi, esi
|
|
xor edi, edi
|
|
dk_test_long_cards:
|
|
invoke DurakCardRank, esi
|
|
cmp eax, 4
|
|
jb @F
|
|
mov durakPlayerHand[edi*4], esi
|
|
inc edi
|
|
@@:
|
|
inc esi
|
|
cmp esi, 52
|
|
jb dk_test_long_cards
|
|
call ClearDurakTable
|
|
mov dkState3D, DK_TURN
|
|
mov dkActor3D, 0
|
|
mov dkAttacker3D, 0
|
|
mov dkSelection3D, 0
|
|
mov dkTaking3D, 0
|
|
mov dkLimit3D, 6
|
|
mov durakAICnt, 0
|
|
mov durakDeckLeft, 0
|
|
xor esi, esi
|
|
dk_test_selection:
|
|
mov eax, dkSelection3D
|
|
cmp eax, esi
|
|
jne dk_test_311
|
|
invoke DurakMoveSelection3D, 1
|
|
inc esi
|
|
cmp esi, 36
|
|
jb dk_test_selection
|
|
cmp dkSelection3D, 0
|
|
jne dk_test_311
|
|
invoke DurakMoveSelection3D, -1
|
|
cmp dkSelection3D, 35
|
|
jne dk_test_311
|
|
cmp dkPage3D, 32
|
|
jne dk_test_311
|
|
call RenderNativeDurak3D
|
|
invoke WriteActionSnapshot3D, OFFSET dkTestLong
|
|
test eax, eax
|
|
jz dk_test_311
|
|
mov mouseX3D, 21
|
|
mov mouseY3D, 180
|
|
mov mouseClick3D, 1
|
|
call HandleNativeDurak3D
|
|
cmp dkSelection3D, 32
|
|
jne dk_test_311
|
|
mov mouseX3D, 5
|
|
mov mouseY3D, 186
|
|
mov mouseClick3D, 1
|
|
call HandleNativeDurak3D
|
|
cmp dkSelection3D, 24
|
|
jne dk_test_311
|
|
|
|
; Exit confirmation freezes every active animation/turn phase.
|
|
mov esi, DK_DEAL
|
|
dk_test_exit_phase:
|
|
mov engineMode, MODE_DURAK
|
|
mov dkState3D, esi
|
|
mov dkTimer3D, 90
|
|
mov bankroll, 9900
|
|
mov dkStake3D, 100
|
|
call ClearKeys3D
|
|
call CardTableEscape3D
|
|
cmp eax, 1
|
|
jne dk_test_312
|
|
cmp cardExitActive3D, 1
|
|
jne dk_test_312
|
|
mov deltaTime3D, 1000
|
|
call HandleNativeDurak3D
|
|
cmp dkTimer3D, 90
|
|
jne dk_test_312
|
|
cmp dkState3D, esi
|
|
jne dk_test_312
|
|
cmp esi, DK_DEAL
|
|
jne @F
|
|
call RenderNativeDurak3D
|
|
invoke WriteActionSnapshot3D, OFFSET dkTestExit
|
|
test eax, eax
|
|
jz dk_test_312
|
|
@@:
|
|
mov pressedKeys3D[4Eh], 1
|
|
call HandleNativeDurak3D
|
|
cmp cardExitActive3D, 0
|
|
jne dk_test_312
|
|
cmp engineMode, MODE_DURAK
|
|
jne dk_test_312
|
|
cmp dkTimer3D, 90
|
|
jne dk_test_312
|
|
call RequestCardExit3D
|
|
mov pressedKeys3D[59h], 1
|
|
call HandleNativeDurak3D
|
|
cmp engineMode, MODE_WALK
|
|
jne dk_test_312
|
|
cmp bankroll, 9900
|
|
jne dk_test_312
|
|
cmp dkState3D, DK_RESULT
|
|
jne dk_test_312
|
|
inc esi
|
|
cmp esi, DK_RESULT
|
|
jb dk_test_exit_phase
|
|
mov engineMode, MODE_DURAK
|
|
mov dkState3D, DK_IDLE
|
|
call CardTableEscape3D
|
|
cmp engineMode, MODE_WALK
|
|
jne dk_test_312
|
|
xor eax, eax
|
|
ret
|
|
dk_test_301:
|
|
mov eax, 301
|
|
ret
|
|
dk_test_302:
|
|
mov eax, 302
|
|
ret
|
|
dk_test_303:
|
|
mov eax, 303
|
|
ret
|
|
dk_test_304:
|
|
mov eax, 304
|
|
ret
|
|
dk_test_305:
|
|
mov eax, 305
|
|
ret
|
|
dk_test_306:
|
|
mov eax, 306
|
|
ret
|
|
dk_test_307:
|
|
mov eax, 307
|
|
ret
|
|
dk_test_308:
|
|
mov eax, 308
|
|
ret
|
|
dk_test_309:
|
|
mov eax, 309
|
|
ret
|
|
dk_test_310:
|
|
mov eax, 310
|
|
ret
|
|
dk_test_311:
|
|
mov eax, 311
|
|
ret
|
|
dk_test_312:
|
|
mov eax, 312
|
|
ret
|
|
RunDurakTest3D ENDP
|