- Add playable ten-frame bowling against bot with two timing gates (direction/power) and fixed-step physics - Add lane match interaction, shaded ball surface, pin collisions, bonus balls, and live score sheet - Scale rooftop terrace visitor sprites to eye level according to the taller rooftop standing eye height - Resolve mode and interaction ID conflicts with Hell FPS (MODE_BOWLING=30, INTERACT_BOWL_PLAY=56) - Update launcher hash, installer package, and expansion regression test suites
507 lines
10 KiB
PHP
507 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 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
|
|
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
|
|
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
|
|
inc esi
|
|
cmp esi,10
|
|
jb bp_rack_pin
|
|
mov bpHitMask3D,0
|
|
mov bpGutter3D,0
|
|
mov bpAccumulator3D,0
|
|
mov bpBallX3D,0
|
|
mov bpBallY3D,FP_1*225/10
|
|
ret
|
|
BowlingPlayRack3D ENDP
|
|
|
|
BowlingPlayLaunch3D PROC
|
|
mov bpState3D,BP_RELEASE
|
|
mov bpTime3D,0
|
|
mov bpAccumulator3D,0
|
|
mov eax,bpLockedPower3D
|
|
imul eax,6*FP_1
|
|
cdq
|
|
mov ecx,100
|
|
idiv ecx
|
|
add eax,3*FP_1
|
|
imul eax,16
|
|
cdq
|
|
mov ecx,1000
|
|
idiv ecx
|
|
mov ecx,eax
|
|
neg eax
|
|
mov bpBallVY3D,eax
|
|
mov eax,bpLockedAim3D
|
|
imul ecx
|
|
mov ecx,18*FP_1
|
|
idiv ecx
|
|
mov bpBallVX3D,eax
|
|
ret
|
|
BowlingPlayLaunch3D ENDP
|
|
|
|
BowlingPlayHit3D PROC uses esi pin:DWORD,vx:DWORD,vy:DWORD
|
|
mov esi,pin
|
|
mov ecx,esi
|
|
mov eax,1
|
|
shl eax,cl
|
|
test bpHitMask3D,eax
|
|
jnz bp_hit_done
|
|
or bpHitMask3D,eax
|
|
mov eax,vx
|
|
mov bpPinVX3D[esi*4],eax
|
|
mov eax,vy
|
|
mov bpPinVY3D[esi*4],eax
|
|
bp_hit_done:
|
|
ret
|
|
BowlingPlayHit3D ENDP
|
|
|
|
; 16-ms fixed steps, lane-relative 16.16 discs. No random hit selection.
|
|
BowlingPlayStep3D PROC uses ebx esi edi
|
|
local deltaX:DWORD,deltaY:DWORD,impulseX:DWORD,rackMask:DWORD
|
|
mov esi,bpLane3D
|
|
mov eax,bwRack3D[esi*4]
|
|
mov rackMask,eax
|
|
mov eax,bpBallVX3D
|
|
add bpBallX3D,eax
|
|
mov eax,bpBallVY3D
|
|
add bpBallY3D,eax
|
|
mov eax,bpBallX3D
|
|
cdq
|
|
xor eax,edx
|
|
sub eax,edx
|
|
cmp eax,FP_1*74/100
|
|
jbe bp_step_pins
|
|
mov bpGutter3D,1
|
|
mov eax,FP_1*87/100
|
|
cmp bpBallX3D,0
|
|
jge @F
|
|
neg eax
|
|
@@:
|
|
mov bpBallX3D,eax
|
|
mov bpBallVX3D,0
|
|
bp_step_pins:
|
|
xor esi,esi
|
|
bp_step_pin:
|
|
mov ecx,esi
|
|
mov ebx,1
|
|
shl ebx,cl
|
|
test rackMask,ebx
|
|
jz bp_step_next_pin
|
|
test bpHitMask3D,ebx
|
|
jnz bp_step_move_pin
|
|
cmp bpGutter3D,0
|
|
jne bp_step_next_pin
|
|
mov eax,bpPinX3D[esi*4]
|
|
sub eax,bpBallX3D
|
|
mov deltaX,eax
|
|
sar eax,8
|
|
imul eax,eax
|
|
mov edi,eax
|
|
mov eax,bpPinY3D[esi*4]
|
|
sub eax,bpBallY3D
|
|
sar eax,8
|
|
imul eax,eax
|
|
add eax,edi
|
|
cmp eax,56*56
|
|
ja bp_step_next_pin
|
|
mov eax,deltaX
|
|
sar eax,3
|
|
add eax,bpBallVX3D
|
|
mov impulseX,eax
|
|
mov eax,bpBallVY3D
|
|
imul eax,3
|
|
sar eax,2
|
|
invoke BowlingPlayHit3D,esi,impulseX,eax
|
|
bp_step_move_pin:
|
|
mov eax,bpPinVX3D[esi*4]
|
|
add bpPinX3D[esi*4],eax
|
|
imul eax,245
|
|
sar eax,8
|
|
mov bpPinVX3D[esi*4],eax
|
|
mov eax,bpPinVY3D[esi*4]
|
|
add bpPinY3D[esi*4],eax
|
|
imul eax,245
|
|
sar eax,8
|
|
mov bpPinVY3D[esi*4],eax
|
|
xor edi,edi
|
|
bp_step_chain:
|
|
mov ecx,edi
|
|
mov ebx,1
|
|
shl ebx,cl
|
|
test rackMask,ebx
|
|
jz bp_step_chain_next
|
|
test bpHitMask3D,ebx
|
|
jnz bp_step_chain_next
|
|
mov eax,bpPinX3D[edi*4]
|
|
sub eax,bpPinX3D[esi*4]
|
|
mov deltaX,eax
|
|
sar eax,8
|
|
imul eax,eax
|
|
mov ebx,eax
|
|
mov eax,bpPinY3D[edi*4]
|
|
sub eax,bpPinY3D[esi*4]
|
|
mov deltaY,eax
|
|
sar eax,8
|
|
imul eax,eax
|
|
add eax,ebx
|
|
cmp eax,49*49
|
|
ja bp_step_chain_next
|
|
mov eax,deltaX
|
|
sar eax,8
|
|
imul bpPinVX3D[esi*4]
|
|
mov ebx,eax
|
|
mov eax,deltaY
|
|
sar eax,8
|
|
imul bpPinVY3D[esi*4]
|
|
add eax,ebx
|
|
jle bp_step_chain_next
|
|
mov eax,bpPinVX3D[esi*4]
|
|
sar eax,1
|
|
mov ebx,deltaX
|
|
sar ebx,3
|
|
add eax,ebx
|
|
mov impulseX,eax
|
|
mov eax,bpPinVY3D[esi*4]
|
|
sar eax,1
|
|
mov ebx,deltaY
|
|
sar ebx,3
|
|
add eax,ebx
|
|
invoke BowlingPlayHit3D,edi,impulseX,eax
|
|
bp_step_chain_next:
|
|
inc edi
|
|
cmp edi,10
|
|
jb bp_step_chain
|
|
bp_step_next_pin:
|
|
inc esi
|
|
cmp esi,10
|
|
jb bp_step_pin
|
|
ret
|
|
BowlingPlayStep3D ENDP
|
|
|
|
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 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:
|
|
invoke BowlingRegisterRoll3D,bpLane3D,ecx
|
|
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
|
|
invoke Pressed3D,9
|
|
test eax,eax
|
|
jz @F
|
|
xor bpScoreOpen3D,1
|
|
@@:
|
|
mov eax,mouseClick3D
|
|
mov click,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
|
|
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_DIRECTION
|
|
jne bp_handle_power
|
|
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,350
|
|
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
|
|
cmp bpBallY3D,3*FP_1
|
|
jl bp_handle_impact_done
|
|
jmp bp_handle_fixed_step
|
|
bp_handle_roll_end:
|
|
cmp bpBallY3D,3*FP_1
|
|
jl bp_handle_impact_done
|
|
cmp bpTime3D,12000
|
|
jb bp_handle_done
|
|
bp_handle_impact_done:
|
|
call BowlingPlayFinishRoll3D
|
|
ret
|
|
bp_handle_settle:
|
|
cmp bpState3D,BP_SETTLE
|
|
jne bp_handle_bot
|
|
cmp bpTime3D,1800
|
|
jb bp_handle_done
|
|
call BowlingPlayNext3D
|
|
ret
|
|
bp_handle_bot:
|
|
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:
|
|
ret
|
|
HandleBowlingPlay3D ENDP
|
|
|
|
include src_graphics\bowling_play_render.inc
|