InitNativeCoin3D PROC mov coin3d_state,COIN_IDLE mov coin3d_timer,0 mov coin3d_streak,0 mov coin3d_win,0 mov coin3d_choice,1 mov coin3d_result,1 mov coinExitQueued3D,0 mov coinError3D,0 cmp coin3d_bet,50 jae @F mov coin3d_bet,50 @@: cmp coin3d_bet,5000 jbe @F mov coin3d_bet,5000 @@: call LoadNativeCoinArt3D call OpenCoinDetail3D ret InitNativeCoin3D ENDP LoadNativeCoinArt3D PROC cmp coinArtReady3D,1 je coin_art_loaded invoke LoadAnimPack3D,OFFSET coinTableArt3D,OFFSET coinTablePath3D invoke LoadAnimPack3D,OFFSET coinFacesArt3D,OFFSET coinFacesPath3D invoke LoadAnimPack3D,OFFSET coinHandsArt3D,OFFSET coinHandsPath3D invoke ValidateCityPack3D,OFFSET coinTableArt3D,640,480,1 invoke ValidateCityPack3D,OFFSET coinFacesArt3D,128,128,2 invoke ValidateCityPack3D,OFFSET coinHandsArt3D,224,224,16 cmp coinTableArt3D.pixels,0 je coin_art_failed cmp coinFacesArt3D.pixels,0 je coin_art_failed cmp coinHandsArt3D.pixels,0 je coin_art_failed mov coinArtReady3D,1 coin_art_loaded: mov eax,1 ret coin_art_failed: call FreeNativeCoinArt3D xor eax,eax ret LoadNativeCoinArt3D ENDP FreeNativeCoinArt3D PROC call CloseCoinDetail3D invoke FreeAnimPack3D,OFFSET coinTableArt3D invoke FreeAnimPack3D,OFFSET coinFacesArt3D invoke FreeAnimPack3D,OFFSET coinHandsArt3D mov coinArtReady3D,0 ret FreeNativeCoinArt3D ENDP CoinEscape3D PROC mov paused3D,0 cmp coin3d_state,COIN_TOSS jne coin_leave_hall mov coinExitQueued3D,1 call ClearKeys3D ret coin_leave_hall: call CloseCoinDetail3D mov coinExitQueued3D,0 mov engineMode,MODE_WALK call ClearKeys3D invoke PlayCasinoSound3D,0,0,0 ret CoinEscape3D ENDP ; A paid flip settles once, even if Escape was pressed while it was in the air. CoinSettle3D PROC cmp coin3d_state,COIN_TOSS jne coin_settle_done mov coin3d_timer,COIN_TOTAL_MS mov coin3d_win,0 mov eax,coin3d_choice cmp eax,coin3d_result jne coin_settle_loss inc coin3d_streak mov eax,coin3d_bet shl eax,1 mov coin3d_win,eax add bankroll,eax jnc @F mov bankroll,1000000000 @@: cmp bankroll,1000000000 jbe @F mov bankroll,1000000000 @@: invoke PlayCasinoSound3D,OFFSET soundCoinDing,0,1 jmp coin_settle_save coin_settle_loss: mov coin3d_streak,0 invoke PlayCasinoSound3D,OFFSET soundLose,0,1 coin_settle_save: mov coin3d_state,COIN_RESULT xor eax,eax cmp coin3d_win,0 setne al invoke NpcRecordRound3D,0,eax call SaveProgress3D coin_settle_done: ret CoinSettle3D ENDP HandleNativeCoin3D PROC uses ebx cmp mouseClick3D,0 je coin_native_state cmp mouseY3D,3 jb coin_native_state cmp mouseY3D,17 jae coin_native_state cmp mouseX3D,252 jb coin_native_view cmp mouseX3D,312 jae coin_native_state mov mouseClick3D,0 call CoinEscape3D cmp engineMode,MODE_WALK je coin_native_done jmp coin_native_state coin_native_view: cmp mouseX3D,198 jb coin_native_state cmp mouseX3D,246 jae coin_native_state mov mouseClick3D,0 call OpenCoinDetail3D coin_native_state: cmp coin3d_state,COIN_TOSS jne coin_native_result mov eax,coin3d_timer add eax,deltaTime3D jc coin_native_settle cmp eax,COIN_TOTAL_MS jae coin_native_settle mov coin3d_timer,eax ret coin_native_settle: call CoinSettle3D cmp coinExitQueued3D,0 je coin_native_done call CoinEscape3D ret coin_native_result: cmp coin3d_state,COIN_RESULT jne coin_native_mouse invoke Pressed3D,20h test eax,eax jnz coin_native_again invoke Pressed3D,0Dh test eax,eax jnz coin_native_again cmp mouseClick3D,0 je coin_native_done mov mouseClick3D,0 cmp mouseY3D,219 jb coin_native_done cmp mouseY3D,237 jae coin_native_done cmp mouseX3D,220 jb coin_native_done cmp mouseX3D,312 jae coin_native_done coin_native_again: mov coin3d_state,COIN_IDLE mov coin3d_timer,0 mov coinError3D,0 mov mouseClick3D,0 call ClearKeys3D ret coin_native_mouse: cmp mouseClick3D,0 je coin_native_keys mov mouseClick3D,0 cmp mouseY3D,199 jb coin_native_keys cmp mouseY3D,215 jae coin_native_sides cmp mouseX3D,118 jb coin_native_keys cmp mouseX3D,134 jb coin_native_less cmp mouseX3D,140 jb coin_native_keys cmp mouseX3D,156 jb coin_native_more jmp coin_native_keys coin_native_sides: cmp mouseY3D,219 jb coin_native_keys cmp mouseY3D,237 jae coin_native_keys cmp mouseX3D,8 jb coin_native_keys cmp mouseX3D,98 jb coin_native_heads cmp mouseX3D,106 jb coin_native_keys cmp mouseX3D,196 jb coin_native_tails cmp mouseX3D,220 jb coin_native_keys cmp mouseX3D,312 jb coin_native_start coin_native_keys: invoke Pressed3D,26h test eax,eax jnz coin_native_more invoke Pressed3D,57h test eax,eax jnz coin_native_more invoke Pressed3D,28h test eax,eax jnz coin_native_less invoke Pressed3D,53h test eax,eax jnz coin_native_less invoke Pressed3D,31h test eax,eax jnz coin_native_heads invoke Pressed3D,32h test eax,eax jnz coin_native_tails invoke Pressed3D,20h test eax,eax jnz coin_native_start invoke Pressed3D,0Dh test eax,eax jnz coin_native_start ret coin_native_more: cmp coin3d_bet,5000 jae coin_native_done add coin3d_bet,50 mov coinError3D,0 ret coin_native_less: cmp coin3d_bet,50 jbe coin_native_done sub coin3d_bet,50 mov coinError3D,0 ret coin_native_heads: mov coin3d_choice,1 ret coin_native_tails: mov coin3d_choice,2 ret coin_native_start: cmp coinArtReady3D,1 jne coin_native_done mov eax,coin3d_bet cmp eax,50 jb coin_native_done cmp eax,5000 ja coin_native_done cmp eax,bankroll ja coin_native_insufficient sub bankroll,eax mov coin3d_state,COIN_TOSS mov coin3d_timer,0 mov coin3d_win,0 mov coinExitQueued3D,0 mov coinError3D,0 mov eax,coin3d_choice dec eax shl eax,8 add eax,96 mov coinStartPhase3D,eax invoke RandomRange3D,2 inc eax mov coin3d_result,eax call SaveProgress3D invoke PlayCasinoSound3D,OFFSET soundCoin,0,1 call ClearKeys3D ret coin_native_insufficient: mov coinError3D,1 coin_native_done: ret HandleNativeCoin3D ENDP ; Derive pose from absolute elapsed time; never alter bank, outcome or RNG here. CoinPose3D PROC uses ebx esi timeMs:DWORD local phase:DWORD,flightTime:DWORD,bounceTime:DWORD mov coinX3D,414 mov coinY3D,266 mov coinGroundY3D,344 mov coinWidth3D,32 mov coinHeight3D,12 mov coinShadowRadius3D,30 mov coinShadowAlpha3D,90 mov coinHandY3D,240 mov coinHandPose3D,0 mov eax,coin3d_choice dec eax mov coinFace3D,eax shl eax,8 mov coinAngle3D,eax cmp coin3d_state,COIN_IDLE je coin_pose_done mov eax,timeMs cmp eax,COIN_RELEASE_MS jae coin_pose_air xor edx,edx mov ecx,60 div ecx mov coinHandPose3D,eax ret coin_pose_air: sub eax,COIN_RELEASE_MS mov flightTime,eax mov ebx,eax xor edx,edx mov ecx,65 div ecx add eax,5 cmp eax,15 jbe @F mov eax,15 @@: mov coinHandPose3D,eax cmp ebx,200 jb @F sub ebx,200 shr ebx,1 cmp ebx,300 jbe coin_pose_withdraw mov ebx,300 coin_pose_withdraw: add coinHandY3D,ebx @@: cmp flightTime,COIN_FLIGHT_MS jae coin_pose_landing mov eax,flightTime shl eax,16 xor edx,edx mov ecx,COIN_FLIGHT_MS div ecx mov phase,eax imul eax,94 shr eax,16 sub coinX3D,eax ; Ballistic height from the thumb to the felt, with no mid-air easing/hover. mov eax,FP_1 sub eax,phase mul phase shrd eax,edx,16 imul eax,480 shr eax,16 mov ebx,FP_1 sub ebx,phase imul ebx,78 shr ebx,16 add eax,ebx mov ebx,coinGroundY3D sub ebx,eax mov coinY3D,ebx shr eax,2 sub coinShadowAlpha3D,eax mov eax,coin3d_result dec eax shl eax,8 add eax,2*512 sub eax,coinStartPhase3D mul phase shrd eax,edx,16 add eax,coinStartPhase3D and eax,511 mov coinAngle3D,eax mov ebx,tableCos[eax*4] mov coinFace3D,0 test ebx,ebx jns @F neg ebx mov coinFace3D,1 @@: imul ebx,32 shr ebx,16 cmp ebx,3 jae @F mov ebx,3 @@: mov coinHeight3D,ebx ret coin_pose_landing: mov coinX3D,320 mov coinY3D,344 mov coinGroundY3D,344 mov coinHeight3D,32 mov coinShadowAlpha3D,110 mov eax,coin3d_result dec eax mov coinFace3D,eax shl eax,8 mov coinAngle3D,eax mov eax,flightTime sub eax,COIN_FLIGHT_MS mov bounceTime,eax cmp eax,60 jbe @F mov eax,60 @@: mov ebx,eax imul eax,18 xor edx,edx mov ecx,60 div ecx sub coinHeight3D,eax mov eax,ebx imul eax,24 xor edx,edx div ecx add coinWidth3D,eax mov eax,bounceTime mov ebx,180 mov esi,72 cmp eax,180 jb coin_pose_bounce sub eax,180 mov ebx,120 mov esi,24 cmp eax,120 jae coin_pose_done coin_pose_bounce: shl eax,16 xor edx,edx div ebx mov ecx,eax neg eax add eax,FP_1 mul ecx shrd eax,edx,16 imul eax,esi shr eax,16 sub coinY3D,eax coin_pose_done: ret CoinPose3D ENDP ; Fractional shadow on actual framebuffer pixels, rather than a black rectangular sprite. DrawCoinShadow3D PROC uses ebx esi edi centerX:DWORD,centerY:DWORD,radiusX:DWORD,radiusY:DWORD,opacity:DWORD local row:DWORD,column:DWORD,dy2:DWORD,limit:DWORD,inverse:DWORD mov eax,255 sub eax,opacity mov inverse,eax mov eax,radiusX imul eax,eax mov ebx,radiusY imul ebx,ebx imul eax,ebx mov limit,eax mov eax,centerY sub eax,radiusY mov row,eax coin_shadow_row: mov eax,row sub eax,centerY imul eax,eax imul eax,radiusX imul eax,radiusX mov dy2,eax mov eax,centerX sub eax,radiusX mov column,eax coin_shadow_pixel: cmp row,SCREEN_H jae coin_shadow_next cmp column,SCREEN_W jae coin_shadow_next mov eax,column sub eax,centerX imul eax,eax imul eax,radiusY imul eax,radiusY add eax,dy2 cmp eax,limit ja coin_shadow_next mov edi,row imul edi,SCREEN_W add edi,column lea edi,screenBuffer[edi*4] mov esi,[edi] xor ebx,ebx xor ecx,ecx coin_shadow_channel: mov eax,esi and eax,255 imul eax,inverse add eax,128 mov edx,eax shr edx,8 add eax,edx shr eax,8 shl eax,cl or ebx,eax shr esi,8 add ecx,8 cmp ecx,24 jb coin_shadow_channel mov [edi],ebx coin_shadow_next: inc column mov eax,centerX add eax,radiusX cmp column,eax jle coin_shadow_pixel inc row mov eax,centerY add eax,radiusY cmp row,eax jle coin_shadow_row ret DrawCoinShadow3D ENDP RenderNativeCoin3D PROC uses ebx esi edi local x:DWORD,y:DWORD,tint:DWORD cmp coinArtReady3D,1 jne coin_render_missing mov esi,coinTableArt3D.pixels lea edi,screenBuffer mov ecx,SCREEN_SIZE rep movsd invoke CoinPose3D,coin3d_timer cmp coin3d_timer,COIN_RELEASE_MS jae coin_render_released invoke DrawAnimSprite3D,OFFSET coinHandsArt3D,coinHandPose3D,320,coinHandY3D,240,240 jmp coin_render_hud coin_render_released: mov eax,coinGroundY3D add eax,14 invoke DrawCoinShadow3D,coinX3D,eax,coinShadowRadius3D,5,coinShadowAlpha3D invoke DrawAnimSprite3D,OFFSET coinHandsArt3D,coinHandPose3D,320,coinHandY3D,240,240 mov eax,coinWidth3D shr eax,1 neg eax add eax,coinX3D mov x,eax mov eax,coinHeight3D shr eax,1 neg eax add eax,coinY3D mov y,eax add eax,2 invoke DrawAnimSprite3D,OFFSET coinFacesArt3D,coinFace3D,x,eax,coinWidth3D,coinHeight3D invoke DrawAnimSprite3D,OFFSET coinFacesArt3D,coinFace3D,x,y,coinWidth3D,coinHeight3D coin_render_hud: invoke DrawBox,0,0,320,20,0014191Dh invoke DrawString8x8,12,6,OFFSET coinTitle3D,00E5D29Eh invoke DrawBoxBorder,198,3,48,14,00252D2Ah,0086754Eh,1 invoke DrawString8x8,210,6,OFFSET coinDetailView3D,00E5D29Eh invoke DrawBoxBorder,252,3,60,14,00252D2Ah,0086754Eh,1 invoke DrawString8x8,266,6,OFFSET coinExitText3D,00E5D29Eh invoke DrawBox,4,23,138,15,0014191Dh invoke DrawString8x8,8,26,OFFSET coinBankText3D,00E5D29Eh invoke DrawNumber,60,26,bankroll,00FFFFFFh invoke DrawBox,0,194,320,46,0014191Dh cmp coin3d_state,COIN_TOSS je coin_render_toss_hud cmp coin3d_state,COIN_RESULT je coin_render_result_hud invoke DrawString8x8,8,202,OFFSET coinStakeText3D,00E5D29Eh invoke DrawNumber,72,202,coin3d_bet,00FFFFFFh invoke DrawBoxBorder,118,199,16,16,003B3024h,00C6AA66h,1 invoke DrawString8x8,122,203,OFFSET coinMinusText3D,00FFFFFFh invoke DrawBoxBorder,140,199,16,16,003B3024h,00C6AA66h,1 invoke DrawString8x8,144,203,OFFSET coinPlusText3D,00FFFFFFh cmp coinError3D,0 je @F invoke DrawString8x8,178,202,OFFSET coinLowBankText3D,00E99383h @@: mov tint,0086754Eh cmp coin3d_choice,1 jne @F mov tint,00EAC96Dh @@: invoke DrawBoxBorder,8,219,90,18,00252D2Ah,tint,1 invoke DrawString8x8,34,224,OFFSET coinHeadsText3D,00F4E7C8h mov tint,0086754Eh cmp coin3d_choice,2 jne @F mov tint,00EAC96Dh @@: invoke DrawBoxBorder,106,219,90,18,00252D2Ah,tint,1 invoke DrawString8x8,132,224,OFFSET coinTailsText3D,00F4E7C8h invoke DrawBoxBorder,220,219,92,18,00423929h,00C6AA66h,1 invoke DrawString8x8,242,224,OFFSET coinFlipText3D,00FFFFFFh jmp coin_render_done coin_render_toss_hud: mov eax,OFFSET coinTossText3D cmp coin3d_timer,COIN_RELEASE_MS jae @F mov eax,OFFSET coinPrepareText3D @@: cmp coin3d_timer,COIN_LAND_MS jb @F mov eax,OFFSET coinLandingText3D @@: cmp coinExitQueued3D,0 je @F mov eax,OFFSET coinLeavingText3D @@: invoke DrawString8x8,82,214,eax,00E5D29Eh jmp coin_render_done coin_render_result_hud: mov eax,OFFSET coinHeadsText3D cmp coin3d_result,1 je @F mov eax,OFFSET coinTailsText3D @@: invoke DrawString8x8,8,202,eax,00E5D29Eh invoke DrawString8x8,140,202,OFFSET coinReturnText3D,00E5D29Eh invoke DrawNumber,212,202,coin3d_win,00FFFFFFh invoke DrawBoxBorder,220,219,92,18,003B3024h,00C6AA66h,1 invoke DrawString8x8,238,224,OFFSET coinAgainText3D,00FFFFFFh jmp coin_render_done coin_render_missing: invoke DrawBox,0,0,320,240,0014191Dh invoke DrawString8x8,76,108,OFFSET coinMissingText3D,00E5D29Eh coin_render_done: call UpdateCoinDetail3D ret RenderNativeCoin3D ENDP include src_graphics\coin_detail.inc