.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