- Darts: native 500-point match against Max with sway/fatigue mouse aim, parabolic throw camera, raster arm animations, and 16 camera-relative flying dart views - AI Observer: autonomous spectator mode for Hold'em, Blackjack, Durak, and Billiards with profile isolation and playback controls - Fortune Session: raster sprite packs, mist/orb animations, tarot divination spreads, and pack tools - Hall Integration: wall dartboard in lounge, observer terminal dispatch, and bot turn hooks - Packaging & Verification: updated installer streaming hash, synchronized launcher, passing check suites and release smoke checks
657 lines
13 KiB
PHP
657 lines
13 KiB
PHP
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
|
|
mov eax,bx0
|
|
sub eax,7
|
|
mov edx,by0
|
|
sub edx,2
|
|
invoke DrawBuckshotPanel3D,eax,edx,15,5,00101112h
|
|
mov eax,by0
|
|
sub eax,7
|
|
mov edx,bx0
|
|
sub edx,2
|
|
invoke DrawBuckshotPanel3D,edx,eax,5,15,00101112h
|
|
mov eax,bx0
|
|
sub eax,6
|
|
invoke DrawBuckshotPanel3D,eax,by0,13,2,00F6E6ADh
|
|
mov eax,by0
|
|
sub eax,6
|
|
invoke DrawBuckshotPanel3D,bx0,eax,2,13,00F6E6ADh
|
|
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
|