; An owned, non-activating window shares the game's clock and settled outcome. OpenCoinDetail3D PROC cmp h3DWnd,0 je detail_open_done cmp coinDetailWnd3D,0 jne detail_open_done mov coinDetailWC3D.cbSize,SIZEOF C3D_WNDCLASSEX mov coinDetailWC3D.style,CS_HREDRAW or CS_VREDRAW mov coinDetailWC3D.lpfnWndProc,OFFSET CoinDetailEvents3D mov eax,h3DInst mov coinDetailWC3D.hInstance,eax mov coinDetailWC3D.lpszClassName,OFFSET coinDetailClass3D invoke LoadCursorA,0,32512 mov coinDetailWC3D.hCursor,eax invoke RegisterClassExA,OFFSET coinDetailWC3D mov coinDetailBmi3D.bmiHeader.biSize,SIZEOF C3D_BITMAPINFOHEADER mov coinDetailBmi3D.bmiHeader.biWidth,COIN_DETAIL_W mov coinDetailBmi3D.bmiHeader.biHeight,-COIN_DETAIL_H mov coinDetailBmi3D.bmiHeader.biPlanes,1 mov coinDetailBmi3D.bmiHeader.biBitCount,32 mov coinDetailBmi3D.bmiHeader.biSizeImage,COIN_DETAIL_W*COIN_DETAIL_H*4 invoke CreateWindowExA,08000080h,OFFSET coinDetailClass3D,OFFSET coinDetailTitle3D,80800000h,0,0,COIN_DETAIL_W,COIN_DETAIL_H,h3DWnd,0,h3DInst,0 mov coinDetailWnd3D,eax test eax,eax jz detail_open_done call LayoutCoinDetail3D invoke IsWindowVisible,h3DWnd test eax,eax jz detail_open_done invoke ShowWindow,coinDetailWnd3D,4 detail_open_done: ret OpenCoinDetail3D ENDP ; Restore only our own resize; never overwrite a later F11 or user window move. CloseCoinDetail3D PROC uses esi edi local current:CoinDetailRect3D cmp coinDetailWnd3D,0 je detail_restore invoke DestroyWindow,coinDetailWnd3D mov coinDetailWnd3D,0 detail_restore: cmp coinDetailReserved3D,0 je detail_close_done mov coinDetailReserved3D,0 invoke IsWindow,h3DWnd test eax,eax jz detail_close_done mov eax,fullscreen3D cmp eax,coinDetailFullscreen3D jne detail_close_done invoke GetWindowRect,h3DWnd,ADDR current lea esi,current lea edi,coinDetailApplied3D mov ecx,4 repe cmpsd jne detail_close_done mov eax,coinDetailOriginal3D[8] sub eax,coinDetailOriginal3D mov edx,coinDetailOriginal3D[12] sub edx,coinDetailOriginal3D[4] invoke SetWindowPos,h3DWnd,0,coinDetailOriginal3D,coinDetailOriginal3D[4],eax,edx,14h detail_close_done: ret CloseCoinDetail3D ENDP LayoutCoinDetail3D PROC uses ebx esi edi local current:CoinDetailRect3D,panelX:DWORD,panelY:DWORD,panelW:DWORD,panelH:DWORD cmp coinDetailWnd3D,0 je detail_layout_done mov eax,coinDetailWidth3D mov panelW,eax mov eax,coinDetailHeight3D mov panelH,eax invoke GetWindowRect,h3DWnd,ADDR current cmp coinDetailReserved3D,0 je detail_layout_new mov eax,fullscreen3D cmp eax,coinDetailFullscreen3D jne detail_layout_new lea esi,current lea edi,coinDetailApplied3D mov ecx,4 repe cmpsd je detail_layout_position detail_layout_new: mov coinDetailReserved3D,0 invoke MonitorFromWindow,h3DWnd,2 invoke GetMonitorInfoA,eax,OFFSET coinDetailMonitor3D test eax,eax jz detail_layout_done ; Work area bounds include taskbar and monitors with a negative origin. mov ebx,coinDetailMonitor3D[28] sub ebx,coinDetailMonitor3D[20] mov eax,COIN_DETAIL_W cmp ebx,800 jae @F mov eax,ebx shr eax,2 @@: mov panelW,eax mov eax,coinDetailMonitor3D[32] sub eax,coinDetailMonitor3D[24] cmp eax,COIN_DETAIL_H jbe @F mov eax,COIN_DETAIL_H @@: mov panelH,eax mov coinDetailHeight3D,eax mov eax,panelW mov coinDetailWidth3D,eax mov eax,current.right add eax,8 add eax,panelW cmp eax,coinDetailMonitor3D[28] jle detail_layout_position lea esi,current lea edi,coinDetailOriginal3D mov ecx,4 rep movsd mov eax,fullscreen3D mov coinDetailFullscreen3D,eax mov eax,coinDetailMonitor3D[28] sub eax,panelW sub eax,8 sub eax,coinDetailMonitor3D[20] mov ebx,coinDetailMonitor3D[32] sub ebx,coinDetailMonitor3D[24] invoke SetWindowPos,h3DWnd,0,coinDetailMonitor3D[20],coinDetailMonitor3D[24],eax,ebx,14h invoke GetWindowRect,h3DWnd,ADDR current lea esi,current lea edi,coinDetailApplied3D mov ecx,4 rep movsd mov coinDetailReserved3D,1 detail_layout_position: mov eax,current.right add eax,8 mov panelX,eax mov eax,current.top mov ebx,current.bottom sub ebx,eax sub ebx,panelH sar ebx,1 add eax,ebx cmp eax,coinDetailMonitor3D[24] jge @F mov eax,coinDetailMonitor3D[24] @@: mov ebx,coinDetailMonitor3D[32] sub ebx,panelH cmp eax,ebx jle @F mov eax,ebx @@: mov panelY,eax invoke SetWindowPos,coinDetailWnd3D,0,panelX,panelY,panelW,panelH,14h detail_layout_done: ret LayoutCoinDetail3D ENDP UpdateCoinDetail3D PROC cmp coinDetailWnd3D,0 je detail_update_done call LayoutCoinDetail3D invoke InvalidateRect,coinDetailWnd3D,0,0 invoke UpdateWindow,coinDetailWnd3D detail_update_done: ret UpdateCoinDetail3D ENDP CoinDetailEvents3D PROC hwnd:DWORD,message:DWORD,wp:DWORD,lp:DWORD local paint:CoinDetailPaint3D,rect:CoinDetailRect3D,dc:DWORD cmp message,WM_CLOSE je detail_event_close cmp message,WM_DESTROY je detail_event_destroy cmp message,201h jne @F invoke GetClientRect,hwnd,ADDR rect movzx eax,WORD PTR lp imul eax,COIN_DETAIL_W xor edx,edx div rect.right cmp eax,280 jb detail_event_done movzx eax,WORD PTR lp[2] imul eax,COIN_DETAIL_H xor edx,edx div rect.bottom cmp eax,36 jb detail_event_close jmp detail_event_done @@: cmp message,14h jne @F mov eax,1 ret @@: cmp message,21h jne @F mov eax,3 ret @@: cmp message,0Fh jne detail_event_default invoke BeginPaint,hwnd,ADDR paint mov dc,eax call RenderCoinDetail3D invoke GetClientRect,hwnd,ADDR rect invoke StretchDIBits,dc,0,0,rect.right,rect.bottom,0,0,COIN_DETAIL_W,COIN_DETAIL_H,OFFSET coinDetailBuffer3D,OFFSET coinDetailBmi3D,0,SRCCOPY invoke EndPaint,hwnd,ADDR paint jmp detail_event_done detail_event_close: call CloseCoinDetail3D jmp detail_event_done detail_event_destroy: mov coinDetailWnd3D,0 detail_event_done: xor eax,eax ret detail_event_default: invoke DefWindowProcA,hwnd,message,wp,lp ret CoinDetailEvents3D ENDP CoinDetailBox3D PROC uses edi x:DWORD,y:DWORD,w:DWORD,h:DWORD,color:DWORD local row:DWORD mov eax,y mov row,eax detail_box_row: mov eax,row cmp eax,COIN_DETAIL_H jae detail_box_done imul eax,COIN_DETAIL_W add eax,x lea edi,coinDetailBuffer3D[eax*4] mov ecx,w mov eax,color rep stosd inc row dec h jnz detail_box_row detail_box_done: ret CoinDetailBox3D ENDP CoinDetailText3D PROC uses ebx esi edi x:DWORD,y:DWORD,pText:DWORD,color:DWORD,scale:DWORD local row:DWORD,column:DWORD,bits:DWORD mov esi,pText detail_text_char: movzx eax,BYTE PTR [esi] test eax,eax jz detail_text_done lea ebx,font8x8[eax*8] mov row,0 detail_text_row: mov ecx,row movzx eax,BYTE PTR [ebx+ecx] mov bits,eax mov column,0 detail_text_pixel: test bits,80h jz detail_text_next mov eax,column imul eax,scale add eax,x mov edx,scale add edx,eax cmp edx,COIN_DETAIL_W ja detail_text_next mov edx,row imul edx,scale add edx,y mov ecx,scale add ecx,edx cmp ecx,COIN_DETAIL_H ja detail_text_next invoke CoinDetailBox3D,eax,edx,scale,scale,color detail_text_next: shl bits,1 inc column cmp column,8 jb detail_text_pixel inc row cmp row,8 jb detail_text_row mov eax,scale shl eax,3 add x,eax inc esi jmp detail_text_char detail_text_done: ret CoinDetailText3D ENDP CoinDetailNumber3D PROC uses ebx edi x:DWORD,y:DWORD,value:DWORD,color:DWORD local digits[16]:BYTE lea edi,digits[15] mov BYTE PTR [edi],0 mov eax,value mov ebx,10 detail_number_digit: xor edx,edx div ebx add dl,'0' dec edi mov [edi],dl test eax,eax jnz detail_number_digit invoke CoinDetailText3D,x,y,edi,color,2 ret CoinDetailNumber3D ENDP ; Binary-alpha faces are sampled into a private buffer, never the main scene. CoinDetailFace3D PROC uses ebx esi edi face:DWORD,height:DWORD local row:DWORD,column:DWORD,sourceRow:DWORD,top:DWORD cmp coinFacesArt3D.pixels,0 je detail_face_done mov eax,face and eax,1 shl eax,16 add eax,coinFacesArt3D.pixels mov esi,eax mov eax,height shr eax,1 neg eax add eax,166 mov top,eax mov row,0 detail_face_row: mov eax,row shl eax,7 xor edx,edx div height shl eax,9 mov sourceRow,eax mov eax,row add eax,top imul eax,COIN_DETAIL_W add eax,60 lea edi,coinDetailBuffer3D[eax*4] mov column,0 detail_face_pixel: mov eax,column shl eax,7 xor edx,edx mov ecx,200 div ecx shl eax,2 add eax,sourceRow mov ebx,[esi+eax] test ebx,0FF000000h jz @F mov [edi],ebx @@: add edi,4 inc column cmp column,200 jb detail_face_pixel inc row mov eax,row cmp eax,height jb detail_face_row detail_face_done: ret CoinDetailFace3D ENDP RenderCoinDetail3D PROC uses ebx esi edi invoke CoinDetailBox3D,0,0,320,400,0014191Dh invoke CoinDetailBox3D,0,0,320,36,00252D2Ah invoke CoinDetailText3D,16,10,OFFSET coinDetailTitle3D,00E5D29Eh,2 invoke CoinDetailText3D,292,10,OFFSET coinDetailClose3D,00ADB9BCh,2 cmp coinArtReady3D,1 jne detail_render_missing invoke CoinPose3D,coin3d_timer mov ebx,200 cmp coin3d_state,COIN_IDLE je detail_render_face cmp coin3d_timer,COIN_LAND_MS jae detail_render_face mov eax,coinAngle3D mov ebx,tableCos[eax*4] test ebx,ebx jns @F neg ebx @@: imul ebx,200 shr ebx,16 cmp ebx,6 jae detail_render_face mov ebx,6 detail_render_face: invoke CoinDetailFace3D,coinFace3D,ebx cmp coin3d_state,COIN_IDLE je detail_render_pick cmp coin3d_timer,COIN_LAND_MS jb detail_render_air mov eax,OFFSET coinHeadsText3D mov ebx,96 cmp coin3d_result,1 je @F mov eax,OFFSET coinTailsText3D mov ebx,80 @@: invoke CoinDetailText3D,ebx,284,eax,00F4E7C8h,4 mov eax,coin3d_result cmp eax,coin3d_choice jne detail_render_loss invoke CoinDetailText3D,104,336,OFFSET coinDetailWin3D,0087D4A5h,2 invoke CoinDetailText3D,100,366,OFFSET coinDetailPlus3D,0087D4A5h,2 invoke CoinDetailNumber3D,124,366,coin3d_bet,0087D4A5h invoke CoinDetailText3D,212,366,OFFSET coinDetailCash3D,0087D4A5h,2 ret detail_render_loss: invoke CoinDetailText3D,96,336,OFFSET coinDetailLose3D,00E99383h,2 invoke CoinDetailText3D,100,366,OFFSET coinDetailMinus3D,00E99383h,2 invoke CoinDetailNumber3D,124,366,coin3d_bet,00E99383h invoke CoinDetailText3D,212,366,OFFSET coinDetailCash3D,00E99383h,2 ret detail_render_air: invoke CoinDetailText3D,40,310,OFFSET coinDetailAir3D,00E5D29Eh,2 ret detail_render_pick: invoke CoinDetailText3D,104,292,OFFSET coinDetailPick3D,00ADB9BCh,2 mov eax,OFFSET coinHeadsText3D mov ebx,96 cmp coin3d_choice,1 je @F mov eax,OFFSET coinTailsText3D mov ebx,80 @@: invoke CoinDetailText3D,ebx,330,eax,00F4E7C8h,4 ret detail_render_missing: invoke CoinDetailText3D,16,190,OFFSET coinMissingText3D,00E99383h,2 ret RenderCoinDetail3D ENDP