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

388 lines
8.8 KiB
PHP

BowlingApplyBallMass3D PROC uses esi
mov esi,bpLane3D
mov eax,bpWeightKg3D
cmp bwTurn3D[esi*4],0
je @F
mov eax,bpBotWeightKg3D
@@:
cmp eax,4
jae @F
mov eax,4
@@:
cmp eax,7
jbe @F
mov eax,7
@@:
mov bpShotWeightKg3D,eax
imul eax,1000
mov bpBallGrams3D,eax
mov ecx,eax
mov eax,BP_PIN_GRAMS*FP_1
xor edx,edx
div ecx
mov bpInvMass3D[BP_BALL_BODY*4],eax
ret
BowlingApplyBallMass3D ENDP
; Selection consumes its own event, never the direction-lock/throw event.
HandleBowlingWeight3D PROC uses ebx esi mousePress:DWORD
xor esi,esi
bp_weight_key:
lea eax,[esi+31h]
invoke Pressed3D,eax
test eax,eax
jnz bp_weight_choose
inc esi
cmp esi,4
jb bp_weight_key
cmp mousePress,0
je bp_weight_no
cmp bpState3D,BP_SELECT_BALL
je bp_weight_rack_hit
cmp mouseY3D,26
jb bp_weight_no
cmp mouseY3D,44
jae bp_weight_no
cmp mouseX3D,8
jb bp_weight_no
cmp mouseX3D,96
jae bp_weight_no
mov bpState3D,BP_SELECT_BALL
mov eax,1
ret
bp_weight_rack_hit:
call BowlingRackCamera3D
call UpdateCamera3D
xor esi,esi
bp_weight_hit:
invoke BowlingRackScreen3D,esi
mov eax,mouseX3D
sub eax,bpRackHitX3D[esi*4]
imul eax,eax
mov ebx,eax
mov eax,mouseY3D
sub eax,bpRackHitY3D[esi*4]
imul eax,eax
add ebx,eax
mov eax,bpRackHitRadius3D[esi*4]
add eax,2
imul eax,eax
cmp ebx,eax
jbe bp_weight_choose
mov eax,bpRackHitX3D[esi*4]
sub eax,18
cmp mouseX3D,eax
jb bp_weight_hit_next
add eax,36
cmp mouseX3D,eax
jae bp_weight_hit_next
mov eax,bpRackHitY3D[esi*4]
add eax,bpRackHitRadius3D[esi*4]
add eax,2
cmp mouseY3D,eax
jb bp_weight_hit_next
add eax,14
cmp mouseY3D,eax
jb bp_weight_choose
bp_weight_hit_next:
inc esi
cmp esi,4
jb bp_weight_hit
; Ignore clicks on the floor instead of accidentally locking the direction.
cmp mouseY3D,193
jb bp_weight_rack_consumed
cmp mouseY3D,213
jae bp_weight_rack_consumed
cmp mouseX3D,128
jb bp_weight_rack_consumed
cmp mouseX3D,192
jae bp_weight_rack_consumed
mov bpState3D,BP_DIRECTION
bp_weight_rack_consumed:
mov eax,1
ret
bp_weight_no:
xor eax,eax
ret
bp_weight_choose:
lea eax,[esi+4]
mov bpWeightKg3D,eax
mov bpState3D,BP_DIRECTION
mov eax,1
ret
HandleBowlingWeight3D ENDP
DrawBowlingWeight3D PROC uses ebx esi edi
local x:DWORD,y:DWORD,edge:DWORD
cmp bpScoreOpen3D,0
jne bp_weight_draw_done
cmp bpState3D,BP_SELECT_BALL
jne bp_weight_locked_label
invoke DrawString8x8,120,32,OFFSET bpSelectBallText,00E8D7ADh
xor esi,esi
bp_weight_rack_label:
invoke BowlingRackScreen3D,esi
mov eax,bpRackHitX3D[esi*4]
sub eax,18
mov x,eax
mov eax,bpRackHitY3D[esi*4]
add eax,bpRackHitRadius3D[esi*4]
add eax,2
mov y,eax
mov edge,003C4D53h
lea eax,[esi+4]
cmp eax,bpWeightKg3D
jne @F
mov eax,bpBallColors3D[esi*4]
mov edge,eax
@@:
invoke DrawBoxBorder,x,y,36,14,00121B20h,edge,1
mov eax,x
add eax,2
mov ebx,y
add ebx,3
invoke DrawString8x8,eax,ebx,bpWeightLabels3D[esi*4],00FFFFFFh
inc esi
cmp esi,4
jb bp_weight_rack_label
invoke DrawBoxBorder,128,193,64,20,00121B20h,005BC9BEh,1
invoke DrawString8x8,136,199,OFFSET bpTakeBallText,00FFFFFFh
ret
bp_weight_locked_label:
mov eax,bpShotWeightKg3D
cmp bpState3D,BP_DIRECTION
je bp_weight_selected_label
cmp bpState3D,BP_POWER
jne @F
bp_weight_selected_label:
mov eax,bpWeightKg3D
@@:
cmp bpState3D,BP_BOT
jne @F
mov eax,bpBotWeightKg3D
@@:
mov esi,eax
invoke FormatNumber,eax,OFFSET bpText3D
invoke AppendCString,OFFSET bpText3D,OFFSET bpKilogramsText
sub esi,4
cmp esi,3
ja bp_weight_draw_done
mov eax,bpBallColors3D[esi*4]
mov edge,eax
cmp bpState3D,BP_DIRECTION
jne bp_weight_static_label
invoke DrawBoxBorder,8,26,88,18,00121B20h,edge,1
invoke DrawString8x8,14,31,OFFSET bpChangeBallText,00E8D7ADh
invoke DrawString8x8,50,31,OFFSET bpText3D,00FFFFFFh
ret
bp_weight_static_label:
invoke DrawBox,8,27,5,7,edge
invoke DrawString8x8,18,26,OFFSET bpText3D,00E8D7ADh
bp_weight_draw_done:
ret
DrawBowlingWeight3D ENDP
BowlingBallMaterial3D PROC kg:DWORD
mov eax,kg
sub eax,4
cmp eax,3
jbe @F
mov eax,2
@@:
mov eax,bpBallMaterials3D[eax*4]
ret
BowlingBallMaterial3D ENDP
BowlingRackCamera3D PROC
mov eax,bpLane3D
shr eax,1
imul eax,FP_1*38/10
add eax,FP_1*585/100
mov playerX,eax
mov playerY,FP_1*2583/100
mov playerAngle,256
mov viewEye3D,FP_1*102/100
ret
BowlingRackCamera3D ENDP
; Labels and picking share the actual world projection, not guessed UI slots.
BowlingRackScreen3D PROC uses ebx esi index:DWORD
mov esi,index
imul ebx,esi,-FP_1*245/1000
add ebx,FP_1*262/10
mov eax,playerX
sub eax,FP_1*135/100
invoke ProjectCityPoint3D,eax,ebx
sar eax,1
mov bpRackHitX3D[esi*4],eax
mov ebx,edx
mov eax,viewEye3D
sub eax,FP_1*84/100
imul eax,SCREEN_H
cdq
idiv ebx
add eax,viewHorizon3D
sar eax,1
mov bpRackHitY3D[esi*4],eax
mov eax,FP_1*12/100*SCREEN_H
cdq
idiv ebx
shr eax,1
mov bpRackHitRadius3D[esi*4],eax
ret
BowlingRackScreen3D ENDP
RenderBowlingBallRack3D PROC uses ebx esi edi centre:DWORD,pairIndex:DWORD
local lo:DWORD,hi:DWORD,x:DWORD,y:DWORD
; Storage runs lengthwise, alongside (not across) the clear return track.
mov eax,centre
add eax,FP_1*43/100
mov lo,eax
add eax,FP_1*4/100
mov hi,eax
invoke DrawRoofSolid3D,lo,hi,FP_1*253/10,FP_1*264/10,FP_1*70/100,FP_1*75/100,238
add lo,FP_1*20/100
add hi,FP_1*20/100
invoke DrawRoofSolid3D,lo,hi,FP_1*253/10,FP_1*264/10,FP_1*70/100,FP_1*75/100,238
mov eax,centre
add eax,FP_1*35/100
mov lo,eax
add eax,FP_1*40/100
mov hi,eax
invoke DrawRoofSolid3D,lo,hi,FP_1*253/10,FP_1*2538/100,FP_1*6/100,FP_1*73/100,254
invoke DrawRoofSolid3D,lo,hi,FP_1*2632/100,FP_1*264/10,FP_1*6/100,FP_1*73/100,254
xor esi,esi
bp_rack_stock:
cmp bpActive3D,0
je bp_rack_stock_draw
mov eax,bpLane3D
shr eax,1
cmp eax,pairIndex
jne bp_rack_stock_draw
cmp bpState3D,BP_SELECT_BALL
je bp_rack_stock_draw
mov eax,bpWeightKg3D
cmp bpState3D,BP_DIRECTION
je @F
cmp bpState3D,BP_POWER
je @F
mov eax,bpShotWeightKg3D
@@:
sub eax,4
cmp eax,esi
je bp_rack_stock_next
bp_rack_stock_draw:
mov eax,centre
add eax,FP_1*55/100
mov x,eax
imul eax,esi,-FP_1*245/1000
add eax,FP_1*262/10
mov y,eax
invoke DrawBowlingBallAt3D,x,y,FP_1*84/100,bpBallMaterials3D[esi*4],45
bp_rack_stock_next:
inc esi
cmp esi,4
jb bp_rack_stock
ret
RenderBowlingBallRack3D ENDP
; Reuse the blue marble's luminance; only its hue changes. Preserve alpha.
BowlingTintBallPixel3D PROC uses ebx ecx pixel:DWORD,kg:DWORD
mov eax,pixel
cmp kg,6
je bp_tint_done
mov ebx,eax
and ebx,255
mov ecx,eax
shr ecx,16
and ecx,255
and eax,0FF00FF00h
cmp kg,4
jne @F
mov edx,pixel
shr edx,8
and edx,255
shl ebx,8
and eax,0FFFF00FFh
or eax,ebx
or eax,edx
shl ecx,16
or eax,ecx
ret
@@:
or eax,ecx
cmp kg,5
jne bp_tint_gold
mov edx,eax
and edx,0000FF00h
shr edx,1
and edx,0000FF00h
and eax,0FFFF00FFh
or eax,edx
bp_tint_gold:
cmp kg,7
jne @F
mov edx,pixel
shr edx,8
and edx,255
add edx,ebx
shr edx,1
shl edx,8
and eax,0FFFF00FFh
or eax,edx
@@:
shl ebx,16
or eax,ebx
bp_tint_done:
ret
BowlingTintBallPixel3D ENDP
; A cached single-frame scratch pack keeps skin, sleeve and source assets intact.
BowlingTintHand3D PROC uses ebx esi edi frame:DWORD,kg:DWORD
mov eax,frame
cmp eax,bpRackHandFrame3D
jne bp_tint_hand_build
mov eax,kg
cmp eax,bpRackHandKg3D
je bp_tint_hand_done
bp_tint_hand_build:
mov eax,frame
mov bpRackHandFrame3D,eax
shl eax,18
add eax,bpHandArt3D.pixels
mov esi,eax
mov eax,kg
mov bpRackHandKg3D,eax
lea edi,bpTintedHandPixels3D
mov ebx,256*256
bp_tint_hand_pixel:
lodsd
cmp kg,6
je bp_tint_hand_store
mov edx,eax
and edx,255
mov ecx,eax
shr ecx,8
and ecx,255
add ecx,24
cmp edx,ecx
jbe bp_tint_hand_store
mov ecx,eax
shr ecx,16
and ecx,255
add ecx,24
cmp edx,ecx
jbe bp_tint_hand_store
invoke BowlingTintBallPixel3D,eax,kg
bp_tint_hand_store:
stosd
dec ebx
jnz bp_tint_hand_pixel
mov bpTintedHand3D.imageWidth,256
mov bpTintedHand3D.height,256
mov bpTintedHand3D.frames,1
mov bpTintedHand3D.bytes,256*256*4
mov bpTintedHand3D.pixels,OFFSET bpTintedHandPixels3D
bp_tint_hand_done:
ret
BowlingTintHand3D ENDP