EightCount3D PROC uses ebx esi mov poolAtStart3D,0 mov ecx,poolPlayer3D mov ebx,poolGroups3D[ecx*4] test ebx,ebx jz eight_count_done mov esi,1 eight_count_loop: cmp esi,8 je eight_count_next mov eax,1 cmp esi,8 jb @F mov eax,2 @@: cmp eax,ebx jne eight_count_next mov eax,poolActive3D[esi*4] add poolAtStart3D,eax eight_count_next: inc esi cmp esi,16 jb eight_count_loop eight_count_done: ret EightCount3D ENDP EightLegal3D PROC uses ebx ball:DWORD xor eax,eax mov ecx,ball test ecx,ecx jle eight_legal_done cmp ecx,15 ja eight_legal_done mov ebx,poolPlayer3D mov ebx,poolGroups3D[ebx*4] test ebx,ebx jz eight_legal_open cmp poolAtStart3D,0 jne eight_legal_group cmp ecx,8 sete al ret eight_legal_group: cmp ecx,8 je eight_legal_done mov eax,1 cmp ecx,8 jb @F mov eax,2 @@: cmp eax,ebx sete al movzx eax,al ret eight_legal_open: cmp ecx,8 setne al eight_legal_done: ret EightLegal3D ENDP ; An obvious shot uses the same predictor as the visible guide. Explicit calls ; lock either ball or pocket independently; cached prediction never settles play. EightAutoCall3D PROC uses ebx esi edi cmp poolVariant3D,1 jne eight_auto_done cmp poolState3D,POOL_AIM jne eight_auto_done call EightCount3D call PoolPredict3D test poolCallManual3D,1 jnz eight_auto_pocket mov poolCalled3D,0 mov ebx,poolTraceFirst3D invoke EightLegal3D,ebx test eax,eax jz eight_auto_scan mov poolCalled3D,ebx bt poolTracePotted3D,ebx jnc eight_auto_scan test poolCallManual3D,2 jz eight_auto_select mov eax,poolTraceFinal3D[80*4+ebx*4] cmp eax,poolCalledPocket3D je eight_auto_select eight_auto_scan: mov ebx,1 eight_auto_next: bt poolTracePotted3D,ebx jnc eight_auto_advance invoke EightLegal3D,ebx test eax,eax jz eight_auto_advance eight_auto_filter: test poolCallManual3D,2 jz eight_auto_select mov eax,poolTraceFinal3D[80*4+ebx*4] cmp eax,poolCalledPocket3D je eight_auto_select eight_auto_advance: inc ebx cmp ebx,16 jb eight_auto_next jmp eight_auto_pocket eight_auto_select: mov poolCalled3D,ebx eight_auto_pocket: test poolCallManual3D,2 jnz eight_auto_done mov poolCalledPocket3D,-1 mov ebx,poolCalled3D cmp ebx,1 jb eight_auto_done cmp ebx,15 ja eight_auto_done bt poolTracePotted3D,ebx jnc eight_auto_done mov eax,poolTraceFinal3D[80*4+ebx*4] cmp eax,5 ja eight_auto_done mov poolCalledPocket3D,eax eight_auto_done: ret EightAutoCall3D ENDP ; In pool the group owns the ball, not whoever happened to pocket it. ; Recounting also assigns balls pocketed while the table was still open. EightSyncGroups3D PROC uses ebx esi edi mov pyrScore3D,0 mov pyrScore3D[4],0 mov pyrOwner3D,-1 mov esi,1 eight_sync_ball: mov pyrOwner3D[esi*4],-1 cmp esi,8 je eight_sync_next cmp poolActive3D[esi*4],0 jne eight_sync_next mov eax,1 cmp esi,8 jb @F mov eax,2 @@: xor ebx,ebx cmp eax,poolGroups3D je eight_sync_credit inc ebx cmp eax,poolGroups3D[4] jne eight_sync_next eight_sync_credit: mov pyrOwner3D[esi*4],ebx inc pyrScore3D[ebx*4] eight_sync_next: inc esi cmp esi,16 jb eight_sync_ball ret EightSyncGroups3D ENDP ; Called-ball eight-ball rules share only simulation and aiming with pyramid. EightFinish3D PROC uses ebx esi edi local originalPots:DWORD cmp pyrSettled3D,0 jne eight_finish_done mov pyrSettled3D,1 mov poolCallManual3D,0 mov poolTraceValid3D,0 mov eax,poolPotted3D mov originalPots,eax mov poolFoul3D,0 cmp poolActive3D,0 je eight_finish_foul cmp poolFirst3D,-1 je eight_finish_foul cmp poolBreak3D,0 jne eight_finish_break invoke EightLegal3D,poolFirst3D test eax,eax jz eight_finish_foul cmp poolRail3D,0 jne eight_finish_eight cmp poolPotted3D,0 jne eight_finish_eight jmp eight_finish_foul eight_finish_break: mov eax,poolPotted3D and eax,0FFFEh jnz eight_finish_eight mov eax,poolBreakRails3D and eax,0FFFEh xor ecx,ecx eight_break_rails: test eax,eax jz @F lea edx,[eax-1] and eax,edx inc ecx jmp eight_break_rails @@: cmp ecx,4 jae eight_finish_eight mov pyrIllegalBreak3D,1 mov pyrFoulReason3D,2 mov eax,poolPlayer3D xor eax,1 mov poolPlayer3D,eax mov pyrChoiceActor3D,eax mov poolState3D,POOL_CHOICE mov poolTime3D,0 call EightSyncGroups3D ret eight_finish_foul: mov poolFoul3D,1 eight_finish_eight: bt poolPotted3D,8 jnc eight_finish_continue cmp poolBreak3D,0 je eight_finish_result invoke PyramidRespot3D,8 btr poolPotted3D,8 jmp eight_finish_continue eight_finish_result: mov eax,poolPlayer3D cmp poolFoul3D,0 jne eight_finish_lost cmp poolAtStart3D,0 jne eight_finish_lost mov ecx,poolGroups3D[eax*4] test ecx,ecx jz eight_finish_lost cmp poolCalled3D,8 jne eight_finish_lost mov ecx,poolCalledPocket3D cmp poolPocket3D[32],ecx je eight_finish_winner eight_finish_lost: xor eax,1 eight_finish_winner: mov poolWinner3D,eax mov poolState3D,POOL_RESULT call EightSyncGroups3D ret eight_finish_continue: cmp poolFoul3D,0 jne eight_finish_hand cmp poolBreak3D,0 je eight_finish_called mov eax,originalPots and eax,0FFFEh jnz eight_finish_aim jmp eight_finish_switch eight_finish_called: mov ebx,poolCalled3D cmp ebx,1 jb eight_finish_switch cmp ebx,15 ja eight_finish_switch bt poolPotted3D,ebx jnc eight_finish_switch mov eax,poolCalledPocket3D cmp poolPocket3D[ebx*4],eax jne eight_finish_switch invoke EightLegal3D,ebx test eax,eax jz eight_finish_switch mov ecx,poolPlayer3D cmp poolGroups3D[ecx*4],0 jne eight_finish_aim mov eax,1 cmp ebx,8 jb @F mov eax,2 @@: mov poolGroups3D[ecx*4],eax xor ecx,1 xor eax,3 mov poolGroups3D[ecx*4],eax jmp eight_finish_aim eight_finish_hand: xor poolPlayer3D,1 mov poolState3D,POOL_HAND mov poolBreak3D,0 mov poolTime3D,0 mov pyrCue3D,0 mov poolActive3D,0 call EightSyncGroups3D ret eight_finish_switch: xor poolPlayer3D,1 eight_finish_aim: mov poolState3D,POOL_AIM mov poolBreak3D,0 mov poolTime3D,0 mov pyrCue3D,0 call EightCount3D call EightSyncGroups3D eight_finish_done: ret EightFinish3D ENDP EightHand3D PROC uses ebx esi cmp poolPlayer3D,1 jne eight_hand_human cmp poolAI3D,0 je eight_hand_human mov esi,55*FP_1 eight_hand_row: mov ebx,40*FP_1 eight_hand_cell: invoke PoolPlaceCue3D,ebx,esi test eax,eax jnz eight_hand_placed add ebx,6*FP_1 cmp ebx,280*FP_1 jle eight_hand_cell add esi,6*FP_1 cmp esi,175*FP_1 jle eight_hand_row ret eight_hand_human: cmp mouseClick3D,0 je eight_hand_done mov mouseClick3D,0 mov eax,mouseX3D shl eax,16 mov ebx,mouseY3D shl ebx,16 invoke PoolPlaceCue3D,eax,ebx test eax,eax jz eight_hand_done eight_hand_placed: mov poolState3D,POOL_AIM mov poolTime3D,0 mov poolTraceValid3D,0 eight_hand_done: ret EightHand3D ENDP