- Bowling feel: impulse contact solver, string pinsetter cycle, in-world lengthwise return rack and visible ball return lift - Ball weights: 4/5/6/7 kg selection with equal launch work physics, momentum balance, and projected picking - Audio: dedicated MCI channels with 7 synthesized waveaudio cues (release, rolling, impacts, applause, pinsetter, return) - First-person animations: 33-frame player underarm throw/follow-through sequence (player-underarm-v2) - Visitors: 10 persistent shared cast identities with exclusive reservations, activity transitions, and chair sit/rise animations - Tests & verification: comprehensive native regression test suites and updated documentation - Synchronize binaries and update launcher hash to 536E23BED4055562BC63871826FF44FFED037923A9BE8E0F591131DB4FBD104B
455 lines
12 KiB
PHP
455 lines
12 KiB
PHP
.data
|
|
bpFeelScoreRolls dd 10,7,3,0,8,5,4,9,0,6,2,8,1,7,2,9,0,10,7,3
|
|
bpFeelScorePath db 'build\hall-expansion\bowling-scorecard-full.bmp',0
|
|
bpFeelPinPath0 db 'build\hall-expansion\bowling-impact-0.bmp',0
|
|
bpFeelPinPath1 db 'build\hall-expansion\bowling-impact-1.bmp',0
|
|
bpFeelPinPath2 db 'build\hall-expansion\bowling-impact-2.bmp',0
|
|
bpFeelPinPath3 db 'build\hall-expansion\bowling-impact-3.bmp',0
|
|
bpFeelPinPaths dd OFFSET bpFeelPinPath0,OFFSET bpFeelPinPath1,OFFSET bpFeelPinPath2,OFFSET bpFeelPinPath3
|
|
bpFeelStatus db 'status bowlroll mode',0
|
|
bpFeelStatusLight db 'status bowllight mode',0
|
|
bpFeelStatusReset db 'status bowlreset mode',0
|
|
bpFeelStatusReturn db 'status bowlreturn mode',0
|
|
bpFeelReply db 64 dup(0)
|
|
bpFeelSampleAim dd -FP_1/2,-FP_1*45/100,-FP_1*4/10,-FP_1*35/100,-FP_1*3/10,-FP_1/4,-FP_1/5,-FP_1*15/100,-FP_1/10,-FP_1/20
|
|
dd 0,FP_1/20,FP_1/10,FP_1*15/100,FP_1/5,FP_1/4,FP_1*3/10,FP_1*35/100,FP_1*4/10,FP_1*45/100,FP_1/2
|
|
bpFeelSamplePower dd 0,50,100
|
|
bpFeelSamples dd 63*4 dup(0)
|
|
bpFeelSamplesPath db 'build\hall-expansion\bowling-physics-samples.bin',0
|
|
bpFeelSetterTimes dd 0,150,300,900,2000,3750,4150,4400
|
|
bpFeelEmptyPinPath db 'build\hall-expansion\bowling-shape-empty.bmp',0
|
|
bpFeelTinyPinPath db 'build\hall-expansion\bowling-shape-tiny.bmp',0
|
|
include tools/tests/bowling_hand_paths.inc
|
|
.code
|
|
BowlingFeelNativeTests PROC uses ebx esi edi
|
|
local window:DWORD,volume:DWORD,tilt:DWORD,aim:DWORD,power:DWORD,handle:DWORD,count:DWORD
|
|
mov expansionStage,170
|
|
call InitBowling3D
|
|
mov hallLevel3D,HALL_BOWLING
|
|
invoke BeginBowlingPlay3D,1
|
|
mov expansionStage,179
|
|
call ResetBowlingPlay3D
|
|
; Subpixel negative impulses must not collapse the pin's local basis.
|
|
invoke BowlingPlayKick3D,0,1,-1
|
|
cmp bpPinAxisX3D,0
|
|
jne bp_feel_fail
|
|
cmp bpPinAxisY3D,-FP_1
|
|
jne bp_feel_fail
|
|
invoke BowlingPlayKick3D,0,257,257
|
|
mov eax,bpPinAxisX3D
|
|
imul eax
|
|
shrd eax,edx,16
|
|
mov ebx,eax
|
|
mov eax,bpPinAxisY3D
|
|
imul eax
|
|
shrd eax,edx,16
|
|
add eax,ebx
|
|
cmp eax,FP_1*99/100
|
|
jb bp_feel_fail
|
|
cmp eax,FP_1*101/100
|
|
ja bp_feel_fail
|
|
mov bpState3D,BP_SETTLE
|
|
mov bpBallY3D,FP_1*28/10
|
|
mov bpPinTilt3D,128*256
|
|
mov bwRack3D[4],0
|
|
call RenderBowlingPlay3D
|
|
invoke ExpansionSnapshot,OFFSET bpFeelEmptyPinPath
|
|
mov bwRack3D[4],1
|
|
call RenderBowlingPlay3D
|
|
invoke ExpansionSnapshot,OFFSET bpFeelTinyPinPath
|
|
mov expansionStage,170
|
|
call ResetBowlingPlay3D
|
|
mov bwRack3D[4],1
|
|
mov bpGutter3D,1
|
|
mov bpPinVX3D,512
|
|
invoke BowlingPlayKick3D,0,512,0
|
|
cmp bpHitMask3D,0
|
|
jne bp_feel_fail
|
|
mov esi,200
|
|
bp_feel_weak:
|
|
call BowlingPlayStep3D
|
|
dec esi
|
|
jnz bp_feel_weak
|
|
cmp bpHitMask3D,0
|
|
jne bp_feel_fail
|
|
cmp bpPinTilt3D,24*256
|
|
jae bp_feel_fail
|
|
mov expansionStage,171
|
|
call ResetBowlingPlay3D
|
|
mov bwRack3D[4],1
|
|
mov bpGutter3D,1
|
|
mov bpPinVX3D,10000
|
|
invoke BowlingPlayKick3D,0,10000,0
|
|
cmp bpHitMask3D,0
|
|
jne bp_feel_fail
|
|
mov esi,120
|
|
bp_feel_topple:
|
|
call BowlingPlayStep3D
|
|
dec esi
|
|
jnz bp_feel_topple
|
|
test bpHitMask3D,1
|
|
jz bp_feel_fail
|
|
cmp bpPinTilt3D,100*256
|
|
jb bp_feel_fail
|
|
cmp bpPinX3D,FP_1*93/100
|
|
jg bp_feel_fail
|
|
mov expansionStage,172
|
|
; Opening contacts are separated but must not gain another impulse.
|
|
call ResetBowlingPlay3D
|
|
mov bpPinX3D,0
|
|
mov bpPinX3D[4],FP_1*15/100
|
|
mov bpPinY3D,4*FP_1
|
|
mov bpPinY3D[4],4*FP_1
|
|
mov bpPinVX3D,-2000
|
|
mov bpPinVX3D[4],2000
|
|
invoke BowlingPlayContact3D,0,1
|
|
cmp bpPinVX3D,-2000
|
|
jne bp_feel_fail
|
|
cmp bpPinVX3D[4],2000
|
|
jne bp_feel_fail
|
|
; A fallen pin can receive a second impact and transfer momentum again.
|
|
mov bpPinX3D,0
|
|
mov bpPinX3D[4],FP_1*15/100
|
|
mov bpPinVX3D,2000
|
|
mov bpPinVX3D[4],0
|
|
mov bpPinTilt3D,128*256
|
|
mov bpHitMask3D,1
|
|
invoke BowlingPlayContact3D,0,1
|
|
cmp bpPinVX3D[4],500
|
|
jb bp_feel_fail
|
|
cmp bpPinVX3D,2000
|
|
jae bp_feel_fail
|
|
mov expansionStage,173
|
|
call ResetBowlingPlay3D
|
|
mov bpEndTicks3D,100
|
|
mov bpPinTilt3D,40*256
|
|
call BowlingPlayReady3D
|
|
test eax,eax
|
|
jnz bp_feel_fail
|
|
mov bpPinTilt3D,128*256
|
|
call BowlingPlayReady3D
|
|
cmp eax,1
|
|
jne bp_feel_fail
|
|
mov expansionStage,174
|
|
call ResetBowlingPlay3D
|
|
lea esi,bpFeelScoreRolls
|
|
lea edi,bwRolls3D[192]
|
|
mov ecx,20
|
|
rep movsd
|
|
mov bwRollCount3D[8],20
|
|
invoke BowlingScore3D,2
|
|
invoke BowlingRollGlyph3D,2,0,0
|
|
cmp eax,'X'
|
|
jne bp_feel_fail
|
|
invoke BowlingRollGlyph3D,2,1,1
|
|
cmp eax,'/'
|
|
jne bp_feel_fail
|
|
invoke BowlingRollGlyph3D,2,2,0
|
|
cmp eax,'-'
|
|
jne bp_feel_fail
|
|
invoke BowlingRollGlyph3D,2,9,0
|
|
cmp eax,'X'
|
|
jne bp_feel_fail
|
|
invoke BowlingRollGlyph3D,2,9,1
|
|
cmp eax,'7'
|
|
jne bp_feel_fail
|
|
invoke BowlingRollGlyph3D,2,9,2
|
|
cmp eax,'/'
|
|
jne bp_feel_fail
|
|
mov bpScoreOpen3D,1
|
|
call RenderBowlingPlay3D
|
|
invoke ExpansionSnapshot,OFFSET bpFeelScorePath
|
|
mov bwRolls3D[192],0
|
|
mov bwRolls3D[196],10
|
|
mov bwRollCount3D[8],2
|
|
invoke BowlingRollGlyph3D,2,0,1
|
|
cmp eax,'/'
|
|
jne bp_feel_fail
|
|
lea esi,bpFeelScoreRolls
|
|
lea edi,bwRolls3D[192]
|
|
mov ecx,20
|
|
rep movsd
|
|
mov bwRollCount3D[8],20
|
|
mov bwRolls3D[192+18*4],0
|
|
mov bwRolls3D[192+19*4],10
|
|
invoke BowlingRollGlyph3D,2,9,2
|
|
cmp eax,'/'
|
|
jne bp_feel_fail
|
|
mov expansionStage,175
|
|
call ResetBowlingPlay3D
|
|
mov bpLockedAim3D,0
|
|
mov bpLockedPower3D,85
|
|
call BowlingPlayLaunch3D
|
|
mov bpState3D,BP_ROLL
|
|
mov esi,0
|
|
mov edi,0
|
|
bp_feel_impact:
|
|
call BowlingPlayStep3D
|
|
inc esi
|
|
cmp esi,160
|
|
jb bp_feel_impact
|
|
mov eax,esi
|
|
and eax,15
|
|
jnz bp_feel_impact
|
|
imul eax,esi,16
|
|
mov bpTime3D,eax
|
|
call RenderBowlingPlay3D
|
|
invoke ExpansionSnapshot,bpFeelPinPaths[edi*4]
|
|
inc edi
|
|
cmp edi,4
|
|
jb bp_feel_impact
|
|
mov power,0
|
|
mov aim,0
|
|
mov edi,0
|
|
bp_feel_sample:
|
|
call ResetBowlingPlay3D
|
|
mov eax,aim
|
|
mov eax,bpFeelSampleAim[eax*4]
|
|
mov bpLockedAim3D,eax
|
|
mov bpFeelSamples[edi],eax
|
|
mov eax,power
|
|
mov eax,bpFeelSamplePower[eax*4]
|
|
mov bpLockedPower3D,eax
|
|
mov bpFeelSamples[edi+4],eax
|
|
call BowlingPlayLaunch3D
|
|
mov esi,900
|
|
bp_feel_sample_steps:
|
|
call BowlingPlayStep3D
|
|
; Check the constraints throughout the roll, not just at settlement.
|
|
mov ebx,0
|
|
bp_feel_sample_bounds:
|
|
mov eax,bpPinX3D[ebx*4]
|
|
sub eax,bwPinX3D[ebx*4]
|
|
sar eax,8
|
|
imul eax,eax
|
|
mov ecx,eax
|
|
mov eax,bpPinY3D[ebx*4]
|
|
sub eax,bwPinY3D[ebx*4]
|
|
sar eax,8
|
|
imul eax,eax
|
|
add eax,ecx
|
|
cmp eax,132*132
|
|
ja bp_feel_fail
|
|
mov eax,bpPinAxisX3D[ebx*4]
|
|
imul eax
|
|
shrd eax,edx,16
|
|
mov ecx,eax
|
|
mov eax,bpPinAxisY3D[ebx*4]
|
|
imul eax
|
|
shrd eax,edx,16
|
|
add eax,ecx
|
|
cmp eax,FP_1*99/100
|
|
jb bp_feel_fail
|
|
cmp eax,FP_1*101/100
|
|
ja bp_feel_fail
|
|
inc ebx
|
|
cmp ebx,10
|
|
jb bp_feel_sample_bounds
|
|
dec esi
|
|
jnz bp_feel_sample_steps
|
|
mov eax,bpHitMask3D
|
|
mov bpFeelSamples[edi+8],eax
|
|
mov eax,bpPinTilt3D
|
|
mov bpFeelSamples[edi+12],eax
|
|
add edi,16
|
|
inc aim
|
|
cmp aim,21
|
|
jb bp_feel_sample
|
|
mov aim,0
|
|
inc power
|
|
cmp power,3
|
|
jb bp_feel_sample
|
|
invoke CreateFileA,OFFSET bpFeelSamplesPath,40000000h,0,0,2,80h,0
|
|
mov handle,eax
|
|
invoke WriteFile,handle,OFFSET bpFeelSamples,SIZEOF bpFeelSamples,ADDR count,0
|
|
invoke CloseHandle,handle
|
|
mov expansionStage,176
|
|
call ResetBowlingPlay3D
|
|
xor esi,esi
|
|
bp_feel_hand:
|
|
mov bpState3D,BP_RELEASE
|
|
imul eax,esi,33
|
|
mov bpTime3D,eax
|
|
cmp esi,21
|
|
jb @F
|
|
mov bpState3D,BP_ROLL
|
|
sub eax,21*33
|
|
mov bpTime3D,eax
|
|
@@:
|
|
call RenderBowlingPlay3D
|
|
invoke ExpansionSnapshot,bpFeelHandPaths[esi*4]
|
|
inc esi
|
|
cmp esi,33
|
|
jb bp_feel_hand
|
|
mov expansionStage,178
|
|
call ResetBowlingPlay3D
|
|
mov bpPinX3D,2*FP_1
|
|
mov bpPinVX3D,10000
|
|
invoke BowlingPlayTether3D,0
|
|
cmp bpPinX3D,FP_1*67/100
|
|
ja bp_feel_fail
|
|
cmp bpPinVX3D,2500
|
|
ja bp_feel_fail
|
|
mov bpPinTilt3D,128*256
|
|
mov bpPinAxisX3D,FP_1
|
|
mov bpPinAxisY3D,0
|
|
invoke BowlingPlayDeckBounds3D,0
|
|
cmp bpPinX3D,FP_1*48/100
|
|
ja bp_feel_fail
|
|
call ResetBowlingPlay3D
|
|
mov bpHitMask3D,1
|
|
mov bpPinTilt3D,128*256
|
|
call BowlingPlayFinishRoll3D
|
|
mov deltaTime3D,250
|
|
mov esi,7
|
|
bp_feel_start_setter:
|
|
call HandleBowlingPlay3D
|
|
dec esi
|
|
jnz bp_feel_start_setter
|
|
cmp bpState3D,BP_RESET
|
|
jne bp_feel_fail
|
|
cmp bwRollCount3D[8],1
|
|
jne bp_feel_fail
|
|
mov bpTime3D,1100
|
|
invoke BowlingPinsetterPose3D,0
|
|
test eax,eax
|
|
jz bp_feel_fail
|
|
cmp bpVisualPinLift3D,FP_1/2
|
|
jb bp_feel_fail
|
|
cmp bpPinTilt3D,128*256
|
|
jne bp_feel_fail
|
|
mov bpTime3D,1800
|
|
invoke BowlingPinsetterPose3D,0
|
|
cmp eax,1
|
|
jne bp_feel_fail
|
|
cmp bpVisualPinLift3D,FP_1
|
|
jb bp_feel_fail
|
|
mov bpTime3D,2450
|
|
invoke BowlingPinsetterPose3D,0
|
|
cmp eax,1
|
|
jne bp_feel_fail
|
|
cmp bpVisualPinLift3D,FP_1
|
|
jb bp_feel_fail
|
|
invoke BowlingPinsetterPose3D,1
|
|
cmp eax,1
|
|
jne bp_feel_fail
|
|
mov bwNewRack3D[4],1
|
|
invoke BowlingPinsetterPose3D,0
|
|
cmp eax,1
|
|
jne bp_feel_fail
|
|
mov bwNewRack3D[4],0
|
|
mov bpTime3D,3750
|
|
invoke BowlingPinsetterPose3D,1
|
|
cmp bpVisualPinLift3D,0
|
|
jne bp_feel_fail
|
|
mov esi,0
|
|
bp_feel_setter_capture:
|
|
mov eax,bpFeelSetterTimes[esi*4]
|
|
mov bpTime3D,eax
|
|
mov bpBallY3D,FP_1*28/10
|
|
call RenderBowlingPlay3D
|
|
invoke ExpansionSnapshot,bpFeelSetterPaths[esi*4]
|
|
inc esi
|
|
cmp esi,8
|
|
jb bp_feel_setter_capture
|
|
mov bpTime3D,BP_RESET_MS
|
|
mov deltaTime3D,0
|
|
call HandleBowlingPlay3D
|
|
cmp bpState3D,BP_RETURN
|
|
jne bp_feel_fail
|
|
mov bpTime3D,BP_RETURN_MS
|
|
call HandleBowlingPlay3D
|
|
cmp bpState3D,BP_DIRECTION
|
|
jne bp_feel_fail
|
|
cmp bwRack3D[4],1022
|
|
jne bp_feel_fail
|
|
cmp bwRollCount3D[8],1
|
|
jne bp_feel_fail
|
|
; First-ball miss leaves the standing rack alone and never runs the hoist.
|
|
call ResetBowlingPlay3D
|
|
call BowlingPlayFinishRoll3D
|
|
mov bpTime3D,1600
|
|
call HandleBowlingPlay3D
|
|
cmp bpState3D,BP_RETURN
|
|
jne bp_feel_fail
|
|
mov bpTime3D,BP_RETURN_MS
|
|
call HandleBowlingPlay3D
|
|
cmp bpState3D,BP_DIRECTION
|
|
jne bp_feel_fail
|
|
cmp bwRack3D[4],1023
|
|
jne bp_feel_fail
|
|
mov bpState3D,BP_RESET
|
|
mov bpTime3D,0
|
|
call BowlingPinsetterGate3D
|
|
cmp eax,FP_1
|
|
jne bp_feel_fail
|
|
mov bpTime3D,400
|
|
call BowlingPinsetterGate3D
|
|
cmp eax,FP_1*14/100
|
|
ja bp_feel_fail
|
|
mov bpTime3D,4400
|
|
call BowlingPinsetterGate3D
|
|
cmp eax,FP_1
|
|
jne bp_feel_fail
|
|
mov expansionStage,177
|
|
; Real MCI devices, muted: opens, volume, release/roll/impact and close.
|
|
mov eax,h3DWnd
|
|
mov window,eax
|
|
mov eax,settingsVolume
|
|
mov volume,eax
|
|
mov h3DWnd,1
|
|
mov settingsVolume,0
|
|
call BowlingAudioOpen3D
|
|
mov bpScoreOpen3D,0
|
|
mov bpState3D,BP_ROLL
|
|
mov bpEndTicks3D,0
|
|
mov bpImpactEnergy3D,6000
|
|
mov bpImpactCooldown3D,0
|
|
call BowlingAudioUpdate3D
|
|
invoke mciSendStringA,OFFSET bpFeelStatus,OFFSET bpFeelReply,64,0
|
|
test eax,eax
|
|
jnz bp_feel_audio_fail
|
|
cmp BYTE PTR bpFeelReply,'p'
|
|
jne bp_feel_audio_fail
|
|
invoke mciSendStringA,OFFSET bpFeelStatusLight,OFFSET bpFeelReply,64,0
|
|
test eax,eax
|
|
jnz bp_feel_audio_fail
|
|
invoke mciSendStringA,OFFSET bpFeelStatusReset,OFFSET bpFeelReply,64,0
|
|
test eax,eax
|
|
jnz bp_feel_audio_fail
|
|
mov bpScoreOpen3D,1
|
|
call BowlingAudioUpdate3D
|
|
cmp bpAudioRolling3D,0
|
|
jne bp_feel_audio_fail
|
|
mov bpScoreOpen3D,0
|
|
mov bpState3D,BP_RETURN
|
|
mov bpTime3D,500
|
|
call BowlingAudioUpdate3D
|
|
invoke mciSendStringA,OFFSET bpFeelStatusReturn,OFFSET bpFeelReply,64,0
|
|
test eax,eax
|
|
jnz bp_feel_audio_fail
|
|
cmp BYTE PTR bpFeelReply,'p'
|
|
jne bp_feel_audio_fail
|
|
mov bpScoreOpen3D,1
|
|
call BowlingAudioUpdate3D
|
|
cmp bpAudioReturning3D,0
|
|
jne bp_feel_audio_fail
|
|
call BowlingAudioClose3D
|
|
invoke mciSendStringA,OFFSET bpFeelStatus,OFFSET bpFeelReply,64,0
|
|
test eax,eax
|
|
jz bp_feel_audio_fail
|
|
invoke mciSendStringA,OFFSET bpFeelStatusReturn,OFFSET bpFeelReply,64,0
|
|
test eax,eax
|
|
jz bp_feel_audio_fail
|
|
mov eax,window
|
|
mov h3DWnd,eax
|
|
mov eax,volume
|
|
mov settingsVolume,eax
|
|
call LeaveBowlingPlay3D
|
|
ret
|
|
bp_feel_audio_fail:
|
|
call BowlingAudioClose3D
|
|
bp_feel_fail:
|
|
invoke ExitProcess,expansionStage
|
|
ret
|
|
BowlingFeelNativeTests ENDP
|