DrawCityWakeActor3D PROC uses ebx mov cityWakeActor3D.posX,FP_1*97/10 mov cityWakeActor3D.posY,FP_1*49/2 cmp cityPhase3D,CITY_WAKE jne wake_actor_depart mov eax,cityTime3D cmp eax,2800 jae wake_actor_straighten xor edx,edx mov ecx,175 div ecx and eax,15 jmp wake_actor_draw wake_actor_straighten: sub eax,2800 imul eax,8 xor edx,edx mov ecx,1700 div ecx cmp eax,7 jbe @F mov eax,7 @@: add eax,16 jmp wake_actor_draw wake_actor_depart: cmp cityPhase3D,CITY_LIGHT jne wake_actor_done mov eax,cityTime3D sub eax,350 jns @F xor eax,eax @@: invoke CityEase3D,eax,1950 imul eax,3 sub cityWakeActor3D.posY,eax mov eax,cityTime3D xor edx,edx mov ecx,90 div ecx and eax,7 add eax,24 wake_actor_draw: mov cityWakeActor3D.frame,eax invoke DrawCityObject3D,OFFSET cityWakeActor3D,0 wake_actor_done: ret DrawCityWakeActor3D ENDP DrawCitySeatedLegs3D PROC uses ebx cmp cityPhase3D,CITY_LIGHT jbe wake_legs_seated cmp cityPhase3D,CITY_SMOKE jne wake_legs_done invoke CityEase3D,cityTime3D,900 imul eax,300 shr eax,16 add eax,240 mov ebx,eax jmp wake_legs_draw wake_legs_seated: mov ebx,240 wake_legs_draw: invoke DrawAnimSprite3D,OFFSET cityKneesPack3D,0,0,ebx,640,240 wake_legs_done: ret DrawCitySeatedLegs3D ENDP DrawCityLighter3D PROC uses ebx esi edi local px:DWORD,py:DWORD,sleeveX:DWORD,sleeveY:DWORD cmp cityPhase3D,CITY_LIGHT jne wake_lighter_done mov eax,cityTime3D imul eax,16 xor edx,edx mov ecx,2300 div ecx cmp eax,15 jbe @F mov eax,15 @@: mov esi,eax mov cityCigaretteX3D,500 mov eax,cityClock3D shr eax,3 and eax,511 mov eax,tableCos[eax*4] sar eax,14 add eax,310 mov edi,eax invoke CityEase3D,cityTime3D,600 neg eax add eax,FP_1 imul eax,110 shr eax,16 add eax,edi mov cityCigaretteY3D,eax mov eax,cityCigaretteX3D sub eax,40 sub eax,110 mov px,eax mov eax,cityCigaretteY3D sub eax,40 add eax,8 sub eax,55 mov py,eax cmp cityTime3D,1800 jb @F mov eax,cityTime3D sub eax,1800 invoke CityEase3D,eax,500 imul eax,220 shr eax,16 add py,eax @@: ; Measured cuff anchors join the real forearm underneath each animated wrist. mov eax,cityLighterCuffX3D[esi*4] imul eax,220 shr eax,8 add eax,px sub eax,110 mov sleeveX,eax mov eax,cityLighterCuffY3D[esi*4] imul eax,220 shr eax,8 add eax,py sub eax,20 mov sleeveY,eax invoke DrawAnimSprite3D,OFFSET citySleevePack3D,0,sleeveX,sleeveY,220,330 invoke DrawAnimSprite3D,OFFSET cityLighterPack3D,esi,px,py,220,220 wake_lighter_done: ret DrawCityLighter3D ENDP DrawCityWakeSubtitle3D PROC cmp cityTime3D,1100 jb wake_subtitle_done cmp cityTime3D,4300 jae wake_subtitle_done invoke DrawBox,0,205,320,35,00151B1Dh invoke DrawString8x8,92,211,OFFSET cityWakeLine1,00E6DED2h invoke DrawString8x8,60,225,OFFSET cityWakeLine2,00E6DED2h wake_subtitle_done: ret DrawCityWakeSubtitle3D ENDP ; Sky-only raycasting cannot represent a vertical view. Blend the pitched world ; into the already rendered sky instead of popping between the two projections. BlendCitySky3D PROC uses ebx esi edi amount:DWORD local inverse:DWORD,red:DWORD,green:DWORD mov ebx,amount mov eax,256 sub eax,ebx mov inverse,eax xor esi,esi wake_sky_blend: mov eax,screenBuffer[esi*4] mov edi,citySkyBuffer3D[esi*4] movzx ecx,al imul ecx,inverse mov edx,edi and edx,255 imul edx,ebx add ecx,edx shr ecx,8 mov red,ecx movzx ecx,ah imul ecx,inverse mov edx,edi shr edx,8 and edx,255 imul edx,ebx add ecx,edx shr ecx,8 shl ecx,8 mov green,ecx shr eax,16 and eax,255 imul eax,inverse shr edi,16 and edi,255 imul edi,ebx add eax,edi shr eax,8 shl eax,16 or eax,green or eax,red mov screenBuffer[esi*4],eax inc esi cmp esi,SCREEN_SIZE jb wake_sky_blend ret BlendCitySky3D ENDP