- Billiards: add native Russian Pyramid & American Eight-Ball pool with physics prediction, controls, and regression tests - Scratch Tickets: add dedicated counter, mat presentation, elliptical coin scraping, 4 ticket types, and payout effects - First-Person Dice: add native dice scene, hand anchor frames, throwing animation, and table perspective - City Wake & Weather: add arrival cutscene, alley geometry, weather/rain effects, and lighter/rocker animation - World Dressing: add hall paintings, furniture packs, hall lighting, and scene regression tests - Build & Tooling: update build.bat for modern MSVC toolchain, update launcher hash, and refresh shipping binaries
481 lines
12 KiB
PHP
481 lines
12 KiB
PHP
GetCapture PROTO
|
|
.data
|
|
scratchTestReady3D db "build\actions\scratch-ready.bmp",0
|
|
scratchTestCovered3D db "build\actions\scratch-covered.bmp",0
|
|
scratchTestPartial3D db "build\actions\scratch-partial.bmp",0
|
|
scratchTestResult3D db "build\actions\scratch-result.bmp",0
|
|
scratchTestMissing3D db "build\actions\scratch-missing.bmp",0
|
|
scratchTestStage3D dd 140
|
|
scratchTestCounts3D dd 7 dup(0)
|
|
scratchTestGrid3D dd 9 dup(0)
|
|
scratchTypeCapture3D db "build\actions\scratch-kind-0-covered.bmp",0
|
|
scratchTypeResult3D db "build\actions\scratch-kind-0-result.bmp",0
|
|
.code
|
|
|
|
RunScratchPointerTest3D PROC uses ebx esi edi
|
|
local oldMode:DWORD,oldW:DWORD,oldH:DWORD,oldLeft:DWORD,oldTop:DWORD,ok:DWORD
|
|
mov eax,engineMode
|
|
mov oldMode,eax
|
|
mov eax,viewWidth3D
|
|
mov oldW,eax
|
|
mov eax,viewHeight3D
|
|
mov oldH,eax
|
|
mov eax,viewLeft3D
|
|
mov oldLeft,eax
|
|
mov eax,viewTop3D
|
|
mov oldTop,eax
|
|
mov ok,0
|
|
mov engineMode,MODE_SCRATCH
|
|
mov scrState3D,0
|
|
mov viewWidth3D,1280
|
|
mov viewHeight3D,960
|
|
mov viewLeft3D,20
|
|
mov viewTop3D,40
|
|
; (200,195) native -> (420,430) client, including letterbox offsets.
|
|
invoke WindowEvents3D,h3DWnd,201h,1,01AE01A4h
|
|
cmp scrPointerX3D,200
|
|
jne scratch_pointer_restore
|
|
cmp scrPointerY3D,195
|
|
jne scratch_pointer_restore
|
|
cmp scrHeld3D,1
|
|
jne scratch_pointer_restore
|
|
invoke GetCapture
|
|
cmp eax,h3DWnd
|
|
jne scratch_pointer_restore
|
|
; Release outside the viewport still releases capture; quick click survives.
|
|
invoke WindowEvents3D,h3DWnd,202h,0,0FFFFFFFFh
|
|
cmp scrHeld3D,0
|
|
jne scratch_pointer_restore
|
|
cmp scrClick3D,1
|
|
jne scratch_pointer_restore
|
|
invoke GetCapture
|
|
test eax,eax
|
|
jnz scratch_pointer_restore
|
|
invoke WindowEvents3D,h3DWnd,201h,1,01AE01A4h
|
|
invoke WindowEvents3D,h3DWnd,8,0,0
|
|
cmp scrHeld3D,0
|
|
jne scratch_pointer_restore
|
|
cmp scrLastValid3D,0
|
|
jne scratch_pointer_restore
|
|
cmp scrPointerValid3D,0
|
|
jne scratch_pointer_restore
|
|
invoke GetCapture
|
|
test eax,eax
|
|
jnz scratch_pointer_restore
|
|
invoke WindowEvents3D,h3DWnd,201h,1,0FFFFFFFFh
|
|
cmp scrPointerValid3D,0
|
|
jne scratch_pointer_restore
|
|
cmp scrHeld3D,0
|
|
jne scratch_pointer_restore
|
|
mov ok,1
|
|
scratch_pointer_restore:
|
|
call ClearKeys3D
|
|
mov eax,oldMode
|
|
mov engineMode,eax
|
|
mov eax,oldW
|
|
mov viewWidth3D,eax
|
|
mov eax,oldH
|
|
mov viewHeight3D,eax
|
|
mov eax,oldLeft
|
|
mov viewLeft3D,eax
|
|
mov eax,oldTop
|
|
mov viewTop3D,eax
|
|
mov eax,ok
|
|
ret
|
|
RunScratchPointerTest3D ENDP
|
|
|
|
ScratchTestUncover3D PROC uses ebx esi edi
|
|
local rowY:DWORD,left:DWORD,right:DWORD
|
|
mov scrDealMs3D,0
|
|
xor esi,esi
|
|
scratch_uncover_cell:
|
|
invoke ScratchCellOrigin3D,esi
|
|
mov left,eax
|
|
add eax,scrCellW3D
|
|
dec eax
|
|
mov right,eax
|
|
mov rowY,edx
|
|
mov edi,edx
|
|
add edi,scrCellH3D
|
|
scratch_uncover_row:
|
|
invoke ScratchStroke3D,left,rowY,right,rowY
|
|
add rowY,6
|
|
cmp rowY,edi
|
|
jb scratch_uncover_row
|
|
inc esi
|
|
cmp esi,scrCellCount3D
|
|
jb scratch_uncover_cell
|
|
ret
|
|
ScratchTestUncover3D ENDP
|
|
|
|
RunScratchVariantsTest3D PROC uses ebx esi edi
|
|
local kind:DWORD,round:DWORD,expected:DWORD,hits:DWORD,total:DWORD,ticketSeed:DWORD
|
|
mov kind,0
|
|
scratch_variant_test_kind:
|
|
mov scrState3D,0
|
|
mov eax,kind
|
|
mov scrType3D,eax
|
|
mov round,0
|
|
scratch_variant_test_round:
|
|
mov bankroll,10000
|
|
mov scrState3D,0
|
|
mov scrPriceIndex3D,0
|
|
mov eax,round
|
|
add eax,47
|
|
mov rngSeed3D,eax
|
|
call BuyScratch3D
|
|
mov scrDealMs3D,0
|
|
cmp scrState3D,1
|
|
jne scratch_variants_fail
|
|
cmp scrNewPixels3D,0
|
|
jne scratch_variants_fail
|
|
xor esi,esi
|
|
scratch_test_clean_dust:
|
|
cmp scrDustLife3D[esi*4],0
|
|
jne scratch_variants_fail
|
|
inc esi
|
|
cmp esi,32
|
|
jb scratch_test_clean_dust
|
|
mov eax,scrGross3D
|
|
add eax,9950
|
|
mov expected,eax
|
|
mov eax,rngSeed3D
|
|
mov ticketSeed,eax
|
|
mov eax,kind
|
|
inc eax
|
|
invoke ScratchSelectType3D,eax
|
|
mov eax,kind
|
|
cmp scrType3D,eax
|
|
jne scratch_variants_fail
|
|
mov hits,0
|
|
mov total,0
|
|
cmp kind,1
|
|
je scratch_test_number_rules
|
|
cmp kind,2
|
|
jne scratch_variant_check_payment
|
|
xor esi,esi
|
|
scratch_test_row_rules:
|
|
mov eax,scrGrid3D[esi*4]
|
|
cmp eax,scrGrid3D[esi*4+4]
|
|
jne scratch_test_row_next
|
|
cmp eax,scrGrid3D[esi*4+8]
|
|
jne scratch_test_row_next
|
|
inc hits
|
|
mov eax,scrMultipliers3D[eax*4]
|
|
imul eax,scrStake3D
|
|
add total,eax
|
|
scratch_test_row_next:
|
|
add esi,3
|
|
cmp esi,9
|
|
jb scratch_test_row_rules
|
|
jmp scratch_test_rule_total
|
|
scratch_test_number_rules:
|
|
xor esi,esi
|
|
scratch_test_number_bounds:
|
|
mov eax,scrGrid3D[esi*4]
|
|
dec eax
|
|
cmp eax,30
|
|
jae scratch_variants_fail
|
|
inc esi
|
|
cmp esi,9
|
|
jb scratch_test_number_bounds
|
|
mov esi,3
|
|
scratch_test_number_cell:
|
|
xor edi,edi
|
|
scratch_test_number_match:
|
|
mov eax,scrGrid3D[edi*4]
|
|
cmp eax,scrGrid3D[esi*4]
|
|
jne @F
|
|
inc hits
|
|
mov eax,scrCellPrizes3D[esi*4]
|
|
add total,eax
|
|
@@:
|
|
inc edi
|
|
cmp edi,3
|
|
jb scratch_test_number_match
|
|
inc esi
|
|
cmp esi,9
|
|
jb scratch_test_number_cell
|
|
scratch_test_rule_total:
|
|
mov eax,total
|
|
cmp eax,scrGross3D
|
|
jne scratch_variants_fail
|
|
cmp hits,1
|
|
ja scratch_variants_fail
|
|
scratch_variant_check_payment:
|
|
cmp round,0
|
|
jne scratch_variant_quit_test
|
|
mov eax,kind
|
|
add al,'0'
|
|
mov BYTE PTR scratchTypeCapture3D[27],al
|
|
mov BYTE PTR scratchTypeResult3D[27],al
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTypeCapture3D
|
|
cmp kind,2
|
|
jne @F
|
|
; The corner of a circle is paper, not erasable silver.
|
|
invoke ScratchCellOrigin3D,0
|
|
invoke ScratchErasePixel3D,eax,edx
|
|
cmp scrCounts3D,0
|
|
jne scratch_variants_fail
|
|
@@:
|
|
call ScratchTestUncover3D
|
|
cmp scrState3D,2
|
|
jne scratch_variants_fail
|
|
mov eax,scrCellCount3D
|
|
cmp scrOpened3D,eax
|
|
jne scratch_variants_fail
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTypeResult3D
|
|
scratch_variant_quit_test:
|
|
call SettleScratchOnQuit3D
|
|
call SettleScratchOnQuit3D
|
|
mov eax,expected
|
|
cmp bankroll,eax
|
|
jne scratch_variants_fail
|
|
mov eax,ticketSeed
|
|
cmp rngSeed3D,eax
|
|
jne scratch_variants_fail
|
|
inc round
|
|
cmp round,200
|
|
jb scratch_variant_test_round
|
|
inc kind
|
|
cmp kind,4
|
|
jb scratch_variant_test_kind
|
|
mov scrState3D,0
|
|
invoke ScratchSelectType3D,0
|
|
cmp scrType3D,0
|
|
jne scratch_variants_fail
|
|
mov eax,1
|
|
ret
|
|
scratch_variants_fail:
|
|
mov eax,145
|
|
ret
|
|
RunScratchVariantsTest3D ENDP
|
|
|
|
include tools/tests/scratch_portrait_test.inc
|
|
include tools/tests/scratch_effects_test.inc
|
|
|
|
RunScratchTest3D PROC uses ebx esi edi
|
|
local oldBank:DWORD,oldRng:DWORD,paintSeed:DWORD,cleared:DWORD,expected:DWORD,round:DWORD
|
|
mov eax,bankroll
|
|
mov oldBank,eax
|
|
mov eax,rngSeed3D
|
|
mov oldRng,eax
|
|
mov scratchTestStage3D,140
|
|
mov scrState3D,0
|
|
mov scrType3D,0
|
|
call BeginScratch3D
|
|
cmp scrReady3D,1
|
|
jne scratch_test_fail
|
|
cmp scrCounterArt3D.pixels,0
|
|
je scratch_test_fail
|
|
mov scrState3D,0
|
|
mov scrPriceIndex3D,0
|
|
mov bankroll,10000
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTestReady3D
|
|
mov rngSeed3D,47
|
|
call BuyScratch3D
|
|
mov scrDealMs3D,0
|
|
cmp bankroll,9950
|
|
jne scratch_test_fail
|
|
cmp scrGross3D,250
|
|
jne scratch_test_fail
|
|
cmp scrPrizeSymbol3D,4
|
|
jne scratch_test_fail
|
|
mov eax,rngSeed3D
|
|
mov paintSeed,eax
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTestCovered3D
|
|
mov scratchTestStage3D,141
|
|
call BuyScratch3D
|
|
cmp bankroll,9950
|
|
jne scratch_test_fail
|
|
mov eax,paintSeed
|
|
cmp rngSeed3D,eax
|
|
jne scratch_test_fail
|
|
; Negative coordinates and panel gutters must not change any coating.
|
|
invoke ScratchStamp3D,-100,-100
|
|
invoke ScratchStamp3D,258,220
|
|
cmp scrCounts3D,0
|
|
jne scratch_test_fail
|
|
mov scrHeld3D,0
|
|
mov scrPointerValid3D,1
|
|
mov scrPointerX3D,200
|
|
mov scrPointerY3D,195
|
|
call HandleScratch3D
|
|
cmp scrCounts3D,0
|
|
jne scratch_test_fail
|
|
; Fast drag, a release, and a second disconnected drag.
|
|
mov scrHeld3D,1
|
|
call HandleScratch3D
|
|
mov scrPointerX3D,490
|
|
call HandleScratch3D
|
|
mov eax,scrCounts3D
|
|
mov cleared,eax
|
|
cmp eax,400
|
|
jb scratch_test_fail
|
|
cmp scrCounts3D[4],400
|
|
jb scratch_test_fail
|
|
cmp scrCounts3D[8],400
|
|
jb scratch_test_fail
|
|
call ScratchCancelStroke3D
|
|
mov scrPointerX3D,200
|
|
mov scrPointerY3D,295
|
|
mov scrHeld3D,1
|
|
call HandleScratch3D
|
|
cmp scrCounts3D[12],0
|
|
jne scratch_test_fail
|
|
mov scrPointerValid3D,0
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTestPartial3D
|
|
mov scratchTestStage3D,142
|
|
call LeaveScratch3D
|
|
cmp engineMode,MODE_WALK
|
|
jne scratch_test_fail
|
|
call BeginScratch3D
|
|
mov eax,cleared
|
|
cmp scrCounts3D,eax
|
|
jne scratch_test_fail
|
|
mov eax,paintSeed
|
|
cmp rngSeed3D,eax
|
|
jne scratch_test_fail
|
|
cmp bankroll,9950
|
|
jne scratch_test_fail
|
|
call ScratchTestUncover3D
|
|
cmp scrOpened3D,9
|
|
jne scratch_test_fail
|
|
cmp scrState3D,2
|
|
jne scratch_test_fail
|
|
cmp bankroll,10200
|
|
jne scratch_test_fail
|
|
call FinishScratch3D
|
|
call SettleScratchOnQuit3D
|
|
cmp bankroll,10200
|
|
jne scratch_test_fail
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTestResult3D
|
|
mov eax,paintSeed
|
|
cmp rngSeed3D,eax
|
|
jne scratch_test_fail
|
|
mov scratchTestStage3D,143
|
|
mov round,0
|
|
scratch_test_round:
|
|
mov scrState3D,0
|
|
mov bankroll,10000
|
|
mov eax,round
|
|
xor edx,edx
|
|
mov ecx,3
|
|
div ecx
|
|
mov scrPriceIndex3D,edx
|
|
call BuyScratch3D
|
|
cmp scrState3D,1
|
|
jne scratch_test_fail
|
|
mov eax,10000
|
|
sub eax,scrStake3D
|
|
mov expected,eax
|
|
cmp bankroll,eax
|
|
jne scratch_test_fail
|
|
lea edi,scratchTestCounts3D
|
|
xor eax,eax
|
|
mov ecx,7
|
|
rep stosd
|
|
xor esi,esi
|
|
scratch_test_grid:
|
|
mov eax,scrGrid3D[esi*4]
|
|
cmp eax,6
|
|
ja scratch_test_fail
|
|
inc scratchTestCounts3D[eax*4]
|
|
inc esi
|
|
cmp esi,9
|
|
jb scratch_test_grid
|
|
xor esi,esi
|
|
scratch_test_triples:
|
|
cmp esi,scrPrizeSymbol3D
|
|
jne scratch_test_other_count
|
|
cmp scratchTestCounts3D[esi*4],3
|
|
jne scratch_test_fail
|
|
mov eax,scrMultipliers3D[esi*4]
|
|
imul eax,scrStake3D
|
|
cmp scrGross3D,eax
|
|
jne scratch_test_fail
|
|
jmp scratch_test_next_count
|
|
scratch_test_other_count:
|
|
cmp scratchTestCounts3D[esi*4],2
|
|
ja scratch_test_fail
|
|
scratch_test_next_count:
|
|
inc esi
|
|
cmp esi,7
|
|
jb scratch_test_triples
|
|
mov eax,scrGross3D
|
|
add expected,eax
|
|
mov eax,rngSeed3D
|
|
mov paintSeed,eax
|
|
call BuyScratch3D
|
|
mov eax,paintSeed
|
|
cmp rngSeed3D,eax
|
|
jne scratch_test_fail
|
|
; Normal exit pays the pending amount once without further RNG.
|
|
call SettleScratchOnQuit3D
|
|
call SettleScratchOnQuit3D
|
|
mov eax,expected
|
|
cmp bankroll,eax
|
|
jne scratch_test_fail
|
|
mov eax,paintSeed
|
|
cmp rngSeed3D,eax
|
|
jne scratch_test_fail
|
|
inc round
|
|
cmp round,500
|
|
jb scratch_test_round
|
|
mov scratchTestStage3D,144
|
|
mov bankroll,0
|
|
mov scrState3D,0
|
|
call BuyScratch3D
|
|
cmp scrState3D,0
|
|
jne scratch_test_fail
|
|
cmp scrError3D,1
|
|
jne scratch_test_fail
|
|
mov scrState3D,1
|
|
mov scrOpened3D,9
|
|
mov scrGross3D,12500
|
|
mov bankroll,999999990
|
|
call FinishScratch3D
|
|
cmp bankroll,1000000000
|
|
jne scratch_test_fail
|
|
call RunScratchVariantsTest3D
|
|
cmp eax,1
|
|
jne scratch_test_extra_fail
|
|
call RunScratchPortraitTest3D
|
|
cmp eax,1
|
|
jne scratch_test_extra_fail
|
|
call RunScratchCatalogTest3D
|
|
cmp eax,1
|
|
jne scratch_test_extra_fail
|
|
call RunScratchEffectsTest3D
|
|
cmp eax,1
|
|
je @F
|
|
scratch_test_extra_fail:
|
|
mov scratchTestStage3D,eax
|
|
jmp scratch_test_fail
|
|
@@:
|
|
mov scrReady3D,0
|
|
call RenderScratch3D
|
|
invoke WriteActionSnapshot3D,OFFSET scratchTestMissing3D
|
|
mov scrReady3D,1
|
|
mov scrState3D,0
|
|
mov scrOpened3D,0
|
|
mov scrError3D,0
|
|
mov scrGross3D,0
|
|
mov scrPriceIndex3D,0
|
|
mov eax,oldBank
|
|
mov bankroll,eax
|
|
mov eax,oldRng
|
|
mov rngSeed3D,eax
|
|
call ClearKeys3D
|
|
mov eax,1
|
|
ret
|
|
scratch_test_fail:
|
|
mov eax,scratchTestStage3D
|
|
ret
|
|
RunScratchTest3D ENDP
|