; A single rigid sprite transform aligns the dart axis with the live target. DrawDartsArm3D PROC uses ebx esi edi pose:DWORD,targetX:SDWORD,targetY:SDWORD local originX:DWORD,originY:DWORD,left:DWORD,right:DWORD,bottom:DWORD,row:DWORD,column:DWORD local deltaX:DWORD,deltaY:DWORD,sourceX:DWORD,framePtr:DWORD mov eax,pose shl eax,18 add eax,dtHands3D.pixels mov framePtr,eax mov eax,targetX sub eax,10 mov originX,eax mov left,eax add eax,363 mov right,eax mov eax,targetY add eax,49 mov originY,eax add eax,182 cmp eax,400 jle @F mov eax,400 @@: mov bottom,eax mov eax,originY sub eax,182 cmp eax,32 jge @F mov eax,32 @@: mov row,eax cmp left,0 jge @F mov left,0 @@: cmp right,640 jle dt_arm_row mov right,640 dt_arm_row: mov eax,row cmp eax,bottom jge dt_arm_done sub eax,originY mov deltaY,eax mov eax,left mov column,eax dt_arm_column: mov eax,column cmp eax,right jge dt_arm_next_row sub eax,originX mov deltaX,eax sub eax,deltaY imul eax,46341 sar eax,16 cmp eax,256 jae dt_arm_skip mov sourceX,eax mov eax,deltaX add eax,deltaY imul eax,46341 sar eax,16 cmp eax,256 jae dt_arm_skip shl eax,8 add eax,sourceX mov esi,framePtr mov eax,[esi+eax*4] test eax,80000000h jz dt_arm_skip and eax,00FFFFFFh mov edx,row imul edx,640 add edx,column mov screenBuffer[edx*4],eax dt_arm_skip: inc column jmp dt_arm_column dt_arm_next_row: inc row jmp dt_arm_row dt_arm_done: ret DrawDartsArm3D ENDP ; Furniture is attached to fixed world planes, never camera-facing billboards. DrawDartsProps3D PROC uses ebx esi edi local item:DWORD,column:DWORD,depth:DWORD,sourceU:DWORD,packPtr:DWORD local firstY:DWORD,lastY:DWORD,row:DWORD,sourceY:DWORD,stepY:DWORD,span:DWORD mov item,0 dt_prop_item: imul eax,item,28 lea esi,dtProps3D[eax] mov eax,[esi+24] mov packPtr,eax mov column,0 dt_prop_column: mov ebx,column cmp dword ptr [esi],0 jne dt_prop_side mov ecx,dtRayZ3D[ebx*4] mov eax,[esi+4] sub eax,dtCamZ3D jmp dt_prop_distance dt_prop_side: mov ecx,dtRayX3D[ebx*4] mov eax,[esi+4] sub eax,dtCamX3D dt_prop_distance: test ecx,ecx jz dt_prop_next_column shl eax,16 cdq idiv ecx cmp eax,40 jl dt_prop_next_column cmp eax,dtRayDepth3D[ebx*4] jge dt_prop_next_column mov depth,eax mov eax,dtRayX3D[ebx*4] mov edi,dtCamX3D cmp dword ptr [esi],0 je @F mov eax,dtRayZ3D[ebx*4] mov edi,dtCamZ3D @@: imul depth shrd eax,edx,16 add eax,edi sub eax,[esi+8] js dt_prop_next_column mov ecx,[esi+12] sub ecx,[esi+8] cmp eax,ecx jge dt_prop_next_column mov edi,packPtr imul eax,[edi].AnimPack3D.imageWidth cdq idiv ecx mov sourceU,eax mov eax,[esi+20] sub eax,dtCamY3D imul eax,dtLens3D cdq idiv depth mov ecx,dtScreenY3D sub ecx,eax mov firstY,ecx mov eax,[esi+16] sub eax,dtCamY3D imul eax,dtLens3D cdq idiv depth mov ecx,dtScreenY3D sub ecx,eax mov lastY,ecx sub ecx,firstY jle dt_prop_next_column mov span,ecx mov eax,[edi].AnimPack3D.height shl eax,16 xor edx,edx div span mov stepY,eax mov eax,firstY cmp eax,32 jge @F mov eax,32 @@: mov row,eax sub eax,firstY imul eax,stepY mov sourceY,eax cmp lastY,400 jle dt_prop_row mov lastY,400 dt_prop_row: mov eax,row cmp eax,lastY jge dt_prop_next_column mov eax,sourceY shr eax,16 cmp eax,[edi].AnimPack3D.height jae dt_prop_next_column imul eax,[edi].AnimPack3D.imageWidth add eax,sourceU mov edx,[edi].AnimPack3D.pixels mov eax,[edx+eax*4] test eax,80000000h jz @F mov edx,row imul edx,640 add edx,column and eax,00FFFFFFh mov screenBuffer[edx*4],eax @@: mov eax,stepY add sourceY,eax inc row jmp dt_prop_row dt_prop_next_column: inc column cmp column,640 jb dt_prop_column inc item cmp item,4 jb dt_prop_item ret DrawDartsProps3D ENDP ; Write chalk glyphs directly into the wall texture, so the score follows perspective. DartsWallText3D PROC uses ebx esi edi px:DWORD,py:DWORD,textPtr:DWORD local row:DWORD,column:DWORD,pen:DWORD,glyph:DWORD mov esi,textPtr mov eax,px mov pen,eax dt_chalk_char: movzx eax,byte ptr [esi] test eax,eax jz dt_chalk_done lea eax,font8x8[eax*8] mov glyph,eax mov row,0 dt_chalk_row: mov eax,glyph mov edx,row movzx ebx,byte ptr [eax+edx] mov column,0 dt_chalk_pixel: test ebx,80h jz @F mov eax,row add eax,py shl eax,9 add eax,pen add eax,column mov edi,dtWall3D.pixels mov dword ptr [edi+eax*4],0FFD8D9C2h @@: shl ebx,1 inc column cmp column,8 jb dt_chalk_pixel inc row cmp row,8 jb dt_chalk_row add pen,8 inc esi jmp dt_chalk_char dt_chalk_done: ret DartsWallText3D ENDP UpdateDartsWall3D PROC uses ebx esi edi cmp dtWallDirty3D,0 je dt_wall_score_done cmp dtWall3D.pixels,0 je dt_wall_score_done mov ebx,104 dt_chalk_clear: mov eax,ebx shl eax,9 add eax,32 mov edi,dtWall3D.pixels lea edi,[edi+eax*4] mov ecx,102 mov eax,0FF202623h rep stosd inc ebx cmp ebx,282 jb dt_chalk_clear invoke DartsWallText3D,40,108,OFFSET dtYou invoke DartsWallText3D,86,108,OFFSET dtBot invoke FormatNumber,dtScores3D,OFFSET hudNumBuffer invoke DartsWallText3D,40,126,OFFSET hudNumBuffer invoke FormatNumber,dtScores3D[4],OFFSET hudNumBuffer invoke DartsWallText3D,86,126,OFFSET hudNumBuffer mov ebx,dtHistoryRows3D sub ebx,7 jns @F xor ebx,ebx @@: mov esi,150 dt_chalk_history: cmp ebx,dtHistoryRows3D jae dt_chalk_clean invoke FormatNumber,dtHistory3D[ebx*8],OFFSET hudNumBuffer invoke DartsWallText3D,40,esi,OFFSET hudNumBuffer invoke FormatNumber,dtHistory3D[ebx*8+4],OFFSET hudNumBuffer invoke DartsWallText3D,86,esi,OFFSET hudNumBuffer add esi,17 inc ebx jmp dt_chalk_history dt_chalk_clean: mov dtWallDirty3D,0 dt_wall_score_done: ret UpdateDartsWall3D ENDP DrawDartsScoreboard3D PROC uses ebx esi edi invoke DrawBoxBorder,54,23,212,174,001A2420h,00B0A16Eh,2 invoke DrawString8x8,70,32,OFFSET dtScoreTitle,00E9DEBAh invoke DrawString8x8,118,49,OFFSET dtYou,0090CDB9h invoke DrawString8x8,198,49,OFFSET dtBot,00E8D7ADh mov ebx,dtHistoryRows3D sub ebx,10 jns @F xor ebx,ebx @@: mov esi,65 dt_scoreboard_row: cmp ebx,dtHistoryRows3D jae dt_scoreboard_current lea eax,[ebx+1] invoke FormatNumber,eax,OFFSET hudNumBuffer invoke DrawString8x8,70,esi,OFFSET hudNumBuffer,008A9C91h invoke FormatNumber,dtHistory3D[ebx*8],OFFSET hudNumBuffer invoke DrawString8x8,118,esi,OFFSET hudNumBuffer,00E2E2CFh invoke FormatNumber,dtHistory3D[ebx*8+4],OFFSET hudNumBuffer invoke DrawString8x8,198,esi,OFFSET hudNumBuffer,00E2E2CFh add esi,10 inc ebx jmp dt_scoreboard_row dt_scoreboard_current: invoke DrawBox,66,170,188,1,00758772h invoke FormatNumber,dtScores3D,OFFSET hudNumBuffer invoke DrawString8x8,118,180,OFFSET hudNumBuffer,00FFFFFFh invoke FormatNumber,dtScores3D[4],OFFSET hudNumBuffer invoke DrawString8x8,198,180,OFFSET hudNumBuffer,00FFFFFFh ret DrawDartsScoreboard3D ENDP