; 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 ret InitBowlingBallSurface3D ENDP DrawBowlingPlayPin3D PROC uses ebx esi edi pin:DWORD,centre:DWORD local x:DWORD,y:DWORD,z:DWORD,headY:DWORD,ry:DWORD,rz:DWORD mov esi,pin mov ecx,esi mov ebx,1 shl ebx,cl mov edi,bpLane3D test bwRack3D[edi*4],ebx jz bp_pin_done mov eax,bpPinX3D[esi*4] add eax,centre mov x,eax mov eax,bpPinY3D[esi*4] mov y,eax mov headY,eax mov z,FP_1*15/100 mov ry,FP_1/10 mov rz,FP_1*13/100 test bpHitMask3D,ebx jz bp_pin_draw mov z,FP_1*7/100 mov ry,FP_1*23/100 mov rz,FP_1*6/100 sub headY,FP_1/4 bp_pin_draw: invoke DrawRoofEllipsoid3D,x,y,z,FP_1/10,ry,rz,239 mov eax,FP_1*34/100 test bpHitMask3D,ebx jz @F mov eax,FP_1*7/100 @@: invoke DrawRoofEllipsoid3D,x,headY,eax,FP_1*65/1000,FP_1*65/1000,FP_1*6/100,239 mov eax,z add eax,rz invoke DrawRoofEllipsoid3D,x,headY,eax,FP_1*45/1000,FP_1*45/1000,FP_1*25/1000,240 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 DrawBowlingPlayScores3D PROC uses ebx esi edi local x:DWORD,y:DWORD,owner:DWORD invoke DrawBoxBorder,4,47,312,139,00151F26h,005BC9BEh,1 invoke DrawString8x8,12,55,OFFSET bpScoreText,00E8D7ADh xor esi,esi bp_score_heading: imul eax,esi,26 add eax,44 mov x,eax lea eax,[esi+1] invoke FormatNumber,eax,OFFSET bpText3D invoke DrawString8x8,x,73,OFFSET bpText3D,00AABDB6h inc esi cmp esi,10 jb bp_score_heading xor edi,edi bp_score_owner: lea eax,[edi*2] imul eax,18 add eax,96 mov y,eax mov eax,OFFSET bpYou test edi,edi jz @F mov eax,OFFSET bpBot @@: invoke DrawString8x8,9,y,eax,005BC9BEh mov eax,bpLane3D shl eax,1 add eax,edi mov owner,eax xor esi,esi bp_score_cell: imul eax,esi,26 add eax,44 mov x,eax invoke BowlingFrameTotal3D,owner,esi cmp eax,-1 je bp_score_empty invoke FormatNumber,eax,OFFSET bpText3D invoke DrawString8x8,x,y,OFFSET bpText3D,00FFFFFFh jmp bp_score_next bp_score_empty: invoke DrawBox,x,y,8,1,005C727Bh bp_score_next: inc esi cmp esi,10 jb bp_score_cell inc edi cmp edi,2 jb bp_score_owner ret DrawBowlingPlayScores3D ENDP 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 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 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_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 imul eax,ebx,FP_1*7/20 cdq idiv ecx mov edx,HALL_STANDING_EYE sub edx,eax mov viewEye3D,edx bp_camera_ready: call UpdateCamera3D call RenderBowling3D 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: cmp bpState3D,BP_FINISHED je bp_render_hud mov eax,bpBallX3D add eax,bpCentre3D invoke DrawBowlingBall3D,eax,bpBallY3D,253 bp_render_hud: 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 jne @F 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_POWER je bp_render_power cmp bpState3D,BP_SETTLE je bp_render_result cmp bpState3D,BP_FINISHED je bp_render_finished 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,246,62,OFFSET bpPowerText,00E8D7ADh invoke DrawBoxBorder,276,79,13,124,00121B20h,00AABDB6h,1 invoke DrawBox,278,82,9,118,00D67057h invoke DrawBox,278,128,9,38,00E7C455h invoke DrawBox,278,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,270,y,25,2,00FFFFFFh invoke FormatNumber,bpPower3D,OFFSET bpText3D invoke DrawString8x8,246,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: cmp bpScoreOpen3D,0 je @F call DrawBowlingPlayScores3D @@: ret RenderBowlingPlay3D ENDP