include src_graphics\darts_environment.inc ; One-pixel, alpha-blended trajectory, clipped to the 3D playfield. DrawDartsLine3D PROC uses ebx esi edi x0:SDWORD,y0:SDWORD,x1:SDWORD,y1:SDWORD,opacity:DWORD local stepX:DWORD,stepY:DWORD,steps:DWORD,px:DWORD,py:DWORD,paint: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 @@: cmp ebx,2048 ja dt_line_done test ebx,ebx jnz @F inc ebx @@: mov steps,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 steps dt_line_pixel: mov eax,px sar eax,16 cmp eax,640 jae dt_line_skip mov edx,py sar edx,16 cmp edx,32 jl dt_line_skip cmp edx,400 jge dt_line_skip imul edx,640 add edx,eax lea edi,screenBuffer[edx*4] mov esi,[edi] movzx eax,byte ptr [edi] mov ecx,219 sub ecx,eax imul ecx,opacity sar ecx,8 add eax,ecx mov paint,eax mov eax,esi shr eax,8 and eax,255 mov ecx,210 sub ecx,eax imul ecx,opacity sar ecx,8 add eax,ecx shl eax,8 or paint,eax mov eax,esi shr eax,16 and eax,255 mov ecx,180 sub ecx,eax imul ecx,opacity sar ecx,8 add eax,ecx shl eax,16 or eax,paint mov [edi],eax dt_line_skip: mov eax,stepX add px,eax mov eax,stepY add py,eax dec steps jnz dt_line_pixel dt_line_done: ret DrawDartsLine3D ENDP DrawDartsTrail3D PROC uses ebx esi edi local timeMs:DWORD,lastX:DWORD,lastY:DWORD,valid:DWORD,fade:DWORD,alpha:DWORD mov eax,dtTimer3D mov fade,256 cmp dtState3D,DT_FLIGHT je dt_trail_start cmp dtState3D,DT_IMPACT jne dt_trail_done cmp eax,300 jae dt_trail_done imul eax,256 xor edx,edx mov ecx,300 div ecx mov ecx,256 sub ecx,eax mov fade,ecx mov eax,DT_THROW_MS dt_trail_start: mov timeMs,eax mov valid,0 mov ebx,12 dt_trail_segment: imul eax,ebx,20 mov ecx,timeMs sub ecx,eax js dt_trail_next invoke DartsPath3D,ecx invoke DartsProject3D,eax,edx,ecx cmp ecx,60 jl dt_trail_invalid mov esi,eax mov edi,edx cmp valid,0 je dt_trail_remember mov eax,13 sub eax,ebx imul eax,9 imul eax,fade shr eax,8 mov alpha,eax invoke DrawDartsLine3D,lastX,lastY,esi,edi,alpha dt_trail_remember: mov lastX,esi mov lastY,edi mov valid,1 jmp dt_trail_next dt_trail_invalid: mov valid,0 dt_trail_next: dec ebx jns dt_trail_segment dt_trail_done: ret DrawDartsTrail3D ENDP ; Independent scene camera. Hall player coordinates are never borrowed or modified. PrepareDartsRays3D PROC uses ebx esi edi local cameraRay:DWORD,wallType:DWORD,wallT:DWORD,sideT:DWORD xor ebx,ebx dt_ray_column: mov eax,ebx sub eax,320 shl eax,16 cdq idiv dtLens3D mov cameraRay,eax imul dtYawCos3D shrd eax,edx,16 add eax,dtYawSin3D mov dtRayX3D[ebx*4],eax mov eax,cameraRay imul dtYawSin3D shrd eax,edx,16 neg eax add eax,dtYawCos3D mov dtRayZ3D[ebx*4],eax mov wallT,7FFFFFFFh mov wallType,0 test eax,eax jz dt_ray_side mov ecx,eax mov eax,DT_WALL test ecx,ecx jns @F mov eax,-2000 mov wallType,2 @@: sub eax,dtCamZ3D shl eax,16 cdq idiv ecx test eax,eax jle dt_ray_side mov wallT,eax dt_ray_side: mov ecx,dtRayX3D[ebx*4] test ecx,ecx jz dt_ray_hit mov eax,2600 test ecx,ecx jns @F mov eax,-2600 @@: sub eax,dtCamX3D shl eax,16 cdq idiv ecx test eax,eax jle dt_ray_hit cmp eax,wallT jge dt_ray_hit mov wallT,eax mov wallType,1 dt_ray_hit: mov eax,wallT cmp eax,1 jge @F mov eax,1 @@: mov dtRayDepth3D[ebx*4],eax mov esi,eax mov eax,dtRayX3D[ebx*4] imul esi shrd eax,edx,16 add eax,dtCamX3D mov dtRayHitX3D[ebx*4],eax cmp wallType,1 jne @F mov eax,dtRayZ3D[ebx*4] imul esi shrd eax,edx,16 add eax,dtCamZ3D @@: imul eax,256 cdq mov ecx,500 idiv ecx and eax,255 mov dtRayU3D[ebx*4],eax mov eax,wallType mov dtRayFront3D[ebx*4],eax inc ebx cmp ebx,640 jb dt_ray_column ret PrepareDartsRays3D ENDP ; True inverse projection onto front/side/back walls, floor and ceiling. DrawDartsRoom3D PROC uses ebx esi edi local row:DWORD,rayY:DWORD,worldY:DWORD,depth:DWORD,sourceU:DWORD,sourceV:DWORD call PrepareDartsRays3D mov row,32 dt_room_row: mov eax,dtScreenY3D sub eax,row shl eax,16 cdq idiv dtLens3D mov rayY,eax mov eax,row imul eax,640*4 lea edi,screenBuffer[eax] xor ebx,ebx dt_room_pixel: mov eax,rayY imul dtRayDepth3D[ebx*4] shrd eax,edx,16 add eax,dtCamY3D mov worldY,eax cmp eax,-1730 jl dt_room_floor cmp eax,1300 jg dt_room_ceiling cmp dtRayFront3D[ebx*4],0 jne dt_room_wall mov eax,dtRayHitX3D[ebx*4] add eax,256 cmp eax,512 jae dt_room_wall mov sourceU,eax mov eax,256 sub eax,worldY cmp eax,512 jae dt_room_wall shl eax,9 add eax,sourceU mov esi,dtBoard3D.pixels mov eax,[esi+eax*4] test eax,80000000h jnz dt_room_store dt_room_wall: mov eax,570 sub eax,worldY imul eax,512 cdq mov ecx,1800 idiv ecx test eax,eax jns @F xor eax,eax @@: cmp eax,511 jbe @F mov eax,511 @@: shl eax,9 mov sourceV,eax mov eax,dtRayU3D[ebx*4] and eax,15 add eax,190 cmp dtRayFront3D[ebx*4],0 jne dt_room_wall_sample mov ecx,dtRayHitX3D[ebx*4] add ecx,850 cmp ecx,1700 jae dt_room_wall_sample imul eax,ecx,512 cdq mov ecx,1700 idiv ecx dt_room_wall_sample: add eax,sourceV mov esi,dtWall3D.pixels mov eax,[esi+eax*4] jmp dt_room_store dt_room_floor: mov eax,-1730 jmp dt_room_horizontal dt_room_ceiling: mov eax,1300 dt_room_horizontal: sub eax,dtCamY3D shl eax,16 cdq idiv rayY mov depth,eax mov eax,dtRayX3D[ebx*4] imul depth shrd eax,edx,16 add eax,dtCamX3D imul eax,256 cdq mov ecx,500 idiv ecx and eax,255 mov sourceU,eax mov eax,dtRayZ3D[ebx*4] imul depth shrd eax,edx,16 add eax,dtCamZ3D imul eax,256 cdq mov ecx,500 idiv ecx and eax,255 shl eax,8 add eax,sourceU mov esi,dtRoom3D.pixels add esi,5*256*256*4 mov eax,[esi+eax*4] cmp rayY,0 jle dt_room_store mov eax,00444943h dt_room_store: and eax,00FFFFFFh stosd inc ebx cmp ebx,640 jb dt_room_pixel inc row cmp row,400 jb dt_room_row ret DrawDartsRoom3D ENDP ; Camera-relative raster views retain the generated metal and flight detail. DrawDartsModel3D PROC uses ebx esi edi x:SDWORD,y:SDWORD,z:SDWORD local deltaX:DWORD,deltaZ:DWORD,angle:DWORD,pose:DWORD local centerX:DWORD,centerY:DWORD,depth:DWORD,span:DWORD,worldX:DWORD,worldY:DWORD mov eax,x sub eax,dtCamX3D mov deltaX,eax mov eax,z sub eax,dtCamZ3D mov deltaZ,eax fild deltaX fild deltaZ fpatan fabs fmul dtAngleFactor3D fistp angle imul eax,angle,60 add eax,32768 shr eax,16 cmp eax,15 jbe @F mov eax,15 @@: mov pose,eax mov eax,x sub eax,70 imul eax,64 cdq mov ecx,DT_WALL idiv ecx mov edx,x sub edx,eax mov worldX,edx mov eax,y sub eax,280 cmp z,DT_WALL-8 jae @F mov eax,dtTimer3D imul eax,560 xor edx,edx mov ecx,DT_THROW_MS div ecx mov edx,y add edx,280 sub edx,eax mov eax,edx @@: imul eax,64 cdq mov ecx,DT_WALL idiv ecx mov edx,y sub edx,eax mov worldY,edx mov eax,z sub eax,64 invoke DartsProject3D,worldX,worldY,eax cmp ecx,80 jl dt_model_done mov centerX,eax mov centerY,edx mov depth,ecx imul eax,dtLens3D,160 xor edx,edx div depth cmp eax,240 jbe @F mov eax,240 @@: cmp eax,12 jae @F mov eax,12 @@: mov span,eax invoke DartsProject3D,x,y,z mov centerX,eax mov centerY,edx mov ebx,pose mov eax,dtDartTipX3D[ebx*4] imul eax,span shr eax,8 sub centerX,eax mov eax,dtDartTipY3D[ebx*4] imul eax,span shr eax,8 sub centerY,eax invoke DrawAnimSprite3D,OFFSET dtDart3D,pose,centerX,centerY,span,span dt_model_done: ret DrawDartsModel3D ENDP RenderDarts3D PROC uses ebx esi edi local bx0:DWORD,by0:DWORD,boardSpan:DWORD,handX:DWORD,handY:DWORD,pose:DWORD cmp dtError3D,0 jne dt_render_error call DartsCamera3D call UpdateDartsWall3D call DrawDartsRoom3D call DrawDartsProps3D call DrawDartsTrail3D xor ebx,ebx dt_render_marks: cmp ebx,dtCount3D jae dt_render_flight invoke DrawDartsModel3D,dtMarkX3D[ebx*4],dtMarkY3D[ebx*4],DT_WALL-4 inc ebx jmp dt_render_marks dt_render_flight: cmp dtState3D,DT_FLIGHT jne dt_render_hand invoke DartsProject3D,dtShotX3D,dtShotY3D,dtShotZ3D cmp ecx,140 jl dt_render_hand invoke DrawDartsModel3D,dtShotX3D,dtShotY3D,dtShotZ3D dt_render_hand: mov pose,0 cmp dtState3D,DT_AIM je dt_render_aim_hand cmp dtState3D,DT_RELEASE je dt_render_release_hand cmp dtState3D,DT_FLIGHT jne dt_render_hud cmp dtTimer3D,250 jae dt_render_hud mov eax,dtTimer3D xor edx,edx mov ecx,50 div ecx add eax,12 cmp eax,15 jbe dt_render_pose mov eax,15 jmp dt_render_pose dt_render_release_hand: mov eax,dtTimer3D imul eax,3 xor edx,edx mov ecx,200 div ecx add eax,8 cmp eax,10 jne dt_render_pose mov eax,11 jmp dt_render_pose dt_render_aim_hand: mov eax,0 cmp dtHolding3D,0 je dt_render_pose mov eax,dtHoldTime3D imul eax,4 xor edx,edx mov ecx,280 div ecx cmp eax,3 jbe @F mov eax,3 @@: add eax,4 dt_render_pose: mov pose,eax invoke DartsProject3D,dtAimX3D,dtAimY3D,DT_WALL mov bx0,eax mov by0,edx add eax,16 mov handX,eax mov eax,edx sub eax,110 mov handY,eax invoke DrawDartsArm3D,pose,bx0,by0 cmp dtState3D,DT_AIM jne dt_render_hud invoke DrawDartsReticle3D,bx0,by0 dt_render_hud: invoke DrawBox,0,0,320,16,00151D20h invoke DrawString8x8,8,4,OFFSET dtTitle,00E8D7ADh invoke DrawString8x8,112,4,OFFSET dtYou,0090CDB9h invoke FormatNumber,dtScores3D,OFFSET hudNumBuffer invoke DrawString8x8,140,4,OFFSET hudNumBuffer,00FFFFFFh invoke DrawString8x8,204,4,OFFSET dtBot,00E8D7ADh invoke FormatNumber,dtScores3D[4],OFFSET hudNumBuffer invoke DrawString8x8,248,4,OFFSET hudNumBuffer,00FFFFFFh invoke DrawBox,0,200,320,40,00151D20h mov ebx,OFFSET dtYourTurn cmp dtActor3D,0 je @F mov ebx,OFFSET dtBotTurn @@: cmp dtState3D,DT_WIN jne dt_hud_actor mov ebx,OFFSET dtYouWin cmp dtWinner3D,0 je dt_hud_actor mov ebx,OFFSET dtBotWin dt_hud_actor: invoke DrawString8x8,8,206,ebx,00E8D7ADh xor ebx,ebx dt_render_scores: imul esi,ebx,52 add esi,8 invoke DrawBoxBorder,esi,220,46,16,00293436h,00728689h,1 cmp ebx,dtCount3D jae @F invoke FormatNumber,dtMarkScore3D[ebx*4],OFFSET hudNumBuffer add esi,7 invoke DrawString8x8,esi,224,OFFSET hudNumBuffer,00FFFFFFh @@: inc ebx cmp ebx,3 jb dt_render_scores invoke DrawBoxBorder,230,220,82,16,00293436h,00728689h,1 invoke DrawString8x8,248,224,OFFSET dtAgain,00FFFFFFh cmp dtState3D,DT_AIM jne @F invoke DartsScore3D,dtAimX3D,dtAimY3D mov esi,OFFSET dtSingle cmp edx,3 jne dt_preview_double mov esi,OFFSET dtTriple jmp dt_preview_sector dt_preview_double: cmp edx,2 jne dt_preview_sector mov esi,OFFSET dtDouble dt_preview_sector: test edx,edx jz dt_preview_value mov ecx,edx xor edx,edx div ecx dt_preview_value: mov edi,eax invoke DrawString8x8,176,206,OFFSET dtTarget,00AABDB6h invoke DrawString8x8,224,206,esi,00F6E6ADh invoke FormatNumber,edi,OFFSET hudNumBuffer invoke DrawString8x8,236,206,OFFSET hudNumBuffer,00FFFFFFh jmp dt_render_done @@: cmp dtState3D,DT_RELEASE je dt_render_done cmp dtState3D,DT_FLIGHT je dt_render_done cmp dtState3D,DT_RETURN je dt_render_done mov ebx,OFFSET dtWin cmp dtRemaining3D,0 je dt_render_done mov ebx,OFFSET dtBust cmp dtBust3D,0 jne dt_render_banner mov ebx,OFFSET dtMiss cmp dtLast3D,0 je dt_render_banner mov ebx,OFFSET dtThrow dt_render_banner: invoke DrawString8x8,192,206,ebx,00E8D7ADh dt_render_done: cmp dtScoreOpen3D,0 je @F call DrawDartsScoreboard3D @@: ret dt_render_error: invoke DrawBox,0,0,320,240,00151D20h invoke DrawString8x8,12,104,OFFSET dtLoading,00E8D7ADh ret RenderDarts3D ENDP