; Expedition lifecycle and fixed 35 Hz simulation. No external game runtime. HFPlaySound PROC channel:DWORD cmp hfSoundReady,0 je @F mov eax,channel cmp eax,6 jae @F invoke mciSendStringA,hfSndPlays[eax*4],0,0,0 @@: ret HFPlaySound ENDP HFLoad PROC uses esi edi cmp hfLoaded,1 je hf_load_ok xor esi,esi hf_load_next: invoke LoadAnimPack3D,hfPacks[esi*4],hfPaths[esi*4] test eax,eax jz hf_load_failed inc esi cmp esi,HF_PACK_COUNT jb hf_load_next ; Dedicated texture slots, never overwrite casino materials. mov esi,hfMaterials.pixels mov edi,OFFSET texturesBuffer+HF_WALL*65536 mov ecx,12*128*128 cld rep movsd mov hfLoaded,1 hf_load_ok: mov eax,1 ret hf_load_failed: call FreeHellFPS3D xor eax,eax ret HFLoad ENDP FreeHellFPS3D PROC uses esi xor esi,esi @@: invoke FreeAnimPack3D,hfPacks[esi*4] inc esi cmp esi,HF_PACK_COUNT jb @B mov hfLoaded,0 invoke mciSendStringA,OFFSET hfMusicClose,0,0,0 xor esi,esi @@: invoke mciSendStringA,hfSndCloses[esi*4],0,0,0 inc esi cmp esi,6 jb @B mov hfSoundReady,0 ret FreeHellFPS3D ENDP HFReset PROC uses esi edi ebx mov esi,OFFSET hfMapTemplate mov edi,OFFSET hfMap mov ecx,256 cld rep movsd xor eax,eax mov edi,OFFSET hfBolts mov ecx,SIZEOF hfBolts/4 rep stosd mov edi,OFFSET hfImpacts mov ecx,SIZEOF hfImpacts/4 rep stosd mov edi,OFFSET hfItemTaken mov ecx,HF_ITEMS rep stosd mov esi,OFFSET hfEnemySeeds mov edi,OFFSET hfEnemies mov ebx,HF_ENEMIES hf_reset_enemy: lodsd mov [edi].HFEnemy.x,eax lodsd mov [edi].HFEnemy.y,eax lodsd mov [edi].HFEnemy.kind,eax mov eax,hfMonsterHP[eax*4] mov [edi].HFEnemy.hp,eax mov [edi].HFEnemy.cooldown,35 mov [edi].HFEnemy.pose,0 mov [edi].HFEnemy.timer,0 mov [edi].HFEnemy.awake,0 add edi,SIZEOF HFEnemy dec ebx jnz hf_reset_enemy mov hfState,0 mov hfHealth,100 mov hfArmor,0 mov hfBullets,80 mov hfShells,0 mov hfWeapon,0 mov hfHasShotgun,0 mov hfKey,0 mov hfSecrets,0 mov hfKills,0 mov hfTicks,0 mov hfAccumulator,0 mov hfCooldown,0 mov hfFlash,0 mov hfHurt,0 mov hfDoorMask,0 mov hfAwarded,0 mov hfFireHeld,0 mov hfFirePending,0 mov hfUsePending,0 mov playerX,3*FP_1+FP_HALF mov playerY,26*FP_1+FP_HALF mov playerAngle,0 mov worldMap3D,OFFSET hfMap mov hallLevel3D,99 mov floorTexture3D,HF_FLOOR mov viewEye3D,FP_1 mov viewCeiling3D,FP_1*5/2 mov outdoorRender3D,0 mov viewHorizon3D,HALF_H mov engineMode,MODE_HELL_FPS mov hfMessage,OFFSET hfWelcomeText mov hfMessageTime,210 call ClearKeys3D call UpdateCamera3D call HFBuildFlow ret HFReset ENDP BeginHellFPS3D PROC uses esi call HFLoad test eax,eax jnz @F invoke CopyString3D,OFFSET hfMissingText,OFFSET flashMessage mov flashTimer,180 ret @@: mov eax,playerX mov hfOldX,eax mov eax,playerY mov hfOldY,eax mov eax,playerAngle mov hfOldAngle,eax mov eax,worldMap3D mov hfOldMap,eax mov eax,floorTexture3D mov hfOldFloor,eax mov eax,hallLevel3D mov hfOldLevel,eax mov eax,viewEye3D mov hfOldEye,eax mov eax,viewCeiling3D mov hfOldCeiling,eax call StopTowerMusic call StopJukeboxTrack3D invoke PlayCasinoSound3D,0,0,0 invoke mciSendStringA,OFFSET hfMusicOpen,0,0,0 mov hfMusicError,eax mov hfLastVolume,-1 call HFUpdateMusicVolume invoke mciSendStringA,OFFSET hfMusicPlay,0,0,0 or hfMusicError,eax mov hfSoundFailures,0 xor esi,esi hf_open_sound: invoke mciSendStringA,hfSndOpens[esi*4],0,0,0 test eax,eax jz @F inc hfSoundFailures @@: inc esi cmp esi,6 jb hf_open_sound mov hfSoundReady,1 call HFReset ret BeginHellFPS3D ENDP LeaveHellFPS3D PROC uses esi mov eax,hfOldX mov playerX,eax mov eax,hfOldY mov playerY,eax mov eax,hfOldAngle mov playerAngle,eax mov eax,hfOldMap mov worldMap3D,eax mov eax,hfOldFloor mov floorTexture3D,eax mov eax,hfOldLevel mov hallLevel3D,eax mov eax,hfOldEye mov viewEye3D,eax mov eax,hfOldCeiling mov viewCeiling3D,eax mov hfFireHeld,0 mov hfFirePending,0 mov engineMode,MODE_WALK mov paused3D,0 invoke mciSendStringA,OFFSET hfMusicClose,0,0,0 xor esi,esi @@: invoke mciSendStringA,hfSndCloses[esi*4],0,0,0 inc esi cmp esi,6 jb @B mov hfSoundReady,0 call ClearKeys3D call UpdateCamera3D ret LeaveHellFPS3D ENDP HFUpdateMusicVolume PROC mov eax,settingsVolume cmp eax,hfLastVolume je @F mov hfLastVolume,eax imul eax,HF_MUSIC_SCALE invoke FormatNumber,eax,OFFSET hfNumber invoke CopyCString,OFFSET hfVolumeCommand,OFFSET hfVolumePrefix invoke AppendCString,OFFSET hfVolumeCommand,OFFSET hfNumber invoke mciSendStringA,OFFSET hfVolumeCommand,0,0,0 mov hfVolumeError,eax @@: ret HFUpdateMusicVolume ENDP HandleHellFPS3D PROC uses ebx call HFUpdateMusicVolume cmp hfState,0 je hf_handle_play invoke Pressed3D,0Dh test eax,eax jz hf_handle_done cmp hfState,1 jne hf_handle_exit call HFReset ret hf_handle_exit: call LeaveHellFPS3D ret hf_handle_play: call HandlePlayerInput invoke Pressed3D,31h test eax,eax jz @F mov hfWeapon,0 @@: invoke Pressed3D,32h test eax,eax jz @F cmp hfHasShotgun,0 je @F mov hfWeapon,1 @@: invoke Pressed3D,45h or hfUsePending,eax mov eax,mouseClick3D or hfFirePending,eax mov mouseClick3D,0 mov eax,deltaTime3D imul eax,35 add hfAccumulator,eax hf_handle_tick: cmp hfAccumulator,1000 jb hf_handle_done sub hfAccumulator,1000 call HFTick cmp hfState,0 je hf_handle_tick mov hfAccumulator,0 hf_handle_done: ret HandleHellFPS3D ENDP