KAZIK/tools/tests/slots_test.inc
Artvasil09 4f8ae0893b Implement native slots, coin toss, European roulette and hall furniture
Add native assembly scenes and assets for Slots (777), Coin flip, and European Roulette; add 3D hall furniture packs and prompts; improve Russian UI strings in CP1251; update launcher hash and rebuild shipping binaries.
2026-10-10 14:43:30 +03:00

423 lines
11 KiB
PHP

.data
slotsTestStage3D dd 0
slotsTest0 db "build\actions\slots-ready.bmp",0
slotsTest1 db "build\actions\slots-600.bmp",0
slotsTest2 db "build\actions\slots-1799.bmp",0
slotsTest3 db "build\actions\slots-1800.bmp",0
slotsTest4 db "build\actions\slots-2400.bmp",0
slotsTest5 db "build\actions\slots-win.bmp",0
slotsTest6 db "build\actions\slots-paytable.bmp",0
slotsTest7 db "build\actions\slots-exit.bmp",0
slotsTestTimes dd 600,1799,1800,2400
slotsTestPaths dd OFFSET slotsTest1,OFFSET slotsTest2,OFFSET slotsTest3,OFFSET slotsTest4
slotsTestRates dd 16,33,50,250
.code
RunSlotsTest3D PROC uses ebx esi edi
local oldBank:DWORD,oldMode:DWORD,oldSeed:DWORD,oldX:DWORD,oldY:DWORD,oldAngle:DWORD
local total:DWORD,iterations:DWORD,expected:DWORD,rngSnapshot:DWORD,ticks:DWORD
local previous:DWORD,reel:DWORD,timer:DWORD,first:DWORD,second:DWORD,third:DWORD
mov eax,bankroll
mov oldBank,eax
mov eax,engineMode
mov oldMode,eax
mov eax,rngSeed3D
mov oldSeed,eax
mov eax,playerX
mov oldX,eax
mov eax,playerY
mov oldY,eax
mov eax,playerAngle
mov oldAngle,eax
mov bankroll,100000
mov slotsTestStage3D,1
mov engineMode,MODE_WALK
mov interactTargetId,INTERACT_SLOTS_777
call Trigger3DInteraction
cmp engineMode,MODE_SLOTS
jne slots_test_fail
cmp bankroll,100000
jne slots_test_fail
cmp slotSpinState,SLOT_READY
jne slots_test_fail
call TableBusy3D
test eax,eax
jnz slots_test_fail
call RenderNativeSlots3D
invoke WriteActionSnapshot3D,OFFSET slotsTest0
test eax,eax
jz slots_test_fail
; Invalid dimensions fail closed, with no charged stake or loaded remnants.
mov slotSymbolsPack3D.frames,7
call InitNativeSlots3D
test eax,eax
jnz slots_test_fail
cmp slotSymbolsPack3D.pixels,0
jne slots_test_fail
cmp slotCabinetPack3D.pixels,0
jne slots_test_fail
call StartNativeSlots3D
cmp bankroll,100000
jne slots_test_fail
mov BYTE PTR slotSymbolsPath3D,'!'
call InitNativeSlots3D
mov BYTE PTR slotSymbolsPath3D,'a'
test eax,eax
jnz slots_test_fail
cmp slotCabinetPack3D.pixels,0
jne slots_test_fail
call InitNativeSlots3D
test eax,eax
jz slots_test_fail
mov slotBet,0
call StartNativeSlots3D
cmp slotSpinState,SLOT_READY
jne slots_test_fail
mov slotBet,10001
call StartNativeSlots3D
cmp bankroll,100000
jne slots_test_fail
mov bankroll,49
mov slotBet,50
mov eax,rngSeed3D
mov rngSnapshot,eax
call StartNativeSlots3D
cmp bankroll,49
jne slots_test_fail
mov eax,rngSnapshot
cmp rngSeed3D,eax
jne slots_test_fail
cmp slotError3D,1
jne slots_test_fail
; Every possible 20^3 stop combination exercises the actual MASM evaluator.
mov slotsTestStage3D,2
mov total,0
xor ebx,ebx
slots_test_first:
xor esi,esi
slots_test_second:
xor edi,edi
slots_test_third:
mov eax,slotStrip3D[ebx*4]
mov first,eax
mov eax,slotStrip3D[esi*4]
mov second,eax
mov eax,slotStrip3D[edi*4]
mov third,eax
invoke SlotMultiplier3D,first,second,third
add total,eax
mov expected,eax
mov ecx,first
cmp ecx,second
jne slots_test_pair_other
cmp ecx,third
jne slots_test_pair
mov eax,slotTriple3D[ecx*4]
jmp slots_test_compare
slots_test_pair_other:
cmp ecx,third
je slots_test_pair
mov ecx,second
cmp ecx,third
jne slots_test_zero
slots_test_pair:
xor eax,eax
cmp ecx,1
sete al
inc eax
jmp slots_test_compare
slots_test_zero:
xor eax,eax
slots_test_compare:
cmp eax,expected
jne slots_test_fail
inc edi
cmp edi,20
jb slots_test_third
inc esi
cmp esi,20
jb slots_test_second
inc ebx
cmp ebx,20
jb slots_test_first
cmp total,7202
jne slots_test_fail
invoke SlotMultiplier3D,8,8,8
test eax,eax
jnz slots_test_fail
; Five hundred complete paid spins at four update rates, no double debit/pay.
mov slotsTestStage3D,3
mov iterations,500
slots_test_round:
mov slotSpinState,SLOT_READY
mov slotBet,100
mov slotPaytable3D,0
mov bankroll,100000
call StartNativeSlots3D
cmp bankroll,99900
jne slots_test_fail
cmp slotSpinState,SLOT_SPIN
jne slots_test_fail
mov eax,rngSeed3D
mov rngSnapshot,eax
call StartNativeSlots3D
cmp bankroll,99900
jne slots_test_fail
mov eax,rngSnapshot
cmp rngSeed3D,eax
jne slots_test_fail
invoke SlotMultiplier3D,slotReel1,slotReel2,slotReel3
imul eax,100
add eax,99900
mov expected,eax
mov eax,iterations
and eax,3
mov eax,slotsTestRates[eax*4]
mov deltaTime3D,eax
mov ticks,0
slots_test_round_tick:
; Spinning ignores wager and start input, rather than queueing it for later.
mov pressedKeys3D[57h],1
mov pressedKeys3D[20h],1
call HandleNativeSlots3D
call ClearKeys3D
cmp slotBet,100
jne slots_test_fail
mov eax,rngSnapshot
cmp rngSeed3D,eax
jne slots_test_fail
inc ticks
cmp ticks,200
ja slots_test_fail
cmp slotSpinState,SLOT_SPIN
je slots_test_round_tick
mov eax,expected
cmp bankroll,eax
jne slots_test_fail
call SettleNativeSlots3D
mov eax,expected
cmp bankroll,eax
jne slots_test_fail
xor esi,esi
slots_test_final_reel:
invoke SlotReelPosition3D,esi
shr eax,6
cmp eax,slotTargets3D[esi*4]
jne slots_test_fail
inc esi
cmp esi,3
jb slots_test_final_reel
dec iterations
jnz slots_test_round
; The same millisecond timestamp gives the same strictly nondecreasing path.
mov slotsTestStage3D,4
mov slotSpinState,SLOT_SPIN
mov reel,0
slots_test_monotonic_reel:
mov timer,0
mov previous,0
slots_test_monotonic_tick:
mov eax,timer
mov slotSpinTimer,eax
invoke SlotReelPosition3D,reel
cmp eax,previous
jb slots_test_fail
mov previous,eax
inc timer
cmp timer,3000
jbe slots_test_monotonic_tick
inc reel
cmp reel,3
jb slots_test_monotonic_reel
; Force known stops for visual timing snapshots; neither drawing nor a panel pays.
mov slotsTestStage3D,5
mov slotSpinState,SLOT_READY
mov slotStops3D,0
mov slotStops3D[4],6
mov slotStops3D[8],12
mov bankroll,100000
call StartNativeSlots3D
mov slotReel1,0
mov slotReel2,0
mov slotReel3,0
xor esi,esi
slots_test_force_sevens:
mov slotTargets3D[esi*4],10
mov eax,10
sub eax,slotStartStops3D[esi*4]
jns @F
add eax,20
@@:
add eax,slotCycles3D[esi*4]
shl eax,6
mov slotTravel3D[esi*4],eax
inc esi
cmp esi,3
jb slots_test_force_sevens
xor esi,esi
slots_test_snapshots:
mov eax,slotsTestTimes[esi*4]
mov slotSpinTimer,eax
mov eax,rngSeed3D
mov rngSnapshot,eax
call RenderNativeSlots3D
mov eax,rngSnapshot
cmp rngSeed3D,eax
jne slots_test_fail
cmp bankroll,99900
jne slots_test_fail
mov eax,slotsTestTimes[esi*4]
cmp slotSpinTimer,eax
jne slots_test_fail
invoke WriteActionSnapshot3D,slotsTestPaths[esi*4]
test eax,eax
jz slots_test_fail
inc esi
cmp esi,4
jb slots_test_snapshots
call SettleNativeSlots3D
cmp bankroll,109900
jne slots_test_fail
call RenderNativeSlots3D
invoke WriteActionSnapshot3D,OFFSET slotsTest5
mov pressedKeys3D[50h],1
mov deltaTime3D,16
call HandleNativeSlots3D
cmp slotPaytable3D,1
jne slots_test_fail
call RenderNativeSlots3D
invoke WriteActionSnapshot3D,OFFSET slotsTest6
call StartNativeSlots3D
cmp bankroll,109900
jne slots_test_fail
call SlotEscape3D
cmp slotPaytable3D,0
jne slots_test_fail
cmp engineMode,MODE_SLOTS
jne slots_test_fail
; Header clicks use the same safe queued-exit path as Escape.
mov slotsTestStage3D,6
call StartNativeSlots3D
invoke SlotMultiplier3D,slotReel1,slotReel2,slotReel3
imul eax,100
add eax,109800
mov expected,eax
mov mouseClick3D,1
mov mouseX3D,280
mov mouseY3D,9
call HandleNativeSlots3D
cmp slotLeaveAfter3D,1
jne slots_test_fail
cmp paused3D,0
jne slots_test_fail
cmp engineMode,MODE_SLOTS
jne slots_test_fail
call RenderNativeSlots3D
invoke WriteActionSnapshot3D,OFFSET slotsTest7
mov deltaTime3D,250
mov ticks,0
slots_test_exit_tick:
call HandleNativeSlots3D
inc ticks
cmp ticks,13
ja slots_test_fail
cmp engineMode,MODE_SLOTS
je slots_test_exit_tick
cmp engineMode,MODE_WALK
jne slots_test_fail
mov eax,expected
cmp bankroll,eax
jne slots_test_fail
mov eax,oldX
cmp playerX,eax
jne slots_test_fail
mov eax,oldY
cmp playerY,eax
jne slots_test_fail
mov eax,oldAngle
cmp playerAngle,eax
jne slots_test_fail
; Mouse and key edge controls have identical bounded wager selections.
mov slotsTestStage3D,7
mov engineMode,MODE_SLOTS
call InitNativeSlots3D
test eax,eax
jz slots_test_fail
mov mouseX3D,44
mov mouseY3D,226
mov mouseClick3D,1
call HandleNativeSlots3D
cmp slotBet,100
jne slots_test_fail
call HandleNativeSlots3D
cmp slotBet,100
jne slots_test_fail
mov pressedKeys3D[53h],1
call HandleNativeSlots3D
cmp slotBet,50
jne slots_test_fail
call HandleNativeSlots3D
cmp slotBet,50
jne slots_test_fail
mov slotBetIndex3D,0
mov slotBet,10
mov pressedKeys3D[28h],1
call HandleNativeSlots3D
cmp slotBet,10
jne slots_test_fail
mov slotBetIndex3D,6
mov slotBet,10000
mov pressedKeys3D[26h],1
call HandleNativeSlots3D
cmp slotBet,10000
jne slots_test_fail
mov bankroll,100000
call StartNativeSlots3D
invoke SlotMultiplier3D,slotReel1,slotReel2,slotReel3
imul eax,10000
add eax,90000
mov expected,eax
mov slotSpinTimer,2999
mov deltaTime3D,16
mov mouseX3D,280
mov mouseY3D,9
mov mouseClick3D,1
call HandleNativeSlots3D
cmp engineMode,MODE_WALK
jne slots_test_fail
mov eax,expected
cmp bankroll,eax
jne slots_test_fail
mov engineMode,MODE_SLOTS
call CardTableEscape3D
cmp eax,1
jne slots_test_fail
cmp engineMode,MODE_WALK
jne slots_test_fail
; Bank cap and idempotent settlement remain safe at the maximum wager.
mov bankroll,999999999
mov slotStake3D,10000
mov slotReel1,7
mov slotReel2,7
mov slotReel3,7
mov slotSpinState,SLOT_SPIN
call SettleNativeSlots3D
cmp bankroll,1000000000
jne slots_test_fail
call SettleNativeSlots3D
cmp bankroll,1000000000
jne slots_test_fail
mov eax,oldBank
mov bankroll,eax
mov eax,oldSeed
mov rngSeed3D,eax
mov eax,oldMode
mov engineMode,eax
call ClearKeys3D
call FreeNativeSlots3D
xor eax,eax
ret
slots_test_fail:
mov eax,slotsTestStage3D
add eax,440
ret
RunSlotsTest3D ENDP