; World sprites share casino depth testing. HUD uses native 640x480 pixels. HFText PROC uses esi edi ebx x:DWORD,y:DWORD,text:DWORD,color:DWORD local row:DWORD,column:DWORD,cursor:DWORD,bits:DWORD mov esi,text mov eax,x mov cursor,eax hf_text_char: movzx eax,BYTE PTR [esi] test eax,eax jz hf_text_done lea edi,font8x8[eax*8] mov row,0 hf_text_row: mov eax,row movzx eax,BYTE PTR [edi+eax] mov bits,eax mov column,0 hf_text_pixel: test bits,80h jz hf_text_next_pixel mov eax,y add eax,row cmp eax,480 jae hf_text_next_pixel mov ebx,cursor add ebx,column cmp ebx,640 jae hf_text_next_pixel imul eax,640 add eax,ebx mov ebx,color mov screenBuffer[eax*4],ebx hf_text_next_pixel: shl bits,1 inc column cmp column,8 jb hf_text_pixel inc row cmp row,8 jb hf_text_row add cursor,8 inc esi jmp hf_text_char hf_text_done: ret HFText ENDP HFNumber PROC x:DWORD,y:DWORD,value:DWORD invoke FormatNumber,value,OFFSET hfNumber invoke HFText,x,y,OFFSET hfNumber,00FFE0A0h ret HFNumber ENDP HFLargeNumber PROC uses ebx edi rightEdge:DWORD,y:DWORD,value:DWORD,percent:DWORD mov ebx,value mov edi,rightEdge cmp percent,0 je hf_large_digit sub edi,28 invoke DrawAnimSprite3D,OFFSET hfDigitsArt,10,edi,y,32,32 hf_large_digit: mov eax,ebx xor edx,edx mov ecx,10 div ecx mov ebx,eax sub edi,28 invoke DrawAnimSprite3D,OFFSET hfDigitsArt,edx,edi,y,32,32 test ebx,ebx jnz hf_large_digit ret HFLargeNumber ENDP HFRenderStatus PROC uses ebx invoke DrawAnimSprite3D,OFFSET hfHUDArt,0,0,416,640,64 mov eax,hfBullets cmp hfWeapon,0 je @F mov eax,hfShells @@: invoke HFLargeNumber,86,422,eax,0 invoke HFLargeNumber,208,422,hfHealth,1 invoke HFLargeNumber,466,422,hfArmor,1 ; Replace multiplayer FRAGS field with the owned weapon slots. invoke DrawBox,108,209,35,31,003C3B36h invoke HFText,228,460,OFFSET hfArmsText,00B0ACA0h mov eax,00777770h cmp hfWeapon,0 jne @F mov eax,00FFE070h @@: invoke HFText,230,434,OFFSET hfSlot1Text,eax cmp hfHasShotgun,0 je hf_status_face mov eax,00777770h cmp hfWeapon,1 jne @F mov eax,00FFE070h @@: invoke HFText,258,434,OFFSET hfSlot2Text,eax hf_status_face: mov eax,100 sub eax,hfHealth xor edx,edx mov ecx,20 div ecx cmp eax,4 jbe @F mov eax,4 @@: shl eax,2 mov ebx,eax cmp hfHurt,0 je hf_face_idle add ebx,3 jmp hf_face_draw hf_face_idle: mov eax,hfTicks shr eax,5 xor edx,edx mov ecx,3 div ecx add ebx,edx hf_face_draw: cmp hfState,1 jne @F mov ebx,20 @@: invoke DrawAnimSprite3D,OFFSET hfFacesArt,ebx,296,416,48,64 cmp hfKey,0 je @F invoke DrawAnimSprite3D,OFFSET hfItemsArt,5,476,420,28,28 @@: ; Clear original ammo glyphs, then draw live reserve counts. invoke DrawBox,257,209,62,30,002E302Ch invoke HFText,518,420,OFFSET hfAmmoTypesText,00B0ACA0h invoke HFNumber,558,420,hfBullets invoke HFText,590,420,OFFSET hfMaxBulletsText,008E8C80h invoke HFText,518,434,OFFSET hfShellTypeText,00B0ACA0h invoke HFNumber,558,434,hfShells invoke HFText,590,434,OFFSET hfMaxShellsText,008E8C80h invoke HFText,518,448,OFFSET hfEmptyAmmoText,008E8C80h invoke HFText,518,462,OFFSET hfEmptyCellText,008E8C80h ret HFRenderStatus ENDP RenderHellPortal3D PROC cmp hallLevel3D,0 jne hf_portal_done invoke LoadAnimPack3D,OFFSET hfPaintingArt,OFFSET hfPaintingPath cmp hfPaintingArt.pixels,0 je hf_portal_done ; Gilt landscape hung flat on the south wall opposite the bar. invoke DrawCityVertical3D,1,HF_PORTAL_Y,3*FP_1,9*FP_1,FP_1*35/100,FP_1*235/100,HF_PAINTING_MATERIAL hf_portal_done: ret RenderHellPortal3D ENDP RenderHellFPS3D PROC uses esi edi ebx call UpdateCamera3D call RenderCeilingAndFloor call RenderWalls call PrepareCityDepth3D ; Animated lava patch, same bounds as HFTick damage. mov eax,hfTicks shr eax,3 and eax,3 add eax,HF_LAVA invoke DrawCityHorizontal3D,16*FP_1,18*FP_1,17*FP_1,20*FP_1,128,eax mov esi,OFFSET hfEnemies mov edi,HF_ENEMIES hf_render_enemy: mov eax,[esi].HFEnemy.x mov hfObject.posX,eax mov eax,[esi].HFEnemy.y mov hfObject.posY,eax mov eax,[esi].HFEnemy.kind mov eax,hfMonsterPacks[eax*4] mov hfObject.asset,eax mov eax,[esi].HFEnemy.pose mov hfObject.frame,eax mov hfObject.worldW,FP_1*6/5 mov hfObject.worldH,FP_1*3/2 mov hfObject.groundZ,0 cmp [esi].HFEnemy.kind,3 jne @F mov hfObject.worldW,FP_1*9/5 mov hfObject.worldH,FP_1*22/10 @@: invoke DrawCityObject3D,OFFSET hfObject,0 add esi,SIZEOF HFEnemy dec edi jnz hf_render_enemy mov hfObject.asset,OFFSET hfItemsArt mov hfObject.worldW,FP_1/2 mov hfObject.worldH,FP_1/2 mov hfObject.groundZ,0 xor edi,edi mov esi,OFFSET hfItemSeeds hf_render_item: cmp hfItemTaken[edi*4],0 jne hf_render_item_next mov eax,[esi] mov hfObject.posX,eax mov eax,[esi+4] mov hfObject.posY,eax mov eax,[esi+8] mov hfObject.frame,eax invoke DrawCityObject3D,OFFSET hfObject,0 hf_render_item_next: add esi,12 inc edi cmp edi,HF_ITEMS jb hf_render_item mov hfObject.asset,OFFSET hfFireArt mov hfObject.worldW,FP_1/3 mov hfObject.worldH,FP_1/3 mov hfObject.groundZ,FP_1*3/4 mov eax,hfTicks shr eax,2 and eax,1 mov hfObject.frame,eax mov esi,OFFSET hfBolts mov edi,32 hf_render_bolt: cmp [esi].HFBolt.life,0 je hf_render_bolt_next mov eax,[esi].HFBolt.x mov hfObject.posX,eax mov eax,[esi].HFBolt.y mov hfObject.posY,eax invoke DrawCityObject3D,OFFSET hfObject,0 hf_render_bolt_next: add esi,SIZEOF HFBolt dec edi jnz hf_render_bolt mov hfObject.asset,OFFSET hfImpactsArt mov hfObject.worldW,FP_1/3 mov hfObject.worldH,FP_1/3 mov hfObject.groundZ,FP_1*5/6 mov esi,OFFSET hfImpacts mov edi,HF_SHOT_PELLETS hf_render_impact: cmp [esi].HFImpact.life,0 je hf_render_impact_next mov eax,[esi].HFImpact.x mov hfObject.posX,eax mov eax,[esi].HFImpact.y mov hfObject.posY,eax mov eax,8 sub eax,[esi].HFImpact.life shr eax,1 mov hfObject.frame,eax invoke DrawCityObject3D,OFFSET hfObject,0 hf_render_impact_next: add esi,SIZEOF HFImpact dec edi jnz hf_render_impact mov hfObject.asset,OFFSET hfPortalArt mov hfObject.posX,28*FP_1 mov hfObject.posY,29*FP_1 mov hfObject.worldW,FP_1*3/2 mov hfObject.worldH,2*FP_1 mov hfObject.groundZ,0 mov eax,hfTicks shr eax,2 and eax,7 mov hfObject.frame,eax invoke DrawCityObject3D,OFFSET hfObject,0 cmp hfState,0 jne hf_render_hud mov esi,OFFSET hfPistol mov edi,0 cmp hfWeapon,1 jne hf_weapon_pose mov esi,OFFSET hfShotgun hf_weapon_pose: cmp hfCooldown,0 je hf_weapon_draw cmp hfWeapon,0 jne hf_shotgun_pose ; Four recovery poses over the nine-tick pistol cycle. mov eax,9 sub eax,hfCooldown shr eax,1 inc eax cmp eax,4 jbe @F mov eax,4 @@: mov edi,eax jmp hf_weapon_draw hf_shotgun_pose: mov edi,3 cmp hfCooldown,10 jbe hf_weapon_draw mov edi,2 cmp hfCooldown,18 jbe hf_weapon_draw mov edi,1 hf_weapon_draw: invoke DrawAnimSprite3D,esi,edi,176,176,288,240 cmp hfFlash,0 je @F invoke DrawAnimSprite3D,OFFSET hfFireArt,0,296,202,48,48 @@: invoke DrawBox,159,117,2,7,00D0C0A0h invoke DrawBox,156,120,8,1,00D0C0A0h hf_render_hud: cmp hfHurt,0 je @F invoke DrawBox,0,0,320,3,00902010h invoke DrawBox,0,0,3,210,00902010h invoke DrawBox,317,0,3,210,00902010h @@: call HFRenderStatus cmp hfMessageTime,0 je @F invoke HFText,12,34,hfMessage,00FFD090h @@: cmp hfState,0 je hf_render_done invoke DrawBox,24,80,272,65,00181010h mov eax,OFFSET hfDeadText cmp hfState,1 je @F mov eax,OFFSET hfWinText @@: invoke HFText,64,176,eax,00FFB070h invoke HFText,64,208,OFFSET hfStatsText,00C0A080h mov eax,hfTicks xor edx,edx mov ecx,35 div ecx invoke HFNumber,80,226,eax invoke HFNumber,232,226,hfKills invoke HFNumber,392,226,hfSecrets cmp hfState,2 jne hf_render_done mov eax,OFFSET hfRepeatText cmp hfAwarded,0 je @F mov eax,OFFSET hfRewardText @@: invoke HFText,144,258,eax,00FFE0A0h hf_render_done: ret RenderHellFPS3D ENDP