.data pyrTestStage3D dd 0 pyrTestRack db "build\actions\pyramid-rack.bmp",0 pyrTestAim db "build\actions\pyramid-aim.bmp",0 pyrTestStrike db "build\actions\pyramid-strike.bmp",0 pyrTestPenalty db "build\actions\pyramid-penalty.bmp",0 pyrTestChoice db "build\actions\pyramid-choice.bmp",0 pyrTestWin db "build\actions\pyramid-win.bmp",0 .code RunBilliardsChoiceTest3D PROTO PyramidTestLedger3D PROC uses ebx esi edi xor esi,esi xor ebx,ebx xor edi,edi pyr_test_ledger_ball: cmp poolActive3D[esi*4],1 jne @F inc ebx cmp pyrOwner3D[esi*4],-1 jne pyr_test_ledger_bad jmp pyr_test_ledger_next @@: cmp pyrOwner3D[esi*4],0 jl pyr_test_ledger_bad cmp pyrOwner3D[esi*4],1 ja pyr_test_ledger_bad inc edi pyr_test_ledger_next: inc esi cmp esi,16 jb pyr_test_ledger_ball add ebx,edi cmp ebx,16 jne pyr_test_ledger_bad mov eax,pyrScore3D add eax,pyrScore3D[4] cmp eax,edi jne pyr_test_ledger_bad xor eax,eax ret pyr_test_ledger_bad: mov eax,1 ret PyramidTestLedger3D ENDP RunPyramidTest3D PROC uses ebx esi edi local oldBank:DWORD,oldSeed:DWORD,oldAI:DWORD,oldMode:DWORD,ticks:DWORD,value:DWORD mov eax,bankroll mov oldBank,eax mov eax,rngSeed3D mov oldSeed,eax mov eax,poolAI3D mov oldAI,eax mov eax,engineMode mov oldMode,eax mov engineMode,MODE_POOL mov poolAI3D,0 call ClearKeys3D mov pyrTestStage3D,1 call ResetPool3D call PyramidTestLedger3D test eax,eax jnz pyr_test_fail call RenderPool3D invoke WriteActionSnapshot3D,OFFSET pyrTestRack ; Old Q8 squares wrapped at 256 pixels and potted a distant ball. mov poolX3D,286*FP_1 mov poolY3D,50*FP_1 invoke PoolPocketBall3D,0 cmp poolActive3D,1 jne pyr_test_fail mov poolX3D,34*FP_1 mov poolY3D,180*FP_1 invoke PoolPocketBall3D,0 cmp poolActive3D,1 jne pyr_test_fail mov pyrTestStage3D,2 call ResetPool3D mov poolBreak3D,0 invoke PoolAimPoint3D,250*FP_1,115*FP_1+FP_1/2 test pyrFine3D,7 jz pyr_test_fail mov poolX3D[12*4],100*FP_1 mov poolY3D[12*4],90*FP_1 mov poolX3D[4],160*FP_1 mov poolY3D[4],90*FP_1 invoke PyramidSelect3D,12 cmp pyrCue3D,12 jne pyr_test_fail invoke PoolAimPoint3D,200*FP_1,90*FP_1 call RenderPool3D cmp pyrTarget3D,-1 je pyr_test_fail invoke WriteActionSnapshot3D,OFFSET pyrTestAim call PoolShoot3D cmp poolState3D,POOL_STRIKE jne pyr_test_fail mov poolTime3D,120 call RenderPool3D invoke WriteActionSnapshot3D,OFFSET pyrTestStrike mov deltaTime3D,120 call HandlePool3D cmp poolVX3D[12*4],0 jle pyr_test_fail cmp poolVX3D,0 jne pyr_test_fail mov pyrTestStage3D,3 call ResetPool3D mov poolBreak3D,0 mov poolFirst3D,1 mov poolActive3D,0 mov poolPocket3D,1 mov poolPotted3D,1 call PoolFinishShot3D cmp poolFoul3D,0 jne pyr_test_fail cmp pyrScore3D,1 jne pyr_test_fail cmp poolPlayer3D,0 jne pyr_test_fail cmp pyrCue3D,0 je pyr_test_fail call PoolFinishShot3D cmp pyrScore3D,1 jne pyr_test_fail call PyramidTestLedger3D test eax,eax jnz pyr_test_fail mov pyrTestStage3D,4 call ResetPool3D mov poolBreak3D,0 mov poolFirst3D,-1 mov poolActive3D[3*4],0 mov poolActive3D[9*4],0 mov poolPotted3D,208h call PoolFinishShot3D cmp poolState3D,POOL_PENALTY jne pyr_test_fail cmp poolActive3D[3*4],1 jne pyr_test_fail cmp poolActive3D[9*4],1 jne pyr_test_fail cmp poolPlayer3D,1 jne pyr_test_fail call RenderPool3D invoke WriteActionSnapshot3D,OFFSET pyrTestPenalty invoke PyramidPenalty3D,4 invoke PyramidPenalty3D,5 cmp pyrScore3D[4],1 jne pyr_test_fail cmp poolActive3D[5*4],1 jne pyr_test_fail call RenderPool3D invoke WriteActionSnapshot3D,OFFSET pyrTestChoice invoke PyramidChoice3D,1 cmp poolPlayer3D,0 jne pyr_test_fail call PyramidTestLedger3D test eax,eax jnz pyr_test_fail ; Invalid break has partial-rack choices; the penalty is not erased. call ResetPool3D mov poolFirst3D,1 mov poolBreakRails3D,6 call PoolFinishShot3D cmp pyrIllegalBreak3D,1 jne pyr_test_fail invoke PyramidPenalty3D,0 invoke PyramidChoice3D,2 cmp poolBreak3D,1 jne pyr_test_fail cmp poolActive3D,1 jne pyr_test_fail cmp pyrScore3D[4],1 jne pyr_test_fail call PyramidTestLedger3D test eax,eax jnz pyr_test_fail mov pyrTestStage3D,5 ; Three object cushions, or two plus an object crossing, is a legal break. call ResetPool3D mov poolFirst3D,1 mov poolBreakRails3D,0Eh call PoolFinishShot3D cmp poolFoul3D,0 jne pyr_test_fail call ResetPool3D mov poolFirst3D,1 mov poolBreakRails3D,6 mov pyrHistoryCross3D[4],1 call PoolFinishShot3D cmp poolFoul3D,0 jne pyr_test_fail mov pyrTestStage3D,6 ; Legal completion needs ordered events along the same transfer chain. call ResetPool3D mov poolBreak3D,0 mov poolFirst3D,1 invoke PyramidRail3D,1,0 invoke PyramidRail3D,1,0 cmp pyrValidEnd3D,0 jne pyr_test_fail invoke PyramidRail3D,1,1 cmp pyrValidEnd3D,1 jne pyr_test_fail call ResetPool3D mov poolFirst3D,1 mov pyrPreviousX3D[4],159*FP_1 mov poolX3D[4],161*FP_1 invoke PyramidCross3D,1 invoke PyramidRail3D,2,0 cmp pyrValidEnd3D,0 jne pyr_test_fail invoke PyramidRail3D,1,0 cmp pyrValidEnd3D,1 jne pyr_test_fail call ResetPool3D mov poolFirst3D,1 invoke PyramidRail3D,1,0 mov pyrPreviousX3D[4],159*FP_1 mov poolX3D[4],161*FP_1 invoke PyramidCross3D,1 cmp pyrValidEnd3D,1 jne pyr_test_fail call ResetPool3D mov poolFirst3D,1 invoke PyramidRail3D,1,0 mov poolX3D[4],80*FP_1 mov poolX3D[8],90*FP_1 invoke PyramidContact3D,1,2 invoke PyramidRail3D,2,1 cmp pyrValidEnd3D,1 jne pyr_test_fail mov pyrTestStage3D,7 ; The real bot must pot through geometry, not inject a pocket result. call ResetPool3D mov poolBreak3D,0 mov poolPlayer3D,1 mov poolAI3D,0 mov esi,2 pyr_test_ai_clear: mov poolActive3D[esi*4],0 inc esi cmp esi,16 jb pyr_test_ai_clear mov poolX3D,160*FP_1 mov poolY3D,115*FP_1 mov poolX3D[4],160*FP_1 mov poolY3D[4],70*FP_1 call PoolChooseAI3D cmp pyrCue3D,0 jne pyr_test_fail call PoolShoot3D mov deltaTime3D,240 call HandlePool3D mov deltaTime3D,16 mov ticks,0 pyr_test_ai_tick: call HandlePool3D inc ticks cmp ticks,1000 ja pyr_test_fail cmp poolState3D,POOL_MOVING je pyr_test_ai_tick cmp pyrScore3D[4],1 jb pyr_test_fail cmp poolPocket3D[4],1 jne pyr_test_fail mov pyrTestStage3D,8 call ResetPool3D mov poolBreak3D,0 mov poolFirst3D,9 mov poolPotted3D,01FEh mov esi,1 pyr_test_winning_balls: mov poolActive3D[esi*4],0 mov poolPocket3D[esi*4],1 inc esi cmp esi,9 jb pyr_test_winning_balls call PoolFinishShot3D cmp pyrScore3D,8 jne pyr_test_fail cmp poolWinner3D,0 jne pyr_test_fail cmp poolState3D,POOL_RESULT jne pyr_test_fail call PyramidTestLedger3D test eax,eax jnz pyr_test_fail call RenderPool3D invoke WriteActionSnapshot3D,OFFSET pyrTestWin call RunBilliardsChoiceTest3D test eax,eax jnz pyr_test_choice_fail mov eax,oldBank cmp bankroll,eax jne pyr_test_fail mov eax,oldSeed cmp rngSeed3D,eax jne pyr_test_fail mov eax,oldAI mov poolAI3D,eax mov eax,oldMode mov engineMode,eax call ClearKeys3D xor eax,eax ret pyr_test_choice_fail: ret pyr_test_fail: mov eax,pyrTestStage3D add eax,920 ret RunPyramidTest3D ENDP include tools\tests\billiards_choice_test.inc