KAZIK/src_graphics/bowling_play_render.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

566 lines
13 KiB
PHP

; A small native marble surface avoids shipping a second copy of a ball sprite.
InitBowlingBallSurface3D PROC uses ebx esi edi
local stripe:DWORD
xor esi,esi
lea edi,bpBallSurface3D
bp_ball_tex_row:
xor ebx,ebx
bp_ball_tex_pixel:
mov eax,esi
shl eax,3
and eax,511
mov eax,tableSin[eax*4]
sar eax,11
lea eax,[eax+ebx*8]
and eax,511
mov eax,tableSin[eax*4]
add eax,FP_1
shr eax,12
mov stripe,eax
lea edx,[eax+5]
shl edx,16
lea eax,[eax*2+48]
shl eax,8
or edx,eax
mov eax,stripe
shl eax,1
add eax,155
or eax,edx
or eax,0FF000000h
stosd
inc ebx
cmp ebx,64
jb bp_ball_tex_pixel
inc esi
cmp esi,64
jb bp_ball_tex_row
xor esi,esi
bp_ball_tex_variants:
mov eax,bpBallSurface3D[esi*4]
invoke BowlingTintBallPixel3D,eax,4
mov bpBallSurface3D[esi*4+64*64*4],eax
mov eax,bpBallSurface3D[esi*4]
invoke BowlingTintBallPixel3D,eax,5
mov bpBallSurface3D[esi*4+2*64*64*4],eax
mov eax,bpBallSurface3D[esi*4]
invoke BowlingTintBallPixel3D,eax,7
mov bpBallSurface3D[esi*4+3*64*64*4],eax
inc esi
cmp esi,64*64
jb bp_ball_tex_variants
ret
InitBowlingBallSurface3D ENDP
include src_graphics\bowling_pin_shape.inc
include src_graphics\bowling_pinsetter.inc
DrawBowlingPlayPin3D PROC uses ebx esi edi pin:DWORD,centre:DWORD
local baseX:DWORD,baseY:DWORD,axisX:DWORD,axisY:DWORD,axisZ:DWORD
local x:DWORD,y:DWORD,z:DWORD,radius:DWORD
mov esi,pin
invoke BowlingPinsetterPose3D,esi
test eax,eax
jz bp_pin_done
mov eax,bpVisualPinX3D
add eax,centre
mov baseX,eax
mov eax,bpVisualPinY3D
mov baseY,eax
mov eax,bpVisualPinTilt3D
shr eax,8
cmp eax,128
jbe @F
mov eax,128
@@:
mov edi,tableSin[eax*4]
mov ecx,edi
neg ecx
mov bpRenderVZ3D,ecx
mov eax,tableCos[eax*4]
mov axisZ,eax
mov bpRenderNZ3D,eax
imul bpPinAxisX3D[esi*4]
shrd eax,edx,16
mov bpRenderVX3D,eax
mov eax,axisZ
imul bpPinAxisY3D[esi*4]
shrd eax,edx,16
mov bpRenderVY3D,eax
mov eax,bpPinAxisY3D[esi*4]
mov bpRenderUX3D,eax
mov eax,bpPinAxisX3D[esi*4]
neg eax
mov bpRenderUY3D,eax
mov eax,bpPinAxisX3D[esi*4]
imul edi
shrd eax,edx,16
mov axisX,eax
mov bpRenderNX3D,eax
mov eax,bpPinAxisY3D[esi*4]
imul edi
shrd eax,edx,16
mov axisY,eax
mov bpRenderNY3D,eax
xor ebx,ebx
bp_pin_section:
mov eax,bpPinSectionHeight3D[ebx*4]
imul axisX
shrd eax,edx,16
add eax,baseX
mov x,eax
mov eax,bpPinSectionHeight3D[ebx*4]
imul axisY
shrd eax,edx,16
add eax,baseY
mov y,eax
mov eax,bpPinSectionHeight3D[ebx*4]
imul axisZ
shrd eax,edx,16
add eax,FP_1*8/100
add eax,bpVisualPinLift3D
mov z,eax
mov eax,bpPinSectionRadius3D[ebx*4]
mov radius,eax
invoke DrawBowlingEllipsoid3D,x,y,z,radius,radius,bpPinSectionLength3D[ebx*4],bpPinSectionMaterial3D[ebx*4]
inc ebx
cmp ebx,4
jb bp_pin_section
bp_pin_done:
ret
DrawBowlingPlayPin3D ENDP
; A frame's cumulative score stays unresolved until all its bonuses are known.
BowlingFrameTotal3D PROC uses ebx esi edi owner:DWORD,wanted:DWORD
local total:DWORD,index:DWORD,available:DWORD,current:DWORD
mov ebx,owner
mov eax,bwRollCount3D[ebx*4]
mov available,eax
imul ebx,96
lea esi,bwRolls3D[ebx]
mov index,0
mov current,0
mov total,0
bp_frame_loop:
mov edi,index
cmp edi,available
jae bp_frame_pending
mov eax,[esi+edi*4]
mov ebx,eax
inc edi
cmp edi,available
jae bp_frame_pending
add eax,[esi+edi*4]
inc edi
cmp ebx,10
je bp_frame_bonus
cmp eax,10
jne bp_frame_open
bp_frame_bonus:
cmp edi,available
jae bp_frame_pending
add eax,[esi+edi*4]
bp_frame_open:
add total,eax
cmp ebx,10
jne @F
dec edi
@@:
mov index,edi
mov eax,current
cmp eax,wanted
je bp_frame_ready
inc current
jmp bp_frame_loop
bp_frame_ready:
mov eax,total
ret
bp_frame_pending:
mov eax,-1
ret
BowlingFrameTotal3D ENDP
include src_graphics\bowling_scorecard.inc
DrawBowlingGaugeLine3D PROC uses ebx esi edi x0:DWORD,y0:DWORD,x1:DWORD,y1:DWORD
local px:DWORD,py:DWORD,stepX:DWORD,stepY:DWORD
mov eax,x1
sub eax,x0
cdq
xor eax,edx
sub eax,edx
mov ebx,eax
mov eax,y1
sub eax,y0
cdq
xor eax,edx
sub eax,edx
cmp eax,ebx
jbe @F
mov ebx,eax
@@:
test ebx,ebx
jnz @F
inc ebx
@@:
mov eax,x1
sub eax,x0
shl eax,16
cdq
idiv ebx
mov stepX,eax
mov eax,y1
sub eax,y0
shl eax,16
cdq
idiv ebx
mov stepY,eax
mov eax,x0
shl eax,16
mov px,eax
mov eax,y0
shl eax,16
mov py,eax
inc ebx
bp_gauge_line:
mov eax,px
sar eax,16
mov edx,py
sar edx,16
invoke DrawBox,eax,edx,1,1,00D8F5B7h
mov eax,stepX
add px,eax
mov eax,stepY
add py,eax
dec ebx
jnz bp_gauge_line
ret
DrawBowlingGaugeLine3D ENDP
include src_graphics\bowling_performance.inc
RenderBowlingPlay3D PROC uses ebx esi edi
local x:DWORD,y:DWORD,color:DWORD,owner:DWORD,startY:DWORD
mov eax,bpCentre3D
mov playerX,eax
mov startY,FP_1*252/10
mov esi,bpLane3D
cmp bwTurn3D[esi*4],0
je @F
mov startY,FP_1*264/10
@@:
mov eax,startY
mov playerY,eax
mov playerAngle,384
call BowlingEye3D
cmp bpState3D,BP_ROLL
je bp_camera_follow
cmp bpState3D,BP_SETTLE
je bp_camera_follow
cmp bpState3D,BP_RESET
jne bp_camera_ready
bp_camera_follow:
mov eax,bpBallY3D
add eax,FP_1*27/10
cmp eax,7*FP_1
jge @F
mov eax,7*FP_1
@@:
mov playerY,eax
mov viewEye3D,FP_1*7/10
cmp bpState3D,BP_RESET
jne bp_camera_roll_blend
mov ebx,bpTime3D
cmp ebx,400
jbe @F
mov ebx,400
@@:
imul eax,ebx,2*FP_1
cdq
mov ecx,400
idiv ecx
add playerY,eax
mov eax,playerY
mov ebx,bpTime3D
sub ebx,BP_RESET_MS-800
jle bp_camera_ready
cmp ebx,800
jbe @F
mov ebx,800
@@:
mov edx,startY
sub edx,eax
mov eax,edx
imul eax,ebx
cdq
mov ecx,800
idiv ecx
add playerY,eax
imul eax,ebx,HALL_STANDING_EYE-FP_1*7/10
cdq
idiv ecx
add viewEye3D,eax
jmp bp_camera_ready
bp_camera_roll_blend:
cmp bpState3D,BP_ROLL
jne bp_camera_ready
mov ebx,bpTime3D
cmp ebx,500
jae bp_camera_ready
sub eax,startY
imul eax,ebx
cdq
mov ecx,500
idiv ecx
add eax,startY
mov playerY,eax
mov edx,HALL_STANDING_EYE
cmp bwTurn3D[esi*4],0
jne @F
mov edx,FP_1*55/100
@@:
mov x,edx
mov eax,FP_1*7/10
sub eax,edx
imul eax,ebx
cdq
idiv ecx
add eax,x
mov viewEye3D,eax
bp_camera_ready:
cmp bpState3D,BP_SELECT_BALL
jne @F
call BowlingRackCamera3D
@@:
cmp bpState3D,BP_RETURN
jne @F
invoke BowlingReturnCamera3D,startY
@@:
cmp bpState3D,BP_RELEASE
jne @F
cmp bwTurn3D[esi*4],0
jne @F
mov eax,bpTime3D
cmp eax,BP_RELEASE_MS
jbe bp_camera_release_time
mov eax,BP_RELEASE_MS
bp_camera_release_time:
imul eax,FP_1/2
cdq
mov ecx,BP_RELEASE_MS
idiv ecx
mov edx,HALL_STANDING_EYE
sub edx,eax
mov viewEye3D,edx
@@:
call UpdateCamera3D
call RenderBowling3D
call RenderBowlingPinsetter3D
mov esi,bpLane3D
cmp bwTurn3D[esi*4],1
jne bp_render_ball
cmp bpState3D,BP_BOT
je bp_render_bot_ready
cmp bpState3D,BP_RELEASE
je bp_render_bot_throw
cmp bpState3D,BP_ROLL
jne bp_render_ball
invoke ConfigureCharacter3D,OFFSET bwActor3D,6,CAST_THROW,2300,0,-FP_1
jmp bp_render_bot_draw
bp_render_bot_throw:
invoke ConfigureCharacter3D,OFFSET bwActor3D,6,CAST_THROW,bpTime3D,0,-FP_1
jmp bp_render_bot_draw
bp_render_bot_ready:
invoke ConfigureCharacter3D,OFFSET bwActor3D,6,CAST_IDLE,bpTime3D,0,0
bp_render_bot_draw:
mov eax,bpCentre3D
add eax,FP_1*38/100
mov bwActor3D.posX,eax
mov bwActor3D.posY,FP_1*235/10
invoke DrawCityObject3D,OFFSET bwActor3D,0
bp_render_ball:
call RenderBowlingReactions3D
cmp bpState3D,BP_SELECT_BALL
je bp_render_hud
cmp bpState3D,BP_FINISHED
je bp_render_hud
cmp bpState3D,BP_ROLL
je bp_render_real_ball
cmp bpState3D,BP_SETTLE
je bp_render_real_ball
cmp bpState3D,BP_RESET
je bp_render_hud
cmp bpState3D,BP_RETURN
je bp_render_hud
cmp bpHandArt3D.pixels,0
jne bp_render_hud
bp_render_real_ball:
cmp bpEndTicks3D,25
jae bp_render_hud
mov eax,bpBallX3D
add eax,bpCentre3D
mov x,eax
invoke BowlingBallMaterial3D,bpShotWeightKg3D
invoke DrawBowlingBall3D,x,bpBallY3D,eax
bp_render_hud:
call DrawBowlingPlayerHand3D
invoke DrawBox,0,0,320,17,00121B20h
invoke DrawString8x8,8,4,OFFSET bpTitle,00E8D7ADh
mov eax,bpLane3D
shl eax,1
mov owner,eax
mov esi,eax
invoke DrawString8x8,100,4,OFFSET bpYou,005BC9BEh
invoke FormatNumber,bwScores3D[esi*4],OFFSET bpText3D
invoke DrawString8x8,126,4,OFFSET bpText3D,00FFFFFFh
invoke DrawString8x8,205,4,OFFSET bpBot,00E8D7ADh
invoke FormatNumber,bwScores3D[esi*4+4],OFFSET bpText3D
invoke DrawString8x8,248,4,OFFSET bpText3D,00FFFFFFh
invoke DrawBox,0,221,320,19,00121B20h
invoke DrawString8x8,268,227,OFFSET bpExitText,00E8D7ADh
mov esi,bpLane3D
mov eax,bwTurn3D[esi*4]
add owner,eax
mov eax,OFFSET bpYou
cmp bwTurn3D[esi*4],0
je @F
mov eax,OFFSET bpBot
@@:
invoke DrawString8x8,8,227,eax,005BC9BEh
mov ebx,owner
mov eax,bwFrames3D[ebx*4]
cmp bpState3D,BP_SETTLE
je bp_frame_result
cmp bpState3D,BP_RESET
jne @F
bp_frame_result:
cmp bwFrameDone3D[esi*4],0
je @F
dec eax
@@:
inc eax
cmp eax,10
jbe @F
mov eax,10
@@:
invoke FormatNumber,eax,OFFSET bpText3D
invoke DrawString8x8,60,227,OFFSET bpFrameText,00AABDB6h
invoke DrawString8x8,116,227,OFFSET bpText3D,00FFFFFFh
cmp bpState3D,BP_DIRECTION
je bp_render_direction
cmp bpState3D,BP_SELECT_BALL
je bp_render_done
cmp bpState3D,BP_POWER
je bp_render_power
cmp bpState3D,BP_SETTLE
je bp_render_result
cmp bpState3D,BP_FINISHED
je bp_render_finished
cmp bpState3D,BP_RESET
jne @F
invoke DrawString8x8,104,197,OFFSET bpResetText,00E8D7ADh
jmp bp_render_done
@@:
cmp bpState3D,BP_RETURN
jne @F
invoke DrawString8x8,104,197,OFFSET bpReturnText,00E8D7ADh
jmp bp_render_done
@@:
invoke DrawString8x8,8,204,OFFSET bpRollText,00E8D7ADh
jmp bp_render_done
bp_render_direction:
invoke DrawString8x8,108,145,OFFSET bpDirectionText,00E8D7ADh
xor esi,esi
bp_render_arc:
lea eax,[esi-70]
imul eax,eax
xor edx,edx
mov ecx,380
div ecx
add eax,169
mov y,eax
mov color,00D67057h
cmp esi,27
jb @F
cmp esi,113
ja @F
mov color,00E7C455h
cmp esi,59
jb @F
cmp esi,81
ja @F
mov color,005BC98Ch
@@:
lea eax,[esi+90]
invoke DrawBox,eax,y,1,6,color
inc esi
cmp esi,141
jb bp_render_arc
mov eax,bpAim3D
imul eax,52
sar eax,16
add eax,160
mov x,eax
invoke DrawBowlingGaugeLine3D,160,205,eax,162
mov eax,x
lea ebx,[eax-5]
invoke DrawBowlingGaugeLine3D,eax,162,ebx,168
mov eax,x
lea ebx,[eax+5]
invoke DrawBowlingGaugeLine3D,eax,162,ebx,168
jmp bp_render_done
bp_render_power:
invoke DrawString8x8,16,62,OFFSET bpPowerText,00E8D7ADh
invoke DrawBoxBorder,30,79,13,124,00121B20h,00AABDB6h,1
invoke DrawBox,32,82,9,118,00D67057h
invoke DrawBox,32,128,9,38,00E7C455h
invoke DrawBox,32,82,9,46,005BC98Ch
mov eax,bpPower3D
imul eax,116
xor edx,edx
mov ecx,100
div ecx
mov edx,198
sub edx,eax
mov y,edx
invoke DrawBox,24,y,25,2,00FFFFFFh
invoke FormatNumber,bpPower3D,OFFSET bpText3D
invoke DrawString8x8,50,180,OFFSET bpText3D,00FFFFFFh
jmp bp_render_done
bp_render_result:
mov eax,OFFSET bpResultText
cmp bpGutter3D,0
je @F
mov eax,OFFSET bpGutterText
@@:
cmp bpLastKind3D,1
jne @F
mov eax,OFFSET bpStrikeText
@@:
cmp bpLastKind3D,2
jne @F
mov eax,OFFSET bpSpareText
@@:
invoke DrawString8x8,104,197,eax,00E8D7ADh
invoke FormatNumber,bpLast3D,OFFSET bpText3D
invoke DrawString8x8,192,197,OFFSET bpText3D,00FFFFFFh
jmp bp_render_done
bp_render_finished:
mov eax,bwScores3D[esi*8]
mov ebx,OFFSET bpDrawText
cmp eax,bwScores3D[esi*8+4]
je @F
mov ebx,OFFSET bpWinText
ja @F
mov ebx,OFFSET bpLoseText
@@:
invoke DrawBoxBorder,72,150,176,58,00121B20h,005BC9BEh,1
invoke DrawString8x8,88,161,ebx,00E8D7ADh
invoke DrawString8x8,136,187,OFFSET bpAgainText,00FFFFFFh
bp_render_done:
call DrawBowlingWeight3D
cmp bpScoreOpen3D,0
je @F
call DrawBowlingPlayScores3D
@@:
ret
RenderBowlingPlay3D ENDP