KAZIK/src_graphics/bowling_play.inc
Artvasil09 7e081beeca feat: enhance bowling physics, audio, ball weight selection, and visitor cast routines
- 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
2026-11-04 18:44:12 +03:00

480 lines
10 KiB
PHP

; Two timing gates commit one immutable launch; the same solver serves both players.
BeginBowlingPlay3D PROC uses esi lane:DWORD
cmp bpActive3D,0
jne bp_begin_no
mov esi,lane
cmp esi,BW_LANES
jae bp_begin_no
cmp bwBusy3D[esi*4],0
jne bp_begin_no
mov eax,playerX
mov bpHomeX3D,eax
mov eax,playerY
mov bpHomeY3D,eax
mov eax,playerAngle
mov bpHomeAngle3D,eax
mov bpLane3D,esi
imul eax,esi,BW_LANE_STEP
add eax,3*FP_1
mov bpCentre3D,eax
mov bpActive3D,1
mov bwBusy3D[esi*4],2
mov engineMode,MODE_BOWLING
mov paused3D,0
mov bwSeat3D,0
call ResetBowlingPlay3D
mov bpState3D,BP_SELECT_BALL
call BowlingAudioOpen3D
mov eax,1
ret
bp_begin_no:
xor eax,eax
ret
BeginBowlingPlay3D ENDP
ResetBowlingPlay3D PROC uses ebx esi edi
mov esi,bpLane3D
lea ebx,[esi*8]
mov bwFrames3D[ebx],0
mov bwFrames3D[ebx+4],0
mov bwRollCount3D[ebx],0
mov bwRollCount3D[ebx+4],0
mov bwScores3D[ebx],0
mov bwScores3D[ebx+4],0
imul eax,esi,192
lea edi,bwRolls3D[eax]
xor eax,eax
mov ecx,48
rep stosd
mov bwTurn3D[esi*4],0
mov bwBall3D[esi*4],0
mov bwRack3D[esi*4],1023
mov bwState3D[esi*4],0
mov bwHit3D[esi*4],0
mov bwTime3D[esi*4],0
mov bpState3D,BP_DIRECTION
mov bpTime3D,0
call BowlingPlayStartAim3D
mov bpScoreOpen3D,0
mov bpLast3D,0
mov bpLastKind3D,0
mov bpReactionTime3D,0
mov bpAfterReturn3D,BP_DIRECTION
call BowlingPlayRack3D
call ClearKeys3D
mov mouseClick3D,0
ret
ResetBowlingPlay3D ENDP
; Randomize only the visible starting phase, never the committed trajectory.
BowlingPlayStartAim3D PROC
mov eax,bwRng3D
imul eax,1664525
add eax,1013904223
mov bwRng3D,eax
shr eax,16
and eax,2047
mov bpClock3D,eax
ret
BowlingPlayStartAim3D ENDP
LeaveBowlingPlay3D PROC uses esi
cmp bpActive3D,0
je bp_leave_done
call BowlingAudioClose3D
mov esi,bpLane3D
mov bwBusy3D[esi*4],0
mov bwRack3D[esi*4],1023
mov bwHit3D[esi*4],0
mov bwState3D[esi*4],0
mov bpActive3D,0
mov bpScoreOpen3D,0
mov eax,bpHomeX3D
mov playerX,eax
mov eax,bpHomeY3D
mov playerY,eax
mov eax,bpHomeAngle3D
mov playerAngle,eax
mov engineMode,MODE_WALK
call BowlingEye3D
call UpdateCamera3D
call ClearKeys3D
mov mouseClick3D,0
mov bwMonitorClock3D,-1
bp_leave_done:
ret
LeaveBowlingPlay3D ENDP
BowlingPlayRack3D PROC uses esi
xor esi,esi
bp_rack_pin:
mov eax,bwPinX3D[esi*4]
mov bpPinX3D[esi*4],eax
mov eax,bwPinY3D[esi*4]
mov bpPinY3D[esi*4],eax
mov bpPinVX3D[esi*4],0
mov bpPinVY3D[esi*4],0
mov bpPinTilt3D[esi*4],0
mov bpPinTiltV3D[esi*4],0
mov bpPinAxisX3D[esi*4],0
mov bpPinAxisY3D[esi*4],-FP_1
mov bpPinSpin3D[esi*4],0
mov bpPinContactTick3D[esi*4],0
mov bpRadius3D[esi*4],24
inc esi
cmp esi,10
jb bp_rack_pin
mov bpHitMask3D,0
mov bpGutter3D,0
mov bpAccumulator3D,0
mov bpPhysicsTicks3D,0
mov bpEndTicks3D,0
mov bpImpactEnergy3D,0
mov bpImpactCooldown3D,0
mov bpAudioReleased3D,0
mov bpBallX3D,FP_1/2
mov bpBallY3D,24*FP_1
ret
BowlingPlayRack3D ENDP
BowlingPlayLaunch3D PROC
local speed:DWORD,aimX:DWORD,aimLength:REAL8
mov bpState3D,BP_RELEASE
mov bpTime3D,0
mov bpAccumulator3D,0
call BowlingApplyBallMass3D
mov eax,bpLockedPower3D
imul eax,6*FP_1
cdq
mov ecx,100
idiv ecx
add eax,3*FP_1
mov speed,eax
; The gauge fixes launch work, calibrated to the existing six-kilogram ball.
; v = v_reference * sqrt(m_reference / m); no mass-dependent aim noise.
fild bpReferenceKg3D
fidiv bpShotWeightKg3D
fsqrt
fimul speed
fist bpLaunchSpeed3D
fimul bpTickMs3D
fidiv bpSecondMs3D
fistp speed
mov eax,bpLockedAim3D
sub eax,bpBallX3D
mov aimX,eax
fild aimX
fmul st,st
fild bpLaneDistance3D
fmul st,st
faddp st(1),st
fsqrt
fstp aimLength
fild aimX
fdiv aimLength
fimul speed
fistp bpBallVX3D
fild bpLaneDistance3D
fdiv aimLength
fimul speed
fchs
fistp bpBallVY3D
ret
BowlingPlayLaunch3D ENDP
include src_graphics\bowling_physics.inc
include src_graphics\bowling_audio.inc
include src_graphics\bowling_return.inc
include src_graphics\bowling_weight.inc
BowlingPlayFinishRoll3D PROC uses esi
mov eax,bpHitMask3D
xor ecx,ecx
bp_finish_count:
test eax,eax
jz bp_finish_register
lea edx,[eax-1]
and eax,edx
inc ecx
jmp bp_finish_count
bp_finish_register:
mov bpLast3D,ecx
mov bpReaction3D,CAST_TALK
cmp ecx,7
jb @F
mov bpReaction3D,CAST_CHEER
@@:
mov bpReactionTime3D,6500
mov bpLastKind3D,0
mov esi,bpLane3D
cmp bwBall3D[esi*4],1
jne bp_finish_strike
mov eax,bwFirstHit3D[esi*4]
cmp eax,10
je bp_finish_strike
add eax,ecx
cmp eax,10
jne bp_finish_register_score
mov bpLastKind3D,2
jmp bp_finish_register_score
bp_finish_strike:
cmp ecx,10
jne bp_finish_register_score
mov bpLastKind3D,1
bp_finish_register_score:
cmp bpLastKind3D,0
je @F
mov bpReaction3D,CAST_CHEER
@@:
cmp bpReaction3D,CAST_CHEER
jne @F
cmp bpAudioReady3D,0
je @F
invoke mciSendStringA,OFFSET bpClapPlay,0,0,0
@@:
invoke BowlingRegisterRoll3D,bpLane3D,bpLast3D
mov bpState3D,BP_SETTLE
mov bpTime3D,0
mov bwMonitorClock3D,-1
ret
BowlingPlayFinishRoll3D ENDP
BowlingPlayNext3D PROC uses ebx esi
mov esi,bpLane3D
mov eax,bpHitMask3D
not eax
and bwRack3D[esi*4],eax
cmp bwNewRack3D[esi*4],0
je @F
mov bwRack3D[esi*4],1023
@@:
cmp bwFrameDone3D[esi*4],0
je bp_next_ready
xor bwTurn3D[esi*4],1
lea ebx,[esi*2]
add ebx,bwTurn3D[esi*4]
cmp bwFrames3D[ebx*4],10
jb bp_next_ready
xor bwTurn3D[esi*4],1
lea ebx,[esi*2]
add ebx,bwTurn3D[esi*4]
cmp bwFrames3D[ebx*4],10
jb bp_next_ready
mov bpState3D,BP_FINISHED
ret
bp_next_ready:
call BowlingPlayRack3D
call BowlingPlayStartAim3D
mov bpTime3D,0
mov bpState3D,BP_DIRECTION
cmp bwTurn3D[esi*4],0
je @F
mov bpState3D,BP_BOT
@@:
ret
BowlingPlayNext3D ENDP
HandleBowlingPlay3D PROC uses ebx esi
local click:DWORD,elapsed:DWORD,mousePress:DWORD
mov eax,deltaTime3D
sub bpImpactCooldown3D,eax
jns @F
mov bpImpactCooldown3D,0
@@:
sub bpReactionTime3D,eax
jns @F
mov bpReactionTime3D,0
@@:
invoke Pressed3D,9
test eax,eax
jz @F
xor bpScoreOpen3D,1
@@:
mov eax,mouseClick3D
mov click,eax
mov mousePress,eax
mov mouseClick3D,0
cmp click,0
je @F
cmp mouseY3D,224
jb @F
cmp mouseX3D,265
jb @F
call LeaveBowlingPlay3D
ret
@@:
invoke Pressed3D,20h
or click,eax
cmp bpScoreOpen3D,0
jne bp_handle_done
cmp bpState3D,BP_FINISHED
jne bp_handle_clock
cmp click,0
je bp_handle_done
call ResetBowlingPlay3D
mov bpState3D,BP_SELECT_BALL
ret
bp_handle_clock:
mov eax,deltaTime3D
cmp eax,250
jbe @F
mov eax,250
@@:
mov elapsed,eax
add bpClock3D,eax
add bpTime3D,eax
cmp bpState3D,BP_SELECT_BALL
jne @F
cmp mousePress,0
jne bp_handle_rack_mouse
cmp click,0
je bp_handle_rack_mouse
mov bpState3D,BP_DIRECTION
ret
bp_handle_rack_mouse:
invoke HandleBowlingWeight3D,mousePress
jmp bp_handle_done
@@:
cmp bpState3D,BP_DIRECTION
jne bp_handle_power
invoke HandleBowlingWeight3D,mousePress
test eax,eax
jnz bp_handle_done
mov eax,bpClock3D
xor edx,edx
mov ecx,4
div ecx
and eax,511
mov eax,tableSin[eax*4]
imul eax,6
cdq
mov ecx,5
idiv ecx
mov bpAim3D,eax
cmp click,0
je bp_handle_done
mov bpLockedAim3D,eax
mov bpState3D,BP_POWER
mov bpClock3D,0
mov bpTime3D,0
ret
bp_handle_power:
cmp bpState3D,BP_POWER
jne bp_handle_release
mov eax,bpClock3D
xor edx,edx
mov ecx,1600
div ecx
mov eax,edx
cmp eax,800
jbe @F
neg eax
add eax,1600
@@:
shr eax,3
mov bpPower3D,eax
cmp click,0
je bp_handle_done
mov bpLockedPower3D,eax
call BowlingPlayLaunch3D
ret
bp_handle_release:
cmp bpState3D,BP_RELEASE
jne bp_handle_roll
mov esi,bpLane3D
mov ecx,BP_RELEASE_MS
cmp bwTurn3D[esi*4],0
je @F
mov ecx,2400
@@:
cmp bpTime3D,ecx
jb bp_handle_done
mov bpState3D,BP_ROLL
mov bpTime3D,0
ret
bp_handle_roll:
cmp bpState3D,BP_ROLL
jne bp_handle_settle
mov eax,elapsed
add bpAccumulator3D,eax
bp_handle_fixed_step:
cmp bpAccumulator3D,16
jb bp_handle_roll_end
sub bpAccumulator3D,16
call BowlingPlayStep3D
call BowlingPlayReady3D
test eax,eax
jnz bp_handle_impact_done
jmp bp_handle_fixed_step
bp_handle_roll_end:
jmp bp_handle_done
bp_handle_impact_done:
call BowlingPlayFinishRoll3D
ret
bp_handle_settle:
cmp bpState3D,BP_SETTLE
jne bp_handle_reset
cmp bpTime3D,1600
jb bp_handle_done
cmp bpHitMask3D,0
jne @F
mov esi,bpLane3D
cmp bwNewRack3D[esi*4],0
jne @F
call CompleteBowlingRoll3D
ret
@@:
mov bpState3D,BP_RESET
mov bpTime3D,0
cmp bpAudioReady3D,0
je bp_handle_done
invoke mciSendStringA,OFFSET bpResetPlay,0,0,0
jmp bp_handle_done
bp_handle_reset:
cmp bpState3D,BP_RESET
jne bp_handle_bot
cmp bpTime3D,BP_RESET_MS
jb bp_handle_done
call CompleteBowlingRoll3D
ret
bp_handle_bot:
cmp bpState3D,BP_RETURN
jne bp_handle_bot_ready
cmp bpTime3D,BP_RETURN_MS
jb bp_handle_done
mov eax,bpAfterReturn3D
mov bpState3D,eax
mov bpTime3D,0
call ClearKeys3D
jmp bp_handle_done
bp_handle_bot_ready:
cmp bpState3D,BP_BOT
jne bp_handle_done
cmp bpTime3D,1100
jb bp_handle_done
mov eax,bwRng3D
imul eax,1664525
add eax,1013904223
mov bwRng3D,eax
shr eax,16
xor edx,edx
mov ecx,101
div ecx
sub edx,50
imul eax,edx,FP_1
cdq
mov ecx,100
idiv ecx
mov bpLockedAim3D,eax
mov eax,bwRng3D
shr eax,24
and eax,31
add eax,60
mov bpLockedPower3D,eax
call BowlingPlayLaunch3D
bp_handle_done:
call BowlingAudioUpdate3D
ret
HandleBowlingPlay3D ENDP
include src_graphics\bowling_play_render.inc