PyramidBall3D PROC uses ebx esi ball:DWORD,x:DWORD,y:DWORD,sizePx:DWORD mov ebx,ball cmp poolVariant3D,1 jne pyr_ball_palette mov eax,sizePx shr eax,1 mov edx,x sub edx,eax mov ecx,y sub ecx,eax invoke DrawAnimSprite3D,OFFSET poolEightPack3D,ebx,edx,ecx,sizePx,sizePx jmp pyr_ball_number pyr_ball_palette: mov eax,pyrRoll3D[ebx*4] shr eax,17 and eax,3 test ebx,ebx jnz @F add eax,4 @@: mov esi,eax mov eax,sizePx shr eax,1 mov edx,x sub edx,eax mov ecx,y sub ecx,eax invoke DrawAnimSprite3D,OFFSET pyrBallsPack3D,esi,edx,ecx,sizePx,sizePx pyr_ball_number: cmp sizePx,12 jne pyr_ball_done test ebx,ebx jz pyr_ball_done mov esi,x sub esi,1 mov eax,y sub eax,2 cmp ebx,10 jb @F sub esi,2 invoke DrawWheelDigit3D,esi,eax,1,1,003B3933h add esi,4 mov eax,y sub eax,2 sub ebx,10 @@: invoke DrawWheelDigit3D,esi,eax,ebx,1,003B3933h pyr_ball_done: ret PyramidBall3D ENDP ; A swept aim preview terminates on the first real ball or cushion. PyramidGuide3D PROC uses ebx esi edi local px:DWORD,py:DWORD,pointX:DWORD,pointY:DWORD mov pyrTarget3D,-1 mov ebx,pyrCue3D mov eax,poolX3D[ebx*4] mov px,eax mov eax,poolY3D[ebx*4] mov py,eax mov esi,6 pyr_guide_step: mov eax,pyrDirX3D imul esi sar eax,1 add eax,px mov pointX,eax mov eax,pyrDirY3D imul esi sar eax,1 add eax,py mov pointY,eax cmp pointX,30*FP_1+POOL_RADIUS jl pyr_guide_done cmp pointX,290*FP_1-POOL_RADIUS jg pyr_guide_done cmp pointY,50*FP_1+POOL_RADIUS jl pyr_guide_done cmp pointY,180*FP_1-POOL_RADIUS jg pyr_guide_done xor edi,edi pyr_guide_obstacle: cmp edi,pyrCue3D je pyr_guide_next_obstacle cmp poolActive3D[edi*4],1 jne pyr_guide_next_obstacle mov eax,pointX sub eax,poolX3D[edi*4] sar eax,12 imul eax,eax mov ebx,eax mov eax,pointY sub eax,poolY3D[edi*4] sar eax,12 imul eax,eax add eax,ebx cmp eax,25*16*16 jb pyr_guide_hit pyr_guide_next_obstacle: inc edi cmp edi,16 jb pyr_guide_obstacle test esi,7 jnz pyr_guide_next mov eax,pointX sar eax,16 mov ebx,pointY sar ebx,16 invoke DrawPixel,eax,ebx,00B1D7CFh pyr_guide_next: inc esi cmp esi,560 jb pyr_guide_step pyr_guide_done: ret pyr_guide_hit: mov pyrTarget3D,edi mov eax,pointX mov pyrGuideX3D,eax sar eax,16 mov ebx,pointY mov pyrGuideY3D,ebx sar ebx,16 invoke DrawCircle,eax,ebx,3,00B1D7CFh mov eax,pointX sar eax,16 mov ebx,pointY sar ebx,16 invoke DrawCircle,eax,ebx,2,00295041h ret PyramidGuide3D ENDP RenderPool3D PROC uses ebx esi edi local px:DWORD,py:DWORD,tip:DWORD,dirx:DWORD,diry:DWORD mov esi,pyrTablePack3D.pixels test esi,esi jz pyr_render_missing lea edi,screenBuffer mov ecx,SCREEN_SIZE rep movsd cmp poolState3D,POOL_SELECT jne pyr_render_game invoke DrawBox,0,0,320,35,00151D20h invoke DrawString8x8,16,12,OFFSET poolSelectTitle3D,00E8D7ADh invoke DrawBoxBorder,252,3,60,14,002C3637h,00687672h,1 invoke DrawString8x8,258,6,OFFSET cardExitButton3D,00E9D8B0h invoke DrawBoxBorder,40,80,240,48,00192720h,00D6B971h,2 invoke DrawString8x8,68,99,OFFSET poolSelectPyramid3D,00FFFFFFh invoke DrawBoxBorder,40,144,240,48,00192720h,00D6B971h,2 invoke DrawString8x8,58,163,OFFSET poolSelectEight3D,00FFFFFFh ret pyr_render_game: call EightAutoCall3D xor esi,esi pyr_render_mouths: mov eax,poolPocketX3D[esi*4] sar eax,16 mov ebx,poolPocketY3D[esi*4] sar ebx,16 mov px,eax mov py,ebx invoke DrawCircle,eax,ebx,3,000B1010h cmp poolVariant3D,1 jne @F mov eax,poolPocketX3D[esi*4] sar eax,16 mov ebx,poolPocketY3D[esi*4] sar ebx,16 invoke DrawCircle,px,py,5,000B1010h cmp esi,poolCalledPocket3D jne @F invoke DrawCircle,px,py,6,00D6B971h invoke DrawCircle,px,py,4,000B1010h @@: inc esi cmp esi,6 jb pyr_render_mouths invoke DrawPixel,95,115,00838C73h invoke DrawPixel,160,115,00838C73h invoke DrawPixel,225,115,00838C73h cmp poolBreak3D,0 je @F invoke DrawBox,95,53,1,124,003C7261h @@: cmp poolState3D,POOL_AIM jne pyr_render_objects call PyramidDirection3D cmp pyrGuideOn3D,0 je pyr_render_objects call PoolDrawPrediction3D pyr_render_objects: xor esi,esi pyr_render_ball: cmp poolActive3D[esi*4],1 jne pyr_render_sunk mov eax,poolX3D[esi*4] sar eax,15 mov px,eax mov eax,poolY3D[esi*4] sar eax,15 mov py,eax cmp poolVariant3D,1 jne @F cmp esi,poolCalled3D jne @F mov eax,px sar eax,1 mov ebx,py sar ebx,1 invoke DrawCircle,eax,ebx,4,00D6B971h @@: cmp esi,pyrCue3D jne @F cmp poolState3D,POOL_AIM jne @F mov eax,px sar eax,1 mov ebx,py sar ebx,1 invoke DrawCircle,eax,ebx,4,007BAFACh @@: invoke PyramidBall3D,esi,px,py,12 jmp pyr_render_next pyr_render_sunk: cmp poolSinkTime3D[esi*4],0 je pyr_render_next mov ecx,poolPocket3D[esi*4] cmp ecx,5 ja pyr_render_next mov eax,poolPocketX3D[ecx*4] sar eax,15 mov px,eax mov eax,poolPocketY3D[ecx*4] sar eax,15 mov py,eax mov eax,poolSinkTime3D[esi*4] imul eax,12 xor edx,edx mov ecx,220 div ecx test eax,eax jz pyr_render_next invoke PyramidBall3D,esi,px,py,eax pyr_render_next: inc esi cmp esi,16 jb pyr_render_ball cmp poolState3D,POOL_AIM je pyr_render_cue cmp poolState3D,POOL_STRIKE jne pyr_render_hud pyr_render_cue: mov ebx,pyrCue3D mov eax,poolX3D[ebx*4] mov px,eax mov eax,poolY3D[ebx*4] mov py,eax mov eax,pyrDirX3D mov dirx,eax mov eax,pyrDirY3D mov diry,eax mov tip,5 cmp poolState3D,POOL_STRIKE jne @F mov tip,3 mov eax,240 sub eax,poolTime3D cmp eax,0 jge pyr_cue_time xor eax,eax pyr_cue_time: shr eax,4 add tip,eax @@: mov esi,tip mov edi,44 pyr_cue_draw: mov eax,dirx imul esi neg eax add eax,px sar eax,16 mov ebx,eax mov eax,diry imul esi neg eax add eax,py sar eax,16 mov tip,eax invoke DrawCircle,ebx,eax,1,003E2E23h invoke DrawPixel,ebx,tip,00DCC59Ah inc esi dec edi jnz pyr_cue_draw pyr_render_hud: invoke DrawBox,0,0,320,20,00151D20h mov ebx,OFFSET pyrTitle3D cmp poolVariant3D,0 je @F mov ebx,OFFSET poolTitle3D @@: invoke DrawString8x8,8,6,ebx,00E8D7ADh invoke DrawNumber,112,6,pyrScore3D,00F4F3E8h invoke DrawString8x8,128,6,OFFSET pyrScoreSep3D,00E8D7ADh invoke DrawNumber,144,6,pyrScore3D[4],00F4F3E8h cmp poolVariant3D,1 jne @F invoke DrawString8x8,88,6,OFFSET pyrPlayerName3D,00E8D7ADh invoke DrawString8x8,160,6,OFFSET pyrAIName3D,00E8D7ADh @@: mov ebx,OFFSET pyrPlayerName3D cmp poolPlayer3D,0 je @F mov ebx,OFFSET pyrAIName3D @@: invoke DrawString8x8,184,6,ebx,00A8DDB9h invoke DrawBoxBorder,252,3,60,14,002C3637h,00687672h,1 invoke DrawString8x8,258,6,OFFSET cardExitButton3D,00E9D8B0h mov ebx,OFFSET pyrTurnText3D cmp poolBreak3D,0 je @F mov ebx,OFFSET pyrBreakText3D @@: cmp poolState3D,POOL_PENALTY jne @F mov ebx,OFFSET pyrPenaltyText3D @@: cmp poolState3D,POOL_CHOICE jne @F mov ebx,OFFSET pyrChoiceText3D @@: cmp poolState3D,POOL_MOVING jne @F mov ebx,OFFSET poolMovingText3D @@: cmp poolState3D,POOL_STRIKE jne @F mov ebx,OFFSET poolShotText3D @@: cmp poolState3D,POOL_HAND jne @F mov ebx,OFFSET poolPlaceText3D @@: invoke DrawBox,0,22,320,15,00151D20h invoke DrawString8x8,8,26,ebx,00E8D7ADh cmp poolVariant3D,1 jne @F mov ecx,poolPlayer3D mov ecx,poolGroups3D[ecx*4] mov eax,poolGroupTexts3D[ecx*4] invoke DrawString8x8,176,26,eax,00E8D7ADh @@: cmp poolState3D,POOL_PENALTY je @F cmp poolState3D,POOL_CHOICE jne pyr_render_footer @@: mov ecx,pyrFoulReason3D mov eax,pyrStatusNames3D[ecx*4] invoke DrawString8x8,176,26,eax,00EAAD9Ah pyr_render_footer: invoke DrawBox,0,186,320,54,00151D20h xor esi,esi mov ebx,20 mov edi,174 pyr_render_shelves: mov eax,pyrOwner3D[esi*4] test eax,eax js pyr_shelf_next cmp eax,1 jne pyr_shelf_player invoke PyramidBall3D,esi,edi,381,10 add edi,12 jmp pyr_shelf_next pyr_shelf_player: invoke PyramidBall3D,esi,ebx,381,10 add ebx,12 pyr_shelf_next: inc esi cmp esi,16 jb pyr_render_shelves invoke DrawString8x8,202,187,OFFSET poolPowerText3D,00CCBE94h mov eax,poolPower3D sub eax,8000 imul eax,100 xor edx,edx mov ecx,82000 div ecx invoke DrawNumber,254,187,eax,00FFFFFFh mov eax,poolPower3D sub eax,8000 imul eax,106 xor edx,edx mov ecx,82000 div ecx mov tip,eax invoke DrawBox,202,201,106,5,00363D36h invoke DrawBox,202,201,tip,5,00D5BB73h mov eax,tip add eax,201 invoke DrawBox,eax,199,2,9,00F4F0DDh invoke DrawBoxBorder,12,215,74,22,0039412Fh,00AC9862h,1 cmp poolVariant3D,1 je eight_render_call invoke DrawString8x8,18,222,OFFSET pyrCueText3D,00FFFFFFh invoke DrawNumber,62,222,pyrCue3D,00EAD19Bh jmp eight_render_call_done eight_render_call: invoke DrawString8x8,18,222,OFFSET poolCallText3D,00FFFFFFh cmp poolCalled3D,0 je eight_render_no_call invoke DrawNumber,64,222,poolCalled3D,00EAD19Bh jmp eight_render_pocket eight_render_no_call: invoke DrawString8x8,64,222,OFFSET poolUnsetText3D,00EAD19Bh eight_render_pocket: mov eax,poolCalledPocket3D inc eax jz eight_render_no_pocket invoke DrawNumber,173,187,eax,00EAD19Bh jmp eight_render_pocket_label eight_render_no_pocket: invoke DrawString8x8,173,187,OFFSET poolUnsetText3D,00EAD19Bh eight_render_pocket_label: invoke DrawString8x8,129,187,OFFSET poolPocketText3D,00FFFFFFh eight_render_call_done: mov ebx,0039412Fh cmp pyrGuideOn3D,0 jne @F mov ebx,00242A2Ch @@: invoke DrawBoxBorder,92,215,104,22,ebx,00AC9862h,1 invoke DrawString8x8,106,222,OFFSET pyrGuideText3D,00FFFFFFh invoke DrawBoxBorder,202,215,106,22,00425232h,00BBA76Fh,1 mov ebx,OFFSET poolShotText3D cmp poolState3D,POOL_PENALTY jne @F mov ebx,OFFSET pyrSkipText3D @@: cmp poolState3D,POOL_RESULT jne @F mov ebx,OFFSET poolRackText3D @@: invoke DrawString8x8,226,222,ebx,00FFFFFFh cmp poolState3D,POOL_CHOICE jne pyr_render_result invoke DrawBox,0,211,320,29,00151D20h invoke DrawBoxBorder,8,215,70,22,0039412Fh,00AC9862h,1 invoke DrawString8x8,19,222,OFFSET pyrPlayText3D,00FFFFFFh invoke DrawBoxBorder,86,215,70,22,0039412Fh,00AC9862h,1 invoke DrawString8x8,89,222,OFFSET pyrPassText3D,00FFFFFFh cmp pyrIllegalBreak3D,0 je pyr_render_result invoke DrawBoxBorder,164,215,70,22,0039412Fh,00AC9862h,1 invoke DrawString8x8,167,222,OFFSET pyrRackText3D,00FFFFFFh invoke DrawBoxBorder,242,215,70,22,0039412Fh,00AC9862h,1 invoke DrawString8x8,249,222,OFFSET pyrTheirBreakText3D,00FFFFFFh pyr_render_result: cmp poolState3D,POOL_RESULT jne pyr_render_done invoke DrawBoxBorder,76,88,168,43,00192720h,00D6B971h,2 mov ebx,OFFSET pyrPlayerName3D cmp poolWinner3D,0 je @F mov ebx,OFFSET pyrAIName3D @@: invoke DrawString8x8,92,100,ebx,00FFFFFFh invoke DrawString8x8,92,115,OFFSET poolWinText3D,00E8D7ADh pyr_render_done: ret pyr_render_missing: invoke DrawBox,0,0,320,240,00151D20h invoke DrawString8x8,56,108,OFFSET unavailableText3D,00E8D7ADh ret RenderPool3D ENDP