Implement 32x32 BFS visitor navigation and daily contracts system with companion .npc journals; add native assembly scenes for Clover slots, Pyramid cards, Blackjack Party and Russian Party; package animation and sprite packs; add comprehensive offline test suites and rebuild shipping binaries.
688 lines
14 KiB
PHP
688 lines
14 KiB
PHP
PyramidSelect3D PROC uses ebx ball:DWORD
|
|
cmp poolBreak3D,0
|
|
je @F
|
|
mov pyrCue3D,0
|
|
ret
|
|
@@:
|
|
mov ebx,ball
|
|
cmp ebx,15
|
|
ja pyr_select_default
|
|
cmp poolActive3D[ebx*4],1
|
|
jne pyr_select_default
|
|
mov pyrCue3D,ebx
|
|
mov poolCalled3D,ebx
|
|
ret
|
|
pyr_select_default:
|
|
mov ebx,pyrCue3D
|
|
cmp poolActive3D[ebx*4],1
|
|
je pyr_select_done
|
|
xor ebx,ebx
|
|
pyr_select_scan:
|
|
cmp poolActive3D[ebx*4],1
|
|
je pyr_select_found
|
|
inc ebx
|
|
cmp ebx,16
|
|
jb pyr_select_scan
|
|
ret
|
|
pyr_select_found:
|
|
mov pyrCue3D,ebx
|
|
mov poolCalled3D,ebx
|
|
pyr_select_done:
|
|
ret
|
|
PyramidSelect3D ENDP
|
|
|
|
PyramidPick3D PROC uses ebx esi px:DWORD,py:DWORD
|
|
xor esi,esi
|
|
pyr_pick_ball:
|
|
cmp poolActive3D[esi*4],1
|
|
jne pyr_pick_next
|
|
mov eax,px
|
|
sub eax,poolX3D[esi*4]
|
|
sar eax,12
|
|
imul eax,eax
|
|
mov ebx,eax
|
|
mov eax,py
|
|
sub eax,poolY3D[esi*4]
|
|
sar eax,12
|
|
imul eax,eax
|
|
add eax,ebx
|
|
cmp eax,36*16*16
|
|
ja pyr_pick_next
|
|
mov eax,esi
|
|
ret
|
|
pyr_pick_next:
|
|
inc esi
|
|
cmp esi,16
|
|
jb pyr_pick_ball
|
|
mov eax,-1
|
|
ret
|
|
PyramidPick3D ENDP
|
|
|
|
PyramidDirection3D PROC uses ebx esi
|
|
mov ecx,poolAngle3D
|
|
and ecx,511
|
|
cmp pyrFineActive3D,0
|
|
jne pyr_direction_fine
|
|
mov eax,tableCos[ecx*4]
|
|
mov pyrDirX3D,eax
|
|
mov eax,tableSin[ecx*4]
|
|
mov pyrDirY3D,eax
|
|
ret
|
|
pyr_direction_fine:
|
|
mov ecx,pyrFine3D
|
|
and ecx,4095
|
|
mov ebx,ecx
|
|
and ebx,7
|
|
shr ecx,3
|
|
lea esi,[ecx+1]
|
|
and esi,511
|
|
mov eax,tableCos[esi*4]
|
|
sub eax,tableCos[ecx*4]
|
|
imul eax,ebx
|
|
sar eax,3
|
|
add eax,tableCos[ecx*4]
|
|
mov pyrDirX3D,eax
|
|
mov eax,tableSin[esi*4]
|
|
sub eax,tableSin[ecx*4]
|
|
imul eax,ebx
|
|
sar eax,3
|
|
add eax,tableSin[ecx*4]
|
|
mov pyrDirY3D,eax
|
|
ret
|
|
PyramidDirection3D ENDP
|
|
|
|
PoolAimPoint3D PROC uses ebx px:DWORD,py:DWORD
|
|
local deltaX:DWORD,deltaY:DWORD,phase:DWORD
|
|
mov ebx,pyrCue3D
|
|
mov eax,px
|
|
sub eax,poolX3D[ebx*4]
|
|
mov deltaX,eax
|
|
mov ecx,py
|
|
sub ecx,poolY3D[ebx*4]
|
|
mov deltaY,ecx
|
|
or eax,ecx
|
|
jz pyr_aim_done
|
|
fild deltaY
|
|
fild deltaX
|
|
fpatan
|
|
fmul pyrAimFactor3D
|
|
fistp phase
|
|
mov eax,phase
|
|
and eax,4095
|
|
mov pyrFine3D,eax
|
|
mov pyrFineActive3D,1
|
|
call PyramidDirection3D
|
|
pyr_aim_done:
|
|
ret
|
|
PoolAimPoint3D ENDP
|
|
|
|
PoolShoot3D PROC uses ebx esi
|
|
cmp poolState3D,POOL_AIM
|
|
jne pyr_shoot_done
|
|
mov ebx,pyrCue3D
|
|
cmp ebx,15
|
|
ja pyr_shoot_done
|
|
cmp poolActive3D[ebx*4],1
|
|
jne pyr_shoot_done
|
|
cmp pyrTablePack3D.pixels,0
|
|
je pyr_shoot_done
|
|
cmp pyrBallsPack3D.pixels,0
|
|
je pyr_shoot_done
|
|
cmp poolBreak3D,0
|
|
je @F
|
|
test ebx,ebx
|
|
jnz pyr_shoot_done
|
|
cmp poolX3D,95*FP_1
|
|
jge pyr_shoot_done
|
|
@@:
|
|
mov poolFirst3D,-1
|
|
mov poolRail3D,0
|
|
mov poolBreakRails3D,0
|
|
mov poolPotted3D,0
|
|
mov poolFoul3D,0
|
|
mov pyrFoulReason3D,0
|
|
mov pyrValidEnd3D,0
|
|
mov pyrSettled3D,0
|
|
mov poolAccumulator3D,0
|
|
mov poolTime3D,0
|
|
mov poolState3D,POOL_STRIKE
|
|
xor esi,esi
|
|
pyr_shoot_history:
|
|
mov pyrHistoryRails3D[esi*4],0
|
|
mov pyrHistoryCross3D[esi*4],0
|
|
mov pyrRailHalf3D[esi*4],0
|
|
inc esi
|
|
cmp esi,16
|
|
jb pyr_shoot_history
|
|
call PyramidDirection3D
|
|
pyr_shoot_done:
|
|
ret
|
|
PoolShoot3D ENDP
|
|
|
|
; Obstruction checks use Q4 geometry with a 64-bit projection numerator.
|
|
PyramidPathClear3D PROC uses ebx esi edi sx:DWORD,sy:DWORD,ex:DWORD,ey:DWORD,skipA:DWORD,skipB:DWORD
|
|
local deltaX:DWORD,deltaY:DWORD,length2:DWORD,projection:DWORD,wx:DWORD,wy:DWORD
|
|
mov eax,ex
|
|
sub eax,sx
|
|
sar eax,12
|
|
mov deltaX,eax
|
|
imul eax,eax
|
|
mov ebx,eax
|
|
mov eax,ey
|
|
sub eax,sy
|
|
sar eax,12
|
|
mov deltaY,eax
|
|
imul eax,eax
|
|
add eax,ebx
|
|
mov length2,eax
|
|
test eax,eax
|
|
jz pyr_path_bad
|
|
xor esi,esi
|
|
pyr_path_ball:
|
|
cmp esi,skipA
|
|
je pyr_path_next
|
|
cmp esi,skipB
|
|
je pyr_path_next
|
|
cmp poolActive3D[esi*4],1
|
|
jne pyr_path_next
|
|
mov eax,poolX3D[esi*4]
|
|
sub eax,sx
|
|
sar eax,12
|
|
mov wx,eax
|
|
imul eax,deltaX
|
|
mov ebx,eax
|
|
mov eax,poolY3D[esi*4]
|
|
sub eax,sy
|
|
sar eax,12
|
|
mov wy,eax
|
|
imul eax,deltaY
|
|
add eax,ebx
|
|
test eax,eax
|
|
jle pyr_path_next
|
|
cmp eax,length2
|
|
jge pyr_path_next
|
|
mov ecx,FP_1
|
|
imul ecx
|
|
idiv length2
|
|
mov projection,eax
|
|
imul deltaX
|
|
shrd eax,edx,16
|
|
sub eax,wx
|
|
imul eax,eax
|
|
mov ebx,eax
|
|
mov eax,projection
|
|
imul deltaY
|
|
shrd eax,edx,16
|
|
sub eax,wy
|
|
imul eax,eax
|
|
add eax,ebx
|
|
cmp eax,25*16*16
|
|
jb pyr_path_bad
|
|
pyr_path_next:
|
|
inc esi
|
|
cmp esi,16
|
|
jb pyr_path_ball
|
|
mov eax,1
|
|
ret
|
|
pyr_path_bad:
|
|
xor eax,eax
|
|
ret
|
|
PyramidPathClear3D ENDP
|
|
|
|
; Search every cue/target/pocket triple; no hidden outcomes or teleported pots.
|
|
PoolChooseAI3D PROC uses ebx esi edi
|
|
local cue:DWORD,target:DWORD,pocket:DWORD,deltaX:DWORD,deltaY:DWORD,distance:DWORD
|
|
local gx:DWORD,gy:DWORD,best:DWORD,bestCue:DWORD,bestX:DWORD,bestY:DWORD,bestPower:DWORD
|
|
local shotLength:DWORD
|
|
cmp poolBreak3D,0
|
|
je pyr_ai_search
|
|
mov pyrCue3D,0
|
|
mov poolAngle3D,0
|
|
mov pyrFineActive3D,0
|
|
mov poolPower3D,85000
|
|
ret
|
|
pyr_ai_search:
|
|
mov best,7FFFFFFFh
|
|
mov bestCue,-1
|
|
mov cue,0
|
|
pyr_ai_cue:
|
|
mov ecx,cue
|
|
cmp poolActive3D[ecx*4],1
|
|
jne pyr_ai_next_cue
|
|
mov target,0
|
|
pyr_ai_target:
|
|
mov esi,target
|
|
cmp esi,cue
|
|
je pyr_ai_next_target
|
|
cmp poolActive3D[esi*4],1
|
|
jne pyr_ai_next_target
|
|
mov pocket,0
|
|
pyr_ai_pocket:
|
|
mov edi,pocket
|
|
mov eax,poolPocketX3D[edi*4]
|
|
sub eax,poolX3D[esi*4]
|
|
mov deltaX,eax
|
|
mov eax,poolPocketY3D[edi*4]
|
|
sub eax,poolY3D[esi*4]
|
|
mov deltaY,eax
|
|
invoke PyramidDistance3D,deltaX,deltaY
|
|
test eax,eax
|
|
jz pyr_ai_next_pocket
|
|
mov distance,eax
|
|
mov eax,deltaX
|
|
mov ecx,POOL_DIAMETER
|
|
imul ecx
|
|
idiv distance
|
|
mov ebx,poolX3D[esi*4]
|
|
sub ebx,eax
|
|
mov gx,ebx
|
|
mov eax,deltaY
|
|
mov ecx,POOL_DIAMETER
|
|
imul ecx
|
|
idiv distance
|
|
mov ebx,poolY3D[esi*4]
|
|
sub ebx,eax
|
|
mov gy,ebx
|
|
cmp gx,30*FP_1+POOL_RADIUS
|
|
jl pyr_ai_next_pocket
|
|
cmp gx,290*FP_1-POOL_RADIUS
|
|
jg pyr_ai_next_pocket
|
|
cmp gy,50*FP_1+POOL_RADIUS
|
|
jl pyr_ai_next_pocket
|
|
cmp gy,180*FP_1-POOL_RADIUS
|
|
jg pyr_ai_next_pocket
|
|
mov ecx,cue
|
|
mov eax,gx
|
|
sub eax,poolX3D[ecx*4]
|
|
sar eax,12
|
|
mov ebx,deltaX
|
|
sar ebx,12
|
|
imul eax,ebx
|
|
mov ebx,eax
|
|
mov eax,gy
|
|
sub eax,poolY3D[ecx*4]
|
|
sar eax,12
|
|
mov edx,deltaY
|
|
sar edx,12
|
|
imul eax,edx
|
|
add eax,ebx
|
|
test eax,eax
|
|
jle pyr_ai_next_pocket
|
|
invoke PyramidPathClear3D,poolX3D[ecx*4],poolY3D[ecx*4],gx,gy,cue,target
|
|
test eax,eax
|
|
jz pyr_ai_next_pocket
|
|
mov edi,pocket
|
|
invoke PyramidPathClear3D,poolX3D[esi*4],poolY3D[esi*4],poolPocketX3D[edi*4],poolPocketY3D[edi*4],cue,target
|
|
test eax,eax
|
|
jz pyr_ai_next_pocket
|
|
mov ecx,cue
|
|
mov eax,gx
|
|
sub eax,poolX3D[ecx*4]
|
|
mov ebx,gy
|
|
sub ebx,poolY3D[ecx*4]
|
|
invoke PyramidDistance3D,eax,ebx
|
|
mov shotLength,eax
|
|
add eax,distance
|
|
cmp eax,best
|
|
jae pyr_ai_next_pocket
|
|
mov best,eax
|
|
mov ecx,cue
|
|
mov bestCue,ecx
|
|
mov ecx,gx
|
|
mov bestX,ecx
|
|
mov ecx,gy
|
|
mov bestY,ecx
|
|
; v^2/(2*rolling loss) estimates the travel budget, with margin for a cut.
|
|
sar eax,16
|
|
imul eax,220
|
|
add eax,22000
|
|
cmp eax,85000
|
|
jbe @F
|
|
mov eax,85000
|
|
@@:
|
|
mov bestPower,eax
|
|
pyr_ai_next_pocket:
|
|
inc pocket
|
|
cmp pocket,6
|
|
jb pyr_ai_pocket
|
|
pyr_ai_next_target:
|
|
inc target
|
|
cmp target,16
|
|
jb pyr_ai_target
|
|
pyr_ai_next_cue:
|
|
inc cue
|
|
cmp cue,16
|
|
jb pyr_ai_cue
|
|
cmp bestCue,-1
|
|
je pyr_ai_safety
|
|
mov eax,bestCue
|
|
mov pyrCue3D,eax
|
|
invoke PoolAimPoint3D,bestX,bestY
|
|
mov eax,bestPower
|
|
mov poolPower3D,eax
|
|
ret
|
|
pyr_ai_safety:
|
|
invoke PyramidSelect3D,-1
|
|
mov esi,pyrCue3D
|
|
xor edi,edi
|
|
pyr_ai_safety_target:
|
|
cmp edi,esi
|
|
je @F
|
|
cmp poolActive3D[edi*4],1
|
|
je pyr_ai_safety_found
|
|
@@:
|
|
inc edi
|
|
cmp edi,16
|
|
jb pyr_ai_safety_target
|
|
ret
|
|
pyr_ai_safety_found:
|
|
invoke PoolAimPoint3D,poolX3D[edi*4],poolY3D[edi*4]
|
|
mov poolPower3D,65000
|
|
ret
|
|
PoolChooseAI3D ENDP
|
|
|
|
HandlePool3D PROC uses ebx esi edi
|
|
xor esi,esi
|
|
pyr_sink_tick:
|
|
mov eax,deltaTime3D
|
|
sub poolSinkTime3D[esi*4],eax
|
|
jnc @F
|
|
mov poolSinkTime3D[esi*4],0
|
|
@@:
|
|
inc esi
|
|
cmp esi,16
|
|
jb pyr_sink_tick
|
|
mov eax,deltaTime3D
|
|
add poolTime3D,eax
|
|
cmp mouseClick3D,0
|
|
je pyr_update
|
|
cmp mouseY3D,3
|
|
jb pyr_update
|
|
cmp mouseY3D,17
|
|
jae pyr_update
|
|
cmp mouseX3D,252
|
|
jb pyr_update
|
|
cmp mouseX3D,312
|
|
jae pyr_update
|
|
mov engineMode,MODE_WALK
|
|
call ClearKeys3D
|
|
call SaveProgress3D
|
|
ret
|
|
pyr_update:
|
|
cmp poolState3D,POOL_MOVING
|
|
jne pyr_strike
|
|
add poolAccumulator3D,eax
|
|
pyr_fixed_tick:
|
|
cmp poolAccumulator3D,2
|
|
jb pyr_handle_done
|
|
sub poolAccumulator3D,2
|
|
call PoolStep3D
|
|
cmp poolStill3D,0
|
|
je pyr_fixed_tick
|
|
call PoolFinishShot3D
|
|
ret
|
|
pyr_strike:
|
|
cmp poolState3D,POOL_STRIKE
|
|
jne pyr_idle
|
|
cmp poolTime3D,240
|
|
jb pyr_handle_done
|
|
mov ebx,pyrCue3D
|
|
mov eax,pyrDirX3D
|
|
imul poolPower3D
|
|
shrd eax,edx,16
|
|
mov poolVX3D[ebx*4],eax
|
|
mov eax,pyrDirY3D
|
|
imul poolPower3D
|
|
shrd eax,edx,16
|
|
mov poolVY3D[ebx*4],eax
|
|
mov poolState3D,POOL_MOVING
|
|
mov poolAccumulator3D,0
|
|
ret
|
|
pyr_idle:
|
|
cmp poolState3D,POOL_RESULT
|
|
jne pyr_actor
|
|
invoke Pressed3D,20h
|
|
test eax,eax
|
|
jnz pyr_restart
|
|
cmp mouseClick3D,0
|
|
je pyr_handle_done
|
|
cmp mouseY3D,211
|
|
jb pyr_handle_done
|
|
cmp mouseX3D,202
|
|
jb pyr_handle_done
|
|
pyr_restart:
|
|
call InitPool3D
|
|
ret
|
|
pyr_actor:
|
|
cmp poolPlayer3D,1
|
|
jne pyr_human
|
|
cmp poolAI3D,0
|
|
je pyr_human
|
|
cmp poolTime3D,1000
|
|
jb pyr_handle_done
|
|
cmp poolState3D,POOL_PENALTY
|
|
jne @F
|
|
xor esi,esi
|
|
pyr_ai_penalty:
|
|
cmp poolActive3D[esi*4],1
|
|
je pyr_ai_penalty_pick
|
|
inc esi
|
|
cmp esi,16
|
|
jb pyr_ai_penalty
|
|
ret
|
|
pyr_ai_penalty_pick:
|
|
invoke PyramidPenalty3D,esi
|
|
ret
|
|
@@:
|
|
cmp poolState3D,POOL_CHOICE
|
|
jne @F
|
|
invoke PyramidChoice3D,0
|
|
ret
|
|
@@:
|
|
call PoolChooseAI3D
|
|
call PoolShoot3D
|
|
ret
|
|
pyr_human:
|
|
cmp poolState3D,POOL_CHOICE
|
|
jne pyr_human_penalty
|
|
mov esi,0
|
|
pyr_choice_key:
|
|
lea eax,[esi+31h]
|
|
invoke Pressed3D,eax
|
|
test eax,eax
|
|
jnz pyr_choice_selected
|
|
inc esi
|
|
cmp esi,4
|
|
jb pyr_choice_key
|
|
invoke Pressed3D,0Dh
|
|
test eax,eax
|
|
jz @F
|
|
xor esi,esi
|
|
jmp pyr_choice_selected
|
|
@@:
|
|
cmp mouseClick3D,0
|
|
je pyr_handle_done
|
|
cmp mouseY3D,215
|
|
jb pyr_handle_done
|
|
cmp mouseY3D,237
|
|
jae pyr_handle_done
|
|
mov eax,mouseX3D
|
|
sub eax,8
|
|
js pyr_handle_done
|
|
xor edx,edx
|
|
mov ecx,78
|
|
div ecx
|
|
cmp edx,70
|
|
jae pyr_handle_done
|
|
mov esi,eax
|
|
pyr_choice_selected:
|
|
invoke PyramidChoice3D,esi
|
|
ret
|
|
pyr_human_penalty:
|
|
cmp poolState3D,POOL_PENALTY
|
|
jne pyr_human_aim
|
|
invoke Pressed3D,0Dh
|
|
test eax,eax
|
|
jnz pyr_penalty_skip
|
|
cmp mouseClick3D,0
|
|
je pyr_handle_done
|
|
cmp mouseY3D,215
|
|
jb @F
|
|
cmp mouseY3D,238
|
|
jae @F
|
|
cmp mouseX3D,202
|
|
jae pyr_penalty_skip
|
|
@@:
|
|
mov eax,mouseX3D
|
|
shl eax,16
|
|
mov ebx,mouseY3D
|
|
shl ebx,16
|
|
invoke PyramidPick3D,eax,ebx
|
|
cmp eax,-1
|
|
je pyr_handle_done
|
|
invoke PyramidPenalty3D,eax
|
|
ret
|
|
pyr_penalty_skip:
|
|
mov poolState3D,POOL_CHOICE
|
|
ret
|
|
pyr_human_aim:
|
|
cmp mouseClick3D,0
|
|
je pyr_keys
|
|
mov mouseClick3D,0
|
|
mov eax,mouseX3D
|
|
mov ebx,mouseY3D
|
|
cmp ebx,50
|
|
jb pyr_keys
|
|
cmp ebx,180
|
|
ja pyr_mouse_footer
|
|
shl eax,16
|
|
shl ebx,16
|
|
cmp pyrPickClick3D,0
|
|
je @F
|
|
mov pyrPickClick3D,0
|
|
invoke PyramidPick3D,eax,ebx
|
|
cmp eax,-1
|
|
je pyr_handle_done
|
|
invoke PyramidSelect3D,eax
|
|
ret
|
|
@@:
|
|
cmp poolBreak3D,0
|
|
je pyr_mouse_aim
|
|
cmp keys3D[10h],0
|
|
je pyr_mouse_aim
|
|
cmp eax,95*FP_1
|
|
jge pyr_handle_done
|
|
invoke PoolPlaceCue3D,eax,ebx
|
|
ret
|
|
pyr_mouse_aim:
|
|
invoke PoolAimPoint3D,eax,ebx
|
|
ret
|
|
pyr_mouse_footer:
|
|
cmp ebx,193
|
|
jb pyr_keys
|
|
cmp ebx,209
|
|
ja pyr_mouse_command
|
|
cmp eax,202
|
|
jb pyr_keys
|
|
cmp eax,308
|
|
ja pyr_keys
|
|
sub eax,202
|
|
imul eax,82000
|
|
xor edx,edx
|
|
mov ecx,106
|
|
div ecx
|
|
add eax,8000
|
|
mov poolPower3D,eax
|
|
ret
|
|
pyr_mouse_command:
|
|
cmp ebx,211
|
|
jb pyr_keys
|
|
cmp ebx,238
|
|
jae pyr_keys
|
|
cmp eax,86
|
|
jb pyr_cycle_cue
|
|
cmp eax,196
|
|
jb pyr_toggle_guide
|
|
call PoolShoot3D
|
|
ret
|
|
pyr_keys:
|
|
mov eax,deltaTime3D
|
|
imul eax,120
|
|
cmp keys3D[10h],0
|
|
je @F
|
|
mov eax,deltaTime3D
|
|
imul eax,30
|
|
@@:
|
|
add eax,pyrAimCarry3D
|
|
xor edx,edx
|
|
mov ecx,1000
|
|
div ecx
|
|
mov pyrAimCarry3D,edx
|
|
mov ebx,eax
|
|
cmp pyrFineActive3D,0
|
|
jne @F
|
|
mov eax,poolAngle3D
|
|
shl eax,3
|
|
mov pyrFine3D,eax
|
|
@@:
|
|
cmp keys3D[25h],0
|
|
je @F
|
|
sub pyrFine3D,ebx
|
|
mov pyrFineActive3D,1
|
|
@@:
|
|
cmp keys3D[27h],0
|
|
je @F
|
|
add pyrFine3D,ebx
|
|
mov pyrFineActive3D,1
|
|
@@:
|
|
and pyrFine3D,4095
|
|
mov eax,deltaTime3D
|
|
imul eax,100
|
|
cmp keys3D[26h],0
|
|
je @F
|
|
add poolPower3D,eax
|
|
@@:
|
|
cmp keys3D[28h],0
|
|
je @F
|
|
sub poolPower3D,eax
|
|
@@:
|
|
cmp poolPower3D,8000
|
|
jge @F
|
|
mov poolPower3D,8000
|
|
@@:
|
|
cmp poolPower3D,90000
|
|
jle @F
|
|
mov poolPower3D,90000
|
|
@@:
|
|
invoke Pressed3D,42h
|
|
test eax,eax
|
|
jnz pyr_cycle_cue
|
|
invoke Pressed3D,50h
|
|
test eax,eax
|
|
jnz pyr_toggle_guide
|
|
invoke Pressed3D,20h
|
|
test eax,eax
|
|
jz pyr_handle_done
|
|
call PoolShoot3D
|
|
ret
|
|
pyr_toggle_guide:
|
|
xor pyrGuideOn3D,1
|
|
ret
|
|
pyr_cycle_cue:
|
|
cmp poolBreak3D,0
|
|
jne pyr_handle_done
|
|
mov esi,pyrCue3D
|
|
mov edi,16
|
|
pyr_cycle_scan:
|
|
inc esi
|
|
and esi,15
|
|
cmp poolActive3D[esi*4],1
|
|
je pyr_cycle_found
|
|
dec edi
|
|
jnz pyr_cycle_scan
|
|
ret
|
|
pyr_cycle_found:
|
|
invoke PyramidSelect3D,esi
|
|
pyr_handle_done:
|
|
ret
|
|
HandlePool3D ENDP
|