- 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
377 lines
8.1 KiB
PHP
377 lines
8.1 KiB
PHP
; Presentation state has its own clock and RNG; it never changes ticket odds.
|
|
ScratchEase3D PROC elapsed:DWORD,duration:DWORD
|
|
mov eax,elapsed
|
|
cmp eax,duration
|
|
jb @F
|
|
mov eax,256
|
|
ret
|
|
@@:
|
|
shl eax,8
|
|
xor edx,edx
|
|
div duration
|
|
mov ecx,eax
|
|
imul eax,eax
|
|
shl ecx,1
|
|
neg ecx
|
|
add ecx,768
|
|
imul eax,ecx
|
|
shr eax,16
|
|
ret
|
|
ScratchEase3D ENDP
|
|
|
|
ScratchStartDeal3D PROC
|
|
mov scrDealMs3D,900
|
|
mov scrPayoutMs3D,0
|
|
invoke PlayCasinoSound3D,OFFSET scrPaperSound3D,0,1
|
|
ret
|
|
ScratchStartDeal3D ENDP
|
|
|
|
ScratchStartPayout3D PROC
|
|
mov scrDealMs3D,0
|
|
mov scrPayoutMs3D,0
|
|
cmp engineMode,MODE_SCRATCH
|
|
jne @F
|
|
cmp scrGross3D,0
|
|
je @F
|
|
mov scrPayoutMs3D,1800
|
|
invoke PlayCasinoSound3D,OFFSET scrPayoutSound3D,0,1
|
|
@@:
|
|
ret
|
|
ScratchStartPayout3D ENDP
|
|
|
|
ScratchTickVisuals3D PROC uses ebx esi
|
|
mov eax,deltaTime3D
|
|
cmp eax,250
|
|
jbe @F
|
|
mov eax,250
|
|
@@:
|
|
sub scrDealMs3D,eax
|
|
jns @F
|
|
mov scrDealMs3D,0
|
|
@@:
|
|
sub scrPayoutMs3D,eax
|
|
jns @F
|
|
mov scrPayoutMs3D,0
|
|
@@:
|
|
sub scrScrapeCooldown3D,eax
|
|
jns @F
|
|
mov scrScrapeCooldown3D,0
|
|
@@:
|
|
cmp eax,100
|
|
jbe @F
|
|
mov eax,100
|
|
@@:
|
|
add scrDustStep3D,eax
|
|
scratch_visual_step:
|
|
cmp scrDustStep3D,8
|
|
jb scratch_visual_done
|
|
sub scrDustStep3D,8
|
|
xor esi,esi
|
|
scratch_visual_particle:
|
|
cmp scrDustLife3D[esi*4],0
|
|
je scratch_visual_next
|
|
sub scrDustLife3D[esi*4],8
|
|
jns @F
|
|
mov scrDustLife3D[esi*4],0
|
|
@@:
|
|
mov eax,scrDustY3D[esi*4]
|
|
cmp eax,scrDustFloor3D[esi*4]
|
|
jge scratch_visual_next
|
|
mov eax,scrDustVX3D[esi*4]
|
|
add scrDustX3D[esi*4],eax
|
|
add scrDustVY3D[esi*4],6
|
|
mov eax,scrDustVY3D[esi*4]
|
|
add scrDustY3D[esi*4],eax
|
|
mov eax,scrDustFloor3D[esi*4]
|
|
cmp scrDustY3D[esi*4],eax
|
|
jl scratch_visual_next
|
|
mov scrDustY3D[esi*4],eax
|
|
scratch_visual_next:
|
|
inc esi
|
|
cmp esi,SCR_DUST_COUNT
|
|
jb scratch_visual_particle
|
|
jmp scratch_visual_step
|
|
scratch_visual_done:
|
|
ret
|
|
ScratchTickVisuals3D ENDP
|
|
|
|
ScratchSpawnDust3D PROC uses ebx esi edi
|
|
cmp scrState3D,1
|
|
jne scratch_spawn_begin
|
|
cmp scrScrapeCooldown3D,0
|
|
jne @F
|
|
invoke PlayCasinoSound3D,OFFSET scrScrapeSound3D,0,1
|
|
mov scrScrapeCooldown3D,150
|
|
@@:
|
|
scratch_spawn_begin:
|
|
mov edi,3
|
|
scratch_spawn_fragment:
|
|
mov esi,scrDustIndex3D
|
|
mov eax,scrVisualSeed3D
|
|
imul eax,1664525
|
|
add eax,1013904223
|
|
mov scrVisualSeed3D,eax
|
|
mov ebx,eax
|
|
and eax,511
|
|
add eax,1200
|
|
mov scrDustLife3D[esi*4],eax
|
|
mov eax,scrPointerX3D
|
|
shl eax,8
|
|
mov scrDustX3D[esi*4],eax
|
|
mov eax,scrPointerY3D
|
|
shl eax,8
|
|
mov scrDustY3D[esi*4],eax
|
|
mov eax,ebx
|
|
shr eax,12
|
|
and eax,255
|
|
sub eax,128
|
|
mov scrDustVX3D[esi*4],eax
|
|
mov eax,ebx
|
|
shr eax,20
|
|
and eax,127
|
|
add eax,64
|
|
neg eax
|
|
mov scrDustVY3D[esi*4],eax
|
|
mov eax,ebx
|
|
shr eax,8
|
|
and eax,31
|
|
add eax,scrPointerY3D
|
|
add eax,20
|
|
cmp eax,385
|
|
jbe @F
|
|
mov eax,385
|
|
@@:
|
|
shl eax,8
|
|
mov scrDustFloor3D[esi*4],eax
|
|
inc esi
|
|
and esi,SCR_DUST_COUNT-1
|
|
mov scrDustIndex3D,esi
|
|
dec edi
|
|
jnz scratch_spawn_fragment
|
|
ret
|
|
ScratchSpawnDust3D ENDP
|
|
|
|
ScratchDrawDust3D PROC uses ebx esi edi
|
|
xor esi,esi
|
|
scratch_draw_fragment:
|
|
cmp scrDustLife3D[esi*4],0
|
|
je scratch_draw_fragment_next
|
|
mov eax,scrDustX3D[esi*4]
|
|
sar eax,8
|
|
cmp eax,638
|
|
jae scratch_draw_fragment_next
|
|
mov edx,scrDustY3D[esi*4]
|
|
sar edx,8
|
|
cmp edx,40
|
|
jb scratch_draw_fragment_next
|
|
cmp edx,386
|
|
jae scratch_draw_fragment_next
|
|
imul edx,640
|
|
add edx,eax
|
|
mov ebx,esi
|
|
and ebx,3
|
|
mov eax,scrDustInk3D[ebx*4]
|
|
mov screenBuffer[edx*4],eax
|
|
mov screenBuffer[edx*4+4],eax
|
|
test esi,1
|
|
jz scratch_draw_fragment_next
|
|
mov screenBuffer[edx*4+640*4],00868D89h
|
|
scratch_draw_fragment_next:
|
|
inc esi
|
|
cmp esi,SCR_DUST_COUNT
|
|
jb scratch_draw_fragment
|
|
ret
|
|
ScratchDrawDust3D ENDP
|
|
|
|
ScratchSaveBackdrop3D PROC uses esi edi
|
|
cmp scrDealMs3D,350
|
|
jbe @F
|
|
lea esi,screenBuffer[640*40*4]
|
|
lea edi,scrBackdrop3D[640*40*4]
|
|
mov ecx,640*348
|
|
rep movsd
|
|
@@:
|
|
ret
|
|
ScratchSaveBackdrop3D ENDP
|
|
|
|
ScratchDrawDelivery3D PROC uses ebx esi edi
|
|
local left:DWORD,top:DWORD,right:DWORD,bottom:DWORD,rowY:DWORD,pointX:DWORD
|
|
local offsetX:DWORD,offsetY:DWORD,sourceBase:DWORD
|
|
cmp scrDealMs3D,350
|
|
jbe scratch_delivery_done
|
|
mov eax,900
|
|
sub eax,scrDealMs3D
|
|
invoke ScratchEase3D,eax,550
|
|
neg eax
|
|
add eax,256
|
|
imul edx,eax,360
|
|
sar edx,8
|
|
mov offsetY,edx
|
|
imul eax,-56
|
|
sar eax,8
|
|
mov offsetX,eax
|
|
lea edi,scrPaperLayer3D
|
|
xor eax,eax
|
|
mov ecx,640*480
|
|
rep stosd
|
|
mov left,96
|
|
mov top,92
|
|
mov right,544
|
|
mov bottom,380
|
|
cmp scrType3D,4
|
|
jae scratch_delivery_portrait
|
|
mov eax,scrType3D
|
|
imul eax,448*288*4
|
|
add eax,scrTicketArt3D.pixels
|
|
mov sourceBase,eax
|
|
jmp scratch_delivery_bounds
|
|
scratch_delivery_portrait:
|
|
mov eax,scrViewX3D
|
|
mov left,eax
|
|
add eax,scrViewW3D
|
|
mov right,eax
|
|
mov eax,scrViewY3D
|
|
mov top,eax
|
|
add eax,scrViewH3D
|
|
mov bottom,eax
|
|
scratch_delivery_bounds:
|
|
cmp top,40
|
|
jge @F
|
|
mov top,40
|
|
@@:
|
|
cmp bottom,388
|
|
jle @F
|
|
mov bottom,388
|
|
@@:
|
|
mov eax,top
|
|
mov rowY,eax
|
|
scratch_delivery_row:
|
|
mov eax,left
|
|
mov pointX,eax
|
|
scratch_delivery_pixel:
|
|
cmp scrType3D,4
|
|
jae scratch_delivery_copy
|
|
mov eax,rowY
|
|
sub eax,92
|
|
imul eax,448
|
|
add eax,pointX
|
|
sub eax,96
|
|
mov edi,sourceBase
|
|
cmp BYTE PTR [edi+eax*4+3],0
|
|
je scratch_delivery_next
|
|
scratch_delivery_copy:
|
|
imul ebx,rowY,640
|
|
add ebx,pointX
|
|
mov eax,screenBuffer[ebx*4]
|
|
or eax,0FF000000h
|
|
mov scrPaperLayer3D[ebx*4],eax
|
|
scratch_delivery_next:
|
|
inc pointX
|
|
mov eax,pointX
|
|
cmp eax,right
|
|
jb scratch_delivery_pixel
|
|
inc rowY
|
|
mov eax,rowY
|
|
cmp eax,bottom
|
|
jb scratch_delivery_row
|
|
lea esi,scrBackdrop3D[640*40*4]
|
|
lea edi,screenBuffer[640*40*4]
|
|
mov ecx,640*348
|
|
rep movsd
|
|
; A clipped, paper-shaped contact shadow, never a rectangular overlay.
|
|
mov eax,top
|
|
mov rowY,eax
|
|
scratch_delivery_shadow_row:
|
|
mov eax,left
|
|
mov pointX,eax
|
|
scratch_delivery_shadow_pixel:
|
|
imul ebx,rowY,640
|
|
add ebx,pointX
|
|
cmp BYTE PTR scrPaperLayer3D[ebx*4+3],0
|
|
je scratch_delivery_shadow_next
|
|
mov eax,pointX
|
|
add eax,offsetX
|
|
add eax,4
|
|
cmp eax,640
|
|
jae scratch_delivery_shadow_next
|
|
mov edx,rowY
|
|
add edx,offsetY
|
|
add edx,6
|
|
cmp edx,40
|
|
jb scratch_delivery_shadow_next
|
|
cmp edx,388
|
|
jae scratch_delivery_shadow_next
|
|
imul edx,640
|
|
add edx,eax
|
|
mov eax,screenBuffer[edx*4]
|
|
mov ecx,eax
|
|
and ecx,00FCFCFCh
|
|
shr ecx,2
|
|
sub eax,ecx
|
|
mov screenBuffer[edx*4],eax
|
|
scratch_delivery_shadow_next:
|
|
inc pointX
|
|
mov eax,pointX
|
|
cmp eax,right
|
|
jb scratch_delivery_shadow_pixel
|
|
inc rowY
|
|
mov eax,rowY
|
|
cmp eax,bottom
|
|
jb scratch_delivery_shadow_row
|
|
invoke DrawAnimSprite3D,OFFSET scrPaperLayerPack3D,0,offsetX,offsetY,640,480
|
|
scratch_delivery_done:
|
|
ret
|
|
ScratchDrawDelivery3D ENDP
|
|
|
|
ScratchDrawPayout3D PROC uses ebx esi edi
|
|
local elapsed:DWORD,progress:DWORD,coinX:DWORD,coinY:DWORD
|
|
cmp scrState3D,2
|
|
jne scratch_payout_done
|
|
cmp scrGross3D,0
|
|
je scratch_payout_done
|
|
mov eax,1800
|
|
sub eax,scrPayoutMs3D
|
|
mov elapsed,eax
|
|
invoke ScratchEase3D,eax,400
|
|
imul eax,96
|
|
sar eax,8
|
|
sub eax,88
|
|
invoke DrawAnimSprite3D,OFFSET scrPayoutArt3D,0,eax,300,88,66
|
|
xor esi,esi
|
|
scratch_payout_coin:
|
|
imul eax,esi,110
|
|
add eax,350
|
|
mov edx,elapsed
|
|
sub edx,eax
|
|
js scratch_payout_coin_next
|
|
cmp edx,850
|
|
jae scratch_payout_coin_next
|
|
invoke ScratchEase3D,edx,850
|
|
mov progress,eax
|
|
imul ebx,eax,60
|
|
sar ebx,8
|
|
add ebx,40
|
|
mov edx,256
|
|
sub edx,eax
|
|
imul edx,eax
|
|
imul edx,80
|
|
sar edx,16
|
|
add ebx,edx
|
|
mov coinX,ebx
|
|
imul eax,260
|
|
sar eax,8
|
|
neg eax
|
|
add eax,330
|
|
mov coinY,eax
|
|
mov eax,elapsed
|
|
shr eax,6
|
|
add eax,esi
|
|
and eax,3
|
|
invoke DrawAnimSprite3D,OFFSET scrCoinArt3D,eax,coinX,coinY,20,20
|
|
scratch_payout_coin_next:
|
|
inc esi
|
|
cmp esi,5
|
|
jb scratch_payout_coin
|
|
scratch_payout_done:
|
|
ret
|
|
ScratchDrawPayout3D ENDP
|